From 9d436205be3e4c05854530134be61b46b13136ff Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 3 Sep 2009 21:32:41 +0000 Subject: [PATCH] Mark constructors used in initialization of base(s) and fields as referecned with location where they are used. Still need to look at destructor aspects of them. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80950 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 62 ++++++++++++++---------- test/CodeGenCXX/constructor-template.cpp | 14 ++++-- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 7c854be1dd..075c945456 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -948,17 +948,27 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, if (VBase->getType()->isDependentType()) continue; if (CXXBaseOrMemberInitializer *Value = - AllBaseFields.lookup(VBase->getType()->getAs())) + AllBaseFields.lookup(VBase->getType()->getAs())) { + CXXRecordDecl *BaseDecl = + cast(VBase->getType()->getAs()->getDecl()); + assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); + if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context)) + MarkDeclarationReferenced(Value->getSourceLocation(), Ctor); AllToInit.push_back(Value); + } else { CXXRecordDecl *VBaseDecl = cast(VBase->getType()->getAs()->getDecl()); assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null"); - if (!VBaseDecl->getDefaultConstructor(Context)) + CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context); + if (!Ctor) Bases.push_back(VBase); + else + MarkDeclarationReferenced(Constructor->getLocation(), Ctor); + CXXBaseOrMemberInitializer *Member = new (Context) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0, - VBaseDecl->getDefaultConstructor(Context), + Ctor, SourceLocation(), SourceLocation()); AllToInit.push_back(Member); @@ -975,14 +985,24 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, if (Base->getType()->isDependentType()) continue; if (CXXBaseOrMemberInitializer *Value = - AllBaseFields.lookup(Base->getType()->getAs())) + AllBaseFields.lookup(Base->getType()->getAs())) { + CXXRecordDecl *BaseDecl = + cast(Base->getType()->getAs()->getDecl()); + assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); + if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context)) + MarkDeclarationReferenced(Value->getSourceLocation(), Ctor); AllToInit.push_back(Value); + } else { CXXRecordDecl *BaseDecl = - cast(Base->getType()->getAs()->getDecl()); + cast(Base->getType()->getAs()->getDecl()); assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); - if (!BaseDecl->getDefaultConstructor(Context)) + CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context); + if (!Ctor) Bases.push_back(Base); + else + MarkDeclarationReferenced(Constructor->getLocation(), Ctor); + CXXBaseOrMemberInitializer *Member = new (Context) CXXBaseOrMemberInitializer(Base->getType(), 0, 0, BaseDecl->getDefaultConstructor(Context), @@ -1017,6 +1037,14 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, continue; } if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*Field)) { + QualType FT = (*Field)->getType(); + if (const RecordType* RT = FT->getAs()) { + CXXRecordDecl *FieldRecDecl = cast(RT->getDecl()); + assert(FieldRecDecl && "setBaseOrMemberInitializers - BaseDecl null"); + if (CXXConstructorDecl *Ctor = + FieldRecDecl->getDefaultConstructor(Context)) + MarkDeclarationReferenced(Value->getSourceLocation(), Ctor); + } AllToInit.push_back(Value); continue; } @@ -1033,6 +1061,8 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor, SourceLocation(), SourceLocation()); AllToInit.push_back(Member); + if (Ctor) + MarkDeclarationReferenced(Constructor->getLocation(), Ctor); if (FT.isConstQualified() && (!Ctor || Ctor->isTrivial())) { Diag(Constructor->getLocation(), diag::err_unintialized_member_in_ctor) << Context.getTagDeclType(ClassDecl) << 1 << (*Field)->getDeclName(); @@ -1176,25 +1206,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, if (Constructor->isDependentContext()) return; - // Mark all constructors used in initialization of class's members - // as referenced. - // FIXME. We can do this while building the initializer list. But - // MarkDeclarationReferenced is not accessible in ASTContext. - for (CXXConstructorDecl::init_const_iterator B = Constructor->init_begin(), - E = Constructor->init_end(); - B != E; ++B) { - CXXBaseOrMemberInitializer *Member = (*B); - if (!Member->isMemberInitializer()) - continue; - FieldDecl *Field = Member->getMember(); - QualType FT = Context.getBaseElementType(Field->getType()); - if (FT->isDependentType()) - continue; - if (const RecordType* RT = FT->getAs()) - if (CXXConstructorDecl *Ctor = - cast(RT->getDecl())->getDefaultConstructor(Context)) - MarkDeclarationReferenced(Ctor->getLocation(), Ctor); - } + if (Diags.getDiagnosticLevel(diag::warn_base_initialized) == Diagnostic::Ignored && Diags.getDiagnosticLevel(diag::warn_field_initialized) == diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp index 43abda435b..5fc6c2dfab 100644 --- a/test/CodeGenCXX/constructor-template.cpp +++ b/test/CodeGenCXX/constructor-template.cpp @@ -24,7 +24,14 @@ public: List(){ } // List*>::List() remains undefined. }; -template class BinomialNode { +template class Node { + int i; +public: + Node(){ } // Node*>::Node() remains undefined. +}; + + +template class BinomialNode : Node*> { public: BinomialNode(T value) {} List*> nodes; @@ -35,7 +42,8 @@ int main() { BinomialNode *node = new BinomialNode(1); } +// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev: // CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev: -// CHECK-LP32:__ZN4ListIP12BinomialNodeIiEEC1Ev: - +// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev: +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev: