[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang-tools-extra / unittests / clang-tidy / DeclRefExprUtilsTest.cpp
bloba653b11faad282829e4f2a0ea27ec0c659d2791f
1 #include "../clang-tidy/utils/DeclRefExprUtils.h"
2 #include "ClangTidyDiagnosticConsumer.h"
3 #include "ClangTidyTest.h"
4 #include "clang/ASTMatchers/ASTMatchFinder.h"
5 #include "clang/ASTMatchers/ASTMatchers.h"
6 #include "clang/Tooling/Tooling.h"
7 #include "gtest/gtest.h"
9 namespace clang {
10 namespace tidy {
12 namespace {
13 using namespace clang::ast_matchers;
15 class ConstReferenceDeclRefExprsTransform : public ClangTidyCheck {
16 public:
17 ConstReferenceDeclRefExprsTransform(StringRef CheckName,
18 ClangTidyContext *Context)
19 : ClangTidyCheck(CheckName, Context) {}
21 void registerMatchers(MatchFinder *Finder) override {
22 Finder->addMatcher(varDecl(hasName("target")).bind("var"), this);
25 void check(const MatchFinder::MatchResult &Result) override {
26 const auto *D = Result.Nodes.getNodeAs<VarDecl>("var");
27 using utils::decl_ref_expr::constReferenceDeclRefExprs;
28 const auto const_decrefexprs = constReferenceDeclRefExprs(
29 *D, *cast<FunctionDecl>(D->getDeclContext())->getBody(),
30 *Result.Context);
32 for (const DeclRefExpr *const Expr : const_decrefexprs) {
33 assert(Expr);
34 diag(Expr->getBeginLoc(), "const usage")
35 << FixItHint::CreateInsertion(Expr->getBeginLoc(), "/*const*/");
39 } // namespace
41 namespace test {
43 void RunTest(StringRef Snippet) {
45 StringRef CommonCode = R"(
46 struct ConstTag{};
47 struct NonConstTag{};
49 struct S {
50 void constMethod() const;
51 void nonConstMethod();
53 void operator()(ConstTag) const;
54 void operator()(NonConstTag);
56 void operator[](int);
57 void operator[](int) const;
59 bool operator==(const S&) const;
61 int int_member;
62 int* ptr_member;
66 struct Derived : public S {
70 void useVal(S);
71 void useRef(S&);
72 void usePtr(S*);
73 void usePtrPtr(S**);
74 void usePtrConstPtr(S* const*);
75 void useConstRef(const S&);
76 void useConstPtr(const S*);
77 void useConstPtrRef(const S*&);
78 void useConstPtrPtr(const S**);
79 void useConstPtrConstRef(const S* const&);
80 void useConstPtrConstPtr(const S* const*);
82 void useInt(int);
83 void useIntRef(int&);
84 void useIntConstRef(const int&);
85 void useIntPtr(int*);
86 void useIntConstPtr(const int*);
88 )";
90 std::string Code = (CommonCode + Snippet).str();
92 llvm::SmallVector<StringRef, 1> Parts;
93 StringRef(Code).split(Parts, "/*const*/");
95 EXPECT_EQ(Code, runCheckOnCode<ConstReferenceDeclRefExprsTransform>(
96 join(Parts, "")));
99 TEST(ConstReferenceDeclRefExprsTest, ConstValueVar) {
100 RunTest(R"(
101 void f(const S target) {
102 useVal(/*const*/target);
103 useConstRef(/*const*/target);
104 useConstPtr(&target);
105 useConstPtrConstRef(&target);
106 /*const*/target.constMethod();
107 /*const*/target(ConstTag{});
108 /*const*/target[42];
109 useConstRef((/*const*/target));
110 (/*const*/target).constMethod();
111 (void)(/*const*/target == /*const*/target);
112 (void)target;
113 (void)&target;
114 (void)*&target;
115 S copy1 = /*const*/target;
116 S copy2(/*const*/target);
117 useInt(/*const*/target.int_member);
118 useIntConstRef(/*const*/target.int_member);
119 useIntPtr(target.ptr_member);
120 useIntConstPtr(&target.int_member);
122 )");
125 TEST(ConstReferenceDeclRefExprsTest, ConstRefVar) {
126 RunTest(R"(
127 void f(const S& target) {
128 useVal(/*const*/target);
129 useConstRef(/*const*/target);
130 useConstPtr(&target);
131 useConstPtrConstRef(&target);
132 /*const*/target.constMethod();
133 /*const*/target(ConstTag{});
134 /*const*/target[42];
135 useConstRef((/*const*/target));
136 (/*const*/target).constMethod();
137 (void)(/*const*/target == /*const*/target);
138 (void)target;
139 (void)&target;
140 (void)*&target;
141 S copy1 = /*const*/target;
142 S copy2(/*const*/target);
143 useInt(/*const*/target.int_member);
144 useIntConstRef(/*const*/target.int_member);
145 useIntPtr(target.ptr_member);
146 useIntConstPtr(&target.int_member);
148 )");
151 TEST(ConstReferenceDeclRefExprsTest, ValueVar) {
152 RunTest(R"(
153 void f(S target, const S& other) {
154 useConstRef(/*const*/target);
155 useVal(/*const*/target);
156 useConstPtr(&target);
157 useConstPtrConstRef(&target);
158 /*const*/target.constMethod();
159 target.nonConstMethod();
160 /*const*/target(ConstTag{});
161 target[42];
162 /*const*/target(ConstTag{});
163 target(NonConstTag{});
164 useRef(target);
165 usePtr(&target);
166 useConstRef((/*const*/target));
167 (/*const*/target).constMethod();
168 (void)(/*const*/target == /*const*/target);
169 (void)(/*const*/target == other);
170 (void)target;
171 (void)&target;
172 (void)*&target;
173 S copy1 = /*const*/target;
174 S copy2(/*const*/target);
175 useInt(/*const*/target.int_member);
176 useIntConstRef(/*const*/target.int_member);
177 useIntPtr(target.ptr_member);
178 useIntConstPtr(&target.int_member);
180 )");
183 TEST(ConstReferenceDeclRefExprsTest, RefVar) {
184 RunTest(R"(
185 void f(S& target) {
186 useVal(/*const*/target);
187 useConstRef(/*const*/target);
188 useConstPtr(&target);
189 useConstPtrConstRef(&target);
190 /*const*/target.constMethod();
191 target.nonConstMethod();
192 /*const*/target(ConstTag{});
193 target[42];
194 useConstRef((/*const*/target));
195 (/*const*/target).constMethod();
196 (void)(/*const*/target == /*const*/target);
197 (void)target;
198 (void)&target;
199 (void)*&target;
200 S copy1 = /*const*/target;
201 S copy2(/*const*/target);
202 useInt(/*const*/target.int_member);
203 useIntConstRef(/*const*/target.int_member);
204 useIntPtr(target.ptr_member);
205 useIntConstPtr(&target.int_member);
207 )");
210 TEST(ConstReferenceDeclRefExprsTest, PtrVar) {
211 RunTest(R"(
212 void f(S* target) {
213 useVal(*target);
214 useConstRef(*target);
215 useConstPtr(target);
216 useConstPtrConstRef(/*const*/target);
217 /*const*/target->constMethod();
218 target->nonConstMethod();
219 (*target)(ConstTag{});
220 (*target)[42];
221 target->operator[](42);
222 useConstRef((*target));
223 (/*const*/target)->constMethod();
224 (void)(*target == *target);
225 (void)*target;
226 (void)target;
227 S copy1 = *target;
228 S copy2(*target);
229 useInt(target->int_member);
230 useIntConstRef(target->int_member);
231 useIntPtr(target->ptr_member);
232 useIntConstPtr(&target->int_member);
234 )");
237 TEST(ConstReferenceDeclRefExprsTest, ConstPtrVar) {
238 RunTest(R"(
239 void f(const S* target) {
240 useVal(*target);
241 useConstRef(*target);
242 useConstPtr(target);
243 useConstPtrRef(target);
244 useConstPtrPtr(&target);
245 useConstPtrConstPtr(&target);
246 useConstPtrConstRef(/*const*/target);
247 /*const*/target->constMethod();
248 (*target)(ConstTag{});
249 (*target)[42];
250 /*const*/target->operator[](42);
251 (void)(*target == *target);
252 (void)target;
253 (void)*target;
254 if(target) {}
255 S copy1 = *target;
256 S copy2(*target);
257 useInt(target->int_member);
258 useIntConstRef(target->int_member);
259 useIntPtr(target->ptr_member);
260 useIntConstPtr(&target->int_member);
262 )");
265 TEST(ConstReferenceDeclRefExprsTest, ConstPtrPtrVar) {
266 RunTest(R"(
267 void f(const S** target) {
268 useVal(**target);
269 useConstRef(**target);
270 useConstPtr(*target);
271 useConstPtrRef(*target);
272 useConstPtrPtr(target);
273 useConstPtrConstPtr(target);
274 useConstPtrConstRef(*target);
275 (void)target;
276 (void)*target;
277 (void)**target;
278 if(target) {}
279 if(*target) {}
280 S copy1 = **target;
281 S copy2(**target);
282 useInt((*target)->int_member);
283 useIntConstRef((*target)->int_member);
284 useIntPtr((*target)->ptr_member);
285 useIntConstPtr(&(*target)->int_member);
287 )");
290 TEST(ConstReferenceDeclRefExprsTest, ConstPtrConstPtrVar) {
291 RunTest(R"(
292 void f(const S* const* target) {
293 useVal(**target);
294 useConstRef(**target);
295 useConstPtr(*target);
296 useConstPtrConstPtr(target);
297 useConstPtrConstRef(*target);
298 (void)target;
299 (void)target;
300 (void)**target;
301 if(target) {}
302 if(*target) {}
303 S copy1 = **target;
304 S copy2(**target);
305 useInt((*target)->int_member);
306 useIntConstRef((*target)->int_member);
307 useIntPtr((*target)->ptr_member);
308 useIntConstPtr(&(*target)->int_member);
310 )");
313 } // namespace test
314 } // namespace tidy
315 } // namespace clang