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