]> granicus.if.org Git - clang/commitdiff
Introduce ContextDecl, patch by Argiris Kirtzidis!
authorChris Lattner <sabre@nondot.org>
Fri, 4 Apr 2008 06:12:32 +0000 (06:12 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 4 Apr 2008 06:12:32 +0000 (06:12 +0000)
-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

12 files changed:
Driver/RewriteTest.cpp
include/clang/AST/Decl.h
include/clang/AST/DeclBase.h [new file with mode: 0644]
include/clang/AST/DeclObjC.h
lib/AST/ASTContext.cpp
lib/AST/Decl.cpp
lib/AST/DeclObjC.cpp
lib/AST/DeclSerialization.cpp
lib/Sema/Sema.cpp
lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp

index c5645762486c8b9649d30e862c9448182ef8f39b..b7c65a5e2bf68239f242564436885a9f5ddd2ce8 100644 (file)
@@ -822,7 +822,7 @@ Stmt *RewriteTest::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
         std::string RecName = clsDeclared->getIdentifier()->getName();
         RecName += "_IMPL";
         IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
-        RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, 
+        RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL,
                                             SourceLocation(), II, 0);
         assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
         QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
@@ -1581,7 +1581,8 @@ void RewriteTest::SynthSelGetUidFunctionDecl() {
   QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(),
                                                    &ArgTys[0], ArgTys.size(),
                                                    false /*isVariadic*/);
-  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                           SourceLocation(), 
                                            SelGetUidIdent, getFuncType,
                                            FunctionDecl::Extern, false, 0);
 }
@@ -1595,7 +1596,8 @@ void RewriteTest::SynthGetProtocolFunctionDecl() {
   QualType getFuncType = Context->getFunctionType(Context->getObjCProtoType(),
                                                   &ArgTys[0], ArgTys.size(),
                                                   false /*isVariadic*/);
-  GetProtocolFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  GetProtocolFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                             SourceLocation(), 
                                              SelGetProtoIdent, getFuncType,
                                              FunctionDecl::Extern, false, 0);
 }
@@ -1622,7 +1624,8 @@ void RewriteTest::SynthSuperContructorFunctionDecl() {
   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
                                                   &ArgTys[0], ArgTys.size(),
                                                   false);
-  SuperContructorFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  SuperContructorFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                         SourceLocation(), 
                                          msgSendIdent, msgSendType,
                                          FunctionDecl::Extern, false, 0);
 }
@@ -1640,7 +1643,8 @@ void RewriteTest::SynthMsgSendFunctionDecl() {
   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
                                                   &ArgTys[0], ArgTys.size(),
                                                   true /*isVariadic*/);
-  MsgSendFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  MsgSendFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                         SourceLocation(),
                                          msgSendIdent, msgSendType,
                                          FunctionDecl::Extern, false, 0);
 }
@@ -1649,7 +1653,8 @@ void RewriteTest::SynthMsgSendFunctionDecl() {
 void RewriteTest::SynthMsgSendSuperFunctionDecl() {
   IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
   llvm::SmallVector<QualType, 16> ArgTys;
-  RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, SourceLocation(),
+  RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL,
+                                      SourceLocation(),
                                       &Context->Idents.get("objc_super"), 0);
   QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
   assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
@@ -1660,7 +1665,8 @@ void RewriteTest::SynthMsgSendSuperFunctionDecl() {
   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
                                                   &ArgTys[0], ArgTys.size(),
                                                   true /*isVariadic*/);
-  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                              SourceLocation(), 
                                               msgSendIdent, msgSendType,
                                               FunctionDecl::Extern, false, 0);
 }
@@ -1678,7 +1684,8 @@ void RewriteTest::SynthMsgSendStretFunctionDecl() {
   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
                                                   &ArgTys[0], ArgTys.size(),
                                                   true /*isVariadic*/);
-  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                         SourceLocation(), 
                                          msgSendIdent, msgSendType,
                                          FunctionDecl::Extern, false, 0);
 }
@@ -1689,7 +1696,8 @@ void RewriteTest::SynthMsgSendSuperStretFunctionDecl() {
   IdentifierInfo *msgSendIdent = 
     &Context->Idents.get("objc_msgSendSuper_stret");
   llvm::SmallVector<QualType, 16> ArgTys;
-  RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, SourceLocation(),
+  RecordDecl *RD = RecordDecl::Create(*Context, Decl::Struct, NULL,
+                                      SourceLocation(),
                                       &Context->Idents.get("objc_super"), 0);
   QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
   assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
@@ -1700,7 +1708,7 @@ void RewriteTest::SynthMsgSendSuperStretFunctionDecl() {
   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
                                                   &ArgTys[0], ArgTys.size(),
                                                   true /*isVariadic*/);
-  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context,
+  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, NULL,
                                                        SourceLocation(), 
                                               msgSendIdent, msgSendType,
                                               FunctionDecl::Extern, false, 0);
@@ -1719,7 +1727,8 @@ void RewriteTest::SynthMsgSendFpretFunctionDecl() {
   QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
                                                   &ArgTys[0], ArgTys.size(),
                                                   true /*isVariadic*/);
-  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                              SourceLocation(), 
                                               msgSendIdent, msgSendType,
                                               FunctionDecl::Extern, false, 0);
 }
@@ -1733,7 +1742,8 @@ void RewriteTest::SynthGetClassFunctionDecl() {
   QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
                                                    &ArgTys[0], ArgTys.size(),
                                                    false /*isVariadic*/);
-  GetClassFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  GetClassFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                          SourceLocation(), 
                                           getClassIdent, getClassType,
                                           FunctionDecl::Extern, false, 0);
 }
@@ -1747,7 +1757,8 @@ void RewriteTest::SynthGetMetaClassFunctionDecl() {
   QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
                                                    &ArgTys[0], ArgTys.size(),
                                                    false /*isVariadic*/);
-  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, SourceLocation(), 
+  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, NULL,
+                                              SourceLocation(), 
                                               getClassIdent, getClassType,
                                               FunctionDecl::Extern, false, 0);
 }
@@ -1769,7 +1780,7 @@ Stmt *RewriteTest::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
   // The minus 2 removes the begin/end double quotes.
   Preamble += utostr(prettyBuf.str().size()-2) + "};\n";
   
-  FileVarDecl *NewVD = FileVarDecl::Create(*Context, SourceLocation(), 
+  FileVarDecl *NewVD = FileVarDecl::Create(*Context, NULL, SourceLocation(), 
                                        &Context->Idents.get(S.c_str()), strType, 
                                        VarDecl::Static, NULL);
   DeclRefExpr *DRE = new DeclRefExpr(NewVD, strType, SourceLocation());
@@ -1817,7 +1828,7 @@ ObjCInterfaceDecl *RewriteTest::isSuperReceiver(Expr *recExpr) {
 // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
 QualType RewriteTest::getSuperStructType() {
   if (!SuperStructDecl) {
-    SuperStructDecl = RecordDecl::Create(*Context, Decl::Struct,
+    SuperStructDecl = RecordDecl::Create(*Context, Decl::Struct, NULL,
                                          SourceLocation(), 
                                          &Context->Idents.get("objc_super"), 0);
     QualType FieldTypes[2];
@@ -1830,7 +1841,8 @@ QualType RewriteTest::getSuperStructType() {
     FieldDecl *FieldDecls[2];
   
     for (unsigned i = 0; i < 2; ++i)
-      FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0, 
+      FieldDecls[i] = FieldDecl::Create(*Context, SuperStructDecl,
+                                        SourceLocation(), 0, 
                                         FieldTypes[i]);
   
     SuperStructDecl->defineBody(FieldDecls, 4);
@@ -1840,7 +1852,7 @@ QualType RewriteTest::getSuperStructType() {
 
 QualType RewriteTest::getConstantStringStructType() {
   if (!ConstantStringDecl) {
-    ConstantStringDecl = RecordDecl::Create(*Context, Decl::Struct,
+    ConstantStringDecl = RecordDecl::Create(*Context, Decl::Struct, NULL,
                                             SourceLocation(), 
                          &Context->Idents.get("__NSConstantStringImpl"), 0);
     QualType FieldTypes[4];
@@ -1857,7 +1869,8 @@ QualType RewriteTest::getConstantStringStructType() {
     FieldDecl *FieldDecls[4];
   
     for (unsigned i = 0; i < 4; ++i)
-      FieldDecls[i] = FieldDecl::Create(*Context, SourceLocation(), 0,
+      FieldDecls[i] = FieldDecl::Create(*Context, ConstantStringDecl,
+                                        SourceLocation(), 0,
                                         FieldTypes[i]);
   
     ConstantStringDecl->defineBody(FieldDecls, 4);
index 75b3ff70404f56eedbae87290932ed47f65c7b98..557a4a25c09d4c94e0e11e2ca5591e903042070c 100644 (file)
 #ifndef LLVM_CLANG_AST_DECL_H
 #define LLVM_CLANG_AST_DECL_H
 
-#include "clang/AST/Attr.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/Bitcode/SerializationFwd.h"
-
-namespace clang {
-class Decl;
-}
+#include "clang/AST/DeclBase.h"
 
 namespace clang {
 class Expr;
 class Stmt;
 class StringLiteral;
-class FunctionDecl;
 class IdentifierInfo;
 
-/// Decl - This represents one declaration (or definition), e.g. a variable, 
-/// typedef, function, struct, etc.  
-///
-class Decl {
-public:
-  enum Kind {
-    // This lists the concrete classes of Decl in order of the inheritance
-    // hierarchy.  This allows us to do efficient classof tests based on the
-    // enums below.   The commented out names are abstract class names.
-    
-    // Decl
-    //   NamedDecl
-           Field,
-             ObjCIvar,
-           ObjCCategory,
-           ObjCCategoryImpl,
-           ObjCImplementation,
-           ObjCProtocol,
-           PropertyDecl,
-    //     ScopedDecl
-    //       TypeDecl
-               Typedef,
-    //         TagDecl
-                 Enum,
-    //           RecordDecl
-                   Struct,
-                   Union,
-                   Class,
-    //       ValueDecl
-               EnumConstant,
-               Function,
-    //         VarDecl
-                 BlockVar,
-                 FileVar,
-                 ParmVar,
-         ObjCInterface,
-         ObjCCompatibleAlias,
-         ObjCMethod,
-         ObjCClass,
-         ObjCForwardProtocol,
-         LinkageSpec,
-   FileScopeAsm,
-  
-    // For each non-leaf class, we now define a mapping to the first/last member
-    // of the class, to allow efficient classof.
-    NamedFirst  = Field,         NamedLast  = ParmVar,
-    FieldFirst  = Field,         FieldLast  = ObjCIvar,
-    ScopedFirst = Typedef,       ScopedLast = ParmVar,
-    TypeFirst   = Typedef,       TypeLast   = Class,
-    TagFirst    = Enum         , TagLast    = Class,
-    RecordFirst = Struct       , RecordLast = Class,
-    ValueFirst  = EnumConstant , ValueLast  = ParmVar,
-    VarFirst    = BlockVar     , VarLast    = ParmVar
-  };
-
-  /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
-  /// labels, tags, members and ordinary identifiers.
-  enum IdentifierNamespace {
-    IDNS_Label,
-    IDNS_Tag,
-    IDNS_Member,
-    IDNS_Ordinary
-  };
-  
-  /// ObjCDeclQualifier - Qualifier used on types in method declarations
-  /// for remote messaging. They are meant for the arguments though and
-  /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
-  enum ObjCDeclQualifier {
-    OBJC_TQ_None = 0x0,
-    OBJC_TQ_In = 0x1,
-    OBJC_TQ_Inout = 0x2,
-    OBJC_TQ_Out = 0x4,
-    OBJC_TQ_Bycopy = 0x8,
-    OBJC_TQ_Byref = 0x10,
-    OBJC_TQ_Oneway = 0x20
-  };
-    
-private:
-  /// Loc - The location that this decl.
-  SourceLocation Loc;
-  
-  /// DeclKind - This indicates which class this is.
-  Kind DeclKind   :  8;
-  
-  /// InvalidDecl - This indicates a semantic error occurred.
-  unsigned int InvalidDecl :  1;
-  
-  /// HasAttrs - This indicates whether the decl has attributes or not.
-  unsigned int HasAttrs : 1;
-protected:
-  Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
-    HasAttrs(false) {
-    if (Decl::CollectingStats()) addDeclKind(DK);
-  }
-  
-public:
-  // TODO: This should probably be made protected once derived classes have
-  // destructors.
-  virtual ~Decl();
-  
-  SourceLocation getLocation() const { return Loc; }
-  void setLocation(SourceLocation L) { Loc = L; }
-
-  Kind getKind() const { return DeclKind; }
-  const char *getDeclKindName() const;
-  
-  void addAttr(Attr *attr);
-  const Attr *getAttrs() const;
-
-  template<typename T> const T *getAttr() const {
-    for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
-      if (const T *V = dyn_cast<T>(attr))
-        return V;
-
-    return 0;
-  }
-    
-  /// setInvalidDecl - Indicates the Decl had a semantic error. This
-  /// allows for graceful error recovery.
-  void setInvalidDecl() { InvalidDecl = 1; }
-  bool isInvalidDecl() const { return (bool) InvalidDecl; }
-  
-  IdentifierNamespace getIdentifierNamespace() const {
-    switch (DeclKind) {
-    default: assert(0 && "Unknown decl kind!");
-    case Typedef:
-    case Function:
-    case BlockVar:
-    case FileVar:
-    case ParmVar:
-    case EnumConstant:
-    case ObjCInterface:
-    case ObjCCompatibleAlias:
-      return IDNS_Ordinary;
-    case Struct:
-    case Union:
-    case Class:
-    case Enum:
-      return IDNS_Tag;
-    }
-  }
-  // global temp stats (until we have a per-module visitor)
-  static void addDeclKind(Kind k);
-  static bool CollectingStats(bool Enable = false);
-  static void PrintStats();
-    
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Decl *) { return true; }
-  
-  /// Emit - Serialize this Decl to Bitcode.
-  void Emit(llvm::Serializer& S) const;
-    
-  /// Create - Deserialize a Decl from Bitcode.
-  static Decl* Create(llvm::Deserializer& D);
-
-protected:
-  /// EmitImpl - Provides the subclass-specific serialization logic for
-  ///   serializing out a decl.
-  virtual void EmitImpl(llvm::Serializer& S) const {
-    // FIXME: This will eventually be a pure virtual function.
-    assert (false && "Not implemented.");
-  }
-  
-  void EmitInRec(llvm::Serializer& S) const;
-  void ReadInRec(llvm::Deserializer& D);
-};
-
 /// NamedDecl - This represents a decl with an identifier for a name.  Many
 /// decls have names, but not ObjCMethodDecl, @class, etc.
 class NamedDecl : public Decl {
@@ -234,11 +58,16 @@ class ScopedDecl : public NamedDecl {
   ///
   ScopedDecl *Next;
 
+  ContextDecl *CtxDecl;
+
 protected:
-  ScopedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id,ScopedDecl *PrevDecl)
-    : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0) {}
+  ScopedDecl(Kind DK, ContextDecl *CD, SourceLocation L,
+             IdentifierInfo *Id, ScopedDecl *PrevDecl)
+    : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0), CtxDecl(CD) {}
   
 public:
+  ContextDecl *getContext() const { return CtxDecl; }
+
   ScopedDecl *getNext() const { return Next; }
   void setNext(ScopedDecl *N) { Next = N; }
   
@@ -253,8 +82,13 @@ public:
   // scoped decl is defined outside the current function or method.  This is
   // roughly global variables and functions, but also handles enums (which could
   // be defined inside or outside a function etc).
-  bool isDefinedOutsideFunctionOrMethod() const;
-  
+  bool isDefinedOutsideFunctionOrMethod() const {
+    if (getContext())
+      return !getContext()->isFunctionOrMethod();
+    else
+      return true;
+  }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
     return D->getKind() >= ScopedFirst && D->getKind() <= ScopedLast;
@@ -276,9 +110,9 @@ class ValueDecl : public ScopedDecl {
   QualType DeclType;
 
 protected:
-  ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
-            ScopedDecl *PrevDecl) 
-    : ScopedDecl(DK, L, Id, PrevDecl), DeclType(T) {}
+  ValueDecl(Kind DK, ContextDecl *CD, SourceLocation L,
+            IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl) 
+    : ScopedDecl(DK, CD, L, Id, PrevDecl), DeclType(T) {}
 public:
   QualType getType() const { return DeclType; }
   void setType(QualType newType) { DeclType = newType; }
@@ -309,9 +143,9 @@ private:
   
   friend class StmtIteratorBase;
 protected:
-  VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
+  VarDecl(Kind DK, ContextDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T,
           StorageClass SC, ScopedDecl *PrevDecl)
-    : ValueDecl(DK, L, Id, T, PrevDecl), Init(0) { SClass = SC; }
+    : ValueDecl(DK, CD, L, Id, T, PrevDecl), Init(0) { SClass = SC; }
 public:
   StorageClass getStorageClass() const { return (StorageClass)SClass; }
 
@@ -362,11 +196,12 @@ protected:
 ///   void foo() { int x; static int y; extern int z; }
 ///
 class BlockVarDecl : public VarDecl {
-  BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+  BlockVarDecl(ContextDecl *CD, SourceLocation L,
+               IdentifierInfo *Id, QualType T, StorageClass S,
                ScopedDecl *PrevDecl)
-    : VarDecl(BlockVar, L, Id, T, S, PrevDecl) {}
+    : VarDecl(BlockVar, CD, L, Id, T, S, PrevDecl) {}
 public:
-  static BlockVarDecl *Create(ASTContext &C, SourceLocation L,
+  static BlockVarDecl *Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
                               IdentifierInfo *Id, QualType T, StorageClass S,
                               ScopedDecl *PrevDecl);
   // Implement isa/cast/dyncast/etc.
@@ -385,11 +220,13 @@ protected:
 /// definitions (C99 6.9.2p2) using our type system (without storing a
 /// pointer to the decl's scope, which is transient).
 class FileVarDecl : public VarDecl {
-  FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+  FileVarDecl(ContextDecl *CD, SourceLocation L,
+              IdentifierInfo *Id, QualType T, StorageClass S,
               ScopedDecl *PrevDecl)
-    : VarDecl(FileVar, L, Id, T, S, PrevDecl) {}
+    : VarDecl(FileVar, CD, L, Id, T, S, PrevDecl) {}
 public:
-  static FileVarDecl *Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
+  static FileVarDecl *Create(ASTContext &C, ContextDecl *CD,
+                             SourceLocation L, IdentifierInfo *Id,
                              QualType T, StorageClass S, ScopedDecl *PrevDecl);
   
   // Implement isa/cast/dyncast/etc.
@@ -410,12 +247,14 @@ class ParmVarDecl : public VarDecl {
   /// in, inout, etc.
   unsigned objcDeclQualifier : 6;
   
-  ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+  ParmVarDecl(ContextDecl *CD, SourceLocation L,
+              IdentifierInfo *Id, QualType T, StorageClass S,
               ScopedDecl *PrevDecl)
-    : VarDecl(ParmVar, L, Id, T, S, PrevDecl), 
+    : VarDecl(ParmVar, CD, L, Id, T, S, PrevDecl), 
     objcDeclQualifier(OBJC_TQ_None) {}
 public:
-  static ParmVarDecl *Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
+  static ParmVarDecl *Create(ASTContext &C, ContextDecl *CD,
+                             SourceLocation L,IdentifierInfo *Id,
                              QualType T, StorageClass S, ScopedDecl *PrevDecl);
   
   ObjCDeclQualifier getObjCDeclQualifier() const {
@@ -440,7 +279,7 @@ protected:
 
 /// FunctionDecl - An instance of this class is created to represent a function
 /// declaration or definition.
-class FunctionDecl : public ValueDecl {
+class FunctionDecl : public ValueDecl, public ContextDecl {
 public:
   enum StorageClass {
     None, Extern, Static, PrivateExtern
@@ -462,13 +301,15 @@ private:
   unsigned SClass : 2;
   bool IsInline : 1;
   
-  FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+  FunctionDecl(ContextDecl *CD, SourceLocation L,
+               IdentifierInfo *Id, QualType T,
                StorageClass S, bool isInline, ScopedDecl *PrevDecl)
-    : ValueDecl(Function, L, Id, T, PrevDecl), 
+    : ValueDecl(Function, CD, L, Id, T, PrevDecl), 
+      ContextDecl(Function),
       ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {}
   virtual ~FunctionDecl();
 public:
-  static FunctionDecl *Create(ASTContext &C, SourceLocation L,
+  static FunctionDecl *Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
                               IdentifierInfo *Id, QualType T, 
                               StorageClass S = None, bool isInline = false, 
                               ScopedDecl *PrevDecl = 0);
@@ -525,14 +366,18 @@ protected:
 class FieldDecl : public NamedDecl {
   QualType DeclType;  
   Expr *BitWidth;
+  ContextDecl *CtxDecl;
 protected:
-  FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
+  FieldDecl(Kind DK, ContextDecl *CD,
+            SourceLocation L, IdentifierInfo *Id, QualType T,
             Expr *BW = NULL)
-    : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW) {}
-  FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW)
+    : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW), CtxDecl(CD) {}
+  FieldDecl(RecordDecl *CD, SourceLocation L,
+            IdentifierInfo *Id, QualType T, Expr *BW)
     : NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {}
 public:
-  static FieldDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
+  static FieldDecl *Create(ASTContext &C, RecordDecl *CD,
+                           SourceLocation L, IdentifierInfo *Id,
                            QualType T, Expr *BW = NULL);
 
   QualType getType() const { return DeclType; }
@@ -540,6 +385,7 @@ public:
   
   bool isBitField() const { return BitWidth != NULL; }
   Expr *getBitWidth() const { return BitWidth; }
+  ContextDecl *getContextDecl() const { return CtxDecl; }
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
     return D->getKind() >= FieldFirst && D->getKind() <= FieldLast;
@@ -564,14 +410,16 @@ class EnumConstantDecl : public ValueDecl {
   Expr *Init; // an integer constant expression
   llvm::APSInt Val; // The value.
 protected:
-  EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
+  EnumConstantDecl(ContextDecl *CD, SourceLocation L,
+                   IdentifierInfo *Id, QualType T, Expr *E,
                    const llvm::APSInt &V, ScopedDecl *PrevDecl)
-    : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {}
+    : ValueDecl(EnumConstant, CD, L, Id, T, PrevDecl), Init(E), Val(V) {}
   ~EnumConstantDecl() {}
 public:
 
-  static EnumConstantDecl *Create(ASTContext &C, SourceLocation L,
-                                  IdentifierInfo *Id, QualType T, Expr *E,
+  static EnumConstantDecl *Create(ASTContext &C, EnumDecl *CD,
+                                  SourceLocation L, IdentifierInfo *Id,
+                                  QualType T, Expr *E,
                                   const llvm::APSInt &V, ScopedDecl *PrevDecl);
   
   const Expr *getInitExpr() const { return Init; }
@@ -607,8 +455,9 @@ class TypeDecl : public ScopedDecl {
   Type *TypeForDecl;
   friend class ASTContext;
 protected:
-  TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
-    : ScopedDecl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
+  TypeDecl(Kind DK, ContextDecl *CD, SourceLocation L,
+           IdentifierInfo *Id, ScopedDecl *PrevDecl)
+    : ScopedDecl(DK, CD, L, Id, PrevDecl), TypeForDecl(0) {}
 public:
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
@@ -621,12 +470,14 @@ public:
 class TypedefDecl : public TypeDecl {
   /// UnderlyingType - This is the type the typedef is set to.
   QualType UnderlyingType;
-  TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PD) 
-    : TypeDecl(Typedef, L, Id, PD), UnderlyingType(T) {}
+  TypedefDecl(ContextDecl *CD, SourceLocation L,
+              IdentifierInfo *Id, QualType T, ScopedDecl *PD) 
+    : TypeDecl(Typedef, CD, L, Id, PD), UnderlyingType(T) {}
   ~TypedefDecl() {}
 public:
   
-  static TypedefDecl *Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
+  static TypedefDecl *Create(ASTContext &C, ContextDecl *CD,
+                             SourceLocation L,IdentifierInfo *Id,
                              QualType T, ScopedDecl *PD);
   
   QualType getUnderlyingType() const { return UnderlyingType; }
@@ -648,13 +499,14 @@ protected:
 
 
 /// TagDecl - Represents the declaration of a struct/union/class/enum.
-class TagDecl : public TypeDecl {
+class TagDecl : public TypeDecl, public ContextDecl {
   /// IsDefinition - True if this is a definition ("struct foo {};"), false if
   /// it is a declaration ("struct foo;").
   bool IsDefinition : 1;
 protected:
-  TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
-    : TypeDecl(DK, L, Id, PrevDecl) {
+  TagDecl(Kind DK, ContextDecl *CD, SourceLocation L,
+          IdentifierInfo *Id, ScopedDecl *PrevDecl)
+    : TypeDecl(DK, CD, L, Id, PrevDecl), ContextDecl(DK) {
     IsDefinition = false;
   }
 public:
@@ -695,13 +547,15 @@ class EnumDecl : public TagDecl {
   /// have a different type than this does.
   QualType IntegerType;
   
-  EnumDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
-    : TagDecl(Enum, L, Id, PrevDecl) {
+  EnumDecl(ContextDecl *CD, SourceLocation L,
+           IdentifierInfo *Id, ScopedDecl *PrevDecl)
+    : TagDecl(Enum, CD, L, Id, PrevDecl) {
       ElementList = 0;
       IntegerType = QualType();
     }
 public:
-  static EnumDecl *Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
+  static EnumDecl *Create(ASTContext &C, ContextDecl *CD,
+                          SourceLocation L, IdentifierInfo *Id,
                           ScopedDecl *PrevDecl);
   
   /// defineElements - When created, EnumDecl correspond to a forward declared
@@ -753,8 +607,8 @@ class RecordDecl : public TagDecl {
   FieldDecl **Members;   // Null if not defined.
   int NumMembers;   // -1 if not defined.
   
-  RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, 
-             ScopedDecl *PrevDecl) : TagDecl(DK, L, Id, PrevDecl) {
+  RecordDecl(Kind DK, ContextDecl *CD, SourceLocation L, IdentifierInfo *Id, 
+             ScopedDecl *PrevDecl) : TagDecl(DK, CD, L, Id, PrevDecl) {
     HasFlexibleArrayMember = false;
     assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
     Members = 0;
@@ -762,8 +616,9 @@ class RecordDecl : public TagDecl {
   }
 public:
   
-  static RecordDecl *Create(ASTContext &C, Kind DK, SourceLocation L,
-                            IdentifierInfo *Id, ScopedDecl *PrevDecl);
+  static RecordDecl *Create(ASTContext &C, Kind DK, ContextDecl *CD,
+                            SourceLocation L, IdentifierInfo *Id,
+                            ScopedDecl *PrevDecl);
   
   bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
   void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
new file mode 100644 (file)
index 0000000..ae8fdc7
--- /dev/null
@@ -0,0 +1,330 @@
+//===-- DeclBase.h - Base Classes for representing declarations *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Decl and ContextDecl interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLBASE_H
+#define LLVM_CLANG_AST_DECLBASE_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+class FunctionDecl;
+class ObjCMethodDecl;
+class TagDecl;
+class ObjCInterfaceDecl;
+
+/// Decl - This represents one declaration (or definition), e.g. a variable, 
+/// typedef, function, struct, etc.  
+///
+class Decl {
+public:
+  enum Kind {
+    // This lists the concrete classes of Decl in order of the inheritance
+    // hierarchy.  This allows us to do efficient classof tests based on the
+    // enums below.   The commented out names are abstract class names.
+    
+    // Decl
+    //   NamedDecl
+           Field,
+             ObjCIvar,
+           ObjCCategory,
+           ObjCCategoryImpl,
+           ObjCImplementation,
+           ObjCProtocol,
+           PropertyDecl,
+    //     ScopedDecl
+    //       TypeDecl
+               Typedef,
+    //         TagDecl
+                 Enum,
+    //           RecordDecl
+                   Struct,
+                   Union,
+                   Class,
+    //       ValueDecl
+               EnumConstant,
+               Function,
+    //         VarDecl
+                 BlockVar,
+                 FileVar,
+                 ParmVar,
+         ObjCInterface,
+         ObjCCompatibleAlias,
+         ObjCMethod,
+         ObjCClass,
+         ObjCForwardProtocol,
+         LinkageSpec,
+   FileScopeAsm,
+  
+    // For each non-leaf class, we now define a mapping to the first/last member
+    // of the class, to allow efficient classof.
+    NamedFirst  = Field,         NamedLast  = ParmVar,
+    FieldFirst  = Field,         FieldLast  = ObjCIvar,
+    ScopedFirst = Typedef,       ScopedLast = ParmVar,
+    TypeFirst   = Typedef,       TypeLast   = Class,
+    TagFirst    = Enum         , TagLast    = Class,
+    RecordFirst = Struct       , RecordLast = Class,
+    ValueFirst  = EnumConstant , ValueLast  = ParmVar,
+    VarFirst    = BlockVar     , VarLast    = ParmVar
+  };
+
+  /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
+  /// labels, tags, members and ordinary identifiers.
+  enum IdentifierNamespace {
+    IDNS_Label,
+    IDNS_Tag,
+    IDNS_Member,
+    IDNS_Ordinary
+  };
+  
+  /// ObjCDeclQualifier - Qualifier used on types in method declarations
+  /// for remote messaging. They are meant for the arguments though and
+  /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
+  enum ObjCDeclQualifier {
+    OBJC_TQ_None = 0x0,
+    OBJC_TQ_In = 0x1,
+    OBJC_TQ_Inout = 0x2,
+    OBJC_TQ_Out = 0x4,
+    OBJC_TQ_Bycopy = 0x8,
+    OBJC_TQ_Byref = 0x10,
+    OBJC_TQ_Oneway = 0x20
+  };
+    
+private:
+  /// Loc - The location that this decl.
+  SourceLocation Loc;
+  
+  /// DeclKind - This indicates which class this is.
+  Kind DeclKind   :  8;
+  
+  /// InvalidDecl - This indicates a semantic error occurred.
+  unsigned int InvalidDecl :  1;
+  
+  /// HasAttrs - This indicates whether the decl has attributes or not.
+  unsigned int HasAttrs : 1;
+protected:
+  Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
+    HasAttrs(false) {
+    if (Decl::CollectingStats()) addDeclKind(DK);
+  }
+  
+public:
+  // TODO: This should probably be made protected once derived classes have
+  // destructors.
+  virtual ~Decl();
+  
+  SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  Kind getKind() const { return DeclKind; }
+  const char *getDeclKindName() const;
+  
+  void addAttr(Attr *attr);
+  const Attr *getAttrs() const;
+
+  template<typename T> const T *getAttr() const {
+    for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
+      if (const T *V = dyn_cast<T>(attr))
+        return V;
+
+    return 0;
+  }
+    
+  /// setInvalidDecl - Indicates the Decl had a semantic error. This
+  /// allows for graceful error recovery.
+  void setInvalidDecl() { InvalidDecl = 1; }
+  bool isInvalidDecl() const { return (bool) InvalidDecl; }
+  
+  IdentifierNamespace getIdentifierNamespace() const {
+    switch (DeclKind) {
+    default: assert(0 && "Unknown decl kind!");
+    case Typedef:
+    case Function:
+    case BlockVar:
+    case FileVar:
+    case ParmVar:
+    case EnumConstant:
+    case ObjCInterface:
+    case ObjCCompatibleAlias:
+      return IDNS_Ordinary;
+    case Struct:
+    case Union:
+    case Class:
+    case Enum:
+      return IDNS_Tag;
+    }
+  }
+  // global temp stats (until we have a per-module visitor)
+  static void addDeclKind(Kind k);
+  static bool CollectingStats(bool Enable = false);
+  static void PrintStats();
+    
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *) { return true; }
+  
+  /// Emit - Serialize this Decl to Bitcode.
+  void Emit(llvm::Serializer& S) const;
+    
+  /// Create - Deserialize a Decl from Bitcode.
+  static Decl* Create(llvm::Deserializer& D);
+
+protected:
+  /// EmitImpl - Provides the subclass-specific serialization logic for
+  ///   serializing out a decl.
+  virtual void EmitImpl(llvm::Serializer& S) const {
+    // FIXME: This will eventually be a pure virtual function.
+    assert (false && "Not implemented.");
+  }
+  
+  void EmitInRec(llvm::Serializer& S) const;
+  void ReadInRec(llvm::Deserializer& D);
+};
+
+/// ContextDecl - This is used only as base class of specific decl types that
+/// can act as declaration contexts. These decls are:
+///
+///   FunctionDecl
+///   ObjCMethodDecl
+///   TagDecl
+///   ObjCInterfaceDecl
+///
+class ContextDecl {
+  /// DeclKind - This indicates which class this is.
+  Decl::Kind DeclKind   :  8;
+
+  // Used in the CastTo template to get the DeclKind
+  // from a Decl or a ContextDecl. ContextDecl doesn't have a getKind() method
+  // to avoid 'ambiguous access' compiler errors.
+  template<typename T> struct KindTrait {
+    static Decl::Kind getKind(const T *D) { return D->getKind(); }
+  };
+
+  // Used only by the ToDecl and FromDecl methods
+  template<typename To, typename From>
+  static To *CastTo(const From *D) {
+    Decl::Kind DK = KindTrait<From>::getKind(D);
+    switch(DK) {
+      case Decl::Function:
+        return static_cast<FunctionDecl*>(const_cast<From*>(D));
+      case Decl::ObjCMethod:
+        return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
+      case Decl::ObjCInterface:
+        return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
+      default:
+        // check for TagDecl
+        if (DK >= Decl::TagFirst && DK <= Decl::TagLast)
+          return static_cast<TagDecl*>(const_cast<From*>(D));
+        assert(false && "a decl that inherits ContextDecl isn't handled");
+        return 0;
+    }
+  }
+
+protected:
+  ContextDecl(Decl::Kind K) : DeclKind(K) {}
+
+public:
+  /// getParent - Returns the containing ContextDecl if this is a ScopedDecl,
+  /// else returns NULL.
+  ContextDecl *getParent() const;
+
+  bool isFunctionOrMethod() const {
+    switch (DeclKind) {
+      case Decl::Function:
+      case Decl::ObjCMethod:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  /// ToDecl and FromDecl make Decl <-> ContextDecl castings.
+  /// They are intended to be used by the simplify_type and cast_convert_val
+  /// templates.
+  static Decl        *ToDecl   (const ContextDecl *D);
+  static ContextDecl *FromDecl (const Decl *D);
+
+  static bool classof(const Decl *D) {
+    switch (D->getKind()) {
+      case Decl::Function:
+      case Decl::ObjCMethod:
+      case Decl::ObjCInterface:
+        return true;
+      default:
+        // check for TagDecl
+        return D->getKind() >= Decl::TagFirst &&
+               D->getKind() <= Decl::TagLast;
+    }
+  }
+  static bool classof(const ContextDecl *D) { return true; }
+  static bool classof(const FunctionDecl *D) { return true; }
+  static bool classof(const ObjCMethodDecl *D) { return true; }
+  static bool classof(const TagDecl *D) { return true; }
+  static bool classof(const ObjCInterfaceDecl *D) { return true; }
+};
+
+template<> struct ContextDecl::KindTrait<ContextDecl> {
+  static Decl::Kind getKind(const ContextDecl *D) { return D->DeclKind; }
+};
+
+} // end clang.
+
+namespace llvm {
+/// Implement simplify_type for ContextDecl, so that we can dyn_cast from 
+/// ContextDecl to a specific Decl class.
+  template<> struct simplify_type<const ::clang::ContextDecl*> {
+  typedef ::clang::Decl* SimpleType;
+  static SimpleType getSimplifiedValue(const ::clang::ContextDecl *Val) {
+    return ::clang::ContextDecl::ToDecl(Val);
+  }
+};
+template<> struct simplify_type< ::clang::ContextDecl*>
+  : public simplify_type<const ::clang::ContextDecl*> {};
+
+template<> struct simplify_type<const ::clang::ContextDecl> {
+  typedef ::clang::Decl SimpleType;
+  static SimpleType &getSimplifiedValue(const ::clang::ContextDecl &Val) {
+    return *::clang::ContextDecl::ToDecl(&Val);
+  }
+};
+template<> struct simplify_type< ::clang::ContextDecl>
+  : public simplify_type<const ::clang::ContextDecl> {};
+
+/// Implement cast_convert_val for ContextDecl, so that we can dyn_cast from 
+/// a Decl class to ContextDecl.
+template<class FromTy>
+struct cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy> {
+  static ::clang::ContextDecl &doit(const FromTy &Val) {
+    return *::clang::ContextDecl::FromDecl(&Val);
+  }
+};
+template<class FromTy>
+struct cast_convert_val< ::clang::ContextDecl,FromTy,FromTy>
+  : public cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy>
+    {};
+
+template<class FromTy>
+struct cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*> {
+  static ::clang::ContextDecl *doit(const FromTy *Val) {
+    return ::clang::ContextDecl::FromDecl(Val);
+  }
+};
+template<class FromTy>
+struct cast_convert_val< ::clang::ContextDecl,FromTy*,FromTy*> 
+  : public cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*>
+    {};
+
+} // end namespace llvm
+
+#endif
index 7f4a9752a502b42afbe2d5635c7ac6197e53ea01..d2250934561c6be708416bb72ee3f42ad7b66351 100644 (file)
@@ -48,7 +48,7 @@ class ObjCPropertyDecl;
 /// A selector represents a unique name for a method. The selector names for
 /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
 ///
-class ObjCMethodDecl : public Decl {
+class ObjCMethodDecl : public Decl, public ContextDecl {
 public:
   enum ImplementationControl { None, Required, Optional };
 private:
@@ -96,6 +96,7 @@ private:
                  bool isVariadic = false,
                  ImplementationControl impControl = None)
   : Decl(ObjCMethod, beginLoc),
+    ContextDecl(ObjCMethod),
     IsInstance(isInstance), IsVariadic(isVariadic),
     DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
     MethodContext(static_cast<NamedDecl*>(contextDecl)),
@@ -105,7 +106,8 @@ private:
   virtual ~ObjCMethodDecl();
 public:
 
-  static ObjCMethodDecl *Create(ASTContext &C, SourceLocation beginLoc, 
+  static ObjCMethodDecl *Create(ASTContext &C,
+                                SourceLocation beginLoc, 
                                 SourceLocation endLoc, Selector SelInfo,
                                 QualType T, Decl *contextDecl,
                                 AttributeList *M = 0, bool isInstance = true,
@@ -191,7 +193,7 @@ public:
 ///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
 ///   typically inherit from NSObject (an exception is NSProxy).
 ///
-class ObjCInterfaceDecl : public NamedDecl {
+class ObjCInterfaceDecl : public NamedDecl, public ContextDecl {
   /// TypeForDecl - This indicates the Type object that represents this
   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
   Type *TypeForDecl;
@@ -229,9 +231,11 @@ class ObjCInterfaceDecl : public NamedDecl {
   SourceLocation EndLoc; // marks the '>', '}', or identifier.
   SourceLocation AtEndLoc; // marks the end of the entire interface.
 
-  ObjCInterfaceDecl(SourceLocation atLoc, unsigned numRefProtos,
+  ObjCInterfaceDecl(SourceLocation atLoc,
+                    unsigned numRefProtos,
                     IdentifierInfo *Id, bool FD, bool isInternal)
-    : NamedDecl(ObjCInterface, atLoc, Id), TypeForDecl(0), SuperClass(0),
+    : NamedDecl(ObjCInterface, atLoc, Id), ContextDecl(ObjCInterface),
+      TypeForDecl(0), SuperClass(0),
       ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0), 
       NumIvars(0),
       InstanceMethods(0), NumInstanceMethods(0), 
@@ -242,7 +246,8 @@ class ObjCInterfaceDecl : public NamedDecl {
       }
 public:
 
-  static ObjCInterfaceDecl *Create(ASTContext &C, SourceLocation atLoc,
+  static ObjCInterfaceDecl *Create(ASTContext &C,
+                                   SourceLocation atLoc,
                                    unsigned numRefProtos, IdentifierInfo *Id,
                                    bool ForwardDecl = false,
                                    bool isInternal = false);
@@ -371,10 +376,12 @@ public:
 ///   }
 ///
 class ObjCIvarDecl : public FieldDecl {
-  ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 
-    : FieldDecl(ObjCIvar, L, Id, T) {}
+  ObjCIvarDecl(ContextDecl *CD, SourceLocation L, 
+               IdentifierInfo *Id, QualType T)
+    : FieldDecl(ObjCIvar, CD, L, Id, T) {}
 public:
-  static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L,
+  static ObjCIvarDecl *Create(ASTContext &C, ObjCInterfaceDecl *CD,
+                              SourceLocation L,
                               IdentifierInfo *Id, QualType T);
     
   enum AccessControl {
@@ -559,7 +566,7 @@ class ObjCForwardProtocolDecl : public Decl {
   ObjCProtocolDecl **ReferencedProtocols;
   unsigned NumReferencedProtocols;
   
-  ObjCForwardProtocolDecl(SourceLocation L, 
+  ObjCForwardProtocolDecl(SourceLocation L,
                           ObjCProtocolDecl **Elts, unsigned nElts)
   : Decl(ObjCForwardProtocol, L) { 
     NumReferencedProtocols = nElts;
@@ -645,8 +652,8 @@ class ObjCCategoryDecl : public NamedDecl {
   }
 public:
   
-  static ObjCCategoryDecl *Create(ASTContext &C, SourceLocation L,
-                                  IdentifierInfo *Id);
+  static ObjCCategoryDecl *Create(ASTContext &C,
+                                  SourceLocation L, IdentifierInfo *Id);
   
   ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
   void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
@@ -735,8 +742,8 @@ class ObjCCategoryImplDecl : public NamedDecl {
                        ObjCInterfaceDecl *classInterface)
     : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
 public:
-  static ObjCCategoryImplDecl *Create(ASTContext &C, SourceLocation L,
-                                      IdentifierInfo *Id,
+  static ObjCCategoryImplDecl *Create(ASTContext &C,
+                                      SourceLocation L, IdentifierInfo *Id,
                                       ObjCInterfaceDecl *classInterface);
         
   ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
@@ -817,8 +824,8 @@ class ObjCImplementationDecl : public NamedDecl {
       ClassInterface(classInterface), SuperClass(superDecl),
       Ivars(0), NumIvars(0) {}
 public:  
-  static ObjCImplementationDecl *Create(ASTContext &C, SourceLocation L,
-                                        IdentifierInfo *Id,
+  static ObjCImplementationDecl *Create(ASTContext &C,
+                                        SourceLocation L, IdentifierInfo *Id,
                                         ObjCInterfaceDecl *classInterface,
                                         ObjCInterfaceDecl *superDecl);
   
@@ -883,8 +890,8 @@ class ObjCCompatibleAliasDecl : public NamedDecl {
                           ObjCInterfaceDecl* aliasedClass)
     : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {}
 public:
-  static ObjCCompatibleAliasDecl *Create(ASTContext &C, SourceLocation L,
-                                         IdentifierInfo *Id,
+  static ObjCCompatibleAliasDecl *Create(ASTContext &C,
+                                         SourceLocation L, IdentifierInfo *Id,
                                          ObjCInterfaceDecl* aliasedClass);
 
   const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
index ce75122b3d7bf80f43d31160a46ad8efbd33cab4..9e51b292fb30f19fd4c057ff525eb19fb7adf479 100644 (file)
@@ -1115,7 +1115,7 @@ QualType ASTContext::maxIntegerType(QualType lhs, QualType rhs) {
 QualType ASTContext::getCFConstantStringType() {
   if (!CFConstantStringTypeDecl) {
     CFConstantStringTypeDecl = 
-      RecordDecl::Create(*this, Decl::Struct, SourceLocation(), 
+      RecordDecl::Create(*this, Decl::Struct, NULL, SourceLocation(), 
                          &Idents.get("NSConstantString"), 0);
     QualType FieldTypes[4];
   
@@ -1131,7 +1131,8 @@ QualType ASTContext::getCFConstantStringType() {
     FieldDecl *FieldDecls[4];
   
     for (unsigned i = 0; i < 4; ++i)
-      FieldDecls[i] = FieldDecl::Create(*this, SourceLocation(), 0,
+      FieldDecls[i] = FieldDecl::Create(*this, CFConstantStringTypeDecl,
+                                        SourceLocation(), 0,
                                         FieldTypes[i]);
   
     CFConstantStringTypeDecl->defineBody(FieldDecls, 4);
@@ -1907,14 +1908,14 @@ ASTContext* ASTContext::Create(llvm::Deserializer& D) {
   TargetInfo &t = D.ReadRef<TargetInfo>();
   IdentifierTable &idents = D.ReadRef<IdentifierTable>();
   SelectorTable &sels = D.ReadRef<SelectorTable>();
-  
+
   unsigned size_reserve = D.ReadInt();
   
   ASTContext* A = new ASTContext(SM,t,idents,sels,size_reserve);
   
   for (unsigned i = 0; i < size_reserve; ++i)
     Type::Create(*A,i,D);
-
+  
   // FIXME: A->CFConstantStringTypeDecl = D.ReadOwnedPtr<RecordDecl>();
   
   return A;
index 3e7d83826eb2aec83a4e162c4c910ae8d8646493..38a20c1c015ee9f0da2b234c7819d6040fc6c15c 100644 (file)
@@ -204,77 +204,87 @@ void Decl::addDeclKind(Kind k) {
 // Decl Allocation/Deallocation Method Implementations
 //===----------------------------------------------------------------------===//
 
-BlockVarDecl *BlockVarDecl::Create(ASTContext &C, SourceLocation L,
+BlockVarDecl *BlockVarDecl::Create(ASTContext &C, ContextDecl *CD,
+                                   SourceLocation L,
                                    IdentifierInfo *Id, QualType T,
                                    StorageClass S, ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<BlockVarDecl>();
-  return new (Mem) BlockVarDecl(L, Id, T, S, PrevDecl);
+  return new (Mem) BlockVarDecl(CD, L, Id, T, S, PrevDecl);
 }
 
 
-FileVarDecl *FileVarDecl::Create(ASTContext &C, SourceLocation L,
-                                 IdentifierInfo *Id, QualType T, StorageClass S,
+FileVarDecl *FileVarDecl::Create(ASTContext &C, ContextDecl *CD,
+                                 SourceLocation L, IdentifierInfo *Id,
+                                 QualType T, StorageClass S,
                                  ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<FileVarDecl>();
-  return new (Mem) FileVarDecl(L, Id, T, S, PrevDecl);
+  return new (Mem) FileVarDecl(CD, L, Id, T, S, PrevDecl);
 }
 
-ParmVarDecl *ParmVarDecl::Create(ASTContext &C, SourceLocation L,
-                                 IdentifierInfo *Id, QualType T, StorageClass S,
+ParmVarDecl *ParmVarDecl::Create(ASTContext &C, ContextDecl *CD,
+                                 SourceLocation L, IdentifierInfo *Id,
+                                 QualType T, StorageClass S,
                                  ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<ParmVarDecl>();
-  return new (Mem) ParmVarDecl(L, Id, T, S, PrevDecl);
+  return new (Mem) ParmVarDecl(CD, L, Id, T, S, PrevDecl);
 }
 
-FunctionDecl *FunctionDecl::Create(ASTContext &C, SourceLocation L, 
+FunctionDecl *FunctionDecl::Create(ASTContext &C, ContextDecl *CD,
+                                   SourceLocation L, 
                                    IdentifierInfo *Id, QualType T, 
                                    StorageClass S, bool isInline, 
                                    ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<FunctionDecl>();
-  return new (Mem) FunctionDecl(L, Id, T, S, isInline, PrevDecl);
+  return new (Mem) FunctionDecl(CD, L, Id, T, S, isInline, PrevDecl);
 }
 
-FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
+FieldDecl *FieldDecl::Create(ASTContext &C, RecordDecl *CD, SourceLocation L,
                              IdentifierInfo *Id, QualType T, Expr *BW) {
   void *Mem = C.getAllocator().Allocate<FieldDecl>();
-  return new (Mem) FieldDecl(L, Id, T, BW);
+  return new (Mem) FieldDecl(CD, L, Id, T, BW);
 }
 
 
-EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, SourceLocation L,
+EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
+                                           SourceLocation L,
                                            IdentifierInfo *Id, QualType T,
                                            Expr *E, const llvm::APSInt &V, 
                                            ScopedDecl *PrevDecl){
   void *Mem = C.getAllocator().Allocate<EnumConstantDecl>();
-  return new (Mem) EnumConstantDecl(L, Id, T, E, V, PrevDecl);
+  return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl);
 }
 
-TypedefDecl *TypedefDecl::Create(ASTContext &C, SourceLocation L,
+TypedefDecl *TypedefDecl::Create(ASTContext &C, ContextDecl *CD,
+                                 SourceLocation L,
                                  IdentifierInfo *Id, QualType T,
                                  ScopedDecl *PD) {
   void *Mem = C.getAllocator().Allocate<TypedefDecl>();
-  return new (Mem) TypedefDecl(L, Id, T, PD);
+  return new (Mem) TypedefDecl(CD, L, Id, T, PD);
 }
 
-EnumDecl *EnumDecl::Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id,
+EnumDecl *EnumDecl::Create(ASTContext &C, ContextDecl *CD, SourceLocation L,
+                           IdentifierInfo *Id,
                            ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<EnumDecl>();
-  return new (Mem) EnumDecl(L, Id, PrevDecl);
+  return new (Mem) EnumDecl(CD, L, Id, PrevDecl);
 }
 
-RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, SourceLocation L,
-                               IdentifierInfo *Id, ScopedDecl *PrevDecl) {
+RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, ContextDecl *CD,
+                               SourceLocation L, IdentifierInfo *Id,
+                               ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<RecordDecl>();
-  return new (Mem) RecordDecl(DK, L, Id, PrevDecl);
+  return new (Mem) RecordDecl(DK, CD, L, Id, PrevDecl);
 }
 
-FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, SourceLocation L,
+FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
+                                           SourceLocation L,
                                            StringLiteral *Str) {
   void *Mem = C.getAllocator().Allocate<FileScopeAsmDecl>();
   return new (Mem) FileScopeAsmDecl(L, Str);
 }
 
-LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, SourceLocation L,
+LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
+                                         SourceLocation L,
                                          LanguageIDs Lang, Decl *D) {
   void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
   return new (Mem) LinkageSpecDecl(L, Lang, D);
@@ -320,35 +330,32 @@ const Attr *Decl::getAttrs() const {
 }
 
 //===----------------------------------------------------------------------===//
-// NamedDecl Implementation
+// ContextDecl Implementation
 //===----------------------------------------------------------------------===//
 
-const char *NamedDecl::getName() const {
-  if (const IdentifierInfo *II = getIdentifier())
-    return II->getName();
-  return "";
+ContextDecl *ContextDecl::getParent() const {
+  if (ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
+    return SD->getContext();
+  else
+    return NULL;
+}
+
+Decl *ContextDecl::ToDecl (const ContextDecl *D) {
+  return CastTo<Decl>(D);
+}
+
+ContextDecl *ContextDecl::FromDecl (const Decl *D) {
+  return CastTo<ContextDecl>(D);
 }
 
 //===----------------------------------------------------------------------===//
-// ScopedDecl Implementation
+// NamedDecl Implementation
 //===----------------------------------------------------------------------===//
 
-// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
-// scoped decl is defined outside the current function or method.  This is
-// roughly global variables and functions, but also handles enums (which could
-// be defined inside or outside a function etc).
-bool ScopedDecl::isDefinedOutsideFunctionOrMethod() const {
-  if (const VarDecl *VD = dyn_cast<VarDecl>(this))
-    return VD->hasGlobalStorage();
-  if (isa<FunctionDecl>(this))
-    return true;
-  
-  // FIXME: This needs to check the context the decl was defined in!
-  if (isa<TypeDecl>(this) || isa<EnumConstantDecl>(this))
-    return true;
-  
-  assert(0 && "Unknown ScopedDecl!");
-  return false;
+const char *NamedDecl::getName() const {
+  if (const IdentifierInfo *II = getIdentifier())
+    return II->getName();
+  return "";
 }
 
 //===----------------------------------------------------------------------===//
index 2e3a06a956faee7944e09add2d8f12e66daeffe0..a01c3042d31b5396740f612020e5c1845c3bd095 100644 (file)
@@ -19,7 +19,8 @@ using namespace clang;
 // ObjC Decl Allocation/Deallocation Method Implementations
 //===----------------------------------------------------------------------===//
 
-ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc, 
+ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
+                                       SourceLocation beginLoc, 
                                        SourceLocation endLoc,
                                        Selector SelInfo, QualType T,
                                        Decl *contextDecl,
@@ -27,61 +28,71 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, SourceLocation beginLoc,
                                        bool isVariadic,
                                        ImplementationControl impControl) {
   void *Mem = C.getAllocator().Allocate<ObjCMethodDecl>();
-  return new (Mem) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, contextDecl,
+  return new (Mem) ObjCMethodDecl(beginLoc, endLoc,
+                                  SelInfo, T, contextDecl,
                                   M, isInstance, 
                                   isVariadic, impControl);
 }
 
-ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,SourceLocation atLoc,
+ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
+                                             SourceLocation atLoc,
                                              unsigned numRefProtos,
                                              IdentifierInfo *Id,
                                              bool ForwardDecl, bool isInternal){
   void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>();
-  return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos, Id, ForwardDecl,
+  return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos,
+                                     Id, ForwardDecl,
                                      isInternal);
 }
 
-ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L,
+ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCInterfaceDecl *CD,
+                                   SourceLocation L,
                                    IdentifierInfo *Id, QualType T) {
   void *Mem = C.getAllocator().Allocate<ObjCIvarDecl>();
-  return new (Mem) ObjCIvarDecl(L, Id, T);
+  return new (Mem) ObjCIvarDecl(CD, L, Id, T);
 }
 
-ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, SourceLocation L, 
+ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C,
+                                           SourceLocation L, 
                                            unsigned numRefProtos,
                                            IdentifierInfo *Id) {
   void *Mem = C.getAllocator().Allocate<ObjCProtocolDecl>();
   return new (Mem) ObjCProtocolDecl(L, numRefProtos, Id);
 }
 
-ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, SourceLocation L,
+ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C,
+                                     SourceLocation L,
                                      ObjCInterfaceDecl **Elts, unsigned nElts) {
   void *Mem = C.getAllocator().Allocate<ObjCClassDecl>();
   return new (Mem) ObjCClassDecl(L, Elts, nElts);
 }
 
 ObjCForwardProtocolDecl *
-ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L, 
+ObjCForwardProtocolDecl::Create(ASTContext &C,
+                                SourceLocation L, 
                                 ObjCProtocolDecl **Elts, unsigned NumElts) {
   void *Mem = C.getAllocator().Allocate<ObjCForwardProtocolDecl>();
   return new (Mem) ObjCForwardProtocolDecl(L, Elts, NumElts);
 }
 
-ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, SourceLocation L,
+ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C,
+                                           SourceLocation L,
                                            IdentifierInfo *Id) {
   void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
   return new (Mem) ObjCCategoryDecl(L, Id);
 }
 
 ObjCCategoryImplDecl *
-ObjCCategoryImplDecl::Create(ASTContext &C, SourceLocation L,IdentifierInfo *Id,
+ObjCCategoryImplDecl::Create(ASTContext &C,
+                             SourceLocation L,IdentifierInfo *Id,
                              ObjCInterfaceDecl *ClassInterface) {
   void *Mem = C.getAllocator().Allocate<ObjCCategoryImplDecl>();
   return new (Mem) ObjCCategoryImplDecl(L, Id, ClassInterface);
 }
 
 ObjCImplementationDecl *
-ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L,
+ObjCImplementationDecl::Create(ASTContext &C,
+                               SourceLocation L,
                                IdentifierInfo *Id,
                                ObjCInterfaceDecl *ClassInterface,
                                ObjCInterfaceDecl *SuperDecl) {
@@ -90,14 +101,16 @@ ObjCImplementationDecl::Create(ASTContext &C, SourceLocation L,
 }
 
 ObjCCompatibleAliasDecl *
-ObjCCompatibleAliasDecl::Create(ASTContext &C, SourceLocation L,
+ObjCCompatibleAliasDecl::Create(ASTContext &C,
+                                SourceLocation L,
                                 IdentifierInfo *Id, 
                                 ObjCInterfaceDecl* AliasedClass) {
   void *Mem = C.getAllocator().Allocate<ObjCCompatibleAliasDecl>();
   return new (Mem) ObjCCompatibleAliasDecl(L, Id, AliasedClass);
 }
 
-ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, SourceLocation L) {
+ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
+                                           SourceLocation L) {
   void *Mem = C.getAllocator().Allocate<ObjCPropertyDecl>();
   return new (Mem) ObjCPropertyDecl(L);
 }
@@ -431,3 +444,4 @@ void ObjCPropertyDecl::setPropertyDeclLists(ObjCIvarDecl **Properties,
 }
 
 
+
index fe2ccefdce2afacf25d9f9abf45bf2f8cfb2764e..3a79b9e0e292983822f892d2ca1b1798dba4aa7b 100644 (file)
@@ -39,7 +39,7 @@ Decl* Decl::Create(Deserializer& D) {
     default:
       assert (false && "Not implemented.");
       break;
-      
+
     case BlockVar:
       return BlockVarDecl::CreateImpl(D);
       
@@ -106,11 +106,15 @@ void NamedDecl::ReadInRec(Deserializer& D) {
 void ScopedDecl::EmitInRec(Serializer& S) const {
   NamedDecl::EmitInRec(S);
   S.EmitPtr(getNext());                     // From ScopedDecl.  
+  S.EmitPtr(cast_or_null<Decl>(getContext()));  // From ScopedDecl.
 }
 
 void ScopedDecl::ReadInRec(Deserializer& D) {
   NamedDecl::ReadInRec(D);
   D.ReadPtr(Next);                                  // From ScopedDecl.
+  Decl *TmpD;
+  D.ReadPtr(TmpD);                                  // From ScopedDecl.
+  CtxDecl = cast_or_null<ContextDecl>(TmpD);
 }
     
   //===------------------------------------------------------------===//
@@ -194,7 +198,7 @@ void VarDecl::ReadImpl(Deserializer& D) {
 
 BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) {  
   BlockVarDecl* decl = 
-    new BlockVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
+    new BlockVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
  
   decl->VarDecl::ReadImpl(D);
   
@@ -207,7 +211,7 @@ BlockVarDecl* BlockVarDecl::CreateImpl(Deserializer& D) {
 
 FileVarDecl* FileVarDecl::CreateImpl(Deserializer& D) {
   FileVarDecl* decl =
-    new FileVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
+    new FileVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
   
   decl->VarDecl::ReadImpl(D);
 
@@ -225,7 +229,7 @@ void ParmVarDecl::EmitImpl(llvm::Serializer& S) const {
 
 ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D) {
   ParmVarDecl* decl =
-    new ParmVarDecl(SourceLocation(),NULL,QualType(),None,NULL);
+    new ParmVarDecl(0, SourceLocation(),NULL,QualType(),None,NULL);
   
   decl->VarDecl::ReadImpl(D);
   decl->objcDeclQualifier = static_cast<ObjCDeclQualifier>(D.ReadInt());
@@ -245,7 +249,7 @@ void EnumDecl::EmitImpl(Serializer& S) const {
 }
 
 EnumDecl* EnumDecl::CreateImpl(Deserializer& D) {
-  EnumDecl* decl = new EnumDecl(SourceLocation(),NULL,NULL);
+  EnumDecl* decl = new EnumDecl(0, SourceLocation(),NULL,NULL);
   
   decl->ScopedDecl::ReadInRec(D);
   decl->setDefinition(D.ReadBool());
@@ -277,7 +281,7 @@ EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D) {
   D.Read(val);
   
   EnumConstantDecl* decl = 
-    new EnumConstantDecl(SourceLocation(),NULL,QualType(),NULL,
+    new EnumConstantDecl(0, SourceLocation(),NULL,QualType(),NULL,
                          val,NULL);
   
   decl->ValueDecl::ReadInRec(D);
@@ -302,7 +306,7 @@ void FieldDecl::EmitImpl(Serializer& S) const {
 }
 
 FieldDecl* FieldDecl::CreateImpl(Deserializer& D) {
-  FieldDecl* decl = new FieldDecl(SourceLocation(), NULL, QualType(), 0);
+  FieldDecl* decl = new FieldDecl(0, SourceLocation(), NULL, QualType(), 0);
   decl->DeclType.ReadBackpatch(D);  
   decl->ReadInRec(D);
   decl->BitWidth = D.ReadOwnedPtr<Expr>();
@@ -338,7 +342,7 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D) {
   bool IsInline = D.ReadBool();
   
   FunctionDecl* decl =
-    new FunctionDecl(SourceLocation(),NULL,QualType(),SClass, IsInline, 0);
+    new FunctionDecl(0, SourceLocation(),NULL,QualType(),SClass, IsInline, 0);
   
   decl->ValueDecl::ReadInRec(D);
   D.ReadPtr(decl->DeclChain);
@@ -382,7 +386,7 @@ void RecordDecl::EmitImpl(Serializer& S) const {
 }
 
 RecordDecl* RecordDecl::CreateImpl(Decl::Kind DK, Deserializer& D) {
-  RecordDecl* decl = new RecordDecl(DK,SourceLocation(),NULL,NULL);
+  RecordDecl* decl = new RecordDecl(DK,0,SourceLocation(),NULL,NULL);
     
   decl->ScopedDecl::ReadInRec(D);
   decl->setDefinition(D.ReadBool());
@@ -418,7 +422,7 @@ void TypedefDecl::EmitImpl(Serializer& S) const {
 TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D) {
   QualType T = QualType::ReadVal(D);
   
-  TypedefDecl* decl = new TypedefDecl(SourceLocation(),NULL,T,NULL);
+  TypedefDecl* decl = new TypedefDecl(0, SourceLocation(),NULL,T,NULL);
   
   decl->ScopedDecl::ReadInRec(D);
   decl->ScopedDecl::ReadOutRec(D);
index da78ec0678788e86b2d6cb289896d9e2641b365e..9e379e4be7460c91f3867682acca00adff324f26 100644 (file)
@@ -59,7 +59,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
   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 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
   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 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
 
 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 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
   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 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
     
     // 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);
index d2ad5c5f754bd2448060fabaceed9ea4a50f9acd..b1d0499d137129aa983eff0852ac2258ed2010f1 100644 (file)
@@ -32,6 +32,7 @@ namespace clang {
   class ASTConsumer;
   class Preprocessor;
   class Decl;
+  class ContextDecl;
   class NamedDecl;
   class ScopedDecl;
   class Expr;
@@ -73,7 +74,9 @@ class Sema : public Action {
   /// 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 @@ private:
   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);
index c9ea54fa0e9b5260580390209814df04eed38572..6f0f351000c72b7ff5335e5c5573d549cbb1c40f 100644 (file)
@@ -40,6 +40,17 @@ Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) {
   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 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
     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 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
     }
 
     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 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
              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 @@ Sema::ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI,
   } 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 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
   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 @@ Sema::DeclTy *Sema::ActOnFinishFunctionBody(DeclTy *D, StmtTy *Body) {
     MD->setBody((Stmt*)Body);
     CurMethodDecl = 0;
   }  
+  PopContextDecl();
   // Verify and clean out per-function state.
   
   // Check goto/label use.
@@ -1173,7 +1191,8 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
   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 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
   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 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
   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 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl,
   // 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 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *tagDecl,
            // 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 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
                                       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 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
   }
   
   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.
index 69a102203f4802dbee806300489e3940e1022af3..6b9b9e2d4312c759ef6d38c9e58057d6a7411514 100644 (file)
@@ -33,6 +33,7 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
   
   // 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,6 +814,21 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
     Diag(MethodLoc, diag::error_missing_method_context);
     return 0;
   }
+  QualType resultDeclType;
+  
+  if (ReturnType)
+    resultDeclType = QualType::getFromOpaquePtr(ReturnType);
+  else // get the type for "id".
+    resultDeclType = Context.getObjCIdType();
+  
+  ObjCMethodDecl* ObjCMethod = 
+    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
+                           ClassDecl, AttrList, 
+                           MethodType == tok::minus, isVariadic,
+                           MethodDeclKind == tok::objc_optional ? 
+                           ObjCMethodDecl::Optional : 
+                           ObjCMethodDecl::Required);
+  
   llvm::SmallVector<ParmVarDecl*, 16> Params;
   
   for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
@@ -823,28 +839,15 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(
       argType = QualType::getFromOpaquePtr(ArgTypes[i]);
     else
       argType = Context.getObjCIdType();
-    ParmVarDecl* Param = ParmVarDecl::Create(Context, SourceLocation(/*FIXME*/),
+    ParmVarDecl* Param = ParmVarDecl::Create(Context, ObjCMethod,
+                                             SourceLocation(/*FIXME*/),
                                              ArgNames[i], argType,
                                              VarDecl::None, 0);
     Param->setObjCDeclQualifier(
       CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier()));
     Params.push_back(Param);
   }
-  QualType resultDeclType;
-  
-  if (ReturnType)
-    resultDeclType = QualType::getFromOpaquePtr(ReturnType);
-  else // get the type for "id".
-    resultDeclType = Context.getObjCIdType();
-  
-  ObjCMethodDecl* ObjCMethod = 
-    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
-                           ClassDecl, AttrList, 
-                           MethodType == tok::minus, isVariadic,
-                           MethodDeclKind == tok::objc_optional ? 
-                           ObjCMethodDecl::Optional : 
-                           ObjCMethodDecl::Required);
-  
+
   ObjCMethod->setMethodParams(&Params[0], Sel.getNumArgs());
   ObjCMethod->setObjCDeclQualifier(
     CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));