clang API Documentation
00001 //===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the NestedNameSpecifier class, which represents 00011 // a C++ nested-name-specifier. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H 00015 #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H 00016 00017 #include "clang/Basic/Diagnostic.h" 00018 #include "llvm/ADT/FoldingSet.h" 00019 #include "llvm/ADT/PointerIntPair.h" 00020 #include "llvm/Support/Compiler.h" 00021 00022 namespace clang { 00023 00024 class ASTContext; 00025 class CXXRecordDecl; 00026 class NamespaceAliasDecl; 00027 class NamespaceDecl; 00028 class IdentifierInfo; 00029 struct PrintingPolicy; 00030 class Type; 00031 class TypeLoc; 00032 class LangOptions; 00033 00034 /// \brief Represents a C++ nested name specifier, such as 00035 /// "\::std::vector<int>::". 00036 /// 00037 /// C++ nested name specifiers are the prefixes to qualified 00038 /// namespaces. For example, "foo::" in "foo::x" is a nested name 00039 /// specifier. Nested name specifiers are made up of a sequence of 00040 /// specifiers, each of which can be a namespace, type, identifier 00041 /// (for dependent names), decltype specifier, or the global specifier ('::'). 00042 /// The last two specifiers can only appear at the start of a 00043 /// nested-namespace-specifier. 00044 class NestedNameSpecifier : public llvm::FoldingSetNode { 00045 00046 /// \brief Enumeration describing 00047 enum StoredSpecifierKind { 00048 StoredIdentifier = 0, 00049 StoredDecl = 1, 00050 StoredTypeSpec = 2, 00051 StoredTypeSpecWithTemplate = 3 00052 }; 00053 00054 /// \brief The nested name specifier that precedes this nested name 00055 /// specifier. 00056 /// 00057 /// The pointer is the nested-name-specifier that precedes this 00058 /// one. The integer stores one of the first four values of type 00059 /// SpecifierKind. 00060 llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix; 00061 00062 /// \brief The last component in the nested name specifier, which 00063 /// can be an identifier, a declaration, or a type. 00064 /// 00065 /// When the pointer is NULL, this specifier represents the global 00066 /// specifier '::'. Otherwise, the pointer is one of 00067 /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of 00068 /// specifier as encoded within the prefix. 00069 void* Specifier; 00070 00071 public: 00072 /// \brief The kind of specifier that completes this nested name 00073 /// specifier. 00074 enum SpecifierKind { 00075 /// \brief An identifier, stored as an IdentifierInfo*. 00076 Identifier, 00077 /// \brief A namespace, stored as a NamespaceDecl*. 00078 Namespace, 00079 /// \brief A namespace alias, stored as a NamespaceAliasDecl*. 00080 NamespaceAlias, 00081 /// \brief A type, stored as a Type*. 00082 TypeSpec, 00083 /// \brief A type that was preceded by the 'template' keyword, 00084 /// stored as a Type*. 00085 TypeSpecWithTemplate, 00086 /// \brief The global specifier '::'. There is no stored value. 00087 Global, 00088 /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of 00089 /// the class it appeared in. 00090 Super 00091 }; 00092 00093 private: 00094 /// \brief Builds the global specifier. 00095 NestedNameSpecifier() 00096 : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {} 00097 00098 /// \brief Copy constructor used internally to clone nested name 00099 /// specifiers. 00100 NestedNameSpecifier(const NestedNameSpecifier &Other) 00101 : llvm::FoldingSetNode(Other), Prefix(Other.Prefix), 00102 Specifier(Other.Specifier) { 00103 } 00104 00105 void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION; 00106 00107 /// \brief Either find or insert the given nested name specifier 00108 /// mockup in the given context. 00109 static NestedNameSpecifier *FindOrInsert(const ASTContext &Context, 00110 const NestedNameSpecifier &Mockup); 00111 00112 public: 00113 /// \brief Builds a specifier combining a prefix and an identifier. 00114 /// 00115 /// The prefix must be dependent, since nested name specifiers 00116 /// referencing an identifier are only permitted when the identifier 00117 /// cannot be resolved. 00118 static NestedNameSpecifier *Create(const ASTContext &Context, 00119 NestedNameSpecifier *Prefix, 00120 IdentifierInfo *II); 00121 00122 /// \brief Builds a nested name specifier that names a namespace. 00123 static NestedNameSpecifier *Create(const ASTContext &Context, 00124 NestedNameSpecifier *Prefix, 00125 const NamespaceDecl *NS); 00126 00127 /// \brief Builds a nested name specifier that names a namespace alias. 00128 static NestedNameSpecifier *Create(const ASTContext &Context, 00129 NestedNameSpecifier *Prefix, 00130 NamespaceAliasDecl *Alias); 00131 00132 /// \brief Builds a nested name specifier that names a type. 00133 static NestedNameSpecifier *Create(const ASTContext &Context, 00134 NestedNameSpecifier *Prefix, 00135 bool Template, const Type *T); 00136 00137 /// \brief Builds a specifier that consists of just an identifier. 00138 /// 00139 /// The nested-name-specifier is assumed to be dependent, but has no 00140 /// prefix because the prefix is implied by something outside of the 00141 /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent 00142 /// type. 00143 static NestedNameSpecifier *Create(const ASTContext &Context, 00144 IdentifierInfo *II); 00145 00146 /// \brief Returns the nested name specifier representing the global 00147 /// scope. 00148 static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context); 00149 00150 /// \brief Returns the nested name specifier representing the __super scope 00151 /// for the given CXXRecordDecl. 00152 static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context, 00153 CXXRecordDecl *RD); 00154 00155 /// \brief Return the prefix of this nested name specifier. 00156 /// 00157 /// The prefix contains all of the parts of the nested name 00158 /// specifier that preced this current specifier. For example, for a 00159 /// nested name specifier that represents "foo::bar::", the current 00160 /// specifier will contain "bar::" and the prefix will contain 00161 /// "foo::". 00162 NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); } 00163 00164 /// \brief Determine what kind of nested name specifier is stored. 00165 SpecifierKind getKind() const; 00166 00167 /// \brief Retrieve the identifier stored in this nested name 00168 /// specifier. 00169 IdentifierInfo *getAsIdentifier() const { 00170 if (Prefix.getInt() == StoredIdentifier) 00171 return (IdentifierInfo *)Specifier; 00172 00173 return nullptr; 00174 } 00175 00176 /// \brief Retrieve the namespace stored in this nested name 00177 /// specifier. 00178 NamespaceDecl *getAsNamespace() const; 00179 00180 /// \brief Retrieve the namespace alias stored in this nested name 00181 /// specifier. 00182 NamespaceAliasDecl *getAsNamespaceAlias() const; 00183 00184 /// \brief Retrieve the record declaration stored in this nested name 00185 /// specifier. 00186 CXXRecordDecl *getAsRecordDecl() const; 00187 00188 /// \brief Retrieve the type stored in this nested name specifier. 00189 const Type *getAsType() const { 00190 if (Prefix.getInt() == StoredTypeSpec || 00191 Prefix.getInt() == StoredTypeSpecWithTemplate) 00192 return (const Type *)Specifier; 00193 00194 return nullptr; 00195 } 00196 00197 /// \brief Whether this nested name specifier refers to a dependent 00198 /// type or not. 00199 bool isDependent() const; 00200 00201 /// \brief Whether this nested name specifier involves a template 00202 /// parameter. 00203 bool isInstantiationDependent() const; 00204 00205 /// \brief Whether this nested-name-specifier contains an unexpanded 00206 /// parameter pack (for C++11 variadic templates). 00207 bool containsUnexpandedParameterPack() const; 00208 00209 /// \brief Print this nested name specifier to the given output 00210 /// stream. 00211 void print(raw_ostream &OS, const PrintingPolicy &Policy) const; 00212 00213 void Profile(llvm::FoldingSetNodeID &ID) const { 00214 ID.AddPointer(Prefix.getOpaqueValue()); 00215 ID.AddPointer(Specifier); 00216 } 00217 00218 /// \brief Dump the nested name specifier to standard output to aid 00219 /// in debugging. 00220 void dump(const LangOptions &LO); 00221 }; 00222 00223 /// \brief A C++ nested-name-specifier augmented with source location 00224 /// information. 00225 class NestedNameSpecifierLoc { 00226 NestedNameSpecifier *Qualifier; 00227 void *Data; 00228 00229 /// \brief Determines the data length for the last component in the 00230 /// given nested-name-specifier. 00231 static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier); 00232 00233 /// \brief Determines the data length for the entire 00234 /// nested-name-specifier. 00235 static unsigned getDataLength(NestedNameSpecifier *Qualifier); 00236 00237 public: 00238 /// \brief Construct an empty nested-name-specifier. 00239 NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { } 00240 00241 /// \brief Construct a nested-name-specifier with source location information 00242 /// from 00243 NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data) 00244 : Qualifier(Qualifier), Data(Data) { } 00245 00246 /// \brief Evalutes true when this nested-name-specifier location is 00247 /// non-empty. 00248 LLVM_EXPLICIT operator bool() const { return Qualifier; } 00249 00250 /// \brief Evalutes true when this nested-name-specifier location is 00251 /// empty. 00252 bool hasQualifier() const { return Qualifier; } 00253 00254 /// \brief Retrieve the nested-name-specifier to which this instance 00255 /// refers. 00256 NestedNameSpecifier *getNestedNameSpecifier() const { 00257 return Qualifier; 00258 } 00259 00260 /// \brief Retrieve the opaque pointer that refers to source-location data. 00261 void *getOpaqueData() const { return Data; } 00262 00263 /// \brief Retrieve the source range covering the entirety of this 00264 /// nested-name-specifier. 00265 /// 00266 /// For example, if this instance refers to a nested-name-specifier 00267 /// \c \::std::vector<int>::, the returned source range would cover 00268 /// from the initial '::' to the last '::'. 00269 SourceRange getSourceRange() const LLVM_READONLY; 00270 00271 /// \brief Retrieve the source range covering just the last part of 00272 /// this nested-name-specifier, not including the prefix. 00273 /// 00274 /// For example, if this instance refers to a nested-name-specifier 00275 /// \c \::std::vector<int>::, the returned source range would cover 00276 /// from "vector" to the last '::'. 00277 SourceRange getLocalSourceRange() const; 00278 00279 /// \brief Retrieve the location of the beginning of this 00280 /// nested-name-specifier. 00281 SourceLocation getBeginLoc() const { 00282 return getSourceRange().getBegin(); 00283 } 00284 00285 /// \brief Retrieve the location of the end of this 00286 /// nested-name-specifier. 00287 SourceLocation getEndLoc() const { 00288 return getSourceRange().getEnd(); 00289 } 00290 00291 /// \brief Retrieve the location of the beginning of this 00292 /// component of the nested-name-specifier. 00293 SourceLocation getLocalBeginLoc() const { 00294 return getLocalSourceRange().getBegin(); 00295 } 00296 00297 /// \brief Retrieve the location of the end of this component of the 00298 /// nested-name-specifier. 00299 SourceLocation getLocalEndLoc() const { 00300 return getLocalSourceRange().getEnd(); 00301 } 00302 00303 /// \brief Return the prefix of this nested-name-specifier. 00304 /// 00305 /// For example, if this instance refers to a nested-name-specifier 00306 /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the 00307 /// returned prefix may be empty, if this is the first component of 00308 /// the nested-name-specifier. 00309 NestedNameSpecifierLoc getPrefix() const { 00310 if (!Qualifier) 00311 return *this; 00312 00313 return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data); 00314 } 00315 00316 /// \brief For a nested-name-specifier that refers to a type, 00317 /// retrieve the type with source-location information. 00318 TypeLoc getTypeLoc() const; 00319 00320 /// \brief Determines the data length for the entire 00321 /// nested-name-specifier. 00322 unsigned getDataLength() const { return getDataLength(Qualifier); } 00323 00324 friend bool operator==(NestedNameSpecifierLoc X, 00325 NestedNameSpecifierLoc Y) { 00326 return X.Qualifier == Y.Qualifier && X.Data == Y.Data; 00327 } 00328 00329 friend bool operator!=(NestedNameSpecifierLoc X, 00330 NestedNameSpecifierLoc Y) { 00331 return !(X == Y); 00332 } 00333 }; 00334 00335 /// \brief Class that aids in the construction of nested-name-specifiers along 00336 /// with source-location information for all of the components of the 00337 /// nested-name-specifier. 00338 class NestedNameSpecifierLocBuilder { 00339 /// \brief The current representation of the nested-name-specifier we're 00340 /// building. 00341 NestedNameSpecifier *Representation; 00342 00343 /// \brief Buffer used to store source-location information for the 00344 /// nested-name-specifier. 00345 /// 00346 /// Note that we explicitly manage the buffer (rather than using a 00347 /// SmallVector) because \c Declarator expects it to be possible to memcpy() 00348 /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder. 00349 char *Buffer; 00350 00351 /// \brief The size of the buffer used to store source-location information 00352 /// for the nested-name-specifier. 00353 unsigned BufferSize; 00354 00355 /// \brief The capacity of the buffer used to store source-location 00356 /// information for the nested-name-specifier. 00357 unsigned BufferCapacity; 00358 00359 public: 00360 NestedNameSpecifierLocBuilder() 00361 : Representation(nullptr), Buffer(nullptr), BufferSize(0), 00362 BufferCapacity(0) {} 00363 00364 NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other); 00365 00366 NestedNameSpecifierLocBuilder & 00367 operator=(const NestedNameSpecifierLocBuilder &Other); 00368 00369 ~NestedNameSpecifierLocBuilder() { 00370 if (BufferCapacity) 00371 free(Buffer); 00372 } 00373 00374 /// \brief Retrieve the representation of the nested-name-specifier. 00375 NestedNameSpecifier *getRepresentation() const { return Representation; } 00376 00377 /// \brief Extend the current nested-name-specifier by another 00378 /// nested-name-specifier component of the form 'type::'. 00379 /// 00380 /// \param Context The AST context in which this nested-name-specifier 00381 /// resides. 00382 /// 00383 /// \param TemplateKWLoc The location of the 'template' keyword, if present. 00384 /// 00385 /// \param TL The TypeLoc that describes the type preceding the '::'. 00386 /// 00387 /// \param ColonColonLoc The location of the trailing '::'. 00388 void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, 00389 SourceLocation ColonColonLoc); 00390 00391 /// \brief Extend the current nested-name-specifier by another 00392 /// nested-name-specifier component of the form 'identifier::'. 00393 /// 00394 /// \param Context The AST context in which this nested-name-specifier 00395 /// resides. 00396 /// 00397 /// \param Identifier The identifier. 00398 /// 00399 /// \param IdentifierLoc The location of the identifier. 00400 /// 00401 /// \param ColonColonLoc The location of the trailing '::'. 00402 void Extend(ASTContext &Context, IdentifierInfo *Identifier, 00403 SourceLocation IdentifierLoc, SourceLocation ColonColonLoc); 00404 00405 /// \brief Extend the current nested-name-specifier by another 00406 /// nested-name-specifier component of the form 'namespace::'. 00407 /// 00408 /// \param Context The AST context in which this nested-name-specifier 00409 /// resides. 00410 /// 00411 /// \param Namespace The namespace. 00412 /// 00413 /// \param NamespaceLoc The location of the namespace name. 00414 /// 00415 /// \param ColonColonLoc The location of the trailing '::'. 00416 void Extend(ASTContext &Context, NamespaceDecl *Namespace, 00417 SourceLocation NamespaceLoc, SourceLocation ColonColonLoc); 00418 00419 /// \brief Extend the current nested-name-specifier by another 00420 /// nested-name-specifier component of the form 'namespace-alias::'. 00421 /// 00422 /// \param Context The AST context in which this nested-name-specifier 00423 /// resides. 00424 /// 00425 /// \param Alias The namespace alias. 00426 /// 00427 /// \param AliasLoc The location of the namespace alias 00428 /// name. 00429 /// 00430 /// \param ColonColonLoc The location of the trailing '::'. 00431 void Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 00432 SourceLocation AliasLoc, SourceLocation ColonColonLoc); 00433 00434 /// \brief Turn this (empty) nested-name-specifier into the global 00435 /// nested-name-specifier '::'. 00436 void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); 00437 00438 /// \brief Turns this (empty) nested-name-specifier into '__super' 00439 /// nested-name-specifier. 00440 /// 00441 /// \param Context The AST context in which this nested-name-specifier 00442 /// resides. 00443 /// 00444 /// \param RD The declaration of the class in which nested-name-specifier 00445 /// appeared. 00446 /// 00447 /// \param SuperLoc The location of the '__super' keyword. 00448 /// name. 00449 /// 00450 /// \param ColonColonLoc The location of the trailing '::'. 00451 void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, 00452 SourceLocation SuperLoc, SourceLocation ColonColonLoc); 00453 /// \brief Make a new nested-name-specifier from incomplete source-location 00454 /// information. 00455 /// 00456 /// This routine should be used very, very rarely, in cases where we 00457 /// need to synthesize a nested-name-specifier. Most code should instead use 00458 /// \c Adopt() with a proper \c NestedNameSpecifierLoc. 00459 void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, 00460 SourceRange R); 00461 00462 /// \brief Adopt an existing nested-name-specifier (with source-range 00463 /// information). 00464 void Adopt(NestedNameSpecifierLoc Other); 00465 00466 /// \brief Retrieve the source range covered by this nested-name-specifier. 00467 SourceRange getSourceRange() const LLVM_READONLY { 00468 return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange(); 00469 } 00470 00471 /// \brief Retrieve a nested-name-specifier with location information, 00472 /// copied into the given AST context. 00473 /// 00474 /// \param Context The context into which this nested-name-specifier will be 00475 /// copied. 00476 NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; 00477 00478 /// \brief Retrieve a nested-name-specifier with location 00479 /// information based on the information in this builder. 00480 /// 00481 /// This loc will contain references to the builder's internal data and may 00482 /// be invalidated by any change to the builder. 00483 NestedNameSpecifierLoc getTemporary() const { 00484 return NestedNameSpecifierLoc(Representation, Buffer); 00485 } 00486 00487 /// \brief Clear out this builder, and prepare it to build another 00488 /// nested-name-specifier with source-location information. 00489 void Clear() { 00490 Representation = nullptr; 00491 BufferSize = 0; 00492 } 00493 00494 /// \brief Retrieve the underlying buffer. 00495 /// 00496 /// \returns A pair containing a pointer to the buffer of source-location 00497 /// data and the size of the source-location data that resides in that 00498 /// buffer. 00499 std::pair<char *, unsigned> getBuffer() const { 00500 return std::make_pair(Buffer, BufferSize); 00501 } 00502 }; 00503 00504 /// Insertion operator for diagnostics. This allows sending 00505 /// NestedNameSpecifiers into a diagnostic with <<. 00506 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 00507 NestedNameSpecifier *NNS) { 00508 DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS), 00509 DiagnosticsEngine::ak_nestednamespec); 00510 return DB; 00511 } 00512 00513 } 00514 00515 #endif