clang  11.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)
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.
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 *
200  Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc,
201  IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
202  ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
203  SourceLocation LAngleLoc, SourceLocation RAngleLoc,
204  ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid,
206  TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
207  totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
208  TemplateIdAnnotation(TemplateKWLoc, TemplateNameLoc, Name,
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(
217  getTemplateArgs(), getTemplateArgs() + NumArgs,
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 ||
227  Kind == TNK_Dependent_template_name ||
228  Kind == TNK_Undeclared_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 
239  TemplateIdAnnotation(SourceLocation TemplateKWLoc,
240  SourceLocation TemplateNameLoc, IdentifierInfo *Name,
241  OverloadedOperatorKind OperatorKind,
242  ParsedTemplateTy OpaqueTemplateName,
243  TemplateNameKind TemplateKind,
244  SourceLocation LAngleLoc, SourceLocation RAngleLoc,
246  bool ArgsInvalid) noexcept
247  : TemplateKWLoc(TemplateKWLoc), TemplateNameLoc(TemplateNameLoc),
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.
260  unsigned NumParams);
261 } // end namespace clang
262 
263 #endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
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. ...
SourceLocation getEllipsisLoc() const
Retrieve the location of the ellipsis that makes a template template argument into a pack expansion...
IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
The name refers to a dependent template name:
Definition: TemplateKinds.h:46
Expr * getAsExpr() const
Retrieve the non-type template argument&#39;s expression.
The base class of the type hierarchy.
Definition: Type.h:1472
TemplateNameKind Kind
The kind of template that Template refers to.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:69
Information about a template-id annotation token.
One of these records is kept for each identifier that is lexed.
Lookup for the name failed, but we&#39;re assuming it was a template name anyway.
Definition: TemplateKinds.h:50
SourceLocation getLocation() const
Retrieve the location of the template argument.
bool ArgsInvalid
Whether an error was encountered in the template arguments.
A non-type template parameter, stored as an expression.
ParsedType getAsType() const
Retrieve the template type argument&#39;s type.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:64
SourceLocation TemplateKWLoc
TemplateKWLoc - The location of the template keyword.
SourceLocation LAngleLoc
The location of the &#39;<&#39; before the template argument list.
Defines the clang::TemplateNameKind enum.
ParsedTemplateArgument(const CXXScopeSpec &SS, ParsedTemplateTy Template, SourceLocation TemplateLoc)
Create a template template argument.
KindType
Describes the kind of template argument that was parsed.
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
Create a template type argument or non-type template argument.
This represents one expression.
Definition: Expr.h:110
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines an enumeration for C++ overloaded operators.
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
Definition: TemplateKinds.h:20
ParsedTemplateArgument()
Build an empty template argument.
const CXXScopeSpec & getScopeSpec() const
Retrieve the nested-name-specifier that precedes the template name in a template template argument...
Kind
Represents the parsed form of a C++ template argument.
Encodes a location in the source.
KindType getKind() const
Determine what kind of template argument we have.
A template type parameter, stored as a type.
The name does not refer to a template.
Definition: TemplateKinds.h:22
Dataflow Directional Tag Classes.
ParsedTemplateTy getAsTemplate() const
Retrieve the template template argument&#39;s template name.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
SourceLocation RAngleLoc
The location of the &#39;>&#39; after the template argument list.
bool isInvalid() const
Determine whether the given template argument is invalid.
bool mightBeType() const
Determine whether this might be a type template.
The name refers to a template whose specialization produces a type.
Definition: TemplateKinds.h:30
ParsedTemplateArgument getTemplatePackExpansion(SourceLocation EllipsisLoc) const
Retrieve a pack expansion of the given template template argument.
OverloadedOperatorKind Operator
FIXME: Temporarily stores the overloaded operator kind.
friend TrailingObjects
SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams)
Retrieves the range of the given template parameter lists.
Defines the clang::SourceLocation class and associated facilities.
A trivial tuple used to represent a source range.
A template template argument, stored as a template name.
unsigned NumArgs
NumArgs - The number of template arguments.
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:91
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.