Author: rtrieu Date: Wed Mar 28 22:14:17 2018 New Revision: 328763 URL: http://llvm.org/viewvc/llvm-project?rev=328763&view=rev Log: 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. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=328763&r1=328762&r2=328763&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Mar 28 22:14:17 2018 @@ -16028,39 +16028,10 @@ static bool ValidDuplicateEnum(EnumConst 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<Decl *> 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( if (Enum->getNumPositiveBits() > 63 || Enum->getNumNegativeBits() > 64) return; + if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation())) + return; + typedef SmallVector<EnumConstantDecl *, 3> ECDVector; - typedef SmallVector<ECDVector *, 3> DuplicatesVector; + typedef SmallVector<std::unique_ptr<ECDVector>, 3> DuplicatesVector; typedef llvm::PointerUnion<EnumConstantDecl*, ECDVector*> DeclOrVector; - typedef llvm::DenseMap<DupKey, DeclOrVector, DenseMapInfoDupKey> - ValueToVectorMap; + typedef llvm::DenseMap<int64_t, DeclOrVector> 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<EnumConstantDecl>(Elements[i]); + // an initializer. + for (auto *Element : Elements) { + EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(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( 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<EnumConstantDecl>(Elements[i]); + for (auto *Element : Elements) { + // The last loop returned if any constant was null. + EnumConstantDecl *ECD = cast<EnumConstantDecl>(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<EnumConstantDecl*>()) { // 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<ECDVector>(); 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( } // 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(); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits