blob: fada62f10b4672d9ea3e0de7451db6313ce60bc2 [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
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
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 Kyrtzidis00bc6452008-05-09 23:39:43 +0000114/// 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");
Chris Lattnera2f42b12008-04-11 07:06:57 +0000119
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000120 void *Ptr = II->getFETokenInfo<void>();
121 if (!Ptr) return end(II);
122
123 LookupContext LC(Ctx);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000124
125 if (isDeclPtr(Ptr)) {
126 NamedDecl *D = static_cast<NamedDecl*>(Ptr);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000127
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000128 if (LC.isEqOrContainedBy(LookupContext(D)))
129 return iterator(D);
130 else
131 return end(II);
132
133 }
134
Chris Lattnera2f42b12008-04-11 07:06:57 +0000135 IdDeclInfo *IDI = toIdDeclInfo(Ptr);
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000136 return iterator(IDI->FindContext(LC));
Chris Lattnera2f42b12008-04-11 07:06:57 +0000137}
138
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000139/// 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");
Chris Lattnera2f42b12008-04-11 07:06:57 +0000144
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000145 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
Chris Lattnera2f42b12008-04-11 07:06:57 +0000158 }
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000159
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();
Chris Lattnera2f42b12008-04-11 07:06:57 +0000164
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000165 return ctx_iterator(I);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000166}
167
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000168
Chris Lattnera2f42b12008-04-11 07:06:57 +0000169/// Returns the IdDeclInfo associated to the IdentifierInfo.
170/// It creates a new IdDeclInfo if one was not created before for this id.
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000171IdentifierResolver::IdDeclInfo &
172IdentifierResolver::IdDeclInfoMap::operator[](IdentifierInfo *II) {
Chris Lattnera2f42b12008-04-11 07:06:57 +0000173 assert (II && "null IdentifierInfo passed");
174 void *Ptr = II->getFETokenInfo<void>();
175
Argyrios Kyrtzidis00bc6452008-05-09 23:39:43 +0000176 if (Ptr) return *toIdDeclInfo(Ptr);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000177
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000178 if (CurIndex == VECTOR_SIZE) {
179 // Add a IdDeclInfo vector 'pool'
Argyrios Kyrtzidis72e62b02008-04-12 12:38:58 +0000180 IDIVecs.push_back(std::vector<IdDeclInfo>());
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000181 // Fill the vector
182 IDIVecs.back().resize(VECTOR_SIZE);
Chris Lattnera2f42b12008-04-11 07:06:57 +0000183 CurIndex = 0;
184 }
Argyrios Kyrtzidis321f2782008-04-12 01:50:47 +0000185 IdDeclInfo *IDI = &IDIVecs.back()[CurIndex];
Chris Lattnera2f42b12008-04-11 07:06:57 +0000186 II->setFETokenInfo(reinterpret_cast<void*>(
187 reinterpret_cast<uintptr_t>(IDI) | 0x1)
188 );
189 ++CurIndex;
190 return *IDI;
191}