clang 22.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/STLExtras.h"
23#include "llvm/ADT/SmallVector.h"
24#include <cassert>
25#include <cstdlib>
26#include <new>
27
28namespace clang {
29 /// Represents the parsed form of a C++ template argument.
31 public:
32 /// Describes the kind of template argument that was parsed.
33 enum KindType {
34 /// A template type parameter, stored as a type.
36 /// A non-type template parameter, stored as an expression.
38 /// A template template argument, stored as a template name.
40 };
41
42 /// Build an empty template argument.
43 ///
44 /// This template argument is invalid.
45 ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
46
47 /// Create a template type argument or non-type template argument.
48 ///
49 /// \param Arg the template type argument or non-type template argument.
50 /// \param Loc the location of the type.
52 : Kind(Kind), Arg(Arg), NameLoc(NameLoc) {}
53
54 /// Create a template template argument.
55 ///
56 /// \param SS the C++ scope specifier that precedes the template name, if
57 /// any.
58 ///
59 /// \param Template the template to which this template template
60 /// argument refers.
61 ///
62 /// \param TemplateLoc the location of the template name.
66 Arg(Template.getAsOpaquePtr()), SS(SS), TemplateKwLoc(TemplateKwLoc),
67 NameLoc(NameLoc) {}
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");
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 getTemplateKwLoc() const { return TemplateKwLoc; }
95
96 /// Retrieve the location of the template argument.
97 SourceLocation getNameLoc() const { return NameLoc; }
98
99 /// Retrieve the nested-name-specifier that precedes the template
100 /// name in a template template argument.
101 const CXXScopeSpec &getScopeSpec() const {
102 assert(Kind == Template &&
103 "Only template template arguments can have a scope specifier");
104 return SS;
105 }
106
107 /// Retrieve the location of the ellipsis that makes a template
108 /// template argument into a pack expansion.
110 assert(Kind == Template &&
111 "Only template template arguments can have an ellipsis");
112 return EllipsisLoc;
113 }
114
115 /// Retrieve a pack expansion of the given template template
116 /// argument.
117 ///
118 /// \param EllipsisLoc The location of the ellipsis.
120 SourceLocation EllipsisLoc) const;
121
122 private:
123 KindType Kind;
124
125 /// The actual template argument representation, which may be
126 /// an \c Sema::TypeTy* (for a type), an Expr* (for an
127 /// expression), or an Sema::TemplateTy (for a template).
128 void *Arg;
129
130 /// The nested-name-specifier that can accompany a template template
131 /// argument.
132 CXXScopeSpec SS;
133
134 /// the location of the template keyword.
135 SourceLocation TemplateKwLoc;
136
137 /// the location of the template name.
138 SourceLocation NameLoc;
139
140 /// The ellipsis location that can accompany a template template
141 /// argument (turning it into a template template argument expansion).
142 SourceLocation EllipsisLoc;
143 };
144
145 /// Information about a template-id annotation
146 /// token.
147 ///
148 /// A template-id annotation token contains the template name,
149 /// template arguments, and the source locations for important
150 /// tokens. All of the information about template arguments is allocated
151 /// directly after this structure.
152 /// A template-id annotation token can also be generated by a type-constraint
153 /// construct with no explicit template arguments, e.g. "template<C T>" would
154 /// annotate C as a TemplateIdAnnotation with no template arguments (the angle
155 /// locations would be invalid in this case).
157 : private llvm::TrailingObjects<TemplateIdAnnotation,
158 ParsedTemplateArgument> {
160 /// TemplateKWLoc - The location of the template keyword.
161 /// For e.g. typename T::template Y<U>
163
164 /// TemplateNameLoc - The location of the template name within the
165 /// source.
167
168 /// FIXME: Temporarily stores the name of a specialization
170
171 /// FIXME: Temporarily stores the overloaded operator kind.
173
174 /// The declaration of the template corresponding to the
175 /// template-name.
177
178 /// The kind of template that Template refers to. If this is
179 /// TNK_Non_template, an error was encountered and diagnosed
180 /// when parsing or looking up the template name.
182
183 /// The location of the '<' before the template argument
184 /// list.
186
187 /// The location of the '>' after the template argument
188 /// list.
190
191 /// NumArgs - The number of template arguments.
192 unsigned NumArgs;
193
194 /// Whether an error was encountered in the template arguments.
195 /// If so, NumArgs and the trailing arguments are best-effort.
197
198 /// Retrieves a pointer to the template arguments
199 ParsedTemplateArgument *getTemplateArgs() { return getTrailingObjects(); }
200
201 /// Creates a new TemplateIdAnnotation with NumArgs arguments and
202 /// appends it to List.
203 static TemplateIdAnnotation *
205 const IdentifierInfo *Name, OverloadedOperatorKind OperatorKind,
206 ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind,
210 TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc(
211 totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size())))
213 OperatorKind, OpaqueTemplateName, TemplateKind,
214 LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid);
215 CleanupList.push_back(TemplateId);
216 return TemplateId;
217 }
218
219 void Destroy() {
220 for (ParsedTemplateArgument &A :
221 llvm::make_range(getTemplateArgs(), getTemplateArgs() + NumArgs))
222 A.~ParsedTemplateArgument();
223 this->~TemplateIdAnnotation();
224 free(this);
225 }
226
227 /// Determine whether this might be a type template.
228 bool mightBeType() const {
229 return Kind == TNK_Non_template ||
233 }
234
235 bool hasInvalidName() const { return Kind == TNK_Non_template; }
236 bool hasInvalidArgs() const { return ArgsInvalid; }
237
238 bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); }
239
240 private:
242
245 const IdentifierInfo *Name,
246 OverloadedOperatorKind OperatorKind,
247 ParsedTemplateTy OpaqueTemplateName,
248 TemplateNameKind TemplateKind,
251 bool ArgsInvalid) noexcept
253 Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName),
254 Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
255 NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) {
256
257 llvm::uninitialized_copy(TemplateArgs, getTemplateArgs());
258 }
259 ~TemplateIdAnnotation() = default;
260 };
261
262 /// Retrieves the range of the given template parameter lists.
263 SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
264 unsigned NumParams);
265} // end namespace clang
266
267#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:73
This represents one expression.
Definition: Expr.h:112
One of these records is kept for each identifier that is lexed.
static OpaquePtr getFromOpaquePtr(void *P)
Definition: Ownership.h:92
Represents the parsed form of a C++ template argument.
ParsedTemplateArgument(SourceLocation TemplateKwLoc, const CXXScopeSpec &SS, ParsedTemplateTy Template, SourceLocation NameLoc)
Create a template template argument.
ParsedTemplateArgument()
Build an empty template argument.
KindType getKind() const
Determine what kind of template argument we have.
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.
ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation NameLoc)
Create a template type argument or non-type template argument.
SourceLocation getTemplateKwLoc() const
Retrieve the location of the template argument.
Expr * getAsExpr() const
Retrieve the non-type template argument's expression.
SourceLocation getNameLoc() const
Retrieve the location of the 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: TypeBase.h:1833
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.
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.
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.
bool mightBeType() const
Determine whether this might be a type template.
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.
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.