clang  16.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 
11 #include "clang/AST/GlobalDecl.h"
12 #include "clang/AST/Mangle.h"
14 
15 #include <stdio.h>
16 #include <memory>
17 
18 namespace clang {
19 
20 namespace TypeName {
21 
22 /// Create a NestedNameSpecifier for Namesp and its enclosing
23 /// scopes.
24 ///
25 /// \param[in] Ctx - the AST Context to be used.
26 /// \param[in] Namesp - the NamespaceDecl for which a NestedNameSpecifier
27 /// is requested.
28 /// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
29 /// specifier "::" should be prepended or not.
30 static NestedNameSpecifier *createNestedNameSpecifier(
31  const ASTContext &Ctx,
32  const NamespaceDecl *Namesp,
33  bool WithGlobalNsPrefix);
34 
35 /// Create a NestedNameSpecifier for TagDecl and its enclosing
36 /// scopes.
37 ///
38 /// \param[in] Ctx - the AST Context to be used.
39 /// \param[in] TD - the TagDecl for which a NestedNameSpecifier is
40 /// requested.
41 /// \param[in] FullyQualify - Convert all template arguments into fully
42 /// qualified names.
43 /// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
44 /// specifier "::" should be prepended or not.
45 static NestedNameSpecifier *createNestedNameSpecifier(
46  const ASTContext &Ctx, const TypeDecl *TD,
47  bool FullyQualify, bool WithGlobalNsPrefix);
48 
49 static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
50  const ASTContext &Ctx, const Decl *decl,
51  bool FullyQualified, bool WithGlobalNsPrefix);
52 
53 static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
54  const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix);
55 
57  TemplateName &TName,
58  bool WithGlobalNsPrefix) {
59  bool Changed = false;
60  NestedNameSpecifier *NNS = nullptr;
61 
62  TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
63  // ArgTDecl won't be NULL because we asserted that this isn't a
64  // dependent context very early in the call chain.
65  assert(ArgTDecl != nullptr);
67 
68  if (QTName && !QTName->hasTemplateKeyword()) {
69  NNS = QTName->getQualifier();
71  Ctx, NNS, WithGlobalNsPrefix);
72  if (QNNS != NNS) {
73  Changed = true;
74  NNS = QNNS;
75  } else {
76  NNS = nullptr;
77  }
78  } else {
80  Ctx, ArgTDecl, true, WithGlobalNsPrefix);
81  }
82  if (NNS) {
83  TemplateName UnderlyingTN(ArgTDecl);
84  if (UsingShadowDecl *USD = TName.getAsUsingShadowDecl())
85  UnderlyingTN = TemplateName(USD);
86  TName =
88  /*TemplateKeyword=*/false, UnderlyingTN);
89  Changed = true;
90  }
91  return Changed;
92 }
93 
95  TemplateArgument &Arg,
96  bool WithGlobalNsPrefix) {
97  bool Changed = false;
98 
99  // Note: we do not handle TemplateArgument::Expression, to replace it
100  // we need the information for the template instance decl.
101 
102  if (Arg.getKind() == TemplateArgument::Template) {
103  TemplateName TName = Arg.getAsTemplate();
104  Changed = getFullyQualifiedTemplateName(Ctx, TName, WithGlobalNsPrefix);
105  if (Changed) {
106  Arg = TemplateArgument(TName);
107  }
108  } else if (Arg.getKind() == TemplateArgument::Type) {
109  QualType SubTy = Arg.getAsType();
110  // Check if the type needs more desugaring and recurse.
111  QualType QTFQ = getFullyQualifiedType(SubTy, Ctx, WithGlobalNsPrefix);
112  if (QTFQ != SubTy) {
113  Arg = TemplateArgument(QTFQ);
114  Changed = true;
115  }
116  }
117  return Changed;
118 }
119 
121  const Type *TypePtr,
122  bool WithGlobalNsPrefix) {
123  // DependentTemplateTypes exist within template declarations and
124  // definitions. Therefore we shouldn't encounter them at the end of
125  // a translation unit. If we do, the caller has made an error.
126  assert(!isa<DependentTemplateSpecializationType>(TypePtr));
127  // In case of template specializations, iterate over the arguments
128  // and fully qualify them as well.
129  if (const auto *TST = dyn_cast<const TemplateSpecializationType>(TypePtr)) {
130  bool MightHaveChanged = false;
132  // Cheap to copy and potentially modified by
133  // getFullyQualifedTemplateArgument.
134  for (TemplateArgument Arg : TST->template_arguments()) {
135  MightHaveChanged |= getFullyQualifiedTemplateArgument(
136  Ctx, Arg, WithGlobalNsPrefix);
137  FQArgs.push_back(Arg);
138  }
139 
140  // If a fully qualified arg is different from the unqualified arg,
141  // allocate new type in the AST.
142  if (MightHaveChanged) {
144  TST->getTemplateName(), FQArgs,
145  TST->getCanonicalTypeInternal());
146  // getTemplateSpecializationType returns a fully qualified
147  // version of the specialization itself, so no need to qualify
148  // it.
149  return QT.getTypePtr();
150  }
151  } else if (const auto *TSTRecord = dyn_cast<const RecordType>(TypePtr)) {
152  // We are asked to fully qualify and we have a Record Type,
153  // which can point to a template instantiation with no sugar in any of
154  // its template argument, however we still need to fully qualify them.
155 
156  if (const auto *TSTDecl =
157  dyn_cast<ClassTemplateSpecializationDecl>(TSTRecord->getDecl())) {
158  const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
159 
160  bool MightHaveChanged = false;
162  for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
163  // cheap to copy and potentially modified by
164  // getFullyQualifedTemplateArgument
165  TemplateArgument Arg(TemplateArgs[I]);
166  MightHaveChanged |= getFullyQualifiedTemplateArgument(
167  Ctx, Arg, WithGlobalNsPrefix);
168  FQArgs.push_back(Arg);
169  }
170 
171  // If a fully qualified arg is different from the unqualified arg,
172  // allocate new type in the AST.
173  if (MightHaveChanged) {
174  TemplateName TN(TSTDecl->getSpecializedTemplate());
176  TN, FQArgs,
177  TSTRecord->getCanonicalTypeInternal());
178  // getTemplateSpecializationType returns a fully qualified
179  // version of the specialization itself, so no need to qualify
180  // it.
181  return QT.getTypePtr();
182  }
183  }
184  }
185  return TypePtr;
186 }
187 
188 static NestedNameSpecifier *createOuterNNS(const ASTContext &Ctx, const Decl *D,
189  bool FullyQualify,
190  bool WithGlobalNsPrefix) {
191  const DeclContext *DC = D->getDeclContext();
192  if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
193  while (NS && NS->isInline()) {
194  // Ignore inline namespace;
195  NS = dyn_cast<NamespaceDecl>(NS->getDeclContext());
196  }
197  if (NS && NS->getDeclName()) {
198  return createNestedNameSpecifier(Ctx, NS, WithGlobalNsPrefix);
199  }
200  return nullptr; // no starting '::', no anonymous
201  } else if (const auto *TD = dyn_cast<TagDecl>(DC)) {
202  return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
203  } else if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC)) {
205  Ctx, TDD, FullyQualify, WithGlobalNsPrefix);
206  } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
208  }
209  return nullptr; // no starting '::' if |WithGlobalNsPrefix| is false
210 }
211 
212 /// Return a fully qualified version of this name specifier.
214  const ASTContext &Ctx, NestedNameSpecifier *Scope,
215  bool WithGlobalNsPrefix) {
216  switch (Scope->getKind()) {
218  // Already fully qualified
219  return Scope;
222  Ctx, Scope->getAsNamespace(), WithGlobalNsPrefix);
224  // Namespace aliases are only valid for the duration of the
225  // scope where they were introduced, and therefore are often
226  // invalid at the end of the TU. So use the namespace name more
227  // likely to be valid at the end of the TU.
229  Ctx,
230  Scope->getAsNamespaceAlias()->getNamespace()->getCanonicalDecl(),
231  WithGlobalNsPrefix);
233  // A function or some other construct that makes it un-namable
234  // at the end of the TU. Skip the current component of the name,
235  // but use the name of it's prefix.
237  Ctx, Scope->getPrefix(), WithGlobalNsPrefix);
241  const Type *Type = Scope->getAsType();
242  // Find decl context.
243  const TagDecl *TD = nullptr;
244  if (const TagType *TagDeclType = Type->getAs<TagType>()) {
245  TD = TagDeclType->getDecl();
246  } else {
247  TD = Type->getAsCXXRecordDecl();
248  }
249  if (TD) {
251  true /*FullyQualified*/,
252  WithGlobalNsPrefix);
253  } else if (const auto *TDD = dyn_cast<TypedefType>(Type)) {
254  return TypeName::createNestedNameSpecifier(Ctx, TDD->getDecl(),
255  true /*FullyQualified*/,
256  WithGlobalNsPrefix);
257  }
258  return Scope;
259  }
260  }
261  llvm_unreachable("bad NNS kind");
262 }
263 
264 /// Create a nested name specifier for the declaring context of
265 /// the type.
267  const ASTContext &Ctx, const Decl *Decl,
268  bool FullyQualified, bool WithGlobalNsPrefix) {
269  assert(Decl);
270 
272  const auto *Outer = dyn_cast_or_null<NamedDecl>(DC);
273  const auto *OuterNS = dyn_cast_or_null<NamespaceDecl>(DC);
274  if (Outer && !(OuterNS && OuterNS->isAnonymousNamespace())) {
275  if (const auto *CxxDecl = dyn_cast<CXXRecordDecl>(DC)) {
276  if (ClassTemplateDecl *ClassTempl =
277  CxxDecl->getDescribedClassTemplate()) {
278  // We are in the case of a type(def) that was declared in a
279  // class template but is *not* type dependent. In clang, it
280  // gets attached to the class template declaration rather than
281  // any specific class template instantiation. This result in
282  // 'odd' fully qualified typename:
283  //
284  // vector<_Tp,_Alloc>::size_type
285  //
286  // Make the situation is 'useable' but looking a bit odd by
287  // picking a random instance as the declaring context.
288  if (ClassTempl->spec_begin() != ClassTempl->spec_end()) {
289  Decl = *(ClassTempl->spec_begin());
290  Outer = dyn_cast<NamedDecl>(Decl);
291  OuterNS = dyn_cast<NamespaceDecl>(Decl);
292  }
293  }
294  }
295 
296  if (OuterNS) {
297  return createNestedNameSpecifier(Ctx, OuterNS, WithGlobalNsPrefix);
298  } else if (const auto *TD = dyn_cast<TagDecl>(Outer)) {
300  Ctx, TD, FullyQualified, WithGlobalNsPrefix);
301  } else if (isa<TranslationUnitDecl>(Outer)) {
302  // Context is the TU. Nothing needs to be done.
303  return nullptr;
304  } else {
305  // Decl's context was neither the TU, a namespace, nor a
306  // TagDecl, which means it is a type local to a scope, and not
307  // accessible at the end of the TU.
308  return nullptr;
309  }
310  } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
312  }
313  return nullptr;
314 }
315 
316 /// Create a nested name specifier for the declaring context of
317 /// the type.
319  const ASTContext &Ctx, const Type *TypePtr,
320  bool FullyQualified, bool WithGlobalNsPrefix) {
321  if (!TypePtr) return nullptr;
322 
323  Decl *Decl = nullptr;
324  // There are probably other cases ...
325  if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
326  Decl = TDT->getDecl();
327  } else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
328  Decl = TagDeclType->getDecl();
329  } else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
330  Decl = TST->getTemplateName().getAsTemplateDecl();
331  } else {
332  Decl = TypePtr->getAsCXXRecordDecl();
333  }
334 
335  if (!Decl) return nullptr;
336 
338  Ctx, Decl, FullyQualified, WithGlobalNsPrefix);
339 }
340 
342  const NamespaceDecl *Namespace,
343  bool WithGlobalNsPrefix) {
344  while (Namespace && Namespace->isInline()) {
345  // Ignore inline namespace;
346  Namespace = dyn_cast<NamespaceDecl>(Namespace->getDeclContext());
347  }
348  if (!Namespace) return nullptr;
349 
350  bool FullyQualified = true; // doesn't matter, DeclContexts are namespaces
352  Ctx,
353  createOuterNNS(Ctx, Namespace, FullyQualified, WithGlobalNsPrefix),
354  Namespace);
355 }
356 
358  const TypeDecl *TD,
359  bool FullyQualify,
360  bool WithGlobalNsPrefix) {
361  const Type *TypePtr = TD->getTypeForDecl();
362  if (isa<const TemplateSpecializationType>(TypePtr) ||
363  isa<const RecordType>(TypePtr)) {
364  // We are asked to fully qualify and we have a Record Type (which
365  // may point to a template specialization) or Template
366  // Specialization Type. We need to fully qualify their arguments.
367 
368  TypePtr = getFullyQualifiedTemplateType(Ctx, TypePtr, WithGlobalNsPrefix);
369  }
370 
372  Ctx, createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
373  false /*No TemplateKeyword*/, TypePtr);
374 }
375 
376 /// Return the fully qualified type, including fully-qualified
377 /// versions of any template parameters.
379  bool WithGlobalNsPrefix) {
380  // In case of myType* we need to strip the pointer first, fully
381  // qualify and attach the pointer once again.
382  if (isa<PointerType>(QT.getTypePtr())) {
383  // Get the qualifiers.
384  Qualifiers Quals = QT.getQualifiers();
385  QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
386  QT = Ctx.getPointerType(QT);
387  // Add back the qualifiers.
388  QT = Ctx.getQualifiedType(QT, Quals);
389  return QT;
390  }
391 
392  if (auto *MPT = dyn_cast<MemberPointerType>(QT.getTypePtr())) {
393  // Get the qualifiers.
394  Qualifiers Quals = QT.getQualifiers();
395  // Fully qualify the pointee and class types.
396  QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
397  QualType Class = getFullyQualifiedType(QualType(MPT->getClass(), 0), Ctx,
398  WithGlobalNsPrefix);
399  QT = Ctx.getMemberPointerType(QT, Class.getTypePtr());
400  // Add back the qualifiers.
401  QT = Ctx.getQualifiedType(QT, Quals);
402  return QT;
403  }
404 
405  // In case of myType& we need to strip the reference first, fully
406  // qualify and attach the reference once again.
407  if (isa<ReferenceType>(QT.getTypePtr())) {
408  // Get the qualifiers.
409  bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
410  Qualifiers Quals = QT.getQualifiers();
411  QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
412  // Add the r- or l-value reference type back to the fully
413  // qualified one.
414  if (IsLValueRefTy)
415  QT = Ctx.getLValueReferenceType(QT);
416  else
417  QT = Ctx.getRValueReferenceType(QT);
418  // Add back the qualifiers.
419  QT = Ctx.getQualifiedType(QT, Quals);
420  return QT;
421  }
422 
423  // Remove the part of the type related to the type being a template
424  // parameter (we won't report it as part of the 'type name' and it
425  // is actually make the code below to be more complex (to handle
426  // those)
427  while (isa<SubstTemplateTypeParmType>(QT.getTypePtr())) {
428  // Get the qualifiers.
429  Qualifiers Quals = QT.getQualifiers();
430 
431  QT = cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();
432 
433  // Add back the qualifiers.
434  QT = Ctx.getQualifiedType(QT, Quals);
435  }
436 
437  NestedNameSpecifier *Prefix = nullptr;
438  // Local qualifiers are attached to the QualType outside of the
439  // elaborated type. Retrieve them before descending into the
440  // elaborated type.
441  Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
442  QT = QualType(QT.getTypePtr(), 0);
444  if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
445  QT = ETypeInput->getNamedType();
446  assert(!QT.hasLocalQualifiers());
447  Keyword = ETypeInput->getKeyword();
448  }
449 
450  // We don't consider the alias introduced by `using a::X` as a new type.
451  // The qualified name is still a::X.
452  if (const auto *UT = QT->getAs<UsingType>()) {
453  QT = Ctx.getQualifiedType(UT->getUnderlyingType(), PrefixQualifiers);
454  return getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
455  }
456 
457  // Create a nested name specifier if needed.
459  true /*FullyQualified*/,
460  WithGlobalNsPrefix);
461 
462  // In case of template specializations iterate over the arguments and
463  // fully qualify them as well.
464  if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
465  isa<const RecordType>(QT.getTypePtr())) {
466  // We are asked to fully qualify and we have a Record Type (which
467  // may point to a template specialization) or Template
468  // Specialization Type. We need to fully qualify their arguments.
469 
470  const Type *TypePtr = getFullyQualifiedTemplateType(
471  Ctx, QT.getTypePtr(), WithGlobalNsPrefix);
472  QT = QualType(TypePtr, 0);
473  }
474  if (Prefix || Keyword != ETK_None) {
475  QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
476  }
477  QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
478  return QT;
479 }
480 
482  const ASTContext &Ctx,
483  const PrintingPolicy &Policy,
484  bool WithGlobalNsPrefix) {
485  QualType FQQT = getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
486  return FQQT.getAsString(Policy);
487 }
488 
489 } // end namespace TypeName
490 } // end namespace clang
clang::ElaboratedTypeKeyword
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: Type.h:5552
clang::NestedNameSpecifier::Create
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
Definition: NestedNameSpecifier.cpp:59
clang::ASTContext::getQualifiedType
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2112
clang::NestedNameSpecifier::Identifier
@ Identifier
An identifier, stored as an IdentifierInfo*.
Definition: NestedNameSpecifier.h:81
clang::TypeName::getFullyQualifiedTemplateArgument
static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx, TemplateArgument &Arg, bool WithGlobalNsPrefix)
Definition: QualTypeNames.cpp:94
clang::NestedNameSpecifier::Super
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
Definition: NestedNameSpecifier.h:101
clang::QualType::getLocalQualifiers
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition: Type.h:6654
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1389
llvm::SmallVector
Definition: LLVM.h:38
clang::NestedNameSpecifier::NamespaceAlias
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
Definition: NestedNameSpecifier.h:87
clang::ASTContext::getTemplateSpecializationType
QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
Definition: ASTContext.cpp:4985
clang::QualType::getQualifiers
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:6662
clang::TypeName::createNestedNameSpecifierForScopeOf
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.
Definition: QualTypeNames.cpp:266
clang::UsingType
Definition: Type.h:4502
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::TypeDecl::getTypeForDecl
const Type * getTypeForDecl() const
Definition: Decl.h:3257
clang::TemplateName::getAsTemplateDecl
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Definition: TemplateName.cpp:146
clang::QualifiedTemplateName::getQualifier
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
Definition: TemplateName.h:460
clang::NestedNameSpecifier
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Definition: NestedNameSpecifier.h:50
clang::Qualifiers
The collection of all-type qualifiers we support.
Definition: Type.h:147
clang::TypeName::createNestedNameSpecifier
static NestedNameSpecifier * createNestedNameSpecifier(const ASTContext &Ctx, const NamespaceDecl *Namesp, bool WithGlobalNsPrefix)
Create a NestedNameSpecifier for Namesp and its enclosing scopes.
Definition: QualTypeNames.cpp:341
clang::UsingShadowDecl
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3222
clang::QualType::getAsString
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1088
clang::TagType
Definition: Type.h:4792
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
clang::TypeName::createOuterNNS
static NestedNameSpecifier * createOuterNNS(const ASTContext &Ctx, const Decl *D, bool FullyQualify, bool WithGlobalNsPrefix)
Definition: QualTypeNames.cpp:188
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1565
clang::ASTContext::getQualifiedTemplateName
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
Definition: ASTContext.cpp:9195
clang::NestedNameSpecifier::Namespace
@ Namespace
A namespace, stored as a NamespaceDecl*.
Definition: NestedNameSpecifier.h:84
clang::TemplateArgument::getKind
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:244
DeclTemplate.h
clang::TypeName::getFullyQualifiedName
std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx, const PrintingPolicy &Policy, bool WithGlobalNsPrefix=false)
Get the fully qualified name for a type.
Definition: QualTypeNames.cpp:481
clang::Scope
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7386
clang::ASTContext::getRValueReferenceType
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
Definition: ASTContext.cpp:3505
clang::TemplateArgument
Represents a template argument.
Definition: TemplateBase.h:61
clang::RISCV::Policy
Policy
Definition: RISCVVIntrinsicUtils.h:96
clang::DeclContext::isTranslationUnit
bool isTranslationUnit() const
Definition: DeclBase.h:1998
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::TagDecl
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3423
clang::TemplateName::getAsUsingShadowDecl
UsingShadowDecl * getAsUsingShadowDecl() const
Retrieve the using shadow declaration through which the underlying template declaration is introduced...
Definition: TemplateName.cpp:209
clang::TypeDecl
Represents a declaration of a type.
Definition: Decl.h:3233
clang::NestedNameSpecifier::Global
@ Global
The global specifier '::'. There is no stored value.
Definition: NestedNameSpecifier.h:97
clang::Type::getAsCXXRecordDecl
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1760
clang::QualifiedTemplateName::hasTemplateKeyword
bool hasTemplateKeyword() const
Whether the template name was prefixed by the "template" keyword.
Definition: TemplateName.h:464
QualTypeNames.h
clang::NestedNameSpecifier::TypeSpecWithTemplate
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
Definition: NestedNameSpecifier.h:94
clang::ETK_None
@ ETK_None
No keyword precedes the qualified type name.
Definition: Type.h:5573
clang::TemplateName::getAsQualifiedTemplateName
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Definition: TemplateName.cpp:201
clang::TypeName::getFullyQualifiedNestedNameSpecifier
static NestedNameSpecifier * getFullyQualifiedNestedNameSpecifier(const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix)
Return a fully qualified version of this name specifier.
Definition: QualTypeNames.cpp:213
clang::DeclContext::getRedeclContext
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1829
clang::ast_matchers::decl
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Definition: ASTMatchersInternal.cpp:734
clang::ClassTemplateDecl
Declaration of a class template.
Definition: DeclTemplate.h:2273
clang::TemplateName
Represents a C++ template name within the type system.
Definition: TemplateName.h:201
clang::TemplateDecl
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:408
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::QualifiedTemplateName
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:432
clang::TemplateArgumentList
A template argument list.
Definition: DeclTemplate.h:238
clang::ASTContext::getElaboratedType
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl=nullptr) const
Definition: ASTContext.cpp:5065
clang::ASTContext::getLValueReferenceType
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Definition: ASTContext.cpp:3465
DeclarationName.h
clang::DeclaratorContext::TypeName
@ TypeName
clang::TemplateArgument::Type
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
clang
Definition: CalledOnceCheck.h:17
clang::TemplateArgument::Template
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:86
clang::TemplateArgument::getAsTemplate
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:292
clang::TypeName::getFullyQualifiedTemplateType
static const Type * getFullyQualifiedTemplateType(const ASTContext &Ctx, const Type *TypePtr, bool WithGlobalNsPrefix)
Definition: QualTypeNames.cpp:120
clang::TypeName::getFullyQualifiedType
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...
Definition: QualTypeNames.cpp:378
clang::TypeName::getFullyQualifiedTemplateName
static bool getFullyQualifiedTemplateName(const ASTContext &Ctx, TemplateName &TName, bool WithGlobalNsPrefix)
Definition: QualTypeNames.cpp:56
GlobalDecl.h
clang::QualType::getTypePtr
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6622
clang::NestedNameSpecifier::GlobalSpecifier
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.
Definition: NestedNameSpecifier.cpp:126
clang::ASTContext::getPointerType
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Definition: ASTContext.cpp:3341
clang::NestedNameSpecifier::TypeSpec
@ TypeSpec
A type, stored as a Type*.
Definition: NestedNameSpecifier.h:90
Mangle.h
clang::TemplateArgumentList::size
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:297
clang::NamespaceDecl
Represent a C++ namespace.
Definition: Decl.h:542
clang::QualType::hasLocalQualifiers
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
Definition: Type.h:842
clang::ASTContext::getMemberPointerType
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
Definition: ASTContext.cpp:3543
clang::TemplateArgument::getAsType
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:268
clang::Decl::getDeclContext
DeclContext * getDeclContext()
Definition: DeclBase.h:441