[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