NestedNameSpecifier.h 20 KB

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