clang  19.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.
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.
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 *
200  const IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
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  const IdentifierInfo *Name,
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
Defines an enumeration for C++ overloaded operators.
SourceLocation Loc
Definition: SemaObjC.cpp:755
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TemplateNameKind enum.
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:74
This represents one expression.
Definition: Expr.h:110
One of these records is kept for each identifier that is lexed.
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:91
Represents the parsed form of a C++ template argument.
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
Create a template type argument or non-type template argument.
Expr * getAsExpr() const
Retrieve the non-type template argument's expression.
ParsedTemplateArgument()
Build an empty template argument.
KindType getKind() const
Determine what kind of template argument we have.
SourceLocation getLocation() const
Retrieve the location of the template argument.
ParsedTemplateTy getAsTemplate() const
Retrieve the template template argument's template name.
ParsedTemplateArgument getTemplatePackExpansion(SourceLocation EllipsisLoc) const
Retrieve a pack expansion of the given template template argument.
ParsedType getAsType() const
Retrieve the template type argument's type.
KindType
Describes the kind of template argument that was parsed.
@ Type
A template type parameter, stored as a type.
@ Template
A template template argument, stored as a template name.
@ NonType
A non-type template parameter, stored as an expression.
bool isInvalid() const
Determine whether the given template argument is invalid.
SourceLocation getEllipsisLoc() const
Retrieve the location of the ellipsis that makes a template template argument into a pack expansion.
const CXXScopeSpec & getScopeSpec() const
Retrieve the nested-name-specifier that precedes the template name in a template template argument.
ParsedTemplateArgument(const CXXScopeSpec &SS, ParsedTemplateTy Template, SourceLocation TemplateLoc)
Create a template template argument.
Encodes a location in the source.
The base class of the type hierarchy.
Definition: Type.h:1813
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams)
Retrieves the range of the given template parameter lists.
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
Definition: TemplateKinds.h:20
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
Definition: TemplateKinds.h:30
@ TNK_Dependent_template_name
The name refers to a dependent template name:
Definition: TemplateKinds.h:46
@ TNK_Non_template
The name does not refer to a template.
Definition: TemplateKinds.h:22
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
Definition: TemplateKinds.h:50
Information about a template-id annotation token.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.
static TemplateIdAnnotation * Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, const 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.
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
SourceLocation RAngleLoc
The location of the '>' after the template argument list.
SourceLocation LAngleLoc
The location of the '<' before the template argument list.
bool ArgsInvalid
Whether an error was encountered in the template arguments.
OverloadedOperatorKind Operator
FIXME: Temporarily stores the overloaded operator kind.
SourceLocation TemplateKWLoc
TemplateKWLoc - The location of the template keyword.
bool mightBeType() const
Determine whether this might be a type template.
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.