26 #include "llvm/ADT/FoldingSet.h" 27 #include "llvm/ADT/SmallVector.h" 28 #include "llvm/Support/Casting.h" 29 #include "llvm/Support/Compiler.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/raw_ostream.h" 37 using namespace clang;
40 NestedNameSpecifier::FindOrInsert(
const ASTContext &Context,
42 llvm::FoldingSetNodeID
ID;
45 void *InsertPos =
nullptr;
47 = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
51 Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
60 assert(II &&
"Identifier cannot be NULL");
61 assert((!Prefix || Prefix->
isDependent()) &&
"Prefix must be dependent");
64 Mockup.Prefix.setPointer(Prefix);
65 Mockup.Prefix.setInt(StoredIdentifier);
66 Mockup.Specifier = II;
67 return FindOrInsert(Context, Mockup);
74 assert(NS &&
"Namespace cannot be NULL");
78 "Broken nested name specifier");
80 Mockup.Prefix.setPointer(Prefix);
81 Mockup.Prefix.setInt(StoredDecl);
83 return FindOrInsert(Context, Mockup);
90 assert(Alias &&
"Namespace alias cannot be NULL");
94 "Broken nested name specifier");
96 Mockup.Prefix.setPointer(Prefix);
97 Mockup.Prefix.setInt(StoredDecl);
98 Mockup.Specifier = Alias;
99 return FindOrInsert(Context, Mockup);
105 bool Template,
const Type *T) {
106 assert(T &&
"Type cannot be NULL");
108 Mockup.Prefix.setPointer(Prefix);
109 Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
110 Mockup.Specifier =
const_cast<Type*
>(T);
111 return FindOrInsert(Context, Mockup);
116 assert(II &&
"Identifier cannot be NULL");
118 Mockup.Prefix.setPointer(
nullptr);
119 Mockup.Prefix.setInt(StoredIdentifier);
120 Mockup.Specifier = II;
121 return FindOrInsert(Context, Mockup);
126 if (!Context.GlobalNestedNameSpecifier)
127 Context.GlobalNestedNameSpecifier =
129 return Context.GlobalNestedNameSpecifier;
136 Mockup.Prefix.setPointer(
nullptr);
137 Mockup.Prefix.setInt(StoredDecl);
138 Mockup.Specifier = RD;
139 return FindOrInsert(Context, Mockup);
146 switch (Prefix.getInt()) {
147 case StoredIdentifier:
152 if (isa<CXXRecordDecl>(ND))
160 case StoredTypeSpecWithTemplate:
164 llvm_unreachable(
"Invalid NNS Kind!");
169 if (Prefix.getInt() == StoredDecl)
170 return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
177 if (Prefix.getInt() == StoredDecl)
178 return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
185 switch (Prefix.getInt()) {
186 case StoredIdentifier:
193 case StoredTypeSpecWithTemplate:
197 llvm_unreachable(
"Invalid NNS Kind!");
216 if (
Base.getType()->isDependentType())
227 llvm_unreachable(
"Invalid NNS Kind!");
249 llvm_unreachable(
"Invalid NNS Kind!");
268 llvm_unreachable(
"Invalid NNS Kind!");
274 bool ResolveTemplateArguments)
const {
309 if (ResolveTemplateArguments && Record) {
311 Record->printName(OS);
328 assert(!isa<ElaboratedType>(T) &&
329 "Elaborated type in nested-name-specifier");
331 = dyn_cast<TemplateSpecializationType>(T)) {
334 SpecType->getTemplateName().print(OS, InnerPolicy,
true);
351 dump(llvm::errs(), LO);
368 assert(Qualifier &&
"Expected a non-NULL qualifier");
371 unsigned Length =
sizeof(unsigned);
373 switch (Qualifier->
getKind()) {
383 Length +=
sizeof(unsigned);
390 Length +=
sizeof(
void *);
400 for (; Qualifier; Qualifier = Qualifier->
getPrefix())
401 Length += getLocalDataLength(Qualifier);
409 memcpy(&Raw, static_cast<char *>(Data) + Offset,
sizeof(
unsigned));
417 memcpy(&Result, static_cast<char *>(Data) + Offset,
sizeof(
void*));
430 getLocalSourceRange().getEnd());
438 switch (Qualifier->
getKind()) {
460 llvm_unreachable(
"Invalid NNS Kind!");
474 static void Append(
char *Start,
char *
End,
char *&Buffer,
unsigned &BufferSize,
475 unsigned &BufferCapacity) {
479 if (BufferSize + (End - Start) > BufferCapacity) {
482 (
unsigned)(BufferCapacity ? BufferCapacity * 2 :
sizeof(
void *) * 2),
483 (
unsigned)(BufferSize + (End - Start)));
484 char *NewBuffer =
static_cast<char *
>(llvm::safe_malloc(NewCapacity));
485 if (BufferCapacity) {
486 memcpy(NewBuffer, Buffer, BufferSize);
490 BufferCapacity = NewCapacity;
493 memcpy(Buffer + BufferSize, Start, End - Start);
494 BufferSize += End-Start;
499 unsigned &BufferSize,
unsigned &BufferCapacity) {
501 Append(reinterpret_cast<char *>(&Raw),
502 reinterpret_cast<char *>(&Raw) +
sizeof(
unsigned),
503 Buffer, BufferSize, BufferCapacity);
507 static void SavePointer(
void *Ptr,
char *&Buffer,
unsigned &BufferSize,
508 unsigned &BufferCapacity) {
509 Append(reinterpret_cast<char *>(&Ptr),
510 reinterpret_cast<char *>(&Ptr) +
sizeof(
void *),
511 Buffer, BufferSize, BufferCapacity);
516 : Representation(Other.Representation) {
520 if (Other.BufferCapacity == 0) {
522 Buffer = Other.Buffer;
523 BufferSize = Other.BufferSize;
528 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
535 Representation = Other.Representation;
537 if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
539 BufferSize = Other.BufferSize;
540 memcpy(Buffer, Other.Buffer, BufferSize);
545 if (BufferCapacity) {
557 if (Other.BufferCapacity == 0) {
559 Buffer = Other.Buffer;
560 BufferSize = Other.BufferSize;
566 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
621 assert(!Representation &&
"Already have a nested-name-specifier!?");
642 Representation = Qualifier;
649 Stack.push_back(NNS);
650 while (!Stack.empty()) {
676 Buffer, BufferSize, BufferCapacity);
685 Representation =
nullptr;
695 BufferSize = Other.getDataLength();
706 if (BufferCapacity == 0)
712 void *Mem = Context.
Allocate(BufferSize,
alignof(
void *));
713 memcpy(Mem, Buffer, BufferSize);
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.
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.
C Language Family Type Representation.
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in...
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
Defines the C++ template declaration subclasses.
The base class of the type hierarchy.
Represent a C++ namespace.
A container of type source information.
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. ...
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
static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
Base wrapper for a particular "section" of type source info.
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 ...
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.
__DEVICE__ int max(int __a, int __b)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
NestedNameSpecifierLocBuilder()=default
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
static void SaveSourceLocation(SourceLocation Loc, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
Save a source location to the given buffer.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
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...
static SourceLocation LoadSourceLocation(void *Data, unsigned Offset)
Load a (possibly unaligned) source location from a given address and offset.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
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.
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...
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.
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.
Defines the clang::LangOptions interface.
NestedNameSpecifierLoc getPrefix() const
Return the prefix of this nested-name-specifier.
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
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.
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.
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 '__super' nested-name-specifier.
Encodes a location in the source.
unsigned SuppressScope
Suppresses printing of scope specifiers.
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 '::'.
static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
Save a pointer to the given buffer.
static void * LoadPointer(void *Data, unsigned Offset)
Load a (possibly unaligned) pointer from a given address and offset.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
void * Allocate(size_t Size, unsigned Align=8) const
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 'template' keyword, stored as a Type*.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
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).
Defines the clang::SourceLocation class and associated facilities.
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.
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
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...
A trivial tuple used to represent a source range.
This represents a decl that may have a name.
Represents a C++ namespace alias.
The global specifier '::'. There is no stored value.
SourceLocation getBegin() const
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.