27 #include "llvm/ADT/FoldingSet.h" 28 #include "llvm/ADT/SmallVector.h" 29 #include "llvm/Support/Casting.h" 30 #include "llvm/Support/Compiler.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include "llvm/Support/raw_ostream.h" 38 using namespace clang;
41 NestedNameSpecifier::FindOrInsert(
const ASTContext &Context,
43 llvm::FoldingSetNodeID
ID;
46 void *InsertPos =
nullptr;
48 = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
52 Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
61 assert(II &&
"Identifier cannot be NULL");
62 assert((!Prefix || Prefix->
isDependent()) &&
"Prefix must be dependent");
65 Mockup.Prefix.setPointer(Prefix);
66 Mockup.Prefix.setInt(StoredIdentifier);
67 Mockup.Specifier = II;
68 return FindOrInsert(Context, Mockup);
75 assert(NS &&
"Namespace cannot be NULL");
79 "Broken nested name specifier");
81 Mockup.Prefix.setPointer(Prefix);
82 Mockup.Prefix.setInt(StoredDecl);
84 return FindOrInsert(Context, Mockup);
91 assert(Alias &&
"Namespace alias cannot be NULL");
95 "Broken nested name specifier");
97 Mockup.Prefix.setPointer(Prefix);
98 Mockup.Prefix.setInt(StoredDecl);
99 Mockup.Specifier = Alias;
100 return FindOrInsert(Context, Mockup);
106 bool Template,
const Type *T) {
107 assert(T &&
"Type cannot be NULL");
109 Mockup.Prefix.setPointer(Prefix);
110 Mockup.Prefix.setInt(Template? StoredTypeSpecWithTemplate : StoredTypeSpec);
111 Mockup.Specifier =
const_cast<Type*
>(T);
112 return FindOrInsert(Context, Mockup);
117 assert(II &&
"Identifier cannot be NULL");
119 Mockup.Prefix.setPointer(
nullptr);
120 Mockup.Prefix.setInt(StoredIdentifier);
121 Mockup.Specifier = II;
122 return FindOrInsert(Context, Mockup);
127 if (!Context.GlobalNestedNameSpecifier)
128 Context.GlobalNestedNameSpecifier =
130 return Context.GlobalNestedNameSpecifier;
137 Mockup.Prefix.setPointer(
nullptr);
138 Mockup.Prefix.setInt(StoredDecl);
139 Mockup.Specifier = RD;
140 return FindOrInsert(Context, Mockup);
147 switch (Prefix.getInt()) {
148 case StoredIdentifier:
153 if (isa<CXXRecordDecl>(ND))
161 case StoredTypeSpecWithTemplate:
165 llvm_unreachable(
"Invalid NNS Kind!");
170 if (Prefix.getInt() == StoredDecl)
171 return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
178 if (Prefix.getInt() == StoredDecl)
179 return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
186 switch (Prefix.getInt()) {
187 case StoredIdentifier:
194 case StoredTypeSpecWithTemplate:
198 llvm_unreachable(
"Invalid NNS Kind!");
217 if (
Base.getType()->isDependentType())
228 llvm_unreachable(
"Invalid NNS Kind!");
250 llvm_unreachable(
"Invalid NNS Kind!");
269 llvm_unreachable(
"Invalid NNS Kind!");
275 bool ResolveTemplateArguments)
const {
310 if (ResolveTemplateArguments && Record) {
312 Record->printName(OS);
329 assert(!isa<ElaboratedType>(T) &&
330 "Elaborated type in nested-name-specifier");
332 = dyn_cast<TemplateSpecializationType>(T)) {
335 SpecType->getTemplateName().print(OS, InnerPolicy,
true);
352 dump(llvm::errs(), LO);
369 assert(Qualifier &&
"Expected a non-NULL qualifier");
372 unsigned Length =
sizeof(unsigned);
374 switch (Qualifier->
getKind()) {
384 Length +=
sizeof(unsigned);
391 Length +=
sizeof(
void *);
401 for (; Qualifier; Qualifier = Qualifier->
getPrefix())
402 Length += getLocalDataLength(Qualifier);
410 memcpy(&Raw, static_cast<char *>(Data) + Offset,
sizeof(
unsigned));
418 memcpy(&Result, static_cast<char *>(Data) + Offset,
sizeof(
void*));
431 getLocalSourceRange().getEnd());
439 switch (Qualifier->
getKind()) {
461 llvm_unreachable(
"Invalid NNS Kind!");
475 static void Append(
char *Start,
char *
End,
char *&Buffer,
unsigned &BufferSize,
476 unsigned &BufferCapacity) {
480 if (BufferSize + (End - Start) > BufferCapacity) {
483 (
unsigned)(BufferCapacity ? BufferCapacity * 2 :
sizeof(
void *) * 2),
484 (
unsigned)(BufferSize + (End - Start)));
485 char *NewBuffer =
static_cast<char *
>(llvm::safe_malloc(NewCapacity));
486 if (BufferCapacity) {
487 memcpy(NewBuffer, Buffer, BufferSize);
491 BufferCapacity = NewCapacity;
494 memcpy(Buffer + BufferSize, Start, End - Start);
495 BufferSize += End-Start;
500 unsigned &BufferSize,
unsigned &BufferCapacity) {
502 Append(reinterpret_cast<char *>(&Raw),
503 reinterpret_cast<char *>(&Raw) +
sizeof(
unsigned),
504 Buffer, BufferSize, BufferCapacity);
508 static void SavePointer(
void *Ptr,
char *&Buffer,
unsigned &BufferSize,
509 unsigned &BufferCapacity) {
510 Append(reinterpret_cast<char *>(&Ptr),
511 reinterpret_cast<char *>(&Ptr) +
sizeof(
void *),
512 Buffer, BufferSize, BufferCapacity);
517 : Representation(Other.Representation) {
521 if (Other.BufferCapacity == 0) {
523 Buffer = Other.Buffer;
524 BufferSize = Other.BufferSize;
529 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
536 Representation = Other.Representation;
538 if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
540 BufferSize = Other.BufferSize;
541 memcpy(Buffer, Other.Buffer, BufferSize);
546 if (BufferCapacity) {
558 if (Other.BufferCapacity == 0) {
560 Buffer = Other.Buffer;
561 BufferSize = Other.BufferSize;
567 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
622 assert(!Representation &&
"Already have a nested-name-specifier!?");
643 Representation = Qualifier;
650 Stack.push_back(NNS);
651 while (!Stack.empty()) {
677 Buffer, BufferSize, BufferCapacity);
686 Representation =
nullptr;
696 BufferSize = Other.getDataLength();
707 if (BufferCapacity == 0)
713 void *Mem = Context.
Allocate(BufferSize,
alignof(
void *));
714 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.
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.
__DEVICE__ int max(int __a, int __b)
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.