clang 20.0.0git
TemplateName.h
Go to the documentation of this file.
1//===- TemplateName.h - C++ Template Name Representation --------*- 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 defines the TemplateName interface and subclasses.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
14#define LLVM_CLANG_AST_TEMPLATENAME_H
15
18#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/FoldingSet.h"
20#include "llvm/ADT/PointerIntPair.h"
21#include "llvm/ADT/PointerUnion.h"
22#include "llvm/Support/PointerLikeTypeTraits.h"
23#include <cassert>
24#include <optional>
25
26namespace clang {
27
28class ASTContext;
29class Decl;
30class DependentTemplateName;
31class IdentifierInfo;
32class NamedDecl;
33class NestedNameSpecifier;
35class OverloadedTemplateStorage;
36class AssumedTemplateStorage;
37class DeducedTemplateStorage;
38struct PrintingPolicy;
39class QualifiedTemplateName;
40class SubstTemplateTemplateParmPackStorage;
41class SubstTemplateTemplateParmStorage;
42class TemplateArgument;
43class TemplateDecl;
44class TemplateTemplateParmDecl;
45class UsingShadowDecl;
46
47/// Implementation class used to describe either a set of overloaded
48/// template names or an already-substituted template template parameter pack.
50protected:
51 enum Kind {
53 Assumed, // defined in DeclarationName.h
57 };
58
59 struct BitsTag {
60 LLVM_PREFERRED_TYPE(Kind)
62
63 // The template parameter index.
64 unsigned Index : 14;
65
66 /// The pack index, or the number of stored templates
67 /// or template arguments, depending on which subclass we have.
68 unsigned Data : 15;
69 };
70
71 union {
72 struct BitsTag Bits;
74 };
75
77 Bits.Kind = Kind;
79 Bits.Data = Data;
80 }
81
82public:
84 return Bits.Kind == Overloaded
85 ? reinterpret_cast<OverloadedTemplateStorage *>(this)
86 : nullptr;
87 }
88
90 return Bits.Kind == Assumed
91 ? reinterpret_cast<AssumedTemplateStorage *>(this)
92 : nullptr;
93 }
94
96 return Bits.Kind == Deduced
97 ? reinterpret_cast<DeducedTemplateStorage *>(this)
98 : nullptr;
99 }
100
103 ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
104 : nullptr;
105 }
106
109 ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
110 : nullptr;
111 }
112};
113
114/// A structure for storing the information associated with an
115/// overloaded template name.
117 friend class ASTContext;
118
119 OverloadedTemplateStorage(unsigned size)
120 : UncommonTemplateNameStorage(Overloaded, 0, size) {}
121
123 return reinterpret_cast<NamedDecl **>(this + 1);
124 }
125 NamedDecl * const *getStorage() const {
126 return reinterpret_cast<NamedDecl *const *>(this + 1);
127 }
128
129public:
130 unsigned size() const { return Bits.Data; }
131
132 using iterator = NamedDecl *const *;
133
134 iterator begin() const { return getStorage(); }
135 iterator end() const { return getStorage() + Bits.Data; }
136
138 return llvm::ArrayRef(begin(), end());
139 }
140};
141
142/// A structure for storing an already-substituted template template
143/// parameter pack.
144///
145/// This kind of template names occurs when the parameter pack has been
146/// provided with a template template argument pack in a context where its
147/// enclosing pack expansion could not be fully expanded.
149 public llvm::FoldingSetNode {
150 const TemplateArgument *Arguments;
151 llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
152
153public:
155 Decl *AssociatedDecl, unsigned Index,
156 bool Final);
157
158 /// A template-like entity which owns the whole pattern being substituted.
159 /// This will own a set of template parameters.
160 Decl *getAssociatedDecl() const;
161
162 /// Returns the index of the replaced parameter in the associated declaration.
163 /// This should match the result of `getParameterPack()->getIndex()`.
164 unsigned getIndex() const { return Bits.Index; }
165
166 // When true the substitution will be 'Final' (subst node won't be placed).
167 bool getFinal() const;
168
169 /// Retrieve the template template parameter pack being substituted.
170 TemplateTemplateParmDecl *getParameterPack() const;
171
172 /// Retrieve the template template argument pack with which this
173 /// parameter was substituted.
174 TemplateArgument getArgumentPack() const;
175
176 void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
177
178 static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
179 const TemplateArgument &ArgPack, Decl *AssociatedDecl,
180 unsigned Index, bool Final);
181};
182
184 // The position in the template parameter list
185 // the first argument corresponds to.
186 unsigned StartPos;
188
189 operator bool() const { return !Args.empty(); }
190};
191
192/// Represents a C++ template name within the type system.
193///
194/// A C++ template name refers to a template within the C++ type
195/// system. In most cases, a template name is simply a reference to a
196/// class template, e.g.
197///
198/// \code
199/// template<typename T> class X { };
200///
201/// X<int> xi;
202/// \endcode
203///
204/// Here, the 'X' in \c X<int> is a template name that refers to the
205/// declaration of the class template X, above. Template names can
206/// also refer to function templates, C++0x template aliases, etc.
207///
208/// Some template names are dependent. For example, consider:
209///
210/// \code
211/// template<typename MetaFun, typename T1, typename T2> struct apply2 {
212/// typedef typename MetaFun::template apply<T1, T2>::type type;
213/// };
214/// \endcode
215///
216/// Here, "apply" is treated as a template name within the typename
217/// specifier in the typedef. "apply" is a nested template, and can
218/// only be understood in the context of a template instantiation,
219/// hence is represented as a dependent template name.
221 // NameDecl is either a TemplateDecl or a UsingShadowDecl depending on the
222 // NameKind.
223 // !! There is no free low bits in 32-bit builds to discriminate more than 4
224 // pointer types in PointerUnion.
225 using StorageType =
226 llvm::PointerUnion<Decl *, UncommonTemplateNameStorage *,
228
229 StorageType Storage;
230
231 explicit TemplateName(void *Ptr);
232
233public:
234 // Kind of name that is actually stored.
235 enum NameKind {
236 /// A single template declaration.
238
239 /// A set of overloaded template declarations.
241
242 /// An unqualified-id that has been assumed to name a function template
243 /// that will be found by ADL.
245
246 /// A qualified template name, where the qualification is kept
247 /// to describe the source code as written.
249
250 /// A dependent template name that has not been resolved to a
251 /// template (or set of templates).
253