[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