Author: Clement Courbet Date: 2021-11-24T16:47:55+01:00 New Revision: 3b72448084052785b79566fa5bd374feb8ae3907
URL: https://github.com/llvm/llvm-project/commit/3b72448084052785b79566fa5bd374feb8ae3907 DIFF: https://github.com/llvm/llvm-project/commit/3b72448084052785b79566fa5bd374feb8ae3907.diff LOG: [clang-tidy] Add unit tests for `DeclRefExprUtils`. In preparation for D114539. Added: clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp Modified: clang-tools-extra/unittests/clang-tidy/CMakeLists.txt Removed: ################################################################################ diff --git a/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt b/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt index 4a8d50f01473..6c9fa61cf92e 100644 --- a/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt +++ b/clang-tools-extra/unittests/clang-tidy/CMakeLists.txt @@ -20,6 +20,7 @@ add_extra_unittest(ClangTidyTests AddConstTest.cpp ClangTidyDiagnosticConsumerTest.cpp ClangTidyOptionsTest.cpp + DeclRefExprUtilsTest.cpp IncludeInserterTest.cpp GlobListTest.cpp GoogleModuleTest.cpp diff --git a/clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp b/clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp new file mode 100644 index 000000000000..d47add410b2c --- /dev/null +++ b/clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp @@ -0,0 +1,315 @@ +#include "../clang-tidy/utils/DeclRefExprUtils.h" +#include "ClangTidyDiagnosticConsumer.h" +#include "ClangTidyTest.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/Tooling.h" +#include "gtest/gtest.h" + +namespace clang { +namespace tidy { + +namespace { +using namespace clang::ast_matchers; + +class ConstReferenceDeclRefExprsTransform : public ClangTidyCheck { +public: + ConstReferenceDeclRefExprsTransform(StringRef CheckName, + ClangTidyContext *Context) + : ClangTidyCheck(CheckName, Context) {} + + void registerMatchers(MatchFinder *Finder) override { + Finder->addMatcher(varDecl(hasName("target")).bind("var"), this); + } + + void check(const MatchFinder::MatchResult &Result) override { + const auto *D = Result.Nodes.getNodeAs<VarDecl>("var"); + using utils::decl_ref_expr::constReferenceDeclRefExprs; + const auto const_decrefexprs = constReferenceDeclRefExprs( + *D, *cast<FunctionDecl>(D->getDeclContext())->getBody(), + *Result.Context); + + for (const DeclRefExpr *const Expr : const_decrefexprs) { + assert(Expr); + diag(Expr->getBeginLoc(), "const usage") + << FixItHint::CreateInsertion(Expr->getBeginLoc(), "/*const*/"); + } + } +}; +} // namespace + +namespace test { + +void RunTest(StringRef Snippet) { + + StringRef CommonCode = R"( + struct ConstTag{}; + struct NonConstTag{}; + + struct S { + void constMethod() const; + void nonConstMethod(); + + void operator()(ConstTag) const; + void operator()(NonConstTag); + + void operator[](int); + void operator[](int) const; + + bool operator==(const S&) const; + + int int_member; + int* ptr_member; + + }; + + struct Derived : public S { + + }; + + void useVal(S); + void useRef(S&); + void usePtr(S*); + void usePtrPtr(S**); + void usePtrConstPtr(S* const*); + void useConstRef(const S&); + void useConstPtr(const S*); + void useConstPtrRef(const S*&); + void useConstPtrPtr(const S**); + void useConstPtrConstRef(const S* const&); + void useConstPtrConstPtr(const S* const*); + + void useInt(int); + void useIntRef(int&); + void useIntConstRef(const int&); + void useIntPtr(int*); + void useIntConstPtr(const int*); + + )"; + + std::string Code = (CommonCode + Snippet).str(); + + llvm::SmallVector<StringRef, 1> Parts; + StringRef(Code).split(Parts, "/*const*/"); + + EXPECT_EQ(Code, runCheckOnCode<ConstReferenceDeclRefExprsTransform>( + join(Parts, ""))); +} + +TEST(ConstReferenceDeclRefExprsTest, ConstValueVar) { + RunTest(R"( + void f(const S target) { + useVal(/*const*/target); + useConstRef(/*const*/target); + useConstPtr(&target); + useConstPtrConstRef(&target); + /*const*/target.constMethod(); + /*const*/target(ConstTag{}); + /*const*/target[42]; + useConstRef((/*const*/target)); + (/*const*/target).constMethod(); + (void)(/*const*/target == /*const*/target); + (void)target; + (void)⌖ + (void)*⌖ + S copy1 = /*const*/target; + S copy2(/*const*/target); + useInt(target.int_member); + useIntConstRef(target.int_member); + useIntPtr(target.ptr_member); + useIntConstPtr(&target.int_member); + } +)"); +} + +TEST(ConstReferenceDeclRefExprsTest, ConstRefVar) { + RunTest(R"( + void f(const S& target) { + useVal(/*const*/target); + useConstRef(/*const*/target); + useConstPtr(&target); + useConstPtrConstRef(&target); + /*const*/target.constMethod(); + /*const*/target(ConstTag{}); + /*const*/target[42]; + useConstRef((/*const*/target)); + (/*const*/target).constMethod(); + (void)(/*const*/target == /*const*/target); + (void)target; + (void)⌖ + (void)*⌖ + S copy1 = /*const*/target; + S copy2(/*const*/target); + useInt(target.int_member); + useIntConstRef(target.int_member); + useIntPtr(target.ptr_member); + useIntConstPtr(&target.int_member); + } +)"); +} + +TEST(ConstReferenceDeclRefExprsTest, ValueVar) { + RunTest(R"( + void f(S target, const S& other) { + useConstRef(/*const*/target); + useVal(/*const*/target); + useConstPtr(&target); + useConstPtrConstRef(&target); + /*const*/target.constMethod(); + target.nonConstMethod(); + /*const*/target(ConstTag{}); + target[42]; + /*const*/target(ConstTag{}); + target(NonConstTag{}); + useRef(target); + usePtr(&target); + useConstRef((/*const*/target)); + (/*const*/target).constMethod(); + (void)(/*const*/target == /*const*/target); + (void)(/*const*/target == other); + (void)target; + (void)⌖ + (void)*⌖ + S copy1 = /*const*/target; + S copy2(/*const*/target); + useInt(target.int_member); + useIntConstRef(target.int_member); + useIntPtr(target.ptr_member); + useIntConstPtr(&target.int_member); + } +)"); +} + +TEST(ConstReferenceDeclRefExprsTest, RefVar) { + RunTest(R"( + void f(S& target) { + useVal(/*const*/target); + useConstRef(/*const*/target); + useConstPtr(&target); + useConstPtrConstRef(&target); + /*const*/target.constMethod(); + target.nonConstMethod(); + /*const*/target(ConstTag{}); + target[42]; + useConstRef((/*const*/target)); + (/*const*/target).constMethod(); + (void)(/*const*/target == /*const*/target); + (void)target; + (void)⌖ + (void)*⌖ + S copy1 = /*const*/target; + S copy2(/*const*/target); + useInt(target.int_member); + useIntConstRef(target.int_member); + useIntPtr(target.ptr_member); + useIntConstPtr(&target.int_member); + } +)"); +} + +TEST(ConstReferenceDeclRefExprsTest, PtrVar) { + RunTest(R"( + void f(S* target) { + useVal(*target); + useConstRef(*target); + useConstPtr(target); + useConstPtrConstRef(/*const*/target); + /*const*/target->constMethod(); + target->nonConstMethod(); + (*target)(ConstTag{}); + (*target)[42]; + target->operator[](42); + useConstRef((*target)); + (/*const*/target)->constMethod(); + (void)(*target == *target); + (void)*target; + (void)target; + S copy1 = *target; + S copy2(*target); + useInt(target->int_member); + useIntConstRef(target->int_member); + useIntPtr(target->ptr_member); + useIntConstPtr(&target->int_member); + } +)"); +} + +TEST(ConstReferenceDeclRefExprsTest, ConstPtrVar) { + RunTest(R"( + void f(const S* target) { + useVal(*target); + useConstRef(*target); + useConstPtr(target); + useConstPtrRef(target); + useConstPtrPtr(&target); + useConstPtrConstPtr(&target); + useConstPtrConstRef(/*const*/target); + /*const*/target->constMethod(); + (*target)(ConstTag{}); + (*target)[42]; + /*const*/target->operator[](42); + (void)(*target == *target); + (void)target; + (void)*target; + if(target) {} + S copy1 = *target; + S copy2(*target); + useInt(target->int_member); + useIntConstRef(target->int_member); + useIntPtr(target->ptr_member); + useIntConstPtr(&target->int_member); + } +)"); +} + +TEST(ConstReferenceDeclRefExprsTest, ConstPtrPtrVar) { + RunTest(R"( + void f(const S** target) { + useVal(**target); + useConstRef(**target); + useConstPtr(*target); + useConstPtrRef(*target); + useConstPtrPtr(target); + useConstPtrConstPtr(target); + useConstPtrConstRef(*target); + (void)target; + (void)*target; + (void)**target; + if(target) {} + if(*target) {} + S copy1 = **target; + S copy2(**target); + useInt((*target)->int_member); + useIntConstRef((*target)->int_member); + useIntPtr((*target)->ptr_member); + useIntConstPtr(&(*target)->int_member); + } +)"); +} + +TEST(ConstReferenceDeclRefExprsTest, ConstPtrConstPtrVar) { + RunTest(R"( + void f(const S* const* target) { + useVal(**target); + useConstRef(**target); + useConstPtr(*target); + useConstPtrConstPtr(target); + useConstPtrConstRef(*target); + (void)target; + (void)target; + (void)**target; + if(target) {} + if(*target) {} + S copy1 = **target; + S copy2(**target); + useInt((*target)->int_member); + useIntConstRef((*target)->int_member); + useIntPtr((*target)->ptr_member); + useIntConstPtr(&(*target)->int_member); + } +)"); +} + +} // namespace test +} // namespace tidy +} // namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits