r328763 - Refactor some code for a warning. NFC.
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 28 22:14:18 PDT 2018
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();
}
}
More information about the cfe-commits
mailing list