[clang-tools-extra] 3b72448 - [clang-tidy] Add unit tests for `DeclRefExprUtils`.
Clement Courbet via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 24 07:48:19 PST 2021
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
More information about the cfe-commits
mailing list