IdentifierResolver.cpp [plain text]
#include "clang/Sema/IdentifierResolver.h"
#include "clang/Sema/Scope.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/LangOptions.h"
using namespace clang;
class IdentifierResolver::IdDeclInfoMap {
static const unsigned int POOL_SIZE = 512;
struct IdDeclInfoPool {
IdDeclInfoPool(IdDeclInfoPool *Next) : Next(Next) {}
IdDeclInfoPool *Next;
IdDeclInfo Pool[POOL_SIZE];
};
IdDeclInfoPool *CurPool;
unsigned int CurIndex;
public:
IdDeclInfoMap() : CurPool(0), CurIndex(POOL_SIZE) {}
~IdDeclInfoMap() {
IdDeclInfoPool *Cur = CurPool;
while (IdDeclInfoPool *P = Cur) {
Cur = Cur->Next;
delete P;
}
}
IdDeclInfo &operator[](DeclarationName Name);
};
void IdentifierResolver::IdDeclInfo::RemoveDecl(NamedDecl *D) {
for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
if (D == *(I-1)) {
Decls.erase(I-1);
return;
}
}
assert(0 && "Didn't find this decl on its identifier's chain!");
}
bool
IdentifierResolver::IdDeclInfo::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
for (DeclsTy::iterator I = Decls.end(); I != Decls.begin(); --I) {
if (Old == *(I-1)) {
*(I - 1) = New;
return true;
}
}
return false;
}
IdentifierResolver::IdentifierResolver(const LangOptions &langOpt)
: LangOpt(langOpt), IdDeclInfos(new IdDeclInfoMap) {
}
IdentifierResolver::~IdentifierResolver() {
delete IdDeclInfos;
}
bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
ASTContext &Context, Scope *S,
bool ExplicitInstantiationOrSpecialization) const {
Ctx = Ctx->getRedeclContext();
if (Ctx->isFunctionOrMethod()) {
while (S->getEntity() &&
((DeclContext *)S->getEntity())->isTransparentContext())
S = S->getParent();
if (S->isDeclScope(D))
return true;
if (LangOpt.CPlusPlus) {
assert(S->getParent() && "No TUScope?");
if (S->getParent()->getFlags() & Scope::ControlScope)
return S->getParent()->isDeclScope(D);
}
return false;
}
DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
return ExplicitInstantiationOrSpecialization
? Ctx->InEnclosingNamespaceSetOf(DCtx)
: Ctx->Equals(DCtx);
}
void IdentifierResolver::AddDecl(NamedDecl *D) {
DeclarationName Name = D->getDeclName();
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
II->setIsFromAST(false);
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) {
Name.setFETokenInfo(D);
return;
}
IdDeclInfo *IDI;
if (isDeclPtr(Ptr)) {
Name.setFETokenInfo(NULL);
IDI = &(*IdDeclInfos)[Name];
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
IDI->AddDecl(PrevD);
} else
IDI = toIdDeclInfo(Ptr);
IDI->AddDecl(D);
}
void IdentifierResolver::InsertDeclAfter(iterator Pos, NamedDecl *D) {
DeclarationName Name = D->getDeclName();
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) {
AddDecl(D);
return;
}
if (isDeclPtr(Ptr)) {
if (Pos == iterator()) {
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
RemoveDecl(PrevD);
AddDecl(D);
AddDecl(PrevD);
} else {
AddDecl(D);
}
return;
}
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
II->setIsFromAST(false);
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
if (Pos.isIterator()) {
IDI->InsertDecl(Pos.getIterator() + 1, D);
} else
IDI->InsertDecl(IDI->decls_begin(), D);
}
void IdentifierResolver::RemoveDecl(NamedDecl *D) {
assert(D && "null param passed");
DeclarationName Name = D->getDeclName();
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
II->setIsFromAST(false);
void *Ptr = Name.getFETokenInfo<void>();
assert(Ptr && "Didn't find this decl on its identifier's chain!");
if (isDeclPtr(Ptr)) {
assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
Name.setFETokenInfo(NULL);
return;
}
return toIdDeclInfo(Ptr)->RemoveDecl(D);
}
bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
assert(Old->getDeclName() == New->getDeclName() &&
"Cannot replace a decl with another decl of a different name");
DeclarationName Name = Old->getDeclName();
if (IdentifierInfo *II = Name.getAsIdentifierInfo())
II->setIsFromAST(false);
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr)
return false;
if (isDeclPtr(Ptr)) {
if (Ptr == Old) {
Name.setFETokenInfo(New);
return true;
}
return false;
}
return toIdDeclInfo(Ptr)->ReplaceDecl(Old, New);
}
IdentifierResolver::iterator
IdentifierResolver::begin(DeclarationName Name) {
void *Ptr = Name.getFETokenInfo<void>();
if (!Ptr) return end();
if (isDeclPtr(Ptr))
return iterator(static_cast<NamedDecl*>(Ptr));
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
if (I != IDI->decls_begin())
return iterator(I-1);
return end();
}
void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
NamedDecl *D) {
II->setIsFromAST(false);
void *Ptr = II->getFETokenInfo<void>();
if (!Ptr) {
II->setFETokenInfo(D);
return;
}
IdDeclInfo *IDI;
if (isDeclPtr(Ptr)) {
II->setFETokenInfo(NULL);
IDI = &(*IdDeclInfos)[II];
NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
IDI->AddDecl(PrevD);
} else
IDI = toIdDeclInfo(Ptr);
IDI->AddDecl(D);
}
IdentifierResolver::IdDeclInfo &
IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
void *Ptr = Name.getFETokenInfo<void>();
if (Ptr) return *toIdDeclInfo(Ptr);
if (CurIndex == POOL_SIZE) {
CurPool = new IdDeclInfoPool(CurPool);
CurIndex = 0;
}
IdDeclInfo *IDI = &CurPool->Pool[CurIndex];
Name.setFETokenInfo(reinterpret_cast<void*>(
reinterpret_cast<uintptr_t>(IDI) | 0x1)
);
++CurIndex;
return *IDI;
}
void IdentifierResolver::iterator::incrementSlowCase() {
NamedDecl *D = **this;
void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
BaseIter I = getIterator();
if (I != Info->decls_begin())
*this = iterator(I-1);
else *this = iterator();
}