[cfe-commits] r74480 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/class-base-member-init.cpp
Fariborz Jahanian
fjahanian at apple.com
Mon Jun 29 17:02:17 PDT 2009
Author: fjahanian
Date: Mon Jun 29 19:02:17 2009
New Revision: 74480
URL: http://llvm.org/viewvc/llvm-project?rev=74480&view=rev
Log:
A more detailed diagnosis of ill-formed ctor-initializer
list.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaCXX/class-base-member-init.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=74480&r1=74479&r2=74480&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Jun 29 19:02:17 2009
@@ -588,15 +588,20 @@
/// 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 @@
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.
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=74480&r1=74479&r2=74480&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Jun 29 19:02:17 2009
@@ -294,8 +294,9 @@
}
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::
-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");
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=74480&r1=74479&r2=74480&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jun 29 19:02:17 2009
@@ -688,7 +688,8 @@
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 @@
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 @@
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;
}
}
}
Modified: cfe/trunk/test/SemaCXX/class-base-member-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/class-base-member-init.cpp?rev=74480&r1=74479&r2=74480&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/class-base-member-init.cpp (original)
+++ cfe/trunk/test/SemaCXX/class-base-member-init.cpp Mon Jun 29 19:02:17 2009
@@ -7,7 +7,9 @@
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;
More information about the cfe-commits
mailing list