1193326Sed//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the NestedNameSpecifier class, which represents 11193326Sed// a C++ nested-name-specifier. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H 15193326Sed#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H 16193326Sed 17198092Srdivacky#include "clang/Basic/Diagnostic.h" 18193326Sed#include "llvm/ADT/FoldingSet.h" 19193326Sed#include "llvm/ADT/PointerIntPair.h" 20234353Sdim#include "llvm/Support/Compiler.h" 21193326Sed 22193326Sednamespace clang { 23193326Sed 24193326Sedclass ASTContext; 25219077Sdimclass NamespaceAliasDecl; 26193326Sedclass NamespaceDecl; 27193326Sedclass IdentifierInfo; 28198092Srdivackystruct PrintingPolicy; 29193326Sedclass Type; 30219077Sdimclass TypeLoc; 31195341Sedclass LangOptions; 32193326Sed 33193326Sed/// \brief Represents a C++ nested name specifier, such as 34239462Sdim/// "\::std::vector<int>::". 35193326Sed/// 36193326Sed/// C++ nested name specifiers are the prefixes to qualified 37193326Sed/// namespaces. For example, "foo::" in "foo::x" is a nested name 38193326Sed/// specifier. Nested name specifiers are made up of a sequence of 39193326Sed/// specifiers, each of which can be a namespace, type, identifier 40234353Sdim/// (for dependent names), decltype specifier, or the global specifier ('::'). 41234353Sdim/// The last two specifiers can only appear at the start of a 42234353Sdim/// nested-namespace-specifier. 43193326Sedclass NestedNameSpecifier : public llvm::FoldingSetNode { 44219077Sdim 45219077Sdim /// \brief Enumeration describing 46219077Sdim enum StoredSpecifierKind { 47219077Sdim StoredIdentifier = 0, 48219077Sdim StoredNamespaceOrAlias = 1, 49219077Sdim StoredTypeSpec = 2, 50219077Sdim StoredTypeSpecWithTemplate = 3 51219077Sdim }; 52219077Sdim 53193326Sed /// \brief The nested name specifier that precedes this nested name 54193326Sed /// specifier. 55193326Sed /// 56193326Sed /// The pointer is the nested-name-specifier that precedes this 57193326Sed /// one. The integer stores one of the first four values of type 58193326Sed /// SpecifierKind. 59219077Sdim llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix; 60193326Sed 61193326Sed /// \brief The last component in the nested name specifier, which 62193326Sed /// can be an identifier, a declaration, or a type. 63193326Sed /// 64193326Sed /// When the pointer is NULL, this specifier represents the global 65193326Sed /// specifier '::'. Otherwise, the pointer is one of 66193326Sed /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of 67193326Sed /// specifier as encoded within the prefix. 68193326Sed void* Specifier; 69193326Sed 70193326Sedpublic: 71193326Sed /// \brief The kind of specifier that completes this nested name 72193326Sed /// specifier. 73193326Sed enum SpecifierKind { 74193326Sed /// \brief An identifier, stored as an IdentifierInfo*. 75219077Sdim Identifier, 76219077Sdim /// \brief A namespace, stored as a NamespaceDecl*. 77219077Sdim Namespace, 78219077Sdim /// \brief A namespace alias, stored as a NamespaceAliasDecl*. 79219077Sdim NamespaceAlias, 80193326Sed /// \brief A type, stored as a Type*. 81219077Sdim TypeSpec, 82193326Sed /// \brief A type that was preceded by the 'template' keyword, 83193326Sed /// stored as a Type*. 84219077Sdim TypeSpecWithTemplate, 85193326Sed /// \brief The global specifier '::'. There is no stored value. 86219077Sdim Global 87193326Sed }; 88193326Sed 89193326Sedprivate: 90193326Sed /// \brief Builds the global specifier. 91219077Sdim NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { } 92193326Sed 93193326Sed /// \brief Copy constructor used internally to clone nested name 94193326Sed /// specifiers. 95198092Srdivacky NestedNameSpecifier(const NestedNameSpecifier &Other) 96198092Srdivacky : llvm::FoldingSetNode(Other), Prefix(Other.Prefix), 97193326Sed Specifier(Other.Specifier) { 98193326Sed } 99193326Sed 100243830Sdim void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION; 101193326Sed 102193326Sed /// \brief Either find or insert the given nested name specifier 103193326Sed /// mockup in the given context. 104218893Sdim static NestedNameSpecifier *FindOrInsert(const ASTContext &Context, 105193326Sed const NestedNameSpecifier &Mockup); 106193326Sed 107193326Sedpublic: 108193326Sed /// \brief Builds a specifier combining a prefix and an identifier. 109193326Sed /// 110193326Sed /// The prefix must be dependent, since nested name specifiers 111193326Sed /// referencing an identifier are only permitted when the identifier 112193326Sed /// cannot be resolved. 113218893Sdim static NestedNameSpecifier *Create(const ASTContext &Context, 114198092Srdivacky NestedNameSpecifier *Prefix, 115193326Sed IdentifierInfo *II); 116193326Sed 117193326Sed /// \brief Builds a nested name specifier that names a namespace. 118218893Sdim static NestedNameSpecifier *Create(const ASTContext &Context, 119198092Srdivacky NestedNameSpecifier *Prefix, 120249423Sdim const NamespaceDecl *NS); 121193326Sed 122219077Sdim /// \brief Builds a nested name specifier that names a namespace alias. 123219077Sdim static NestedNameSpecifier *Create(const ASTContext &Context, 124219077Sdim NestedNameSpecifier *Prefix, 125219077Sdim NamespaceAliasDecl *Alias); 126219077Sdim 127193326Sed /// \brief Builds a nested name specifier that names a type. 128218893Sdim static NestedNameSpecifier *Create(const ASTContext &Context, 129198092Srdivacky NestedNameSpecifier *Prefix, 130218893Sdim bool Template, const Type *T); 131193326Sed 132198092Srdivacky /// \brief Builds a specifier that consists of just an identifier. 133198092Srdivacky /// 134198092Srdivacky /// The nested-name-specifier is assumed to be dependent, but has no 135198092Srdivacky /// prefix because the prefix is implied by something outside of the 136198092Srdivacky /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent 137198092Srdivacky /// type. 138218893Sdim static NestedNameSpecifier *Create(const ASTContext &Context, 139218893Sdim IdentifierInfo *II); 140198092Srdivacky 141193326Sed /// \brief Returns the nested name specifier representing the global 142193326Sed /// scope. 143218893Sdim static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context); 144193326Sed 145193326Sed /// \brief Return the prefix of this nested name specifier. 146193326Sed /// 147193326Sed /// The prefix contains all of the parts of the nested name 148193326Sed /// specifier that preced this current specifier. For example, for a 149193326Sed /// nested name specifier that represents "foo::bar::", the current 150193326Sed /// specifier will contain "bar::" and the prefix will contain 151193326Sed /// "foo::". 152193326Sed NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); } 153193326Sed 154193326Sed /// \brief Determine what kind of nested name specifier is stored. 155219077Sdim SpecifierKind getKind() const; 156193326Sed 157193326Sed /// \brief Retrieve the identifier stored in this nested name 158193326Sed /// specifier. 159193326Sed IdentifierInfo *getAsIdentifier() const { 160219077Sdim if (Prefix.getInt() == StoredIdentifier) 161193326Sed return (IdentifierInfo *)Specifier; 162193326Sed 163193326Sed return 0; 164193326Sed } 165198092Srdivacky 166193326Sed /// \brief Retrieve the namespace stored in this nested name 167193326Sed /// specifier. 168219077Sdim NamespaceDecl *getAsNamespace() const; 169193326Sed 170219077Sdim /// \brief Retrieve the namespace alias stored in this nested name 171219077Sdim /// specifier. 172219077Sdim NamespaceAliasDecl *getAsNamespaceAlias() const; 173193326Sed 174193326Sed /// \brief Retrieve the type stored in this nested name specifier. 175218893Sdim const Type *getAsType() const { 176219077Sdim if (Prefix.getInt() == StoredTypeSpec || 177219077Sdim Prefix.getInt() == StoredTypeSpecWithTemplate) 178218893Sdim return (const Type *)Specifier; 179193326Sed 180193326Sed return 0; 181193326Sed } 182193326Sed 183193326Sed /// \brief Whether this nested name specifier refers to a dependent 184193326Sed /// type or not. 185193326Sed bool isDependent() const; 186193326Sed 187224145Sdim /// \brief Whether this nested name specifier involves a template 188224145Sdim /// parameter. 189224145Sdim bool isInstantiationDependent() const; 190224145Sdim 191218893Sdim /// \brief Whether this nested-name-specifier contains an unexpanded 192239462Sdim /// parameter pack (for C++11 variadic templates). 193218893Sdim bool containsUnexpandedParameterPack() const; 194218893Sdim 195193326Sed /// \brief Print this nested name specifier to the given output 196193326Sed /// stream. 197226633Sdim void print(raw_ostream &OS, const PrintingPolicy &Policy) const; 198193326Sed 199193326Sed void Profile(llvm::FoldingSetNodeID &ID) const { 200193326Sed ID.AddPointer(Prefix.getOpaqueValue()); 201193326Sed ID.AddPointer(Specifier); 202193326Sed } 203193326Sed 204193326Sed /// \brief Dump the nested name specifier to standard output to aid 205193326Sed /// in debugging. 206195341Sed void dump(const LangOptions &LO); 207193326Sed}; 208193326Sed 209219077Sdim/// \brief A C++ nested-name-specifier augmented with source location 210219077Sdim/// information. 211219077Sdimclass NestedNameSpecifierLoc { 212219077Sdim NestedNameSpecifier *Qualifier; 213219077Sdim void *Data; 214219077Sdim 215219077Sdim /// \brief Determines the data length for the last component in the 216219077Sdim /// given nested-name-specifier. 217219077Sdim static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier); 218219077Sdim 219219077Sdim /// \brief Determines the data length for the entire 220219077Sdim /// nested-name-specifier. 221219077Sdim static unsigned getDataLength(NestedNameSpecifier *Qualifier); 222219077Sdim 223219077Sdimpublic: 224219077Sdim /// \brief Construct an empty nested-name-specifier. 225219077Sdim NestedNameSpecifierLoc() : Qualifier(0), Data(0) { } 226234353Sdim 227219077Sdim /// \brief Construct a nested-name-specifier with source location information 228234353Sdim /// from 229219077Sdim NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data) 230219077Sdim : Qualifier(Qualifier), Data(Data) { } 231234353Sdim 232219077Sdim /// \brief Evalutes true when this nested-name-specifier location is 233219077Sdim /// non-empty. 234263508Sdim LLVM_EXPLICIT operator bool() const { return Qualifier; } 235219077Sdim 236263508Sdim /// \brief Evalutes true when this nested-name-specifier location is 237263508Sdim /// empty. 238263508Sdim bool hasQualifier() const { return Qualifier; } 239263508Sdim 240219077Sdim /// \brief Retrieve the nested-name-specifier to which this instance 241219077Sdim /// refers. 242219077Sdim NestedNameSpecifier *getNestedNameSpecifier() const { 243219077Sdim return Qualifier; 244219077Sdim } 245219077Sdim 246219077Sdim /// \brief Retrieve the opaque pointer that refers to source-location data. 247219077Sdim void *getOpaqueData() const { return Data; } 248234353Sdim 249219077Sdim /// \brief Retrieve the source range covering the entirety of this 250219077Sdim /// nested-name-specifier. 251219077Sdim /// 252219077Sdim /// For example, if this instance refers to a nested-name-specifier 253239462Sdim /// \c \::std::vector<int>::, the returned source range would cover 254219077Sdim /// from the initial '::' to the last '::'. 255234353Sdim SourceRange getSourceRange() const LLVM_READONLY; 256219077Sdim 257219077Sdim /// \brief Retrieve the source range covering just the last part of 258219077Sdim /// this nested-name-specifier, not including the prefix. 259219077Sdim /// 260219077Sdim /// For example, if this instance refers to a nested-name-specifier 261239462Sdim /// \c \::std::vector<int>::, the returned source range would cover 262219077Sdim /// from "vector" to the last '::'. 263219077Sdim SourceRange getLocalSourceRange() const; 264219077Sdim 265219077Sdim /// \brief Retrieve the location of the beginning of this 266219077Sdim /// nested-name-specifier. 267234353Sdim SourceLocation getBeginLoc() const { 268219077Sdim return getSourceRange().getBegin(); 269219077Sdim } 270219077Sdim 271219077Sdim /// \brief Retrieve the location of the end of this 272219077Sdim /// nested-name-specifier. 273234353Sdim SourceLocation getEndLoc() const { 274219077Sdim return getSourceRange().getEnd(); 275219077Sdim } 276219077Sdim 277219077Sdim /// \brief Retrieve the location of the beginning of this 278219077Sdim /// component of the nested-name-specifier. 279234353Sdim SourceLocation getLocalBeginLoc() const { 280219077Sdim return getLocalSourceRange().getBegin(); 281219077Sdim } 282234353Sdim 283219077Sdim /// \brief Retrieve the location of the end of this component of the 284219077Sdim /// nested-name-specifier. 285234353Sdim SourceLocation getLocalEndLoc() const { 286219077Sdim return getLocalSourceRange().getEnd(); 287219077Sdim } 288219077Sdim 289219077Sdim /// \brief Return the prefix of this nested-name-specifier. 290219077Sdim /// 291219077Sdim /// For example, if this instance refers to a nested-name-specifier 292239462Sdim /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the 293219077Sdim /// returned prefix may be empty, if this is the first component of 294219077Sdim /// the nested-name-specifier. 295219077Sdim NestedNameSpecifierLoc getPrefix() const { 296219077Sdim if (!Qualifier) 297219077Sdim return *this; 298219077Sdim 299219077Sdim return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data); 300219077Sdim } 301219077Sdim 302219077Sdim /// \brief For a nested-name-specifier that refers to a type, 303219077Sdim /// retrieve the type with source-location information. 304219077Sdim TypeLoc getTypeLoc() const; 305219077Sdim 306219077Sdim /// \brief Determines the data length for the entire 307219077Sdim /// nested-name-specifier. 308219077Sdim unsigned getDataLength() const { return getDataLength(Qualifier); } 309234353Sdim 310234353Sdim friend bool operator==(NestedNameSpecifierLoc X, 311219077Sdim NestedNameSpecifierLoc Y) { 312219077Sdim return X.Qualifier == Y.Qualifier && X.Data == Y.Data; 313219077Sdim } 314219077Sdim 315234353Sdim friend bool operator!=(NestedNameSpecifierLoc X, 316219077Sdim NestedNameSpecifierLoc Y) { 317219077Sdim return !(X == Y); 318219077Sdim } 319219077Sdim}; 320219077Sdim 321221345Sdim/// \brief Class that aids in the construction of nested-name-specifiers along 322221345Sdim/// with source-location information for all of the components of the 323221345Sdim/// nested-name-specifier. 324221345Sdimclass NestedNameSpecifierLocBuilder { 325234353Sdim /// \brief The current representation of the nested-name-specifier we're 326221345Sdim /// building. 327221345Sdim NestedNameSpecifier *Representation; 328234353Sdim 329221345Sdim /// \brief Buffer used to store source-location information for the 330221345Sdim /// nested-name-specifier. 331221345Sdim /// 332234353Sdim /// Note that we explicitly manage the buffer (rather than using a 333221345Sdim /// SmallVector) because \c Declarator expects it to be possible to memcpy() 334221345Sdim /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder. 335221345Sdim char *Buffer; 336234353Sdim 337221345Sdim /// \brief The size of the buffer used to store source-location information 338221345Sdim /// for the nested-name-specifier. 339221345Sdim unsigned BufferSize; 340234353Sdim 341234353Sdim /// \brief The capacity of the buffer used to store source-location 342221345Sdim /// information for the nested-name-specifier. 343221345Sdim unsigned BufferCapacity; 344221345Sdim 345221345Sdimpublic: 346234353Sdim NestedNameSpecifierLocBuilder() 347234353Sdim : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { } 348234353Sdim 349221345Sdim NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other); 350234353Sdim 351221345Sdim NestedNameSpecifierLocBuilder & 352221345Sdim operator=(const NestedNameSpecifierLocBuilder &Other); 353234353Sdim 354234353Sdim ~NestedNameSpecifierLocBuilder() { 355234353Sdim if (BufferCapacity) 356234353Sdim free(Buffer); 357234353Sdim } 358234353Sdim 359221345Sdim /// \brief Retrieve the representation of the nested-name-specifier. 360221345Sdim NestedNameSpecifier *getRepresentation() const { return Representation; } 361234353Sdim 362221345Sdim /// \brief Extend the current nested-name-specifier by another 363221345Sdim /// nested-name-specifier component of the form 'type::'. 364221345Sdim /// 365221345Sdim /// \param Context The AST context in which this nested-name-specifier 366221345Sdim /// resides. 367221345Sdim /// 368221345Sdim /// \param TemplateKWLoc The location of the 'template' keyword, if present. 369221345Sdim /// 370221345Sdim /// \param TL The TypeLoc that describes the type preceding the '::'. 371221345Sdim /// 372221345Sdim /// \param ColonColonLoc The location of the trailing '::'. 373221345Sdim void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, 374221345Sdim SourceLocation ColonColonLoc); 375234353Sdim 376234353Sdim /// \brief Extend the current nested-name-specifier by another 377221345Sdim /// nested-name-specifier component of the form 'identifier::'. 378221345Sdim /// 379221345Sdim /// \param Context The AST context in which this nested-name-specifier 380221345Sdim /// resides. 381221345Sdim /// 382221345Sdim /// \param Identifier The identifier. 383221345Sdim /// 384221345Sdim /// \param IdentifierLoc The location of the identifier. 385221345Sdim /// 386221345Sdim /// \param ColonColonLoc The location of the trailing '::'. 387221345Sdim void Extend(ASTContext &Context, IdentifierInfo *Identifier, 388221345Sdim SourceLocation IdentifierLoc, SourceLocation ColonColonLoc); 389234353Sdim 390234353Sdim /// \brief Extend the current nested-name-specifier by another 391221345Sdim /// nested-name-specifier component of the form 'namespace::'. 392221345Sdim /// 393221345Sdim /// \param Context The AST context in which this nested-name-specifier 394221345Sdim /// resides. 395221345Sdim /// 396221345Sdim /// \param Namespace The namespace. 397221345Sdim /// 398221345Sdim /// \param NamespaceLoc The location of the namespace name. 399221345Sdim /// 400221345Sdim /// \param ColonColonLoc The location of the trailing '::'. 401221345Sdim void Extend(ASTContext &Context, NamespaceDecl *Namespace, 402221345Sdim SourceLocation NamespaceLoc, SourceLocation ColonColonLoc); 403234353Sdim 404234353Sdim /// \brief Extend the current nested-name-specifier by another 405221345Sdim /// nested-name-specifier component of the form 'namespace-alias::'. 406221345Sdim /// 407221345Sdim /// \param Context The AST context in which this nested-name-specifier 408221345Sdim /// resides. 409221345Sdim /// 410221345Sdim /// \param Alias The namespace alias. 411221345Sdim /// 412234353Sdim /// \param AliasLoc The location of the namespace alias 413221345Sdim /// name. 414221345Sdim /// 415221345Sdim /// \param ColonColonLoc The location of the trailing '::'. 416221345Sdim void Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 417221345Sdim SourceLocation AliasLoc, SourceLocation ColonColonLoc); 418234353Sdim 419221345Sdim /// \brief Turn this (empty) nested-name-specifier into the global 420221345Sdim /// nested-name-specifier '::'. 421221345Sdim void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); 422234353Sdim 423221345Sdim /// \brief Make a new nested-name-specifier from incomplete source-location 424221345Sdim /// information. 425221345Sdim /// 426221345Sdim /// This routine should be used very, very rarely, in cases where we 427221345Sdim /// need to synthesize a nested-name-specifier. Most code should instead use 428221345Sdim /// \c Adopt() with a proper \c NestedNameSpecifierLoc. 429234353Sdim void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, 430221345Sdim SourceRange R); 431234353Sdim 432234353Sdim /// \brief Adopt an existing nested-name-specifier (with source-range 433221345Sdim /// information). 434221345Sdim void Adopt(NestedNameSpecifierLoc Other); 435234353Sdim 436221345Sdim /// \brief Retrieve the source range covered by this nested-name-specifier. 437234353Sdim SourceRange getSourceRange() const LLVM_READONLY { 438221345Sdim return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange(); 439221345Sdim } 440234353Sdim 441221345Sdim /// \brief Retrieve a nested-name-specifier with location information, 442221345Sdim /// copied into the given AST context. 443221345Sdim /// 444221345Sdim /// \param Context The context into which this nested-name-specifier will be 445221345Sdim /// copied. 446221345Sdim NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; 447221345Sdim 448224145Sdim /// \brief Retrieve a nested-name-specifier with location 449239462Sdim /// information based on the information in this builder. 450239462Sdim /// 451239462Sdim /// This loc will contain references to the builder's internal data and may 452224145Sdim /// be invalidated by any change to the builder. 453224145Sdim NestedNameSpecifierLoc getTemporary() const { 454224145Sdim return NestedNameSpecifierLoc(Representation, Buffer); 455224145Sdim } 456224145Sdim 457221345Sdim /// \brief Clear out this builder, and prepare it to build another 458221345Sdim /// nested-name-specifier with source-location information. 459221345Sdim void Clear() { 460221345Sdim Representation = 0; 461221345Sdim BufferSize = 0; 462221345Sdim } 463234353Sdim 464221345Sdim /// \brief Retrieve the underlying buffer. 465221345Sdim /// 466221345Sdim /// \returns A pair containing a pointer to the buffer of source-location 467221345Sdim /// data and the size of the source-location data that resides in that 468221345Sdim /// buffer. 469221345Sdim std::pair<char *, unsigned> getBuffer() const { 470221345Sdim return std::make_pair(Buffer, BufferSize); 471221345Sdim } 472221345Sdim}; 473234353Sdim 474234353Sdim/// Insertion operator for diagnostics. This allows sending 475234353Sdim/// NestedNameSpecifiers into a diagnostic with <<. 476198092Srdivackyinline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 477198092Srdivacky NestedNameSpecifier *NNS) { 478198092Srdivacky DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS), 479226633Sdim DiagnosticsEngine::ak_nestednamespec); 480198092Srdivacky return DB; 481193326Sed} 482193326Sed 483198092Srdivacky} 484198092Srdivacky 485193326Sed#endif 486