clang  15.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()), SS(SS), Loc(TemplateLoc) {}
67 
68  /// Determine whether the given template argument is invalid.
69  bool isInvalid() const { return Arg == nullptr; }
70 
71  /// Determine what kind of template argument we have.
72  KindType getKind() const { return Kind; }
73 
74  /// Retrieve the template type argument's type.
76  assert(Kind == Type && "Not a template type argument");
77  return ParsedType::getFromOpaquePtr(Arg);
78  }
79 
80  /// Retrieve the non-type template argument's expression.
81  Expr *getAsExpr() const {
82  assert(Kind == NonType && "Not a non-type template argument");
83  return static_cast<Expr*>(Arg);
84  }
85 
86  /// Retrieve the template template argument's template name.
88  assert(Kind == Template && "Not a template template argument");
90  }
91 
92  /// Retrieve the location of the template argument.
93  SourceLocation getLocation() const { return Loc; }
94 
95  /// Retrieve the nested-name-specifier that precedes the template
96  /// name in a template template argument.
97  const CXXScopeSpec &getScopeSpec() const {
98  assert(Kind == Template &&
99  "Only template template arguments can have a scope specifier");
100  return SS;
101  }
102 
103  /// Retrieve the location of the ellipsis that makes a template
104  /// template argument into a pack expansion.
106  assert(Kind == Template &&
107  "Only template template arguments can have an ellipsis");
108  return EllipsisLoc;
109  }
110 
111  /// Retrieve a pack expansion of the given template template
112  /// argument.
113  ///
114  /// \param EllipsisLoc The location of the ellipsis.
116  SourceLocation EllipsisLoc) const;
117 
118  private:
119  KindType Kind;
120 
121  /// The actual template argument representation, which may be
122  /// an \c Sema::TypeTy* (for a type), an Expr* (for an
123  /// expression), or an Sema::TemplateTy (for a template).
124  void *Arg;
125 
126  /// The nested-name-specifier that can accompany a template template
127  /// argument.
128  CXXScopeSpec SS;
129 
130  /// the location of the template argument.
131  SourceLocation Loc;
132 
133  /// The ellipsis location that can accompany a template template
134  /// argument (turning it into a template template argument expansion).
135  SourceLocation EllipsisLoc;
136  };
137 
138  /// Information about a template-id annotation
139  /// token.
140  ///
141  /// A template-id annotation token contains the template name,
142  /// template arguments, and the source locations for important
143  /// tokens. All of the information about template arguments is allocated
144  /// directly after this structure.
145  /// A template-id annotation token can also be generated by a type-constraint
146  /// construct with no explicit template arguments, e.g. "template<C T>" would
147  /// annotate C as a TemplateIdAnnotation with no template arguments (the angle
148  /// locations would be invalid in this case).
149  struct TemplateIdAnnotation final
150  : private llvm::TrailingObjects<TemplateIdAnnotation,
151  ParsedTemplateArgument> {
153  /// TemplateKWLoc - The location of the template keyword.
154  /// For e.g. typename T::template Y<U>
156 
157  /// TemplateNameLoc - The location of the template name within the
158  /// source.
160 
161  /// FIXME: Temporarily stores the name of a specialization
163 
164  /// FIXME: Temporarily stores the overloaded operator kind.
166 
167  /// The declaration of the template corresponding to the
168  /// template-name.
170 
171  /// The kind of template that Template refers to. If this is
172  /// TNK_Non_template, an error was encountered and diagnosed
173  /// when parsing or looking up the template name.
175 
176  /// The location of the '<' before the template argument
177  /// list.
179 
180  /// The location of the '>' after the template argument
181  /// list.
183 
184  /// NumArgs - The number of template arguments.
185  unsigned NumArgs;
186 
187  /// Whether an error was encountered in the template arguments.
188  /// If so, NumArgs and the trailing arguments are best-effort.
190 
191  /// Retrieves a pointer to the template arguments
193  return getTrailingObjects<ParsedTemplateArgument>();
194  }
195 
196  /// Creates a new TemplateIdAnnotation with NumArgs arguments and
197  /// appends it to List.
198  static TemplateIdAnnotation *
201  ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
205  TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
206  totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
208  OperatorKind, OpaqueTemplateName, TemplateKind,
209  LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
210  CleanupList.push_back(TemplateId);
211  return TemplateId;
212  }
213 
214  void Destroy() {
215  for (ParsedTemplateArgument &A :
216  llvm::make_range(getTemplateArgs(), getTemplateArgs() + NumArgs))
217  A.~ParsedTemplateArgument();
218  this->~TemplateIdAnnotation();
219  free(this);
220  }
221 
222  /// Determine whether this might be a type template.
223  bool mightBeType() const {
224  return Kind == TNK_Non_template ||
225  Kind == TNK_Type_template ||
228  }
229 
230  bool hasInvalidName() const { return Kind == TNK_Non_template; }
231  bool hasInvalidArgs() const { return ArgsInvalid; }
232 
233  bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
234 
235  private:
236  TemplateIdAnnotation(const TemplateIdAnnotation &) = delete;
237 
240  OverloadedOperatorKind OperatorKind,
241  ParsedTemplateTy OpaqueTemplateName,
242  TemplateNameKind TemplateKind,
245  bool ArgsInvalid) noexcept
247  Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
248  Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
249  NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
250 
251  std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(),
252  getTemplateArgs());
253  }
254  ~TemplateIdAnnotation() = default;
255  };
256 
257  /// Retrieves the range of the given template parameter lists.
258  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
259  unsigned NumParams);
260 } // end namespace clang
261 
262 #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:149
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:199
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:86
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:231
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:185
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1556
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:182
OperatorKinds.h
clang::TemplateIdAnnotation::Operator
OverloadedOperatorKind Operator
FIXME: Temporarily stores the overloaded operator kind.
Definition: ParsedTemplate.h:165
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:174
clang::ParsedTemplateArgument::ParsedTemplateArgument
ParsedTemplateArgument()
Build an empty template argument.
Definition: ParsedTemplate.h:44
clang::TemplateIdAnnotation::hasInvalidName
bool hasInvalidName() const
Definition: ParsedTemplate.h:230
clang::ParsedTemplateArgument::getTemplatePackExpansion
ParsedTemplateArgument getTemplatePackExpansion(SourceLocation EllipsisLoc) const
Retrieve a pack expansion of the given template template argument.
Definition: SemaTemplate.cpp:911
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:214
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:97
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:178
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:72
SourceLocation.h
clang::TemplateIdAnnotation::TemplateNameLoc
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
Definition: ParsedTemplate.h:159
clang::ParsedTemplateArgument::isInvalid
bool isInvalid() const
Determine whether the given template argument is invalid.
Definition: ParsedTemplate.h:69
clang::TemplateIdAnnotation::mightBeType
bool mightBeType() const
Determine whether this might be a type template.
Definition: ParsedTemplate.h:223
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:46
llvm::ArrayRef
Definition: LLVM.h:34
clang::ParsedTemplateArgument::getAsExpr
Expr * getAsExpr() const
Retrieve the non-type template argument's expression.
Definition: ParsedTemplate.h:81
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:84
clang::TemplateIdAnnotation::TemplateKWLoc
SourceLocation TemplateKWLoc
TemplateKWLoc - The location of the template keyword.
Definition: ParsedTemplate.h:155
clang::TemplateIdAnnotation::TrailingObjects
friend TrailingObjects
Definition: ParsedTemplate.h:152
clang
Definition: CalledOnceCheck.h:17
clang::TemplateIdAnnotation::Name
IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
Definition: ParsedTemplate.h:162
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:192
clang::TemplateIdAnnotation::ArgsInvalid
bool ArgsInvalid
Whether an error was encountered in the template arguments.
Definition: ParsedTemplate.h:189
clang::TemplateIdAnnotation::isInvalid
bool isInvalid() const
Definition: ParsedTemplate.h:233
llvm::SmallVectorImpl
Definition: Randstruct.h:18
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:105
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:93
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:75
clang::TemplateIdAnnotation::Template
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.
Definition: ParsedTemplate.h:169
clang::ParsedTemplateArgument::getAsTemplate
ParsedTemplateTy getAsTemplate() const
Retrieve the template template argument's template name.
Definition: ParsedTemplate.h:87