mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 01:29:52 +00:00
[clang-tidy] Add unit tests for DeclRefExprUtils
.
In preparation for D114539.
This commit is contained in:
parent
6ee69c0dea
commit
3b72448084
@ -20,6 +20,7 @@ add_extra_unittest(ClangTidyTests
|
||||
AddConstTest.cpp
|
||||
ClangTidyDiagnosticConsumerTest.cpp
|
||||
ClangTidyOptionsTest.cpp
|
||||
DeclRefExprUtilsTest.cpp
|
||||
IncludeInserterTest.cpp
|
||||
GlobListTest.cpp
|
||||
GoogleModuleTest.cpp
|
||||
|
315
clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp
Normal file
315
clang-tools-extra/unittests/clang-tidy/DeclRefExprUtilsTest.cpp
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user