Add additional note to mark the cause of synthesized constructors. Mark

declaration invalid if the constructor can't be properly built.  Addresses
remaining review comments from Fariborz for r86500.

llvm-svn: 86579
This commit is contained in:
Eli Friedman 2009-11-09 19:20:36 +00:00
parent 36d7c5f29b
commit 9cf6b59400
5 changed files with 27 additions and 8 deletions

View File

@ -433,6 +433,8 @@ def err_implicit_object_parameter_init : Error<
def note_field_decl : Note<"member is declared here">;
def note_previous_class_decl : Note<
"%0 declared here">;
def note_ctor_synthesized_at : Note<
"implicit default constructor for %0 first required here">;
def err_missing_default_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{base class|member}2 %3 which does not have a default "

View File

@ -1186,7 +1186,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
NumArgs, C, IdLoc, RParenLoc);
}
void
bool
Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
CXXBaseOrMemberInitializer **Initializers,
unsigned NumInitializers,
@ -1197,6 +1197,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*> AllBaseFields;
bool HasDependentBaseInit = false;
bool HadError = false;
for (unsigned i = 0; i < NumInitializers; i++) {
CXXBaseOrMemberInitializer *Member = Initializers[i];
@ -1258,6 +1259,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< 0 << VBase->getType();
Diag(VBaseDecl->getLocation(), diag::note_previous_class_decl)
<< Context.getTagDeclType(VBaseDecl);
HadError = true;
continue;
}
@ -1307,6 +1309,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< 0 << Base->getType();
Diag(BaseDecl->getLocation(), diag::note_previous_class_decl)
<< Context.getTagDeclType(BaseDecl);
HadError = true;
continue;
}
@ -1378,6 +1381,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
Diag(Field->getLocation(), diag::note_field_decl);
Diag(RT->getDecl()->getLocation(), diag::note_previous_class_decl)
<< Context.getTagDeclType(RT->getDecl());
HadError = true;
continue;
}
@ -1399,6 +1403,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
<< 1 << (*Field)->getDeclName();
Diag((*Field)->getLocation(), diag::note_declared_at);
HadError = true;
}
}
else if (FT->isReferenceType()) {
@ -1406,12 +1411,14 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
<< 0 << (*Field)->getDeclName();
Diag((*Field)->getLocation(), diag::note_declared_at);
HadError = true;
}
else if (FT.isConstQualified()) {
Diag(Constructor->getLocation(), diag::err_unintialized_member_in_ctor)
<< (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
<< 1 << (*Field)->getDeclName();
Diag((*Field)->getLocation(), diag::note_declared_at);
HadError = true;
}
}
@ -1425,6 +1432,8 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
for (unsigned Idx = 0; Idx < NumInitializers; ++Idx)
baseOrMemberInitializers[Idx] = AllToInit[Idx];
}
return HadError;
}
static void *GetKeyForTopLevelField(FieldDecl *Field) {
@ -2957,9 +2966,17 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
!Constructor->isUsed()) &&
"DefineImplicitDefaultConstructor - call it for implicit default ctor");
SetBaseOrMemberInitializers(Constructor, 0, 0, true);
CXXRecordDecl *ClassDecl
= cast<CXXRecordDecl>(Constructor->getDeclContext());
assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor");
Constructor->setUsed();
if (SetBaseOrMemberInitializers(Constructor, 0, 0, true)) {
Diag(CurrentLocation, diag::note_ctor_synthesized_at)
<< Context.getTagDeclType(ClassDecl);
Constructor->setInvalidDecl();
} else {
Constructor->setUsed();
}
return;
}

View File

@ -26,7 +26,7 @@ IntHolder &test_X_IntHolderInt(X<IntHolder, int> xih) {
xih.g(); // okay
xih.f(); // expected-note{{instantiation}}
X<IntHolder, int>::Inner inner;
X<IntHolder, int>::Inner inner; // expected-note {{first required here}}
return X<IntHolder, int>::value; // expected-note{{instantiation}}
}

View File

@ -11,7 +11,7 @@ struct X2 : X1 { // expected-note {{'struct X2' declared here}} \
struct X3 : public X2 { // expected-error {{must explicitly initialize the base class 'struct X2'}}
};
X3 x3;
X3 x3; // expected-note {{first required here}}
struct X4 { // expected-error {{must explicitly initialize the member 'x2'}} \
@ -20,7 +20,7 @@ struct X4 { // expected-error {{must explicitly initialize the member 'x2'}} \
X2 & rx2; // expected-note {{declared at}}
};
X4 x4;
X4 x4; // expected-note {{first required here}}
struct Y1 { // has no implicit default constructor
@ -52,5 +52,5 @@ struct Z1 { // expected-error {{must explicitly initialize the reference member
volatile int v1;
};
Z1 z1;
Z1 z1; // expected-note {{first required here}}

View File

@ -6,5 +6,5 @@ struct A { // expected-error {{implicit default constructor for 'struct A' must
};
int main () {
(void)A();
(void)A(); // expected-note {{first required here}}
}