21 #include "llvm/Support/AlignOf.h"
22 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
30 llvm::FoldingSetNodeID
ID;
33 void *InsertPos =
nullptr;
35 = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
37 NNS =
new (
Context, llvm::alignOf<NestedNameSpecifier>())
39 Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
48 assert(II &&
"Identifier cannot be NULL");
49 assert((!Prefix || Prefix->
isDependent()) &&
"Prefix must be dependent");
52 Mockup.Prefix.setPointer(Prefix);
53 Mockup.Prefix.setInt(StoredIdentifier);
54 Mockup.Specifier = II;
55 return FindOrInsert(Context, Mockup);
62 assert(NS &&
"Namespace cannot be NULL");
66 "Broken nested name specifier");
68 Mockup.Prefix.setPointer(Prefix);
69 Mockup.Prefix.setInt(StoredDecl);
71 return FindOrInsert(Context, Mockup);
78 assert(Alias &&
"Namespace alias cannot be NULL");
82 "Broken nested name specifier");
84 Mockup.Prefix.setPointer(Prefix);
85 Mockup.Prefix.setInt(StoredDecl);
86 Mockup.Specifier = Alias;
87 return FindOrInsert(Context, Mockup);
93 bool Template,
const Type *T) {
94 assert(T &&
"Type cannot be NULL");
96 Mockup.Prefix.setPointer(Prefix);
97 Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
98 Mockup.Specifier =
const_cast<Type*
>(T);
99 return FindOrInsert(Context, Mockup);
104 assert(II &&
"Identifier cannot be NULL");
106 Mockup.Prefix.setPointer(
nullptr);
107 Mockup.Prefix.setInt(StoredIdentifier);
108 Mockup.Specifier = II;
109 return FindOrInsert(Context, Mockup);
114 if (!Context.GlobalNestedNameSpecifier)
115 Context.GlobalNestedNameSpecifier =
116 new (
Context, llvm::alignOf<NestedNameSpecifier>())
118 return Context.GlobalNestedNameSpecifier;
125 Mockup.Prefix.setPointer(
nullptr);
126 Mockup.Prefix.setInt(StoredDecl);
127 Mockup.Specifier = RD;
128 return FindOrInsert(Context, Mockup);
135 switch (Prefix.getInt()) {
136 case StoredIdentifier:
141 if (isa<CXXRecordDecl>(ND))
149 case StoredTypeSpecWithTemplate:
153 llvm_unreachable(
"Invalid NNS Kind!");
158 if (Prefix.getInt() == StoredDecl)
159 return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
166 if (Prefix.getInt() == StoredDecl)
167 return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
174 if (Prefix.getInt() == StoredDecl)
175 return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
196 if (
Base.getType()->isDependentType())
207 llvm_unreachable(
"Invalid NNS Kind!");
229 llvm_unreachable(
"Invalid NNS Kind!");
248 llvm_unreachable(
"Invalid NNS Kind!");
299 assert(!isa<ElaboratedType>(T) &&
300 "Elaborated type in nested-name-specifier");
302 = dyn_cast<TemplateSpecializationType>(T)) {
305 SpecType->getTemplateName().print(OS, InnerPolicy,
true);
309 OS, SpecType->getArgs(), SpecType->getNumArgs(), InnerPolicy);
327 assert(Qualifier &&
"Expected a non-NULL qualifier");
332 switch (Qualifier->
getKind()) {
349 Length +=
sizeof(
void *);
359 for (; Qualifier; Qualifier = Qualifier->
getPrefix())
360 Length += getLocalDataLength(Qualifier);
369 memcpy(&Raw, static_cast<char *>(Data) + Offset,
sizeof(
unsigned));
375 void *LoadPointer(
void *Data,
unsigned Offset) {
377 memcpy(&Result, static_cast<char *>(Data) + Offset,
sizeof(
void*));
399 switch (Qualifier->
getKind()) {
401 return LoadSourceLocation(Data, Offset);
407 return SourceRange(LoadSourceLocation(Data, Offset),
408 LoadSourceLocation(Data, Offset +
sizeof(
unsigned)));
414 void *TypeData = LoadPointer(Data, Offset);
417 LoadSourceLocation(Data, Offset +
sizeof(
void*)));
421 llvm_unreachable(
"Invalid NNS Kind!");
427 "Nested-name-specifier location is not a type");
431 void *TypeData = LoadPointer(Data, Offset);
436 void Append(
char *Start,
char *
End,
char *&Buffer,
unsigned &BufferSize,
437 unsigned &BufferCapacity) {
441 if (BufferSize + (End - Start) > BufferCapacity) {
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);
452 BufferCapacity = NewCapacity;
455 memcpy(Buffer + BufferSize, Start, End - Start);
456 BufferSize += End-Start;
461 unsigned &BufferSize,
unsigned &BufferCapacity) {
463 Append(reinterpret_cast<char *>(&Raw),
464 reinterpret_cast<char *>(&Raw) +
sizeof(
unsigned),
465 Buffer, BufferSize, BufferCapacity);
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);
479 : Representation(Other.Representation), Buffer(nullptr),
480 BufferSize(0), BufferCapacity(0)
485 if (Other.BufferCapacity == 0) {
487 Buffer = Other.Buffer;
488 BufferSize = Other.BufferSize;
493 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
500 Representation = Other.Representation;
502 if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
504 BufferSize = Other.BufferSize;
505 memcpy(Buffer, Other.Buffer, BufferSize);
510 if (BufferCapacity) {
522 if (Other.BufferCapacity == 0) {
524 Buffer = Other.Buffer;
525 BufferSize = Other.BufferSize;
530 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
544 SavePointer(TL.
getOpaqueData(), Buffer, BufferSize, BufferCapacity);
545 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
556 SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
557 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
568 SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
569 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
579 SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
580 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
585 assert(!Representation &&
"Already have a nested-name-specifier!?");
589 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
599 SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
600 SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
606 Representation = Qualifier;
613 Stack.push_back(NNS);
614 while (!Stack.empty()) {
620 SaveSourceLocation(R.
getBegin(), Buffer, BufferSize, BufferCapacity);
640 Buffer, BufferSize, BufferCapacity);
649 Representation =
nullptr;
659 BufferSize = Other.getDataLength();
670 if (BufferCapacity == 0)
676 void *Mem = Context.
Allocate(BufferSize, llvm::alignOf<void *>());
677 memcpy(Mem, Buffer, BufferSize);
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
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...
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.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
A container of type source information.
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*.
NestedNameSpecifierLocBuilder()
Describes how types, statements, expressions, and declarations should be printed. ...
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...
Base wrapper for a particular "section" of type source info.
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 ...
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...
const Type * getTypePtr() const
bool SuppressScope
Suppresses printing of scope specifiers.
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...
std::vector< bool > & Stack
ID
Defines the set of possible language-specific address spaces.
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.
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
bool isDependentType() const
Wraps an identifier and optional source location for the identifier.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
The result type of a method or function.
A type, stored as a Type*.
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.
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.
void * Allocate(size_t Size, unsigned Align=8) const
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...
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.
The global specifier '::'. There is no stored value.
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.