clang  3.8.0
NestedNameSpecifier.cpp
Go to the documentation of this file.
1 //===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the NestedNameSpecifier class, which represents
11 // a C++ nested-name-specifier.
12 //
13 //===----------------------------------------------------------------------===//
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/Type.h"
20 #include "clang/AST/TypeLoc.h"
21 #include "llvm/Support/AlignOf.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <cassert>
24 
25 using namespace clang;
26 
28 NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
29  const NestedNameSpecifier &Mockup) {
30  llvm::FoldingSetNodeID ID;
31  Mockup.Profile(ID);
32 
33  void *InsertPos = nullptr;
35  = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
36  if (!NNS) {
37  NNS = new (Context, llvm::alignOf<NestedNameSpecifier>())
38  NestedNameSpecifier(Mockup);
39  Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
40  }
41 
42  return NNS;
43 }
44 
47  NestedNameSpecifier *Prefix, IdentifierInfo *II) {
48  assert(II && "Identifier cannot be NULL");
49  assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
50 
51  NestedNameSpecifier Mockup;
52  Mockup.Prefix.setPointer(Prefix);
53  Mockup.Prefix.setInt(StoredIdentifier);
54  Mockup.Specifier = II;
55  return FindOrInsert(Context, Mockup);
56 }
57 
60  NestedNameSpecifier *Prefix,
61  const NamespaceDecl *NS) {
62  assert(NS && "Namespace cannot be NULL");
63  assert((!Prefix ||
64  (Prefix->getAsType() == nullptr &&
65  Prefix->getAsIdentifier() == nullptr)) &&
66  "Broken nested name specifier");
67  NestedNameSpecifier Mockup;
68  Mockup.Prefix.setPointer(Prefix);
69  Mockup.Prefix.setInt(StoredDecl);
70  Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
71  return FindOrInsert(Context, Mockup);
72 }
73 
76  NestedNameSpecifier *Prefix,
77  NamespaceAliasDecl *Alias) {
78  assert(Alias && "Namespace alias cannot be NULL");
79  assert((!Prefix ||
80  (Prefix->getAsType() == nullptr &&
81  Prefix->getAsIdentifier() == nullptr)) &&
82  "Broken nested name specifier");
83  NestedNameSpecifier Mockup;
84  Mockup.Prefix.setPointer(Prefix);
85  Mockup.Prefix.setInt(StoredDecl);
86  Mockup.Specifier = Alias;
87  return FindOrInsert(Context, Mockup);
88 }
89 
92  NestedNameSpecifier *Prefix,
93  bool Template, const Type *T) {
94  assert(T && "Type cannot be NULL");
95  NestedNameSpecifier Mockup;
96  Mockup.Prefix.setPointer(Prefix);
97  Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
98  Mockup.Specifier = const_cast<Type*>(T);
99  return FindOrInsert(Context, Mockup);
100 }
101 
104  assert(II && "Identifier cannot be NULL");
105  NestedNameSpecifier Mockup;
106  Mockup.Prefix.setPointer(nullptr);
107  Mockup.Prefix.setInt(StoredIdentifier);
108  Mockup.Specifier = II;
109  return FindOrInsert(Context, Mockup);
110 }
111 
114  if (!Context.GlobalNestedNameSpecifier)
115  Context.GlobalNestedNameSpecifier =
116  new (Context, llvm::alignOf<NestedNameSpecifier>())
118  return Context.GlobalNestedNameSpecifier;
119 }
120 
123  CXXRecordDecl *RD) {
124  NestedNameSpecifier Mockup;
125  Mockup.Prefix.setPointer(nullptr);
126  Mockup.Prefix.setInt(StoredDecl);
127  Mockup.Specifier = RD;
128  return FindOrInsert(Context, Mockup);
129 }
130 
132  if (!Specifier)
133  return Global;
134 
135  switch (Prefix.getInt()) {
136  case StoredIdentifier:
137  return Identifier;
138 
139  case StoredDecl: {
140  NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
141  if (isa<CXXRecordDecl>(ND))
142  return Super;
143  return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
144  }
145 
146  case StoredTypeSpec:
147  return TypeSpec;
148 
149  case StoredTypeSpecWithTemplate:
150  return TypeSpecWithTemplate;
151  }
152 
153  llvm_unreachable("Invalid NNS Kind!");
154 }
155 
156 /// \brief Retrieve the namespace stored in this nested name specifier.
158  if (Prefix.getInt() == StoredDecl)
159  return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
160 
161  return nullptr;
162 }
163 
164 /// \brief Retrieve the namespace alias stored in this nested name specifier.
166  if (Prefix.getInt() == StoredDecl)
167  return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
168 
169  return nullptr;
170 }
171 
172 /// \brief Retrieve the record declaration stored in this nested name specifier.
174  if (Prefix.getInt() == StoredDecl)
175  return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
176 
177  return nullptr;
178 }
179 
180 /// \brief Whether this nested name specifier refers to a dependent
181 /// type or not.
183  switch (getKind()) {
184  case Identifier:
185  // Identifier specifiers always represent dependent types
186  return true;
187 
188  case Namespace:
189  case NamespaceAlias:
190  case Global:
191  return false;
192 
193  case Super: {
194  CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
195  for (const auto &Base : RD->bases())
196  if (Base.getType()->isDependentType())
197  return true;
198 
199  return false;
200  }
201 
202  case TypeSpec:
204  return getAsType()->isDependentType();
205  }
206 
207  llvm_unreachable("Invalid NNS Kind!");
208 }
209 
210 /// \brief Whether this nested name specifier refers to a dependent
211 /// type or not.
213  switch (getKind()) {
214  case Identifier:
215  // Identifier specifiers always represent dependent types
216  return true;
217 
218  case Namespace:
219  case NamespaceAlias:
220  case Global:
221  case Super:
222  return false;
223 
224  case TypeSpec:
227  }
228 
229  llvm_unreachable("Invalid NNS Kind!");
230 }
231 
233  switch (getKind()) {
234  case Identifier:
236 
237  case Namespace:
238  case NamespaceAlias:
239  case Global:
240  case Super:
241  return false;
242 
243  case TypeSpec:
246  }
247 
248  llvm_unreachable("Invalid NNS Kind!");
249 }
250 
251 /// \brief Print this nested name specifier to the given output
252 /// stream.
253 void
255  const PrintingPolicy &Policy) const {
256  if (getPrefix())
257  getPrefix()->print(OS, Policy);
258 
259  switch (getKind()) {
260  case Identifier:
261  OS << getAsIdentifier()->getName();
262  break;
263 
264  case Namespace:
265  if (getAsNamespace()->isAnonymousNamespace())
266  return;
267 
268  OS << getAsNamespace()->getName();
269  break;
270 
271  case NamespaceAlias:
272  OS << getAsNamespaceAlias()->getName();
273  break;
274 
275  case Global:
276  break;
277 
278  case Super:
279  OS << "__super";
280  break;
281 
283  OS << "template ";
284  // Fall through to print the type.
285 
286  case TypeSpec: {
287  const Type *T = getAsType();
288 
289  PrintingPolicy InnerPolicy(Policy);
290  InnerPolicy.SuppressScope = true;
291 
292  // Nested-name-specifiers are intended to contain minimally-qualified
293  // types. An actual ElaboratedType will not occur, since we'll store
294  // just the type that is referred to in the nested-name-specifier (e.g.,
295  // a TypedefType, TagType, etc.). However, when we are dealing with
296  // dependent template-id types (e.g., Outer<T>::template Inner<U>),
297  // the type requires its own nested-name-specifier for uniqueness, so we
298  // suppress that nested-name-specifier during printing.
299  assert(!isa<ElaboratedType>(T) &&
300  "Elaborated type in nested-name-specifier");
301  if (const TemplateSpecializationType *SpecType
302  = dyn_cast<TemplateSpecializationType>(T)) {
303  // Print the template name without its corresponding
304  // nested-name-specifier.
305  SpecType->getTemplateName().print(OS, InnerPolicy, true);
306 
307  // Print the template argument list.
309  OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy);
310  } else {
311  // Print the type normally
312  QualType(T, 0).print(OS, InnerPolicy);
313  }
314  break;
315  }
316  }
317 
318  OS << "::";
319 }
320 
321 void NestedNameSpecifier::dump(const LangOptions &LO) const {
322  print(llvm::errs(), PrintingPolicy(LO));
323 }
324 
326  LangOptions LO;
327  print(llvm::errs(), PrintingPolicy(LO));
328 }
329 
330 unsigned
331 NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
332  assert(Qualifier && "Expected a non-NULL qualifier");
333 
334  // Location of the trailing '::'.
335  unsigned Length = sizeof(unsigned);
336 
337  switch (Qualifier->getKind()) {
339  // Nothing more to add.
340  break;
341 
346  // The location of the identifier or namespace name.
347  Length += sizeof(unsigned);
348  break;
349 
352  // The "void*" that points at the TypeLoc data.
353  // Note: the 'template' keyword is part of the TypeLoc.
354  Length += sizeof(void *);
355  break;
356  }
357 
358  return Length;
359 }
360 
361 unsigned
363  unsigned Length = 0;
364  for (; Qualifier; Qualifier = Qualifier->getPrefix())
365  Length += getLocalDataLength(Qualifier);
366  return Length;
367 }
368 
369 namespace {
370  /// \brief Load a (possibly unaligned) source location from a given address
371  /// and offset.
372  SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
373  unsigned Raw;
374  memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
376  }
377 
378  /// \brief Load a (possibly unaligned) pointer from a given address and
379  /// offset.
380  void *LoadPointer(void *Data, unsigned Offset) {
381  void *Result;
382  memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
383  return Result;
384  }
385 }
386 
388  if (!Qualifier)
389  return SourceRange();
390 
391  NestedNameSpecifierLoc First = *this;
392  while (NestedNameSpecifierLoc Prefix = First.getPrefix())
393  First = Prefix;
394 
395  return SourceRange(First.getLocalSourceRange().getBegin(),
397 }
398 
400  if (!Qualifier)
401  return SourceRange();
402 
403  unsigned Offset = getDataLength(Qualifier->getPrefix());
404  switch (Qualifier->getKind()) {
406  return LoadSourceLocation(Data, Offset);
407 
412  return SourceRange(LoadSourceLocation(Data, Offset),
413  LoadSourceLocation(Data, Offset + sizeof(unsigned)));
414 
417  // The "void*" that points at the TypeLoc data.
418  // Note: the 'template' keyword is part of the TypeLoc.
419  void *TypeData = LoadPointer(Data, Offset);
420  TypeLoc TL(Qualifier->getAsType(), TypeData);
421  return SourceRange(TL.getBeginLoc(),
422  LoadSourceLocation(Data, Offset + sizeof(void*)));
423  }
424  }
425 
426  llvm_unreachable("Invalid NNS Kind!");
427 }
428 
430  assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
432  "Nested-name-specifier location is not a type");
433 
434  // The "void*" that points at the TypeLoc data.
435  unsigned Offset = getDataLength(Qualifier->getPrefix());
436  void *TypeData = LoadPointer(Data, Offset);
437  return TypeLoc(Qualifier->getAsType(), TypeData);
438 }
439 
440 namespace {
441  void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
442  unsigned &BufferCapacity) {
443  if (Start == End)
444  return;
445 
446  if (BufferSize + (End - Start) > BufferCapacity) {
447  // Reallocate the buffer.
448  unsigned NewCapacity = std::max(
449  (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
450  (unsigned)(BufferSize + (End - Start)));
451  char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
452  if (BufferCapacity) {
453  memcpy(NewBuffer, Buffer, BufferSize);
454  free(Buffer);
455  }
456  Buffer = NewBuffer;
457  BufferCapacity = NewCapacity;
458  }
459 
460  memcpy(Buffer + BufferSize, Start, End - Start);
461  BufferSize += End-Start;
462  }
463 
464  /// \brief Save a source location to the given buffer.
465  void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
466  unsigned &BufferSize, unsigned &BufferCapacity) {
467  unsigned Raw = Loc.getRawEncoding();
468  Append(reinterpret_cast<char *>(&Raw),
469  reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
470  Buffer, BufferSize, BufferCapacity);
471  }
472 
473  /// \brief Save a pointer to the given buffer.
474  void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
475  unsigned &BufferCapacity) {
476  Append(reinterpret_cast<char *>(&Ptr),
477  reinterpret_cast<char *>(&Ptr) + sizeof(void *),
478  Buffer, BufferSize, BufferCapacity);
479  }
480 }
481 
484  : Representation(Other.Representation), Buffer(nullptr),
485  BufferSize(0), BufferCapacity(0)
486 {
487  if (!Other.Buffer)
488  return;
489 
490  if (Other.BufferCapacity == 0) {
491  // Shallow copy is okay.
492  Buffer = Other.Buffer;
493  BufferSize = Other.BufferSize;
494  return;
495  }
496 
497  // Deep copy
498  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
499  BufferCapacity);
500 }
501 
505  Representation = Other.Representation;
506 
507  if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
508  // Re-use our storage.
509  BufferSize = Other.BufferSize;
510  memcpy(Buffer, Other.Buffer, BufferSize);
511  return *this;
512  }
513 
514  // Free our storage, if we have any.
515  if (BufferCapacity) {
516  free(Buffer);
517  BufferCapacity = 0;
518  }
519 
520  if (!Other.Buffer) {
521  // Empty.
522  Buffer = nullptr;
523  BufferSize = 0;
524  return *this;
525  }
526 
527  if (Other.BufferCapacity == 0) {
528  // Shallow copy is okay.
529  Buffer = Other.Buffer;
530  BufferSize = Other.BufferSize;
531  return *this;
532  }
533 
534  // Deep copy.
535  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
536  BufferCapacity);
537  return *this;
538 }
539 
541  SourceLocation TemplateKWLoc,
542  TypeLoc TL,
543  SourceLocation ColonColonLoc) {
544  Representation = NestedNameSpecifier::Create(Context, Representation,
545  TemplateKWLoc.isValid(),
546  TL.getTypePtr());
547 
548  // Push source-location info into the buffer.
549  SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
550  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
551 }
552 
554  IdentifierInfo *Identifier,
556  SourceLocation ColonColonLoc) {
557  Representation = NestedNameSpecifier::Create(Context, Representation,
558  Identifier);
559 
560  // Push source-location info into the buffer.
561  SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
562  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
563 }
564 
566  NamespaceDecl *Namespace,
567  SourceLocation NamespaceLoc,
568  SourceLocation ColonColonLoc) {
569  Representation = NestedNameSpecifier::Create(Context, Representation,
570  Namespace);
571 
572  // Push source-location info into the buffer.
573  SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
574  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
575 }
576 
578  NamespaceAliasDecl *Alias,
579  SourceLocation AliasLoc,
580  SourceLocation ColonColonLoc) {
581  Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
582 
583  // Push source-location info into the buffer.
584  SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
585  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
586 }
587 
589  SourceLocation ColonColonLoc) {
590  assert(!Representation && "Already have a nested-name-specifier!?");
591  Representation = NestedNameSpecifier::GlobalSpecifier(Context);
592 
593  // Push source-location info into the buffer.
594  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
595 }
596 
598  CXXRecordDecl *RD,
599  SourceLocation SuperLoc,
600  SourceLocation ColonColonLoc) {
601  Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
602 
603  // Push source-location info into the buffer.
604  SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
605  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
606 }
607 
609  NestedNameSpecifier *Qualifier,
610  SourceRange R) {
611  Representation = Qualifier;
612 
613  // Construct bogus (but well-formed) source information for the
614  // nested-name-specifier.
615  BufferSize = 0;
617  for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
618  Stack.push_back(NNS);
619  while (!Stack.empty()) {
620  NestedNameSpecifier *NNS = Stack.pop_back_val();
621  switch (NNS->getKind()) {
625  SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
626  break;
627 
630  TypeSourceInfo *TSInfo
631  = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
632  R.getBegin());
633  SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
634  BufferCapacity);
635  break;
636  }
637 
640  break;
641  }
642 
643  // Save the location of the '::'.
644  SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
645  Buffer, BufferSize, BufferCapacity);
646  }
647 }
648 
650  if (BufferCapacity)
651  free(Buffer);
652 
653  if (!Other) {
654  Representation = nullptr;
655  BufferSize = 0;
656  return;
657  }
658 
659  // Rather than copying the data (which is wasteful), "adopt" the
660  // pointer (which points into the ASTContext) but set the capacity to zero to
661  // indicate that we don't own it.
662  Representation = Other.getNestedNameSpecifier();
663  Buffer = static_cast<char *>(Other.getOpaqueData());
664  BufferSize = Other.getDataLength();
665  BufferCapacity = 0;
666 }
667 
670  if (!Representation)
671  return NestedNameSpecifierLoc();
672 
673  // If we adopted our data pointer from elsewhere in the AST context, there's
674  // no need to copy the memory.
675  if (BufferCapacity == 0)
676  return NestedNameSpecifierLoc(Representation, Buffer);
677 
678  // FIXME: After copying the source-location information, should we free
679  // our (temporary) buffer and adopt the ASTContext-allocated memory?
680  // Doing so would optimize repeated calls to getWithLocInContext().
681  void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
682  memcpy(Mem, Buffer, BufferSize);
683  return NestedNameSpecifierLoc(Representation, Mem);
684 }
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:169
unsigned Length
A (possibly-)qualified type.
Definition: Type.h:575
base_class_range bases()
Definition: DeclCXX.h:713
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1757
C Language Family Type Representation.
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in...
NestedNameSpecifierLoc getPrefix() const
Return the prefix of this nested-name-specifier.
TemplateSpecializationType(TemplateName T, const TemplateArgument *Args, unsigned NumArgs, QualType Canon, QualType Aliased)
Definition: Type.cpp:3118
The base class of the type hierarchy.
Definition: Type.h:1249
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
std::unique_ptr< llvm::MemoryBuffer > Buffer
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:402
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
A container of type source information.
Definition: Decl.h:61
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
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.
NestedNameSpecifierLocBuilder & operator=(const NestedNameSpecifierLocBuilder &Other)
A namespace, stored as a NamespaceDecl*.
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:35
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1521
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:40
SourceRange getLocalSourceRange() const
Retrieve the source range covering just the last part of this nested-name-specifier, not including the prefix.
unsigned getDataLength() const
Determines the data length for the entire nested-name-specifier.
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:91
A C++ nested-name-specifier augmented with source location information.
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
const Type * getTypePtr() const
Definition: TypeLoc.h:111
uint32_t Offset
Definition: CacheTokens.cpp:44
bool SuppressScope
Suppresses printing of scope specifiers.
Definition: PrettyPrinter.h:90
bool isInstantiationDependent() const
Whether this nested name specifier involves a template parameter.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
static void PrintTemplateArgumentList(raw_ostream &OS, const TemplateArgument *Args, unsigned NumArgs, const PrintingPolicy &Policy, bool SkipBrackets=false)
Print a template argument list, including the '<' and '>' enclosing the template arguments...
Class that aids in the construction of nested-name-specifiers along with source-location information ...
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
ASTContext * Context
std::vector< bool > & Stack
const SmallVectorImpl< AnnotatedLine * >::const_iterator End
ID
Defines the set of possible language-specific address spaces.
Definition: AddressSpaces.h:27
static NestedNameSpecifier * SuperSpecifier(const ASTContext &Context, CXXRecordDecl *RD)
Returns the nested name specifier representing the __super scope for the given CXXRecordDecl.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
StringRef getName() const
Return the actual identifier string.
void * getOpaqueData() const
Get the pointer where source information is stored.
Definition: TypeLoc.h:116
Defines the clang::TypeLoc interface and its subclasses.
A namespace alias, stored as a NamespaceAliasDecl*.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine()) const
Definition: Type.h:911
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1751
Wraps an identifier and optional source location for the identifier.
Definition: AttributeList.h:50
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
The result type of a method or function.
SpecifierKind
The kind of specifier that completes this nested name specifier.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:215
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into '__super' nested-name-specifier.
Encodes a location in the source.
void Profile(llvm::FoldingSetNodeID &ID) const
bool isValid() const
Return true if this is a valid SourceLocation object.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc)
Turn this (empty) nested-name-specifier into the global nested-name-specifier '::'.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
SourceLocation getBegin() const
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
Print this nested name specifier to the given output stream.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
A type that was preceded by the 'template' keyword, stored as a Type*.
void * getOpaqueData() const
Retrieve the opaque pointer that refers to source-location data.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Represents a C++ struct/union/class.
Definition: DeclCXX.h:285
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:560
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, SourceLocation ColonColonLoc)
Extend the current nested-name-specifier by another nested-name-specifier component of the form 'type...
A trivial tuple used to represent a source range.
NamedDecl - This represents a decl with a name.
Definition: Decl.h:145
Represents a C++ namespace alias.
Definition: DeclCXX.h:2649
The global specifier '::'. There is no stored value.
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.