clang  14.0.0git
ParsedTemplate.h
Go to the documentation of this file.
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 
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 
27 namespace clang {
28  /// Represents the parsed form of a C++ template argument.
30  public:
31  /// Describes the kind of template argument that was parsed.
32  enum KindType {
33  /// A template type parameter, stored as a type.
35  /// A non-type template parameter, stored as an expression.
37  /// A template template argument, stored as a template name.
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.
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.
64  SourceLocation TemplateLoc)
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.
77  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  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.
89  assert(Kind == Template && "Not a template template argument");
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  assert(Kind == Template &&
100  "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.
107  assert(Kind == Template &&
108  "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.
117  SourceLocation EllipsisLoc) const;
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 name,
143  /// template arguments, and the source locations for important
144  /// tokens. All of the information about template arguments is allocated
145  /// directly after this structure.
146  /// A template-id annotation token can also be generated by a type-constraint
147  /// construct with no explicit template arguments, e.g. "template<C T>" would
148  /// annotate C as a TemplateIdAnnotation with no template arguments (the angle
149  /// locations would be invalid in this case).
150  struct TemplateIdAnnotation final
151  : private llvm::TrailingObjects<TemplateIdAnnotation,
152  ParsedTemplateArgument> {
154  /// TemplateKWLoc - The location of the template keyword.
155  /// For e.g. typename T::template Y<U>
157 
158  /// TemplateNameLoc - The location of the template name within the
159  /// source.
161 
162  /// FIXME: Temporarily stores the name of a specialization
164 
165  /// FIXME: Temporarily stores the overloaded operator kind.
167 
168  /// The declaration of the template corresponding to the
169  /// template-name.
171 
172  /// The kind of template that Template refers to. If this is
173  /// TNK_Non_template, an error was encountered and diagnosed
174  /// when parsing or looking up the template name.
176 
177  /// The location of the '<' before the template argument
178  /// list.
180 
181  /// The location of the '>' after the template argument
182  /// list.
184 
185  /// NumArgs - The number of template arguments.
186  unsigned NumArgs;
187 
188  /// Whether an error was encountered in the template arguments.
189  /// If so, NumArgs and the trailing arguments are best-effort.
191 
192  /// Retrieves a pointer to the template arguments
194  return getTrailingObjects<ParsedTemplateArgument>();
195  }
196 
197  /// Creates a new TemplateIdAnnotation with NumArgs arguments and
198  /// appends it to List.
199  static TemplateIdAnnotation *
202  ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
206  TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
207  totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
209  OperatorKind, OpaqueTemplateName, TemplateKind,
210  LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
211  CleanupList.push_back(TemplateId);
212  return TemplateId;
213  }
214 
215  void Destroy() {
216  std::for_each(
218  [](ParsedTemplateArgument &A) { A.~ParsedTemplateArgument(); });
219  this->~TemplateIdAnnotation();
220  free(this);
221  }
222 
223  /// Determine whether this might be a type template.
224  bool mightBeType() const {
225  return Kind == TNK_Non_template ||
226  Kind == TNK_Type_template ||
229  }
230 
231  bool hasInvalidName() const { return Kind == TNK_Non_template; }
232  bool hasInvalidArgs() const { return ArgsInvalid; }
233 
234  bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
235 
236  private:
237  TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
238 
241  OverloadedOperatorKind OperatorKind,
242  ParsedTemplateTy OpaqueTemplateName,
243  TemplateNameKind TemplateKind,
246  bool ArgsInvalid) noexcept
248  Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
249  Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
250  NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
251 
252  std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
253  getTemplateArgs());
254  }
255  ~TemplateIdAnnotation() = default;
256  };
257 
258  /// Retrieves the range of the given template parameter lists.
259  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
260  unsigned NumParams);
261 } // end namespace clang
262 
263 #endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
clang::TNK_Non_template
@ TNK_Non_template
The name does not refer to a template.
Definition: TemplateKinds.h:22
clang::TemplateIdAnnotation
Information about a template-id annotation token.
Definition: ParsedTemplate.h:150
clang::TemplateIdAnnotation::Create
static TemplateIdAnnotation * Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, IdentifierInfo *Name, OverloadedOperatorKind OperatorKind, ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind, SourceLocation LAngleLoc, SourceLocation RAngleLoc, ArrayRef< ParsedTemplateArgument > TemplateArgs, bool ArgsInvalid, SmallVectorImpl< TemplateIdAnnotation * > &CleanupList)
Creates a new TemplateIdAnnotation with NumArgs arguments and appends it to List.
Definition: ParsedTemplate.h:200
clang::TemplateNameKind
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
Definition: TemplateKinds.h:20
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:88
clang::TNK_Undeclared_template
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
Definition: TemplateKinds.h:50
Ownership.h
clang::TemplateIdAnnotation::hasInvalidArgs
bool hasInvalidArgs() const
Definition: ParsedTemplate.h:232
DeclSpec.h
clang::CXXScopeSpec
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:64
clang::ParsedTemplateArgument::Type
@ Type
A template type parameter, stored as a type.
Definition: ParsedTemplate.h:34
clang::TemplateIdAnnotation::NumArgs
unsigned NumArgs
NumArgs - The number of template arguments.
Definition: ParsedTemplate.h:186
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1490
clang::ParsedTemplateArgument::KindType
KindType
Describes the kind of template argument that was parsed.
Definition: ParsedTemplate.h:32
clang::TemplateIdAnnotation::RAngleLoc
SourceLocation RAngleLoc
The location of the '>' after the template argument list.
Definition: ParsedTemplate.h:183
OperatorKinds.h
clang::TemplateIdAnnotation::Operator
OverloadedOperatorKind Operator
FIXME: Temporarily stores the overloaded operator kind.
Definition: ParsedTemplate.h:166
clang::TNK_Dependent_template_name
@ TNK_Dependent_template_name
The name refers to a dependent template name:
Definition: TemplateKinds.h:46
clang::TemplateIdAnnotation::Kind
TemplateNameKind Kind
The kind of template that Template refers to.
Definition: ParsedTemplate.h:175
clang::ParsedTemplateArgument::ParsedTemplateArgument
ParsedTemplateArgument()
Build an empty template argument.
Definition: ParsedTemplate.h:44
clang::TemplateIdAnnotation::hasInvalidName
bool hasInvalidName() const
Definition: ParsedTemplate.h:231
clang::ParsedTemplateArgument::getTemplatePackExpansion
ParsedTemplateArgument getTemplatePackExpansion(SourceLocation EllipsisLoc) const
Retrieve a pack expansion of the given template template argument.
Definition: SemaTemplate.cpp:907
clang::ParsedTemplateArgument::ParsedTemplateArgument
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
Create a template type argument or non-type template argument.
Definition: ParsedTemplate.h:50
clang::ParsedTemplateArgument::Template
@ Template
A template template argument, stored as a template name.
Definition: ParsedTemplate.h:38
clang::TemplateIdAnnotation::Destroy
void Destroy()
Definition: ParsedTemplate.h:215
clang::ParsedTemplateArgument::getScopeSpec
const CXXScopeSpec & getScopeSpec() const
Retrieve the nested-name-specifier that precedes the template name in a template template argument.
Definition: ParsedTemplate.h:98
clang::OverloadedOperatorKind
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
clang::ParsedTemplateArgument
Represents the parsed form of a C++ template argument.
Definition: ParsedTemplate.h:29
clang::OpaquePtr< TemplateName >
clang::TemplateIdAnnotation::LAngleLoc
SourceLocation LAngleLoc
The location of the '<' before the template argument list.
Definition: ParsedTemplate.h:179
clang::ParsedTemplateArgument::ParsedTemplateArgument
ParsedTemplateArgument(const CXXScopeSpec &SS, ParsedTemplateTy Template, SourceLocation TemplateLoc)
Create a template template argument.
Definition: ParsedTemplate.h:62
clang::ParsedTemplateArgument::getKind
KindType getKind() const
Determine what kind of template argument we have.
Definition: ParsedTemplate.h:73
SourceLocation.h
clang::TemplateIdAnnotation::TemplateNameLoc
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
Definition: ParsedTemplate.h:160
clang::ParsedTemplateArgument::isInvalid
bool isInvalid() const
Determine whether the given template argument is invalid.
Definition: ParsedTemplate.h:70
clang::TemplateIdAnnotation::mightBeType
bool mightBeType() const
Determine whether this might be a type template.
Definition: ParsedTemplate.h:224
clang::TNK_Type_template
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
Definition: TemplateKinds.h:30
clang::getTemplateParamsRange
SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams)
Retrieves the range of the given template parameter lists.
Definition: SemaTemplate.cpp:44
llvm::ArrayRef
Definition: LLVM.h:34
clang::ParsedTemplateArgument::getAsExpr
Expr * getAsExpr() const
Retrieve the non-type template argument's expression.
Definition: ParsedTemplate.h:82
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:67
clang::TemplateIdAnnotation::TemplateKWLoc
SourceLocation TemplateKWLoc
TemplateKWLoc - The location of the template keyword.
Definition: ParsedTemplate.h:156
clang::TemplateIdAnnotation::TrailingObjects
friend TrailingObjects
Definition: ParsedTemplate.h:153
clang
Definition: CalledOnceCheck.h:17
clang::TemplateIdAnnotation::Name
IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
Definition: ParsedTemplate.h:163
clang::ParsedTemplateArgument::NonType
@ NonType
A non-type template parameter, stored as an expression.
Definition: ParsedTemplate.h:36
clang::TemplateIdAnnotation::getTemplateArgs
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
Definition: ParsedTemplate.h:193
clang::TemplateIdAnnotation::ArgsInvalid
bool ArgsInvalid
Whether an error was encountered in the template arguments.
Definition: ParsedTemplate.h:190
clang::TemplateIdAnnotation::isInvalid
bool isInvalid() const
Definition: ParsedTemplate.h:234
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::ParsedTemplateArgument::getEllipsisLoc
SourceLocation getEllipsisLoc() const
Retrieve the location of the ellipsis that makes a template template argument into a pack expansion.
Definition: ParsedTemplate.h:106
TemplateKinds.h
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::ParsedTemplateArgument::getLocation
SourceLocation getLocation() const
Retrieve the location of the template argument.
Definition: ParsedTemplate.h:94
clang::OpaquePtr< QualType >::getFromOpaquePtr
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:91
clang::ParsedTemplateArgument::getAsType
ParsedType getAsType() const
Retrieve the template type argument's type.
Definition: ParsedTemplate.h:76
clang::TemplateIdAnnotation::Template
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.
Definition: ParsedTemplate.h:170
clang::ParsedTemplateArgument::getAsTemplate
ParsedTemplateTy getAsTemplate() const
Retrieve the template template argument's template name.
Definition: ParsedTemplate.h:88