Added new C++ AST Decl subclasses.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52155 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
index 07e9232..96e887c 100644
--- a/include/clang/AST/AST.h
+++ b/include/clang/AST/AST.h
@@ -17,6 +17,7 @@
 // This header exports all AST interfaces.
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 1bfad2e..c404e4f 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file defines the Decl interface and subclasses.
+//  This file defines the Decl subclasses.
 //
 //===----------------------------------------------------------------------===//
 
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_AST_DECL_H
 
 #include "clang/AST/DeclBase.h"
+#include "clang/Parse/AccessSpecifier.h"
 
 namespace clang {
 class Expr;
@@ -382,11 +383,6 @@
   /// function.
   ScopedDecl *DeclChain;
   
-  // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
-  unsigned SClass : 2;
-  bool IsInline : 1;
-  bool IsImplicit : 1;
-  
   /// PreviousDeclaration - A link to the previous declaration of this
   /// same function, NULL if this is the first declaration. For
   /// example, in the following code, the PreviousDeclaration can be
@@ -398,13 +394,19 @@
   ///   int f(int x, int y) { return x + y; }
   FunctionDecl *PreviousDeclaration;
 
-  FunctionDecl(DeclContext *DC, SourceLocation L,
+  // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
+  unsigned SClass : 2;
+  bool IsInline : 1;
+  bool IsImplicit : 1;
+
+protected:
+  FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
                IdentifierInfo *Id, QualType T,
                StorageClass S, bool isInline, ScopedDecl *PrevDecl)
-    : ValueDecl(Function, DC, L, Id, T, PrevDecl), 
-      DeclContext(Function),
-      ParamInfo(0), Body(0), DeclChain(0), SClass(S), 
-      IsInline(isInline), IsImplicit(0), PreviousDeclaration(0) {}
+    : ValueDecl(DK, DC, L, Id, T, PrevDecl), 
+      DeclContext(DK),
+      ParamInfo(0), Body(0), DeclChain(0), PreviousDeclaration(0),
+      SClass(S), IsInline(isInline), IsImplicit(0) {}
 
   virtual ~FunctionDecl();
   virtual void Destroy(ASTContext& C);
@@ -498,7 +500,9 @@
   bool isInline() const { return IsInline; }
  
   // Implement isa/cast/dyncast/etc.
-  static bool classof(const Decl *D) { return D->getKind() == Function; }
+  static bool classof(const Decl *D) {
+    return D->getKind() >= FunctionFirst && D->getKind() <= FunctionLast;
+  }
   static bool classof(const FunctionDecl *D) { return true; }
 
 protected:
@@ -608,6 +612,9 @@
            IdentifierInfo *Id, ScopedDecl *PrevDecl)
     : ScopedDecl(DK, DC, L, Id, PrevDecl), TypeForDecl(0) {}
 public:
+  void setAccess(AccessSpecifier AS) { Access = AS; }
+  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
     return D->getKind() >= TypeFirst && D->getKind() <= TypeLast;
@@ -759,7 +766,8 @@
   /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
   FieldDecl **Members;   // Null if not defined.
   int NumMembers;   // -1 if not defined.
-  
+
+protected:
   RecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 
              ScopedDecl *PrevDecl) : TagDecl(DK, DC, L, Id, PrevDecl) {
     HasFlexibleArrayMember = false;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index b4f4c3b..4bc2cc9 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -21,9 +21,11 @@
 namespace clang {
 class TranslationUnitDecl;
 class NamespaceDecl;
+class ScopedDecl;
 class FunctionDecl;
-class ObjCMethodDecl;
+class CXXRecordDecl;
 class EnumDecl;
+class ObjCMethodDecl;
 class ObjCInterfaceDecl;
 
 /// Decl - This represents one declaration (or definition), e.g. a variable, 
@@ -35,11 +37,13 @@
     // 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.
+    // [DeclContext] indicatea that the class also inherits from DeclContext.
     
     // Decl
-         TranslationUnit,
+         TranslationUnit,  // [DeclContext]
     //   NamedDecl
            Field,
+             CXXField,
              ObjCIvar,
            ObjCCategory,
            ObjCCategoryImpl,
@@ -47,23 +51,29 @@
            ObjCProtocol,
            ObjCProperty,
     //     ScopedDecl
-             Namespace,
+             Namespace,  // [DeclContext]
     //       TypeDecl
                Typedef,
     //         TagDecl
-                 Enum,
+                 Enum,  // [DeclContext]
     //           RecordDecl
                    Struct,
                    Union,
                    Class,
+    //             CXXRecordDecl  [DeclContext]
+                     CXXStruct,
+                     CXXUnion,
+                     CXXClass,
     //       ValueDecl
                EnumConstant,
-               Function,
+               Function,  // [DeclContext]
+                 CXXMethod,
                Var,
+                 CXXClassVar,
                  ParmVar,
-         ObjCInterface,
+         ObjCInterface,  // [DeclContext]
          ObjCCompatibleAlias,
-         ObjCMethod,
+         ObjCMethod,  // [DeclContext]
          ObjCClass,
          ObjCForwardProtocol,
          ObjCPropertyImpl,
@@ -72,14 +82,16 @@
   
     // 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 = Namespace,     ScopedLast = ParmVar,
-    TypeFirst   = Typedef,       TypeLast   = Class,
-    TagFirst    = Enum         , TagLast    = Class,
-    RecordFirst = Struct       , RecordLast = Class,
-    ValueFirst  = EnumConstant , ValueLast  = ParmVar,
-    VarFirst    = Var          , VarLast    = ParmVar
+    NamedFirst     = Field        , NamedLast     = ParmVar,
+    FieldFirst     = Field        , FieldLast     = ObjCIvar,
+    ScopedFirst    = Namespace    , ScopedLast    = ParmVar,
+    TypeFirst      = Typedef      , TypeLast      = CXXClass,
+    TagFirst       = Enum         , TagLast       = CXXClass,
+    RecordFirst    = Struct       , RecordLast    = CXXClass,
+    CXXRecordFirst = CXXStruct    , CXXRecordLast = CXXClass,
+    ValueFirst     = EnumConstant , ValueLast     = ParmVar,
+    FunctionFirst  = Function     , FunctionLast  = CXXMethod,
+    VarFirst       = Var          , VarLast       = ParmVar
   };
 
   /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
@@ -118,7 +130,13 @@
   
   /// HasAttrs - This indicates whether the decl has attributes or not.
   unsigned int HasAttrs : 1;
-protected:
+
+ protected:
+  /// Access - Used by C++ decls for the access specifier.
+  // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+  unsigned Access : 2;
+  friend class CXXClassMemberWrapper;
+
   Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
     HasAttrs(false) {
     if (Decl::CollectingStats()) addDeclKind(DK);
@@ -161,10 +179,14 @@
     case EnumConstant:
     case ObjCInterface:
     case ObjCCompatibleAlias:
+    case CXXField:
       return IDNS_Ordinary;
     case Struct:
     case Union:
     case Class:
+    case CXXStruct:
+    case CXXUnion:
+    case CXXClass:
     case Enum:
       return IDNS_Tag;
     case Namespace:
@@ -206,8 +228,9 @@
 ///   TranslationUnitDecl
 ///   NamespaceDecl
 ///   FunctionDecl
-///   ObjCMethodDecl
+///   CXXRecordDecl
 ///   EnumDecl
+///   ObjCMethodDecl
 ///   ObjCInterfaceDecl
 ///
 class DeclContext {
@@ -230,15 +253,18 @@
         return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
       case Decl::Namespace:
         return static_cast<NamespaceDecl*>(const_cast<From*>(D));
-      case Decl::Function:
-        return static_cast<FunctionDecl*>(const_cast<From*>(D));
+      case Decl::Enum:
+        return static_cast<EnumDecl*>(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));
-      case Decl::Enum:
-        return static_cast<EnumDecl*>(const_cast<From*>(D));
       default:
+        if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
+          return static_cast<FunctionDecl*>(const_cast<From*>(D));
+        if (DK >= Decl::CXXRecordFirst && DK <= Decl::CXXRecordLast)
+          return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
+
         assert(false && "a decl that inherits DeclContext isn't handled");
         return 0;
     }
@@ -255,6 +281,7 @@
   bool isFunctionOrMethod() const {
     switch (DeclKind) {
       case Decl::Function:
+      case Decl::CXXMethod:
       case Decl::ObjCMethod:
         return true;
       default:
@@ -272,12 +299,17 @@
     switch (D->getKind()) {
       case Decl::TranslationUnit:
       case Decl::Namespace:
-      case Decl::Function:
+      case Decl::Enum:
       case Decl::ObjCMethod:
       case Decl::ObjCInterface:
-      case Decl::Enum:
         return true;
       default:
+        if (D->getKind() >= Decl::FunctionFirst &&
+            D->getKind() <= Decl::FunctionLast)
+          return true;
+        if (D->getKind() >= Decl::CXXRecordFirst &&
+            D->getKind() <= Decl::CXXRecordLast)
+          return true;
         return false;
     }
   }
@@ -285,8 +317,9 @@
   static bool classof(const TranslationUnitDecl *D) { return true; }
   static bool classof(const NamespaceDecl *D) { return true; }
   static bool classof(const FunctionDecl *D) { return true; }
-  static bool classof(const ObjCMethodDecl *D) { return true; }
+  static bool classof(const CXXRecordDecl *D) { return true; }
   static bool classof(const EnumDecl *D) { return true; }
+  static bool classof(const ObjCMethodDecl *D) { return true; }
   static bool classof(const ObjCInterfaceDecl *D) { return true; }
 };
 
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
new file mode 100644
index 0000000..4c152f5
--- /dev/null
+++ b/include/clang/AST/DeclCXX.h
@@ -0,0 +1,195 @@
+//===-- DeclCXX.h - Classes for representing C++ 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 C++ Decl subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLCXX_H
+#define LLVM_CLANG_AST_DECLCXX_H
+
+#include "clang/AST/Decl.h"
+
+namespace clang {
+class CXXRecordDecl;
+
+/// CXXFieldDecl - Represents an instance field of a C++ struct/union/class.
+class CXXFieldDecl : public FieldDecl {
+  CXXRecordDecl *Parent;
+
+  CXXFieldDecl(CXXRecordDecl *RD, SourceLocation L, IdentifierInfo *Id,
+               QualType T, Expr *BW = NULL)
+    : FieldDecl(CXXField, L, Id, T, BW), Parent(RD) {}
+public:
+  static CXXFieldDecl *Create(ASTContext &C, CXXRecordDecl *RD,SourceLocation L,
+                              IdentifierInfo *Id, QualType T, Expr *BW = NULL);
+
+  void setAccess(AccessSpecifier AS) { Access = AS; }
+  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
+  CXXRecordDecl *getParent() const { return Parent; }
+    
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return D->getKind() == CXXField; }
+  static bool classof(const CXXFieldDecl *D) { return true; }
+};
+
+/// CXXRecordDecl - Represents a C++ struct/union/class.
+/// The only difference with RecordDecl is that CXXRecordDecl is a DeclContext.
+class CXXRecordDecl : public RecordDecl, public DeclContext {
+protected:
+  CXXRecordDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
+             ScopedDecl *PrevDecl) : RecordDecl(DK, DC, L, Id, PrevDecl),
+                                     DeclContext(DK) {
+    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
+  }
+public:
+  static CXXRecordDecl *Create(ASTContext &C, Kind DK, DeclContext *DC,
+                            SourceLocation L, IdentifierInfo *Id,
+                            ScopedDecl *PrevDecl);
+  
+  const CXXFieldDecl *getMember(unsigned i) const {
+    return cast<const CXXFieldDecl>(RecordDecl::getMember(i));
+  }
+  CXXFieldDecl *getMember(unsigned i) {
+    return cast<CXXFieldDecl>(RecordDecl::getMember(i));
+  }
+
+  /// getMember - If the member doesn't exist, or there are no members, this 
+  /// function will return 0;
+  CXXFieldDecl *getMember(IdentifierInfo *name) {
+    return cast_or_null<CXXFieldDecl>(RecordDecl::getMember(name));
+  }
+
+  static bool classof(const Decl *D) {
+    return D->getKind() >= CXXRecordFirst && D->getKind() <= CXXRecordLast;
+  }
+  static bool classof(const CXXRecordDecl *D) { return true; }
+
+protected:
+  /// EmitImpl - Serialize this CXXRecordDecl.  Called by Decl::Emit.
+  // FIXME: Implement this.
+  //virtual void EmitImpl(llvm::Serializer& S) const;
+  
+  /// CreateImpl - Deserialize a CXXRecordDecl.  Called by Decl::Create.
+  // FIXME: Implement this.
+  static CXXRecordDecl* CreateImpl(Kind DK, llvm::Deserializer& D, ASTContext& C);
+  
+  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
+};
+
+/// CXXMethodDecl - Represents a static or instance method of a
+/// struct/union/class.
+class CXXMethodDecl : public FunctionDecl {
+
+  CXXMethodDecl(CXXRecordDecl *RD, SourceLocation L,
+               IdentifierInfo *Id, QualType T,
+               bool isStatic, bool isInline, ScopedDecl *PrevDecl)
+    : FunctionDecl(CXXMethod, RD, L, Id, T, (isStatic ? Static : None),
+                   isInline, PrevDecl) {}
+public:
+  static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                              SourceLocation L, IdentifierInfo *Id,
+                              QualType T, bool isStatic = false,
+                              bool isInline = false,  ScopedDecl *PrevDecl = 0);
+  
+  bool isStatic() const { return getStorageClass() == Static; }
+  bool isInstance() const { return !isStatic(); }
+
+  void setAccess(AccessSpecifier AS) { Access = AS; }
+  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
+
+  /// getThisType - Returns the type of 'this' pointer.
+  /// Should only be called for instance methods.
+  QualType getThisType(ASTContext &C) const;
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return D->getKind() == CXXMethod; }
+  static bool classof(const CXXMethodDecl *D) { return true; }
+
+protected:
+  /// EmitImpl - Serialize this CXXMethodDecl.  Called by Decl::Emit.
+  // FIXME: Implement this.
+  //virtual void EmitImpl(llvm::Serializer& S) const;
+  
+  /// CreateImpl - Deserialize a CXXMethodDecl.  Called by Decl::Create.
+  // FIXME: Implement this.
+  static CXXMethodDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
+  
+  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
+};
+
+/// CXXClassVarDecl - Represents a static data member of a struct/union/class.
+class CXXClassVarDecl : public VarDecl {
+
+  CXXClassVarDecl(CXXRecordDecl *RD, SourceLocation L,
+              IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
+    : VarDecl(CXXClassVar, RD, L, Id, T, None, PrevDecl) {}
+public:
+  static CXXClassVarDecl *Create(ASTContext &C, CXXRecordDecl *RD,
+                             SourceLocation L,IdentifierInfo *Id,
+                             QualType T, ScopedDecl *PrevDecl);
+  
+  void setAccess(AccessSpecifier AS) { Access = AS; }
+  AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return D->getKind() == CXXClassVar; }
+  static bool classof(const CXXClassVarDecl *D) { return true; }
+  
+protected:
+  /// EmitImpl - Serialize this CXXClassVarDecl. Called by Decl::Emit.
+  // FIXME: Implement this.
+  //virtual void EmitImpl(llvm::Serializer& S) const;
+  
+  /// CreateImpl - Deserialize a CXXClassVarDecl.  Called by Decl::Create.
+  // FIXME: Implement this.
+  static CXXClassVarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
+
+  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
+};
+
+
+/// CXXClassMemberWrapper - A wrapper class for C++ class member decls.
+/// Common functions like set/getAccess are included here to avoid bloating
+/// the interface of non-C++ specific decl classes, like NamedDecl.
+class CXXClassMemberWrapper {
+  Decl *MD;
+
+public:
+  CXXClassMemberWrapper(Decl *D) : MD(D) {
+    assert(isMember(D) && "Not a C++ class member!");
+  }
+
+  AccessSpecifier getAccess() const {
+    return AccessSpecifier(MD->Access);
+  }
+
+  void setAccess(AccessSpecifier AS) {
+    assert(AS != AS_none && "Access must be specified.");
+    MD->Access = AS;
+  }
+
+  CXXRecordDecl *getParent() const {
+    if (ScopedDecl *SD = dyn_cast<ScopedDecl>(MD)) {
+      return cast<CXXRecordDecl>(SD->getDeclContext());
+    }
+    return cast<CXXFieldDecl>(MD)->getParent();
+  }
+
+  static bool isMember(Decl *D) {
+    if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
+      return isa<CXXRecordDecl>(SD->getDeclContext());
+    }
+    return isa<CXXFieldDecl>(D);
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 8d68a58..b5dba10 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -62,7 +62,7 @@
                                    StorageClass S, bool isInline, 
                                    ScopedDecl *PrevDecl) {
   void *Mem = C.getAllocator().Allocate<FunctionDecl>();
-  return new (Mem) FunctionDecl(DC, L, Id, T, S, isInline, PrevDecl);
+  return new (Mem) FunctionDecl(Function, DC, L, Id, T, S, isInline, PrevDecl);
 }
 
 FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index b5b0283..296304a 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/ASTContext.h"
 #include "llvm/ADT/DenseMap.h"
 using namespace clang;
@@ -206,6 +207,13 @@
   case LinkageSpec:         nLinkageSpecDecl++; break;
   case FileScopeAsm:        nFileScopeAsmDecl++; break;
   case TranslationUnit:     break;
+
+  // FIXME: Statistics for C++ decls.
+  case CXXField:
+  case CXXStruct:  case CXXUnion:  case CXXClass:
+  case CXXMethod:
+  case CXXClassVar:
+    break;
   }
 }
 
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
new file mode 100644
index 0000000..c319191
--- /dev/null
+++ b/lib/AST/DeclCXX.cpp
@@ -0,0 +1,58 @@
+//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//

+//

+//                     The LLVM Compiler Infrastructure

+//

+// This file is distributed under the University of Illinois Open Source

+// License. See LICENSE.TXT for details.

+//

+//===----------------------------------------------------------------------===//

+//

+// This file implements the C++ related Decl classes.

+//

+//===----------------------------------------------------------------------===//

+

+#include "clang/AST/DeclCXX.h"

+#include "clang/AST/ASTContext.h"

+using namespace clang;

+

+//===----------------------------------------------------------------------===//

+// Decl Allocation/Deallocation Method Implementations

+//===----------------------------------------------------------------------===//

+ 

+CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,

+                                   SourceLocation L, IdentifierInfo *Id,

+                                   QualType T, Expr *BW) {

+  void *Mem = C.getAllocator().Allocate<CXXFieldDecl>();

+  return new (Mem) CXXFieldDecl(RD, L, Id, T, BW);

+}

+

+CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, Kind DK, DeclContext *DC,

+                                     SourceLocation L, IdentifierInfo *Id,

+                                     ScopedDecl *PrevDecl) {

+  void *Mem = C.getAllocator().Allocate<CXXRecordDecl>();

+  return new (Mem) CXXRecordDecl(DK, DC, L, Id, PrevDecl);

+}

+

+CXXMethodDecl *

+CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,

+                      SourceLocation L, IdentifierInfo *Id,

+                      QualType T, bool isStatic, bool isInline,

+                      ScopedDecl *PrevDecl) {

+  void *Mem = C.getAllocator().Allocate<CXXMethodDecl>();

+  return new (Mem) CXXMethodDecl(RD, L, Id, T, isStatic, isInline, PrevDecl);

+}

+

+QualType CXXMethodDecl::getThisType(ASTContext &C) const {

+  assert(isInstance() && "No 'this' for static methods!");

+  QualType ClassTy = C.getTagDeclType(cast<CXXRecordDecl>(getParent()));

+  QualType ThisTy = C.getPointerType(ClassTy);

+  ThisTy.addConst();

+  return ThisTy;

+}

+

+CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,

+                                   SourceLocation L, IdentifierInfo *Id,

+                                   QualType T, ScopedDecl *PrevDecl) {

+  void *Mem = C.getAllocator().Allocate<CXXClassVarDecl>();

+  return new (Mem) CXXClassVarDecl(RD, L, Id, T, PrevDecl);

+}

diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index bbc28ab..ca9a152 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -384,7 +384,8 @@
   
   void *Mem = C.getAllocator().Allocate<FunctionDecl>();
   FunctionDecl* decl = new (Mem)
-    FunctionDecl(0, SourceLocation(), NULL, QualType(), SClass, IsInline, 0);
+    FunctionDecl(Function, 0, SourceLocation(), NULL,
+                 QualType(), SClass, IsInline, 0);
   
   decl->ValueDecl::ReadInRec(D, C);
   D.ReadPtr(decl->DeclChain);