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