From: Chris Lattner Date: Fri, 11 Apr 2008 07:00:53 +0000 (+0000) Subject: Switch sema to maintaining its own scope chain information for variable X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7f925cc1071117ebe3191db33bbdfd706af297e9;p=clang Switch sema to maintaining its own scope chain information for variable shadowing, instead of threading it through the AST. This patch contributed by Argiris Kirtzidis! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49520 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 8c9bceae21..a0d4ff7995 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -48,14 +48,14 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { // Add the built-in ObjC types. t = cast(Context.getObjCIdType().getTypePtr()); - t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); + IdResolver.AddDecl(t->getDecl(), S); TUScope->AddDecl(t->getDecl()); t = cast(Context.getObjCClassType().getTypePtr()); - t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); + IdResolver.AddDecl(t->getDecl(), S); TUScope->AddDecl(t->getDecl()); ObjCInterfaceType *it = cast(Context.getObjCProtoType()); ObjCInterfaceDecl *IDecl = it->getDecl(); - IDecl->getIdentifier()->setFETokenInfo(IDecl); + IdResolver.AddDecl(IDecl, S); TUScope->AddDecl(IDecl); // Synthesize "typedef struct objc_selector *SEL;" @@ -63,7 +63,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { SourceLocation(), &Context.Idents.get("objc_selector"), 0); - SelTag->getIdentifier()->setFETokenInfo(SelTag); + IdResolver.AddDecl(SelTag, S); TUScope->AddDecl(SelTag); QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag)); @@ -71,7 +71,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { SourceLocation(), &Context.Idents.get("SEL"), SelT, 0); - SelTypedef->getIdentifier()->setFETokenInfo(SelTypedef); + IdResolver.AddDecl(SelTypedef, S); TUScope->AddDecl(SelTypedef); Context.setObjCSelType(SelTypedef); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 143257aeab..3b352bf354 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_AST_SEMA_H #define LLVM_CLANG_AST_SEMA_H +#include "IdentifierResolver.h" #include "clang/Parse/Action.h" #include "clang/Parse/DeclSpec.h" #include "llvm/ADT/SmallVector.h" @@ -113,6 +114,8 @@ class Sema : public Action { ObjCCompatibleAliasDecl*> ObjCAliasTy; ObjCAliasTy ObjCAliasDecls; + IdentifierResolver IdResolver; + // Enum values used by KnownFunctionIDs (see below). enum { id_printf, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 157700f579..a7f8bad574 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -65,23 +65,9 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { IdentifierInfo *II = D->getIdentifier(); if (!II) continue; - // Unlink this decl from the identifier. Because the scope contains decls - // in an unordered collection, and because we have multiple identifier - // namespaces (e.g. tag, normal, label),the decl may not be the first entry. - if (II->getFETokenInfo() == D) { - // Normal case, no multiple decls in different namespaces. - II->setFETokenInfo(D->getNext()); - } else { - // Scan ahead. There are only three namespaces in C, so this loop can - // never execute more than 3 times. - ScopedDecl *SomeDecl = II->getFETokenInfo(); - while (SomeDecl->getNext() != D) { - SomeDecl = SomeDecl->getNext(); - assert(SomeDecl && "Didn't find this decl on its identifier's chain!"); - } - SomeDecl->setNext(D->getNext()); - } - + // Unlink this decl from the identifier. + IdResolver.RemoveDecl(D); + // This will have to be revisited for C++: there we want to nest stuff in // namespace decls etc. Even for C, we might want a top-level translation // unit decl or something. @@ -111,14 +97,13 @@ Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI, Scope *S, bool enableLazyBuiltinCreation) { if (II == 0) return 0; Decl::IdentifierNamespace NS = (Decl::IdentifierNamespace)NSI; - + // Scan up the scope chain looking for a decl that matches this identifier // that is in the appropriate namespace. This search should not take long, as // shadowing of names is uncommon, and deep shadowing is extremely uncommon. - for (ScopedDecl *D = II->getFETokenInfo(); D; D = D->getNext()) - if (D->getIdentifierNamespace() == NS) - return D; - + NamedDecl *ND = IdResolver.Lookup(II, NS); + if (ND) return ND; + // If we didn't find a use of this identifier, and if the identifier // corresponds to a compiler builtin, create the decl object for the builtin // now, injecting it into translation unit scope, and return it. @@ -171,23 +156,12 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, SourceLocation(), II, R, FunctionDecl::Extern, false, 0); - // Find translation-unit scope to insert this function into. - if (Scope *FnS = S->getFnParent()) - S = FnS->getParent(); // Skip all scopes in a function at once. - while (S->getParent()) - S = S->getParent(); - S->AddDecl(New); + // TUScope is the translation-unit scope to insert this function into. + TUScope->AddDecl(New); // Add this decl to the end of the identifier info. - if (ScopedDecl *LastDecl = II->getFETokenInfo()) { - // Scan until we find the last (outermost) decl in the id chain. - while (LastDecl->getNext()) - LastDecl = LastDecl->getNext(); - // Insert before (outside) it. - LastDecl->setNext(New); - } else { - II->setFETokenInfo(New); - } + IdResolver.AddGlobalDecl(New); + return New; } @@ -456,8 +430,7 @@ Sema::CreateImplicitParameter(Scope *S, IdentifierInfo *Id, ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, IdLoc, Id, Type, VarDecl::None, 0, 0); if (Id) { - New->setNext(Id->getFETokenInfo()); - Id->setFETokenInfo(New); + IdResolver.AddDecl(New, S); S->AddDecl(New); } @@ -924,8 +897,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { // If this has an identifier, add it to the scope stack. if (II) { - New->setNext(II->getFETokenInfo()); - II->setFETokenInfo(New); + IdResolver.AddDecl(New, S); S->AddDecl(New); } // If any semantic error occurred, mark the decl as invalid. @@ -1146,8 +1118,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { New->setInvalidDecl(); if (II) { - New->setNext(II->getFETokenInfo()); - II->setFETokenInfo(New); + IdResolver.AddDecl(New, S); S->AddDecl(New); } @@ -1213,9 +1184,8 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) { ParmVarDecl *Param = FD->getParamDecl(p); // If this has an identifier, add it to the scope stack. - if (IdentifierInfo *II = Param->getIdentifier()) { - Param->setNext(II->getFETokenInfo()); - II->setFETokenInfo(Param); + if (Param->getIdentifier()) { + IdResolver.AddDecl(Param, FnBodyScope); FnBodyScope->AddDecl(Param); } } @@ -1408,8 +1378,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, S = S->getParent(); // Add it to the decl chain. - New->setNext(Name->getFETokenInfo()); - Name->setFETokenInfo(New); + IdResolver.AddDecl(New, S); S->AddDecl(New); } @@ -1752,8 +1721,7 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl, LastEnumConst); // Register this decl in the current scope stack. - New->setNext(Id->getFETokenInfo()); - Id->setFETokenInfo(New); + IdResolver.AddDecl(New, S); S->AddDecl(New); return New; } diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 8d09727dd0..127645044c 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -63,8 +63,7 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) { ParmVarDecl *PDecl = MDecl->getParamDecl(i); IdentifierInfo *II = PDecl->getIdentifier(); if (II) { - PDecl->setNext(II->getFETokenInfo()); - II->setFETokenInfo(PDecl); + IdResolver.AddDecl(PDecl, FnBodyScope); FnBodyScope->AddDecl(PDecl); } } @@ -926,3 +925,5 @@ Sema::DeclTy *Sema::ActOnAddObjCProperties(SourceLocation AtLoc, return PDecl; } + +