[clang-tidy] add 'IgnoreMarcos' option to 'special-member-functions' check (#143550)
This commit is contained in:
parent
5ce5ed4b85
commit
e435558ff9
@ -18,6 +18,12 @@ using namespace clang::ast_matchers;
|
||||
|
||||
namespace clang::tidy::cppcoreguidelines {
|
||||
|
||||
namespace {
|
||||
AST_MATCHER(CXXRecordDecl, isInMacro) {
|
||||
return Node.getBeginLoc().isMacroID() && Node.getEndLoc().isMacroID();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
|
||||
StringRef Name, ClangTidyContext *Context)
|
||||
: ClangTidyCheck(Name, Context), AllowMissingMoveFunctions(Options.get(
|
||||
@ -26,7 +32,8 @@ SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
|
||||
AllowMissingMoveFunctionsWhenCopyIsDeleted(
|
||||
Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)),
|
||||
AllowImplicitlyDeletedCopyOrMove(
|
||||
Options.get("AllowImplicitlyDeletedCopyOrMove", false)) {}
|
||||
Options.get("AllowImplicitlyDeletedCopyOrMove", false)),
|
||||
IgnoreMacros(Options.get("IgnoreMacros", true)) {}
|
||||
|
||||
void SpecialMemberFunctionsCheck::storeOptions(
|
||||
ClangTidyOptions::OptionMap &Opts) {
|
||||
@ -36,6 +43,7 @@ void SpecialMemberFunctionsCheck::storeOptions(
|
||||
AllowMissingMoveFunctionsWhenCopyIsDeleted);
|
||||
Options.store(Opts, "AllowImplicitlyDeletedCopyOrMove",
|
||||
AllowImplicitlyDeletedCopyOrMove);
|
||||
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
|
||||
}
|
||||
|
||||
std::optional<TraversalKind>
|
||||
@ -45,11 +53,12 @@ SpecialMemberFunctionsCheck::getCheckTraversalKind() const {
|
||||
}
|
||||
|
||||
void SpecialMemberFunctionsCheck::registerMatchers(MatchFinder *Finder) {
|
||||
auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted());
|
||||
const auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted());
|
||||
const ast_matchers::internal::Matcher<CXXRecordDecl> Anything = anything();
|
||||
|
||||
Finder->addMatcher(
|
||||
cxxRecordDecl(
|
||||
unless(isImplicit()),
|
||||
unless(isImplicit()), IgnoreMacros ? unless(isInMacro()) : Anything,
|
||||
eachOf(has(cxxDestructorDecl(unless(isImplicit())).bind("dtor")),
|
||||
has(cxxConstructorDecl(isCopyConstructor(),
|
||||
IsNotImplicitOrDeleted)
|
||||
|
@ -69,6 +69,7 @@ private:
|
||||
const bool AllowMissingMoveFunctionsWhenCopyIsDeleted;
|
||||
const bool AllowImplicitlyDeletedCopyOrMove;
|
||||
ClassDefiningSpecialMembersMap ClassWithSpecialMembers;
|
||||
const bool IgnoreMacros;
|
||||
};
|
||||
|
||||
} // namespace clang::tidy::cppcoreguidelines
|
||||
|
@ -201,6 +201,10 @@ Changes in existing checks
|
||||
<clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option
|
||||
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
|
||||
|
||||
- Improved :doc:`cppcoreguidelines-special-member-functions
|
||||
<clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by
|
||||
adding the option `IgnoreMacros` to ignore classes defined in macros.
|
||||
|
||||
- Improved :doc:`google-readability-namespace-comments
|
||||
<clang-tidy/checks/google/readability-namespace-comments>` check by adding
|
||||
the option `AllowOmittingNamespaceComments` to accept if a namespace comment
|
||||
@ -210,6 +214,10 @@ Changes in existing checks
|
||||
<clang-tidy/checks/hicpp/avoid-goto>` check by adding the option
|
||||
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
|
||||
|
||||
- Improved :doc:`hicpp-special-member-functions
|
||||
<clang-tidy/checks/hicpp/special-member-functions>` check by adding the
|
||||
option `IgnoreMacros` to ignore classes defined in macros.
|
||||
|
||||
- Improved :doc:`llvm-namespace-comment
|
||||
<clang-tidy/checks/llvm/namespace-comment>` check by adding the option
|
||||
`AllowOmittingNamespaceComments` to accept if a namespace comment is omitted
|
||||
|
@ -85,3 +85,8 @@ Options
|
||||
struct A : boost::noncopyable {
|
||||
~A() { std::cout << "dtor\n"; }
|
||||
};
|
||||
|
||||
.. option:: IgnoreMacros
|
||||
|
||||
If set to `true`, the check will not give warnings for classes defined
|
||||
inside macros. Default is `true`.
|
||||
|
@ -0,0 +1,57 @@
|
||||
// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -config="{CheckOptions: {cppcoreguidelines-special-member-functions.IgnoreMacros: false}}" --
|
||||
|
||||
class DefinesDestructor {
|
||||
~DefinesDestructor();
|
||||
};
|
||||
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
|
||||
|
||||
class DefinesDefaultedDestructor {
|
||||
~DefinesDefaultedDestructor() = default;
|
||||
};
|
||||
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDefaultedDestructor' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
|
||||
|
||||
class DefinesCopyConstructor {
|
||||
DefinesCopyConstructor(const DefinesCopyConstructor &);
|
||||
};
|
||||
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
|
||||
|
||||
class DefinesNothing {
|
||||
};
|
||||
|
||||
class DefinesEverything {
|
||||
DefinesEverything(const DefinesEverything &);
|
||||
DefinesEverything &operator=(const DefinesEverything &);
|
||||
DefinesEverything(DefinesEverything &&);
|
||||
DefinesEverything &operator=(DefinesEverything &&);
|
||||
~DefinesEverything();
|
||||
};
|
||||
|
||||
#define DEFINE_DESTRUCTOR_ONLY(ClassName) \
|
||||
class ClassName { \
|
||||
~ClassName(); \
|
||||
};
|
||||
|
||||
#define DEFINE_COPY_CTOR_ONLY(ClassName) \
|
||||
class ClassName { \
|
||||
ClassName(const ClassName &); \
|
||||
};
|
||||
|
||||
#define DEFINE_CLASS_WITH_DTOR(ClassName) \
|
||||
class ClassName { \
|
||||
~ClassName(); \
|
||||
};
|
||||
|
||||
DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1)
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass1' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
|
||||
DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2)
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: class 'MacroDefinedClass2' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator
|
||||
DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3)
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass3' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
|
||||
|
||||
// Test partial macro expansion
|
||||
#define CLASS_NAME MacroNamedClass
|
||||
class CLASS_NAME {
|
||||
~MacroNamedClass();
|
||||
};
|
||||
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
|
||||
|
@ -70,3 +70,29 @@ struct TemplateClass {
|
||||
// This should not cause problems.
|
||||
TemplateClass<int> InstantiationWithInt;
|
||||
TemplateClass<double> InstantiationWithDouble;
|
||||
|
||||
#define DEFINE_DESTRUCTOR_ONLY(ClassName) \
|
||||
class ClassName { \
|
||||
~ClassName(); \
|
||||
};
|
||||
|
||||
#define DEFINE_COPY_CTOR_ONLY(ClassName) \
|
||||
class ClassName { \
|
||||
ClassName(const ClassName &); \
|
||||
};
|
||||
|
||||
#define DEFINE_CLASS_WITH_DTOR(ClassName) \
|
||||
class ClassName { \
|
||||
~ClassName(); \
|
||||
};
|
||||
|
||||
DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1)
|
||||
DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2)
|
||||
DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3)
|
||||
|
||||
// Test partial macro expansion
|
||||
#define CLASS_NAME MacroNamedClass
|
||||
class CLASS_NAME {
|
||||
~MacroNamedClass();
|
||||
};
|
||||
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
|
||||
|
Loading…
x
Reference in New Issue
Block a user