Clang Project

clang_source_code/include/clang/Sema/ParsedTemplate.h
1//===--- ParsedTemplate.h - Template Parsing Data Types ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file provides data structures that store the parsed representation of
10//  templates.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
15#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
16
17#include "clang/Basic/OperatorKinds.h"
18#include "clang/Basic/SourceLocation.h"
19#include "clang/Basic/TemplateKinds.h"
20#include "clang/Sema/DeclSpec.h"
21#include "clang/Sema/Ownership.h"
22#include "llvm/ADT/SmallVector.h"
23#include <cassert>
24#include <cstdlib>
25#include <new>
26
27namespace clang {
28  /// Represents the parsed form of a C++ template argument.
29  class ParsedTemplateArgument {
30  public:
31    /// Describes the kind of template argument that was parsed.
32    enum KindType {
33      /// A template type parameter, stored as a type.
34      Type,
35      /// A non-type template parameter, stored as an expression.
36      NonType,
37      /// A template template argument, stored as a template name.
38      Template
39    };
40
41    /// Build an empty template argument.
42    ///
43    /// This template argument is invalid.
44    ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
45
46    /// Create a template type argument or non-type template argument.
47    ///
48    /// \param Arg the template type argument or non-type template argument.
49    /// \param Loc the location of the type.
50    ParsedTemplateArgument(KindType Kindvoid *ArgSourceLocation Loc)
51      : Kind(Kind), Arg(Arg), Loc(Loc) { }
52
53    /// Create a template template argument.
54    ///
55    /// \param SS the C++ scope specifier that precedes the template name, if
56    /// any.
57    ///
58    /// \param Template the template to which this template template
59    /// argument refers.
60    ///
61    /// \param TemplateLoc the location of the template name.
62    ParsedTemplateArgument(const CXXScopeSpec &SS,
63                           ParsedTemplateTy Template,
64                           SourceLocation TemplateLoc)
65      : Kind(ParsedTemplateArgument::Template),
66        Arg(Template.getAsOpaquePtr()),
67        SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
68
69    /// Determine whether the given template argument is invalid.
70    bool isInvalid() const { return Arg == nullptr; }
71
72    /// Determine what kind of template argument we have.
73    KindType getKind() const { return Kind; }
74
75    /// Retrieve the template type argument's type.
76    ParsedType getAsType() const {
77       (0) . __assert_fail ("Kind == Type && \"Not a template type argument\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedTemplate.h", 77, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Kind == Type && "Not a template type argument");
78      return ParsedType::getFromOpaquePtr(Arg);
79    }
80
81    /// Retrieve the non-type template argument's expression.
82    Expr *getAsExpr() const {
83       (0) . __assert_fail ("Kind == NonType && \"Not a non-type template argument\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedTemplate.h", 83, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Kind == NonType && "Not a non-type template argument");
84      return static_cast<Expr*>(Arg);
85    }
86
87    /// Retrieve the template template argument's template name.
88    ParsedTemplateTy getAsTemplate() const {
89       (0) . __assert_fail ("Kind == Template && \"Not a template template argument\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedTemplate.h", 89, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Kind == Template && "Not a template template argument");
90      return ParsedTemplateTy::getFromOpaquePtr(Arg);
91    }
92
93    /// Retrieve the location of the template argument.
94    SourceLocation getLocation() const { return Loc; }
95
96    /// Retrieve the nested-name-specifier that precedes the template
97    /// name in a template template argument.
98    const CXXScopeSpec &getScopeSpec() const {
99       (0) . __assert_fail ("Kind == Template && \"Only template template arguments can have a scope specifier\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedTemplate.h", 100, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Kind == Template &&
100 (0) . __assert_fail ("Kind == Template && \"Only template template arguments can have a scope specifier\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedTemplate.h", 100, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">             "Only template template arguments can have a scope specifier");
101      return SS;
102    }
103
104    /// Retrieve the location of the ellipsis that makes a template
105    /// template argument into a pack expansion.
106    SourceLocation getEllipsisLoc() const {
107       (0) . __assert_fail ("Kind == Template && \"Only template template arguments can have an ellipsis\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedTemplate.h", 108, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(Kind == Template &&
108 (0) . __assert_fail ("Kind == Template && \"Only template template arguments can have an ellipsis\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Sema/ParsedTemplate.h", 108, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">             "Only template template arguments can have an ellipsis");
109      return EllipsisLoc;
110    }
111
112    /// Retrieve a pack expansion of the given template template
113    /// argument.
114    ///
115    /// \param EllipsisLoc The location of the ellipsis.
116    ParsedTemplateArgument getTemplatePackExpansion(
117                                              SourceLocation EllipsisLocconst;
118
119  private:
120    KindType Kind;
121
122    /// The actual template argument representation, which may be
123    /// an \c Sema::TypeTy* (for a type), an Expr* (for an
124    /// expression), or an Sema::TemplateTy (for a template).
125    void *Arg;
126
127    /// The nested-name-specifier that can accompany a template template
128    /// argument.
129    CXXScopeSpec SS;
130
131    /// the location of the template argument.
132    SourceLocation Loc;
133
134    /// The ellipsis location that can accompany a template template
135    /// argument (turning it into a template template argument expansion).
136    SourceLocation EllipsisLoc;
137  };
138
139  /// Information about a template-id annotation
140  /// token.
141  ///
142  /// A template-id annotation token contains the template declaration,
143  /// template arguments, whether those template arguments were types,
144  /// expressions, or template names, and the source locations for important
145  /// tokens. All of the information about template arguments is allocated
146  /// directly after this structure.
147  struct TemplateIdAnnotation final
148      : private llvm::TrailingObjects<TemplateIdAnnotation,
149                                      ParsedTemplateArgument> {
150    friend TrailingObjects;
151    /// The nested-name-specifier that precedes the template name.
152    CXXScopeSpec SS;
153
154    /// TemplateKWLoc - The location of the template keyword.
155    /// For e.g. typename T::template Y<U>
156    SourceLocation TemplateKWLoc;
157
158    /// TemplateNameLoc - The location of the template name within the
159    /// source.
160    SourceLocation TemplateNameLoc;
161
162    /// FIXME: Temporarily stores the name of a specialization
163    IdentifierInfo *Name;
164
165    /// FIXME: Temporarily stores the overloaded operator kind.
166    OverloadedOperatorKind Operator;
167
168    /// The declaration of the template corresponding to the
169    /// template-name.
170    ParsedTemplateTy Template;
171
172    /// The kind of template that Template refers to.
173    TemplateNameKind Kind;
174
175    /// The location of the '<' before the template argument
176    /// list.
177    SourceLocation LAngleLoc;
178
179    /// The location of the '>' after the template argument
180    /// list.
181    SourceLocation RAngleLoc;
182
183    /// NumArgs - The number of template arguments.
184    unsigned NumArgs;
185
186    /// Retrieves a pointer to the template arguments
187    ParsedTemplateArgument *getTemplateArgs() {
188      return getTrailingObjects<ParsedTemplateArgument>();
189    }
190
191    /// Creates a new TemplateIdAnnotation with NumArgs arguments and
192    /// appends it to List.
193    static TemplateIdAnnotation *
194    Create(CXXScopeSpec SSSourceLocation TemplateKWLoc,
195           SourceLocation TemplateNameLocIdentifierInfo *Name,
196           OverloadedOperatorKind OperatorKind,
197           ParsedTemplateTy OpaqueTemplateNameTemplateNameKind TemplateKind,
198           SourceLocation LAngleLocSourceLocation RAngleLoc,
199           ArrayRef<ParsedTemplateArgumentTemplateArgs,
200           SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) {
201      TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
202          totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
203          TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name,
204                               OperatorKind, OpaqueTemplateName, TemplateKind,
205                               LAngleLoc, RAngleLoc, TemplateArgs);
206      CleanupList.push_back(TemplateId);
207      return TemplateId;
208    }
209
210    void Destroy() {
211      std::for_each(
212          getTemplateArgs(), getTemplateArgs() + NumArgs,
213          [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
214      this->~TemplateIdAnnotation();
215      free(this);
216    }
217  private:
218    TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
219
220    TemplateIdAnnotation(CXXScopeSpec SSSourceLocation TemplateKWLoc,
221                         SourceLocation TemplateNameLocIdentifierInfo *Name,
222                         OverloadedOperatorKind OperatorKind,
223                         ParsedTemplateTy OpaqueTemplateName,
224                         TemplateNameKind TemplateKind,
225                         SourceLocation LAngleLocSourceLocation RAngleLoc,
226                         ArrayRef<ParsedTemplateArgumentTemplateArgsnoexcept
227        : SS(SS), TemplateKWLoc(TemplateKWLoc),
228          TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind),
229          Template(OpaqueTemplateName), Kind(TemplateKind),
230          LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
231          NumArgs(TemplateArgs.size()) {
232
233      std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
234                              getTemplateArgs());
235    }
236    ~TemplateIdAnnotation() = default;
237  };
238
239  /// Retrieves the range of the given template parameter lists.
240  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
241                                     unsigned NumParams);
242// end namespace clang
243
244#endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
245
clang::ParsedTemplateArgument::KindType
clang::ParsedTemplateArgument::isInvalid
clang::ParsedTemplateArgument::getKind
clang::ParsedTemplateArgument::getAsType
clang::ParsedTemplateArgument::getAsExpr
clang::ParsedTemplateArgument::getAsTemplate
clang::ParsedTemplateArgument::getLocation
clang::ParsedTemplateArgument::getScopeSpec
clang::ParsedTemplateArgument::getEllipsisLoc
clang::ParsedTemplateArgument::getTemplatePackExpansion
clang::ParsedTemplateArgument::Kind
clang::ParsedTemplateArgument::Arg
clang::ParsedTemplateArgument::SS
clang::ParsedTemplateArgument::Loc
clang::ParsedTemplateArgument::EllipsisLoc
clang::TemplateIdAnnotation::SS
clang::TemplateIdAnnotation::TemplateKWLoc
clang::TemplateIdAnnotation::TemplateNameLoc
clang::TemplateIdAnnotation::Name
clang::TemplateIdAnnotation::Operator
clang::TemplateIdAnnotation::Template
clang::TemplateIdAnnotation::Kind
clang::TemplateIdAnnotation::LAngleLoc
clang::TemplateIdAnnotation::RAngleLoc
clang::TemplateIdAnnotation::NumArgs
clang::TemplateIdAnnotation::getTemplateArgs
clang::TemplateIdAnnotation::Create
clang::TemplateIdAnnotation::Destroy