Introduce ContextDecl, patch by Argiris Kirtzidis!

-Added ContextDecl (no TranslationUnitDecl)
-ScopedDecl class has a ContextDecl member
-FieldDecl class has a ContextDecl member, so that a Field or a ObjCIvar can be traced back to their RecordDecl/ObjCInterfaceDecl easily
-FunctionDecl, ObjCMethodDecl, TagDecl, ObjCInterfaceDecl inherit from ContextDecl. With TagDecl as ContextDecl, enum constants have a EnumDecl as their context.
-Moved Decl class to a "DeclBase.h" along with ContextDecl class
-CurContext is handled by Sema




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49208 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index da78ec0..9e379e4 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -59,7 +59,7 @@
   TUScope->AddDecl(IDecl);
   
   // Synthesize "typedef struct objc_selector *SEL;"
-  RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct,
+  RecordDecl *SelTag = RecordDecl::Create(Context, Decl::Struct, CurContext,
                                           SourceLocation(), 
                                           &Context.Idents.get("objc_selector"),
                                           0);
@@ -67,7 +67,8 @@
   TUScope->AddDecl(SelTag);
   
   QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
-  TypedefDecl *SelTypedef = TypedefDecl::Create(Context, SourceLocation(),
+  TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
+                                                SourceLocation(),
                                                 &Context.Idents.get("SEL"),
                                                 SelT, 0);
   SelTypedef->getIdentifier()->setFETokenInfo(SelTypedef);
@@ -77,7 +78,7 @@
 
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
   : PP(pp), Context(ctxt), Consumer(consumer), 
-    CurFunctionDecl(0), CurMethodDecl(0) {
+    CurFunctionDecl(0), CurMethodDecl(0), CurContext(0) {
   
   // Get IdentifierInfo objects for known functions for which we
   // do extra checking.  
@@ -99,11 +100,12 @@
   if (PP.getLangOptions().ObjC1) {
     // Synthesize "typedef struct objc_class *Class;"
     RecordDecl *ClassTag = RecordDecl::Create(Context, Decl::Struct,
-                                              SourceLocation(), 
+                                              NULL,
+                                              SourceLocation(),
                                               &IT.get("objc_class"), 0);
     QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
     TypedefDecl *ClassTypedef = 
-      TypedefDecl::Create(Context, SourceLocation(),
+      TypedefDecl::Create(Context, NULL, SourceLocation(),
                           &Context.Idents.get("Class"), ClassT, 0);
     Context.setObjCClassType(ClassTypedef);
     
@@ -115,13 +117,16 @@
     
     // Synthesize "typedef struct objc_object { Class isa; } *id;"
     RecordDecl *ObjectTag = 
-      RecordDecl::Create(Context, Decl::Struct, SourceLocation(),
+      RecordDecl::Create(Context, Decl::Struct, NULL,
+                         SourceLocation(),
                          &IT.get("objc_object"), 0);
-    FieldDecl *IsaDecl = FieldDecl::Create(Context, SourceLocation(), 0, 
+    FieldDecl *IsaDecl = FieldDecl::Create(Context, ObjectTag,
+                                           SourceLocation(), 0, 
                                            Context.getObjCClassType());
     ObjectTag->defineBody(&IsaDecl, 1);
     QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
-    TypedefDecl *IdTypedef = TypedefDecl::Create(Context, SourceLocation(),
+    TypedefDecl *IdTypedef = TypedefDecl::Create(Context, NULL,
+                                                 SourceLocation(),
                                                  &Context.Idents.get("id"),
                                                  ObjT, 0);
     Context.setObjCIdType(IdTypedef);
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index d2ad5c5..b1d0499 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -32,6 +32,7 @@
   class ASTConsumer;
   class Preprocessor;
   class Decl;
+  class ContextDecl;
   class NamedDecl;
   class ScopedDecl;
   class Expr;
@@ -73,7 +74,9 @@
   /// CurMethodDecl - If inside of a method body, this contains a pointer to
   /// the method decl for the method being parsed.
   ObjCMethodDecl *CurMethodDecl;
-  
+
+  ContextDecl *CurContext;
+
   /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
   /// it (which acts like the label decl in some ways).  Forward referenced
   /// labels have a LabelStmt created for them with a null location & SubStmt.
@@ -246,6 +249,10 @@
   virtual void ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
                              DeclTy **Elements, unsigned NumElements);
 private:
+  /// Set the current declaration context until it gets popped.
+  void PushContextDecl(ContextDecl *CD);
+  void PopContextDecl();
+
   /// Subroutines of ActOnDeclarator().
   TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
                                 ScopedDecl *LastDecl);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c9ea54f..6f0f351 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -40,6 +40,17 @@
   return 0;
 }
 
+void Sema::PushContextDecl(ContextDecl *CD) {
+  assert(CD->getParent() == CurContext &&
+      "The next ContextDecl should be directly contained in the current one.");
+  CurContext = CD;
+}
+
+void Sema::PopContextDecl() {
+  assert(CurContext && "ContextDecl imbalance!");
+  CurContext = CurContext->getParent();
+}
+
 void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
   if (S->decl_empty()) return;
   assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
@@ -156,7 +167,8 @@
     InitBuiltinVaListType();
     
   QualType R = Context.BuiltinInfo.GetBuiltinType(BID, Context);  
-  FunctionDecl *New = FunctionDecl::Create(Context, SourceLocation(), II, R,
+  FunctionDecl *New = FunctionDecl::Create(Context, CurContext,
+                                           SourceLocation(), II, R,
                                            FunctionDecl::Extern, false, 0);
   
   // Find translation-unit scope to insert this function into.
@@ -744,7 +756,8 @@
     }
 
     bool isInline = D.getDeclSpec().isInlineSpecified();
-    FunctionDecl *NewFD = FunctionDecl::Create(Context, D.getIdentifierLoc(),
+    FunctionDecl *NewFD = FunctionDecl::Create(Context, CurContext,
+                                               D.getIdentifierLoc(),
                                                II, R, SC, isInline,
                                                LastDeclarator);
     // Handle attributes.
@@ -784,10 +797,12 @@
              R.getAsString());
         InvalidDecl = true;
       }
-      NewVD = FileVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC,
+      NewVD = FileVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
+                                  II, R, SC,
                                   LastDeclarator);
     } else {
-      NewVD = BlockVarDecl::Create(Context, D.getIdentifierLoc(), II, R, SC,
+      NewVD = BlockVarDecl::Create(Context, CurContext, D.getIdentifierLoc(),
+                                   II, R, SC,
                                    LastDeclarator);
     }
     // Handle attributes prior to checking for duplicates in MergeVarDecl
@@ -1000,7 +1015,8 @@
   } else if (parmDeclType->isFunctionType())
     parmDeclType = Context.getPointerType(parmDeclType);
   
-  ParmVarDecl *New = ParmVarDecl::Create(Context, PI.IdentLoc, II, parmDeclType, 
+  ParmVarDecl *New = ParmVarDecl::Create(Context, CurContext, PI.IdentLoc, II,
+                                         parmDeclType, 
                                          VarDecl::None, 0);
   
   if (PI.InvalidType)
@@ -1060,6 +1076,7 @@
   Decl *decl = static_cast<Decl*>(ActOnDeclarator(GlobalScope, D, 0));
   FunctionDecl *FD = cast<FunctionDecl>(decl);
   CurFunctionDecl = FD;
+  PushContextDecl(FD);
   
   // Create Decl objects for each parameter, adding them to the FunctionDecl.
   llvm::SmallVector<ParmVarDecl*, 16> Params;
@@ -1104,6 +1121,7 @@
     MD->setBody((Stmt*)Body);
     CurMethodDecl = 0;
   }  
+  PopContextDecl();
   // Verify and clean out per-function state.
   
   // Check goto/label use.
@@ -1173,7 +1191,8 @@
   assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
   
   // Scope manipulation handled by caller.
-  TypedefDecl *NewTD = TypedefDecl::Create(Context, D.getIdentifierLoc(), 
+  TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
+                                           D.getIdentifierLoc(),
                                            D.getIdentifier(), 
                                            T, LastDeclarator);
   if (D.getInvalidType())
@@ -1253,7 +1272,7 @@
   case Decl::Enum:
     // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
     // enum X { A, B, C } D;    D should chain to X.
-    New = EnumDecl::Create(Context, Loc, Name, 0);
+    New = EnumDecl::Create(Context, CurContext, Loc, Name, 0);
     // If this is an undefined enum, warn.
     if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum);
     break;
@@ -1262,7 +1281,7 @@
   case Decl::Class:
     // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
     // struct X { int A; } D;    D should chain to X.
-    New = RecordDecl::Create(Context, Kind, Loc, Name, 0);
+    New = RecordDecl::Create(Context, Kind, CurContext, Loc, Name, 0);
     break;
   }    
   
@@ -1326,8 +1345,8 @@
   // FIXME: Chain fielddecls together.
   FieldDecl *NewFD;
   
-  if (isa<RecordDecl>(TagDecl))
-    NewFD = FieldDecl::Create(Context, Loc, II, T, BitWidth);
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(TagDecl))
+    NewFD = FieldDecl::Create(Context, RD, Loc, II, T, BitWidth);
   else if (isa<ObjCInterfaceDecl>(TagDecl) ||
            isa<ObjCImplementationDecl>(TagDecl) ||
            isa<ObjCCategoryDecl>(TagDecl) ||
@@ -1335,7 +1354,7 @@
            // properties can appear within a protocol.
            // See corresponding FIXME in DeclObjC.h:ObjCPropertyDecl.
            isa<ObjCProtocolDecl>(TagDecl))
-    NewFD = ObjCIvarDecl::Create(Context, Loc, II, T);
+    NewFD = ObjCIvarDecl::Create(Context, dyn_cast<ObjCInterfaceDecl>(TagDecl), Loc, II, T);
   else
     assert(0 && "Sema::ActOnField(): Unknown TagDecl");
     
@@ -1515,7 +1534,7 @@
                                       DeclTy *lastEnumConst,
                                       SourceLocation IdLoc, IdentifierInfo *Id,
                                       SourceLocation EqualLoc, ExprTy *val) {
-  theEnumDecl = theEnumDecl;  // silence unused warning.
+  EnumDecl *TheEnumDecl = cast<EnumDecl>(static_cast<Decl*>(theEnumDecl));
   EnumConstantDecl *LastEnumConst =
     cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst));
   Expr *Val = static_cast<Expr*>(val);
@@ -1576,7 +1595,8 @@
   }
   
   EnumConstantDecl *New = 
-    EnumConstantDecl::Create(Context, IdLoc, Id, EltTy, Val, EnumVal,
+    EnumConstantDecl::Create(Context, TheEnumDecl, IdLoc, Id, EltTy,
+                             Val, EnumVal,
                              LastEnumConst);
   
   // Register this decl in the current scope stack.
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 69a1022..6b9b9e2 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -33,6 +33,7 @@
   
   // Allow all of Sema to see that we are entering a method definition.
   CurMethodDecl = MDecl;
+  PushContextDecl(MDecl);
 
   // Create Decl objects for each parameter, entrring them in the scope for
   // binding to their use.
@@ -813,23 +814,6 @@
     Diag(MethodLoc, diag::error_missing_method_context);
     return 0;
   }
-  llvm::SmallVector<ParmVarDecl*, 16> Params;
-  
-  for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
-    // FIXME: arg->AttrList must be stored too!
-    QualType argType;
-    
-    if (ArgTypes[i])
-      argType = QualType::getFromOpaquePtr(ArgTypes[i]);
-    else
-      argType = Context.getObjCIdType();
-    ParmVarDecl* Param = ParmVarDecl::Create(Context, SourceLocation(/*FIXME*/),
-                                             ArgNames[i], argType,
-                                             VarDecl::None, 0);
-    Param->setObjCDeclQualifier(
-      CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
-    Params.push_back(Param);
-  }
   QualType resultDeclType;
   
   if (ReturnType)
@@ -845,6 +829,25 @@
                            ObjCMethodDecl::Optional : 
                            ObjCMethodDecl::Required);
   
+  llvm::SmallVector<ParmVarDecl*, 16> Params;
+  
+  for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
+    // FIXME: arg->AttrList must be stored too!
+    QualType argType;
+    
+    if (ArgTypes[i])
+      argType = QualType::getFromOpaquePtr(ArgTypes[i]);
+    else
+      argType = Context.getObjCIdType();
+    ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
+                                             SourceLocation(/*FIXME*/),
+                                             ArgNames[i], argType,
+                                             VarDecl::None, 0);
+    Param->setObjCDeclQualifier(
+      CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
+    Params.push_back(Param);
+  }
+
   ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
   ObjCMethod->setObjCDeclQualifier(
     CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));