IdentifierResolver.cpp revision 59a9afbb7ca63efd556d052b462feabecd8c6a3d
1//===- IdentifierResolver.cpp - Lexical Scope Name lookup -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the IdentifierResolver class, which is used for lexical 11// scoped lookup, based on identifier. 12// 13//===----------------------------------------------------------------------===// 14 15#include "IdentifierResolver.h" 16#include <list> 17#include <vector> 18 19using namespace clang; 20 21 22/// IdDeclInfoMap - Associates IdDeclInfos with Identifiers. 23/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each 24/// individual IdDeclInfo to heap. 25class IdentifierResolver::IdDeclInfoMap { 26 static const unsigned int VECTOR_SIZE = 512; 27 // Holds vectors of IdDeclInfos that serve as 'pools'. 28 // New vectors are added when the current one is full. 29 std::list< std::vector<IdDeclInfo> > IDIVecs; 30 unsigned int CurIndex; 31 32public: 33 IdDeclInfoMap() : CurIndex(VECTOR_SIZE) {} 34 35 /// Returns the IdDeclInfo associated to the IdentifierInfo. 36 /// It creates a new IdDeclInfo if one was not created before for this id. 37 IdDeclInfo &operator[](IdentifierInfo *II); 38}; 39 40 41IdentifierResolver::IdentifierResolver() : IdDeclInfos(new IdDeclInfoMap) {} 42IdentifierResolver::~IdentifierResolver() { 43 delete IdDeclInfos; 44} 45 46/// AddDecl - Link the decl to its shadowed decl chain. 47void IdentifierResolver::AddDecl(NamedDecl *D) { 48 IdentifierInfo *II = D->getIdentifier(); 49 void *Ptr = II->getFETokenInfo<void>(); 50 51 if (!Ptr) { 52 II->setFETokenInfo(D); 53 return; 54 } 55 56 IdDeclInfo *IDI; 57 58 if (isDeclPtr(Ptr)) { 59 II->setFETokenInfo(NULL); 60 IDI = &(*IdDeclInfos)[II]; 61 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); 62 IDI->AddDecl(PrevD); 63 } else 64 IDI = toIdDeclInfo(Ptr); 65 66 IDI->AddDecl(D); 67} 68 69/// AddShadowedDecl - Link the decl to its shadowed decl chain putting it 70/// after the decl that the iterator points to, thus the 'CIT' decl will be 71/// encountered before the 'D' decl. 72void IdentifierResolver::AddShadowedDecl(NamedDecl *D, NamedDecl *Shadow) { 73 assert(D->getIdentifier() == Shadow->getIdentifier() && "Different ids!"); 74 assert(LookupContext(D) == LookupContext(Shadow) && "Different context!"); 75 76 IdentifierInfo *II = D->getIdentifier(); 77 void *Ptr = II->getFETokenInfo<void>(); 78 assert(Ptr && "No decl from Ptr ?"); 79 80 IdDeclInfo *IDI; 81 82 if (isDeclPtr(Ptr)) { 83 II->setFETokenInfo(NULL); 84 IDI = &(*IdDeclInfos)[II]; 85 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); 86 assert(PrevD == Shadow && "Invalid shadow decl ?"); 87 IDI->AddDecl(D); 88 IDI->AddDecl(PrevD); 89 return; 90 } 91 92 IDI = toIdDeclInfo(Ptr); 93 IDI->AddShadowed(D, Shadow); 94} 95 96/// RemoveDecl - Unlink the decl from its shadowed decl chain. 97/// The decl must already be part of the decl chain. 98void IdentifierResolver::RemoveDecl(NamedDecl *D) { 99 assert(D && "null param passed"); 100 IdentifierInfo *II = D->getIdentifier(); 101 void *Ptr = II->getFETokenInfo<void>(); 102 103 assert(Ptr && "Didn't find this decl on its identifier's chain!"); 104 105 if (isDeclPtr(Ptr)) { 106 assert(D == Ptr && "Didn't find this decl on its identifier's chain!"); 107 II->setFETokenInfo(NULL); 108 return; 109 } 110 111 return toIdDeclInfo(Ptr)->RemoveDecl(D); 112} 113 114/// begin - Returns an iterator for all decls, starting at the given 115/// declaration context. 116IdentifierResolver::iterator 117IdentifierResolver::begin(const IdentifierInfo *II, DeclContext *Ctx) { 118 assert(Ctx && "null param passed"); 119 120 void *Ptr = II->getFETokenInfo<void>(); 121 if (!Ptr) return end(II); 122 123 LookupContext LC(Ctx); 124 125 if (isDeclPtr(Ptr)) { 126 NamedDecl *D = static_cast<NamedDecl*>(Ptr); 127 128 if (LC.isEqOrContainedBy(LookupContext(D))) 129 return iterator(D); 130 else 131 return end(II); 132 133 } 134 135 IdDeclInfo *IDI = toIdDeclInfo(Ptr); 136 return iterator(IDI->FindContext(LC)); 137} 138 139/// ctx_begin - Returns an iterator for only decls that belong to the given 140/// declaration context. 141IdentifierResolver::ctx_iterator 142IdentifierResolver::ctx_begin(const IdentifierInfo *II, DeclContext *Ctx) { 143 assert(Ctx && "null param passed"); 144 145 void *Ptr = II->getFETokenInfo<void>(); 146 if (!Ptr) return ctx_end(II); 147 148 LookupContext LC(Ctx); 149 150 if (isDeclPtr(Ptr)) { 151 NamedDecl *D = static_cast<NamedDecl*>(Ptr); 152 153 if (LC == LookupContext(D)) 154 return ctx_iterator(D); 155 else 156 return ctx_end(II); 157 158 } 159 160 IdDeclInfo *IDI = toIdDeclInfo(Ptr); 161 IdDeclInfo::DeclsTy::iterator I = IDI->FindContext(LookupContext(Ctx)); 162 if (I != IDI->decls_begin() && LC != LookupContext(*(I-1))) 163 I = IDI->decls_begin(); 164 165 return ctx_iterator(I); 166} 167 168 169/// Returns the IdDeclInfo associated to the IdentifierInfo. 170/// It creates a new IdDeclInfo if one was not created before for this id. 171IdentifierResolver::IdDeclInfo & 172IdentifierResolver::IdDeclInfoMap::operator[](IdentifierInfo *II) { 173 assert (II && "null IdentifierInfo passed"); 174 void *Ptr = II->getFETokenInfo<void>(); 175 176 if (Ptr) return *toIdDeclInfo(Ptr); 177 178 if (CurIndex == VECTOR_SIZE) { 179 // Add a IdDeclInfo vector 'pool' 180 IDIVecs.push_back(std::vector<IdDeclInfo>()); 181 // Fill the vector 182 IDIVecs.back().resize(VECTOR_SIZE); 183 CurIndex = 0; 184 } 185 IdDeclInfo *IDI = &IDIVecs.back()[CurIndex]; 186 II->setFETokenInfo(reinterpret_cast<void*>( 187 reinterpret_cast<uintptr_t>(IDI) | 0x1) 188 ); 189 ++CurIndex; 190 return *IDI; 191} 192