clang  6.0.0svn
QualTypeNames.cpp
Go to the documentation of this file.
1 //===------- QualTypeNames.cpp - Generate Complete QualType Names ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 //===----------------------------------------------------------------------===//
6 //
7 // This file is distributed under the University of Illinois Open Source
8 // License. See LICENSE.TXT for details.
9 //
10 //===----------------------------------------------------------------------===//
11 
12 #include "clang/AST/DeclTemplate.h"
14 #include "clang/AST/GlobalDecl.h"
15 #include "clang/AST/Mangle.h"
17 
18 #include <stdio.h>
19 #include <memory>
20 
21 namespace clang {
22 
23 namespace TypeName {
24 
25 /// \brief Create a NestedNameSpecifier for Namesp and its enclosing
26 /// scopes.
27 ///
28 /// \param[in] Ctx - the AST Context to be used.
29 /// \param[in] Namesp - the NamespaceDecl for which a NestedNameSpecifier
30 /// is requested.
31 /// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
32 /// specifier "::" should be prepended or not.
33 static NestedNameSpecifier *createNestedNameSpecifier(
34  const ASTContext &Ctx,
35  const NamespaceDecl *Namesp,
36  bool WithGlobalNsPrefix);
37 
38 /// \brief Create a NestedNameSpecifier for TagDecl and its enclosing
39 /// scopes.
40 ///
41 /// \param[in] Ctx - the AST Context to be used.
42 /// \param[in] TD - the TagDecl for which a NestedNameSpecifier is
43 /// requested.
44 /// \param[in] FullyQualify - Convert all template arguments into fully
45 /// qualified names.
46 /// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
47 /// specifier "::" should be prepended or not.
48 static NestedNameSpecifier *createNestedNameSpecifier(
49  const ASTContext &Ctx, const TypeDecl *TD,
50  bool FullyQualify, bool WithGlobalNsPrefix);
51 
52 static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
53  const ASTContext &Ctx, const Decl *decl,
54  bool FullyQualified, bool WithGlobalNsPrefix);
55 
56 static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
57  const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix);
58 
60  TemplateName &TName,
61  bool WithGlobalNsPrefix) {
62  bool Changed = false;
63  NestedNameSpecifier *NNS = nullptr;
64 
65  TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
66  // ArgTDecl won't be NULL because we asserted that this isn't a
67  // dependent context very early in the call chain.
68  assert(ArgTDecl != nullptr);
70 
71  if (QTName && !QTName->hasTemplateKeyword()) {
72  NNS = QTName->getQualifier();
74  Ctx, NNS, WithGlobalNsPrefix);
75  if (QNNS != NNS) {
76  Changed = true;
77  NNS = QNNS;
78  } else {
79  NNS = nullptr;
80  }
81  } else {
83  Ctx, ArgTDecl, true, WithGlobalNsPrefix);
84  }
85  if (NNS) {
86  TName = Ctx.getQualifiedTemplateName(NNS,
87  /*TemplateKeyword=*/false, ArgTDecl);
88  Changed = true;
89  }
90  return Changed;
91 }
92 
94  TemplateArgument &Arg,
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 Type *TypePtr,
121  bool WithGlobalNsPrefix) {
122  // DependentTemplateTypes exist within template declarations and
123  // definitions. Therefore we shouldn't encounter them at the end of
124  // a translation unit. If we do, the caller has made an error.
125  assert(!isa<DependentTemplateSpecializationType>(TypePtr));
126  // In case of template specializations, iterate over the arguments
127  // and fully qualify them as well.
128  if (const auto *TST = dyn_cast<const TemplateSpecializationType>(TypePtr)) {
129  bool MightHaveChanged = false;
131  for (TemplateSpecializationType::iterator I = TST->begin(), E = TST->end();
132  I != E; ++I) {
133  // Cheap to copy and potentially modified by
134  // getFullyQualifedTemplateArgument.
135  TemplateArgument Arg(*I);
136  MightHaveChanged |= getFullyQualifiedTemplateArgument(
137  Ctx, Arg, WithGlobalNsPrefix);
138  FQArgs.push_back(Arg);
139  }
140 
141  // If a fully qualified arg is different from the unqualified arg,
142  // allocate new type in the AST.
143  if (MightHaveChanged) {
145  TST->getTemplateName(), FQArgs,
146  TST->getCanonicalTypeInternal());
147  // getTemplateSpecializationType returns a fully qualified
148  // version of the specialization itself, so no need to qualify
149  // it.
150  return QT.getTypePtr();
151  }
152  } else if (const auto *TSTRecord = dyn_cast<const RecordType>(TypePtr)) {
153  // We are asked to fully qualify and we have a Record Type,
154  // which can point to a template instantiation with no sugar in any of
155  // its template argument, however we still need to fully qualify them.
156 
157  if (const auto *TSTDecl =
158  dyn_cast<ClassTemplateSpecializationDecl>(TSTRecord->getDecl())) {
159  const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
160 
161  bool MightHaveChanged = false;
163  for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
164  // cheap to copy and potentially modified by
165  // getFullyQualifedTemplateArgument
166  TemplateArgument Arg(TemplateArgs[I]);
167  MightHaveChanged |= getFullyQualifiedTemplateArgument(
168  Ctx, Arg, WithGlobalNsPrefix);
169  FQArgs.push_back(Arg);
170  }
171 
172  // If a fully qualified arg is different from the unqualified arg,
173  // allocate new type in the AST.
174  if (MightHaveChanged) {
175  TemplateName TN(TSTDecl->getSpecializedTemplate());
177  TN, FQArgs,
178  TSTRecord->getCanonicalTypeInternal());
179  // getTemplateSpecializationType returns a fully qualified
180  // version of the specialization itself, so no need to qualify
181  // it.
182  return QT.getTypePtr();
183  }
184  }
185  }
186  return TypePtr;
187 }
188 
189 static NestedNameSpecifier *createOuterNNS(const ASTContext &Ctx, const Decl *D,
190  bool FullyQualify,
191  bool WithGlobalNsPrefix) {
192  const DeclContext *DC = D->getDeclContext();
193  if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
194  while (NS && NS->isInline()) {
195  // Ignore inline namespace;
196  NS = dyn_cast<NamespaceDecl>(NS->getDeclContext());
197  }
198  if (NS->getDeclName()) {
199  return createNestedNameSpecifier(Ctx, NS, WithGlobalNsPrefix);
200  }
201  return nullptr; // no starting '::', no anonymous
202  } else if (const auto *TD = dyn_cast<TagDecl>(DC)) {
203  return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
204  } else if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC)) {
206  Ctx, TDD, FullyQualify, WithGlobalNsPrefix);
207  } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
209  }
210  return nullptr; // no starting '::' if |WithGlobalNsPrefix| is false
211 }
212 
213 /// \brief Return a fully qualified version of this name specifier.
215  const ASTContext &Ctx, NestedNameSpecifier *Scope,
216  bool WithGlobalNsPrefix) {
217  switch (Scope->getKind()) {
219  // Already fully qualified
220  return Scope;
223  Ctx, Scope->getAsNamespace(), WithGlobalNsPrefix);
225  // Namespace aliases are only valid for the duration of the
226  // scope where they were introduced, and therefore are often
227  // invalid at the end of the TU. So use the namespace name more
228  // likely to be valid at the end of the TU.
230  Ctx,
232  WithGlobalNsPrefix);
234  // A function or some other construct that makes it un-namable
235  // at the end of the TU. Skip the current component of the name,
236  // but use the name of it's prefix.
238  Ctx, Scope->getPrefix(), WithGlobalNsPrefix);
242  const Type *Type = Scope->getAsType();
243  // Find decl context.
244  const TagDecl *TD = nullptr;
245  if (const TagType *TagDeclType = Type->getAs<TagType>()) {
246  TD = TagDeclType->getDecl();
247  } else {
248  TD = Type->getAsCXXRecordDecl();
249  }
250  if (TD) {
252  true /*FullyQualified*/,
253  WithGlobalNsPrefix);
254  } else if (const auto *TDD = dyn_cast<TypedefType>(Type)) {
255  return TypeName::createNestedNameSpecifier(Ctx, TDD->getDecl(),
256  true /*FullyQualified*/,
257  WithGlobalNsPrefix);
258  }
259  return Scope;
260  }
261  }
262  llvm_unreachable("bad NNS kind");
263 }
264 
265 /// \brief Create a nested name specifier for the declaring context of
266 /// the type.
268  const ASTContext &Ctx, const Decl *Decl,
269  bool FullyQualified, bool WithGlobalNsPrefix) {
270  assert(Decl);
271 
272  const DeclContext *DC = Decl->getDeclContext()->getRedeclContext();
273  const auto *Outer = dyn_cast_or_null<NamedDecl>(DC);
274  const auto *OuterNS = dyn_cast_or_null<NamespaceDecl>(DC);
275  if (Outer && !(OuterNS && OuterNS->isAnonymousNamespace())) {
276  if (const auto *CxxDecl = dyn_cast<CXXRecordDecl>(DC)) {
277  if (ClassTemplateDecl *ClassTempl =
278  CxxDecl->getDescribedClassTemplate()) {
279  // We are in the case of a type(def) that was declared in a
280  // class template but is *not* type dependent. In clang, it
281  // gets attached to the class template declaration rather than
282  // any specific class template instantiation. This result in
283  // 'odd' fully qualified typename:
284  //
285  // vector<_Tp,_Alloc>::size_type
286  //
287  // Make the situation is 'useable' but looking a bit odd by
288  // picking a random instance as the declaring context.
289  if (ClassTempl->spec_begin() != ClassTempl->spec_end()) {
290  Decl = *(ClassTempl->spec_begin());
291  Outer = dyn_cast<NamedDecl>(Decl);
292  OuterNS = dyn_cast<NamespaceDecl>(Decl);
293  }
294  }
295  }
296 
297  if (OuterNS) {
298  return createNestedNameSpecifier(Ctx, OuterNS, WithGlobalNsPrefix);
299  } else if (const auto *TD = dyn_cast<TagDecl>(Outer)) {
301  Ctx, TD, FullyQualified, WithGlobalNsPrefix);
302  } else if (dyn_cast<TranslationUnitDecl>(Outer)) {
303  // Context is the TU. Nothing needs to be done.
304  return nullptr;
305  } else {
306  // Decl's context was neither the TU, a namespace, nor a
307  // TagDecl, which means it is a type local to a scope, and not
308  // accessible at the end of the TU.
309  return nullptr;
310  }
311  } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
313  }
314  return nullptr;
315 }
316 
317 /// \brief Create a nested name specifier for the declaring context of
318 /// the type.
320  const ASTContext &Ctx, const Type *TypePtr,
321  bool FullyQualified, bool WithGlobalNsPrefix) {
322  if (!TypePtr) return nullptr;
323 
324  Decl *Decl = nullptr;
325  // There are probably other cases ...
326  if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
327  Decl = TDT->getDecl();
328  } else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
329  Decl = TagDeclType->getDecl();
330  } else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
331  Decl = TST->getTemplateName().getAsTemplateDecl();
332  } else {
333  Decl = TypePtr->getAsCXXRecordDecl();
334  }
335 
336  if (!Decl) return nullptr;
337 
339  Ctx, Decl, FullyQualified, WithGlobalNsPrefix);
340 }
341 
343  const NamespaceDecl *Namespace,
344  bool WithGlobalNsPrefix) {
345  while (Namespace && Namespace->isInline()) {
346  // Ignore inline namespace;
347  Namespace = dyn_cast<NamespaceDecl>(Namespace->getDeclContext());
348  }
349  if (!Namespace) return nullptr;
350 
351  bool FullyQualified = true; // doesn't matter, DeclContexts are namespaces
353  Ctx,
354  createOuterNNS(Ctx, Namespace, FullyQualified, WithGlobalNsPrefix),
355  Namespace);
356 }
357 
359  const TypeDecl *TD,
360  bool FullyQualify,
361  bool WithGlobalNsPrefix) {
363  Ctx,
364  createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
365  false /*No TemplateKeyword*/,
366  TD->getTypeForDecl());
367 }
368 
369 /// \brief Return the fully qualified type, including fully-qualified
370 /// versions of any template parameters.
372  bool WithGlobalNsPrefix) {
373  // In case of myType* we need to strip the pointer first, fully
374  // qualify and attach the pointer once again.
375  if (isa<PointerType>(QT.getTypePtr())) {
376  // Get the qualifiers.
377  Qualifiers Quals = QT.getQualifiers();
378  QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
379  QT = Ctx.getPointerType(QT);
380  // Add back the qualifiers.
381  QT = Ctx.getQualifiedType(QT, Quals);
382  return QT;
383  }
384 
385  // In case of myType& we need to strip the reference first, fully
386  // qualify and attach the reference once again.
387  if (isa<ReferenceType>(QT.getTypePtr())) {
388  // Get the qualifiers.
389  bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
390  Qualifiers Quals = QT.getQualifiers();
391  QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
392  // Add the r- or l-value reference type back to the fully
393  // qualified one.
394  if (IsLValueRefTy)
395  QT = Ctx.getLValueReferenceType(QT);
396  else
397  QT = Ctx.getRValueReferenceType(QT);
398  // Add back the qualifiers.
399  QT = Ctx.getQualifiedType(QT, Quals);
400  return QT;
401  }
402 
403  // Remove the part of the type related to the type being a template
404  // parameter (we won't report it as part of the 'type name' and it
405  // is actually make the code below to be more complex (to handle
406  // those)
407  while (isa<SubstTemplateTypeParmType>(QT.getTypePtr())) {
408  // Get the qualifiers.
409  Qualifiers Quals = QT.getQualifiers();
410 
411  QT = dyn_cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();
412 
413  // Add back the qualifiers.
414  QT = Ctx.getQualifiedType(QT, Quals);
415  }
416 
417  NestedNameSpecifier *Prefix = nullptr;
418  // Local qualifiers are attached to the QualType outside of the
419  // elaborated type. Retrieve them before descending into the
420  // elaborated type.
421  Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
422  QT = QualType(QT.getTypePtr(), 0);
424  if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
425  QT = ETypeInput->getNamedType();
426  assert(!QT.hasLocalQualifiers());
427  Keyword = ETypeInput->getKeyword();
428  }
429  // Create a nested name specifier if needed.
431  true /*FullyQualified*/,
432  WithGlobalNsPrefix);
433 
434  // In case of template specializations iterate over the arguments and
435  // fully qualify them as well.
436  if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
437  isa<const RecordType>(QT.getTypePtr())) {
438  // We are asked to fully qualify and we have a Record Type (which
439  // may point to a template specialization) or Template
440  // Specialization Type. We need to fully qualify their arguments.
441 
442  const Type *TypePtr = getFullyQualifiedTemplateType(
443  Ctx, QT.getTypePtr(), WithGlobalNsPrefix);
444  QT = QualType(TypePtr, 0);
445  }
446  if (Prefix || Keyword != ETK_None) {
447  QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
448  }
449  QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
450  return QT;
451 }
452 
454  const ASTContext &Ctx,
455  bool WithGlobalNsPrefix) {
456  PrintingPolicy Policy(Ctx.getPrintingPolicy());
457  Policy.SuppressScope = false;
458  Policy.AnonymousTagLocations = false;
459  Policy.PolishForDeclaration = true;
460  Policy.SuppressUnwrittenScope = true;
461  QualType FQQT = getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
462  return FQQT.getAsString(Policy);
463 }
464 
465 } // end namespace TypeName
466 } // end namespace clang
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.
bool hasTemplateKeyword() const
Whether the template name was prefixed by the "template" keyword.
Definition: TemplateName.h:392
A (possibly-)qualified type.
Definition: Type.h:653
static bool getFullyQualifiedTemplateName(const ASTContext &Ctx, TemplateName &TName, bool WithGlobalNsPrefix)
static NestedNameSpecifier * createNestedNameSpecifier(const ASTContext &Ctx, const NamespaceDecl *Namesp, bool WithGlobalNsPrefix)
Create a NestedNameSpecifier for Namesp and its enclosing scopes.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:456
Microsoft&#39;s &#39;__super&#39; specifier, stored as a CXXRecordDecl* of the class it appeared in...
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:270
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:1880
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
const Type * getTypeForDecl() const
Definition: Decl.h:2778
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Defines the C++ template declaration subclasses.
The base class of the type hierarchy.
Definition: Type.h:1353
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:506
An identifier, stored as an IdentifierInfo*.
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6307
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
NamespaceDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this namespace.
Definition: Decl.h:598
A namespace, stored as a NamespaceDecl*.
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
Represents the result of substituting a type for a template type parameter.
Definition: Type.h:4258
The collection of all-type qualifiers we support.
Definition: Type.h:152
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:149
bool isInline() const
Returns true if this is an inline namespace declaration.
Definition: Decl.h:567
NamespaceDecl * getNamespace()
Retrieve the namespace declaration aliased by this directive.
Definition: DeclCXX.h:3020
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType) const
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition: Type.h:5739
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:635
TypeDecl - Represents a declaration of a type.
Definition: Decl.h:2754
bool SuppressScope
Suppresses printing of scope specifiers.
std::string getAsString() const
Definition: Type.h:979
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5720
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1590
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: Type.h:4707
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
static const Type * getFullyQualifiedTemplateType(const ASTContext &Ctx, const Type *TypePtr, bool WithGlobalNsPrefix)
DeclContext * getDeclContext()
Definition: DeclBase.h:425
Represents a C++ template name within the type system.
Definition: TemplateName.h:178
A namespace alias, stored as a NamespaceAliasDecl*.
NestedNameSpecifier * getQualifier() const
Return the nested name specifier that qualifies this name.
Definition: TemplateName.h:388
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2938
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
Represents a template argument.
Definition: TemplateBase.h:51
QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:366
Dataflow Directional Tag Classes.
static NestedNameSpecifier * createOuterNNS(const ASTContext &Ctx, const Decl *D, bool FullyQualify, bool WithGlobalNsPrefix)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1252
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...
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
bool hasLocalQualifiers() const
Determine whether this particular QualType instance has any qualifiers, without looking through any t...
Definition: Type.h:756
A type that was preceded by the &#39;template&#39; keyword, stored as a Type*.
std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx, bool WithGlobalNsPrefix=false)
Get the fully qualified name for a type.
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1648
The template argument is a type.
Definition: TemplateBase.h:60
static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx, TemplateArgument &Arg, bool WithGlobalNsPrefix)
A template argument list.
Definition: DeclTemplate.h:210
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:235
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type...
The template argument is a template name that was provided for a template template parameter...
Definition: TemplateBase.h:76
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:5747
Declaration of a class template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:257
static NestedNameSpecifier * getFullyQualifiedNestedNameSpecifier(const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix)
Return a fully qualified version of this name specifier.
NamedDecl - This represents a decl with a name.
Definition: Decl.h:245
bool isTranslationUnit() const
Definition: DeclBase.h:1401
No keyword precedes the qualified type name.
Definition: Type.h:4728
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:281
The global specifier &#39;::&#39;. There is no stored value.
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateDecl *Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.