[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 clang::tidy::cppcoreguidelines {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
AST_MATCHER(CXXRecordDecl, isInMacro) {
|
||||||
|
return Node.getBeginLoc().isMacroID() && Node.getEndLoc().isMacroID();
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
|
SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
|
||||||
StringRef Name, ClangTidyContext *Context)
|
StringRef Name, ClangTidyContext *Context)
|
||||||
: ClangTidyCheck(Name, Context), AllowMissingMoveFunctions(Options.get(
|
: ClangTidyCheck(Name, Context), AllowMissingMoveFunctions(Options.get(
|
||||||
@ -26,7 +32,8 @@ SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
|
|||||||
AllowMissingMoveFunctionsWhenCopyIsDeleted(
|
AllowMissingMoveFunctionsWhenCopyIsDeleted(
|
||||||
Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)),
|
Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)),
|
||||||
AllowImplicitlyDeletedCopyOrMove(
|
AllowImplicitlyDeletedCopyOrMove(
|
||||||
Options.get("AllowImplicitlyDeletedCopyOrMove", false)) {}
|
Options.get("AllowImplicitlyDeletedCopyOrMove", false)),
|
||||||
|
IgnoreMacros(Options.get("IgnoreMacros", true)) {}
|
||||||
|
|
||||||
void SpecialMemberFunctionsCheck::storeOptions(
|
void SpecialMemberFunctionsCheck::storeOptions(
|
||||||
ClangTidyOptions::OptionMap &Opts) {
|
ClangTidyOptions::OptionMap &Opts) {
|
||||||
@ -36,6 +43,7 @@ void SpecialMemberFunctionsCheck::storeOptions(
|
|||||||
AllowMissingMoveFunctionsWhenCopyIsDeleted);
|
AllowMissingMoveFunctionsWhenCopyIsDeleted);
|
||||||
Options.store(Opts, "AllowImplicitlyDeletedCopyOrMove",
|
Options.store(Opts, "AllowImplicitlyDeletedCopyOrMove",
|
||||||
AllowImplicitlyDeletedCopyOrMove);
|
AllowImplicitlyDeletedCopyOrMove);
|
||||||
|
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<TraversalKind>
|
std::optional<TraversalKind>
|
||||||
@ -45,11 +53,12 @@ SpecialMemberFunctionsCheck::getCheckTraversalKind() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpecialMemberFunctionsCheck::registerMatchers(MatchFinder *Finder) {
|
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(
|
Finder->addMatcher(
|
||||||
cxxRecordDecl(
|
cxxRecordDecl(
|
||||||
unless(isImplicit()),
|
unless(isImplicit()), IgnoreMacros ? unless(isInMacro()) : Anything,
|
||||||
eachOf(has(cxxDestructorDecl(unless(isImplicit())).bind("dtor")),
|
eachOf(has(cxxDestructorDecl(unless(isImplicit())).bind("dtor")),
|
||||||
has(cxxConstructorDecl(isCopyConstructor(),
|
has(cxxConstructorDecl(isCopyConstructor(),
|
||||||
IsNotImplicitOrDeleted)
|
IsNotImplicitOrDeleted)
|
||||||
|
@ -69,6 +69,7 @@ private:
|
|||||||
const bool AllowMissingMoveFunctionsWhenCopyIsDeleted;
|
const bool AllowMissingMoveFunctionsWhenCopyIsDeleted;
|
||||||
const bool AllowImplicitlyDeletedCopyOrMove;
|
const bool AllowImplicitlyDeletedCopyOrMove;
|
||||||
ClassDefiningSpecialMembersMap ClassWithSpecialMembers;
|
ClassDefiningSpecialMembersMap ClassWithSpecialMembers;
|
||||||
|
const bool IgnoreMacros;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace clang::tidy::cppcoreguidelines
|
} // namespace clang::tidy::cppcoreguidelines
|
||||||
|
@ -201,6 +201,10 @@ Changes in existing checks
|
|||||||
<clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option
|
<clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option
|
||||||
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
|
`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
|
- Improved :doc:`google-readability-namespace-comments
|
||||||
<clang-tidy/checks/google/readability-namespace-comments>` check by adding
|
<clang-tidy/checks/google/readability-namespace-comments>` check by adding
|
||||||
the option `AllowOmittingNamespaceComments` to accept if a namespace comment
|
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
|
<clang-tidy/checks/hicpp/avoid-goto>` check by adding the option
|
||||||
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
|
`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
|
- Improved :doc:`llvm-namespace-comment
|
||||||
<clang-tidy/checks/llvm/namespace-comment>` check by adding the option
|
<clang-tidy/checks/llvm/namespace-comment>` check by adding the option
|
||||||
`AllowOmittingNamespaceComments` to accept if a namespace comment is omitted
|
`AllowOmittingNamespaceComments` to accept if a namespace comment is omitted
|
||||||
|
@ -85,3 +85,8 @@ Options
|
|||||||
struct A : boost::noncopyable {
|
struct A : boost::noncopyable {
|
||||||
~A() { std::cout << "dtor\n"; }
|
~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.
|
// This should not cause problems.
|
||||||
TemplateClass<int> InstantiationWithInt;
|
TemplateClass<int> InstantiationWithInt;
|
||||||
TemplateClass<double> InstantiationWithDouble;
|
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