Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines the IdentifierResolver class, which is used for lexical
  10. // scoped lookup, based on declaration names.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
  15. #define LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
  16.  
  17. #include "clang/Basic/LLVM.h"
  18. #include "llvm/ADT/SmallVector.h"
  19. #include <cassert>
  20. #include <cstddef>
  21. #include <cstdint>
  22. #include <iterator>
  23.  
  24. namespace clang {
  25.  
  26. class Decl;
  27. class DeclarationName;
  28. class DeclContext;
  29. class IdentifierInfo;
  30. class LangOptions;
  31. class NamedDecl;
  32. class Preprocessor;
  33. class Scope;
  34.  
  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.  
  47.     DeclsTy::iterator decls_begin() { return Decls.begin(); }
  48.     DeclsTy::iterator decls_end() { return Decls.end(); }
  49.  
  50.     void AddDecl(NamedDecl *D) { Decls.push_back(D); }
  51.  
  52.     /// RemoveDecl - Remove the decl from the scope chain.
  53.     /// The decl must already be part of the decl chain.
  54.     void RemoveDecl(NamedDecl *D);
  55.  
  56.     /// Insert the given declaration at the given position in the list.
  57.     void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) {
  58.       Decls.insert(Pos, D);
  59.     }
  60.  
  61.   private:
  62.     DeclsTy Decls;
  63.   };
  64.  
  65. public:
  66.   /// iterator - Iterate over the decls of a specified declaration name.
  67.   /// It will walk or not the parent declaration contexts depending on how
  68.   /// it was instantiated.
  69.   class iterator {
  70.   public:
  71.     friend class IdentifierResolver;
  72.  
  73.     using value_type = NamedDecl *;
  74.     using reference = NamedDecl *;
  75.     using pointer = NamedDecl *;
  76.     using iterator_category = std::input_iterator_tag;
  77.     using difference_type = std::ptrdiff_t;
  78.  
  79.     /// Ptr - There are 2 forms that 'Ptr' represents:
  80.     /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
  81.     /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
  82.     ///    same declaration context. (Ptr & 0x1 == 0x1)
  83.     uintptr_t Ptr = 0;
  84.     using BaseIter = IdDeclInfo::DeclsTy::iterator;
  85.  
  86.     /// A single NamedDecl. (Ptr & 0x1 == 0)
  87.     iterator(NamedDecl *D) {
  88.       Ptr = reinterpret_cast<uintptr_t>(D);
  89.       assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
  90.     }
  91.  
  92.     /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
  93.     /// contexts depending on 'LookInParentCtx'.
  94.     iterator(BaseIter I) {
  95.       Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
  96.     }
  97.  
  98.     bool isIterator() const { return (Ptr & 0x1); }
  99.  
  100.     BaseIter getIterator() const {
  101.       assert(isIterator() && "Ptr not an iterator!");
  102.       return reinterpret_cast<BaseIter>(Ptr & ~0x1);
  103.     }
  104.  
  105.     void incrementSlowCase();
  106.  
  107.   public:
  108.     iterator() = default;
  109.  
  110.     NamedDecl *operator*() const {
  111.       if (isIterator())
  112.         return *getIterator();
  113.       else
  114.         return reinterpret_cast<NamedDecl*>(Ptr);
  115.     }
  116.  
  117.     bool operator==(const iterator &RHS) const {
  118.       return Ptr == RHS.Ptr;
  119.     }
  120.     bool operator!=(const iterator &RHS) const {
  121.       return Ptr != RHS.Ptr;
  122.     }
  123.  
  124.     // Preincrement.
  125.     iterator& operator++() {
  126.       if (!isIterator()) // common case.
  127.         Ptr = 0;
  128.       else
  129.         incrementSlowCase();
  130.       return *this;
  131.     }
  132.   };
  133.  
  134.   explicit IdentifierResolver(Preprocessor &PP);
  135.   ~IdentifierResolver();
  136.  
  137.   /// begin - Returns an iterator for decls with the name 'Name'.
  138.   iterator begin(DeclarationName Name);
  139.  
  140.   /// end - Returns an iterator that has 'finished'.
  141.   iterator end() {
  142.     return iterator();
  143.   }
  144.  
  145.   /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
  146.   /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
  147.   /// true if 'D' belongs to the given declaration context.
  148.   ///
  149.   /// \param AllowInlineNamespace If \c true, we are checking whether a prior
  150.   ///        declaration is in scope in a declaration that requires a prior
  151.   ///        declaration (because it is either explicitly qualified or is a
  152.   ///        template instantiation or specialization). In this case, a
  153.   ///        declaration is in scope if it's in the inline namespace set of the
  154.   ///        context.
  155.   bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
  156.                      bool AllowInlineNamespace = false) const;
  157.  
  158.   /// AddDecl - Link the decl to its shadowed decl chain.
  159.   void AddDecl(NamedDecl *D);
  160.  
  161.   /// RemoveDecl - Unlink the decl from its shadowed decl chain.
  162.   /// The decl must already be part of the decl chain.
  163.   void RemoveDecl(NamedDecl *D);
  164.  
  165.   /// Insert the given declaration after the given iterator
  166.   /// position.
  167.   void InsertDeclAfter(iterator Pos, NamedDecl *D);
  168.  
  169.   /// Try to add the given declaration to the top level scope, if it
  170.   /// (or a redeclaration of it) hasn't already been added.
  171.   ///
  172.   /// \param D The externally-produced declaration to add.
  173.   ///
  174.   /// \param Name The name of the externally-produced declaration.
  175.   ///
  176.   /// \returns true if the declaration was added, false otherwise.
  177.   bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name);
  178.  
  179. private:
  180.   const LangOptions &LangOpt;
  181.   Preprocessor &PP;
  182.  
  183.   class IdDeclInfoMap;
  184.   IdDeclInfoMap *IdDeclInfos;
  185.  
  186.   void updatingIdentifier(IdentifierInfo &II);
  187.   void readingIdentifier(IdentifierInfo &II);
  188.  
  189.   /// FETokenInfo contains a Decl pointer if lower bit == 0.
  190.   static inline bool isDeclPtr(void *Ptr) {
  191.     return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
  192.   }
  193.  
  194.   /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
  195.   static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
  196.     assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
  197.           && "Ptr not a IdDeclInfo* !");
  198.     return reinterpret_cast<IdDeclInfo*>(
  199.                     reinterpret_cast<uintptr_t>(Ptr) & ~0x1);
  200.   }
  201. };
  202.  
  203. } // namespace clang
  204.  
  205. #endif // LLVM_CLANG_SEMA_IDENTIFIERRESOLVER_H
  206.