Go to the documentation of this file.
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:
191 return dyn_cast<CXXRecordDecl>(
static_cast<NamedDecl *
>(Specifier));
194 case StoredTypeSpecWithTemplate:
198 llvm_unreachable(
"Invalid NNS Kind!");
205 auto F = NestedNameSpecifierDependence::Dependent |
206 NestedNameSpecifierDependence::Instantiation;
221 if (
Base.getType()->isDependentType())
223 return NestedNameSpecifierDependence::Dependent;
231 llvm_unreachable(
"Invalid NNS Kind!");
235 return getDependence() & NestedNameSpecifierDependence::Dependent;
239 return getDependence() & NestedNameSpecifierDependence::Instantiation;
243 return getDependence() & NestedNameSpecifierDependence::UnexpandedPack;
253 bool ResolveTemplateArguments)
const {
288 if (ResolveTemplateArguments && Record) {
290 Record->printName(OS);
292 OS, Record->getTemplateArgs().asArray(), Policy,
293 Record->getSpecializedTemplate()->getTemplateParameters());
308 assert(!isa<ElaboratedType>(T) &&
309 "Elaborated type in nested-name-specifier");
311 = dyn_cast<TemplateSpecializationType>(T)) {
314 SpecType->getTemplateName().print(OS, InnerPolicy,
320 }
else if (
const auto *DepSpecType =
321 dyn_cast<DependentTemplateSpecializationType>(T)) {
324 OS << DepSpecType->getIdentifier()->getName();
340 dump(llvm::errs(), LO);
357 assert(Qualifier &&
"Expected a non-NULL qualifier");
362 switch (Qualifier->getKind()) {
379 Length +=
sizeof(
void *);
390 Length += getLocalDataLength(Qualifier);
398 memcpy(&Raw,
static_cast<char *
>(Data) +
Offset,
sizeof(Raw));
406 memcpy(&Result,
static_cast<char *
>(Data) +
Offset,
sizeof(
void*));
427 switch (Qualifier->getKind()) {
444 TypeLoc TL(Qualifier->getAsType(), TypeData);
450 llvm_unreachable(
"Invalid NNS Kind!");
461 return TypeLoc(Qualifier->getAsType(), TypeData);
464 static void Append(
char *Start,
char *
End,
char *&Buffer,
unsigned &BufferSize,
465 unsigned &BufferCapacity) {
469 if (BufferSize + (
End - Start) > BufferCapacity) {
472 (
unsigned)(BufferCapacity ? BufferCapacity * 2 :
sizeof(
void *) * 2),
473 (
unsigned)(BufferSize + (
End - Start)));
474 if (!BufferCapacity) {
475 char *NewBuffer =
static_cast<char *
>(llvm::safe_malloc(NewCapacity));
477 memcpy(NewBuffer, Buffer, BufferSize);
480 Buffer =
static_cast<char *
>(llvm::safe_realloc(Buffer, NewCapacity));
482 BufferCapacity = NewCapacity;
484 assert(Buffer && Start &&
End &&
End > Start &&
"Illegal memory buffer copy");
485 memcpy(Buffer + BufferSize, Start,
End - Start);
486 BufferSize +=
End - Start;
491 unsigned &BufferSize,
unsigned &BufferCapacity) {
493 Append(
reinterpret_cast<char *
>(&Raw),
494 reinterpret_cast<char *
>(&Raw) +
sizeof(Raw), Buffer, BufferSize,
499 static void SavePointer(
void *Ptr,
char *&Buffer,
unsigned &BufferSize,
500 unsigned &BufferCapacity) {
501 Append(
reinterpret_cast<char *
>(&Ptr),
502 reinterpret_cast<char *
>(&Ptr) +
sizeof(
void *),
503 Buffer, BufferSize, BufferCapacity);
508 : Representation(Other.Representation) {
512 if (Other.BufferCapacity == 0) {
514 Buffer = Other.Buffer;
515 BufferSize = Other.BufferSize;
520 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
527 Representation = Other.Representation;
529 if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
531 BufferSize = Other.BufferSize;
532 memcpy(Buffer, Other.Buffer, BufferSize);
537 if (BufferCapacity) {
549 if (Other.BufferCapacity == 0) {
551 Buffer = Other.Buffer;
552 BufferSize = Other.BufferSize;
558 Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
613 assert(!Representation &&
"Already have a nested-name-specifier!?");
634 Representation = Qualifier;
641 Stack.push_back(NNS);
642 while (!Stack.empty()) {
668 Buffer, BufferSize, BufferCapacity);
677 Representation =
nullptr;
687 BufferSize = Other.getDataLength();
698 if (BufferCapacity == 0)
704 void *Mem = Context.
Allocate(BufferSize,
alignof(
void *));
705 memcpy(Mem, Buffer, BufferSize);
static NestedNameSpecifier * Create(const ASTContext &Context, NestedNameSpecifier *Prefix, IdentifierInfo *II)
Builds a specifier combining a prefix and an identifier.
static void SaveSourceLocation(SourceLocation Loc, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
Save a source location to the given buffer.
__DEVICE__ int max(int __a, int __b)
@ Identifier
An identifier, stored as an IdentifierInfo*.
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
unsigned SuppressScope
Suppresses printing of scope specifiers.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, unsigned &BufferCapacity)
A trivial tuple used to represent a source range.
Represents a C++ namespace alias.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
Encodes a location in the source.
This represents a decl that may have a name.
SourceLocation getBegin() const
bool isInstantiationDependent() const
Whether this nested name specifier involves a template parameter.
A (possibly-)qualified type.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Represents a type template specialization; the template must be a class template, a type alias templa...
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
Describes how types, statements, expressions, and declarations should be printed.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc)
Turn this (empty) nested-name-specifier into the global nested-name-specifier '::'.
void * getOpaqueData() const
Get the pointer where source information is stored.
const Type * getTypePtr() const
The base class of the type hierarchy.
SourceLocation getBeginLoc() const
Get the begin source location.
void * Allocate(size_t Size, unsigned Align=8) const
@ Namespace
A namespace, stored as a NamespaceDecl*.
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
SourceRange getLocalSourceRange() const
Retrieve the source range covering just the last part of this nested-name-specifier,...
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
void Profile(llvm::FoldingSetNodeID &ID) const
constexpr XRayInstrMask None
SourceLocation getEnd() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
NestedNameSpecifierDependence toNestedNameSpecifierDependendence(TypeDependence D)
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
bool containsErrors() const
Whether this nested name specifier contains an error.
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into '__super' nested-name-specifier.
static SourceLocation LoadSourceLocation(void *Data, unsigned Offset)
Load a (possibly unaligned) source location from a given address and offset.
@ Global
The global specifier '::'. There is no stored value.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
NestedNameSpecifierLocBuilder()=default
A C++ nested-name-specifier augmented with source location information.
Class that aids in the construction of nested-name-specifiers along with source-location information ...
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
NestedNameSpecifierLocBuilder & operator=(const NestedNameSpecifierLocBuilder &Other)
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 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.
void * getOpaqueData() const
Retrieve the opaque pointer that refers to source-location data.
Represents a C++ struct/union/class.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
NestedNameSpecifierDependence getDependence() const
Base wrapper for a particular "section" of type source info.
static NestedNameSpecifier * SuperSpecifier(const ASTContext &Context, CXXRecordDecl *RD)
Returns the nested name specifier representing the __super scope for the given CXXRecordDecl.
One of these records is kept for each identifier that is lexed.
static SourceLocation getFromRawEncoding(UIntTy 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...
unsigned getDataLength() const
Determines the data length for the entire nested-name-specifier.
StringRef getName() const
Return the actual identifier string.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
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.
A container of type source information.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
SpecifierKind
The kind of specifier that completes this nested name specifier.
void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
static NestedNameSpecifier * GlobalSpecifier(const ASTContext &Context)
Returns the nested name specifier representing the global scope.
@ TypeSpec
A type, stored as a Type*.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
Wraps an identifier and optional source location for the identifier.
Represent a C++ namespace.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.