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