[cfe-commits] r80446 - in /cfe/trunk: lib/AST/DeclCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-member-initializers.cpp

Eli Friedman eli.friedman at gmail.com
Sat Aug 29 15:22:07 PDT 2009


Author: efriedma
Date: Sat Aug 29 17:22:07 2009
New Revision: 80446

URL: http://llvm.org/viewvc/llvm-project?rev=80446&view=rev
Log:
Make instantiating initializers for classes with a dependent base type 
work correctly.

The change in lib/AST/DeclCXX.cpp is mostly a large reindentation; I 
couldn't figure out a good way to avoid it.


Modified:
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=80446&r1=80445&r2=80446&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Sat Aug 29 17:22:07 2009
@@ -595,66 +595,81 @@
   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());
   llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
   llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*> AllBaseFields;
+  bool HasDependentBaseInit = false;
   
   for (unsigned i = 0; i < NumInitializers; i++) {
     CXXBaseOrMemberInitializer *Member = Initializers[i];
-    if (Member->isBaseInitializer())
+    if (Member->isBaseInitializer()) {
+      if (Member->getBaseClass()->isDependentType())
+        HasDependentBaseInit = true;
       AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member;
-    else
+    } else {
       AllBaseFields[Member->getMember()] = Member;
+    }
   }
+
+  if (HasDependentBaseInit) {
+    // If we have a dependent base initialization, we can't determine the
+    // association between initializers and bases; just dump the known
+    // initializers into the list, and don't try to deal with other bases.
+    for (unsigned i = 0; i < NumInitializers; i++) {
+      CXXBaseOrMemberInitializer *Member = Initializers[i];
+      if (Member->isBaseInitializer())
+        AllToInit.push_back(Member);
+    }
+  } else {
+    // Push virtual bases before others.
+    for (CXXRecordDecl::base_class_iterator VBase =
+         ClassDecl->vbases_begin(),
+         E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
+      if (VBase->getType()->isDependentType())
+        continue;
+      if (CXXBaseOrMemberInitializer *Value = 
+          AllBaseFields.lookup(VBase->getType()->getAs<RecordType>()))
+        AllToInit.push_back(Value);
+      else {
+        CXXRecordDecl *VBaseDecl = 
+          cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
+        assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
+        if (!VBaseDecl->getDefaultConstructor(C))
+          Bases.push_back(VBase);
+        CXXBaseOrMemberInitializer *Member = 
+          new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
+                                            VBaseDecl->getDefaultConstructor(C),
+                                             SourceLocation(),
+                                             SourceLocation());
+        AllToInit.push_back(Member);
+      }
+    }
     
-  // Push virtual bases before others.
-  for (CXXRecordDecl::base_class_iterator VBase =
-       ClassDecl->vbases_begin(),
-       E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
-    if (VBase->getType()->isDependentType())
-      continue;
-    if (CXXBaseOrMemberInitializer *Value = 
-        AllBaseFields.lookup(VBase->getType()->getAs<RecordType>()))
-      AllToInit.push_back(Value);
-    else {
-      CXXRecordDecl *VBaseDecl = 
-        cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
-      assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
-      if (!VBaseDecl->getDefaultConstructor(C))
-        Bases.push_back(VBase);
-      CXXBaseOrMemberInitializer *Member = 
-        new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
-                                           VBaseDecl->getDefaultConstructor(C),
+    for (CXXRecordDecl::base_class_iterator Base =
+         ClassDecl->bases_begin(),
+         E = ClassDecl->bases_end(); Base != E; ++Base) {
+      // Virtuals are in the virtual base list and already constructed.
+      if (Base->isVirtual())
+        continue;
+      // Skip dependent types.
+      if (Base->getType()->isDependentType())
+        continue;
+      if (CXXBaseOrMemberInitializer *Value = 
+          AllBaseFields.lookup(Base->getType()->getAs<RecordType>()))
+        AllToInit.push_back(Value);
+      else {
+        CXXRecordDecl *BaseDecl = 
+          cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+        assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+        if (!BaseDecl->getDefaultConstructor(C))
+          Bases.push_back(Base);
+        CXXBaseOrMemberInitializer *Member = 
+        new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
+                                           BaseDecl->getDefaultConstructor(C),
                                            SourceLocation(),
                                            SourceLocation());
-      AllToInit.push_back(Member);
-    }
-  }
-  
-  for (CXXRecordDecl::base_class_iterator Base =
-       ClassDecl->bases_begin(),
-       E = ClassDecl->bases_end(); Base != E; ++Base) {
-    // Virtuals are in the virtual base list and already constructed.
-    if (Base->isVirtual())
-      continue;
-    // Skip dependent types.
-    if (Base->getType()->isDependentType())
-      continue;
-    if (CXXBaseOrMemberInitializer *Value = 
-        AllBaseFields.lookup(Base->getType()->getAs<RecordType>()))
-      AllToInit.push_back(Value);
-    else {
-      CXXRecordDecl *BaseDecl = 
-        cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-      assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
-      if (!BaseDecl->getDefaultConstructor(C))
-        Bases.push_back(Base);
-      CXXBaseOrMemberInitializer *Member = 
-      new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
-                                         BaseDecl->getDefaultConstructor(C),
-                                         SourceLocation(),
-                                         SourceLocation());
-      AllToInit.push_back(Member);
+        AllToInit.push_back(Member);
+      }
     }
   }
-  
+
   // non-static data members.
   for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
        E = ClassDecl->field_end(); Field != E; ++Field) {

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80446&r1=80445&r2=80446&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Aug 29 17:22:07 2009
@@ -1134,9 +1134,9 @@
     MemInitResult NewInit;
 
     if (Init->isBaseInitializer()) {
-      // FIXME: Type needs to be instantiated.
-      QualType BaseType = 
-        Context.getCanonicalType(QualType(Init->getBaseClass(), 0));
+      QualType BaseType(Init->getBaseClass(), 0);
+      BaseType = SubstType(BaseType, TemplateArgs, Init->getSourceLocation(),
+                           New->getDeclName());
 
       NewInit = BuildBaseInitializer(BaseType,
                                      (Expr **)NewArgs.data(), 

Modified: cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp?rev=80446&r1=80445&r2=80446&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-member-initializers.cpp Sat Aug 29 17:22:07 2009
@@ -18,3 +18,9 @@
 };
 
 B<int> b0;
+
+template <class T> struct AA { AA(int); };
+template <class T> class BB : public AA<T> {
+  BB() : AA<T>(1) {}
+};
+BB<int> x;





More information about the cfe-commits mailing list