blob: 0b63ad9b530d19dbe8bab0149169f3d7dcf392a9 [file] [log] [blame]
Chris Lattnera2f42b12008-04-11 07:06:57 +00001//===- 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//
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000010// This file implements the IdentifierResolver class, which is used for lexical
Chris Lattnera2f42b12008-04-11 07:06:57 +000011// scoped lookup, based on identifier.
12//
13//===----------------------------------------------------------------------===//
14
15#include "IdentifierResolver.h"
Chris Lattnera2f42b12008-04-11 07:06:57 +000016#include <list>
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000017#include <vector>
Chris Lattnera2f42b12008-04-11 07:06:57 +000018
19using namespace clang;
20
Chris Lattnera2f42b12008-04-11 07:06:57 +000021
22/// IdDeclInfoMap - Associates IdDeclInfos with Identifiers.
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000023/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
Chris Lattnera2f42b12008-04-11 07:06:57 +000024/// individual IdDeclInfo to heap.
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000025class IdentifierResolver::IdDeclInfoMap {
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000026 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;
Chris Lattnera2f42b12008-04-11 07:06:57 +000030 unsigned int CurIndex;
31
32public:
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000033 IdDeclInfoMap() : CurIndex(VECTOR_SIZE) {}
Chris Lattnera2f42b12008-04-11 07:06:57 +000034
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
Argyrios Kyrtzidis7bc198f2008-04-14 00:09:21 +000040
41IdentifierResolver::IdentifierResolver() : IdDeclInfos(new IdDeclInfoMap) {}
42IdentifierResolver::~IdentifierResolver() {
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000043 delete IdDeclInfos;
Argyrios Kyrtzidis7bc198f2008-04-14 00:09:21 +000044}
Chris Lattnera2f42b12008-04-11 07:06:57 +000045
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000046/// AddDecl - Link the decl to its shadowed decl chain.
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000047void IdentifierResolver::AddDecl(NamedDecl *D) {
Chris Lattnera2f42b12008-04-11 07:06:57 +000048 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);
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000060 IDI = &(*IdDeclInfos)[II];
61 NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
62 IDI->AddDecl(PrevD);
Chris Lattnera2f42b12008-04-11 07:06:57 +000063 } else
64 IDI = toIdDeclInfo(Ptr);
65
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000066 IDI->AddDecl(D);
Chris Lattnera2f42b12008-04-11 07:06:57 +000067}
68
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000069/// AddShadowedDecl - Link the decl to its shadowed decl chain putting it
Argyrios Kyrtzidis3d0d83a2008-05-15 17:26:35 +000070/// after the decl that the iterator points to, thus the 'Shadow' decl will be
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000071/// 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
Chris Lattnera2f42b12008-04-11 07:06:57 +000076 IdentifierInfo *II = D->getIdentifier();
77 void *Ptr = II->getFETokenInfo<void>();
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000078 assert(Ptr && "No decl from Ptr ?");
Chris Lattnera2f42b12008-04-11 07:06:57 +000079
80 IdDeclInfo *IDI;
81
82 if (isDeclPtr(Ptr)) {
83 II->setFETokenInfo(NULL);
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000084 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 }
Chris Lattnera2f42b12008-04-11 07:06:57 +000091
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +000092 IDI = toIdDeclInfo(Ptr);
93 IDI->AddShadowed(D, Shadow);
Chris Lattnera2f42b12008-04-11 07:06:57 +000094}
95
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +000096/// RemoveDecl - Unlink the decl from its shadowed decl chain.
Chris Lattnera2f42b12008-04-11 07:06:57 +000097/// 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
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000111 return toIdDeclInfo(Ptr)->RemoveDecl(D);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000112}
113
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000114/// begin - Returns an iterator for decls of identifier 'II', starting at
115/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
116/// decls of parent declaration contexts too.
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000117IdentifierResolver::iterator
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000118IdentifierResolver::begin(const IdentifierInfo *II, DeclContext *Ctx,
119 bool LookInParentCtx) {
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000120 assert(Ctx && "null param passed");
Chris Lattnera2f42b12008-04-11 07:06:57 +0000121
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000122 void *Ptr = II->getFETokenInfo<void>();
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000123 if (!Ptr) return end();
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000124
125 LookupContext LC(Ctx);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000126
127 if (isDeclPtr(Ptr)) {
128 NamedDecl *D = static_cast<NamedDecl*>(Ptr);
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000129 LookupContext DC(D);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000130
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000131 if (( LookInParentCtx && LC.isEqOrContainedBy(DC)) ||
132 (!LookInParentCtx && LC == DC))
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000133 return iterator(D);
134 else
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000135 return end();
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000136 }
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000137
Chris Lattnera2f42b12008-04-11 07:06:57 +0000138 IdDeclInfo *IDI = toIdDeclInfo(Ptr);
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000139
140 IdDeclInfo::DeclsTy::iterator I;
141 if (LookInParentCtx)
142 I = IDI->FindContext(LC);
143 else {
144 for (I = IDI->decls_end(); I != IDI->decls_begin(); --I)
145 if (LookupContext(*(I-1)) == LC)
146 break;
147 }
148
149 if (I != IDI->decls_begin())
150 return iterator(I-1, LookInParentCtx);
151 else // No decls found.
152 return end();
Chris Lattnera2f42b12008-04-11 07:06:57 +0000153}
154
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000155/// PreIncIter - Do a preincrement when 'Ptr' is a BaseIter.
156void IdentifierResolver::iterator::PreIncIter() {
157 NamedDecl *D = **this;
158 LookupContext Ctx(D);
159 void *InfoPtr = D->getIdentifier()->getFETokenInfo<void>();
160 assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
161 IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000162
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000163 BaseIter I = getIterator();
164 if (LookInParentCtx())
165 I = Info->FindContext(Ctx, I);
166 else {
167 if (I != Info->decls_begin() && LookupContext(*(I-1)) != Ctx) {
168 // The next decl is in different declaration context.
169 // Skip remaining decls and set the iterator to the end.
170 I = Info->decls_begin();
171 }
Chris Lattnera2f42b12008-04-11 07:06:57 +0000172 }
173
Argyrios Kyrtzidis90eb5392008-07-17 17:49:50 +0000174 if (I != Info->decls_begin())
175 *this = iterator(I-1, LookInParentCtx());
176 else // No more decls.
177 *this = end();
Chris Lattnera2f42b12008-04-11 07:06:57 +0000178}
179
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000180
Chris Lattnera2f42b12008-04-11 07:06:57 +0000181/// Returns the IdDeclInfo associated to the IdentifierInfo.
182/// It creates a new IdDeclInfo if one was not created before for this id.
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000183IdentifierResolver::IdDeclInfo &
184IdentifierResolver::IdDeclInfoMap::operator[](IdentifierInfo *II) {
Chris Lattnera2f42b12008-04-11 07:06:57 +0000185 assert (II && "null IdentifierInfo passed");
186 void *Ptr = II->getFETokenInfo<void>();
187
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000188 if (Ptr) return *toIdDeclInfo(Ptr);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000189
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000190 if (CurIndex == VECTOR_SIZE) {
191 // Add a IdDeclInfo vector 'pool'
Argyrios Kyrtzidis72e62b02008-04-12 12:38:58 +0000192 IDIVecs.push_back(std::vector<IdDeclInfo>());
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000193 // Fill the vector
194 IDIVecs.back().resize(VECTOR_SIZE);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000195 CurIndex = 0;
196 }
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000197 IdDeclInfo *IDI = &IDIVecs.back()[CurIndex];
Chris Lattnera2f42b12008-04-11 07:06:57 +0000198 II->setFETokenInfo(reinterpret_cast<void*>(
199 reinterpret_cast<uintptr_t>(IDI) | 0x1)
200 );
201 ++CurIndex;
202 return *IDI;
203}