[cfe-commits] r97589 - in /cfe/trunk: lib/CodeGen/CodeGenModule.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/implicit-virtual-member-functions.cpp test/SemaTemplate/virtual-member-functions.cpp
Rafael Espindola
rafael.espindola at gmail.com
Tue Mar 2 13:28:26 PST 2010
Author: rafael
Date: Tue Mar 2 15:28:26 2010
New Revision: 97589
URL: http://llvm.org/viewvc/llvm-project?rev=97589&view=rev
Log:
During codegen assert that any copy assignment, destructor or constructor that
we need to synthesize has been marked as used by Sema.
Change Sema to avoid these asserts.
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/implicit-virtual-member-functions.cpp
cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=97589&r1=97588&r2=97589&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Mar 2 15:28:26 2010
@@ -752,14 +752,20 @@
// A called constructor which has no definition or declaration need be
// synthesized.
else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
- if (CD->isImplicit())
+ if (CD->isImplicit()) {
+ assert (CD->isUsed());
DeferredDeclsToEmit.push_back(D);
+ }
} else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
- if (DD->isImplicit())
+ if (DD->isImplicit()) {
+ assert (DD->isUsed());
DeferredDeclsToEmit.push_back(D);
+ }
} else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
- if (MD->isCopyAssignment() && MD->isImplicit())
+ if (MD->isCopyAssignment() && MD->isImplicit()) {
+ assert (MD->isUsed());
DeferredDeclsToEmit.push_back(D);
+ }
}
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=97589&r1=97588&r2=97589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 2 15:28:26 2010
@@ -1638,8 +1638,22 @@
new (Context) CXXBaseOrMemberInitializer*[NumInitializers];
Constructor->setBaseOrMemberInitializers(baseOrMemberInitializers);
- for (unsigned Idx = 0; Idx < NumInitializers; ++Idx)
- baseOrMemberInitializers[Idx] = AllToInit[Idx];
+ for (unsigned Idx = 0; Idx < NumInitializers; ++Idx) {
+ CXXBaseOrMemberInitializer *Member = AllToInit[Idx];
+ baseOrMemberInitializers[Idx] = Member;
+ if (!Member->isBaseInitializer())
+ continue;
+ const Type *BaseType = Member->getBaseClass();
+ const RecordType *RT = BaseType->getAs<RecordType>();
+ if (!RT)
+ continue;
+ CXXRecordDecl *BaseClassDecl =
+ cast<CXXRecordDecl>(RT->getDecl());
+ if (BaseClassDecl->hasTrivialDestructor())
+ continue;
+ CXXDestructorDecl *DD = BaseClassDecl->getDestructor(Context);
+ MarkDeclarationReferenced(Constructor->getLocation(), DD);
+ }
}
return HadError;
@@ -5791,55 +5805,74 @@
return Dcl;
}
-void Sema::MaybeMarkVirtualMembersReferenced(SourceLocation Loc,
- CXXMethodDecl *MD) {
+static bool needsVtable(CXXMethodDecl *MD, ASTContext &Context) {
// Ignore dependent types.
if (MD->isDependentContext())
- return;
-
+ return false;
+
+ // Ignore declarations that are not definitions.
+ if (!MD->isThisDeclarationADefinition())
+ return false;
+
CXXRecordDecl *RD = MD->getParent();
-
+
// Ignore classes without a vtable.
if (!RD->isDynamicClass())
- return;
+ return false;
- // Ignore declarations that are not definitions.
- if (!MD->isThisDeclarationADefinition())
- return;
-
- if (isa<CXXConstructorDecl>(MD)) {
- switch (MD->getParent()->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ExplicitSpecialization:
- // Classes that aren't instantiations of templates don't need their
- // virtual methods marked until we see the definition of the key
- // function.
- return;
-
- case TSK_ImplicitInstantiation:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- // This is a constructor of a class template; mark all of the virtual
- // members as referenced to ensure that they get instantiatied.
- break;
- }
- } else if (!MD->isOutOfLine()) {
- // Consider only out-of-line definitions of member functions. When we see
- // an inline definition, it's too early to compute the key function.
- return;
- } else if (const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD)) {
- // If this is not the key function, we don't need to mark virtual members.
- if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl())
- return;
- } else {
- // The class has no key function, so we've already noted that we need to
- // mark the virtual members of this class.
- return;
+ switch (MD->getParent()->getTemplateSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ExplicitSpecialization:
+ // Classes that aren't instantiations of templates don't need their
+ // virtual methods marked until we see the definition of the key
+ // function.
+ break;
+
+ case TSK_ImplicitInstantiation:
+ // This is a constructor of a class template; mark all of the virtual
+ // members as referenced to ensure that they get instantiatied.
+ if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))
+ return true;
+ break;
+
+ case TSK_ExplicitInstantiationDeclaration:
+ return true; //FIXME: This looks wrong.
+
+ case TSK_ExplicitInstantiationDefinition:
+ // This is method of a explicit instantiation; mark all of the virtual
+ // members as referenced to ensure that they get instantiatied.
+ return true;
}
-
+
+ // Consider only out-of-line definitions of member functions. When we see
+ // an inline definition, it's too early to compute the key function.
+ if (!MD->isOutOfLine())
+ return false;
+
+ const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
+
+ // If there is no key function, we will need a copy of the vtable.
+ if (!KeyFunction)
+ return true;
+
+ // If this is the key function, we need to mark virtual members.
+ if (KeyFunction->getCanonicalDecl() == MD->getCanonicalDecl())
+ return true;
+
+ return false;
+}
+
+void Sema::MaybeMarkVirtualMembersReferenced(SourceLocation Loc,
+ CXXMethodDecl *MD) {
+ CXXRecordDecl *RD = MD->getParent();
+
// We will need to mark all of the virtual members as referenced to build the
// vtable.
- ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(RD, Loc));
+ // We actually call MarkVirtualMembersReferenced instead of adding to
+ // ClassesWithUnmarkedVirtualMembers because this marking is needed by
+ // codegen that will happend before we finish parsing the file.
+ if (needsVtable(MD, Context))
+ MarkVirtualMembersReferenced(Loc, RD);
}
bool Sema::ProcessPendingClassesWithUnmarkedVirtualMembers() {
@@ -5867,4 +5900,3 @@
MarkDeclarationReferenced(Loc, MD);
}
}
-
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=97589&r1=97588&r2=97589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Mar 2 15:28:26 2010
@@ -426,6 +426,18 @@
: diag::err_throw_incomplete)
<< E->getSourceRange()))
return true;
+
+ // FIXME: This is just a hack to mark the copy constructor referenced.
+ // This should go away when the next FIXME is fixed.
+ const RecordType *RT = Ty->getAs<RecordType>();
+ if (!RT)
+ return false;
+
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ if (RD->hasTrivialCopyConstructor())
+ return false;
+ CXXConstructorDecl *CopyCtor = RD->getCopyConstructor(Context, 0);
+ MarkDeclarationReferenced(ThrowLoc, CopyCtor);
}
// FIXME: Construct a temporary here.
Modified: cfe/trunk/test/SemaCXX/implicit-virtual-member-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/implicit-virtual-member-functions.cpp?rev=97589&r1=97588&r2=97589&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/implicit-virtual-member-functions.cpp (original)
+++ cfe/trunk/test/SemaCXX/implicit-virtual-member-functions.cpp Tue Mar 2 15:28:26 2010
@@ -15,9 +15,9 @@
struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
C();
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
-}; // expected-note {{implicit default destructor for 'struct C' first required here}}
+};
-C::C() { }
+C::C() { } // expected-note {{implicit default destructor for 'struct C' first required here}}
struct D : A { // expected-error {{no suitable member 'operator delete' in 'D'}}
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
Modified: cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp?rev=97589&r1=97588&r2=97589&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp (original)
+++ cfe/trunk/test/SemaTemplate/virtual-member-functions.cpp Tue Mar 2 15:28:26 2010
@@ -14,7 +14,7 @@
}
void f(A<int> x) {
- x.anchor();
+ x.anchor(); // expected-note{{in instantiation of member function 'PR5557::A<int>::anchor' requested here}}
}
template<typename T>
@@ -36,10 +36,10 @@
template<typename T>
struct Derived : Base<T> {
- virtual void foo() { }
+ virtual void foo() { } // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
};
-template struct Derived<int>; // expected-note{{instantiation}}
+template struct Derived<int>;
template<typename T>
struct HasOutOfLineKey {
@@ -52,4 +52,4 @@
return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
}
-HasOutOfLineKey<int> out_of_line;
+HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
More information about the cfe-commits
mailing list