Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ AST_MATCHER(EnumDecl, hasSequentialInitialValues) {
return !AllEnumeratorsArePowersOfTwo;
}

std::string getName(const EnumDecl *Decl) {
if (!Decl->getDeclName())
return "<unnamed>";

return Decl->getQualifiedNameAsString();
}

} // namespace

EnumInitialValueCheck::EnumInitialValueCheck(StringRef Name,
Expand Down Expand Up @@ -158,12 +165,16 @@ void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) {
}

void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) {
PrintingPolicy PP = Result.Context->getPrintingPolicy();
PP.AnonymousTagLocations = false;

if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("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(
Expand All @@ -183,16 +194,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<EnumDecl>("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;
Expand Down
3 changes: 2 additions & 1 deletion clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ Changes in existing checks

- Improved :doc:`readability-enum-initial-value
<clang-tidy/checks/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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ enum EMacro2 {
// CHECK-FIXES: EMacro2_c = 3,
};


enum {
// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: initial values in enum '<unnamed>' are not consistent
// CHECK-MESSAGES-ENABLE: :[[@LINE-2]]:1: warning: initial values in enum '<unnamed>' 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
Expand Down Expand Up @@ -114,4 +125,3 @@ enum WithFwdDeclSequential : int {
EFS2 = 4,
// CHECK-FIXES-ENABLE: EFS2 ,
};

Loading