diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp index 1cb95c2b2347b..e0b9939681794 100644 --- a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp @@ -123,6 +123,13 @@ AST_MATCHER(EnumDecl, hasSequentialInitialValues) { return !AllEnumeratorsArePowersOfTwo; } +std::string getName(const EnumDecl *Decl) { + if (!Decl->getDeclName()) + return ""; + + return Decl->getQualifiedNameAsString(); +} + } // namespace EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name, @@ -160,10 +167,11 @@ void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) { void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Enum = Result.Nodes.getNodeAs("inconsistent")) { DiagnosticBuilder Diag = - diag(Enum->getBeginLoc(), - "initial values in enum %0 are not consistent, consider explicit " - "initialization of all, none or only the first enumerator") - << Enum; + diag( + Enum->getBeginLoc(), + "initial values in enum '%0' are not consistent, consider explicit " + "initialization of all, none or only the first enumerator") + << getName(Enum); for (const EnumConstantDecl *ECD : Enum->enumerators()) if (ECD->getInitExpr() == nullptr) { const SourceLocation EndLoc = Lexer::getLocForEndOfToken( @@ -183,16 +191,16 @@ void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) { if (Loc.isInvalid() || Loc.isMacroID()) return; DiagnosticBuilder Diag = diag(Loc, "zero initial value for the first " - "enumerator in %0 can be disregarded") - << Enum; + "enumerator in '%0' can be disregarded") + << getName(Enum); cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts()); return; } if (const auto *Enum = Result.Nodes.getNodeAs("sequential")) { DiagnosticBuilder Diag = diag(Enum->getBeginLoc(), - "sequential initial value in %0 can be ignored") - << Enum; + "sequential initial value in '%0' can be ignored") + << getName(Enum); for (const EnumConstantDecl *ECD : llvm::drop_begin(Enum->enumerators())) cleanInitialValue(Diag, ECD, *Result.SourceManager, getLangOpts()); return; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 95be0a89cd6c9..a4427ac222b47 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -232,7 +232,8 @@ Changes in existing checks - Improved :doc:`readability-enum-initial-value ` check by only issuing - diagnostics for the definition of an ``enum``, and by fixing a typo in the + diagnostics for the definition of an ``enum``, by not emitting a redundant + file path for anonymous enums in the diagnostic, and by fixing a typo in the diagnostic. - Improved :doc:`readability-implicit-bool-conversion diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c index b9a34d0683d7f..54108585f030f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/enum-initial-value.c @@ -53,6 +53,17 @@ enum EMacro2 { // CHECK-FIXES: EMacro2_c = 3, }; + +enum { + // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum '' are not consistent + // CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum '' are not consistent + EAnonymous_a = 1, + EAnonymous_b, + // CHECK-FIXES: EAnonymous_b = 2, + EAnonymous_c = 3, +}; + + enum EnumZeroFirstInitialValue { EnumZeroFirstInitialValue_0 = 0, // CHECK-MESSAGES-ENABLE: :[[@LINE-1]]:3: warning: zero initial value for the first enumerator in 'EnumZeroFirstInitialValue' can be disregarded @@ -114,4 +125,3 @@ enum WithFwdDeclSequential : int { EFS2 = 4, // CHECK-FIXES-ENABLE: EFS2 , }; -