clang 22.0.0git
QualTypeNames.cpp
Go to the documentation of this file.
1//===------- QualTypeNames.cpp - Generate Complete QualType Names ---------===//
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
12#include "clang/AST/Mangle.h"
13#include "clang/AST/Type.h"
14
15namespace clang {
16
17namespace TypeName {
18
19/// Create a NestedNameSpecifier for Namesp and its enclosing
20/// scopes.
21///
22/// \param[in] Ctx - the AST Context to be used.
23/// \param[in] Namesp - the NamespaceDecl for which a NestedNameSpecifier
24/// is requested.
25/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
26/// specifier "::" should be prepended or not.
27static NestedNameSpecifier
28createNestedNameSpecifier(const ASTContext &Ctx, const NamespaceDecl *Namesp,
29 bool WithGlobalNsPrefix);
30
31/// Create a NestedNameSpecifier for TagDecl and its enclosing
32/// scopes.
33///
34/// \param[in] Ctx - the AST Context to be used.
35/// \param[in] TD - the TagDecl for which a NestedNameSpecifier is
36/// requested.
37/// \param[in] FullyQualify - Convert all template arguments into fully
38/// qualified names.
39/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
40/// specifier "::" should be prepended or not.
41static NestedNameSpecifier createNestedNameSpecifier(const ASTContext &Ctx,
42 const TypeDecl *TD,
43 bool FullyQualify,
44 bool WithGlobalNsPrefix);
45
46static NestedNameSpecifier
47createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Decl *decl,
48 bool FullyQualified,
49 bool WithGlobalNsPrefix);
50
51static NestedNameSpecifier getFullyQualifiedNestedNameSpecifier(
52 const ASTContext &Ctx, NestedNameSpecifier NNS, bool WithGlobalNsPrefix);
53
55 TemplateName &TName,
56 bool WithGlobalNsPrefix) {
57 bool Changed = false;
58 NestedNameSpecifier NNS = std::nullopt;
59
60 TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
61 if (!ArgTDecl) // ArgTDecl can be null in dependent contexts.
62 return false;
63
65
66 if (QTName &&
67 !QTName->hasTemplateKeyword() &&
68 (NNS = QTName->getQualifier())) {
70 getFullyQualifiedNestedNameSpecifier(Ctx, NNS, WithGlobalNsPrefix);
71 if (QNNS != NNS) {
72 Changed = true;
73 NNS = QNNS;
74 } else {
75 NNS = std::nullopt;
76 }
77 } else {
79 Ctx, ArgTDecl, true, WithGlobalNsPrefix);
80 }
81 if (NNS) {
82 TemplateName UnderlyingTN(ArgTDecl);
83 if (UsingShadowDecl *USD = TName.getAsUsingShadowDecl())
84 UnderlyingTN = TemplateName(USD);
85 TName =
87 /*TemplateKeyword=*/false, UnderlyingTN);
88 Changed = true;
89 }
90 return Changed;
91}
92
95 bool WithGlobalNsPrefix) {
96 bool Changed = false;
97
98 // Note: we do not handle TemplateArgument::Expression, to replace it
99 // we need the information for the template instance decl.
100
101 if (Arg.getKind() == TemplateArgument::Template) {
102 TemplateName TName = Arg.getAsTemplate();
103 Changed = getFullyQualifiedTemplateName(Ctx, TName, WithGlobalNsPrefix);
104 if (Changed) {
105 Arg = TemplateArgument(TName);
106 }
107 } else if (Arg.getKind() == TemplateArgument::Type) {
108 QualType SubTy = Arg.getAsType();
109 // Check if the type needs more desugaring and recurse.
110 QualType QTFQ = getFullyQualifiedType(SubTy, Ctx, WithGlobalNsPrefix);
111 if (QTFQ != SubTy) {
112 Arg = TemplateArgument(QTFQ);
113 Changed = true;
114 }
115 }
116 return Changed;
117}
118
120 const TagType *TSTRecord,
122 NestedNameSpecifier Qualifier,
123 bool WithGlobalNsPrefix) {
124 // We are asked to fully qualify and we have a Record Type,
125 // which can point to a template instantiation with no sugar in any of
126 // its template argument, however we still need to fully qualify them.
127
128 const auto *TD = TSTRecord->getOriginalDecl();
129 const auto *TSTDecl = dyn_cast<ClassTemplateSpecializationDecl>(TD);
130 if (!TSTDecl)
131 return Ctx.getTagType(Keyword, Qualifier, TD, /*OwnsTag=*/false)
132 .getTypePtr();
133
134 const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
135
136 bool MightHaveChanged = false;
138 for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
139 // cheap to copy and potentially modified by
140 // getFullyQualifedTemplateArgument
141 TemplateArgument Arg(TemplateArgs[I]);
142 MightHaveChanged |=
143 getFullyQualifiedTemplateArgument(Ctx, Arg, WithGlobalNsPrefix);
144 FQArgs.push_back(Arg);
145 }
146
147 if (!MightHaveChanged)
148 return Ctx.getTagType(Keyword, Qualifier, TD, /*OwnsTag=*/false)
149 .getTypePtr();
150 // If a fully qualified arg is different from the unqualified arg,
151 // allocate new type in the AST.
153 Qualifier, /*TemplateKeyword=*/false,
154 TemplateName(TSTDecl->getSpecializedTemplate()));
156 Keyword, TN, FQArgs,
157 /*CanonicalArgs=*/{}, TSTRecord->getCanonicalTypeInternal());
158 // getTemplateSpecializationType returns a fully qualified
159 // version of the specialization itself, so no need to qualify
160 // it.
161 return QT.getTypePtr();
162}
163
164static const Type *
166 const TemplateSpecializationType *TST,
167 bool WithGlobalNsPrefix) {
168 TemplateName TName = TST->getTemplateName();
169 bool MightHaveChanged =
170 getFullyQualifiedTemplateName(Ctx, TName, WithGlobalNsPrefix);
172 // Cheap to copy and potentially modified by
173 // getFullyQualifedTemplateArgument.
174 for (TemplateArgument Arg : TST->template_arguments()) {
175 MightHaveChanged |=
176 getFullyQualifiedTemplateArgument(Ctx, Arg, WithGlobalNsPrefix);
177 FQArgs.push_back(Arg);
178 }
179
180 if (!MightHaveChanged)
181 return TST;
182
183 QualType NewQT =
184 Ctx.getTemplateSpecializationType(TST->getKeyword(), TName, FQArgs,
185 /*CanonicalArgs=*/{}, TST->desugar());
186 // getTemplateSpecializationType returns a fully qualified
187 // version of the specialization itself, so no need to qualify
188 // it.
189 return NewQT.getTypePtr();
190}
191
193 bool FullyQualify,
194 bool WithGlobalNsPrefix) {
195 const DeclContext *DC = D->getDeclContext();
196 if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
197 while (NS && NS->isInline()) {
198 // Ignore inline namespace;
199 NS = dyn_cast<NamespaceDecl>(NS->getDeclContext());
200 }
201 if (NS && NS->getDeclName()) {
202 return createNestedNameSpecifier(Ctx, NS, WithGlobalNsPrefix);
203 }
204 return std::nullopt; // no starting '::', no anonymous
205 }
206 if (const auto *TD = dyn_cast<TagDecl>(DC))
207 return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
208 if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC))
209 return createNestedNameSpecifier(Ctx, TDD, FullyQualify,
210 WithGlobalNsPrefix);
211 if (WithGlobalNsPrefix && DC->isTranslationUnit())
213 return std::nullopt; // no starting '::' if |WithGlobalNsPrefix| is false
214}
215
216/// Return a fully qualified version of this name specifier.
218 const ASTContext &Ctx, NestedNameSpecifier Scope, bool WithGlobalNsPrefix) {
219 switch (Scope.getKind()) {
221 llvm_unreachable("can't fully qualify the empty nested name specifier");
224 // Already fully qualified
225 return Scope;
228 Ctx, Scope.getAsNamespaceAndPrefix().Namespace->getNamespace(),
229 WithGlobalNsPrefix);
231 const Type *Type = Scope.getAsType();
232 // Find decl context.
233 const TypeDecl *TD;
234 if (const TagType *TagDeclType = Type->getAs<TagType>())
235 TD = TagDeclType->getOriginalDecl();
236 else if (const auto *D = dyn_cast<TypedefType>(Type))
237 TD = D->getDecl();
238 else
239 return Scope;
240 return TypeName::createNestedNameSpecifier(Ctx, TD, /*FullyQualify=*/true,
241 WithGlobalNsPrefix);
242 }
243 }
244 llvm_unreachable("bad NNS kind");
245}
246
247/// Create a nested name specifier for the declaring context of
248/// the type.
251 bool FullyQualified,
252 bool WithGlobalNsPrefix) {
253 assert(Decl);
254
255 // Some declaration cannot be qualified.
257 return std::nullopt;
259 const auto *Outer = dyn_cast<NamedDecl>(DC);
260 const auto *OuterNS = dyn_cast<NamespaceDecl>(DC);
261 if (OuterNS && OuterNS->isAnonymousNamespace())
262 OuterNS = dyn_cast<NamespaceDecl>(OuterNS->getParent());
263 if (Outer) {
264 if (const auto *CxxDecl = dyn_cast<CXXRecordDecl>(DC)) {
265 if (ClassTemplateDecl *ClassTempl =
266 CxxDecl->getDescribedClassTemplate()) {
267 // We are in the case of a type(def) that was declared in a
268 // class template but is *not* type dependent. In clang, it
269 // gets attached to the class template declaration rather than
270 // any specific class template instantiation. This result in
271 // 'odd' fully qualified typename:
272 //
273 // vector<_Tp,_Alloc>::size_type
274 //
275 // Make the situation is 'useable' but looking a bit odd by
276 // picking a random instance as the declaring context.
277 if (!ClassTempl->specializations().empty()) {
278 Decl = *(ClassTempl->spec_begin());
279 Outer = dyn_cast<NamedDecl>(Decl);
280 OuterNS = dyn_cast<NamespaceDecl>(Decl);
281 }
282 }
283 }
284
285 if (OuterNS) {
286 return createNestedNameSpecifier(Ctx, OuterNS, WithGlobalNsPrefix);
287 } else if (const auto *TD = dyn_cast<TagDecl>(Outer)) {
289 Ctx, TD, FullyQualified, WithGlobalNsPrefix);
290 } else if (isa<TranslationUnitDecl>(Outer)) {
291 // Context is the TU. Nothing needs to be done.
292 return std::nullopt;
293 } else {
294 // Decl's context was neither the TU, a namespace, nor a
295 // TagDecl, which means it is a type local to a scope, and not
296 // accessible at the end of the TU.
297 return std::nullopt;
298 }
299 } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
301 }
302 return std::nullopt;
303}
304
305/// Create a nested name specifier for the declaring context of
306/// the type.
309 bool FullyQualified,
310 bool WithGlobalNsPrefix) {
311 if (!TypePtr)
312 return std::nullopt;
313
314 Decl *Decl = nullptr;
315 // There are probably other cases ...
316 if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
317 Decl = TDT->getDecl();
318 } else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
319 Decl = TagDeclType->getOriginalDecl();
320 } else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
321 Decl = TST->getTemplateName().getAsTemplateDecl();
322 } else {
323 Decl = TypePtr->getAsCXXRecordDecl();
324 }
325
326 if (!Decl)
327 return std::nullopt;
328
330 Ctx, Decl, FullyQualified, WithGlobalNsPrefix);
331}
332
335 bool WithGlobalNsPrefix) {
336 while (Namespace && Namespace->isInline()) {
337 // Ignore inline namespace;
338 Namespace = dyn_cast<NamespaceDecl>(Namespace->getDeclContext());
339 }
340 if (!Namespace)
341 return std::nullopt;
342
343 bool FullyQualify = true; // doesn't matter, DeclContexts are namespaces
344 return NestedNameSpecifier(
345 Ctx, Namespace,
346 createOuterNNS(Ctx, Namespace, FullyQualify, WithGlobalNsPrefix));
347}
348
350 const TypeDecl *TD,
351 bool FullyQualify,
352 bool WithGlobalNsPrefix) {
353 const Type *TypePtr = Ctx.getTypeDeclType(TD).getTypePtr();
354 if (auto *RD = dyn_cast<TagType>(TypePtr)) {
355 // We are asked to fully qualify and we have a Record Type (which
356 // may point to a template specialization) or Template
357 // Specialization Type. We need to fully qualify their arguments.
360 createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
361 WithGlobalNsPrefix);
362 } else if (auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
363 TypePtr = getFullyQualifiedTemplateType(Ctx, TST, WithGlobalNsPrefix);
364 }
365 return NestedNameSpecifier(TypePtr);
366}
367
368/// Return the fully qualified type, including fully-qualified
369/// versions of any template parameters.
371 bool WithGlobalNsPrefix) {
372 // In case of myType* we need to strip the pointer first, fully
373 // qualify and attach the pointer once again.
374 if (isa<PointerType>(QT.getTypePtr())) {
375 // Get the qualifiers.
376 Qualifiers Quals = QT.getQualifiers();
377 QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
378 QT = Ctx.getPointerType(QT);
379 // Add back the qualifiers.
380 QT = Ctx.getQualifiedType(QT, Quals);
381 return QT;
382 }
383
384 if (auto *MPT = dyn_cast<MemberPointerType>(QT.getTypePtr())) {
385 // Get the qualifiers.
386 Qualifiers Quals = QT.getQualifiers();
387 // Fully qualify the pointee and class types.
388 QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
390 Ctx, MPT->getQualifier(), WithGlobalNsPrefix);
391 QT = Ctx.getMemberPointerType(QT, Qualifier,
392 MPT->getMostRecentCXXRecordDecl());
393 // Add back the qualifiers.
394 QT = Ctx.getQualifiedType(QT, Quals);
395 return QT;
396 }
397
398 // In case of myType& we need to strip the reference first, fully
399 // qualify and attach the reference once again.
400 if (isa<ReferenceType>(QT.getTypePtr())) {
401 // Get the qualifiers.
402 bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
403 Qualifiers Quals = QT.getQualifiers();
404 QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
405 // Add the r- or l-value reference type back to the fully
406 // qualified one.
407 if (IsLValueRefTy)
408 QT = Ctx.getLValueReferenceType(QT);
409 else
410 QT = Ctx.getRValueReferenceType(QT);
411 // Add back the qualifiers.
412 QT = Ctx.getQualifiedType(QT, Quals);
413 return QT;
414 }
415
416 // Handle types with attributes such as `unique_ptr<int> _Nonnull`.
417 if (auto *AT = dyn_cast<AttributedType>(QT.getTypePtr())) {
418 QualType NewModified =
419 getFullyQualifiedType(AT->getModifiedType(), Ctx, WithGlobalNsPrefix);
420 QualType NewEquivalent =
421 getFullyQualifiedType(AT->getEquivalentType(), Ctx, WithGlobalNsPrefix);
423 return Ctx.getQualifiedType(
424 Ctx.getAttributedType(AT->getAttrKind(), NewModified, NewEquivalent),
425 Qualifiers);
426 }
427
428 // Remove the part of the type related to the type being a template
429 // parameter (we won't report it as part of the 'type name' and it
430 // is actually make the code below to be more complex (to handle
431 // those)
433 // Get the qualifiers.
434 Qualifiers Quals = QT.getQualifiers();
435
436 QT = cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();
437
438 // Add back the qualifiers.
439 QT = Ctx.getQualifiedType(QT, Quals);
440 }
441
442 if (const auto *TST =
443 dyn_cast<const TemplateSpecializationType>(QT.getTypePtr())) {
444
445 const Type *T = getFullyQualifiedTemplateType(Ctx, TST, WithGlobalNsPrefix);
446 if (T == TST)
447 return QT;
448 return Ctx.getQualifiedType(T, QT.getQualifiers());
449 }
450
451 // Local qualifiers are attached to the QualType outside of the
452 // elaborated type. Retrieve them before descending into the
453 // elaborated type.
454 Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
455 QT = QualType(QT.getTypePtr(), 0);
456
457 // We don't consider the alias introduced by `using a::X` as a new type.
458 // The qualified name is still a::X.
459 if (const auto *UT = QT->getAs<UsingType>()) {
460 QT = Ctx.getQualifiedType(UT->desugar(), PrefixQualifiers);
461 return getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
462 }
463
464 // Create a nested name specifier if needed.
466 Ctx, QT.getTypePtr(), true /*FullyQualified*/, WithGlobalNsPrefix);
467
468 // In case of template specializations iterate over the arguments and
469 // fully qualify them as well.
470 if (const auto *TT = dyn_cast<TagType>(QT.getTypePtr())) {
471 // We are asked to fully qualify and we have a Record Type (which
472 // may point to a template specialization) or Template
473 // Specialization Type. We need to fully qualify their arguments.
474
475 const Type *TypePtr = getFullyQualifiedTemplateType(
476 Ctx, TT, TT->getKeyword(), Prefix, WithGlobalNsPrefix);
477 QT = QualType(TypePtr, 0);
478 } else if (const auto *TT = dyn_cast<TypedefType>(QT.getTypePtr())) {
479 QT = Ctx.getTypedefType(
480 TT->getKeyword(), Prefix, TT->getDecl(),
481 getFullyQualifiedType(TT->desugar(), Ctx, WithGlobalNsPrefix));
482 } else {
483 assert(!Prefix && "Unhandled type node");
484 }
485 QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
486 return QT;
487}
488
490 const ASTContext &Ctx,
491 const PrintingPolicy &Policy,
492 bool WithGlobalNsPrefix) {
493 QualType FQQT = getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
494 return FQQT.getAsString(Policy);
495}
496
498 const Decl *Decl,
499 bool WithGlobalNsPrefix) {
500 return createNestedNameSpecifierForScopeOf(Ctx, Decl, /*FullyQualified=*/true,
501 WithGlobalNsPrefix);
502}
503
504} // end namespace TypeName
505} // end namespace clang
Defines the C++ template declaration subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
QualType getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T, ArrayRef< TemplateArgument > SpecifiedArgs, ArrayRef< TemplateArgument > CanonicalArgs, QualType Underlying=QualType()) const
TemplateName getQualifiedTemplateName(NestedNameSpecifier Qualifier, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
QualType getTagType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TagDecl *TD, bool OwnsTag) const
Declaration of a class template.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1449
bool isTranslationUnit() const
Definition DeclBase.h:2185
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isTemplateParameter() const
isTemplateParameter - Determines whether this declaration is a template parameter.
Definition DeclBase.h:2793
DeclContext * getDeclContext()
Definition DeclBase.h:448
Represent a C++ namespace.
Definition Decl.h:591
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
static constexpr NestedNameSpecifier getGlobal()
@ MicrosoftSuper
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
A (possibly-)qualified type.
Definition TypeBase.h:937
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8285
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8325
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition TypeBase.h:1332
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition TypeBase.h:8317
Represents a template name as written in source code.
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
bool hasTemplateKeyword() const
Whether the template name was prefixed by the "template" keyword.
The collection of all-type qualifiers we support.
Definition TypeBase.h:331
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Represents a template argument.
QualType getAsType() const
Retrieve the type for a type template argument.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
@ Template
The template argument is a template name that was provided for a template template parameter.
@ Type
The template argument is a type.
ArgKind getKind() const
Return the kind of stored template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
UsingShadowDecl * getAsUsingShadowDecl() const
Retrieve the using shadow declaration through which the underlying template declaration is introduced...
Represents a declaration of a type.
Definition Decl.h:3510
The base class of the type hierarchy.
Definition TypeBase.h:1833
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9098
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3399
static bool getFullyQualifiedTemplateName(const ASTContext &Ctx, TemplateName &TName, bool WithGlobalNsPrefix)
static const Type * getFullyQualifiedTemplateType(const ASTContext &Ctx, const TagType *TSTRecord, ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, bool WithGlobalNsPrefix)
static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx, TemplateArgument &Arg, bool WithGlobalNsPrefix)
static NestedNameSpecifier createNestedNameSpecifier(const ASTContext &Ctx, const NamespaceDecl *Namesp, bool WithGlobalNsPrefix)
Create a NestedNameSpecifier for Namesp and its enclosing scopes.
static NestedNameSpecifier createOuterNNS(const ASTContext &Ctx, const Decl *D, bool FullyQualify, bool WithGlobalNsPrefix)
std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx, const PrintingPolicy &Policy, bool WithGlobalNsPrefix=false)
Get the fully qualified name for a type.
static NestedNameSpecifier createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Decl *decl, bool FullyQualified, bool WithGlobalNsPrefix)
Create a nested name specifier for the declaring context of the type.
static NestedNameSpecifier getFullyQualifiedNestedNameSpecifier(const ASTContext &Ctx, NestedNameSpecifier NNS, bool WithGlobalNsPrefix)
Return a fully qualified version of this name specifier.
NestedNameSpecifier getFullyQualifiedDeclaredContext(const ASTContext &Ctx, const Decl *Decl, bool WithGlobalNsPrefix=false)
Get the fully qualified name for the declared context of a declaration.
QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, bool WithGlobalNsPrefix=false)
Generates a QualType that can be used to name the same type if used at the end of the current transla...
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
const FunctionProtoType * T
@ Keyword
The name has been typo-corrected to a keyword.
Definition Sema.h:560
U cast(CodeGen::Address addr)
Definition Address.h:327
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition TypeBase.h:5863
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:5884
Describes how types, statements, expressions, and declarations should be printed.