Skip to content

Commit 723c913

Browse files
committed
Add option to ignore unscoped enums in classes
1 parent 129b95d commit 723c913

File tree

4 files changed

+52
-35
lines changed

4 files changed

+52
-35
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,30 @@ using namespace clang::ast_matchers;
1313

1414
namespace clang::tidy::cppcoreguidelines {
1515

16+
UseEnumClassCheck::UseEnumClassCheck(StringRef Name, ClangTidyContext *Context)
17+
: ClangTidyCheck(Name, Context),
18+
IgnoreUnscopedEnumsInClasses(
19+
Options.get("IgnoreUnscopedEnumsInClasses", false)) {}
20+
21+
void UseEnumClassCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
22+
Options.store(Opts, "IgnoreUnscopedEnumsInClasses",
23+
IgnoreUnscopedEnumsInClasses);
24+
}
25+
1626
void UseEnumClassCheck::registerMatchers(MatchFinder *Finder) {
17-
Finder->addMatcher(
18-
enumDecl(unless(isScoped()), unless(hasParent(recordDecl())))
19-
.bind("unscoped_enum"),
20-
this);
27+
auto EnumDecl =
28+
IgnoreUnscopedEnumsInClasses
29+
? enumDecl(unless(isScoped()), unless(hasParent(recordDecl())))
30+
: enumDecl(unless(isScoped()));
31+
Finder->addMatcher(EnumDecl.bind("unscoped_enum"), this);
2132
}
2233

2334
void UseEnumClassCheck::check(const MatchFinder::MatchResult &Result) {
2435
const auto *UnscopedEnum = Result.Nodes.getNodeAs<EnumDecl>("unscoped_enum");
2536

2637
diag(UnscopedEnum->getLocation(),
27-
"enum %0 is unscoped, use enum class instead")
38+
"enum %0 is unscoped, use 'enum class' instead")
2839
<< UnscopedEnum;
29-
diag(UnscopedEnum->getLocation(), "insert 'class'", DiagnosticIDs::Note)
30-
<< FixItHint::CreateInsertion(UnscopedEnum->getLocation(), "class ");
3140
}
3241

3342
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/clang-tidy/cppcoreguidelines/UseEnumClassCheck.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@ namespace clang::tidy::cppcoreguidelines {
2020
/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/use-enum-class.html
2121
class UseEnumClassCheck : public ClangTidyCheck {
2222
public:
23-
UseEnumClassCheck(StringRef Name, ClangTidyContext *Context)
24-
: ClangTidyCheck(Name, Context) {}
23+
UseEnumClassCheck(StringRef Name, ClangTidyContext *Context);
24+
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
2525
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
2626
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
2727
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
28-
return LangOpts.CPlusPlus;
28+
return LangOpts.CPlusPlus11;
2929
}
3030
std::optional<TraversalKind> getCheckTraversalKind() const override {
3131
return TraversalKind::TK_IgnoreUnlessSpelledInSource;
3232
}
33+
34+
private:
35+
const bool IgnoreUnscopedEnumsInClasses;
3336
};
3437

3538
} // namespace clang::tidy::cppcoreguidelines
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-use-enum-class %t -- -config="{CheckOptions: {cppcoreguidelines-use-enum-class.IgnoreUnscopedEnumsInClasses: true}}" --
2+
3+
enum E {};
4+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
5+
6+
enum class EC {};
7+
8+
struct S {
9+
enum E {};
10+
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
11+
// Ignore unscoped enums in recordDecl
12+
enum class EC {};
13+
};
Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,50 @@
1-
// RUN: %check_clang_tidy -std=c++17-or-later %s cppcoreguidelines-use-enum-class %t
1+
// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-use-enum-class %t
22

33
enum E {};
4-
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
4+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
55

66
enum class EC {};
77

88
struct S {
9-
enum E {};
10-
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: enum 'E' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
11-
// Ignore unscoped enums in recordDecl
12-
enum class EC {};
9+
enum E {};
10+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
11+
enum class EC {};
1312
};
1413

1514
class C {
16-
enum E {};
17-
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: enum 'E' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
18-
// Ignore unscoped enums in recordDecl
19-
enum class EC {};
15+
enum E {};
16+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
17+
enum class EC {};
2018
};
2119

2220
template<class T>
2321
class TC {
24-
enum E {};
25-
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: enum 'E' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
26-
// Ignore unscoped enums in recordDecl
27-
enum class EC {};
22+
enum E {};
23+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
24+
enum class EC {};
2825
};
2926

3027
union U {
31-
enum E {};
32-
// CHECK-MESSAGES-NOT: :[[@LINE-1]]:12: warning: enum 'E' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
33-
// Ignore unscoped enums in recordDecl
34-
enum class EC {};
28+
enum E {};
29+
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
30+
enum class EC {};
3531
};
3632

3733
namespace {
3834
enum E {};
39-
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
35+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
4036
enum class EC {};
4137
} // namespace
4238

4339
namespace N {
4440
enum E {};
45-
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
41+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'E' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
4642
enum class EC {};
4743
} // namespace N
4844

4945
template<enum ::EC>
5046
static void foo();
5147

52-
using enum S::E;
53-
using enum S::EC;
54-
5548
enum ForwardE : int;
56-
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'ForwardE' is unscoped, use enum class instead [cppcoreguidelines-use-enum-class]
57-
49+
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: enum 'ForwardE' is unscoped, use 'enum class' instead [cppcoreguidelines-use-enum-class]
5850
enum class ForwardEC : int;

0 commit comments

Comments
 (0)