IdentifierResolver.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- 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 IdentifierResolver class, which is used for lexical
  15. // scoped lookup, based on declaration names.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
  19. #define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
  20. #include "clang/Basic/LLVM.h"
  21. #include "llvm/ADT/SmallVector.h"
  22. #include <cassert>
  23. #include <cstddef>
  24. #include <cstdint>
  25. #include <iterator>
  26. namespace clang {
  27. class Decl;
  28. class DeclarationName;
  29. class DeclContext;
  30. class IdentifierInfo;
  31. class LangOptions;
  32. class NamedDecl;
  33. class Preprocessor;
  34. class Scope;
  35. /// IdentifierResolver - Keeps track of shadowed decls on enclosing
  36. /// scopes. It manages the shadowing chains of declaration names and
  37. /// implements efficient decl lookup based on a declaration name.
  38. class IdentifierResolver {
  39. /// IdDeclInfo - Keeps track of information about decls associated
  40. /// to a particular declaration name. IdDeclInfos are lazily
  41. /// constructed and assigned to a declaration name the first time a
  42. /// decl with that declaration name is shadowed in some scope.
  43. class IdDeclInfo {
  44. public:
  45. using DeclsTy = SmallVector<NamedDecl *, 2>;
  46. DeclsTy::iterator decls_begin() { return Decls.begin(); }
  47. DeclsTy::iterator decls_end() { return Decls.end(); }
  48. void AddDecl(NamedDecl *D) { Decls.push_back(D); }
  49. /// RemoveDecl - Remove the decl from the scope chain.
  50. /// The decl must already be part of the decl chain.
  51. void RemoveDecl(NamedDecl *D);
  52. /// Insert the given declaration at the given position in the list.
  53. void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
  54. Decls.insert(Pos, D);
  55. }
  56. private:
  57. DeclsTy Decls;
  58. };
  59. public:
  60. /// iterator - Iterate over the decls of a specified declaration name.
  61. /// It will walk or not the parent declaration contexts depending on how
  62. /// it was instantiated.
  63. class iterator {
  64. public:
  65. friend class IdentifierResolver;
  66. using value_type = NamedDecl *;
  67. using reference = NamedDecl *;
  68. using pointer = NamedDecl *;
  69. using iterator_category = std::input_iterator_tag;
  70. using difference_type = std::ptrdiff_t;
  71. /// Ptr - There are 2 forms that 'Ptr' represents:
  72. /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
  73. /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
  74. /// same declaration context. (Ptr & 0x1 == 0x1)
  75. uintptr_t Ptr = 0;
  76. using BaseIter = IdDeclInfo::DeclsTy::iterator;
  77. /// A single NamedDecl. (Ptr & 0x1 == 0)
  78. iterator(NamedDecl *D) {
  79. Ptr = reinterpret_cast<uintptr_t>(D);
  80. assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
  81. }
  82. /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
  83. /// contexts depending on 'LookInParentCtx'.
  84. iterator(BaseIter I) {
  85. Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
  86. }
  87. bool isIterator() const { return (Ptr & 0x1); }
  88. BaseIter getIterator() const {
  89. assert(isIterator() && "Ptr not an iterator!");
  90. return reinterpret_cast<BaseIter>(Ptr & ~0x1);
  91. }
  92. void incrementSlowCase();
  93. public:
  94. iterator() = default;
  95. NamedDecl *operator*() const {
  96. if (isIterator())
  97. return *getIterator();
  98. else
  99. return reinterpret_cast<NamedDecl*>(Ptr);
  100. }
  101. bool operator==(const iterator &RHS) const {
  102. return Ptr == RHS.Ptr;
  103. }
  104. bool operator!=(const iterator &RHS) const {
  105. return Ptr != RHS.Ptr;
  106. }
  107. // Preincrement.
  108. iterator& operator++() {
  109. if (!isIterator()) // common case.
  110. Ptr = 0;
  111. else
  112. incrementSlowCase();
  113. return *this;
  114. }
  115. };
  116. explicit IdentifierResolver(Preprocessor &PP);
  117. ~IdentifierResolver();
  118. /// begin - Returns an iterator for decls with the name 'Name'.
  119. iterator begin(DeclarationName Name);
  120. /// end - Returns an iterator that has 'finished'.
  121. iterator end() {
  122. return iterator();
  123. }
  124. /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
  125. /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
  126. /// true if 'D' belongs to the given declaration context.
  127. ///
  128. /// \param AllowInlineNamespace If \c true, we are checking whether a prior
  129. /// declaration is in scope in a declaration that requires a prior
  130. /// declaration (because it is either explicitly qualified or is a
  131. /// template instantiation or specialization). In this case, a
  132. /// declaration is in scope if it's in the inline namespace set of the
  133. /// context.
  134. bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
  135. bool AllowInlineNamespace = false) const;
  136. /// AddDecl - Link the decl to its shadowed decl chain.
  137. void AddDecl(NamedDecl *D);
  138. /// RemoveDecl - Unlink the decl from its shadowed decl chain.
  139. /// The decl must already be part of the decl chain.
  140. void RemoveDecl(NamedDecl *D);
  141. /// Insert the given declaration after the given iterator
  142. /// position.
  143. void InsertDeclAfter(iterator Pos, NamedDecl *D);
  144. /// Try to add the given declaration to the top level scope, if it
  145. /// (or a redeclaration of it) hasn't already been added.
  146. ///
  147. /// \param D The externally-produced declaration to add.
  148. ///
  149. /// \param Name The name of the externally-produced declaration.
  150. ///
  151. /// \returns true if the declaration was added, false otherwise.
  152. bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name);
  153. private:
  154. const LangOptions &LangOpt;
  155. Preprocessor &PP;
  156. class IdDeclInfoMap;
  157. IdDeclInfoMap *IdDeclInfos;
  158. void updatingIdentifier(IdentifierInfo &II);
  159. void readingIdentifier(IdentifierInfo &II);
  160. /// FETokenInfo contains a Decl pointer if lower bit == 0.
  161. static inline bool isDeclPtr(void *Ptr) {
  162. return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
  163. }
  164. /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
  165. static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
  166. assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
  167. && "Ptr not a IdDeclInfo* !");
  168. return reinterpret_cast<IdDeclInfo*>(
  169. reinterpret_cast<uintptr_t>(Ptr) & ~0x1);
  170. }
  171. };
  172. } // namespace clang
  173. #endif // LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
  174. #ifdef __GNUC__
  175. #pragma GCC diagnostic pop
  176. #endif