clang  3.9.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  switch (Prefix.getInt()) {
175  case StoredIdentifier:
176  return nullptr;
177 
178  case StoredDecl:
179  return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
180 
181  case StoredTypeSpec:
182  case StoredTypeSpecWithTemplate:
183  return getAsType()->getAsCXXRecordDecl();
184  }
185 
186  llvm_unreachable("Invalid NNS Kind!");
187 }
188 
189 /// \brief Whether this nested name specifier refers to a dependent
190 /// type or not.
192  switch (getKind()) {
193  case Identifier:
194  // Identifier specifiers always represent dependent types
195  return true;
196 
197  case Namespace:
198  case NamespaceAlias:
199  case Global:
200  return false;
201 
202  case Super: {
203  CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
204  for (const auto &Base : RD->bases())
205  if (Base.getType()->isDependentType())
206  return true;
207 
208  return false;
209  }
210 
211  case TypeSpec:
213  return getAsType()->isDependentType();
214  }
215 
216  llvm_unreachable("Invalid NNS Kind!");
217 }
218 
219 /// \brief Whether this nested name specifier refers to a dependent
220 /// type or not.
222  switch (getKind()) {
223  case Identifier:
224  // Identifier specifiers always represent dependent types
225  return true;
226 
227  case Namespace:
228  case NamespaceAlias:
229  case Global:
230  case Super:
231  return false;
232 
233  case TypeSpec:
236  }
237 
238  llvm_unreachable("Invalid NNS Kind!");
239 }
240 
242  switch (getKind()) {
243  case Identifier:
245 
246  case Namespace:
247  case NamespaceAlias:
248  case Global:
249  case Super:
250  return false;
251 
252  case TypeSpec:
255  }
256 
257  llvm_unreachable("Invalid NNS Kind!");
258 }
259 
260 /// \brief Print this nested name specifier to the given output
261 /// stream.
262 void
264  const PrintingPolicy &Policy) const {
265  if (getPrefix())
266  getPrefix()->print(OS, Policy);
267 
268  switch (getKind()) {
269  case Identifier:
270  OS << getAsIdentifier()->getName();
271  break;
272 
273  case Namespace:
274  if (getAsNamespace()->isAnonymousNamespace())
275  return;
276 
277  OS << getAsNamespace()->getName();
278  break;
279 
280  case NamespaceAlias:
281  OS << getAsNamespaceAlias()->getName();
282  break;
283 
284  case Global:
285  break;
286 
287  case Super:
288  OS << "__super";
289  break;
290 
292  OS << "template ";
293  // Fall through to print the type.
294 
295  case TypeSpec: {
296  const Type *T = getAsType();
297 
298  PrintingPolicy InnerPolicy(Policy);
299  InnerPolicy.SuppressScope = true;
300 
301  // Nested-name-specifiers are intended to contain minimally-qualified
302  // types. An actual ElaboratedType will not occur, since we'll store
303  // just the type that is referred to in the nested-name-specifier (e.g.,
304  // a TypedefType, TagType, etc.). However, when we are dealing with
305  // dependent template-id types (e.g., Outer<T>::template Inner<U>),
306  // the type requires its own nested-name-specifier for uniqueness, so we
307  // suppress that nested-name-specifier during printing.
308  assert(!isa<ElaboratedType>(T) &&
309  "Elaborated type in nested-name-specifier");
310  if (const TemplateSpecializationType *SpecType
311  = dyn_cast<TemplateSpecializationType>(T)) {
312  // Print the template name without its corresponding
313  // nested-name-specifier.
314  SpecType->getTemplateName().print(OS, InnerPolicy, true);
315 
316  // Print the template argument list.
318  OS, SpecType->template_arguments(), InnerPolicy);
319  } else {
320  // Print the type normally
321  QualType(T, 0).print(OS, InnerPolicy);
322  }
323  break;
324  }
325  }
326 
327  OS << "::";
328 }
329 
330 void NestedNameSpecifier::dump(const LangOptions &LO) const {
331  print(llvm::errs(), PrintingPolicy(LO));
332 }
333 
334 LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const {
335  LangOptions LO;
336  print(llvm::errs(), PrintingPolicy(LO));
337 }
338 
339 unsigned
340 NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
341  assert(Qualifier && "Expected a non-NULL qualifier");
342 
343  // Location of the trailing '::'.
344  unsigned Length = sizeof(unsigned);
345 
346  switch (Qualifier->getKind()) {
348  // Nothing more to add.
349  break;
350 
355  // The location of the identifier or namespace name.
356  Length += sizeof(unsigned);
357  break;
358 
361  // The "void*" that points at the TypeLoc data.
362  // Note: the 'template' keyword is part of the TypeLoc.
363  Length += sizeof(void *);
364  break;
365  }
366 
367  return Length;
368 }
369 
370 unsigned
372  unsigned Length = 0;
373  for (; Qualifier; Qualifier = Qualifier->getPrefix())
374  Length += getLocalDataLength(Qualifier);
375  return Length;
376 }
377 
378 namespace {
379  /// \brief Load a (possibly unaligned) source location from a given address
380  /// and offset.
381  SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
382  unsigned Raw;
383  memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
385  }
386 
387  /// \brief Load a (possibly unaligned) pointer from a given address and
388  /// offset.
389  void *LoadPointer(void *Data, unsigned Offset) {
390  void *Result;
391  memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
392  return Result;
393  }
394 }
395 
397  if (!Qualifier)
398  return SourceRange();
399 
400  NestedNameSpecifierLoc First = *this;
401  while (NestedNameSpecifierLoc Prefix = First.getPrefix())
402  First = Prefix;
403 
404  return SourceRange(First.getLocalSourceRange().getBegin(),
406 }
407 
409  if (!Qualifier)
410  return SourceRange();
411 
412  unsigned Offset = getDataLength(Qualifier->getPrefix());
413  switch (Qualifier->getKind()) {
415  return LoadSourceLocation(Data, Offset);
416 
421  return SourceRange(LoadSourceLocation(Data, Offset),
422  LoadSourceLocation(Data, Offset + sizeof(unsigned)));
423 
426  // The "void*" that points at the TypeLoc data.
427  // Note: the 'template' keyword is part of the TypeLoc.
428  void *TypeData = LoadPointer(Data, Offset);
429  TypeLoc TL(Qualifier->getAsType(), TypeData);
430  return SourceRange(TL.getBeginLoc(),
431  LoadSourceLocation(Data, Offset + sizeof(void*)));
432  }
433  }
434 
435  llvm_unreachable("Invalid NNS Kind!");
436 }
437 
439  assert((Qualifier->getKind() == NestedNameSpecifier::TypeSpec ||
441  "Nested-name-specifier location is not a type");
442 
443  // The "void*" that points at the TypeLoc data.
444  unsigned Offset = getDataLength(Qualifier->getPrefix());
445  void *TypeData = LoadPointer(Data, Offset);
446  return TypeLoc(Qualifier->getAsType(), TypeData);
447 }
448 
449 namespace {
450  void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
451  unsigned &BufferCapacity) {
452  if (Start == End)
453  return;
454 
455  if (BufferSize + (End - Start) > BufferCapacity) {
456  // Reallocate the buffer.
457  unsigned NewCapacity = std::max(
458  (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
459  (unsigned)(BufferSize + (End - Start)));
460  char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
461  if (BufferCapacity) {
462  memcpy(NewBuffer, Buffer, BufferSize);
463  free(Buffer);
464  }
465  Buffer = NewBuffer;
466  BufferCapacity = NewCapacity;
467  }
468 
469  memcpy(Buffer + BufferSize, Start, End - Start);
470  BufferSize += End-Start;
471  }
472 
473  /// \brief Save a source location to the given buffer.
474  void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
475  unsigned &BufferSize, unsigned &BufferCapacity) {
476  unsigned Raw = Loc.getRawEncoding();
477  Append(reinterpret_cast<char *>(&Raw),
478  reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
479  Buffer, BufferSize, BufferCapacity);
480  }
481 
482  /// \brief Save a pointer to the given buffer.
483  void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
484  unsigned &BufferCapacity) {
485  Append(reinterpret_cast<char *>(&Ptr),
486  reinterpret_cast<char *>(&Ptr) + sizeof(void *),
487  Buffer, BufferSize, BufferCapacity);
488  }
489 }
490 
493  : Representation(Other.Representation), Buffer(nullptr),
494  BufferSize(0), BufferCapacity(0)
495 {
496  if (!Other.Buffer)
497  return;
498 
499  if (Other.BufferCapacity == 0) {
500  // Shallow copy is okay.
501  Buffer = Other.Buffer;
502  BufferSize = Other.BufferSize;
503  return;
504  }
505 
506  // Deep copy
507  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
508  BufferCapacity);
509 }
510 
514  Representation = Other.Representation;
515 
516  if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
517  // Re-use our storage.
518  BufferSize = Other.BufferSize;
519  memcpy(Buffer, Other.Buffer, BufferSize);
520  return *this;
521  }
522 
523  // Free our storage, if we have any.
524  if (BufferCapacity) {
525  free(Buffer);
526  BufferCapacity = 0;
527  }
528 
529  if (!Other.Buffer) {
530  // Empty.
531  Buffer = nullptr;
532  BufferSize = 0;
533  return *this;
534  }
535 
536  if (Other.BufferCapacity == 0) {
537  // Shallow copy is okay.
538  Buffer = Other.Buffer;
539  BufferSize = Other.BufferSize;
540  return *this;
541  }
542 
543  // Deep copy.
544  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
545  BufferCapacity);
546  return *this;
547 }
548 
550  SourceLocation TemplateKWLoc,
551  TypeLoc TL,
552  SourceLocation ColonColonLoc) {
553  Representation = NestedNameSpecifier::Create(Context, Representation,
554  TemplateKWLoc.isValid(),
555  TL.getTypePtr());
556 
557  // Push source-location info into the buffer.
558  SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
559  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
560 }
561 
563  IdentifierInfo *Identifier,
565  SourceLocation ColonColonLoc) {
566  Representation = NestedNameSpecifier::Create(Context, Representation,
567  Identifier);
568 
569  // Push source-location info into the buffer.
570  SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
571  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
572 }
573 
575  NamespaceDecl *Namespace,
576  SourceLocation NamespaceLoc,
577  SourceLocation ColonColonLoc) {
578  Representation = NestedNameSpecifier::Create(Context, Representation,
579  Namespace);
580 
581  // Push source-location info into the buffer.
582  SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
583  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
584 }
585 
587  NamespaceAliasDecl *Alias,
588  SourceLocation AliasLoc,
589  SourceLocation ColonColonLoc) {
590  Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
591 
592  // Push source-location info into the buffer.
593  SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
594  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
595 }
596 
598  SourceLocation ColonColonLoc) {
599  assert(!Representation && "Already have a nested-name-specifier!?");
600  Representation = NestedNameSpecifier::GlobalSpecifier(Context);
601 
602  // Push source-location info into the buffer.
603  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
604 }
605 
607  CXXRecordDecl *RD,
608  SourceLocation SuperLoc,
609  SourceLocation ColonColonLoc) {
610  Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
611 
612  // Push source-location info into the buffer.
613  SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
614  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
615 }
616 
618  NestedNameSpecifier *Qualifier,
619  SourceRange R) {
620  Representation = Qualifier;
621 
622  // Construct bogus (but well-formed) source information for the
623  // nested-name-specifier.
624  BufferSize = 0;
626  for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
627  Stack.push_back(NNS);
628  while (!Stack.empty()) {
629  NestedNameSpecifier *NNS = Stack.pop_back_val();
630  switch (NNS->getKind()) {
634  SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
635  break;
636 
639  TypeSourceInfo *TSInfo
640  = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
641  R.getBegin());
642  SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
643  BufferCapacity);
644  break;
645  }
646 
649  break;
650  }
651 
652  // Save the location of the '::'.
653  SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
654  Buffer, BufferSize, BufferCapacity);
655  }
656 }
657 
659  if (BufferCapacity)
660  free(Buffer);
661 
662  if (!Other) {
663  Representation = nullptr;
664  BufferSize = 0;
665  return;
666  }
667 
668  // Rather than copying the data (which is wasteful), "adopt" the
669  // pointer (which points into the ASTContext) but set the capacity to zero to
670  // indicate that we don't own it.
671  Representation = Other.getNestedNameSpecifier();
672  Buffer = static_cast<char *>(Other.getOpaqueData());
673  BufferSize = Other.getDataLength();
674  BufferCapacity = 0;
675 }
676 
679  if (!Representation)
680  return NestedNameSpecifierLoc();
681 
682  // If we adopted our data pointer from elsewhere in the AST context, there's
683  // no need to copy the memory.
684  if (BufferCapacity == 0)
685  return NestedNameSpecifierLoc(Representation, Buffer);
686 
687  // FIXME: After copying the source-location information, should we free
688  // our (temporary) buffer and adopt the ASTContext-allocated memory?
689  // Doing so would optimize repeated calls to getWithLocInContext().
690  void *Mem = Context.Allocate(BufferSize, llvm::alignOf<void *>());
691  memcpy(Mem, Buffer, BufferSize);
692  return NestedNameSpecifierLoc(Representation, Mem);
693 }
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:237
unsigned Length
A (possibly-)qualified type.
Definition: Type.h:598
base_class_range bases()
Definition: DeclCXX.h:718
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:1780
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.
The base class of the type hierarchy.
Definition: Type.h:1281
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:471
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
A container of type source information.
Definition: Decl.h:62
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:38
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:1553
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:92
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.
bool isInstantiationDependent() const
Whether this nested name specifier involves a template parameter.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:934
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
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*.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1774
Wraps an identifier and optional source location for the identifier.
Definition: AttributeList.h:72
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.
const std::string ID
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
static void PrintTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, bool SkipBrackets=false)
Print a template argument list, including the '<' and '>' enclosing the template arguments...
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1528
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
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:263
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:568
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:213
Represents a C++ namespace alias.
Definition: DeclCXX.h:2718
The global specifier '::'. There is no stored value.
TemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon, QualType Aliased)
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.