[cfe-commits] [Patch] -Wduplicate-enum which fixes PR6343

Richard Smith richard at metafoo.co.uk
Wed Jul 25 15:05:52 PDT 2012


On Wed, Jul 25, 2012 at 3:03 PM, Richard Smith <richard at metafoo.co.uk>wrote:

> +  // Use to store the smallest APSInt size that can represent all the
> elements.
> +  bool signedness = false;
> +  unsigned bitwidth = 0;
> +
> +  // Skip diagnostic if previous error were found with the enum.
> +  for (unsigned i = 0; i != NumElements; ++i) {
> +    EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]);
> +    if (!ECD)
> +      return;
> +
> +    const llvm::APSInt& Val = ECD->getInitVal();
> +    if (!signedness && Val.isSigned()) {
> +      signedness = true;
> +     ++bitwidth;
> +    }
> +
> +    unsigned ValWidth;
> +    if (Val.isUnsigned())
> +      ValWidth = Val.getActiveBits() + signedness;
> +    else if (Val.isNonNegative())
> +      ValWidth = Val.getActiveBits() + 1;
> +    else
> +      ValWidth = Val.getBitWidth() - Val.countLeadingOnes() + 1;
> +
> +    if (bitwidth < ValWidth)
> +      bitwidth = ValWidth;
> +  }
>
> You can get these directly from the EnumDecl: see getNumPositiveBits,
> getNumNegativeBits.
>
> +  // Store a map of values to decls.  Values are extended to a common size
> +  // first to for comparisons.
> +  std::map<llvm::APSInt, EnumConstantDecl*> ValueMap;
>
> How about building a SmallVector of EnumConstantDecl*, sorting it by init
> value then by whether there is an init expression, and finally performing
> your check as a single linear pass over the vector? That should be a bit
> quicker than the repeated map lookups and heap allocations you're currently
> doing.
>

I'd also suggest disabling the warning if your enumeration doesn't fit in
64 bits, and using getZExtValue rather than extOrTrunc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120725/43d39257/attachment.html>


More information about the cfe-commits mailing list