blob: 83556572f7243e64fb900c1bf8ce1c12df584b81 [file] [log] [blame]
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +00001//===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Tests for the correct import of AST nodes from one AST context to another.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/ASTImporter.h"
16#include "MatchVerifier.h"
17#include "clang/ASTMatchers/ASTMatchFinder.h"
18#include "clang/ASTMatchers/ASTMatchers.h"
19#include "clang/Tooling/Tooling.h"
20#include "gtest/gtest.h"
21
22namespace clang {
23namespace ast_matchers {
24
Aleksei Sidorine45ab562017-12-21 17:41:06 +000025typedef std::vector<std::string> ArgVector;
26typedef std::vector<ArgVector> RunOptions;
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000027
Aleksei Sidorine45ab562017-12-21 17:41:06 +000028static bool isCXX(Language Lang) {
29 return Lang == Lang_CXX || Lang == Lang_CXX11;
30}
31
32static RunOptions getRunOptionsForLanguage(Language Lang) {
33 ArgVector BasicArgs;
34 // Test with basic arguments.
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000035 switch (Lang) {
36 case Lang_C:
Aleksei Sidorine45ab562017-12-21 17:41:06 +000037 BasicArgs = {"-x", "c", "-std=c99"};
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000038 break;
39 case Lang_C89:
Aleksei Sidorine45ab562017-12-21 17:41:06 +000040 BasicArgs = {"-x", "c", "-std=c89"};
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000041 break;
42 case Lang_CXX:
Aleksei Sidorine45ab562017-12-21 17:41:06 +000043 BasicArgs = {"-std=c++98"};
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000044 break;
45 case Lang_CXX11:
Aleksei Sidorine45ab562017-12-21 17:41:06 +000046 BasicArgs = {"-std=c++11"};
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000047 break;
48 case Lang_OpenCL:
49 case Lang_OBJCXX:
Aleksei Sidorine45ab562017-12-21 17:41:06 +000050 llvm_unreachable("Not implemented yet!");
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000051 }
Aleksei Sidorine45ab562017-12-21 17:41:06 +000052
53 // For C++, test with "-fdelayed-template-parsing" enabled to handle MSVC
54 // default behaviour.
55 if (isCXX(Lang)) {
56 ArgVector ArgsForDelayedTemplateParse = BasicArgs;
57 ArgsForDelayedTemplateParse.emplace_back("-fdelayed-template-parsing");
58 return {BasicArgs, ArgsForDelayedTemplateParse};
59 }
60
61 return {BasicArgs};
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000062}
63
64template<typename NodeType, typename MatcherType>
65testing::AssertionResult
Aleksei Sidorine45ab562017-12-21 17:41:06 +000066testImport(const std::string &FromCode, const ArgVector &FromArgs,
67 const std::string &ToCode, const ArgVector &ToArgs,
68 MatchVerifier<NodeType> &Verifier, const MatcherType &AMatcher) {
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000069 const char *const InputFileName = "input.cc";
70 const char *const OutputFileName = "output.cc";
71
72 std::unique_ptr<ASTUnit>
73 FromAST = tooling::buildASTFromCodeWithArgs(
74 FromCode, FromArgs, InputFileName),
75 ToAST = tooling::buildASTFromCodeWithArgs(ToCode, ToArgs, OutputFileName);
76
77 ASTContext &FromCtx = FromAST->getASTContext(),
78 &ToCtx = ToAST->getASTContext();
79
80 // Add input.cc to virtual file system so importer can 'find' it
81 // while importing SourceLocations.
82 vfs::OverlayFileSystem *OFS = static_cast<vfs::OverlayFileSystem *>(
83 ToCtx.getSourceManager().getFileManager().getVirtualFileSystem().get());
84 vfs::InMemoryFileSystem *MFS = static_cast<vfs::InMemoryFileSystem *>(
85 OFS->overlays_begin()->get());
Malcolm Parsonsf76f6502016-11-02 10:39:27 +000086 MFS->addFile(InputFileName, 0, llvm::MemoryBuffer::getMemBuffer(FromCode));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +000087
88 ASTImporter Importer(ToCtx, ToAST->getFileManager(),
89 FromCtx, FromAST->getFileManager(), false);
90
91 IdentifierInfo *ImportedII = &FromCtx.Idents.get("declToImport");
92 assert(ImportedII && "Declaration with 'declToImport' name"
93 "should be specified in test!");
94 DeclarationName ImportDeclName(ImportedII);
95 SmallVector<NamedDecl *, 4> FoundDecls;
96 FromCtx.getTranslationUnitDecl()->localUncachedLookup(
97 ImportDeclName, FoundDecls);
98
99 if (FoundDecls.size() != 1)
100 return testing::AssertionFailure() << "Multiple declarations were found!";
101
102 auto Imported = Importer.Import(*FoundDecls.begin());
103 if (!Imported)
104 return testing::AssertionFailure() << "Import failed, nullptr returned!";
105
106 // This should dump source locations and assert if some source locations
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000107 // were not imported.
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000108 SmallString<1024> ImportChecker;
109 llvm::raw_svector_ostream ToNothing(ImportChecker);
110 ToCtx.getTranslationUnitDecl()->print(ToNothing);
111
Gabor Horvath480892b2017-10-18 09:25:18 +0000112 // This traverses the AST to catch certain bugs like poorly or not
113 // implemented subtrees.
114 Imported->dump(ToNothing);
115
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000116 return Verifier.match(Imported, AMatcher);
117}
118
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000119template<typename NodeType, typename MatcherType>
120void testImport(const std::string &FromCode, Language FromLang,
121 const std::string &ToCode, Language ToLang,
122 MatchVerifier<NodeType> &Verifier,
123 const MatcherType &AMatcher) {
124 auto RunOptsFrom = getRunOptionsForLanguage(FromLang);
125 auto RunOptsTo = getRunOptionsForLanguage(ToLang);
126 for (const auto &FromArgs : RunOptsFrom)
127 for (const auto &ToArgs : RunOptsTo)
128 EXPECT_TRUE(testImport(FromCode, FromArgs, ToCode, ToArgs,
129 Verifier, AMatcher));
130}
131
132
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000133TEST(ImportExpr, ImportStringLiteral) {
134 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000135 testImport("void declToImport() { \"foo\"; }",
136 Lang_CXX, "", Lang_CXX, Verifier,
137 functionDecl(
138 hasBody(
139 compoundStmt(
140 has(
141 stringLiteral(
142 hasType(
143 asString("const char [4]"))))))));
144 testImport("void declToImport() { L\"foo\"; }",
145 Lang_CXX, "", Lang_CXX, Verifier,
146 functionDecl(
147 hasBody(
148 compoundStmt(
149 has(
150 stringLiteral(
151 hasType(
152 asString("const wchar_t [4]"))))))));
153 testImport("void declToImport() { \"foo\" \"bar\"; }",
154 Lang_CXX, "", Lang_CXX, Verifier,
155 functionDecl(
156 hasBody(
157 compoundStmt(
158 has(
159 stringLiteral(
160 hasType(
161 asString("const char [7]"))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000162}
163
164TEST(ImportExpr, ImportGNUNullExpr) {
165 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000166 testImport("void declToImport() { __null; }",
167 Lang_CXX, "", Lang_CXX, Verifier,
168 functionDecl(
169 hasBody(
170 compoundStmt(
171 has(
172 gnuNullExpr(
173 hasType(isInteger())))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000174}
175
176TEST(ImportExpr, ImportCXXNullPtrLiteralExpr) {
177 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000178 testImport("void declToImport() { nullptr; }",
179 Lang_CXX11, "", Lang_CXX11, Verifier,
180 functionDecl(
181 hasBody(
182 compoundStmt(
183 has(
184 cxxNullPtrLiteralExpr())))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000185}
186
187
188TEST(ImportExpr, ImportFloatinglLiteralExpr) {
189 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000190 testImport("void declToImport() { 1.0; }",
191 Lang_C, "", Lang_C, Verifier,
192 functionDecl(
193 hasBody(
194 compoundStmt(
195 has(
196 floatLiteral(
197 equals(1.0),
198 hasType(asString("double"))))))));
199 testImport("void declToImport() { 1.0e-5f; }",
200 Lang_C, "", Lang_C, Verifier,
201 functionDecl(
202 hasBody(
203 compoundStmt(
204 has(
205 floatLiteral(
206 equals(1.0e-5f),
207 hasType(asString("float"))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000208}
209
210TEST(ImportExpr, ImportCompoundLiteralExpr) {
211 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000212 testImport("void declToImport() {"
213 " struct s { int x; long y; unsigned z; }; "
214 " (struct s){ 42, 0L, 1U }; }",
215 Lang_CXX, "", Lang_CXX, Verifier,
216 functionDecl(
217 hasBody(
218 compoundStmt(
219 has(
220 compoundLiteralExpr(
221 hasType(asString("struct s")),
222 has(initListExpr(
223 hasType(asString("struct s")),
224 has(integerLiteral(
225 equals(42), hasType(asString("int")))),
226 has(integerLiteral(
227 equals(0), hasType(asString("long")))),
228 has(integerLiteral(
229 equals(1),
230 hasType(asString("unsigned int"))))
231 ))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000232}
233
234TEST(ImportExpr, ImportCXXThisExpr) {
235 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000236 testImport("class declToImport { void f() { this; } };",
237 Lang_CXX, "", Lang_CXX, Verifier,
238 cxxRecordDecl(
239 hasMethod(
240 hasBody(
241 compoundStmt(
242 has(
243 cxxThisExpr(
244 hasType(
245 asString("class declToImport *")))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000246}
247
248TEST(ImportExpr, ImportAtomicExpr) {
249 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000250 testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }",
251 Lang_C, "", Lang_C, Verifier,
252 functionDecl(hasBody(compoundStmt(has(atomicExpr(
253 has(ignoringParenImpCasts(
254 declRefExpr(hasDeclaration(varDecl(hasName("ptr"))),
255 hasType(asString("int *"))))),
256 has(integerLiteral(equals(1), hasType(asString("int"))))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000257}
258
259TEST(ImportExpr, ImportLabelDeclAndAddrLabelExpr) {
260 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000261 testImport(
262 "void declToImport() { loop: goto loop; &&loop; }", Lang_C, "", Lang_C,
263 Verifier,
264 functionDecl(hasBody(compoundStmt(
265 has(labelStmt(hasDeclaration(labelDecl(hasName("loop"))))),
266 has(addrLabelExpr(hasDeclaration(labelDecl(hasName("loop")))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000267}
268
269AST_MATCHER_P(TemplateDecl, hasTemplateDecl,
270 internal::Matcher<NamedDecl>, InnerMatcher) {
271 const NamedDecl *Template = Node.getTemplatedDecl();
272 return Template && InnerMatcher.matches(*Template, Finder, Builder);
273}
274
275TEST(ImportExpr, ImportParenListExpr) {
276 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000277 testImport(
Manuel Klimek696e5052017-08-02 13:04:44 +0000278 "template<typename T> class dummy { void f() { dummy X(*this); } };"
279 "typedef dummy<int> declToImport;"
280 "template class dummy<int>;",
281 Lang_CXX, "", Lang_CXX, Verifier,
282 typedefDecl(hasType(templateSpecializationType(
283 hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate(
284 classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(allOf(
285 hasName("f"),
286 hasBody(compoundStmt(has(declStmt(hasSingleDecl(
287 varDecl(hasInitializer(parenListExpr(has(unaryOperator(
288 hasOperatorName("*"),
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000289 hasUnaryOperand(cxxThisExpr())))))))))))))))))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000290}
291
Gabor Horvath480892b2017-10-18 09:25:18 +0000292TEST(ImportExpr, ImportSwitch) {
293 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000294 testImport("void declToImport() { int b; switch (b) { case 1: break; } }",
295 Lang_C, "", Lang_C, Verifier,
296 functionDecl(hasBody(compoundStmt(
297 has(switchStmt(has(compoundStmt(has(caseStmt())))))))));
Gabor Horvath480892b2017-10-18 09:25:18 +0000298}
299
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000300TEST(ImportExpr, ImportStmtExpr) {
301 MatchVerifier<Decl> Verifier;
302 // NOTE: has() ignores implicit casts, using hasDescendant() to match it
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000303 testImport(
304 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
305 Lang_C, "", Lang_C, Verifier,
306 functionDecl(
307 hasBody(
308 compoundStmt(
309 has(
310 declStmt(
311 hasSingleDecl(
312 varDecl(
313 hasName("C"),
314 hasType(asString("int")),
315 hasInitializer(
316 stmtExpr(
317 hasAnySubstatement(
318 declStmt(
319 hasSingleDecl(
320 varDecl(
321 hasName("X"),
322 hasType(asString("int")),
323 hasInitializer(
324 integerLiteral(equals(4))))))),
325 hasDescendant(
326 implicitCastExpr()
327 )))))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000328}
329
330TEST(ImportExpr, ImportConditionalOperator) {
331 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000332 testImport(
333 "void declToImport() { true ? 1 : -5; }",
334 Lang_CXX, "", Lang_CXX, Verifier,
335 functionDecl(
336 hasBody(
337 compoundStmt(
338 has(
339 conditionalOperator(
340 hasCondition(cxxBoolLiteral(equals(true))),
341 hasTrueExpression(integerLiteral(equals(1))),
342 hasFalseExpression(
343 unaryOperator(hasUnaryOperand(integerLiteral(equals(5))))
344 )))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000345}
346
347TEST(ImportExpr, ImportBinaryConditionalOperator) {
348 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000349 testImport(
350 "void declToImport() { 1 ?: -5; }", Lang_CXX, "", Lang_CXX, Verifier,
351 functionDecl(
352 hasBody(
353 compoundStmt(
354 has(
355 binaryConditionalOperator(
356 hasCondition(
357 implicitCastExpr(
358 hasSourceExpression(
359 opaqueValueExpr(
360 hasSourceExpression(integerLiteral(equals(1))))),
361 hasType(booleanType()))),
362 hasTrueExpression(
363 opaqueValueExpr(hasSourceExpression(
364 integerLiteral(equals(1))))),
365 hasFalseExpression(
366 unaryOperator(hasOperatorName("-"),
367 hasUnaryOperand(integerLiteral(equals(5)))))
368 ))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000369}
370
371TEST(ImportExpr, ImportDesignatedInitExpr) {
372 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000373 testImport("void declToImport() {"
374 " struct point { double x; double y; };"
375 " struct point ptarray[10] = "
376 "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }",
377 Lang_C, "", Lang_C, Verifier,
378 functionDecl(
379 hasBody(
380 compoundStmt(
381 has(
382 declStmt(
383 hasSingleDecl(
384 varDecl(
385 hasInitializer(
386 initListExpr(
387 hasSyntacticForm(
388 initListExpr(
389 has(
390 designatedInitExpr(
391 designatorCountIs(2),
392 has(floatLiteral(
393 equals(1.0))),
394 has(integerLiteral(
395 equals(2))))),
396 has(
397 designatedInitExpr(
398 designatorCountIs(2),
399 has(floatLiteral(
400 equals(2.0))),
401 has(integerLiteral(
402 equals(2))))),
403 has(
404 designatedInitExpr(
405 designatorCountIs(2),
406 has(floatLiteral(
407 equals(1.0))),
408 has(integerLiteral(
409 equals(0)))))
410 ))))))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000411}
412
413
414TEST(ImportExpr, ImportPredefinedExpr) {
415 MatchVerifier<Decl> Verifier;
416 // __func__ expands as StringLiteral("declToImport")
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000417 testImport("void declToImport() { __func__; }",
418 Lang_CXX, "", Lang_CXX, Verifier,
419 functionDecl(
420 hasBody(
421 compoundStmt(
422 has(
423 predefinedExpr(
424 hasType(
425 asString("const char [13]")),
426 has(
427 stringLiteral(
428 hasType(
429 asString("const char [13]"))))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000430}
431
432TEST(ImportExpr, ImportInitListExpr) {
433 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000434 testImport(
435 "void declToImport() {"
436 " struct point { double x; double y; };"
437 " point ptarray[10] = { [2].y = 1.0, [2].x = 2.0,"
438 " [0].x = 1.0 }; }",
439 Lang_CXX, "", Lang_CXX, Verifier,
440 functionDecl(
441 hasBody(
442 compoundStmt(
443 has(
444 declStmt(
445 hasSingleDecl(
446 varDecl(
447 hasInitializer(
448 initListExpr(
449 has(
450 cxxConstructExpr(
451 requiresZeroInitialization())),
452 has(
453 initListExpr(
454 hasType(asString("struct point")),
455 has(floatLiteral(equals(1.0))),
456 has(implicitValueInitExpr(
457 hasType(asString("double")))))),
458 has(
459 initListExpr(
460 hasType(asString("struct point")),
461 has(floatLiteral(equals(2.0))),
462 has(floatLiteral(equals(1.0)))))
463 ))))))))));
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000464}
465
466
Aleksei Sidorina693b372016-09-28 10:16:56 +0000467const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr;
468
469TEST(ImportExpr, ImportVAArgExpr) {
470 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000471 testImport("void declToImport(__builtin_va_list list, ...) {"
472 " (void)__builtin_va_arg(list, int); }",
473 Lang_CXX, "", Lang_CXX, Verifier,
474 functionDecl(
475 hasBody(
476 compoundStmt(
477 has(
478 cStyleCastExpr(
479 hasSourceExpression(
480 vaArgExpr())))))));
Aleksei Sidorina693b372016-09-28 10:16:56 +0000481}
482
483
Gabor Horvath0866c2f2016-11-23 15:24:23 +0000484TEST(ImportType, ImportAtomicType) {
485 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000486 testImport("void declToImport() { typedef _Atomic(int) a_int; }",
487 Lang_CXX11, "", Lang_CXX11, Verifier,
488 functionDecl(
489 hasBody(
490 compoundStmt(
491 has(
492 declStmt(
493 has(
494 typedefDecl(
495 has(atomicType())))))))));
Gabor Horvath0866c2f2016-11-23 15:24:23 +0000496}
497
498
Gabor Horvath7a91c082017-11-14 11:30:38 +0000499TEST(ImportType, ImportTypeAliasTemplate) {
500 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000501 testImport("template <int K>"
502 "struct dummy { static const int i = K; };"
503 "template <int K> using dummy2 = dummy<K>;"
504 "int declToImport() { return dummy2<3>::i; }",
505 Lang_CXX11, "", Lang_CXX11, Verifier,
506 functionDecl(
507 hasBody(
508 compoundStmt(
509 has(
510 returnStmt(
511 has(
512 implicitCastExpr(
513 has(
514 declRefExpr())))))))));
Gabor Horvath7a91c082017-11-14 11:30:38 +0000515}
516
Gabor Horvath7a91c082017-11-14 11:30:38 +0000517TEST(ImportType, ImportPackExpansion) {
518 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000519 testImport("template <typename... Args>"
520 "struct dummy {"
521 " dummy(Args... args) {}"
522 " static const int i = 4;"
523 "};"
524 "int declToImport() { return dummy<int>::i; }",
525 Lang_CXX11, "", Lang_CXX11, Verifier,
526 functionDecl(
527 hasBody(
528 compoundStmt(
529 has(
530 returnStmt(
531 has(
532 implicitCastExpr(
533 has(
534 declRefExpr())))))))));
Gabor Horvath7a91c082017-11-14 11:30:38 +0000535}
536
Aleksei Sidorinb05f37a2017-11-26 17:04:06 +0000537/// \brief Matches __builtin_types_compatible_p:
538/// GNU extension to check equivalent types
539/// Given
540/// \code
541/// __builtin_types_compatible_p(int, int)
542/// \endcode
543// will generate TypeTraitExpr <...> 'int'
544const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr;
545
546TEST(ImportExpr, ImportTypeTraitExpr) {
547 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000548 testImport("void declToImport() { "
549 " __builtin_types_compatible_p(int, int);"
550 "}",
551 Lang_C, "", Lang_C, Verifier,
552 functionDecl(
553 hasBody(
554 compoundStmt(
555 has(
556 typeTraitExpr(hasType(asString("int"))))))));
Aleksei Sidorinb05f37a2017-11-26 17:04:06 +0000557}
558
559TEST(ImportExpr, ImportTypeTraitExprValDep) {
560 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000561 testImport("template<typename T> struct declToImport {"
562 " void m() { __is_pod(T); }"
563 "};"
564 "void f() { declToImport<int>().m(); }",
565 Lang_CXX11, "", Lang_CXX11, Verifier,
566 classTemplateDecl(
567 has(
568 cxxRecordDecl(
569 has(
570 functionDecl(
571 hasBody(
572 compoundStmt(
Aleksei Sidorinb05f37a2017-11-26 17:04:06 +0000573 has(
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000574 typeTraitExpr(
575 hasType(booleanType())
576 ))))))))));
Aleksei Sidorinb05f37a2017-11-26 17:04:06 +0000577}
Gabor Horvath7a91c082017-11-14 11:30:38 +0000578
Aleksei Sidorin60ccb7d2017-11-27 10:30:00 +0000579const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr>
580 cxxPseudoDestructorExpr;
581
582TEST(ImportExpr, ImportCXXPseudoDestructorExpr) {
583 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000584 testImport("typedef int T;"
585 "void declToImport(int *p) {"
586 " T t;"
587 " p->T::~T();"
588 "}",
589 Lang_CXX, "", Lang_CXX, Verifier,
590 functionDecl(has(compoundStmt(has(
591 callExpr(has(cxxPseudoDestructorExpr())))))));
Aleksei Sidorin60ccb7d2017-11-27 10:30:00 +0000592}
593
Aleksei Sidorin9d8ba2e2017-12-03 16:04:07 +0000594TEST(ImportDecl, ImportUsingDecl) {
595 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000596 testImport("namespace foo { int bar; }"
597 "int declToImport(){ using foo::bar; }",
598 Lang_CXX, "", Lang_CXX, Verifier,
599 functionDecl(
600 has(
601 compoundStmt(
602 has(
603 declStmt(
604 has(
605 usingDecl())))))));
Aleksei Sidorin9d8ba2e2017-12-03 16:04:07 +0000606}
607
608/// \brief Matches shadow declarations introduced into a scope by a
609/// (resolved) using declaration.
610///
611/// Given
612/// \code
613/// namespace n { int f; }
614/// namespace declToImport { using n::f; }
615/// \endcode
616/// usingShadowDecl()
617/// matches \code f \endcode
618const internal::VariadicDynCastAllOfMatcher<Decl,
619 UsingShadowDecl> usingShadowDecl;
620
621TEST(ImportDecl, ImportUsingShadowDecl) {
622 MatchVerifier<Decl> Verifier;
Aleksei Sidorine45ab562017-12-21 17:41:06 +0000623 testImport("namespace foo { int bar; }"
624 "namespace declToImport { using foo::bar; }",
625 Lang_CXX, "", Lang_CXX, Verifier,
626 namespaceDecl(has(usingShadowDecl())));
Aleksei Sidorin9d8ba2e2017-12-03 16:04:07 +0000627}
628
Artem Dergachev4e7c6fd2016-04-14 11:51:27 +0000629} // end namespace ast_matchers
630} // end namespace clang