1212795Sdim//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9212795Sdim// 10212795Sdim// This file defines the IdentifierResolver class, which is used for lexical 11212795Sdim// scoped lookup, based on declaration names. 12212795Sdim// 13212795Sdim//===----------------------------------------------------------------------===// 14212795Sdim 15212795Sdim#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H 16212795Sdim#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H 17212795Sdim 18212795Sdim#include "clang/Basic/IdentifierTable.h" 19234353Sdim#include "llvm/ADT/SmallVector.h" 20212795Sdim 21212795Sdimnamespace clang { 22212795Sdim 23212795Sdimclass ASTContext; 24212795Sdimclass Decl; 25212795Sdimclass DeclContext; 26212795Sdimclass DeclarationName; 27234353Sdimclass ExternalPreprocessorSource; 28212795Sdimclass NamedDecl; 29234353Sdimclass Preprocessor; 30212795Sdimclass Scope; 31234353Sdim 32212795Sdim/// IdentifierResolver - Keeps track of shadowed decls on enclosing 33212795Sdim/// scopes. It manages the shadowing chains of declaration names and 34221345Sdim/// implements efficient decl lookup based on a declaration name. 35212795Sdimclass IdentifierResolver { 36212795Sdim 37212795Sdim /// IdDeclInfo - Keeps track of information about decls associated 38212795Sdim /// to a particular declaration name. IdDeclInfos are lazily 39212795Sdim /// constructed and assigned to a declaration name the first time a 40212795Sdim /// decl with that declaration name is shadowed in some scope. 41212795Sdim class IdDeclInfo { 42212795Sdim public: 43226633Sdim typedef SmallVector<NamedDecl*, 2> DeclsTy; 44212795Sdim 45212795Sdim inline DeclsTy::iterator decls_begin() { return Decls.begin(); } 46212795Sdim inline DeclsTy::iterator decls_end() { return Decls.end(); } 47212795Sdim 48212795Sdim void AddDecl(NamedDecl *D) { Decls.push_back(D); } 49212795Sdim 50212795Sdim /// RemoveDecl - Remove the decl from the scope chain. 51212795Sdim /// The decl must already be part of the decl chain. 52212795Sdim void RemoveDecl(NamedDecl *D); 53212795Sdim 54221345Sdim /// \brief Insert the given declaration at the given position in the list. 55221345Sdim void InsertDecl(DeclsTy::iterator Pos, NamedDecl *D) { 56221345Sdim Decls.insert(Pos, D); 57221345Sdim } 58221345Sdim 59212795Sdim private: 60212795Sdim DeclsTy Decls; 61212795Sdim }; 62212795Sdim 63212795Sdimpublic: 64212795Sdim 65212795Sdim /// iterator - Iterate over the decls of a specified declaration name. 66212795Sdim /// It will walk or not the parent declaration contexts depending on how 67212795Sdim /// it was instantiated. 68212795Sdim class iterator { 69212795Sdim public: 70212795Sdim typedef NamedDecl * value_type; 71212795Sdim typedef NamedDecl * reference; 72212795Sdim typedef NamedDecl * pointer; 73212795Sdim typedef std::input_iterator_tag iterator_category; 74212795Sdim typedef std::ptrdiff_t difference_type; 75212795Sdim 76212795Sdim /// Ptr - There are 3 forms that 'Ptr' represents: 77212795Sdim /// 1) A single NamedDecl. (Ptr & 0x1 == 0) 78212795Sdim /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the 79212795Sdim /// same declaration context. (Ptr & 0x3 == 0x1) 80212795Sdim /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent 81212795Sdim /// declaration contexts too. (Ptr & 0x3 == 0x3) 82212795Sdim uintptr_t Ptr; 83212795Sdim typedef IdDeclInfo::DeclsTy::iterator BaseIter; 84212795Sdim 85212795Sdim /// A single NamedDecl. (Ptr & 0x1 == 0) 86212795Sdim iterator(NamedDecl *D) { 87212795Sdim Ptr = reinterpret_cast<uintptr_t>(D); 88212795Sdim assert((Ptr & 0x1) == 0 && "Invalid Ptr!"); 89212795Sdim } 90212795Sdim /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration 91212795Sdim /// contexts depending on 'LookInParentCtx'. 92212795Sdim iterator(BaseIter I) { 93212795Sdim Ptr = reinterpret_cast<uintptr_t>(I) | 0x1; 94212795Sdim } 95212795Sdim 96212795Sdim bool isIterator() const { return (Ptr & 0x1); } 97212795Sdim 98212795Sdim BaseIter getIterator() const { 99212795Sdim assert(isIterator() && "Ptr not an iterator!"); 100212795Sdim return reinterpret_cast<BaseIter>(Ptr & ~0x3); 101212795Sdim } 102212795Sdim 103212795Sdim friend class IdentifierResolver; 104212795Sdim 105212795Sdim void incrementSlowCase(); 106212795Sdim public: 107212795Sdim iterator() : Ptr(0) {} 108212795Sdim 109212795Sdim NamedDecl *operator*() const { 110212795Sdim if (isIterator()) 111212795Sdim return *getIterator(); 112212795Sdim else 113212795Sdim return reinterpret_cast<NamedDecl*>(Ptr); 114212795Sdim } 115212795Sdim 116212795Sdim bool operator==(const iterator &RHS) const { 117212795Sdim return Ptr == RHS.Ptr; 118212795Sdim } 119212795Sdim bool operator!=(const iterator &RHS) const { 120212795Sdim return Ptr != RHS.Ptr; 121212795Sdim } 122212795Sdim 123212795Sdim // Preincrement. 124212795Sdim iterator& operator++() { 125212795Sdim if (!isIterator()) // common case. 126212795Sdim Ptr = 0; 127212795Sdim else 128212795Sdim incrementSlowCase(); 129212795Sdim return *this; 130212795Sdim } 131212795Sdim 132212795Sdim uintptr_t getAsOpaqueValue() const { return Ptr; } 133212795Sdim 134212795Sdim static iterator getFromOpaqueValue(uintptr_t P) { 135212795Sdim iterator Result; 136212795Sdim Result.Ptr = P; 137212795Sdim return Result; 138212795Sdim } 139212795Sdim }; 140212795Sdim 141212795Sdim /// begin - Returns an iterator for decls with the name 'Name'. 142234353Sdim iterator begin(DeclarationName Name); 143212795Sdim 144212795Sdim /// end - Returns an iterator that has 'finished'. 145234353Sdim iterator end() { 146212795Sdim return iterator(); 147212795Sdim } 148212795Sdim 149212795Sdim /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true 150212795Sdim /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns 151212795Sdim /// true if 'D' belongs to the given declaration context. 152221345Sdim /// 153221345Sdim /// \param ExplicitInstantiationOrSpecialization When true, we are checking 154221345Sdim /// whether the declaration is in scope for the purposes of explicit template 155221345Sdim /// instantiation or specialization. The default is false. 156249423Sdim bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0, 157221345Sdim bool ExplicitInstantiationOrSpecialization = false) const; 158212795Sdim 159212795Sdim /// AddDecl - Link the decl to its shadowed decl chain. 160212795Sdim void AddDecl(NamedDecl *D); 161212795Sdim 162212795Sdim /// RemoveDecl - Unlink the decl from its shadowed decl chain. 163212795Sdim /// The decl must already be part of the decl chain. 164212795Sdim void RemoveDecl(NamedDecl *D); 165212795Sdim 166221345Sdim /// \brief Insert the given declaration after the given iterator 167221345Sdim /// position. 168221345Sdim void InsertDeclAfter(iterator Pos, NamedDecl *D); 169221345Sdim 170234353Sdim /// \brief Try to add the given declaration to the top level scope, if it 171234353Sdim /// (or a redeclaration of it) hasn't already been added. 172212795Sdim /// 173234353Sdim /// \param D The externally-produced declaration to add. 174234353Sdim /// 175234353Sdim /// \param Name The name of the externally-produced declaration. 176234353Sdim /// 177234353Sdim /// \returns true if the declaration was added, false otherwise. 178234353Sdim bool tryAddTopLevelDecl(NamedDecl *D, DeclarationName Name); 179234353Sdim 180234353Sdim explicit IdentifierResolver(Preprocessor &PP); 181212795Sdim ~IdentifierResolver(); 182212795Sdim 183212795Sdimprivate: 184212795Sdim const LangOptions &LangOpt; 185234353Sdim Preprocessor &PP; 186234353Sdim 187212795Sdim class IdDeclInfoMap; 188212795Sdim IdDeclInfoMap *IdDeclInfos; 189212795Sdim 190234353Sdim void updatingIdentifier(IdentifierInfo &II); 191234353Sdim void readingIdentifier(IdentifierInfo &II); 192234353Sdim 193212795Sdim /// FETokenInfo contains a Decl pointer if lower bit == 0. 194212795Sdim static inline bool isDeclPtr(void *Ptr) { 195212795Sdim return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0; 196212795Sdim } 197212795Sdim 198212795Sdim /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1. 199212795Sdim static inline IdDeclInfo *toIdDeclInfo(void *Ptr) { 200212795Sdim assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1 201212795Sdim && "Ptr not a IdDeclInfo* !"); 202212795Sdim return reinterpret_cast<IdDeclInfo*>( 203212795Sdim reinterpret_cast<uintptr_t>(Ptr) & ~0x1 204212795Sdim ); 205212795Sdim } 206212795Sdim}; 207212795Sdim 208212795Sdim} // end namespace clang 209212795Sdim 210212795Sdim#endif 211