diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index edcfcb68e1..83dc86f575 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -10521,233 +10521,6 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, return New; } -// Emits a warning if every element in the enum is the same value and if -// every element is initialized with a integer or boolean literal. -static void CheckForUniqueEnumValues(Sema &S, Decl **Elements, - unsigned NumElements, EnumDecl *Enum, - QualType EnumType) { - if (S.Diags.getDiagnosticLevel(diag::warn_identical_enum_values, - Enum->getLocation()) == - DiagnosticsEngine::Ignored) - return; - - if (NumElements < 2) - return; - - if (!Enum->getIdentifier()) - return; - - llvm::APSInt FirstVal; - - for (unsigned i = 0; i != NumElements; ++i) { - EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]); - if (!ECD) - return; - - Expr *InitExpr = ECD->getInitExpr(); - if (!InitExpr) - return; - InitExpr = InitExpr->IgnoreImpCasts(); - if (!isa<IntegerLiteral>(InitExpr) && !isa<CXXBoolLiteralExpr>(InitExpr)) - return; - - if (i == 0) { - FirstVal = ECD->getInitVal(); - continue; - } - - if (!llvm::APSInt::isSameValue(FirstVal, ECD->getInitVal())) - return; - } - - S.Diag(Enum->getLocation(), diag::warn_identical_enum_values) - << EnumType << FirstVal.toString(10) - << Enum->getSourceRange(); - - EnumConstantDecl *Last = cast<EnumConstantDecl>(Elements[NumElements - 1]), - *Next = cast<EnumConstantDecl>(Elements[NumElements - 2]); - - S.Diag(Last->getLocation(), diag::note_identical_enum_values) - << FixItHint::CreateReplacement(Last->getInitExpr()->getSourceRange(), - Next->getName()); -} - -// Returns true when the enum initial expression does not trigger the -// duplicate enum warning. A few common cases are exempted as follows: -// Element2 = Element1 -// Element2 = Element1 + 1 -// Element2 = Element1 - 1 -// Where Element2 and Element1 are from the same enum. -static bool ValidDuplicateEnum(EnumConstantDecl *ECD, EnumDecl *Enum) { - Expr *InitExpr = ECD->getInitExpr(); - if (!InitExpr) - return true; - InitExpr = InitExpr->IgnoreImpCasts(); - - if (BinaryOperator *BO = dyn_cast<BinaryOperator>(InitExpr)) { - if (!BO->isAdditiveOp()) - return true; - IntegerLiteral *IL = dyn_cast<IntegerLiteral>(BO->getRHS()); - if (!IL) - return true; - if (IL->getValue() != 1) - return true; - - InitExpr = BO->getLHS(); - } - - // This checks if the elements are from the same enum. - DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InitExpr); - if (!DRE) - return true; - - EnumConstantDecl *EnumConstant = dyn_cast<EnumConstantDecl>(DRE->getDecl()); - if (!EnumConstant) - return true; - - if (cast<EnumDecl>(TagDecl::castFromDeclContext(ECD->getDeclContext())) != - Enum) - return true; - - return false; -} - -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; - } -}; - -// 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, Decl **Elements, - unsigned NumElements, EnumDecl *Enum, - QualType EnumType) { - if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values, - Enum->getLocation()) == - DiagnosticsEngine::Ignored) - return; - // Avoid anonymous enums - if (!Enum->getIdentifier()) - return; - - // Only check for small enums. - if (Enum->getNumPositiveBits() > 63 || Enum->getNumNegativeBits() > 64) - return; - - typedef llvm::SmallVector<EnumConstantDecl*, 3> ECDVector; - typedef llvm::SmallVector<ECDVector*, 3> DuplicatesVector; - - typedef llvm::PointerUnion<EnumConstantDecl*, ECDVector*> DeclOrVector; - typedef llvm::DenseMap<DupKey, DeclOrVector, DenseMapInfoDupKey> - ValueToVectorMap; - - DuplicatesVector DupVector; - ValueToVectorMap EnumMap; - - // Populate the EnumMap with all values represented by enum constants without - // an initialier. - for (unsigned i = 0; i < NumElements; ++i) { - EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]); - - // Null EnumConstantDecl means a previous diagnostic has been emitted for - // this constant. Skip this enum since it may be ill-formed. - if (!ECD) { - return; - } - - if (ECD->getInitExpr()) - continue; - - DupKey Key = GetDupKey(ECD->getInitVal()); - DeclOrVector &Entry = EnumMap[Key]; - - // First time encountering this value. - if (Entry.isNull()) - Entry = ECD; - } - - // Create vectors for any values that has duplicates. - for (unsigned i = 0; i < NumElements; ++i) { - EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]); - if (!ValidDuplicateEnum(ECD, Enum)) - continue; - - DupKey Key = GetDupKey(ECD->getInitVal()); - - DeclOrVector& Entry = EnumMap[Key]; - if (Entry.isNull()) - continue; - - 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(); - Vec->push_back(D); - Vec->push_back(ECD); - - // Update entry to point to the duplicates vector. - Entry = Vec; - - // Store the vector somewhere we can consult later for quick emission of - // diagnostics. - DupVector.push_back(Vec); - continue; - } - - ECDVector *Vec = Entry.get<ECDVector*>(); - // Make sure constants are not added more than once. - if (*Vec->begin() == ECD) - continue; - - Vec->push_back(ECD); - } - - // Emit diagnostics. - for (DuplicatesVector::iterator DupVectorIter = DupVector.begin(), - DupVectorEnd = DupVector.end(); - DupVectorIter != DupVectorEnd; ++DupVectorIter) { - ECDVector *Vec = *DupVectorIter; - 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)->getName() << (*I)->getInitVal().toString(10) - << (*I)->getSourceRange(); - ++I; - - // 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)->getName() << (*I)->getInitVal().toString(10) - << (*I)->getSourceRange(); - delete Vec; - } -} - void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, Decl *EnumDeclX, Decl **Elements, unsigned NumElements, @@ -10970,9 +10743,6 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, // it needs to go into the function scope. if (InFunctionDeclarator) DeclsInPrototypeScope.push_back(Enum); - - CheckForUniqueEnumValues(*this, Elements, NumElements, Enum, EnumType); - CheckForDuplicateEnumValues(*this, Elements, NumElements, Enum, EnumType); } Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, |