clang
20.0.0git
include
clang
AST
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
16
#include "
clang/AST/DependenceFlags.h
"
17
#include "
clang/AST/NestedNameSpecifier.h
"
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
26
namespace
clang
{
27
28
class
ASTContext;
29
class
Decl
;
30
class
DependentTemplateName;
31
class
IdentifierInfo;
32
class
NamedDecl;
33
class
NestedNameSpecifier;
34
enum
OverloadedOperatorKind
:
int
;
35
class
OverloadedTemplateStorage;
36
class
AssumedTemplateStorage;
37
class
DeducedTemplateStorage;
38
struct
PrintingPolicy;
39
class
QualifiedTemplateName;
40
class
SubstTemplateTemplateParmPackStorage;
41
class
SubstTemplateTemplateParmStorage;
42
class
TemplateArgument;
43
class
TemplateDecl;
44
class
TemplateTemplateParmDecl;
45
class
UsingShadowDecl;
46
47
/// Implementation class used to describe either a set of overloaded
48
/// template names or an already-substituted template template parameter pack.
49
class
UncommonTemplateNameStorage
{
50
protected
:
51
enum
Kind
{
52
Overloaded
,
53
Assumed
,
// defined in DeclarationName.h
54
Deduced
,
55
SubstTemplateTemplateParm
,
56
SubstTemplateTemplateParmPack
57
};
58
59
struct
BitsTag
{
60
LLVM_PREFERRED_TYPE(
Kind
)
61
unsigned
Kind
: 3;
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
;
73
void
*
PointerAlignment
;
74
};
75
76
UncommonTemplateNameStorage
(
Kind
Kind
,
unsigned
Index
,
unsigned
Data
) {
77
Bits
.
Kind
=
Kind
;
78
Bits
.
Index
=
Index
;
79
Bits
.
Data
=
Data
;
80
}
81
82
public
:
83
OverloadedTemplateStorage
*
getAsOverloadedStorage
() {
84
return
Bits
.
Kind
==
Overloaded
85
?
reinterpret_cast<
OverloadedTemplateStorage
*
>
(
this
)
86
:
nullptr
;
87
}
88
89
AssumedTemplateStorage
*
getAsAssumedTemplateName
() {
90
return
Bits
.
Kind
==
Assumed
91
?
reinterpret_cast<
AssumedTemplateStorage
*
>
(
this
)
92
:
nullptr
;
93
}
94
95
DeducedTemplateStorage
*
getAsDeducedTemplateName
() {
96
return
Bits
.
Kind
==
Deduced
97
?
reinterpret_cast<
DeducedTemplateStorage
*
>
(
this
)
98
:
nullptr
;
99
}
100
101
SubstTemplateTemplateParmStorage
*
getAsSubstTemplateTemplateParm
() {
102
return
Bits
.
Kind
==
SubstTemplateTemplateParm
103
?
reinterpret_cast<
SubstTemplateTemplateParmStorage
*
>
(
this
)
104
:
nullptr
;
105
}
106
107
SubstTemplateTemplateParmPackStorage
*
getAsSubstTemplateTemplateParmPack
() {
108
return
Bits
.
Kind
==
SubstTemplateTemplateParmPack
109
?
reinterpret_cast<
SubstTemplateTemplateParmPackStorage
*
>
(
this
)
110
:
nullptr
;
111
}
112
};
113
114
/// A structure for storing the information associated with an
115
/// overloaded template name.
116
class
OverloadedTemplateStorage
:
public
UncommonTemplateNameStorage
{
117
friend
class
ASTContext
;
118
119
OverloadedTemplateStorage
(
unsigned
size)
120
:
UncommonTemplateNameStorage
(Overloaded, 0, size) {}
121
122
NamedDecl
**
getStorage
() {
123
return
reinterpret_cast<
NamedDecl
**
>
(
this
+ 1);
124
}
125
NamedDecl *
const
*
getStorage
()
const
{
126
return
reinterpret_cast<
NamedDecl *
const
*
>
(
this
+ 1);
127
}
128
129
public
:
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
137
llvm::ArrayRef<NamedDecl*>
decls
()
const
{
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.
148
class
SubstTemplateTemplateParmPackStorage
:
public
UncommonTemplateNameStorage
,
149
public
llvm::FoldingSetNode {
150
const
TemplateArgument
*Arguments;
151
llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
152
153
public
:
154
SubstTemplateTemplateParmPackStorage
(
ArrayRef<TemplateArgument>
ArgPack,
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
183
struct
DefaultArguments
{
184
// The position in the template parameter list
185
// the first argument corresponds to.
186
unsigned
StartPos
;
187
ArrayRef<TemplateArgument>
Args
;
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.
220
class
TemplateName
{
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
*,
227
QualifiedTemplateName
*,
DependentTemplateName
*>;
228
229
StorageType Storage;
230
231
explicit
TemplateName
(
void
*Ptr);
232
233
public
:
234
// Kind of name that is actually stored.
235
enum
NameKind
{
236
/// A single template declaration.
237
Template
,
238
239
/// A set of overloaded template declarations.
240
OverloadedTemplate
,
241
242
/// An unqualified-id that has been assumed to name a function template
243
/// that will be found by ADL.
244
AssumedTemplate
,
245
246
/// A qualified template name, where the qualification is kept
247
/// to describe the source code as written.
248
QualifiedTemplate
,
249
250
/// A dependent template name that has not been resolved to a
251
/// template (or set of templates).
252
DependentTemplate
,
253