Add constructor used to initialize base/member in
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 23 Jul 2009 00:42:24 +0000 (00:42 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 23 Jul 2009 00:42:24 +0000 (00:42 +0000)
CXXBaseOrMemberInitializer AST node. Needed by
its clients to do the initialization.

llvm-svn: 76826

clang/include/clang/AST/DeclCXX.h
clang/lib/AST/DeclCXX.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/SemaCXX/constructor-initializer.cpp

index 6f9eee7..1d153ee 100644 (file)
@@ -736,6 +736,10 @@ class CXXBaseOrMemberInitializer {
   Expr **Args;
   unsigned NumArgs;
   
+  /// CtorToCall - For a base or mamber needing a constructor for their
+  /// initialization, this is the constructor to call.
+  CXXConstructorDecl *CtorToCall;
+  
   /// IdLoc - Location of the id in ctor-initializer list.
   SourceLocation IdLoc;
 
@@ -743,11 +747,13 @@ public:
   /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
   explicit 
   CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
+                             CXXConstructorDecl *C,
                              SourceLocation L);
 
   /// CXXBaseOrMemberInitializer - Creates a new member initializer.
   explicit 
   CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
+                             CXXConstructorDecl *C,
                              SourceLocation L);
 
   /// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
@@ -805,6 +811,8 @@ public:
       return 0;
   }
 
+  CXXConstructorDecl *getConstructor() const { return CtorToCall; }
+  
   SourceLocation getSourceLocation() const { return IdLoc; }
   
   /// begin() - Retrieve an iterator to the first initializer argument.
index eb66c17..0f22301 100644 (file)
@@ -380,6 +380,7 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
 
 CXXBaseOrMemberInitializer::
 CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
+                           CXXConstructorDecl *C,
                            SourceLocation L) 
   : Args(0), NumArgs(0), IdLoc(L) {
   BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
@@ -392,10 +393,12 @@ CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
     for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
       this->Args[Idx] = Args[Idx];
   }
+  CtorToCall = C;
 }
 
 CXXBaseOrMemberInitializer::
 CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
+                           CXXConstructorDecl *C,
                            SourceLocation L)
   : Args(0), NumArgs(0), IdLoc(L) {
   BaseOrMember = reinterpret_cast<uintptr_t>(Member);
@@ -407,6 +410,7 @@ CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
     for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
       this->Args[Idx] = Args[Idx];
   }
+  CtorToCall = C;
 }
 
 CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
@@ -587,9 +591,14 @@ CXXConstructorDecl::setBaseOrMemberInitializers(
     if (AllBaseFields[Key])
       AllToInit.push_back(AllBaseFields[Key]);
     else {
+      CXXRecordDecl *VBaseDecl = 
+        cast<CXXRecordDecl>(VBase->getType()->getAsRecordType()->getDecl());
+      assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
+      // FIXME. Issue error if default ctor is missing.
       CXXBaseOrMemberInitializer *Member = 
-      new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
-                                         SourceLocation());
+        new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
+                                           VBaseDecl->getDefaultConstructor(C),
+                                           SourceLocation());
       AllToInit.push_back(Member);
     }
   }
@@ -605,8 +614,13 @@ CXXConstructorDecl::setBaseOrMemberInitializers(
     if (AllBaseFields[Key])
       AllToInit.push_back(AllBaseFields[Key]);
     else {
+      CXXRecordDecl *BaseDecl = 
+        cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
+      assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+      // FIXME. Issue error if default ctor is missing.
       CXXBaseOrMemberInitializer *Member = 
       new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
+                                         BaseDecl->getDefaultConstructor(C),
                                          SourceLocation());
       AllToInit.push_back(Member);
     }
@@ -625,8 +639,15 @@ CXXConstructorDecl::setBaseOrMemberInitializers(
       FieldType = AT->getElementType();
       
     if (FieldType->getAsRecordType()) {
+      CXXConstructorDecl *Ctor = 0;
+      if (CXXRecordDecl *FieldClassDecl = 
+            dyn_cast<CXXRecordDecl>(FieldType->getAsRecordType()->getDecl()))
+        Ctor = FieldClassDecl->getDefaultConstructor(C);
+      // FIXME. Issue error if default ctor is missing.
       CXXBaseOrMemberInitializer *Member = 
-        new (C) CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation());
+        new (C) CXXBaseOrMemberInitializer((*Field), 0, 0,
+                                           Ctor,
+                                           SourceLocation());
       AllToInit.push_back(Member);
     } 
   }
index 3bb1657..c12878c 100644 (file)
@@ -717,9 +717,17 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
     // FIXME: Handle members of an anonymous union.
 
     if (Member) {
+      CXXConstructorDecl *C = 0;
+      QualType FieldType = Member->getType();
+      if (const ArrayType *Array = Context.getAsArrayType(FieldType))
+        FieldType = Array->getElementType();
+      if (!FieldType->isDependentType() && FieldType->getAsRecordType())
+        C = PerformInitializationByConstructor(
+              FieldType, (Expr **)Args, NumArgs, IdLoc, 
+              SourceRange(IdLoc, RParenLoc), Member->getDeclName(), IK_Direct);
       // FIXME: Perform direct initialization of the member.
       return new (Context) CXXBaseOrMemberInitializer(Member, (Expr **)Args, 
-                                                      NumArgs, IdLoc);
+                                                      NumArgs, C, IdLoc);
     }
   }
   // It didn't name a member, so see if it names a class.
@@ -789,10 +797,17 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
     return Diag(IdLoc, diag::err_not_direct_base_or_virtual)
     << BaseType << ClassDecl->getNameAsCString()
     << SourceRange(IdLoc, RParenLoc);
-    
-
-  return new (Context) CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, 
-                                                  NumArgs, IdLoc);
+  DeclarationName Name 
+    = Context.DeclarationNames.getCXXConstructorName(
+        Context.getCanonicalType(BaseType));
+  CXXConstructorDecl *C = 0;
+  if (!BaseType->isDependentType())
+    C = PerformInitializationByConstructor(BaseType, (Expr **)Args, NumArgs, IdLoc, 
+                                       SourceRange(IdLoc, RParenLoc), Name,
+                                       IK_Direct);
+  
+  return new (Context) CXXBaseOrMemberInitializer(BaseType, (Expr **)Args,
+                                                  NumArgs, C, IdLoc);
 }
 
 static void *GetKeyForTopLevelField(FieldDecl *Field) {
index 206d5d2..66a5f57 100644 (file)
@@ -2,6 +2,7 @@
 class A { 
   int m;
    A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
+   A(int);
 };
 
 class B : public A {