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