clang  3.7.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 
322  print(llvm::errs(), PrintingPolicy(LO));
323 }
324 
325 unsigned
326 NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
327  assert(Qualifier && "Expected a non-NULL qualifier");
328 
329  // Location of the trailing '::'.
330  unsigned Length = sizeof(unsigned);
331 
332  switch (Qualifier->getKind()) {
334  // Nothing more to add.
335  break;
336 
341  // The location of the identifier or namespace name.
342  Length += sizeof(unsigned);
343  break;
344 
347  // The "void*" that points at the TypeLoc data.
348  // Note: the 'template' keyword is part of the TypeLoc.
349  Length += sizeof(void *);
350  break;
351  }
352 
353  return Length;
354 }
355 
356 unsigned
358  unsigned Length = 0;
359  for (; Qualifier; Qualifier = Qualifier->getPrefix())
360  Length += getLocalDataLength(Qualifier);
361  return Length;
362 }
363 
364 namespace {
365  /// \brief Load a (possibly unaligned) source location from a given address
366  /// and offset.
367  SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
368  unsigned Raw;
369  memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
371  }
372 
373  /// \brief Load a (possibly unaligned) pointer from a given address and
374  /// offset.
375  void *LoadPointer(void *Data, unsigned Offset) {
376  void *Result;
377  memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
378  return Result;
379  }
380 }
381 
383  if (!Qualifier)
384  return SourceRange();
385 
386  NestedNameSpecifierLoc First = *this;
387  while (NestedNameSpecifierLoc Prefix = First.getPrefix())
388  First = Prefix;
389 
390  return SourceRange(First.getLocalSourceRange().getBegin(),
392 }
393 
395  if (!Qualifier)
396  return SourceRange();
397 
398  unsigned Offset = getDataLength(Qualifier->getPrefix());
399  switch (Qualifier->getKind()) {
401  return LoadSourceLocation(Data, Offset);
402 
407  return SourceRange(LoadSourceLocation(Data, Offset),
408  LoadSourceLocation(Data, Offset + sizeof(unsigned)));
409 
412  // The "void*" that points at the TypeLoc data.
413  // Note: the 'template' keyword is part of the TypeLoc.
414  void *TypeData = LoadPointer(Data, Offset);
415  TypeLoc TL(Qualifier->getAsType(), TypeData);
416  return SourceRange(TL.getBeginLoc(),
417  LoadSourceLocation(Data, Offset + sizeof(void*)));
418  }
419  }
420 
421  llvm_unreachable("Invalid NNS Kind!");
422 }
423 
425  assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
427  "Nested-name-specifier location is not a type");
428 
429  // The "void*" that points at the TypeLoc data.
430  unsigned Offset = getDataLength(Qualifier->getPrefix());
431  void *TypeData = LoadPointer(Data, Offset);
432  return TypeLoc(Qualifier->getAsType(), TypeData);
433 }
434 
435 namespace {
436  void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
437  unsigned &BufferCapacity) {
438  if (Start == End)
439  return;
440 
441  if (BufferSize + (End - Start) > BufferCapacity) {
442  // Reallocate the buffer.
443  unsigned NewCapacity = std::max(
444  (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
445  (unsigned)(BufferSize + (End - Start)));
446  char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
447  if (BufferCapacity) {
448  memcpy(NewBuffer, Buffer, BufferSize);
449  free(Buffer);
450  }
451  Buffer = NewBuffer;
452  BufferCapacity = NewCapacity;
453  }
454 
455  memcpy(Buffer + BufferSize, Start, End - Start);
456  BufferSize += End-Start;
457  }
458 
459  /// \brief Save a source location to the given buffer.
460  void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
461  unsigned &BufferSize, unsigned &BufferCapacity) {
462  unsigned Raw = Loc.getRawEncoding();
463  Append(reinterpret_cast<char *>(&Raw),
464  reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
465  Buffer, BufferSize, BufferCapacity);
466  }
467 
468  /// \brief Save a pointer to the given buffer.
469  void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
470  unsigned &BufferCapacity) {
471  Append(reinterpret_cast<char *>(&Ptr),
472  reinterpret_cast<char *>(&Ptr) + sizeof(void *),
473  Buffer, BufferSize, BufferCapacity);
474  }
475 }
476 
479  : Representation(Other.Representation), Buffer(nullptr),
480  BufferSize(0), BufferCapacity(0)
481 {
482  if (!Other.Buffer)
483  return;
484 
485  if (Other.BufferCapacity == 0) {
486  // Shallow copy is okay.
487  Buffer = Other.Buffer;
488  BufferSize = Other.BufferSize;
489  return;
490  }
491 
492  // Deep copy
493  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
494  BufferCapacity);
495 }
496 
500  Representation = Other.Representation;
501 
502  if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
503  // Re-use our storage.
504  BufferSize = Other.BufferSize;
505  memcpy(Buffer, Other.Buffer, BufferSize);
506  return *this;
507  }
508 
509  // Free our storage, if we have any.
510  if (BufferCapacity) {
511  free(Buffer);
512  BufferCapacity = 0;
513  }
514 
515  if (!Other.Buffer) {
516  // Empty.
517  Buffer = nullptr;
518  BufferSize = 0;
519  return *this;
520  }
521 
522  if (Other.BufferCapacity == 0) {
523  // Shallow copy is okay.
524  Buffer = Other.Buffer;
525  BufferSize = Other.BufferSize;
526  return *this;
527  }
528 
529  // Deep copy.
530  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
531  BufferCapacity);
532  return *this;
533 }
534 
536  SourceLocation TemplateKWLoc,
537  TypeLoc TL,
538  SourceLocation ColonColonLoc) {
539  Representation = NestedNameSpecifier::Create(Context, Representation,
540  TemplateKWLoc.isValid(),
541  TL.getTypePtr());
542 
543  // Push source-location info into the buffer.
544  SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
545  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
546 }
547 
549  IdentifierInfo *Identifier,
551  SourceLocation ColonColonLoc) {
552  Representation = NestedNameSpecifier::Create(Context, Representation,
553  Identifier);
554 
555  // Push source-location info into the buffer.
556  SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
557  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
558 }
559 
561  NamespaceDecl *Namespace,
562  SourceLocation NamespaceLoc,
563  SourceLocation ColonColonLoc) {
564  Representation = NestedNameSpecifier::Create(Context, Representation,
565  Namespace);
566 
567  // Push source-location info into the buffer.
568  SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
569  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
570 }
571 
573  NamespaceAliasDecl *Alias,
574  SourceLocation AliasLoc,
575  SourceLocation ColonColonLoc) {
576  Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
577 
578  // Push source-location info into the buffer.
579  SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
580  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
581 }
582 
584  SourceLocation ColonColonLoc) {
585  assert(!Representation && "Already have a nested-name-specifier!?");
586  Representation = NestedNameSpecifier::GlobalSpecifier(Context);
587 
588  // Push source-location info into the buffer.
589  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
590 }
591 
593  CXXRecordDecl *RD,
594  SourceLocation SuperLoc,
595  SourceLocation ColonColonLoc) {
596  Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
597 
598  // Push source-location info into the buffer.
599  SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
600  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
601 }
602 
604  NestedNameSpecifier *Qualifier,
605  SourceRange R) {
606  Representation = Qualifier;
607 
608  // Construct bogus (but well-formed) source information for the
609  // nested-name-specifier.
610  BufferSize = 0;
612  for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
613  Stack.push_back(NNS);
614  while (!Stack.empty()) {
615  NestedNameSpecifier *NNS = Stack.pop_back_val();
616  switch (NNS->getKind()) {
620  SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
621  break;
622 
625  TypeSourceInfo *TSInfo
626  = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
627  R.getBegin());
628  SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
629  BufferCapacity);
630  break;
631  }
632 
635  break;
636  }
637 
638  // Save the location of the '::'.
639  SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
640  Buffer, BufferSize, BufferCapacity);
641  }
642 }
643 
645  if (BufferCapacity)
646  free(Buffer);
647 
648  if (!Other) {
649  Representation = nullptr;
650  BufferSize = 0;
651  return;
652  }
653 
654  // Rather than copying the data (which is wasteful), "adopt" the
655  // pointer (which points into the ASTContext) but set the capacity to zero to
656  // indicate that we don't own it.
657  Representation = Other.getNestedNameSpecifier();
658  Buffer = static_cast<char *>(Other.getOpaqueData());
659  BufferSize = Other.getDataLength();
660  BufferCapacity = 0;
661 }
662 
665  if (!Representation)
666  return NestedNameSpecifierLoc();
667 
668  // If we adopted our data pointer from elsewhere in the AST context, there's
669  // no need to copy the memory.
670  if (BufferCapacity == 0)
671  return NestedNameSpecifierLoc(Representation, Buffer);
672 
673  // FIXME: After copying the source-location information, should we free
674  // our (temporary) buffer and adopt the ASTContext-allocated memory?
675  // Doing so would optimize repeated calls to getWithLocInContext().
676  void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
677  memcpy(Mem, Buffer, BufferSize);
678  return NestedNameSpecifierLoc(Representation, Mem);
679 }
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
Definition: Decl.h:168
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:1733
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.
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:400
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
A container of type source information.
Definition: Decl.h:60
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:1506
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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:89
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:43
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...
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:907
bool isDependentType() const
Definition: Type.h:1727
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:208
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. The SourceManager can decode this to get at the full include stack...
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.
void dump(const LangOptions &LO)
Dump the nested name specifier to standard output to aid in debugging.
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:501
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:3941
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...
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...
A trivial tuple used to represent a source range.
Represents a C++ namespace alias.
Definition: DeclCXX.h:2662
The global specifier '::'. There is no stored value.
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.