]> granicus.if.org Git - clang/commitdiff
Switch sema to maintaining its own scope chain information for variable
authorChris Lattner <sabre@nondot.org>
Fri, 11 Apr 2008 07:00:53 +0000 (07:00 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 11 Apr 2008 07:00:53 +0000 (07:00 +0000)
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

lib/Sema/Sema.cpp
lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp

index 8c9bceae21005d2b57547f1e8ae4c02625527c8d..a0d4ff799567cbd395f1aa3d53d42834fc770133 100644 (file)
@@ -48,14 +48,14 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
   
   // Add the built-in ObjC types.
   t = cast<TypedefType>(Context.getObjCIdType().getTypePtr());
-  t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl());
+  IdResolver.AddDecl(t->getDecl(), S);
   TUScope->AddDecl(t->getDecl());
   t = cast<TypedefType>(Context.getObjCClassType().getTypePtr());
-  t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl());
+  IdResolver.AddDecl(t->getDecl(), S);
   TUScope->AddDecl(t->getDecl());
   ObjCInterfaceType *it = cast<ObjCInterfaceType>(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);
 }
index 143257aeab85d30e7d4fb0760a60c02960ad5114..3b352bf3545318675c447520840f1d5f2cd1cf4c 100644 (file)
@@ -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,
index 157700f5794ae1f880de73b5fa00c927d0398d6f..a7f8bad574c7fb369ad573bacdc634a89d0f2faa 100644 (file)
@@ -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<Decl>() == 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<ScopedDecl>();
-      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<ScopedDecl>(); 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<ScopedDecl>()) {
-    // 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<ScopedDecl>());
-    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<ScopedDecl>());
-    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<ScopedDecl>());
-    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<ScopedDecl>());
-      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<ScopedDecl>());
-    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<ScopedDecl>());
-  Id->setFETokenInfo(New);
+  IdResolver.AddDecl(New, S);
   S->AddDecl(New);
   return New;
 }
index 8d09727dd009cb09ae08cfadc6aa8f2f3eda35c8..127645044c3df2939dcb504a4682b907b60a39fa 100644 (file)
@@ -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<ScopedDecl>());
-      II->setFETokenInfo(PDecl);
+      IdResolver.AddDecl(PDecl, FnBodyScope);
       FnBodyScope->AddDecl(PDecl);
     }
   }
@@ -926,3 +925,5 @@ Sema::DeclTy *Sema::ActOnAddObjCProperties(SourceLocation AtLoc,
   return PDecl;
 }
 
+
+