From: Richard Trieu Date: Thu, 29 Mar 2018 05:14:17 +0000 (+0000) Subject: Refactor some code for a warning. NFC. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a04c82fd35ceac9da931f730b9682718157dcd49;p=clang Refactor some code for a warning. NFC. Use range-based for-loops instead of iterators to walk over vectors. Switch the key of the DenseMap so a custom key handler is no longer needed. Remove unncessary adds to the DenseMap. Use unique_ptr instead of manual memory management. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328763 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a4ae32e460..d5e4b8a816 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -16028,39 +16028,10 @@ static bool ValidDuplicateEnum(EnumConstantDecl *ECD, EnumDecl *Enum) { return false; } -namespace { -struct DupKey { - int64_t val; - bool isTombstoneOrEmptyKey; - DupKey(int64_t val, bool isTombstoneOrEmptyKey) - : val(val), isTombstoneOrEmptyKey(isTombstoneOrEmptyKey) {} -}; - -static DupKey GetDupKey(const llvm::APSInt& Val) { - return DupKey(Val.isSigned() ? Val.getSExtValue() : Val.getZExtValue(), - false); -} - -struct DenseMapInfoDupKey { - static DupKey getEmptyKey() { return DupKey(0, true); } - static DupKey getTombstoneKey() { return DupKey(1, true); } - static unsigned getHashValue(const DupKey Key) { - return (unsigned)(Key.val * 37); - } - static bool isEqual(const DupKey& LHS, const DupKey& RHS) { - return LHS.isTombstoneOrEmptyKey == RHS.isTombstoneOrEmptyKey && - LHS.val == RHS.val; - } -}; -} // end anonymous namespace - // Emits a warning when an element is implicitly set a value that // a previous element has already been set to. static void CheckForDuplicateEnumValues(Sema &S, ArrayRef Elements, - EnumDecl *Enum, - QualType EnumType) { - if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation())) - return; + EnumDecl *Enum, QualType EnumType) { // Avoid anonymous enums if (!Enum->getIdentifier()) return; @@ -16069,20 +16040,28 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef Elements, if (Enum->getNumPositiveBits() > 63 || Enum->getNumNegativeBits() > 64) return; + if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation())) + return; + typedef SmallVector ECDVector; - typedef SmallVector DuplicatesVector; + typedef SmallVector, 3> DuplicatesVector; typedef llvm::PointerUnion DeclOrVector; - typedef llvm::DenseMap - ValueToVectorMap; + typedef llvm::DenseMap ValueToVectorMap; + + // Use int64_t as a key to avoid needing special handling for DenseMap keys. + auto EnumConstantToKey = [](const EnumConstantDecl *D) { + llvm::APSInt Val = D->getInitVal(); + return Val.isSigned() ? Val.getSExtValue() : Val.getZExtValue(); + }; DuplicatesVector DupVector; ValueToVectorMap EnumMap; // Populate the EnumMap with all values represented by enum constants without - // an initialier. - for (unsigned i = 0, e = Elements.size(); i != e; ++i) { - EnumConstantDecl *ECD = cast_or_null(Elements[i]); + // an initializer. + for (auto *Element : Elements) { + EnumConstantDecl *ECD = cast_or_null(Element); // Null EnumConstantDecl means a previous diagnostic has been emitted for // this constant. Skip this enum since it may be ill-formed. @@ -16090,45 +16069,45 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef Elements, return; } + // Constants with initalizers are handled in the next loop. if (ECD->getInitExpr()) continue; - DupKey Key = GetDupKey(ECD->getInitVal()); - DeclOrVector &Entry = EnumMap[Key]; - - // First time encountering this value. - if (Entry.isNull()) - Entry = ECD; + // Duplicate values are handled in the next loop. + EnumMap.insert({EnumConstantToKey(ECD), ECD}); } + if (EnumMap.size() == 0) + return; + // Create vectors for any values that has duplicates. - for (unsigned i = 0, e = Elements.size(); i != e; ++i) { - EnumConstantDecl *ECD = cast(Elements[i]); + for (auto *Element : Elements) { + // The last loop returned if any constant was null. + EnumConstantDecl *ECD = cast(Element); if (!ValidDuplicateEnum(ECD, Enum)) continue; - DupKey Key = GetDupKey(ECD->getInitVal()); - - DeclOrVector& Entry = EnumMap[Key]; - if (Entry.isNull()) + auto Iter = EnumMap.find(EnumConstantToKey(ECD)); + if (Iter == EnumMap.end()) continue; + DeclOrVector& Entry = Iter->second; if (EnumConstantDecl *D = Entry.dyn_cast()) { // Ensure constants are different. if (D == ECD) continue; // Create new vector and push values onto it. - ECDVector *Vec = new ECDVector(); + auto Vec = llvm::make_unique(); Vec->push_back(D); Vec->push_back(ECD); // Update entry to point to the duplicates vector. - Entry = Vec; + Entry = Vec.get(); // Store the vector somewhere we can consult later for quick emission of // diagnostics. - DupVector.push_back(Vec); + DupVector.emplace_back(std::move(Vec)); continue; } @@ -16141,26 +16120,21 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef Elements, } // Emit diagnostics. - for (DuplicatesVector::iterator DupVectorIter = DupVector.begin(), - DupVectorEnd = DupVector.end(); - DupVectorIter != DupVectorEnd; ++DupVectorIter) { - ECDVector *Vec = *DupVectorIter; + for (const auto &Vec : DupVector) { assert(Vec->size() > 1 && "ECDVector should have at least 2 elements."); // Emit warning for one enum constant. - ECDVector::iterator I = Vec->begin(); - S.Diag((*I)->getLocation(), diag::warn_duplicate_enum_values) - << (*I) << (*I)->getInitVal().toString(10) - << (*I)->getSourceRange(); - ++I; + auto *FirstECD = Vec->front(); + S.Diag(FirstECD->getLocation(), diag::warn_duplicate_enum_values) + << FirstECD << FirstECD->getInitVal().toString(10) + << FirstECD->getSourceRange(); // Emit one note for each of the remaining enum constants with // the same value. - for (ECDVector::iterator E = Vec->end(); I != E; ++I) - S.Diag((*I)->getLocation(), diag::note_duplicate_element) - << (*I) << (*I)->getInitVal().toString(10) - << (*I)->getSourceRange(); - delete Vec; + for (auto *ECD : llvm::make_range(Vec->begin() + 1, Vec->end())) + S.Diag(ECD->getLocation(), diag::note_duplicate_element) + << ECD << ECD->getInitVal().toString(10) + << ECD->getSourceRange(); } }