aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-10-29 15:46:07 +0000
committerAnders Carlsson <andersca@mac.com>2009-10-29 15:46:07 +0000
commit0ebb6d391d2e29ed48a880517e2ba919bf7016d9 (patch)
treea1f9276a5b2d62237d4909775c9c4e620a80d371
parent8de39b431d3775cd46584080beec3a75d019bd28 (diff)
Make sure to call CompleteConstructorCall for bases and members that are initialized implicitly in constructors so that default arguments etc are set correctly. Fixes PR5283.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85510 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaDecl.cpp3
-rw-r--r--lib/Sema/SemaDeclCXX.cpp81
-rw-r--r--test/SemaTemplate/default-expr-arguments.cpp24
4 files changed, 81 insertions, 29 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 11a3938544..f89b7a7952 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2304,7 +2304,7 @@ public:
SourceLocation RParenLoc,
CXXRecordDecl *ClassDecl);
- void setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
+ void SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
CXXBaseOrMemberInitializer **Initializers,
unsigned NumInitializers,
llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2ba1130c87..71afe68916 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3769,6 +3769,9 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
}
Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+ // Clear the last template instantiation error context.
+ LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
+
if (!D)
return D;
FunctionDecl *FD = 0;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 01ab0a7241..90aef21637 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1123,7 +1123,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
}
void
-Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
+Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
CXXBaseOrMemberInitializer **Initializers,
unsigned NumInitializers,
llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
@@ -1179,7 +1179,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
- assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+ assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
AllToInit.push_back(Value);
@@ -1187,18 +1187,26 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
else {
CXXRecordDecl *VBaseDecl =
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
- assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
+ assert(VBaseDecl && "SetBaseOrMemberInitializers - VBaseDecl null");
CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context);
- if (!Ctor)
+ if (!Ctor) {
Bases.push_back(VBase);
- else
- MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
+ continue;
+ }
+ ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
+ if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0),
+ Constructor->getLocation(), CtorArgs))
+ continue;
+
+ MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
+
CXXBaseOrMemberInitializer *Member =
- new (Context) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
- Ctor,
- SourceLocation(),
- SourceLocation());
+ new (Context) CXXBaseOrMemberInitializer(VBase->getType(),
+ CtorArgs.takeAs<Expr>(),
+ CtorArgs.size(), Ctor,
+ SourceLocation(),
+ SourceLocation());
AllToInit.push_back(Member);
}
}
@@ -1216,7 +1224,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+ assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
AllToInit.push_back(Value);
@@ -1224,18 +1232,26 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
else {
CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
+ assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context);
- if (!Ctor)
+ if (!Ctor) {
Bases.push_back(Base);
- else
- MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
+ continue;
+ }
+
+ ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
+ if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0),
+ Constructor->getLocation(), CtorArgs))
+ continue;
+
+ MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
CXXBaseOrMemberInitializer *Member =
- new (Context) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
- BaseDecl->getDefaultConstructor(Context),
- SourceLocation(),
- SourceLocation());
+ new (Context) CXXBaseOrMemberInitializer(Base->getType(),
+ CtorArgs.takeAs<Expr>(),
+ CtorArgs.size(), Ctor,
+ SourceLocation(),
+ SourceLocation());
AllToInit.push_back(Member);
}
}
@@ -1268,7 +1284,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
QualType FT = (*Field)->getType();
if (const RecordType* RT = FT->getAs<RecordType>()) {
CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RT->getDecl());
- assert(FieldRecDecl && "setBaseOrMemberInitializers - BaseDecl null");
+ assert(FieldRecDecl && "SetBaseOrMemberInitializers - BaseDecl null");
if (CXXConstructorDecl *Ctor =
FieldRecDecl->getDefaultConstructor(Context))
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
@@ -1281,13 +1297,22 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
if (const RecordType* RT = FT->getAs<RecordType>()) {
CXXConstructorDecl *Ctor =
cast<CXXRecordDecl>(RT->getDecl())->getDefaultConstructor(Context);
- if (!Ctor && !FT->isDependentType())
+ if (!Ctor && !FT->isDependentType()) {
Fields.push_back(*Field);
+ continue;
+ }
+
+ ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
+ if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0),
+ Constructor->getLocation(), CtorArgs))
+ continue;
+
CXXBaseOrMemberInitializer *Member =
- new (Context) CXXBaseOrMemberInitializer((*Field), 0, 0,
- Ctor,
- SourceLocation(),
- SourceLocation());
+ new (Context) CXXBaseOrMemberInitializer(*Field,CtorArgs.takeAs<Expr>(),
+ CtorArgs.size(), Ctor,
+ SourceLocation(),
+ SourceLocation());
+
AllToInit.push_back(Member);
if (Ctor)
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
@@ -1327,10 +1352,10 @@ Sema::BuildBaseOrMemberInitializers(ASTContext &C,
CXXBaseOrMemberInitializer **Initializers,
unsigned NumInitializers
) {
- llvm::SmallVector<CXXBaseSpecifier *, 4>Bases;
- llvm::SmallVector<FieldDecl *, 4>Members;
+ llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
+ llvm::SmallVector<FieldDecl *, 4> Members;
- setBaseOrMemberInitializers(Constructor,
+ SetBaseOrMemberInitializers(Constructor,
Initializers, NumInitializers, Bases, Members);
for (unsigned int i = 0; i < Bases.size(); i++)
Diag(Bases[i]->getSourceRange().getBegin(),
diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp
index 575283ed8b..9c0f1ecf0c 100644
--- a/test/SemaTemplate/default-expr-arguments.cpp
+++ b/test/SemaTemplate/default-expr-arguments.cpp
@@ -84,3 +84,27 @@ struct X1 {
void test_X1() {
X1<int> x1;
}
+
+// PR5283
+namespace PR5283 {
+template<typename T> struct A {
+ A(T = 1); // expected-error 3 {{incompatible type initializing 'int', expected 'int *'}}
+};
+
+struct B : A<int*> {
+ B();
+};
+B::B() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct C : virtual A<int*> {
+ C();
+};
+C::C() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct D {
+ D();
+
+ A<int*> a;
+};
+D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+}