forked from OSchip/llvm-project
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:
parent
36d7c5f29b
commit
9cf6b59400
|
@ -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 "
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue