[cfe-commits] r74465 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclCXX.cpp test/SemaCXX/class-base-member-init.cpp
Douglas Gregor
dgregor at apple.com
Mon Jun 29 16:10:39 PDT 2009
On Jun 29, 2009, at 3:33 PM, Fariborz Jahanian wrote:
> Author: fjahanian
> Date: Mon Jun 29 17:33:26 2009
> New Revision: 74465
>
> URL: http://llvm.org/viewvc/llvm-project?rev=74465&view=rev
> Log:
> Diagnose multiple initialzation of data-member/base
> in the ctor-initializer list. More to come.
>
> Added:
> cfe/trunk/test/SemaCXX/class-base-member-init.cpp
> Modified:
> cfe/trunk/include/clang/AST/DeclCXX.h
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=74465&r1=74464&r2=74465&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Jun 29 17:33:26 2009
> @@ -609,6 +609,10 @@
> /// arguments.
> typedef Expr * const * arg_const_iterator;
>
> + /// getBaseOrMember - get the generic 'member' representing
> either the field
> + /// or a base class.
> + uintptr_t getBaseOrMember() const { return BaseOrMember; }
> +
> /// isBaseInitializer - Returns true when this initializer is
> /// initializing a base class.
> bool isBaseInitializer() const { return (BaseOrMember & 0x1) != 0; }
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=74465&r1=74464&r2=74465&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jun 29
> 17:33:26 2009
> @@ -1579,6 +1579,12 @@
> def err_only_constructors_take_base_inits : Error<
> "only constructors take base initializers">;
>
> +def error_multiple_mem_initialization : Error <
> + "multiple initializations given for non-static member '%0'">;
> +
> +def error_multiple_base_initialization : Error <
> + "multiple initializations given for base %0">;
> +
> def err_mem_init_not_member_or_class : Error<
> "member initializer %0 does not name a non-static data member or
> base "
> "class">;
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=74465&r1=74464&r2=74465&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jun 29 17:33:26 2009
> @@ -766,6 +766,24 @@
> Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
> return;
> }
> + llvm::DenseSet<uintptr_t>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());
> + else {
> + if (FieldDecl *Field = Member->getMember())
> + Diag(ColonLoc, diag::error_multiple_mem_initialization)
> + << Field->getNameAsString();
> + else if (Type *BaseClass = Member->getBaseClass())
> + Diag(ColonLoc, diag::error_multiple_base_initialization)
> + << BaseClass->getDesugaredType(true);
> + else
> + assert(false && "ActOnMemInitializers - neither field or
> base");
> + }
> + }
> }
Could we also emit a note pointing to the prior initialization, so
that users know which two initializations to look at?
- Doug
More information about the cfe-commits
mailing list