1 //===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the NestedNameSpecifier class, which represents 11 // a C++ nested-name-specifier. 12 // 13 //===----------------------------------------------------------------------===// 14 #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H 15 #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H 16 17 #include "clang/Basic/Diagnostic.h" 18 #include "llvm/ADT/FoldingSet.h" 19 #include "llvm/ADT/PointerIntPair.h" 20 #include "llvm/Support/Compiler.h" 21 22 namespace clang { 23 24 class ASTContext; 25 class NamespaceAliasDecl; 26 class NamespaceDecl; 27 class IdentifierInfo; 28 struct PrintingPolicy; 29 class Type; 30 class TypeLoc; 31 class LangOptions; 32 33 /// \brief Represents a C++ nested name specifier, such as 34 /// "\::std::vector<int>::". 35 /// 36 /// C++ nested name specifiers are the prefixes to qualified 37 /// namespaces. For example, "foo::" in "foo::x" is a nested name 38 /// specifier. Nested name specifiers are made up of a sequence of 39 /// specifiers, each of which can be a namespace, type, identifier 40 /// (for dependent names), decltype specifier, or the global specifier ('::'). 41 /// The last two specifiers can only appear at the start of a 42 /// nested-namespace-specifier. 43 class NestedNameSpecifier : public llvm::FoldingSetNode { 44 45 /// \brief Enumeration describing 46 enum StoredSpecifierKind { 47 StoredIdentifier = 0, 48 StoredNamespaceOrAlias = 1, 49 StoredTypeSpec = 2, 50 StoredTypeSpecWithTemplate = 3 51 }; 52 53 /// \brief The nested name specifier that precedes this nested name 54 /// specifier. 55 /// 56 /// The pointer is the nested-name-specifier that precedes this 57 /// one. The integer stores one of the first four values of type 58 /// SpecifierKind. 59 llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix; 60 61 /// \brief The last component in the nested name specifier, which 62 /// can be an identifier, a declaration, or a type. 63 /// 64 /// When the pointer is NULL, this specifier represents the global 65 /// specifier '::'. Otherwise, the pointer is one of 66 /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of 67 /// specifier as encoded within the prefix. 68 void* Specifier; 69 70 public: 71 /// \brief The kind of specifier that completes this nested name 72 /// specifier. 73 enum SpecifierKind { 74 /// \brief An identifier, stored as an IdentifierInfo*. 75 Identifier, 76 /// \brief A namespace, stored as a NamespaceDecl*. 77 Namespace, 78 /// \brief A namespace alias, stored as a NamespaceAliasDecl*. 79 NamespaceAlias, 80 /// \brief A type, stored as a Type*. 81 TypeSpec, 82 /// \brief A type that was preceded by the 'template' keyword, 83 /// stored as a Type*. 84 TypeSpecWithTemplate, 85 /// \brief The global specifier '::'. There is no stored value. 86 Global 87 }; 88 89 private: 90 /// \brief Builds the global specifier. NestedNameSpecifier()91 NestedNameSpecifier() 92 : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {} 93 94 /// \brief Copy constructor used internally to clone nested name 95 /// specifiers. NestedNameSpecifier(const NestedNameSpecifier & Other)96 NestedNameSpecifier(const NestedNameSpecifier &Other) 97 : llvm::FoldingSetNode(Other), Prefix(Other.Prefix), 98 Specifier(Other.Specifier) { 99 } 100 101 void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION; 102 103 /// \brief Either find or insert the given nested name specifier 104 /// mockup in the given context. 105 static NestedNameSpecifier *FindOrInsert(const ASTContext &Context, 106 const NestedNameSpecifier &Mockup); 107 108 public: 109 /// \brief Builds a specifier combining a prefix and an identifier. 110 /// 111 /// The prefix must be dependent, since nested name specifiers 112 /// referencing an identifier are only permitted when the identifier 113 /// cannot be resolved. 114 static NestedNameSpecifier *Create(const ASTContext &Context, 115 NestedNameSpecifier *Prefix, 116 IdentifierInfo *II); 117 118 /// \brief Builds a nested name specifier that names a namespace. 119 static NestedNameSpecifier *Create(const ASTContext &Context, 120 NestedNameSpecifier *Prefix, 121 const NamespaceDecl *NS); 122 123 /// \brief Builds a nested name specifier that names a namespace alias. 124 static NestedNameSpecifier *Create(const ASTContext &Context, 125 NestedNameSpecifier *Prefix, 126 NamespaceAliasDecl *Alias); 127 128 /// \brief Builds a nested name specifier that names a type. 129 static NestedNameSpecifier *Create(const ASTContext &Context, 130 NestedNameSpecifier *Prefix, 131 bool Template, const Type *T); 132 133 /// \brief Builds a specifier that consists of just an identifier. 134 /// 135 /// The nested-name-specifier is assumed to be dependent, but has no 136 /// prefix because the prefix is implied by something outside of the 137 /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent 138 /// type. 139 static NestedNameSpecifier *Create(const ASTContext &Context, 140 IdentifierInfo *II); 141 142 /// \brief Returns the nested name specifier representing the global 143 /// scope. 144 static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context); 145 146 /// \brief Return the prefix of this nested name specifier. 147 /// 148 /// The prefix contains all of the parts of the nested name 149 /// specifier that preced this current specifier. For example, for a 150 /// nested name specifier that represents "foo::bar::", the current 151 /// specifier will contain "bar::" and the prefix will contain 152 /// "foo::". getPrefix()153 NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); } 154 155 /// \brief Determine what kind of nested name specifier is stored. 156 SpecifierKind getKind() const; 157 158 /// \brief Retrieve the identifier stored in this nested name 159 /// specifier. getAsIdentifier()160 IdentifierInfo *getAsIdentifier() const { 161 if (Prefix.getInt() == StoredIdentifier) 162 return (IdentifierInfo *)Specifier; 163 164 return nullptr; 165 } 166 167 /// \brief Retrieve the namespace stored in this nested name 168 /// specifier. 169 NamespaceDecl *getAsNamespace() const; 170 171 /// \brief Retrieve the namespace alias stored in this nested name 172 /// specifier. 173 NamespaceAliasDecl *getAsNamespaceAlias() const; 174 175 /// \brief Retrieve the type stored in this nested name specifier. getAsType()176 const Type *getAsType() const { 177 if (Prefix.getInt() == StoredTypeSpec || 178 Prefix.getInt() == StoredTypeSpecWithTemplate) 179 return (const Type *)Specifier; 180 181 return nullptr; 182 } 183 184 /// \brief Whether this nested name specifier refers to a dependent 185 /// type or not. 186 bool isDependent() const; 187 188 /// \brief Whether this nested name specifier involves a template 189 /// parameter. 190 bool isInstantiationDependent() const; 191 192 /// \brief Whether this nested-name-specifier contains an unexpanded 193 /// parameter pack (for C++11 variadic templates). 194 bool containsUnexpandedParameterPack() const; 195 196 /// \brief Print this nested name specifier to the given output 197 /// stream. 198 void print(raw_ostream &OS, const PrintingPolicy &Policy) const; 199 Profile(llvm::FoldingSetNodeID & ID)200 void Profile(llvm::FoldingSetNodeID &ID) const { 201 ID.AddPointer(Prefix.getOpaqueValue()); 202 ID.AddPointer(Specifier); 203 } 204 205 /// \brief Dump the nested name specifier to standard output to aid 206 /// in debugging. 207 void dump(const LangOptions &LO); 208 }; 209 210 /// \brief A C++ nested-name-specifier augmented with source location 211 /// information. 212 class NestedNameSpecifierLoc { 213 NestedNameSpecifier *Qualifier; 214 void *Data; 215 216 /// \brief Determines the data length for the last component in the 217 /// given nested-name-specifier. 218 static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier); 219 220 /// \brief Determines the data length for the entire 221 /// nested-name-specifier. 222 static unsigned getDataLength(NestedNameSpecifier *Qualifier); 223 224 public: 225 /// \brief Construct an empty nested-name-specifier. NestedNameSpecifierLoc()226 NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { } 227 228 /// \brief Construct a nested-name-specifier with source location information 229 /// from NestedNameSpecifierLoc(NestedNameSpecifier * Qualifier,void * Data)230 NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data) 231 : Qualifier(Qualifier), Data(Data) { } 232 233 /// \brief Evalutes true when this nested-name-specifier location is 234 /// non-empty. 235 LLVM_EXPLICIT operator bool() const { return Qualifier; } 236 237 /// \brief Evalutes true when this nested-name-specifier location is 238 /// empty. hasQualifier()239 bool hasQualifier() const { return Qualifier; } 240 241 /// \brief Retrieve the nested-name-specifier to which this instance 242 /// refers. getNestedNameSpecifier()243 NestedNameSpecifier *getNestedNameSpecifier() const { 244 return Qualifier; 245 } 246 247 /// \brief Retrieve the opaque pointer that refers to source-location data. getOpaqueData()248 void *getOpaqueData() const { return Data; } 249 250 /// \brief Retrieve the source range covering the entirety of this 251 /// nested-name-specifier. 252 /// 253 /// For example, if this instance refers to a nested-name-specifier 254 /// \c \::std::vector<int>::, the returned source range would cover 255 /// from the initial '::' to the last '::'. 256 SourceRange getSourceRange() const LLVM_READONLY; 257 258 /// \brief Retrieve the source range covering just the last part of 259 /// this nested-name-specifier, not including the prefix. 260 /// 261 /// For example, if this instance refers to a nested-name-specifier 262 /// \c \::std::vector<int>::, the returned source range would cover 263 /// from "vector" to the last '::'. 264 SourceRange getLocalSourceRange() const; 265 266 /// \brief Retrieve the location of the beginning of this 267 /// nested-name-specifier. getBeginLoc()268 SourceLocation getBeginLoc() const { 269 return getSourceRange().getBegin(); 270 } 271 272 /// \brief Retrieve the location of the end of this 273 /// nested-name-specifier. getEndLoc()274 SourceLocation getEndLoc() const { 275 return getSourceRange().getEnd(); 276 } 277 278 /// \brief Retrieve the location of the beginning of this 279 /// component of the nested-name-specifier. getLocalBeginLoc()280 SourceLocation getLocalBeginLoc() const { 281 return getLocalSourceRange().getBegin(); 282 } 283 284 /// \brief Retrieve the location of the end of this component of the 285 /// nested-name-specifier. getLocalEndLoc()286 SourceLocation getLocalEndLoc() const { 287 return getLocalSourceRange().getEnd(); 288 } 289 290 /// \brief Return the prefix of this nested-name-specifier. 291 /// 292 /// For example, if this instance refers to a nested-name-specifier 293 /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the 294 /// returned prefix may be empty, if this is the first component of 295 /// the nested-name-specifier. getPrefix()296 NestedNameSpecifierLoc getPrefix() const { 297 if (!Qualifier) 298 return *this; 299 300 return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data); 301 } 302 303 /// \brief For a nested-name-specifier that refers to a type, 304 /// retrieve the type with source-location information. 305 TypeLoc getTypeLoc() const; 306 307 /// \brief Determines the data length for the entire 308 /// nested-name-specifier. getDataLength()309 unsigned getDataLength() const { return getDataLength(Qualifier); } 310 311 friend bool operator==(NestedNameSpecifierLoc X, 312 NestedNameSpecifierLoc Y) { 313 return X.Qualifier == Y.Qualifier && X.Data == Y.Data; 314 } 315 316 friend bool operator!=(NestedNameSpecifierLoc X, 317 NestedNameSpecifierLoc Y) { 318 return !(X == Y); 319 } 320 }; 321 322 /// \brief Class that aids in the construction of nested-name-specifiers along 323 /// with source-location information for all of the components of the 324 /// nested-name-specifier. 325 class NestedNameSpecifierLocBuilder { 326 /// \brief The current representation of the nested-name-specifier we're 327 /// building. 328 NestedNameSpecifier *Representation; 329 330 /// \brief Buffer used to store source-location information for the 331 /// nested-name-specifier. 332 /// 333 /// Note that we explicitly manage the buffer (rather than using a 334 /// SmallVector) because \c Declarator expects it to be possible to memcpy() 335 /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder. 336 char *Buffer; 337 338 /// \brief The size of the buffer used to store source-location information 339 /// for the nested-name-specifier. 340 unsigned BufferSize; 341 342 /// \brief The capacity of the buffer used to store source-location 343 /// information for the nested-name-specifier. 344 unsigned BufferCapacity; 345 346 public: NestedNameSpecifierLocBuilder()347 NestedNameSpecifierLocBuilder() 348 : Representation(nullptr), Buffer(nullptr), BufferSize(0), 349 BufferCapacity(0) {} 350 351 NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other); 352 353 NestedNameSpecifierLocBuilder & 354 operator=(const NestedNameSpecifierLocBuilder &Other); 355 ~NestedNameSpecifierLocBuilder()356 ~NestedNameSpecifierLocBuilder() { 357 if (BufferCapacity) 358 free(Buffer); 359 } 360 361 /// \brief Retrieve the representation of the nested-name-specifier. getRepresentation()362 NestedNameSpecifier *getRepresentation() const { return Representation; } 363 364 /// \brief Extend the current nested-name-specifier by another 365 /// nested-name-specifier component of the form 'type::'. 366 /// 367 /// \param Context The AST context in which this nested-name-specifier 368 /// resides. 369 /// 370 /// \param TemplateKWLoc The location of the 'template' keyword, if present. 371 /// 372 /// \param TL The TypeLoc that describes the type preceding the '::'. 373 /// 374 /// \param ColonColonLoc The location of the trailing '::'. 375 void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, 376 SourceLocation ColonColonLoc); 377 378 /// \brief Extend the current nested-name-specifier by another 379 /// nested-name-specifier component of the form 'identifier::'. 380 /// 381 /// \param Context The AST context in which this nested-name-specifier 382 /// resides. 383 /// 384 /// \param Identifier The identifier. 385 /// 386 /// \param IdentifierLoc The location of the identifier. 387 /// 388 /// \param ColonColonLoc The location of the trailing '::'. 389 void Extend(ASTContext &Context, IdentifierInfo *Identifier, 390 SourceLocation IdentifierLoc, SourceLocation ColonColonLoc); 391 392 /// \brief Extend the current nested-name-specifier by another 393 /// nested-name-specifier component of the form 'namespace::'. 394 /// 395 /// \param Context The AST context in which this nested-name-specifier 396 /// resides. 397 /// 398 /// \param Namespace The namespace. 399 /// 400 /// \param NamespaceLoc The location of the namespace name. 401 /// 402 /// \param ColonColonLoc The location of the trailing '::'. 403 void Extend(ASTContext &Context, NamespaceDecl *Namespace, 404 SourceLocation NamespaceLoc, SourceLocation ColonColonLoc); 405 406 /// \brief Extend the current nested-name-specifier by another 407 /// nested-name-specifier component of the form 'namespace-alias::'. 408 /// 409 /// \param Context The AST context in which this nested-name-specifier 410 /// resides. 411 /// 412 /// \param Alias The namespace alias. 413 /// 414 /// \param AliasLoc The location of the namespace alias 415 /// name. 416 /// 417 /// \param ColonColonLoc The location of the trailing '::'. 418 void Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 419 SourceLocation AliasLoc, SourceLocation ColonColonLoc); 420 421 /// \brief Turn this (empty) nested-name-specifier into the global 422 /// nested-name-specifier '::'. 423 void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); 424 425 /// \brief Make a new nested-name-specifier from incomplete source-location 426 /// information. 427 /// 428 /// This routine should be used very, very rarely, in cases where we 429 /// need to synthesize a nested-name-specifier. Most code should instead use 430 /// \c Adopt() with a proper \c NestedNameSpecifierLoc. 431 void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, 432 SourceRange R); 433 434 /// \brief Adopt an existing nested-name-specifier (with source-range 435 /// information). 436 void Adopt(NestedNameSpecifierLoc Other); 437 438 /// \brief Retrieve the source range covered by this nested-name-specifier. getSourceRange()439 SourceRange getSourceRange() const LLVM_READONLY { 440 return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange(); 441 } 442 443 /// \brief Retrieve a nested-name-specifier with location information, 444 /// copied into the given AST context. 445 /// 446 /// \param Context The context into which this nested-name-specifier will be 447 /// copied. 448 NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; 449 450 /// \brief Retrieve a nested-name-specifier with location 451 /// information based on the information in this builder. 452 /// 453 /// This loc will contain references to the builder's internal data and may 454 /// be invalidated by any change to the builder. getTemporary()455 NestedNameSpecifierLoc getTemporary() const { 456 return NestedNameSpecifierLoc(Representation, Buffer); 457 } 458 459 /// \brief Clear out this builder, and prepare it to build another 460 /// nested-name-specifier with source-location information. Clear()461 void Clear() { 462 Representation = nullptr; 463 BufferSize = 0; 464 } 465 466 /// \brief Retrieve the underlying buffer. 467 /// 468 /// \returns A pair containing a pointer to the buffer of source-location 469 /// data and the size of the source-location data that resides in that 470 /// buffer. getBuffer()471 std::pair<char *, unsigned> getBuffer() const { 472 return std::make_pair(Buffer, BufferSize); 473 } 474 }; 475 476 /// Insertion operator for diagnostics. This allows sending 477 /// NestedNameSpecifiers into a diagnostic with <<. 478 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 479 NestedNameSpecifier *NNS) { 480 DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS), 481 DiagnosticsEngine::ak_nestednamespec); 482 return DB; 483 } 484 485 } 486 487 #endif 488