aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-09-03 21:32:41 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-09-03 21:32:41 +0000
commit9d436205be3e4c05854530134be61b46b13136ff (patch)
tree3051e49b2fed607ea4ca044b5b1ae441766a6d8f
parent80545ad0f9b8e52177a8c37bd140bae0ffbd0cc6 (diff)
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
-rw-r--r--lib/Sema/SemaDeclCXX.cpp62
-rw-r--r--test/CodeGenCXX/constructor-template.cpp14
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<RecordType>()))
+ AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
+ CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
+ assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+ if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
+ MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
AllToInit.push_back(Value);
+ }
else {
CXXRecordDecl *VBaseDecl =
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->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<RecordType>()))
+ AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
+ CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+ if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
+ MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
AllToInit.push_back(Value);
+ }
else {
CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->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<RecordType>()) {
+ CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(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<RecordType>())
- if (CXXConstructorDecl *Ctor =
- cast<CXXRecordDecl>(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<BinomialNode<int>*>::List() remains undefined.
};
-template<typename T> class BinomialNode {
+template <typename T> class Node {
+ int i;
+public:
+ Node(){ } // Node<BinomialNode<int>*>::Node() remains undefined.
+};
+
+
+template<typename T> class BinomialNode : Node<BinomialNode<T>*> {
public:
BinomialNode(T value) {}
List<BinomialNode<T>*> nodes;
@@ -35,7 +42,8 @@ int main() {
BinomialNode<int> *node = new BinomialNode<int>(1);
}
+// CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev:
-// CHECK-LP32:__ZN4ListIP12BinomialNodeIiEEC1Ev:
-
+// CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC1Ev:
+// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev: