clang  6.0.0svn
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 =
38  new (Context, alignof(NestedNameSpecifier)) 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, alignof(NestedNameSpecifier)) NestedNameSpecifier();
117  return Context.GlobalNestedNameSpecifier;
118 }
119 
122  CXXRecordDecl *RD) {
123  NestedNameSpecifier Mockup;
124  Mockup.Prefix.setPointer(nullptr);
125  Mockup.Prefix.setInt(StoredDecl);
126  Mockup.Specifier = RD;
127  return FindOrInsert(Context, Mockup);
128 }
129 
131  if (!Specifier)
132  return Global;
133 
134  switch (Prefix.getInt()) {
135  case StoredIdentifier:
136  return Identifier;
137 
138  case StoredDecl: {
139  NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
140  if (isa<CXXRecordDecl>(ND))
141  return Super;
142  return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
143  }
144 
145  case StoredTypeSpec:
146  return TypeSpec;
147 
148  case StoredTypeSpecWithTemplate:
149  return TypeSpecWithTemplate;
150  }
151 
152  llvm_unreachable("Invalid NNS Kind!");
153 }
154 
155 /// \brief Retrieve the namespace stored in this nested name specifier.
157  if (Prefix.getInt() == StoredDecl)
158  return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
159 
160  return nullptr;
161 }
162 
163 /// \brief Retrieve the namespace alias stored in this nested name specifier.
165  if (Prefix.getInt() == StoredDecl)
166  return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
167 
168  return nullptr;
169 }
170 
171 /// \brief Retrieve the record declaration stored in this nested name specifier.
173  switch (Prefix.getInt()) {
174  case StoredIdentifier:
175  return nullptr;
176 
177  case StoredDecl:
178  return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
179 
180  case StoredTypeSpec:
181  case StoredTypeSpecWithTemplate:
182  return getAsType()->getAsCXXRecordDecl();
183  }
184 
185  llvm_unreachable("Invalid NNS Kind!");
186 }
187 
188 /// \brief Whether this nested name specifier refers to a dependent
189 /// type or not.
191  switch (getKind()) {
192  case Identifier:
193  // Identifier specifiers always represent dependent types
194  return true;
195 
196  case Namespace:
197  case NamespaceAlias:
198  case Global:
199  return false;
200 
201  case Super: {
202  CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
203  for (const auto &Base : RD->bases())
204  if (Base.getType()->isDependentType())
205  return true;
206 
207  return false;
208  }
209 
210  case TypeSpec:
212  return getAsType()->isDependentType();
213  }
214 
215  llvm_unreachable("Invalid NNS Kind!");
216 }
217 
218 /// \brief Whether this nested name specifier refers to a dependent
219 /// type or not.
221  switch (getKind()) {
222  case Identifier:
223  // Identifier specifiers always represent dependent types
224  return true;
225 
226  case Namespace:
227  case NamespaceAlias:
228  case Global:
229  case Super:
230  return false;
231 
232  case TypeSpec:
235  }
236 
237  llvm_unreachable("Invalid NNS Kind!");
238 }
239 
241  switch (getKind()) {
242  case Identifier:
244 
245  case Namespace:
246  case NamespaceAlias:
247  case Global:
248  case Super:
249  return false;
250 
251  case TypeSpec:
254  }
255 
256  llvm_unreachable("Invalid NNS Kind!");
257 }
258 
259 /// \brief Print this nested name specifier to the given output
260 /// stream.
261 void
263  const PrintingPolicy &Policy) const {
264  if (getPrefix())
265  getPrefix()->print(OS, Policy);
266 
267  switch (getKind()) {
268  case Identifier:
269  OS << getAsIdentifier()->getName();
270  break;
271 
272  case Namespace:
273  if (getAsNamespace()->isAnonymousNamespace())
274  return;
275 
276  OS << getAsNamespace()->getName();
277  break;
278 
279  case NamespaceAlias:
280  OS << getAsNamespaceAlias()->getName();
281  break;
282 
283  case Global:
284  break;
285 
286  case Super:
287  OS << "__super";
288  break;
289 
291  OS << "template ";
292  // Fall through to print the type.
293  LLVM_FALLTHROUGH;
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(),
405  getLocalSourceRange().getEnd());
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, alignof(void *));
691  memcpy(Mem, Buffer, BufferSize);
692  return NestedNameSpecifierLoc(Representation, Mem);
693 }
Defines the clang::ASTContext interface.
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
A (possibly-)qualified type.
Definition: Type.h:614
base_class_range bases()
Definition: DeclCXX.h:736
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:950
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
C Language Family Type Representation.
Microsoft&#39;s &#39;__super&#39; specifier, stored as a CXXRecordDecl* of the class it appeared in...
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
The base class of the type hierarchy.
Definition: Type.h:1300
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:474
static void PrintTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, bool SkipBrackets=false)
Print a template argument list, including the &#39;<&#39; and &#39;>&#39; enclosing the template arguments.
A container of type source information.
Definition: Decl.h:62
void Profile(llvm::FoldingSetNodeID &ID) const
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
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
const Type * getTypePtr() const
Definition: TypeLoc.h:118
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:40
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:128
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.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
uint32_t Offset
Definition: CacheTokens.cpp:43
SourceRange getLocalSourceRange() const
Retrieve the source range covering just the last part of this nested-name-specifier, not including the prefix.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1572
bool SuppressScope
Suppresses printing of scope specifiers.
Class that aids in the construction of nested-name-specifiers along with source-location information ...
void * getOpaqueData() const
Get the pointer where source information is stored.
Definition: TypeLoc.h:123
bool isInstantiationDependent() const
Whether this nested name specifier involves a template parameter.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1569
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.
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
Print this nested name specifier to the given output stream.
static NestedNameSpecifier * SuperSpecifier(const ASTContext &Context, CXXRecordDecl *RD)
Returns the nested name specifier representing the __super scope for the given CXXRecordDecl.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
SourceLocation End
const FunctionProtoType * T
NestedNameSpecifierLoc getPrefix() const
Return the prefix of this nested-name-specifier.
Defines the clang::TypeLoc interface and its subclasses.
A namespace alias, stored as a NamespaceAliasDecl*.
SourceLocation getEnd() const
Wraps an identifier and optional source location for the identifier.
Definition: AttributeList.h:73
The result type of a method or function.
SpecifierKind
The kind of specifier that completes this nested name specifier.
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into &#39;__super&#39; nested-name-specifier.
Encodes a location in the source.
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 &#39;::&#39;.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1801
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:625
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned getDataLength() const
Determines the data length for the entire nested-name-specifier.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
A type that was preceded by the &#39;template&#39; keyword, stored as a Type*.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:222
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).
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Represents a C++ struct/union/class.
Definition: DeclCXX.h:266
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:237
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1795
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:4351
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 &#39;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:2882
The global specifier &#39;::&#39;. There is no stored value.
SourceLocation getBegin() const
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.