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