clang 17.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"
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.
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");
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).
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 ||
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:
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(),
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
Defines an enumeration for C++ overloaded operators.
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:65
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.
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.
Expr * getAsExpr() const
Retrieve the non-type template argument's expression.
ParsedTemplateArgument(const CXXScopeSpec &SS, ParsedTemplateTy Template, SourceLocation TemplateLoc)
Create a template template argument.
const CXXScopeSpec & getScopeSpec() const
Retrieve the nested-name-specifier that precedes the template name in a template template argument.
Encodes a location in the source.
The base class of the type hierarchy.
Definition: Type.h:1566
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.
TemplateNameKind Kind
The kind of template that Template refers to.
unsigned NumArgs
NumArgs - The number of template arguments.
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
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.
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.
bool mightBeType() const
Determine whether this might be a type template.
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.
IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.