зеркало из https://github.com/microsoft/clang-1.git
A more detailed diagnosis of ill-formed ctor-initializer
list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74480 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
811844d5eb
Коммит
47deacfa43
|
@ -588,15 +588,20 @@ class CXXBaseOrMemberInitializer {
|
|||
/// Args - The arguments used to initialize the base or member.
|
||||
Expr **Args;
|
||||
unsigned NumArgs;
|
||||
|
||||
/// IdLoc - Location of the id in ctor-initializer list.
|
||||
SourceLocation IdLoc;
|
||||
|
||||
public:
|
||||
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
|
||||
explicit
|
||||
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs);
|
||||
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
|
||||
SourceLocation L);
|
||||
|
||||
/// CXXBaseOrMemberInitializer - Creates a new member initializer.
|
||||
explicit
|
||||
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs);
|
||||
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
|
||||
SourceLocation L);
|
||||
|
||||
/// ~CXXBaseOrMemberInitializer - Destroy the base or member initializer.
|
||||
~CXXBaseOrMemberInitializer();
|
||||
|
@ -653,6 +658,8 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
SourceLocation getSourceLocation() const { return IdLoc; }
|
||||
|
||||
/// begin() - Retrieve an iterator to the first initializer argument.
|
||||
arg_iterator begin() { return Args; }
|
||||
/// begin() - Retrieve an iterator to the first initializer argument.
|
||||
|
|
|
@ -294,8 +294,9 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
|
|||
}
|
||||
|
||||
CXXBaseOrMemberInitializer::
|
||||
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
|
||||
: Args(0), NumArgs(0) {
|
||||
CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
|
||||
SourceLocation L)
|
||||
: Args(0), NumArgs(0), IdLoc(L) {
|
||||
BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
|
||||
assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
|
||||
BaseOrMember |= 0x01;
|
||||
|
@ -309,8 +310,9 @@ CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
|
|||
}
|
||||
|
||||
CXXBaseOrMemberInitializer::
|
||||
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
|
||||
: Args(0), NumArgs(0) {
|
||||
CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
|
||||
SourceLocation L)
|
||||
: Args(0), NumArgs(0), IdLoc(L) {
|
||||
BaseOrMember = reinterpret_cast<uintptr_t>(Member);
|
||||
assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
|
||||
|
||||
|
|
|
@ -688,7 +688,8 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
|
|||
|
||||
if (Member) {
|
||||
// FIXME: Perform direct initialization of the member.
|
||||
return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs);
|
||||
return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs,
|
||||
IdLoc);
|
||||
}
|
||||
|
||||
// It didn't name a member, so see if it names a class.
|
||||
|
@ -750,7 +751,8 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
|
|||
return Diag(IdLoc, diag::err_base_init_direct_and_virtual)
|
||||
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
|
||||
|
||||
return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs);
|
||||
return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs,
|
||||
IdLoc);
|
||||
}
|
||||
|
||||
void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
|
||||
|
@ -766,22 +768,27 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
|
|||
Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
|
||||
return;
|
||||
}
|
||||
llvm::DenseSet<uintptr_t>Members;
|
||||
llvm::DenseMap<uintptr_t, CXXBaseOrMemberInitializer *>Members;
|
||||
|
||||
for (unsigned i = 0; i < NumMemInits; i++) {
|
||||
CXXBaseOrMemberInitializer *Member =
|
||||
static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
|
||||
if (Members.count(Member->getBaseOrMember()) == 0)
|
||||
Members.insert(Member->getBaseOrMember());
|
||||
CXXBaseOrMemberInitializer *&PrevMember = Members[Member->getBaseOrMember()];
|
||||
if (!PrevMember)
|
||||
PrevMember = Member;
|
||||
else {
|
||||
if (FieldDecl *Field = Member->getMember())
|
||||
Diag(ColonLoc, diag::error_multiple_mem_initialization)
|
||||
<< Field->getNameAsString();
|
||||
Diag(Member->getSourceLocation(),
|
||||
diag::error_multiple_mem_initialization)
|
||||
<< Field->getNameAsString();
|
||||
else if (Type *BaseClass = Member->getBaseClass())
|
||||
Diag(ColonLoc, diag::error_multiple_base_initialization)
|
||||
Diag(Member->getSourceLocation(),
|
||||
diag::error_multiple_base_initialization)
|
||||
<< BaseClass->getDesugaredType(true);
|
||||
else
|
||||
assert(false && "ActOnMemInitializers - neither field or base");
|
||||
Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer)
|
||||
<< 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@ public:
|
|||
|
||||
struct D : S {
|
||||
D() : b1(0), b2(1), b1(0), S(), S() {} // expected-error {{multiple initializations given for non-static member 'b1'}} \
|
||||
// expected-error {{multiple initializations given for base 'class S'}}
|
||||
// expected-note {{previous initialization is here}} \
|
||||
// expected-error {{multiple initializations given for base 'class S'}} \
|
||||
// expected-note {{previous initialization is here}}
|
||||
|
||||
int b1;
|
||||
int b2;
|
||||
|
|
Загрузка…
Ссылка в новой задаче