Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / unittests / AST / ASTImporterTest.cpp
blob0cbec5cf9ba062faf07bf8a72ca41b4f35347791
1 //===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Tests for the correct import of AST nodes from one AST context to another.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/RecordLayout.h"
14 #include "clang/ASTMatchers/ASTMatchers.h"
15 #include "llvm/Support/SmallVectorMemoryBuffer.h"
17 #include "clang/AST/DeclContextInternals.h"
18 #include "gtest/gtest.h"
20 #include "ASTImporterFixtures.h"
21 #include <optional>
23 namespace clang {
24 namespace ast_matchers {
26 using internal::Matcher;
28 static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) {
29 QualType Ty = FD->getFriendType()->getType().getCanonicalType();
30 return cast<RecordType>(Ty)->getDecl();
33 struct ImportExpr : TestImportBase {};
34 struct ImportType : TestImportBase {};
35 struct ImportDecl : TestImportBase {};
36 struct ImportFixedPointExpr : ImportExpr {};
38 struct CanonicalRedeclChain : ASTImporterOptionSpecificTestBase {};
40 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers) {
41 Decl *FromTU = getTuDecl("void f();", Lang_CXX03);
42 auto Pattern = functionDecl(hasName("f"));
43 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
45 auto Redecls = getCanonicalForwardRedeclChain(D0);
46 ASSERT_EQ(Redecls.size(), 1u);
47 EXPECT_EQ(D0, Redecls[0]);
50 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers2) {
51 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
52 auto Pattern = functionDecl(hasName("f"));
53 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
54 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
55 FunctionDecl *D1 = D2->getPreviousDecl();
57 auto Redecls = getCanonicalForwardRedeclChain(D0);
58 ASSERT_EQ(Redecls.size(), 3u);
59 EXPECT_EQ(D0, Redecls[0]);
60 EXPECT_EQ(D1, Redecls[1]);
61 EXPECT_EQ(D2, Redecls[2]);
64 TEST_P(CanonicalRedeclChain, ShouldBeSameForAllDeclInTheChain) {
65 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
66 auto Pattern = functionDecl(hasName("f"));
67 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
68 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
69 FunctionDecl *D1 = D2->getPreviousDecl();
71 auto RedeclsD0 = getCanonicalForwardRedeclChain(D0);
72 auto RedeclsD1 = getCanonicalForwardRedeclChain(D1);
73 auto RedeclsD2 = getCanonicalForwardRedeclChain(D2);
75 EXPECT_THAT(RedeclsD0, ::testing::ContainerEq(RedeclsD1));
76 EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2));
79 namespace {
80 struct RedirectingImporter : public ASTImporter {
81 using ASTImporter::ASTImporter;
83 protected:
84 llvm::Expected<Decl *> ImportImpl(Decl *FromD) override {
85 auto *ND = dyn_cast<NamedDecl>(FromD);
86 if (!ND || ND->getName() != "shouldNotBeImported")
87 return ASTImporter::ImportImpl(FromD);
88 for (Decl *D : getToContext().getTranslationUnitDecl()->decls()) {
89 if (auto *ND = dyn_cast<NamedDecl>(D))
90 if (ND->getName() == "realDecl") {
91 RegisterImportedDecl(FromD, ND);
92 return ND;
95 return ASTImporter::ImportImpl(FromD);
99 } // namespace
101 struct RedirectingImporterTest : ASTImporterOptionSpecificTestBase {
102 RedirectingImporterTest() {
103 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
104 ASTContext &FromContext, FileManager &FromFileManager,
105 bool MinimalImport,
106 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
107 return new RedirectingImporter(ToContext, ToFileManager, FromContext,
108 FromFileManager, MinimalImport,
109 SharedState);
114 // Test that an ASTImporter subclass can intercept an import call.
115 TEST_P(RedirectingImporterTest, InterceptImport) {
116 Decl *From, *To;
117 std::tie(From, To) =
118 getImportedDecl("class shouldNotBeImported {};", Lang_CXX03,
119 "class realDecl {};", Lang_CXX03, "shouldNotBeImported");
120 auto *Imported = cast<CXXRecordDecl>(To);
121 EXPECT_EQ(Imported->getQualifiedNameAsString(), "realDecl");
123 // Make sure our importer prevented the importing of the decl.
124 auto *ToTU = Imported->getTranslationUnitDecl();
125 auto Pattern = functionDecl(hasName("shouldNotBeImported"));
126 unsigned count =
127 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
128 EXPECT_EQ(0U, count);
131 // Test that when we indirectly import a declaration the custom ASTImporter
132 // is still intercepting the import.
133 TEST_P(RedirectingImporterTest, InterceptIndirectImport) {
134 Decl *From, *To;
135 std::tie(From, To) =
136 getImportedDecl("class shouldNotBeImported {};"
137 "class F { shouldNotBeImported f; };",
138 Lang_CXX03, "class realDecl {};", Lang_CXX03, "F");
140 // Make sure our ASTImporter prevented the importing of the decl.
141 auto *ToTU = To->getTranslationUnitDecl();
142 auto Pattern = functionDecl(hasName("shouldNotBeImported"));
143 unsigned count =
144 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
145 EXPECT_EQ(0U, count);
148 struct ImportPath : ASTImporterOptionSpecificTestBase {
149 Decl *FromTU;
150 FunctionDecl *D0, *D1, *D2;
151 ImportPath() {
152 FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
153 auto Pattern = functionDecl(hasName("f"));
154 D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
155 D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
156 D1 = D2->getPreviousDecl();
160 TEST_P(ImportPath, Push) {
161 ASTImporter::ImportPathTy path;
162 path.push(D0);
163 EXPECT_FALSE(path.hasCycleAtBack());
166 TEST_P(ImportPath, SmallCycle) {
167 ASTImporter::ImportPathTy path;
168 path.push(D0);
169 path.push(D0);
170 EXPECT_TRUE(path.hasCycleAtBack());
171 path.pop();
172 EXPECT_FALSE(path.hasCycleAtBack());
173 path.push(D0);
174 EXPECT_TRUE(path.hasCycleAtBack());
177 TEST_P(ImportPath, GetSmallCycle) {
178 ASTImporter::ImportPathTy path;
179 path.push(D0);
180 path.push(D0);
181 EXPECT_TRUE(path.hasCycleAtBack());
182 std::array<Decl* ,2> Res;
183 int i = 0;
184 for (Decl *Di : path.getCycleAtBack()) {
185 Res[i++] = Di;
187 ASSERT_EQ(i, 2);
188 EXPECT_EQ(Res[0], D0);
189 EXPECT_EQ(Res[1], D0);
192 TEST_P(ImportPath, GetCycle) {
193 ASTImporter::ImportPathTy path;
194 path.push(D0);
195 path.push(D1);
196 path.push(D2);
197 path.push(D0);
198 EXPECT_TRUE(path.hasCycleAtBack());
199 std::array<Decl* ,4> Res;
200 int i = 0;
201 for (Decl *Di : path.getCycleAtBack()) {
202 Res[i++] = Di;
204 ASSERT_EQ(i, 4);
205 EXPECT_EQ(Res[0], D0);
206 EXPECT_EQ(Res[1], D2);
207 EXPECT_EQ(Res[2], D1);
208 EXPECT_EQ(Res[3], D0);
211 TEST_P(ImportPath, CycleAfterCycle) {
212 ASTImporter::ImportPathTy path;
213 path.push(D0);
214 path.push(D1);
215 path.push(D0);
216 path.push(D1);
217 path.push(D2);
218 path.push(D0);
219 EXPECT_TRUE(path.hasCycleAtBack());
220 std::array<Decl* ,4> Res;
221 int i = 0;
222 for (Decl *Di : path.getCycleAtBack()) {
223 Res[i++] = Di;
225 ASSERT_EQ(i, 4);
226 EXPECT_EQ(Res[0], D0);
227 EXPECT_EQ(Res[1], D2);
228 EXPECT_EQ(Res[2], D1);
229 EXPECT_EQ(Res[3], D0);
231 path.pop();
232 path.pop();
233 path.pop();
234 EXPECT_TRUE(path.hasCycleAtBack());
235 i = 0;
236 for (Decl *Di : path.getCycleAtBack()) {
237 Res[i++] = Di;
239 ASSERT_EQ(i, 3);
240 EXPECT_EQ(Res[0], D0);
241 EXPECT_EQ(Res[1], D1);
242 EXPECT_EQ(Res[2], D0);
244 path.pop();
245 EXPECT_FALSE(path.hasCycleAtBack());
248 const internal::VariadicDynCastAllOfMatcher<Stmt, SourceLocExpr> sourceLocExpr;
250 AST_MATCHER_P(SourceLocExpr, hasBuiltinStr, StringRef, Str) {
251 return Node.getBuiltinStr() == Str;
254 TEST_P(ImportExpr, ImportSourceLocExpr) {
255 MatchVerifier<Decl> Verifier;
256 testImport("void declToImport() { (void)__builtin_FILE(); }", Lang_CXX03, "",
257 Lang_CXX03, Verifier,
258 functionDecl(hasDescendant(
259 sourceLocExpr(hasBuiltinStr("__builtin_FILE")))));
260 testImport("void declToImport() { (void)__builtin_FILE_NAME(); }", Lang_CXX03,
261 "", Lang_CXX03, Verifier,
262 functionDecl(hasDescendant(
263 sourceLocExpr(hasBuiltinStr("__builtin_FILE_NAME")))));
264 testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03,
265 "", Lang_CXX03, Verifier,
266 functionDecl(hasDescendant(
267 sourceLocExpr(hasBuiltinStr("__builtin_COLUMN")))));
270 TEST_P(ImportExpr, ImportStringLiteral) {
271 MatchVerifier<Decl> Verifier;
272 testImport("void declToImport() { (void)\"foo\"; }", Lang_CXX03, "",
273 Lang_CXX03, Verifier,
274 functionDecl(hasDescendant(
275 stringLiteral(hasType(asString("const char[4]"))))));
276 testImport("void declToImport() { (void)L\"foo\"; }", Lang_CXX03, "",
277 Lang_CXX03, Verifier,
278 functionDecl(hasDescendant(
279 stringLiteral(hasType(asString("const wchar_t[4]"))))));
280 testImport("void declToImport() { (void) \"foo\" \"bar\"; }", Lang_CXX03, "",
281 Lang_CXX03, Verifier,
282 functionDecl(hasDescendant(
283 stringLiteral(hasType(asString("const char[7]"))))));
286 TEST_P(ImportExpr, ImportChooseExpr) {
287 MatchVerifier<Decl> Verifier;
289 // This case tests C code that is not condition-dependent and has a true
290 // condition.
291 testImport("void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }",
292 Lang_C99, "", Lang_C99, Verifier,
293 functionDecl(hasDescendant(chooseExpr())));
296 const internal::VariadicDynCastAllOfMatcher<Stmt, ShuffleVectorExpr>
297 shuffleVectorExpr;
299 TEST_P(ImportExpr, ImportShuffleVectorExpr) {
300 MatchVerifier<Decl> Verifier;
301 constexpr auto Code = R"code(
302 typedef double vector4double __attribute__((__vector_size__(32)));
303 vector4double declToImport(vector4double a, vector4double b) {
304 return __builtin_shufflevector(a, b, 0, 1, 2, 3);
306 )code";
307 const auto Pattern = functionDecl(hasDescendant(shuffleVectorExpr(
308 allOf(has(declRefExpr(to(parmVarDecl(hasName("a"))))),
309 has(declRefExpr(to(parmVarDecl(hasName("b"))))),
310 has(integerLiteral(equals(0))), has(integerLiteral(equals(1))),
311 has(integerLiteral(equals(2))), has(integerLiteral(equals(3)))))));
312 testImport(Code, Lang_C99, "", Lang_C99, Verifier, Pattern);
315 TEST_P(ImportExpr, ImportGNUNullExpr) {
316 MatchVerifier<Decl> Verifier;
317 testImport("void declToImport() { (void)__null; }", Lang_CXX03, "",
318 Lang_CXX03, Verifier,
319 functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger())))));
322 TEST_P(ImportExpr, ImportGenericSelectionExpr) {
323 MatchVerifier<Decl> Verifier;
325 testImport(
326 "void declToImport() { int x; (void)_Generic(x, int: 0, float: 1); }",
327 Lang_C99, "", Lang_C99, Verifier,
328 functionDecl(hasDescendant(genericSelectionExpr())));
331 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) {
332 MatchVerifier<Decl> Verifier;
333 testImport(
334 "void declToImport() { (void)nullptr; }",
335 Lang_CXX11, "", Lang_CXX11, Verifier,
336 functionDecl(hasDescendant(cxxNullPtrLiteralExpr())));
340 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) {
341 MatchVerifier<Decl> Verifier;
342 testImport("void declToImport() { (void)1.0; }", Lang_C99, "", Lang_C99,
343 Verifier,
344 functionDecl(hasDescendant(
345 floatLiteral(equals(1.0), hasType(asString("double"))))));
346 testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99, "", Lang_C99,
347 Verifier,
348 functionDecl(hasDescendant(
349 floatLiteral(equals(1.0e-5f), hasType(asString("float"))))));
352 TEST_P(ImportFixedPointExpr, ImportFixedPointerLiteralExpr) {
353 MatchVerifier<Decl> Verifier;
354 testImport("void declToImport() { (void)1.0k; }", Lang_C99, "", Lang_C99,
355 Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
356 testImport("void declToImport() { (void)0.75r; }", Lang_C99, "", Lang_C99,
357 Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
360 TEST_P(ImportExpr, ImportImaginaryLiteralExpr) {
361 MatchVerifier<Decl> Verifier;
362 testImport(
363 "void declToImport() { (void)1.0i; }",
364 Lang_CXX14, "", Lang_CXX14, Verifier,
365 functionDecl(hasDescendant(imaginaryLiteral())));
368 TEST_P(ImportExpr, ImportCompoundLiteralExpr) {
369 MatchVerifier<Decl> Verifier;
370 testImport("void declToImport() {"
371 " struct s { int x; long y; unsigned z; }; "
372 " (void)(struct s){ 42, 0L, 1U }; }",
373 Lang_CXX03, "", Lang_CXX03, Verifier,
374 functionDecl(hasDescendant(compoundLiteralExpr(
375 hasType(asString("struct s")),
376 has(initListExpr(
377 hasType(asString("struct s")),
378 has(integerLiteral(equals(42), hasType(asString("int")))),
379 has(integerLiteral(equals(0), hasType(asString("long")))),
380 has(integerLiteral(
381 equals(1), hasType(asString("unsigned int"))))))))));
384 TEST_P(ImportExpr, ImportCXXThisExpr) {
385 MatchVerifier<Decl> Verifier;
386 testImport("class declToImport { void f() { (void)this; } };", Lang_CXX03, "",
387 Lang_CXX03, Verifier,
388 cxxRecordDecl(hasMethod(hasDescendant(
389 cxxThisExpr(hasType(asString("class declToImport *")))))));
392 TEST_P(ImportExpr, ImportAtomicExpr) {
393 MatchVerifier<Decl> Verifier;
394 testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }",
395 Lang_C99, "", Lang_C99, Verifier,
396 functionDecl(hasDescendant(atomicExpr(
397 has(ignoringParenImpCasts(
398 declRefExpr(hasDeclaration(varDecl(hasName("ptr"))),
399 hasType(asString("int *"))))),
400 has(integerLiteral(equals(1), hasType(asString("int"))))))));
403 TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) {
404 MatchVerifier<Decl> Verifier;
405 testImport("void declToImport() { loop: goto loop; (void)&&loop; }", Lang_C99,
406 "", Lang_C99, Verifier,
407 functionDecl(hasDescendant(labelStmt(
408 hasDeclaration(labelDecl(hasName("loop"))))),
409 hasDescendant(addrLabelExpr(
410 hasDeclaration(labelDecl(hasName("loop")))))));
413 AST_MATCHER_P(TemplateDecl, hasTemplateDecl,
414 internal::Matcher<NamedDecl>, InnerMatcher) {
415 const NamedDecl *Template = Node.getTemplatedDecl();
416 return Template && InnerMatcher.matches(*Template, Finder, Builder);
419 TEST_P(ImportExpr, ImportParenListExpr) {
420 MatchVerifier<Decl> Verifier;
421 testImport(
422 "template<typename T> class dummy { void f() { dummy X(*this); } };"
423 "typedef dummy<int> declToImport;"
424 "template class dummy<int>;",
425 Lang_CXX03, "", Lang_CXX03, Verifier,
426 typedefDecl(hasType(elaboratedType(namesType(templateSpecializationType(
427 hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate(
428 classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(
429 allOf(hasName("f"),
430 hasBody(compoundStmt(has(declStmt(hasSingleDecl(varDecl(
431 hasInitializer(parenListExpr(has(unaryOperator(
432 hasOperatorName("*"),
433 hasUnaryOperand(
434 cxxThisExpr())))))))))))))))))))))))));
437 TEST_P(ImportExpr, ImportSwitch) {
438 MatchVerifier<Decl> Verifier;
439 testImport("void declToImport() { int b; switch (b) { case 1: break; } }",
440 Lang_C99, "", Lang_C99, Verifier,
441 functionDecl(hasDescendant(
442 switchStmt(has(compoundStmt(has(caseStmt())))))));
445 TEST_P(ImportExpr, ImportStmtExpr) {
446 MatchVerifier<Decl> Verifier;
447 testImport(
448 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
449 Lang_C99, "", Lang_C99, Verifier,
450 traverse(TK_AsIs,
451 functionDecl(hasDescendant(varDecl(
452 hasName("C"), hasType(asString("int")),
453 hasInitializer(stmtExpr(
454 hasAnySubstatement(declStmt(hasSingleDecl(varDecl(
455 hasName("X"), hasType(asString("int")),
456 hasInitializer(integerLiteral(equals(4))))))),
457 hasDescendant(implicitCastExpr()))))))));
460 TEST_P(ImportExpr, ImportConditionalOperator) {
461 MatchVerifier<Decl> Verifier;
462 testImport("void declToImport() { (void)(true ? 1 : -5); }", Lang_CXX03, "",
463 Lang_CXX03, Verifier,
464 functionDecl(hasDescendant(conditionalOperator(
465 hasCondition(cxxBoolLiteral(equals(true))),
466 hasTrueExpression(integerLiteral(equals(1))),
467 hasFalseExpression(unaryOperator(
468 hasUnaryOperand(integerLiteral(equals(5)))))))));
471 TEST_P(ImportExpr, ImportBinaryConditionalOperator) {
472 MatchVerifier<Decl> Verifier;
473 testImport(
474 "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03, "", Lang_CXX03,
475 Verifier,
476 traverse(TK_AsIs,
477 functionDecl(hasDescendant(binaryConditionalOperator(
478 hasCondition(implicitCastExpr(
479 hasSourceExpression(opaqueValueExpr(
480 hasSourceExpression(integerLiteral(equals(1))))),
481 hasType(booleanType()))),
482 hasTrueExpression(opaqueValueExpr(
483 hasSourceExpression(integerLiteral(equals(1))))),
484 hasFalseExpression(unaryOperator(
485 hasOperatorName("-"),
486 hasUnaryOperand(integerLiteral(equals(5))))))))));
489 TEST_P(ImportExpr, ImportDesignatedInitExpr) {
490 MatchVerifier<Decl> Verifier;
491 testImport(
492 "void declToImport() {"
493 " struct point { double x; double y; };"
494 " struct point ptarray[10] = "
495 "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }",
496 Lang_C99, "", Lang_C99, Verifier,
497 functionDecl(hasDescendant(initListExpr(
498 has(designatedInitExpr(designatorCountIs(2),
499 hasDescendant(floatLiteral(equals(1.0))),
500 hasDescendant(integerLiteral(equals(2))))),
501 has(designatedInitExpr(designatorCountIs(2),
502 hasDescendant(floatLiteral(equals(2.0))),
503 hasDescendant(integerLiteral(equals(2))))),
504 has(designatedInitExpr(designatorCountIs(2),
505 hasDescendant(floatLiteral(equals(1.0))),
506 hasDescendant(integerLiteral(equals(0)))))))));
509 TEST_P(ImportExpr, ImportPredefinedExpr) {
510 MatchVerifier<Decl> Verifier;
511 // __func__ expands as StringLiteral("declToImport")
512 testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "",
513 Lang_CXX03, Verifier,
514 functionDecl(hasDescendant(predefinedExpr(
515 hasType(asString("const char[13]")),
516 has(stringLiteral(hasType(asString("const char[13]"))))))));
519 TEST_P(ImportExpr, ImportInitListExpr) {
520 MatchVerifier<Decl> Verifier;
521 testImport("void declToImport() {"
522 " struct point { double x; double y; };"
523 " point ptarray[10] = { [2].y = 1.0, [2].x = 2.0,"
524 " [0].x = 1.0 }; }",
525 Lang_CXX03, "", Lang_CXX03, Verifier,
526 functionDecl(hasDescendant(initListExpr(
527 has(cxxConstructExpr(requiresZeroInitialization())),
528 has(initListExpr(
529 hasType(asString("point")), has(floatLiteral(equals(1.0))),
530 has(implicitValueInitExpr(hasType(asString("double")))))),
531 has(initListExpr(hasType(asString("point")),
532 has(floatLiteral(equals(2.0))),
533 has(floatLiteral(equals(1.0)))))))));
536 const internal::VariadicDynCastAllOfMatcher<Expr, CXXDefaultInitExpr>
537 cxxDefaultInitExpr;
539 TEST_P(ImportExpr, ImportCXXDefaultInitExpr) {
540 MatchVerifier<Decl> Verifier;
541 testImport("class declToImport { int DefInit = 5; }; declToImport X;",
542 Lang_CXX11, "", Lang_CXX11, Verifier,
543 cxxRecordDecl(hasDescendant(cxxConstructorDecl(
544 hasAnyConstructorInitializer(cxxCtorInitializer(
545 withInitializer(cxxDefaultInitExpr())))))));
546 testImport(
547 "struct X { int A = 5; }; X declToImport{};", Lang_CXX17, "", Lang_CXX17,
548 Verifier,
549 varDecl(hasInitializer(initListExpr(hasInit(0, cxxDefaultInitExpr())))));
552 const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr;
554 TEST_P(ImportExpr, ImportVAArgExpr) {
555 MatchVerifier<Decl> Verifier;
556 testImport("void declToImport(__builtin_va_list list, ...) {"
557 " (void)__builtin_va_arg(list, int); }",
558 Lang_CXX03, "", Lang_CXX03, Verifier,
559 functionDecl(hasDescendant(
560 cStyleCastExpr(hasSourceExpression(vaArgExpr())))));
563 TEST_P(ImportExpr, CXXTemporaryObjectExpr) {
564 MatchVerifier<Decl> Verifier;
565 testImport(
566 "struct C {};"
567 "void declToImport() { C c = C(); }",
568 Lang_CXX03, "", Lang_CXX03, Verifier,
569 traverse(TK_AsIs,
570 functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr(
571 has(materializeTemporaryExpr(has(implicitCastExpr(
572 has(cxxTemporaryObjectExpr()))))))))))));
575 TEST_P(ImportType, ImportAtomicType) {
576 MatchVerifier<Decl> Verifier;
577 testImport(
578 "void declToImport() { typedef _Atomic(int) a_int; }",
579 Lang_CXX11, "", Lang_CXX11, Verifier,
580 functionDecl(hasDescendant(typedefDecl(has(atomicType())))));
583 TEST_P(ImportType, ImportBitIntType) {
584 const AstTypeMatcher<BitIntType> bitIntType;
585 MatchVerifier<Decl> Verifier;
586 testImport("_BitInt(10) declToImport;", Lang_CXX11, "", Lang_CXX11, Verifier,
587 varDecl(hasType(bitIntType())));
590 TEST_P(ImportType, ImportDependentBitIntType) {
591 const AstTypeMatcher<DependentBitIntType> dependentBitIntType;
592 MatchVerifier<Decl> Verifier;
593 testImport("template<int Width> using declToImport = _BitInt(Width);",
594 Lang_CXX11, "", Lang_CXX11, Verifier,
595 typeAliasTemplateDecl(
596 has(typeAliasDecl(hasType(dependentBitIntType())))));
599 TEST_P(ImportType, ImportDependentAddressSpaceType) {
600 const AstTypeMatcher<DependentAddressSpaceType> dependentAddressSpaceType;
601 MatchVerifier<Decl> Verifier;
602 testImport(
604 template<typename T, int AddrSpace>
605 using declToImport = T __attribute__((address_space(AddrSpace)));
607 Lang_CXX11, "", Lang_CXX11, Verifier,
608 typeAliasTemplateDecl(
609 has(typeAliasDecl(hasType(dependentAddressSpaceType())))));
612 TEST_P(ImportType, ImportVectorType) {
613 const AstTypeMatcher<VectorType> vectorType;
614 MatchVerifier<Decl> Verifier;
615 testImport("typedef int __attribute__((vector_size(12))) declToImport;",
616 Lang_CXX11, "", Lang_CXX11, Verifier,
617 typedefDecl(hasType(vectorType())));
620 TEST_P(ImportType, ImportDependentVectorType) {
621 const AstTypeMatcher<DependentVectorType> dependentVectorType;
622 MatchVerifier<Decl> Verifier;
623 testImport(
625 template<typename T, int Size>
626 using declToImport = T __attribute__((vector_size(Size)));
628 Lang_CXX11, "", Lang_CXX11, Verifier,
629 typeAliasTemplateDecl(
630 has(typeAliasDecl(hasType(dependentVectorType())))));
633 struct ImportOpenCLPipe : ImportType {
634 std::vector<std::string> getExtraArgs() const override {
635 return {"-x", "cl", "-cl-no-stdinc", "-cl-std=CL2.0"};
639 TEST_P(ImportOpenCLPipe, ImportPipeType) {
640 const AstTypeMatcher<PipeType> pipeType;
641 MatchVerifier<Decl> Verifier;
642 testImport("typedef pipe int declToImport;", Lang_OpenCL, "", Lang_OpenCL,
643 Verifier, typedefDecl(hasType(pipeType())));
646 struct ImportMatrixType : ImportType {
647 std::vector<std::string> getExtraArgs() const override {
648 return {"-fenable-matrix"};
652 TEST_P(ImportMatrixType, ImportConstantMatrixType) {
653 const AstTypeMatcher<ConstantMatrixType> constantMatrixType;
654 MatchVerifier<Decl> Verifier;
655 testImport("typedef int __attribute__((matrix_type(5, 5))) declToImport;",
656 Lang_CXX11, "", Lang_CXX11, Verifier,
657 typedefDecl(hasType(constantMatrixType())));
660 TEST_P(ImportMatrixType, ImportDependentSizedMatrixType) {
661 const AstTypeMatcher<DependentSizedMatrixType> dependentSizedMatrixType;
662 MatchVerifier<Decl> Verifier;
663 testImport(
665 template<typename T, int Rows, int Cols>
666 using declToImport = T __attribute__((matrix_type(Rows, Cols)));
668 Lang_CXX11, "", Lang_CXX11, Verifier,
669 typeAliasTemplateDecl(
670 has(typeAliasDecl(hasType(dependentSizedMatrixType())))));
673 TEST_P(ImportType, ImportUsingType) {
674 MatchVerifier<Decl> Verifier;
675 testImport("struct C {};"
676 "void declToImport() { using ::C; new C{}; }",
677 Lang_CXX11, "", Lang_CXX11, Verifier,
678 functionDecl(hasDescendant(cxxNewExpr(hasType(pointerType(
679 pointee(elaboratedType(namesType(usingType())))))))));
682 TEST_P(ImportDecl, ImportFunctionTemplateDecl) {
683 MatchVerifier<Decl> Verifier;
684 testImport("template <typename T> void declToImport() { };", Lang_CXX03, "",
685 Lang_CXX03, Verifier, functionTemplateDecl());
688 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) {
689 MatchVerifier<Decl> Verifier;
690 testImport("template <typename T> struct C { T t; };"
691 "template <typename T> void declToImport() {"
692 " C<T> d;"
693 " (void)d.t;"
695 "void instantiate() { declToImport<int>(); }",
696 Lang_CXX03, "", Lang_CXX03, Verifier,
697 functionTemplateDecl(hasDescendant(
698 cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
699 testImport("template <typename T> struct C { T t; };"
700 "template <typename T> void declToImport() {"
701 " C<T> d;"
702 " (void)(&d)->t;"
704 "void instantiate() { declToImport<int>(); }",
705 Lang_CXX03, "", Lang_CXX03, Verifier,
706 functionTemplateDecl(hasDescendant(
707 cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
710 TEST_P(ImportType, ImportTypeAliasTemplate) {
711 MatchVerifier<Decl> Verifier;
712 testImport(
713 "template <int K>"
714 "struct dummy { static const int i = K; };"
715 "template <int K> using dummy2 = dummy<K>;"
716 "int declToImport() { return dummy2<3>::i; }",
717 Lang_CXX11, "", Lang_CXX11, Verifier,
718 traverse(TK_AsIs,
719 functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))),
720 unless(hasAncestor(
721 translationUnitDecl(has(typeAliasDecl())))))));
724 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl>
725 varTemplateSpecializationDecl;
727 TEST_P(ImportDecl, ImportVarTemplate) {
728 MatchVerifier<Decl> Verifier;
729 testImport(
730 "template <typename T>"
731 "T pi = T(3.1415926535897932385L);"
732 "void declToImport() { (void)pi<int>; }",
733 Lang_CXX14, "", Lang_CXX14, Verifier,
734 functionDecl(
735 hasDescendant(declRefExpr(to(varTemplateSpecializationDecl()))),
736 unless(hasAncestor(translationUnitDecl(has(varDecl(
737 hasName("pi"), unless(varTemplateSpecializationDecl()))))))));
740 TEST_P(ImportType, ImportPackExpansion) {
741 MatchVerifier<Decl> Verifier;
742 testImport("template <typename... Args>"
743 "struct dummy {"
744 " dummy(Args... args) {}"
745 " static const int i = 4;"
746 "};"
747 "int declToImport() { return dummy<int>::i; }",
748 Lang_CXX11, "", Lang_CXX11, Verifier,
749 traverse(TK_AsIs, functionDecl(hasDescendant(returnStmt(has(
750 implicitCastExpr(has(declRefExpr()))))))));
753 const internal::VariadicDynCastAllOfMatcher<Type,
754 DependentTemplateSpecializationType>
755 dependentTemplateSpecializationType;
757 TEST_P(ImportType, ImportDependentTemplateSpecialization) {
758 MatchVerifier<Decl> Verifier;
759 testImport("template<typename T>"
760 "struct A;"
761 "template<typename T>"
762 "struct declToImport {"
763 " typename A<T>::template B<T> a;"
764 "};",
765 Lang_CXX03, "", Lang_CXX03, Verifier,
766 classTemplateDecl(has(cxxRecordDecl(has(
767 fieldDecl(hasType(dependentTemplateSpecializationType())))))));
770 TEST_P(ImportType, ImportDeducedTemplateSpecialization) {
771 MatchVerifier<Decl> Verifier;
772 testImport("template <typename T>"
773 "class C { public: C(T); };"
774 "C declToImport(123);",
775 Lang_CXX17, "", Lang_CXX17, Verifier,
776 varDecl(hasType(elaboratedType(
777 namesType(deducedTemplateSpecializationType())))));
780 const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr>
781 sizeOfPackExpr;
783 TEST_P(ImportExpr, ImportSizeOfPackExpr) {
784 MatchVerifier<Decl> Verifier;
785 testImport(
786 "template <typename... Ts>"
787 "void declToImport() {"
788 " const int i = sizeof...(Ts);"
789 "};"
790 "void g() { declToImport<int>(); }",
791 Lang_CXX11, "", Lang_CXX11, Verifier,
792 functionTemplateDecl(hasDescendant(sizeOfPackExpr())));
793 testImport(
794 "template <typename... Ts>"
795 "using X = int[sizeof...(Ts)];"
796 "template <typename... Us>"
797 "struct Y {"
798 " X<Us..., int, double, int, Us...> f;"
799 "};"
800 "Y<float, int> declToImport;",
801 Lang_CXX11, "", Lang_CXX11, Verifier,
802 varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType(
803 hasUnqualifiedDesugaredType(constantArrayType(hasSize(7))))))))));
806 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr> cxxFoldExpr;
808 AST_MATCHER_P(CXXFoldExpr, hasOperator, BinaryOperatorKind, Op) {
809 return Node.getOperator() == Op;
811 AST_MATCHER(CXXFoldExpr, hasInit) { return Node.getInit(); }
812 AST_MATCHER(CXXFoldExpr, isRightFold) { return Node.isRightFold(); }
813 AST_MATCHER(CXXFoldExpr, isLeftFold) { return Node.isLeftFold(); }
815 TEST_P(ImportExpr, ImportCXXFoldExpr) {
816 auto Match1 =
817 cxxFoldExpr(hasOperator(BO_Add), isLeftFold(), unless(hasInit()));
818 auto Match2 = cxxFoldExpr(hasOperator(BO_Sub), isLeftFold(), hasInit());
819 auto Match3 =
820 cxxFoldExpr(hasOperator(BO_Mul), isRightFold(), unless(hasInit()));
821 auto Match4 = cxxFoldExpr(hasOperator(BO_Div), isRightFold(), hasInit());
823 MatchVerifier<Decl> Verifier;
824 testImport("template <typename... Ts>"
825 "void declToImport(Ts... args) {"
826 " const int i1 = (... + args);"
827 " const int i2 = (1 - ... - args);"
828 " const int i3 = (args * ...);"
829 " const int i4 = (args / ... / 1);"
830 "};"
831 "void g() { declToImport(1, 2, 3, 4, 5); }",
832 Lang_CXX17, "", Lang_CXX17, Verifier,
833 functionTemplateDecl(hasDescendant(Match1), hasDescendant(Match2),
834 hasDescendant(Match3),
835 hasDescendant(Match4)));
838 /// \brief Matches __builtin_types_compatible_p:
839 /// GNU extension to check equivalent types
840 /// Given
841 /// \code
842 /// __builtin_types_compatible_p(int, int)
843 /// \endcode
844 // will generate TypeTraitExpr <...> 'int'
845 const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr;
847 TEST_P(ImportExpr, ImportTypeTraitExpr) {
848 MatchVerifier<Decl> Verifier;
849 testImport(
850 "void declToImport() { "
851 " (void)__builtin_types_compatible_p(int, int);"
852 "}",
853 Lang_C99, "", Lang_C99, Verifier,
854 functionDecl(hasDescendant(typeTraitExpr(hasType(asString("int"))))));
857 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr;
859 TEST_P(ImportExpr, ImportCXXTypeidExpr) {
860 MatchVerifier<Decl> Verifier;
861 testImport(
862 "namespace std { class type_info {}; }"
863 "void declToImport() {"
864 " int x;"
865 " auto a = typeid(int); auto b = typeid(x);"
866 "}",
867 Lang_CXX11, "", Lang_CXX11, Verifier,
868 traverse(
869 TK_AsIs,
870 functionDecl(
871 hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant(
872 cxxTypeidExpr())))),
873 hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant(
874 cxxTypeidExpr())))))));
877 TEST_P(ImportExpr, ImportTypeTraitExprValDep) {
878 MatchVerifier<Decl> Verifier;
879 testImport(
880 "template<typename T> struct declToImport {"
881 " void m() { (void)__is_pod(T); }"
882 "};"
883 "void f() { declToImport<int>().m(); }",
884 Lang_CXX11, "", Lang_CXX11, Verifier,
885 classTemplateDecl(has(cxxRecordDecl(has(
886 functionDecl(hasDescendant(
887 typeTraitExpr(hasType(booleanType())))))))));
890 TEST_P(ImportDecl, ImportRecordDeclInFunc) {
891 MatchVerifier<Decl> Verifier;
892 testImport("int declToImport() { "
893 " struct data_t {int a;int b;};"
894 " struct data_t d;"
895 " return 0;"
896 "}",
897 Lang_C99, "", Lang_C99, Verifier,
898 functionDecl(hasBody(compoundStmt(
899 has(declStmt(hasSingleDecl(varDecl(hasName("d")))))))));
902 TEST_P(ImportDecl, ImportedVarDeclPreservesThreadLocalStorage) {
903 MatchVerifier<Decl> Verifier;
904 testImport("thread_local int declToImport;", Lang_CXX11, "", Lang_CXX11,
905 Verifier, varDecl(hasThreadStorageDuration()));
908 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) {
909 Decl *FromTU = getTuDecl("int declToImport() { "
910 " struct data_t {int a;int b;};"
911 " struct data_t d;"
912 " return 0;"
913 "}",
914 Lang_C99, "input.c");
915 auto *FromVar =
916 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d")));
917 ASSERT_TRUE(FromVar);
918 auto ToType =
919 ImportType(FromVar->getType().getCanonicalType(), FromVar, Lang_C99);
920 EXPECT_FALSE(ToType.isNull());
923 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) {
924 // This construct is not supported by ASTImporter.
925 Decl *FromTU = getTuDecl(
926 "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }",
927 Lang_C99, "input.c");
928 auto *From = FirstDeclMatcher<FunctionDecl>().match(
929 FromTU, functionDecl(hasName("declToImport")));
930 ASSERT_TRUE(From);
931 auto *To = Import(From, Lang_C99);
932 EXPECT_EQ(To, nullptr);
935 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) {
936 Decl *FromTU =
937 getTuDecl("#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n"
938 "int declToImport(){ return NONAME_SIZEOF(int); }",
939 Lang_C99, "input.c");
940 auto *From = FirstDeclMatcher<FunctionDecl>().match(
941 FromTU, functionDecl(hasName("declToImport")));
942 ASSERT_TRUE(From);
943 auto *To = Import(From, Lang_C99);
944 ASSERT_TRUE(To);
945 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
946 To, functionDecl(hasName("declToImport"),
947 hasDescendant(unaryExprOrTypeTraitExpr()))));
950 TEST_P(ASTImporterOptionSpecificTestBase,
951 ImportRecordDeclInFuncParamsFromMacro) {
952 // This construct is not supported by ASTImporter.
953 Decl *FromTU =
954 getTuDecl("#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n"
955 "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }",
956 Lang_C99, "input.c");
957 auto *From = FirstDeclMatcher<FunctionDecl>().match(
958 FromTU, functionDecl(hasName("declToImport")));
959 ASSERT_TRUE(From);
960 auto *To = Import(From, Lang_C99);
961 EXPECT_EQ(To, nullptr);
964 const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr>
965 cxxPseudoDestructorExpr;
967 TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) {
968 MatchVerifier<Decl> Verifier;
969 testImport(
970 "typedef int T;"
971 "void declToImport(int *p) {"
972 " T t;"
973 " p->T::~T();"
974 "}",
975 Lang_CXX03, "", Lang_CXX03, Verifier,
976 functionDecl(hasDescendant(callExpr(has(cxxPseudoDestructorExpr())))));
979 TEST_P(ImportDecl, ImportUsingDecl) {
980 MatchVerifier<Decl> Verifier;
981 testImport("namespace foo { int bar; }"
982 "void declToImport() { using foo::bar; }",
983 Lang_CXX03, "", Lang_CXX03, Verifier,
984 functionDecl(hasDescendant(usingDecl(hasName("bar")))));
987 TEST_P(ImportDecl, ImportUsingTemplate) {
988 MatchVerifier<Decl> Verifier;
989 testImport("namespace ns { template <typename T> struct S {}; }"
990 "template <template <typename> class T> class X {};"
991 "void declToImport() {"
992 "using ns::S; X<S> xi; }",
993 Lang_CXX11, "", Lang_CXX11, Verifier,
994 functionDecl(hasDescendant(varDecl(hasTypeLoc(elaboratedTypeLoc(
995 hasNamedTypeLoc(templateSpecializationTypeLoc(
996 hasAnyTemplateArgumentLoc(templateArgumentLoc())))))))));
999 TEST_P(ImportDecl, ImportUsingEnumDecl) {
1000 MatchVerifier<Decl> Verifier;
1001 testImport("namespace foo { enum bar { baz, toto, quux }; }"
1002 "void declToImport() { using enum foo::bar; }",
1003 Lang_CXX20, "", Lang_CXX20, Verifier,
1004 functionDecl(hasDescendant(usingEnumDecl(hasName("bar")))));
1007 const internal::VariadicDynCastAllOfMatcher<Decl, UsingPackDecl> usingPackDecl;
1009 TEST_P(ImportDecl, ImportUsingPackDecl) {
1010 MatchVerifier<Decl> Verifier;
1011 testImport(
1012 "struct A { int operator()() { return 1; } };"
1013 "struct B { int operator()() { return 2; } };"
1014 "template<typename ...T> struct C : T... { using T::operator()...; };"
1015 "C<A, B> declToImport;",
1016 Lang_CXX20, "", Lang_CXX20, Verifier,
1017 varDecl(hasType(elaboratedType(namesType(templateSpecializationType(
1018 hasDeclaration(classTemplateSpecializationDecl(
1019 hasDescendant(usingPackDecl())))))))));
1022 /// \brief Matches shadow declarations introduced into a scope by a
1023 /// (resolved) using declaration.
1025 /// Given
1026 /// \code
1027 /// namespace n { int f; }
1028 /// namespace declToImport { using n::f; }
1029 /// \endcode
1030 /// usingShadowDecl()
1031 /// matches \code f \endcode
1032 const internal::VariadicDynCastAllOfMatcher<Decl,
1033 UsingShadowDecl> usingShadowDecl;
1035 TEST_P(ImportDecl, ImportUsingShadowDecl) {
1036 MatchVerifier<Decl> Verifier;
1037 // from using-decl
1038 testImport("namespace foo { int bar; }"
1039 "namespace declToImport { using foo::bar; }",
1040 Lang_CXX03, "", Lang_CXX03, Verifier,
1041 namespaceDecl(has(usingShadowDecl(hasName("bar")))));
1042 // from using-enum-decl
1043 testImport("namespace foo { enum bar {baz, toto, quux }; }"
1044 "namespace declToImport { using enum foo::bar; }",
1045 Lang_CXX20, "", Lang_CXX20, Verifier,
1046 namespaceDecl(has(usingShadowDecl(hasName("baz")))));
1049 TEST_P(ImportExpr, ImportUnresolvedLookupExpr) {
1050 MatchVerifier<Decl> Verifier;
1051 testImport("template<typename T> int foo();"
1052 "template <typename T> void declToImport() {"
1053 " (void)::foo<T>;"
1054 " (void)::template foo<T>;"
1056 "void instantiate() { declToImport<int>(); }",
1057 Lang_CXX03, "", Lang_CXX03, Verifier,
1058 functionTemplateDecl(hasDescendant(unresolvedLookupExpr())));
1061 TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) {
1062 MatchVerifier<Decl> Verifier;
1063 testImport("template <typename T> struct C { T t; };"
1064 "template <typename T> void declToImport() {"
1065 " C<T> d;"
1066 " d.t = T();"
1068 "void instantiate() { declToImport<int>(); }",
1069 Lang_CXX03, "", Lang_CXX03, Verifier,
1070 functionTemplateDecl(hasDescendant(
1071 binaryOperator(has(cxxUnresolvedConstructExpr())))));
1072 testImport("template <typename T> struct C { T t; };"
1073 "template <typename T> void declToImport() {"
1074 " C<T> d;"
1075 " (&d)->t = T();"
1077 "void instantiate() { declToImport<int>(); }",
1078 Lang_CXX03, "", Lang_CXX03, Verifier,
1079 functionTemplateDecl(hasDescendant(
1080 binaryOperator(has(cxxUnresolvedConstructExpr())))));
1083 /// Check that function "declToImport()" (which is the templated function
1084 /// for corresponding FunctionTemplateDecl) is not added into DeclContext.
1085 /// Same for class template declarations.
1086 TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) {
1087 MatchVerifier<Decl> Verifier;
1088 testImport("template <typename T> void declToImport() { T a = 1; }"
1089 "void instantiate() { declToImport<int>(); }",
1090 Lang_CXX03, "", Lang_CXX03, Verifier,
1091 functionTemplateDecl(hasAncestor(translationUnitDecl(
1092 unless(has(functionDecl(hasName("declToImport"))))))));
1093 testImport("template <typename T> struct declToImport { T t; };"
1094 "void instantiate() { declToImport<int>(); }",
1095 Lang_CXX03, "", Lang_CXX03, Verifier,
1096 classTemplateDecl(hasAncestor(translationUnitDecl(
1097 unless(has(cxxRecordDecl(hasName("declToImport"))))))));
1100 TEST_P(ImportDecl, ImportClassTemplatePartialSpecialization) {
1101 MatchVerifier<Decl> Verifier;
1102 auto Code =
1103 R"s(
1104 struct declToImport {
1105 template <typename T0> struct X;
1106 template <typename T0> struct X<T0 *> {};
1108 )s";
1109 testImport(Code, Lang_CXX03, "", Lang_CXX03, Verifier,
1110 recordDecl(has(classTemplateDecl()),
1111 has(classTemplateSpecializationDecl())));
1114 TEST_P(ImportExpr, CXXOperatorCallExpr) {
1115 MatchVerifier<Decl> Verifier;
1116 testImport(
1117 "class declToImport {"
1118 " void f() { *this = declToImport(); }"
1119 "};",
1120 Lang_CXX03, "", Lang_CXX03, Verifier,
1121 cxxRecordDecl(has(cxxMethodDecl(hasDescendant(cxxOperatorCallExpr())))));
1124 TEST_P(ImportExpr, DependentSizedArrayType) {
1125 MatchVerifier<Decl> Verifier;
1126 testImport("template<typename T, int Size> class declToImport {"
1127 " T data[Size];"
1128 "};",
1129 Lang_CXX03, "", Lang_CXX03, Verifier,
1130 classTemplateDecl(has(cxxRecordDecl(
1131 has(fieldDecl(hasType(dependentSizedArrayType())))))));
1134 TEST_P(ImportExpr, DependentSizedExtVectorType) {
1135 MatchVerifier<Decl> Verifier;
1136 testImport("template<typename T, int Size>"
1137 "class declToImport {"
1138 " typedef T __attribute__((ext_vector_type(Size))) type;"
1139 "};",
1140 Lang_CXX03, "", Lang_CXX03, Verifier,
1141 classTemplateDecl(has(cxxRecordDecl(
1142 has(typedefDecl(hasType(dependentSizedExtVectorType())))))));
1145 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingPackDecl) {
1146 Decl *FromTU = getTuDecl(
1147 "struct A { int operator()() { return 1; } };"
1148 "struct B { int operator()() { return 2; } };"
1149 "template<typename ...T> struct C : T... { using T::operator()...; };"
1150 "C<A, B> Var;",
1151 Lang_CXX20);
1153 auto From = FirstDeclMatcher<UsingPackDecl>().match(FromTU, usingPackDecl());
1154 ASSERT_TRUE(From);
1155 auto To = cast<UsingPackDecl>(Import(From, Lang_CXX20));
1156 ASSERT_TRUE(To);
1158 ArrayRef<NamedDecl *> FromExpansions = From->expansions();
1159 ArrayRef<NamedDecl *> ToExpansions = To->expansions();
1160 ASSERT_EQ(FromExpansions.size(), ToExpansions.size());
1161 for (unsigned int I = 0; I < FromExpansions.size(); ++I) {
1162 auto ImportedExpansion = Import(FromExpansions[I], Lang_CXX20);
1163 EXPECT_EQ(ImportedExpansion, ToExpansions[I]);
1166 auto ImportedDC = cast<Decl>(Import(From->getDeclContext(), Lang_CXX20));
1167 EXPECT_EQ(ImportedDC, cast<Decl>(To->getDeclContext()));
1170 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) {
1171 Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03);
1172 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
1173 FromTU, templateTypeParmDecl(hasName("T")));
1174 TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
1175 ASSERT_FALSE(To->hasDefaultArgument());
1178 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) {
1179 Decl *FromTU =
1180 getTuDecl("template<typename T = int> struct X {};", Lang_CXX03);
1181 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
1182 FromTU, templateTypeParmDecl(hasName("T")));
1183 TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
1184 ASSERT_TRUE(To->hasDefaultArgument());
1185 QualType ToArg = To->getDefaultArgument();
1186 ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy));
1189 TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) {
1190 Decl *FromTU =
1191 getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }",
1192 Lang_CXX03);
1193 auto From = FirstDeclMatcher<FunctionDecl>().match(
1194 FromTU, functionDecl(hasName("f")));
1195 ASSERT_TRUE(From);
1196 ASSERT_TRUE(
1197 cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front())
1198 ->getSubExpr()
1199 ->getBeginLoc()
1200 .isValid());
1201 FunctionDecl *To = Import(From, Lang_CXX03);
1202 ASSERT_TRUE(To);
1203 ASSERT_TRUE(
1204 cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front())
1205 ->getSubExpr()
1206 ->getBeginLoc()
1207 .isValid());
1210 TEST_P(ASTImporterOptionSpecificTestBase,
1211 TemplateTemplateParmDeclNoDefaultArg) {
1212 Decl *FromTU = getTuDecl(R"(
1213 template<template<typename> typename TT> struct Y {};
1215 Lang_CXX17);
1216 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
1217 FromTU, templateTemplateParmDecl(hasName("TT")));
1218 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
1219 ASSERT_FALSE(To->hasDefaultArgument());
1222 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) {
1223 Decl *FromTU = getTuDecl(R"(
1224 template<typename T> struct X {};
1225 template<template<typename> typename TT = X> struct Y {};
1227 Lang_CXX17);
1228 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
1229 FromTU, templateTemplateParmDecl(hasName("TT")));
1230 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
1231 ASSERT_TRUE(To->hasDefaultArgument());
1232 const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument();
1233 ASSERT_TRUE(To->isTemplateDecl());
1234 TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl();
1236 // Find the default argument template 'X' in the AST and compare it against
1237 // the default argument we got.
1238 auto ToExpectedDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
1239 To->getTranslationUnitDecl(), classTemplateDecl(hasName("X")));
1240 ASSERT_EQ(ToTemplate, ToExpectedDecl);
1243 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclNoDefaultArg) {
1244 Decl *FromTU = getTuDecl("template<int N> struct X {};", Lang_CXX03);
1245 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
1246 FromTU, nonTypeTemplateParmDecl(hasName("N")));
1247 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
1248 ASSERT_FALSE(To->hasDefaultArgument());
1251 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclDefaultArg) {
1252 Decl *FromTU = getTuDecl("template<int S = 1> struct X {};", Lang_CXX03);
1253 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
1254 FromTU, nonTypeTemplateParmDecl(hasName("S")));
1255 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
1256 ASSERT_TRUE(To->hasDefaultArgument());
1257 Stmt *ToArg = To->getDefaultArgument();
1258 ASSERT_TRUE(isa<IntegerLiteral>(ToArg));
1259 ASSERT_EQ(cast<IntegerLiteral>(ToArg)->getValue().getLimitedValue(), 1U);
1262 TEST_P(ASTImporterOptionSpecificTestBase, TemplateArgumentsDefaulted) {
1263 Decl *FromTU = getTuDecl(R"(
1264 template<typename T> struct X {};
1265 template<typename TP = double,
1266 int NTTP = 50,
1267 template<typename> typename TT = X> struct S {};
1268 S<> s;
1270 Lang_CXX17);
1271 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
1272 FromTU, classTemplateSpecializationDecl(hasName("S")));
1273 ASSERT_TRUE(FromSpec);
1274 auto *ToSpec = Import(FromSpec, Lang_CXX03);
1275 ASSERT_TRUE(ToSpec);
1276 auto const &TList = ToSpec->getTemplateArgs();
1277 for (auto const &Arg : TList.asArray()) {
1278 ASSERT_TRUE(Arg.getIsDefaulted());
1282 TEST_P(ASTImporterOptionSpecificTestBase,
1283 ImportOfTemplatedDeclOfClassTemplateDecl) {
1284 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
1285 auto From =
1286 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
1287 ASSERT_TRUE(From);
1288 auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX03));
1289 ASSERT_TRUE(To);
1290 Decl *ToTemplated = To->getTemplatedDecl();
1291 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
1292 EXPECT_TRUE(ToTemplated1);
1293 EXPECT_EQ(ToTemplated1, ToTemplated);
1296 TEST_P(ASTImporterOptionSpecificTestBase,
1297 ImportOfTemplatedDeclOfFunctionTemplateDecl) {
1298 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
1299 auto From = FirstDeclMatcher<FunctionTemplateDecl>().match(
1300 FromTU, functionTemplateDecl());
1301 ASSERT_TRUE(From);
1302 auto To = cast<FunctionTemplateDecl>(Import(From, Lang_CXX03));
1303 ASSERT_TRUE(To);
1304 Decl *ToTemplated = To->getTemplatedDecl();
1305 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
1306 EXPECT_TRUE(ToTemplated1);
1307 EXPECT_EQ(ToTemplated1, ToTemplated);
1310 TEST_P(ASTImporterOptionSpecificTestBase,
1311 ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) {
1312 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
1313 auto FromFT =
1314 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
1315 ASSERT_TRUE(FromFT);
1317 auto ToTemplated =
1318 cast<CXXRecordDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1319 EXPECT_TRUE(ToTemplated);
1320 auto ToTU = ToTemplated->getTranslationUnitDecl();
1321 auto ToFT =
1322 FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, classTemplateDecl());
1323 EXPECT_TRUE(ToFT);
1326 TEST_P(ASTImporterOptionSpecificTestBase,
1327 ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
1328 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
1329 auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1330 FromTU, functionTemplateDecl());
1331 ASSERT_TRUE(FromFT);
1333 auto ToTemplated =
1334 cast<FunctionDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1335 EXPECT_TRUE(ToTemplated);
1336 auto ToTU = ToTemplated->getTranslationUnitDecl();
1337 auto ToFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1338 ToTU, functionTemplateDecl());
1339 EXPECT_TRUE(ToFT);
1342 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) {
1343 auto Code =
1345 namespace x {
1346 template<class X> struct S1{};
1347 template<class X> struct S2{};
1348 template<class X> struct S3{};
1351 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
1352 auto FromNs =
1353 FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl());
1354 auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX03));
1355 ASSERT_TRUE(ToNs);
1356 auto From =
1357 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU,
1358 classTemplateDecl(
1359 hasName("S2")));
1360 auto To =
1361 FirstDeclMatcher<ClassTemplateDecl>().match(ToNs,
1362 classTemplateDecl(
1363 hasName("S2")));
1364 ASSERT_TRUE(From);
1365 ASSERT_TRUE(To);
1366 auto ToTemplated = To->getTemplatedDecl();
1367 auto ToTemplated1 =
1368 cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX03));
1369 EXPECT_TRUE(ToTemplated1);
1370 ASSERT_EQ(ToTemplated1, ToTemplated);
1373 TEST_P(ASTImporterOptionSpecificTestBase,
1374 ImportTemplateSpecializationStaticMember) {
1375 auto FromCode =
1377 template <typename H> class Test{
1378 public:
1379 static const unsigned int length;
1382 template<> const unsigned int Test<int>::length;
1383 template<> const unsigned int Test<int>::length = 0;
1385 auto ToCode =
1387 template <typename H> class Test {
1388 public:
1389 static const unsigned int length;
1392 template <> const unsigned int Test<int>::length;
1394 void foo() { int i = 1 / Test<int>::length; }
1396 Decl *FromTU = getTuDecl(FromCode, Lang_CXX14);
1397 auto FromDecl = FirstDeclMatcher<VarDecl>().match(
1398 FromTU, varDecl(hasName("length"), isDefinition()));
1399 Decl *ToTu = getToTuDecl(ToCode, Lang_CXX14);
1400 auto ToX = Import(FromDecl, Lang_CXX03);
1401 auto ToDecl = FirstDeclMatcher<VarDecl>().match(
1402 ToTu, varDecl(hasName("length"), isDefinition()));
1403 EXPECT_TRUE(ToX);
1404 EXPECT_EQ(ToX, ToDecl);
1407 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) {
1408 // This tests the import of isConditionTrue directly to make sure the importer
1409 // gets it right.
1410 Decl *From, *To;
1411 std::tie(From, To) = getImportedDecl(
1412 "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", Lang_C99,
1413 "", Lang_C99);
1415 auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext());
1416 auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext());
1418 const ChooseExpr *FromChooseExpr =
1419 selectFirst<ChooseExpr>("choose", FromResults);
1420 ASSERT_TRUE(FromChooseExpr);
1422 const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults);
1423 ASSERT_TRUE(ToChooseExpr);
1425 EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue());
1426 EXPECT_EQ(FromChooseExpr->isConditionDependent(),
1427 ToChooseExpr->isConditionDependent());
1430 TEST_P(ASTImporterOptionSpecificTestBase, ImportConvertVectorExpr) {
1431 Decl *From, *To;
1432 std::tie(From, To) = getImportedDecl(
1433 "typedef double v4double __attribute__((__vector_size__(32)));"
1434 "typedef float v4float __attribute__((__vector_size__(16)));"
1435 "v4float vf;"
1436 "void declToImport() { (void)__builtin_convertvector(vf, v4double); }",
1437 Lang_CXX03, "", Lang_CXX03);
1439 auto ToResults =
1440 match(convertVectorExpr().bind("convert"), To->getASTContext());
1441 auto FromResults =
1442 match(convertVectorExpr().bind("convert"), From->getASTContext());
1444 const ConvertVectorExpr *FromConvertVectorExpr =
1445 selectFirst<ConvertVectorExpr>("convert", FromResults);
1446 ASSERT_TRUE(FromConvertVectorExpr);
1448 const ConvertVectorExpr *ToConvertVectorExpr =
1449 selectFirst<ConvertVectorExpr>("convert", ToResults);
1450 ASSERT_TRUE(ToConvertVectorExpr);
1453 TEST_P(ASTImporterOptionSpecificTestBase, ImportGenericSelectionExpr) {
1454 Decl *From, *To;
1455 std::tie(From, To) = getImportedDecl(
1457 int declToImport() {
1458 int x;
1459 return _Generic(x, int: 0, default: 1);
1462 Lang_C99, "", Lang_C99);
1464 auto ToResults =
1465 match(genericSelectionExpr().bind("expr"), To->getASTContext());
1466 auto FromResults =
1467 match(genericSelectionExpr().bind("expr"), From->getASTContext());
1469 const GenericSelectionExpr *FromGenericSelectionExpr =
1470 selectFirst<GenericSelectionExpr>("expr", FromResults);
1471 ASSERT_TRUE(FromGenericSelectionExpr);
1473 const GenericSelectionExpr *ToGenericSelectionExpr =
1474 selectFirst<GenericSelectionExpr>("expr", ToResults);
1475 ASSERT_TRUE(ToGenericSelectionExpr);
1477 EXPECT_EQ(FromGenericSelectionExpr->isResultDependent(),
1478 ToGenericSelectionExpr->isResultDependent());
1479 EXPECT_EQ(FromGenericSelectionExpr->getResultIndex(),
1480 ToGenericSelectionExpr->getResultIndex());
1483 TEST_P(ASTImporterOptionSpecificTestBase,
1484 ImportFunctionWithBackReferringParameter) {
1485 Decl *From, *To;
1486 std::tie(From, To) = getImportedDecl(
1488 template <typename T> struct X {};
1490 void declToImport(int y, X<int> &x) {}
1492 template <> struct X<int> {
1493 void g() {
1494 X<int> x;
1495 declToImport(0, x);
1499 Lang_CXX03, "", Lang_CXX03);
1501 MatchVerifier<Decl> Verifier;
1502 auto Matcher = functionDecl(hasName("declToImport"),
1503 parameterCountIs(2),
1504 hasParameter(0, hasName("y")),
1505 hasParameter(1, hasName("x")),
1506 hasParameter(1, hasType(asString("X<int> &"))));
1507 ASSERT_TRUE(Verifier.match(From, Matcher));
1508 EXPECT_TRUE(Verifier.match(To, Matcher));
1511 TEST_P(ASTImporterOptionSpecificTestBase,
1512 TUshouldNotContainTemplatedDeclOfFunctionTemplates) {
1513 Decl *From, *To;
1514 std::tie(From, To) =
1515 getImportedDecl("template <typename T> void declToImport() { T a = 1; }"
1516 "void instantiate() { declToImport<int>(); }",
1517 Lang_CXX03, "", Lang_CXX03);
1519 auto Check = [](Decl *D) -> bool {
1520 auto TU = D->getTranslationUnitDecl();
1521 for (auto Child : TU->decls()) {
1522 if (auto *FD = dyn_cast<FunctionDecl>(Child)) {
1523 if (FD->getNameAsString() == "declToImport") {
1524 GTEST_NONFATAL_FAILURE_(
1525 "TU should not contain any FunctionDecl with name declToImport");
1526 return false;
1530 return true;
1533 ASSERT_TRUE(Check(From));
1534 EXPECT_TRUE(Check(To));
1537 TEST_P(ASTImporterOptionSpecificTestBase,
1538 TUshouldNotContainTemplatedDeclOfClassTemplates) {
1539 Decl *From, *To;
1540 std::tie(From, To) =
1541 getImportedDecl("template <typename T> struct declToImport { T t; };"
1542 "void instantiate() { declToImport<int>(); }",
1543 Lang_CXX03, "", Lang_CXX03);
1545 auto Check = [](Decl *D) -> bool {
1546 auto TU = D->getTranslationUnitDecl();
1547 for (auto Child : TU->decls()) {
1548 if (auto *RD = dyn_cast<CXXRecordDecl>(Child)) {
1549 if (RD->getNameAsString() == "declToImport") {
1550 GTEST_NONFATAL_FAILURE_(
1551 "TU should not contain any CXXRecordDecl with name declToImport");
1552 return false;
1556 return true;
1559 ASSERT_TRUE(Check(From));
1560 EXPECT_TRUE(Check(To));
1563 TEST_P(ASTImporterOptionSpecificTestBase,
1564 TUshouldNotContainTemplatedDeclOfTypeAlias) {
1565 Decl *From, *To;
1566 std::tie(From, To) =
1567 getImportedDecl(
1568 "template <typename T> struct X {};"
1569 "template <typename T> using declToImport = X<T>;"
1570 "void instantiate() { declToImport<int> a; }",
1571 Lang_CXX11, "", Lang_CXX11);
1573 auto Check = [](Decl *D) -> bool {
1574 auto TU = D->getTranslationUnitDecl();
1575 for (auto Child : TU->decls()) {
1576 if (auto *AD = dyn_cast<TypeAliasDecl>(Child)) {
1577 if (AD->getNameAsString() == "declToImport") {
1578 GTEST_NONFATAL_FAILURE_(
1579 "TU should not contain any TypeAliasDecl with name declToImport");
1580 return false;
1584 return true;
1587 ASSERT_TRUE(Check(From));
1588 EXPECT_TRUE(Check(To));
1591 TEST_P(ASTImporterOptionSpecificTestBase,
1592 TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
1594 Decl *From, *To;
1595 std::tie(From, To) = getImportedDecl(
1597 template<class T>
1598 class Base {};
1599 class declToImport : public Base<declToImport> {};
1601 Lang_CXX03, "", Lang_CXX03);
1603 // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU.
1604 auto Pattern =
1605 translationUnitDecl(unless(has(classTemplateSpecializationDecl())));
1606 ASSERT_TRUE(
1607 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1608 EXPECT_TRUE(
1609 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1611 // Check that the ClassTemplateSpecializationDecl is the child of the
1612 // ClassTemplateDecl.
1613 Pattern = translationUnitDecl(has(classTemplateDecl(
1614 hasName("Base"), has(classTemplateSpecializationDecl()))));
1615 ASSERT_TRUE(
1616 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1617 EXPECT_TRUE(
1618 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1621 AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
1622 size_t Index = 0;
1623 for (Decl *D : Node.decls()) {
1624 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
1625 auto *ND = cast<NamedDecl>(D);
1626 if (Index == Order.size())
1627 return false;
1628 if (ND->getName() != Order[Index])
1629 return false;
1630 ++Index;
1633 return Index == Order.size();
1636 TEST_P(ASTImporterOptionSpecificTestBase,
1637 TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) {
1638 Decl *From, *To;
1639 std::tie(From, To) = getImportedDecl(
1641 namespace NS {
1642 template<class T>
1643 class X {};
1644 template class X<int>;
1647 Lang_CXX03, "", Lang_CXX03, "NS");
1649 // Check that the ClassTemplateSpecializationDecl is NOT the child of the
1650 // ClassTemplateDecl.
1651 auto Pattern = namespaceDecl(has(classTemplateDecl(
1652 hasName("X"), unless(has(classTemplateSpecializationDecl())))));
1653 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1654 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1656 // Check that the ClassTemplateSpecializationDecl is the child of the
1657 // NamespaceDecl.
1658 Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X"))));
1659 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1660 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1663 TEST_P(ASTImporterOptionSpecificTestBase,
1664 CXXRecordDeclFieldsShouldBeInCorrectOrder) {
1665 Decl *From, *To;
1666 std::tie(From, To) =
1667 getImportedDecl(
1668 "struct declToImport { int a; int b; };",
1669 Lang_CXX11, "", Lang_CXX11);
1671 MatchVerifier<Decl> Verifier;
1672 ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1673 EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1676 TEST_P(ASTImporterOptionSpecificTestBase,
1677 CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) {
1678 Decl *From, *To;
1679 std::tie(From, To) = getImportedDecl(
1680 // The original recursive algorithm of ASTImporter first imports 'c' then
1681 // 'b' and lastly 'a'. Therefore we must restore the order somehow.
1682 R"s(
1683 struct declToImport {
1684 int a = c + b;
1685 int b = 1;
1686 int c = 2;
1688 )s",
1689 Lang_CXX11, "", Lang_CXX11);
1691 MatchVerifier<Decl> Verifier;
1692 ASSERT_TRUE(
1693 Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1694 EXPECT_TRUE(
1695 Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1698 TEST_P(ASTImporterOptionSpecificTestBase,
1699 CXXRecordDeclFieldAndIndirectFieldOrder) {
1700 Decl *From, *To;
1701 std::tie(From, To) = getImportedDecl(
1702 // First field is "a", then the field for unnamed union, then "b" and "c"
1703 // from it (indirect fields), then "d".
1704 R"s(
1705 struct declToImport {
1706 int a = d;
1707 union {
1708 int b;
1709 int c;
1711 int d;
1713 )s",
1714 Lang_CXX11, "", Lang_CXX11);
1716 MatchVerifier<Decl> Verifier;
1717 ASSERT_TRUE(Verifier.match(
1718 From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1719 EXPECT_TRUE(Verifier.match(
1720 To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1723 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) {
1724 Decl *From, *To;
1725 std::tie(From, To) = getImportedDecl(
1727 struct declToImport {
1730 Lang_CXX03, "", Lang_CXX03);
1732 MatchVerifier<Decl> Verifier;
1733 // Match the implicit Decl.
1734 auto Matcher = cxxRecordDecl(has(cxxRecordDecl()));
1735 ASSERT_TRUE(Verifier.match(From, Matcher));
1736 EXPECT_TRUE(Verifier.match(To, Matcher));
1739 TEST_P(ASTImporterOptionSpecificTestBase,
1740 ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
1741 Decl *From, *To;
1742 std::tie(From, To) = getImportedDecl(
1744 template <typename U>
1745 struct declToImport {
1748 Lang_CXX03, "", Lang_CXX03);
1750 MatchVerifier<Decl> Verifier;
1751 // Match the implicit Decl.
1752 auto Matcher = classTemplateDecl(has(cxxRecordDecl(has(cxxRecordDecl()))));
1753 ASSERT_TRUE(Verifier.match(From, Matcher));
1754 EXPECT_TRUE(Verifier.match(To, Matcher));
1757 TEST_P(ASTImporterOptionSpecificTestBase,
1758 ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
1759 Decl *From, *To;
1760 std::tie(From, To) = getImportedDecl(
1762 template<class T>
1763 class Base {};
1764 class declToImport : public Base<declToImport> {};
1766 Lang_CXX03, "", Lang_CXX03);
1768 auto hasImplicitClass = has(cxxRecordDecl());
1769 auto Pattern = translationUnitDecl(has(classTemplateDecl(
1770 hasName("Base"),
1771 has(classTemplateSpecializationDecl(hasImplicitClass)))));
1772 ASSERT_TRUE(
1773 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1774 EXPECT_TRUE(
1775 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1778 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) {
1779 Decl *From, *To;
1780 std::tie(From, To) =
1781 getImportedDecl("void declToImport() {}", Lang_CXX03, "", Lang_CXX03);
1783 MatchVerifier<Decl> Verifier;
1784 auto Matcher = functionDecl();
1785 ASSERT_TRUE(Verifier.match(From, Matcher));
1786 EXPECT_TRUE(Verifier.match(To, Matcher));
1787 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1790 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) {
1791 Decl *FromTU = getTuDecl(
1793 struct X {};
1794 void operator<<(int, X);
1796 Lang_CXX03);
1797 Decl *From = LastDeclMatcher<Decl>{}.match(FromTU, functionDecl());
1798 const Decl *To = Import(From, Lang_CXX03);
1799 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1802 TEST_P(ASTImporterOptionSpecificTestBase,
1803 ShouldImportMembersOfClassTemplateSpecializationDecl) {
1804 Decl *From, *To;
1805 std::tie(From, To) = getImportedDecl(
1807 template<class T>
1808 class Base { int a; };
1809 class declToImport : Base<declToImport> {};
1811 Lang_CXX03, "", Lang_CXX03);
1813 auto Pattern = translationUnitDecl(has(classTemplateDecl(
1814 hasName("Base"),
1815 has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a"))))))));
1816 ASSERT_TRUE(
1817 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1818 EXPECT_TRUE(
1819 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1822 TEST_P(ASTImporterOptionSpecificTestBase,
1823 ImportDefinitionOfClassTemplateAfterFwdDecl) {
1825 Decl *FromTU = getTuDecl(
1827 template <typename T>
1828 struct B;
1830 Lang_CXX03, "input0.cc");
1831 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1832 FromTU, classTemplateDecl(hasName("B")));
1834 Import(FromD, Lang_CXX03);
1838 Decl *FromTU = getTuDecl(
1840 template <typename T>
1841 struct B {
1842 void f();
1845 Lang_CXX03, "input1.cc");
1846 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
1847 FromTU, functionDecl(hasName("f")));
1848 Import(FromD, Lang_CXX03);
1849 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
1850 FromTU, classTemplateDecl(hasName("B")));
1851 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
1852 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
1856 TEST_P(ASTImporterOptionSpecificTestBase,
1857 ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) {
1858 Decl *ToTU = getToTuDecl(
1860 template <typename T>
1861 struct B {
1862 void f();
1865 template <typename T>
1866 struct B;
1868 Lang_CXX03);
1869 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1870 [](const ClassTemplateDecl *T) {
1871 return T->isThisDeclarationADefinition();
1873 .match(ToTU, classTemplateDecl()));
1875 Decl *FromTU = getTuDecl(
1877 template <typename T>
1878 struct B {
1879 void f();
1882 Lang_CXX03, "input1.cc");
1883 ClassTemplateDecl *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1884 FromTU, classTemplateDecl(hasName("B")));
1886 Import(FromD, Lang_CXX03);
1888 // We should have only one definition.
1889 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1890 [](const ClassTemplateDecl *T) {
1891 return T->isThisDeclarationADefinition();
1893 .match(ToTU, classTemplateDecl()));
1896 TEST_P(ASTImporterOptionSpecificTestBase,
1897 ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) {
1898 Decl *ToTU = getToTuDecl(
1900 struct B {
1901 void f();
1904 struct B;
1906 Lang_CXX03);
1907 ASSERT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1908 ToTU, cxxRecordDecl(unless(isImplicit()))));
1910 Decl *FromTU = getTuDecl(
1912 struct B {
1913 void f();
1916 Lang_CXX03, "input1.cc");
1917 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
1918 FromTU, cxxRecordDecl(hasName("B")));
1920 Import(FromD, Lang_CXX03);
1922 EXPECT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1923 ToTU, cxxRecordDecl(unless(isImplicit()))));
1926 static void CompareSourceLocs(FullSourceLoc Loc1, FullSourceLoc Loc2) {
1927 EXPECT_EQ(Loc1.getExpansionLineNumber(), Loc2.getExpansionLineNumber());
1928 EXPECT_EQ(Loc1.getExpansionColumnNumber(), Loc2.getExpansionColumnNumber());
1929 EXPECT_EQ(Loc1.getSpellingLineNumber(), Loc2.getSpellingLineNumber());
1930 EXPECT_EQ(Loc1.getSpellingColumnNumber(), Loc2.getSpellingColumnNumber());
1932 static void CompareSourceRanges(SourceRange Range1, SourceRange Range2,
1933 SourceManager &SM1, SourceManager &SM2) {
1934 CompareSourceLocs(FullSourceLoc{ Range1.getBegin(), SM1 },
1935 FullSourceLoc{ Range2.getBegin(), SM2 });
1936 CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 },
1937 FullSourceLoc{ Range2.getEnd(), SM2 });
1939 TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) {
1940 Decl *FromTU = getTuDecl(
1942 #define MFOO(arg) arg = arg + 1
1944 void foo() {
1945 int a = 5;
1946 MFOO(a);
1949 Lang_CXX03);
1950 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1951 auto ToD = Import(FromD, Lang_CXX03);
1953 auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr());
1954 auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr());
1955 auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral());
1956 auto FromRHS =
1957 LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral());
1959 SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1960 SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1961 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1962 FromSM);
1963 CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM,
1964 FromSM);
1965 CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM,
1966 FromSM);
1969 TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) {
1970 Decl *FromTU = getTuDecl(
1972 #define FUNC_INT void declToImport
1973 #define FUNC FUNC_INT
1974 FUNC(int a);
1976 Lang_CXX03);
1977 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1978 auto ToD = Import(FromD, Lang_CXX03);
1980 SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1981 SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1982 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1983 FromSM);
1986 TEST_P(
1987 ASTImporterOptionSpecificTestBase,
1988 ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) {
1989 Decl *ToTU = getToTuDecl(
1991 template <typename T>
1992 struct B;
1994 template <>
1995 struct B<int> {};
1997 template <>
1998 struct B<int>;
2000 Lang_CXX03);
2001 // We should have only one definition.
2002 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
2003 [](const ClassTemplateSpecializationDecl *T) {
2004 return T->isThisDeclarationADefinition();
2006 .match(ToTU, classTemplateSpecializationDecl()));
2008 Decl *FromTU = getTuDecl(
2010 template <typename T>
2011 struct B;
2013 template <>
2014 struct B<int> {};
2016 Lang_CXX03, "input1.cc");
2017 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
2018 FromTU, classTemplateSpecializationDecl(hasName("B")));
2020 Import(FromD, Lang_CXX03);
2022 // We should have only one definition.
2023 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
2024 [](const ClassTemplateSpecializationDecl *T) {
2025 return T->isThisDeclarationADefinition();
2027 .match(ToTU, classTemplateSpecializationDecl()));
2030 TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) {
2031 Decl *FromTU = getTuDecl(
2033 struct { int a; int b; } object0 = { 2, 3 };
2034 struct { int x; int y; int z; } object1;
2036 Lang_CXX03, "input0.cc");
2038 auto *Obj0 =
2039 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object0")));
2040 auto *From0 = getRecordDecl(Obj0);
2041 auto *Obj1 =
2042 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object1")));
2043 auto *From1 = getRecordDecl(Obj1);
2045 auto *To0 = Import(From0, Lang_CXX03);
2046 auto *To1 = Import(From1, Lang_CXX03);
2048 EXPECT_TRUE(To0);
2049 EXPECT_TRUE(To1);
2050 EXPECT_NE(To0, To1);
2051 EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl());
2054 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) {
2055 auto *Code =
2057 struct X {
2058 struct { int a; };
2059 struct { int b; };
2062 Decl *FromTU0 = getTuDecl(Code, Lang_C99, "input0.c");
2064 Decl *FromTU1 = getTuDecl(Code, Lang_C99, "input1.c");
2066 auto *X0 =
2067 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
2068 auto *X1 =
2069 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
2070 Import(X0, Lang_C99);
2071 Import(X1, Lang_C99);
2073 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2074 // We expect no (ODR) warning during the import.
2075 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
2076 EXPECT_EQ(1u,
2077 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
2080 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) {
2081 Decl *FromTU0 = getTuDecl(
2083 struct X {
2084 struct { int a; };
2085 struct { int b; };
2088 Lang_C99, "input0.c");
2090 Decl *FromTU1 = getTuDecl(
2092 struct X { // reversed order
2093 struct { int b; };
2094 struct { int a; };
2097 Lang_C99, "input1.c");
2099 auto *X0 =
2100 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
2101 auto *X1 =
2102 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
2103 Import(X0, Lang_C99);
2104 Import(X1, Lang_C99);
2106 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2107 // We expect one (ODR) warning during the import.
2108 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
2109 EXPECT_EQ(1u,
2110 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
2113 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) {
2114 auto Pattern = varDecl(hasName("x"));
2115 VarDecl *Imported1;
2117 Decl *FromTU = getTuDecl("extern int x;", Lang_CXX03, "input0.cc");
2118 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2119 Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2121 VarDecl *Imported2;
2123 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input1.cc");
2124 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2125 Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2127 EXPECT_EQ(Imported1->getCanonicalDecl(), Imported2->getCanonicalDecl());
2128 EXPECT_FALSE(Imported2->isUsed(false));
2130 Decl *FromTU = getTuDecl("extern int x; int f() { return x; }", Lang_CXX03,
2131 "input2.cc");
2132 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2133 FromTU, functionDecl(hasName("f")));
2134 Import(FromD, Lang_CXX03);
2136 EXPECT_TRUE(Imported2->isUsed(false));
2139 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) {
2140 auto Pattern = varDecl(hasName("x"));
2141 VarDecl *ExistingD;
2143 Decl *ToTU = getToTuDecl("int x = 1;", Lang_CXX03);
2144 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
2146 EXPECT_FALSE(ExistingD->isUsed(false));
2148 Decl *FromTU =
2149 getTuDecl("int x = 1; int f() { return x; }", Lang_CXX03, "input1.cc");
2150 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2151 FromTU, functionDecl(hasName("f")));
2152 Import(FromD, Lang_CXX03);
2154 EXPECT_TRUE(ExistingD->isUsed(false));
2157 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) {
2158 auto Pattern = varDecl(hasName("a"));
2159 VarDecl *ExistingD;
2161 Decl *ToTU = getToTuDecl(
2163 struct A {
2164 static const int a = 1;
2167 Lang_CXX03);
2168 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
2170 EXPECT_FALSE(ExistingD->isUsed(false));
2172 Decl *FromTU = getTuDecl(
2174 struct A {
2175 static const int a = 1;
2177 const int *f() { return &A::a; } // requires storage,
2178 // thus used flag will be set
2180 Lang_CXX03, "input1.cc");
2181 auto *FromFunD = FirstDeclMatcher<FunctionDecl>().match(
2182 FromTU, functionDecl(hasName("f")));
2183 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2184 ASSERT_TRUE(FromD->isUsed(false));
2185 Import(FromFunD, Lang_CXX03);
2187 EXPECT_TRUE(ExistingD->isUsed(false));
2190 TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) {
2191 auto Pattern = varDecl(hasName("x"));
2193 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input0.cc");
2194 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2196 auto *Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2198 ASSERT_FALSE(Imported1->isUsed(false));
2200 FromD->setIsUsed();
2201 auto *Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2203 EXPECT_EQ(Imported1, Imported2);
2204 EXPECT_TRUE(Imported2->isUsed(false));
2207 struct ImportFunctions : ASTImporterOptionSpecificTestBase {};
2209 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
2210 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
2211 auto Pattern = functionDecl(hasName("f"));
2212 auto *From =
2213 FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto
2215 Decl *ImportedD = Import(From, Lang_CXX03);
2216 Decl *ToTU = ImportedD->getTranslationUnitDecl();
2218 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2219 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2220 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2221 EXPECT_TRUE(ImportedD == To0);
2222 EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
2223 EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
2224 EXPECT_EQ(To1->getPreviousDecl(), To0);
2227 TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) {
2228 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
2229 auto Pattern = functionDecl(hasName("f"));
2230 auto *From =
2231 LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def
2233 Decl *ImportedD = Import(From, Lang_CXX03);
2234 Decl *ToTU = ImportedD->getTranslationUnitDecl();
2236 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2237 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2238 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2239 EXPECT_TRUE(ImportedD == To1);
2240 EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
2241 EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
2242 EXPECT_EQ(To1->getPreviousDecl(), To0);
2245 TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) {
2246 auto Code =
2248 struct B { virtual void f(); };
2249 void B::f() {}
2250 struct D : B { void f(); };
2252 auto Pattern =
2253 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2254 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2255 CXXMethodDecl *Proto =
2256 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2258 ASSERT_EQ(Proto->size_overridden_methods(), 1u);
2259 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
2260 EXPECT_EQ(To->size_overridden_methods(), 1u);
2263 TEST_P(ImportFunctions, VirtualFlagShouldBePreservedWhenImportingPrototype) {
2264 auto Code =
2266 struct B { virtual void f(); };
2267 void B::f() {}
2269 auto Pattern =
2270 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2271 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2272 CXXMethodDecl *Proto =
2273 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2274 CXXMethodDecl *Def = LastDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2276 ASSERT_TRUE(Proto->isVirtual());
2277 ASSERT_TRUE(Def->isVirtual());
2278 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
2279 EXPECT_TRUE(To->isVirtual());
2282 TEST_P(ImportFunctions,
2283 ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) {
2284 Decl *ToTU = getToTuDecl(
2286 void f() {}
2287 void f();
2289 Lang_CXX03);
2290 ASSERT_EQ(1u,
2291 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
2292 return FD->doesThisDeclarationHaveABody();
2293 }).match(ToTU, functionDecl()));
2295 Decl *FromTU = getTuDecl("void f() {}", Lang_CXX03, "input0.cc");
2296 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
2298 Import(FromD, Lang_CXX03);
2300 EXPECT_EQ(1u,
2301 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
2302 return FD->doesThisDeclarationHaveABody();
2303 }).match(ToTU, functionDecl()));
2306 TEST_P(ImportFunctions, ImportOverriddenMethodTwice) {
2307 auto Code =
2309 struct B { virtual void f(); };
2310 struct D:B { void f(); };
2312 auto BFP =
2313 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2314 auto DFP =
2315 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2317 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
2318 auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2319 Import(DF, Lang_CXX03);
2321 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2322 auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
2323 Import(BF, Lang_CXX03);
2325 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2327 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2328 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2331 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) {
2332 auto CodeWithoutDef =
2334 struct B { virtual void f(); };
2335 struct D:B { void f(); };
2337 auto CodeWithDef =
2339 struct B { virtual void f(){}; };
2340 struct D:B { void f(){}; };
2342 auto BFP =
2343 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2344 auto DFP =
2345 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2346 auto BFDefP = cxxMethodDecl(
2347 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2348 auto DFDefP = cxxMethodDecl(
2349 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
2350 auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition());
2353 Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX03, "input0.cc");
2354 auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP);
2355 Import(FromD, Lang_CXX03);
2358 Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX03, "input1.cc");
2359 auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP);
2360 Import(FromB, Lang_CXX03);
2363 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2365 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2366 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2367 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u);
2368 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u);
2369 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u);
2372 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) {
2373 auto Code =
2375 struct B { virtual void f(); };
2376 struct D:B { void f(); };
2377 void B::f(){};
2380 auto BFP =
2381 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2382 auto BFDefP = cxxMethodDecl(
2383 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2384 auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))),
2385 unless(isDefinition()));
2387 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
2388 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2389 Import(D, Lang_CXX03);
2391 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2392 auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
2393 Import(B, Lang_CXX03);
2395 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2397 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2398 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2400 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2401 ToTU, cxxRecordDecl(hasName("B")));
2402 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2403 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2404 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2406 // The definition should be out-of-class.
2407 EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2408 EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2409 ToBFOutOfClass->getLexicalDeclContext());
2410 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2411 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2413 // Check that the redecl chain is intact.
2414 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2417 TEST_P(ImportFunctions,
2418 ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) {
2419 auto CodeTU0 =
2421 struct B { virtual void f(); };
2422 struct D:B { void f(); };
2424 auto CodeTU1 =
2426 struct B { virtual void f(); };
2427 struct D:B { void f(); };
2428 void B::f(){}
2429 void D::f(){}
2430 void foo(B &b, D &d) { b.f(); d.f(); }
2433 auto BFP =
2434 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2435 auto BFDefP = cxxMethodDecl(
2436 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2437 auto DFP =
2438 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2439 auto DFDefP = cxxMethodDecl(
2440 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
2441 auto FooDef = functionDecl(hasName("foo"));
2444 Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX03, "input0.cc");
2445 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2446 Import(D, Lang_CXX03);
2450 Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX03, "input1.cc");
2451 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef);
2452 Import(Foo, Lang_CXX03);
2455 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2457 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2458 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2459 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2460 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u);
2462 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2463 ToTU, cxxRecordDecl(hasName("B")));
2464 auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match(
2465 ToTU, cxxRecordDecl(hasName("D")));
2466 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2467 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2468 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2469 auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP);
2470 auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match(
2471 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2473 // The definition should be out-of-class.
2474 EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2475 EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2476 ToBFOutOfClass->getLexicalDeclContext());
2477 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2478 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2480 EXPECT_NE(ToDFInClass, ToDFOutOfClass);
2481 EXPECT_NE(ToDFInClass->getLexicalDeclContext(),
2482 ToDFOutOfClass->getLexicalDeclContext());
2483 EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD);
2484 EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU);
2486 // Check that the redecl chain is intact.
2487 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2488 EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass);
2491 TEST_P(ASTImporterOptionSpecificTestBase,
2492 ImportVirtualOverriddenMethodOnALoop) {
2493 // B::f() calls => f1() ==> C ==> C::f()
2494 // \
2495 // \---- A::f()
2497 // C::f()'s ImportOverriddenMethods() asserts B::isVirtual(), so B::f()'s
2498 // ImportOverriddenMethods() should be completed before B::f()'s body
2499 const char *Code =
2501 void f1();
2502 class A {
2503 virtual void f(){}
2505 class B: public A {
2506 void f() override {
2507 f1();
2510 class C: public B {
2511 void f() override {}
2513 void f1() { C c; }
2515 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
2517 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
2518 FromTU, cxxMethodDecl(hasName("B::f")));
2520 auto *ToBF = Import(FromF, Lang_CXX11);
2521 EXPECT_TRUE(ToBF->isVirtual());
2523 auto *ToCF = FirstDeclMatcher<CXXMethodDecl>().match(
2524 ToBF->getTranslationUnitDecl(), cxxMethodDecl(hasName("C::f")));
2525 EXPECT_TRUE(ToCF->isVirtual());
2528 TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) {
2529 std::string Code = "static int v; static int v = 0;";
2530 auto Pattern = varDecl(hasName("v"));
2532 TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C99, "input0.c");
2534 auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern);
2535 auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern);
2537 auto *To0 = Import(From0, Lang_C99);
2538 auto *To1 = Import(From1, Lang_C99);
2540 EXPECT_TRUE(To0);
2541 ASSERT_TRUE(To1);
2542 EXPECT_NE(To0, To1);
2543 EXPECT_EQ(To1->getPreviousDecl(), To0);
2546 TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) {
2547 TranslationUnitDecl *FromTu =
2548 getTuDecl("namespace NS0 { namespace { void f(); } }"
2549 "namespace NS1 { namespace { void f(); } }",
2550 Lang_CXX03, "input0.cc");
2551 auto Pattern = functionDecl(hasName("f"));
2553 auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2554 auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2556 auto *ToF0 = Import(FromF0, Lang_CXX03);
2557 auto *ToF1 = Import(FromF1, Lang_CXX03);
2559 EXPECT_TRUE(ToF0);
2560 ASSERT_TRUE(ToF1);
2561 EXPECT_NE(ToF0, ToF1);
2562 EXPECT_FALSE(ToF1->getPreviousDecl());
2565 TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) {
2567 Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }",
2568 Lang_CXX03, "input0.cc");
2569 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2570 FromTU, functionDecl(hasName("g0")));
2572 Import(FromD, Lang_CXX03);
2575 Decl *FromTU =
2576 getTuDecl("namespace { void f() { int a; } } void g1() { f(); }",
2577 Lang_CXX03, "input1.cc");
2578 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2579 FromTU, functionDecl(hasName("g1")));
2580 Import(FromD, Lang_CXX03);
2583 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2584 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
2585 2u);
2588 TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) {
2589 Decl *FromTU = getTuDecl(
2591 void foo() {
2592 (void)[]() { ; };
2595 Lang_CXX11);
2596 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2597 FromTU, functionDecl(hasName("foo")));
2598 auto *ToD = Import(FromD, Lang_CXX03);
2599 EXPECT_TRUE(ToD);
2600 CXXRecordDecl *LambdaRec =
2601 cast<LambdaExpr>(cast<CStyleCastExpr>(
2602 *cast<CompoundStmt>(ToD->getBody())->body_begin())
2603 ->getSubExpr())
2604 ->getLambdaClass();
2605 EXPECT_TRUE(LambdaRec->getDestructor());
2608 TEST_P(ImportFunctions,
2609 CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2610 Decl *FromTU = getTuDecl(
2612 struct X {
2613 template <typename T>
2614 void foo(){}
2616 void f() {
2617 X x;
2618 x.foo<int>();
2621 Lang_CXX03);
2622 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2623 FromTU, functionDecl(hasName("f")));
2624 auto *ToD = Import(FromD, Lang_CXX03);
2625 EXPECT_TRUE(ToD);
2626 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
2627 ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr()))));
2630 TEST_P(ImportFunctions,
2631 DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2632 Decl *FromTU = getTuDecl(
2634 struct X {
2635 template <typename T>
2636 void foo(){}
2638 template <typename T>
2639 void f() {
2640 X x;
2641 x.foo<T>();
2643 void g() {
2644 f<int>();
2647 Lang_CXX03);
2648 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2649 FromTU, functionDecl(hasName("g")));
2650 auto *ToD = Import(FromD, Lang_CXX03);
2651 EXPECT_TRUE(ToD);
2652 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2653 EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match(
2654 ToTU, translationUnitDecl(hasDescendant(
2655 functionDecl(hasName("f"), hasDescendant(declRefExpr()))))));
2658 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {};
2660 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) {
2661 auto Code =
2663 class X {
2664 template <class T>
2665 void f(T t);
2668 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2669 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2670 FromTU1, functionTemplateDecl(hasName("f")));
2671 auto *ToD1 = Import(FromD1, Lang_CXX03);
2672 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2673 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2674 FromTU2, functionTemplateDecl(hasName("f")));
2675 auto *ToD2 = Import(FromD2, Lang_CXX03);
2676 EXPECT_EQ(ToD1, ToD2);
2679 TEST_P(ImportFunctionTemplates,
2680 ImportFunctionTemplateWithDefInRecordDeclTwice) {
2681 auto Code =
2683 class X {
2684 template <class T>
2685 void f(T t);
2687 template <class T>
2688 void X::f(T t) {};
2690 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2691 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2692 FromTU1, functionTemplateDecl(hasName("f")));
2693 auto *ToD1 = Import(FromD1, Lang_CXX03);
2694 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2695 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2696 FromTU2, functionTemplateDecl(hasName("f")));
2697 auto *ToD2 = Import(FromD2, Lang_CXX03);
2698 EXPECT_EQ(ToD1, ToD2);
2701 TEST_P(ImportFunctionTemplates,
2702 ImportFunctionWhenThereIsAFunTemplateWithSameName) {
2703 getToTuDecl(
2705 template <typename T>
2706 void foo(T) {}
2707 void foo();
2709 Lang_CXX03);
2710 Decl *FromTU = getTuDecl("void foo();", Lang_CXX03);
2711 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2712 FromTU, functionDecl(hasName("foo")));
2713 auto *ImportedD = Import(FromD, Lang_CXX03);
2714 EXPECT_TRUE(ImportedD);
2717 TEST_P(ImportFunctionTemplates,
2718 ImportConstructorWhenThereIsAFunTemplateWithSameName) {
2719 auto Code =
2721 struct Foo {
2722 template <typename T>
2723 Foo(T) {}
2724 Foo();
2727 getToTuDecl(Code, Lang_CXX03);
2728 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2729 auto *FromD =
2730 LastDeclMatcher<CXXConstructorDecl>().match(FromTU, cxxConstructorDecl());
2731 auto *ImportedD = Import(FromD, Lang_CXX03);
2732 EXPECT_TRUE(ImportedD);
2735 TEST_P(ImportFunctionTemplates,
2736 ImportOperatorWhenThereIsAFunTemplateWithSameName) {
2737 getToTuDecl(
2739 template <typename T>
2740 void operator<(T,T) {}
2741 struct X{};
2742 void operator<(X, X);
2744 Lang_CXX03);
2745 Decl *FromTU = getTuDecl(
2747 struct X{};
2748 void operator<(X, X);
2750 Lang_CXX03);
2751 auto *FromD = LastDeclMatcher<FunctionDecl>().match(
2752 FromTU, functionDecl(hasOverloadedOperatorName("<")));
2753 auto *ImportedD = Import(FromD, Lang_CXX03);
2754 EXPECT_TRUE(ImportedD);
2757 struct ImportFriendFunctions : ImportFunctions {};
2759 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {
2760 auto Pattern = functionDecl(hasName("f"));
2762 Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2763 "void f();",
2764 Lang_CXX03, "input0.cc");
2765 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2767 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2768 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2769 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2770 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2771 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2772 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2773 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2776 TEST_P(ImportFriendFunctions,
2777 ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) {
2778 auto Pattern = functionDecl(hasName("f"));
2780 Decl *FromTU = getTuDecl("void f();"
2781 "struct X { friend void f(); };",
2782 Lang_CXX03, "input0.cc");
2783 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2785 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2786 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2787 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2788 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2789 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2790 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2791 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2794 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) {
2795 auto Pattern = functionDecl(hasName("f"));
2797 Decl *FromTU = getTuDecl("struct X { friend void f(){} };"
2798 "void f();",
2799 Lang_CXX03, "input0.cc");
2800 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2802 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2803 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2804 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2805 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2806 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2807 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2808 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2811 TEST_P(ImportFriendFunctions,
2812 ImportFriendFunctionRedeclChainDef_OutOfClassDef) {
2813 auto Pattern = functionDecl(hasName("f"));
2815 Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2816 "void f(){}",
2817 Lang_CXX03, "input0.cc");
2818 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2820 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2821 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2822 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2823 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2824 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2825 EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody());
2826 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2829 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) {
2830 auto Pattern = functionDecl(hasName("f"));
2832 Decl *FromTU = getTuDecl(
2834 class X;
2835 void f(X *x){}
2836 class X{
2837 friend void f(X *x);
2840 Lang_CXX03, "input0.cc");
2841 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2843 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2844 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2845 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2846 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2847 auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>()
2848 .match(ToTU, friendDecl())
2849 ->getFriendDecl());
2850 EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody());
2851 EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD);
2852 // The parameters must refer the same type
2853 EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(),
2854 (*ImportedD->param_begin())->getOriginalType());
2857 TEST_P(ImportFriendFunctions,
2858 ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) {
2859 auto Pattern = functionDecl(hasName("f"));
2861 Decl *FromTU = getTuDecl(
2863 class X;
2864 void f(X *x){}
2865 class X{
2866 friend void f(X *x);
2869 Lang_CXX03, "input0.cc");
2870 auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2872 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2873 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2874 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2875 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2876 auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match(
2877 ToTU, functionDecl(unless(hasParent(friendDecl()))));
2879 EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody());
2880 EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD);
2881 // The parameters must refer the same type
2882 EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(),
2883 (*ImportedD->param_begin())->getOriginalType());
2886 TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) {
2887 auto Pattern = functionDecl(hasName("f"));
2889 FunctionDecl *ImportedD;
2891 Decl *FromTU =
2892 getTuDecl("struct X { friend void f(){} };", Lang_CXX03, "input0.cc");
2893 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2894 ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2896 FunctionDecl *ImportedD1;
2898 Decl *FromTU = getTuDecl("void f();", Lang_CXX03, "input1.cc");
2899 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2900 ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2903 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2904 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2905 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2906 EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody());
2907 EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD);
2910 TEST_P(ImportFriendFunctions, Lookup) {
2911 auto FunctionPattern = functionDecl(hasName("f"));
2912 auto ClassPattern = cxxRecordDecl(hasName("X"));
2914 TranslationUnitDecl *FromTU =
2915 getTuDecl("struct X { friend void f(); };", Lang_CXX03, "input0.cc");
2916 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2917 ASSERT_TRUE(FromD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2918 ASSERT_FALSE(FromD->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2920 auto FromName = FromD->getDeclName();
2921 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2922 auto LookupRes = Class->noload_lookup(FromName);
2923 ASSERT_TRUE(LookupRes.empty());
2924 LookupRes = FromTU->noload_lookup(FromName);
2925 ASSERT_TRUE(LookupRes.isSingleResult());
2928 auto *ToD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2929 auto ToName = ToD->getDeclName();
2931 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2932 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2933 auto LookupRes = Class->noload_lookup(ToName);
2934 EXPECT_TRUE(LookupRes.empty());
2935 LookupRes = ToTU->noload_lookup(ToName);
2936 EXPECT_TRUE(LookupRes.isSingleResult());
2938 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 1u);
2939 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2940 EXPECT_TRUE(To0->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2941 EXPECT_FALSE(To0->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2944 TEST_P(ImportFriendFunctions, LookupWithProtoAfter) {
2945 auto FunctionPattern = functionDecl(hasName("f"));
2946 auto ClassPattern = cxxRecordDecl(hasName("X"));
2948 TranslationUnitDecl *FromTU =
2949 getTuDecl("struct X { friend void f(); };"
2950 // This proto decl makes f available to normal
2951 // lookup, otherwise it is hidden.
2952 // Normal C++ lookup (implemented in
2953 // `clang::Sema::CppLookupName()` and in `LookupDirect()`)
2954 // returns the found `NamedDecl` only if the set IDNS is matched
2955 "void f();",
2956 Lang_CXX03, "input0.cc");
2957 auto *FromFriend =
2958 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2959 auto *FromNormal =
2960 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2961 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2962 ASSERT_FALSE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2963 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2964 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2966 auto FromName = FromFriend->getDeclName();
2967 auto *FromClass =
2968 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2969 auto LookupRes = FromClass->noload_lookup(FromName);
2970 ASSERT_TRUE(LookupRes.empty());
2971 LookupRes = FromTU->noload_lookup(FromName);
2972 ASSERT_TRUE(LookupRes.isSingleResult());
2974 auto *ToFriend = cast<FunctionDecl>(Import(FromFriend, Lang_CXX03));
2975 auto ToName = ToFriend->getDeclName();
2977 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2978 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2979 LookupRes = ToClass->noload_lookup(ToName);
2980 EXPECT_TRUE(LookupRes.empty());
2981 LookupRes = ToTU->noload_lookup(ToName);
2982 // Test is disabled because this result is 2.
2983 EXPECT_TRUE(LookupRes.isSingleResult());
2985 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
2986 ToFriend = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2987 auto *ToNormal = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2988 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2989 EXPECT_FALSE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2990 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2991 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2994 TEST_P(ImportFriendFunctions, LookupWithProtoBefore) {
2995 auto FunctionPattern = functionDecl(hasName("f"));
2996 auto ClassPattern = cxxRecordDecl(hasName("X"));
2998 TranslationUnitDecl *FromTU = getTuDecl("void f();"
2999 "struct X { friend void f(); };",
3000 Lang_CXX03, "input0.cc");
3001 auto *FromNormal =
3002 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
3003 auto *FromFriend =
3004 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
3005 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3006 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3007 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3008 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3010 auto FromName = FromNormal->getDeclName();
3011 auto *FromClass =
3012 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
3013 auto LookupRes = FromClass->noload_lookup(FromName);
3014 ASSERT_TRUE(LookupRes.empty());
3015 LookupRes = FromTU->noload_lookup(FromName);
3016 ASSERT_TRUE(LookupRes.isSingleResult());
3018 auto *ToNormal = cast<FunctionDecl>(Import(FromNormal, Lang_CXX03));
3019 auto ToName = ToNormal->getDeclName();
3020 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3022 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
3023 LookupRes = ToClass->noload_lookup(ToName);
3024 EXPECT_TRUE(LookupRes.empty());
3025 LookupRes = ToTU->noload_lookup(ToName);
3026 EXPECT_TRUE(LookupRes.isSingleResult());
3028 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
3029 ToNormal = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
3030 auto *ToFriend = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
3031 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3032 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3033 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3034 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3037 TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) {
3038 auto Pattern = functionDecl(hasName("f"));
3040 TranslationUnitDecl *FromNormalTU =
3041 getTuDecl("void f();", Lang_CXX03, "input0.cc");
3042 auto *FromNormalF =
3043 FirstDeclMatcher<FunctionDecl>().match(FromNormalTU, Pattern);
3044 TranslationUnitDecl *FromFriendTU =
3045 getTuDecl("class X { friend void f(); };", Lang_CXX03, "input1.cc");
3046 auto *FromFriendF =
3047 FirstDeclMatcher<FunctionDecl>().match(FromFriendTU, Pattern);
3048 auto FromNormalName = FromNormalF->getDeclName();
3049 auto FromFriendName = FromFriendF->getDeclName();
3051 ASSERT_TRUE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3052 ASSERT_FALSE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3053 ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3054 ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3055 auto LookupRes = FromNormalTU->noload_lookup(FromNormalName);
3056 ASSERT_TRUE(LookupRes.isSingleResult());
3057 LookupRes = FromFriendTU->noload_lookup(FromFriendName);
3058 ASSERT_TRUE(LookupRes.isSingleResult());
3060 auto *ToNormalF = cast<FunctionDecl>(Import(FromNormalF, Lang_CXX03));
3061 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3062 auto ToName = ToNormalF->getDeclName();
3063 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3064 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3065 LookupRes = ToTU->noload_lookup(ToName);
3066 EXPECT_TRUE(LookupRes.isSingleResult());
3067 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
3069 auto *ToFriendF = cast<FunctionDecl>(Import(FromFriendF, Lang_CXX03));
3070 LookupRes = ToTU->noload_lookup(ToName);
3071 EXPECT_TRUE(LookupRes.isSingleResult());
3072 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
3074 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3075 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3077 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3078 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3081 TEST_P(ImportFriendFunctions, ImportFriendList) {
3082 TranslationUnitDecl *FromTU = getTuDecl("struct X { friend void f(); };"
3083 "void f();",
3084 Lang_CXX03, "input0.cc");
3085 auto *FromFriendF = FirstDeclMatcher<FunctionDecl>().match(
3086 FromTU, functionDecl(hasName("f")));
3088 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
3089 FromTU, cxxRecordDecl(hasName("X")));
3090 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl());
3091 auto FromFriends = FromClass->friends();
3092 unsigned int FrN = 0;
3093 for (auto Fr : FromFriends) {
3094 ASSERT_EQ(Fr, FromFriend);
3095 ++FrN;
3097 ASSERT_EQ(FrN, 1u);
3099 Import(FromFriendF, Lang_CXX03);
3100 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3101 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
3102 ToTU, cxxRecordDecl(hasName("X")));
3103 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
3104 auto ToFriends = ToClass->friends();
3105 FrN = 0;
3106 for (auto Fr : ToFriends) {
3107 EXPECT_EQ(Fr, ToFriend);
3108 ++FrN;
3110 EXPECT_EQ(FrN, 1u);
3113 AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>,
3114 InnerMatcher) {
3115 if (auto *Typedef = Node.getTypedefNameForAnonDecl())
3116 return InnerMatcher.matches(*Typedef, Finder, Builder);
3117 return false;
3120 TEST_P(ImportDecl, ImportEnumSequential) {
3121 CodeFiles Samples{{"main.c",
3122 {"void foo();"
3123 "void moo();"
3124 "int main() { foo(); moo(); }",
3125 Lang_C99}},
3127 {"foo.c",
3128 {"typedef enum { THING_VALUE } thing_t;"
3129 "void conflict(thing_t type);"
3130 "void foo() { (void)THING_VALUE; }"
3131 "void conflict(thing_t type) {}",
3132 Lang_C99}},
3134 {"moo.c",
3135 {"typedef enum { THING_VALUE } thing_t;"
3136 "void conflict(thing_t type);"
3137 "void moo() { conflict(THING_VALUE); }",
3138 Lang_C99}}};
3140 auto VerificationMatcher =
3141 enumDecl(has(enumConstantDecl(hasName("THING_VALUE"))),
3142 hasTypedefForAnonDecl(hasName("thing_t")));
3144 ImportAction ImportFoo{"foo.c", "main.c", functionDecl(hasName("foo"))},
3145 ImportMoo{"moo.c", "main.c", functionDecl(hasName("moo"))};
3147 testImportSequence(
3148 Samples, {ImportFoo, ImportMoo}, // "foo", them "moo".
3149 // Just check that there is only one enum decl in the result AST.
3150 "main.c", enumDecl(), VerificationMatcher);
3152 // For different import order, result should be the same.
3153 testImportSequence(
3154 Samples, {ImportMoo, ImportFoo}, // "moo", them "foo".
3155 // Check that there is only one enum decl in the result AST.
3156 "main.c", enumDecl(), VerificationMatcher);
3159 TEST_P(ImportDecl, ImportFieldOrder) {
3160 MatchVerifier<Decl> Verifier;
3161 testImport("struct declToImport {"
3162 " int b = a + 2;"
3163 " int a = 5;"
3164 "};",
3165 Lang_CXX11, "", Lang_CXX11, Verifier,
3166 recordDecl(hasFieldOrder({"b", "a"})));
3169 const internal::VariadicDynCastAllOfMatcher<Expr, DependentScopeDeclRefExpr>
3170 dependentScopeDeclRefExpr;
3172 TEST_P(ImportExpr, DependentScopeDeclRefExpr) {
3173 MatchVerifier<Decl> Verifier;
3174 testImport("template <typename T> struct S { static T foo; };"
3175 "template <typename T> void declToImport() {"
3176 " (void) S<T>::foo;"
3178 "void instantiate() { declToImport<int>(); }"
3179 "template <typename T> T S<T>::foo;",
3180 Lang_CXX11, "", Lang_CXX11, Verifier,
3181 functionTemplateDecl(has(functionDecl(has(compoundStmt(
3182 has(cStyleCastExpr(has(dependentScopeDeclRefExpr())))))))));
3184 testImport("template <typename T> struct S {"
3185 "template<typename S> static void foo(){};"
3186 "};"
3187 "template <typename T> void declToImport() {"
3188 " S<T>::template foo<T>();"
3190 "void instantiate() { declToImport<int>(); }",
3191 Lang_CXX11, "", Lang_CXX11, Verifier,
3192 functionTemplateDecl(has(functionDecl(has(compoundStmt(
3193 has(callExpr(has(dependentScopeDeclRefExpr())))))))));
3196 const internal::VariadicDynCastAllOfMatcher<Type, DependentNameType>
3197 dependentNameType;
3199 TEST_P(ImportExpr, DependentNameType) {
3200 MatchVerifier<Decl> Verifier;
3201 testImport("template <typename T> struct declToImport {"
3202 " typedef typename T::type dependent_name;"
3203 "};",
3204 Lang_CXX11, "", Lang_CXX11, Verifier,
3205 classTemplateDecl(has(
3206 cxxRecordDecl(has(typedefDecl(has(dependentNameType())))))));
3209 TEST_P(ImportExpr, UnresolvedMemberExpr) {
3210 MatchVerifier<Decl> Verifier;
3211 testImport("struct S { template <typename T> void mem(); };"
3212 "template <typename U> void declToImport() {"
3213 " S s;"
3214 " s.mem<U>();"
3216 "void instantiate() { declToImport<int>(); }",
3217 Lang_CXX11, "", Lang_CXX11, Verifier,
3218 functionTemplateDecl(has(functionDecl(has(
3219 compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
3222 class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
3223 public:
3224 static constexpr auto DefaultCode = R"(
3225 struct A { int x; };
3226 void f() {
3227 A a;
3228 A a1(a);
3229 A a2(A{});
3230 a = a1;
3231 a = A{};
3232 a.~A();
3233 })";
3235 template <typename MatcherType>
3236 void testImportOf(
3237 const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
3238 test(MethodMatcher, Code, /*ExpectedCount=*/1u);
3241 template <typename MatcherType>
3242 void testNoImportOf(
3243 const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
3244 test(MethodMatcher, Code, /*ExpectedCount=*/0u);
3247 private:
3248 template <typename MatcherType>
3249 void test(const MatcherType &MethodMatcher,
3250 const char *Code, unsigned int ExpectedCount) {
3251 auto ClassMatcher = cxxRecordDecl(unless(isImplicit()));
3253 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3254 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
3255 ToTU, ClassMatcher);
3257 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1u);
3260 CXXMethodDecl *Method =
3261 FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher);
3262 ToClass->removeDecl(Method);
3263 SharedStatePtr->getLookupTable()->remove(Method);
3266 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0u);
3268 Decl *ImportedClass = nullptr;
3270 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc");
3271 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
3272 FromTU, ClassMatcher);
3273 ImportedClass = Import(FromClass, Lang_CXX11);
3276 EXPECT_EQ(ToClass, ImportedClass);
3277 EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher),
3278 ExpectedCount);
3282 TEST_P(ImportImplicitMethods, DefaultConstructor) {
3283 testImportOf(cxxConstructorDecl(isDefaultConstructor()));
3286 TEST_P(ImportImplicitMethods, CopyConstructor) {
3287 testImportOf(cxxConstructorDecl(isCopyConstructor()));
3290 TEST_P(ImportImplicitMethods, MoveConstructor) {
3291 testImportOf(cxxConstructorDecl(isMoveConstructor()));
3294 TEST_P(ImportImplicitMethods, Destructor) {
3295 testImportOf(cxxDestructorDecl());
3298 TEST_P(ImportImplicitMethods, CopyAssignment) {
3299 testImportOf(cxxMethodDecl(isCopyAssignmentOperator()));
3302 TEST_P(ImportImplicitMethods, MoveAssignment) {
3303 testImportOf(cxxMethodDecl(isMoveAssignmentOperator()));
3306 TEST_P(ImportImplicitMethods, DoNotImportUserProvided) {
3307 auto Code = R"(
3308 struct A { A() { int x; } };
3310 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3313 TEST_P(ImportImplicitMethods, DoNotImportDefault) {
3314 auto Code = R"(
3315 struct A { A() = default; };
3317 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3320 TEST_P(ImportImplicitMethods, DoNotImportDeleted) {
3321 auto Code = R"(
3322 struct A { A() = delete; };
3324 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3327 TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) {
3328 auto Code = R"(
3329 struct A { void f() { } };
3331 testNoImportOf(cxxMethodDecl(hasName("f")), Code);
3334 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) {
3335 Decl *ToR1;
3337 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input0.cc");
3338 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3339 FromTU, cxxRecordDecl(hasName("A")));
3341 ToR1 = Import(FromR, Lang_CXX03);
3344 Decl *ToR2;
3346 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input1.cc");
3347 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3348 FromTU, cxxRecordDecl(hasName("A")));
3350 ToR2 = Import(FromR, Lang_CXX03);
3353 EXPECT_EQ(ToR1, ToR2);
3356 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) {
3357 Decl *ToR1;
3359 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3360 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3361 FromTU, cxxRecordDecl(hasName("A")));
3362 ToR1 = Import(FromR, Lang_CXX03);
3364 Decl *ToR2;
3366 Decl *FromTU =
3367 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
3368 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3369 FromTU, cxxRecordDecl(hasName("A")));
3370 ToR2 = Import(FromR, Lang_CXX03);
3372 EXPECT_NE(ToR1, ToR2);
3375 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) {
3376 Decl *ToF1;
3378 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3379 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3380 FromTU, fieldDecl(hasName("x")));
3381 ToF1 = Import(FromF, Lang_CXX03);
3383 Decl *ToF2;
3385 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input1.cc");
3386 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3387 FromTU, fieldDecl(hasName("x")));
3388 ToF2 = Import(FromF, Lang_CXX03);
3390 EXPECT_EQ(ToF1, ToF2);
3393 TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) {
3394 Decl *FromTU = getTuDecl("struct A { unsigned x : 3; };", Lang_CXX03);
3395 auto *FromF =
3396 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x")));
3398 ASSERT_TRUE(FromF->isBitField());
3399 ASSERT_EQ(3u, FromF->getBitWidthValue(FromTU->getASTContext()));
3400 auto *ToField = Import(FromF, Lang_CXX03);
3401 auto *ToTU = ToField->getTranslationUnitDecl();
3403 EXPECT_TRUE(ToField->isBitField());
3404 EXPECT_EQ(3u, ToField->getBitWidthValue(ToTU->getASTContext()));
3406 const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>();
3407 const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>();
3408 ASSERT_TRUE(FromBT);
3409 ASSERT_EQ(BuiltinType::Int, FromBT->getKind());
3410 EXPECT_TRUE(ToBT);
3411 EXPECT_EQ(BuiltinType::Int, ToBT->getKind());
3414 struct ImportBlock : ASTImporterOptionSpecificTestBase {};
3415 TEST_P(ImportBlock, ImportBlocksAreUnsupported) {
3416 const auto *Code = R"(
3417 void test_block__capture_null() {
3418 int *p = 0;
3419 ^(){
3420 *p = 1;
3421 }();
3422 })";
3423 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
3424 auto *FromBlock = FirstDeclMatcher<BlockDecl>().match(FromTU, blockDecl());
3425 ASSERT_TRUE(FromBlock);
3427 auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03);
3429 const auto ExpectUnsupportedConstructError = [](const ASTImportError &Error) {
3430 EXPECT_EQ(ASTImportError::UnsupportedConstruct, Error.Error);
3432 llvm::handleAllErrors(ToBlockOrError.takeError(),
3433 ExpectUnsupportedConstructError);
3436 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl) {
3437 const auto *Code = R"(
3438 template <typename T> struct Wrapper {
3439 Wrapper(T Value = {}) {}
3441 template class Wrapper<int>;
3443 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3444 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match(
3445 FromTU, parmVarDecl(hasType(asString("int"))));
3446 ASSERT_TRUE(FromVar);
3447 ASSERT_TRUE(FromVar->hasUninstantiatedDefaultArg());
3448 ASSERT_TRUE(FromVar->getUninstantiatedDefaultArg());
3450 const auto *ToVar = Import(FromVar, Lang_CXX11);
3451 EXPECT_TRUE(ToVar);
3452 EXPECT_TRUE(ToVar->hasUninstantiatedDefaultArg());
3453 EXPECT_TRUE(ToVar->getUninstantiatedDefaultArg());
3454 EXPECT_NE(FromVar->getUninstantiatedDefaultArg(),
3455 ToVar->getUninstantiatedDefaultArg());
3458 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) {
3459 Decl *ToF1;
3461 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3462 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3463 FromTU, fieldDecl(hasName("x")));
3464 ToF1 = Import(FromF, Lang_CXX03);
3466 Decl *ToF2;
3468 Decl *FromTU =
3469 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
3470 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3471 FromTU, fieldDecl(hasName("x")));
3472 ToF2 = Import(FromF, Lang_CXX03);
3474 EXPECT_NE(ToF1, ToF2);
3477 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) {
3478 Decl *ToM1;
3480 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3481 Lang_CXX03, "input0.cc");
3482 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3483 FromTU, functionDecl(hasName("x"), isDefinition()));
3484 ToM1 = Import(FromM, Lang_CXX03);
3486 Decl *ToM2;
3488 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3489 Lang_CXX03, "input1.cc");
3490 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3491 FromTU, functionDecl(hasName("x"), isDefinition()));
3492 ToM2 = Import(FromM, Lang_CXX03);
3494 EXPECT_EQ(ToM1, ToM2);
3497 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) {
3498 Decl *ToM1;
3500 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3501 Lang_CXX03, "input0.cc");
3502 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3503 FromTU, functionDecl(hasName("x"), isDefinition()));
3504 ToM1 = Import(FromM, Lang_CXX03);
3506 Decl *ToM2;
3508 Decl *FromTU =
3509 getTuDecl("struct A { void x() const; }; void A::x() const { }",
3510 Lang_CXX03, "input1.cc");
3511 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3512 FromTU, functionDecl(hasName("x"), isDefinition()));
3513 ToM2 = Import(FromM, Lang_CXX03);
3515 EXPECT_NE(ToM1, ToM2);
3518 TEST_P(ASTImporterOptionSpecificTestBase,
3519 ImportUnnamedStructsWithRecursingField) {
3520 Decl *FromTU = getTuDecl(
3522 struct A {
3523 struct {
3524 struct A *next;
3525 } entry0;
3526 struct {
3527 struct A *next;
3528 } entry1;
3531 Lang_C99, "input0.cc");
3532 auto *From =
3533 FirstDeclMatcher<RecordDecl>().match(FromTU, recordDecl(hasName("A")));
3535 Import(From, Lang_C99);
3537 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3538 auto *Entry0 =
3539 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
3540 auto *Entry1 =
3541 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry1")));
3542 auto *R0 = getRecordDecl(Entry0);
3543 auto *R1 = getRecordDecl(Entry1);
3544 EXPECT_NE(R0, R1);
3545 EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3546 R0, recordDecl(has(fieldDecl(hasName("next"))))));
3547 EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3548 R1, recordDecl(has(fieldDecl(hasName("next"))))));
3551 TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) {
3552 Decl *FromTU = getTuDecl(
3554 void f(int X, int Y, bool Z) {
3555 (void)[X, Y, Z] { (void)Z; };
3558 Lang_CXX11, "input0.cc");
3559 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
3560 FromTU, functionDecl(hasName("f")));
3561 auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11));
3562 EXPECT_TRUE(ToF);
3564 CXXRecordDecl *FromLambda =
3565 cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>(
3566 FromF->getBody())->body_front())->getSubExpr())->getLambdaClass();
3568 auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11));
3569 EXPECT_TRUE(ToLambda);
3571 // Check if the fields of the lambda class are imported in correct order.
3572 unsigned FromIndex = 0u;
3573 for (auto *FromField : FromLambda->fields()) {
3574 ASSERT_FALSE(FromField->getDeclName());
3575 auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11));
3576 EXPECT_TRUE(ToField);
3577 std::optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField);
3578 EXPECT_TRUE(ToIndex);
3579 EXPECT_EQ(*ToIndex, FromIndex);
3580 ++FromIndex;
3583 EXPECT_EQ(FromIndex, 3u);
3586 TEST_P(ASTImporterOptionSpecificTestBase,
3587 MergeFieldDeclsOfClassTemplateSpecialization) {
3588 std::string ClassTemplate =
3590 template <typename T>
3591 struct X {
3592 int a{0}; // FieldDecl with InitListExpr
3593 X(char) : a(3) {} // (1)
3594 X(int) {} // (2)
3597 Decl *ToTU = getToTuDecl(ClassTemplate +
3599 void foo() {
3600 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr
3601 X<char> xc('c');
3603 )", Lang_CXX11);
3604 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3605 ToTU, classTemplateSpecializationDecl(hasName("X")));
3606 // FieldDecl without InitlistExpr:
3607 auto *ToField = *ToSpec->field_begin();
3608 ASSERT_TRUE(ToField);
3609 ASSERT_FALSE(ToField->getInClassInitializer());
3610 Decl *FromTU = getTuDecl(ClassTemplate +
3612 void bar() {
3613 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr
3614 X<char> xc(1);
3616 )", Lang_CXX11);
3617 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3618 FromTU, classTemplateSpecializationDecl(hasName("X")));
3619 // FieldDecl with InitlistExpr:
3620 auto *FromField = *FromSpec->field_begin();
3621 ASSERT_TRUE(FromField);
3622 ASSERT_TRUE(FromField->getInClassInitializer());
3624 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3625 ASSERT_TRUE(ImportedSpec);
3626 EXPECT_EQ(ImportedSpec, ToSpec);
3627 // After the import, the FieldDecl has to be merged, thus it should have the
3628 // InitListExpr.
3629 EXPECT_TRUE(ToField->getInClassInitializer());
3632 TEST_P(ASTImporterOptionSpecificTestBase,
3633 MergeFunctionOfClassTemplateSpecialization) {
3634 std::string ClassTemplate =
3636 template <typename T>
3637 struct X {
3638 void f() {}
3639 void g() {}
3642 Decl *ToTU = getToTuDecl(ClassTemplate +
3644 void foo() {
3645 X<char> x;
3646 x.f();
3648 )", Lang_CXX11);
3649 Decl *FromTU = getTuDecl(ClassTemplate +
3651 void bar() {
3652 X<char> x;
3653 x.g();
3655 )", Lang_CXX11);
3656 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3657 FromTU, classTemplateSpecializationDecl(hasName("X")));
3658 auto FunPattern = functionDecl(hasName("g"),
3659 hasParent(classTemplateSpecializationDecl()));
3660 auto *FromFun =
3661 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunPattern);
3662 auto *ToFun =
3663 FirstDeclMatcher<FunctionDecl>().match(ToTU, FunPattern);
3664 ASSERT_TRUE(FromFun->hasBody());
3665 ASSERT_FALSE(ToFun->hasBody());
3666 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3667 ASSERT_TRUE(ImportedSpec);
3668 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3669 ToTU, classTemplateSpecializationDecl(hasName("X")));
3670 EXPECT_EQ(ImportedSpec, ToSpec);
3671 EXPECT_TRUE(ToFun->hasBody());
3674 TEST_P(ASTImporterOptionSpecificTestBase, MergeTemplateSpecWithForwardDecl) {
3675 std::string ClassTemplate =
3677 template<typename T>
3678 struct X { int m; };
3679 template<>
3680 struct X<int> { int m; };
3682 // Append a forward decl for our template specialization.
3683 getToTuDecl(ClassTemplate + "template<> struct X<int>;", Lang_CXX11);
3684 Decl *FromTU = getTuDecl(ClassTemplate, Lang_CXX11);
3685 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3686 FromTU, classTemplateSpecializationDecl(hasName("X"), isDefinition()));
3687 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3688 // Check that our definition got merged with the existing definition.
3689 EXPECT_TRUE(FromSpec->isThisDeclarationADefinition());
3690 EXPECT_TRUE(ImportedSpec->isThisDeclarationADefinition());
3693 TEST_P(ASTImporterOptionSpecificTestBase,
3694 ODRViolationOfClassTemplateSpecializationsShouldBeReported) {
3695 std::string ClassTemplate =
3697 template <typename T>
3698 struct X {};
3700 Decl *ToTU = getToTuDecl(ClassTemplate +
3702 template <>
3703 struct X<char> {
3704 int a;
3706 void foo() {
3707 X<char> x;
3710 Lang_CXX11);
3711 Decl *FromTU = getTuDecl(ClassTemplate +
3713 template <>
3714 struct X<char> {
3715 int b;
3717 void foo() {
3718 X<char> x;
3721 Lang_CXX11);
3722 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3723 FromTU, classTemplateSpecializationDecl(hasName("X")));
3724 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3726 // We expect one (ODR) warning during the import.
3727 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
3729 // The second specialization is different from the first, thus it violates
3730 // ODR, consequently we expect to keep the first specialization only, which is
3731 // already in the "To" context.
3732 EXPECT_FALSE(ImportedSpec);
3733 EXPECT_EQ(1u,
3734 DeclCounter<ClassTemplateSpecializationDecl>().match(
3735 ToTU, classTemplateSpecializationDecl(hasName("X"))));
3738 TEST_P(ASTImporterOptionSpecificTestBase,
3739 MergeCtorOfClassTemplateSpecialization) {
3740 std::string ClassTemplate =
3742 template <typename T>
3743 struct X {
3744 X(char) {}
3745 X(int) {}
3748 Decl *ToTU = getToTuDecl(ClassTemplate +
3750 void foo() {
3751 X<char> x('c');
3753 )", Lang_CXX11);
3754 Decl *FromTU = getTuDecl(ClassTemplate +
3756 void bar() {
3757 X<char> x(1);
3759 )", Lang_CXX11);
3760 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3761 FromTU, classTemplateSpecializationDecl(hasName("X")));
3762 // Match the void(int) ctor.
3763 auto CtorPattern =
3764 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))),
3765 hasParent(classTemplateSpecializationDecl()));
3766 auto *FromCtor =
3767 FirstDeclMatcher<CXXConstructorDecl>().match(FromTU, CtorPattern);
3768 auto *ToCtor =
3769 FirstDeclMatcher<CXXConstructorDecl>().match(ToTU, CtorPattern);
3770 ASSERT_TRUE(FromCtor->hasBody());
3771 ASSERT_FALSE(ToCtor->hasBody());
3772 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3773 ASSERT_TRUE(ImportedSpec);
3774 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3775 ToTU, classTemplateSpecializationDecl(hasName("X")));
3776 EXPECT_EQ(ImportedSpec, ToSpec);
3777 EXPECT_TRUE(ToCtor->hasBody());
3780 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) {
3781 const auto *Code =
3783 template <class T> class X { friend T; };
3784 struct Y {};
3785 template class X<Y>;
3787 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3788 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3789 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3790 FromTU, classTemplateSpecializationDecl());
3791 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3792 ToTU, classTemplateSpecializationDecl());
3794 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3795 EXPECT_EQ(ImportedSpec, ToSpec);
3796 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3797 ToTU, classTemplateSpecializationDecl()));
3800 TEST_P(ASTImporterOptionSpecificTestBase,
3801 ClassTemplatePartialSpecializationsShouldNotBeDuplicated) {
3802 auto Code =
3804 // primary template
3805 template<class T1, class T2, int I>
3806 class A {};
3808 // partial specialization
3809 template<class T, int I>
3810 class A<T, T*, I> {};
3812 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3813 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3814 auto *FromSpec =
3815 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3816 FromTU, classTemplatePartialSpecializationDecl());
3817 auto *ToSpec =
3818 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3819 ToTU, classTemplatePartialSpecializationDecl());
3821 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3822 EXPECT_EQ(ImportedSpec, ToSpec);
3823 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3824 ToTU, classTemplatePartialSpecializationDecl()));
3827 TEST_P(ASTImporterOptionSpecificTestBase,
3828 ClassTemplateSpecializationsShouldNotBeDuplicated) {
3829 auto Code =
3831 // primary template
3832 template<class T1, class T2, int I>
3833 class A {};
3835 // full specialization
3836 template<>
3837 class A<int, int, 1> {};
3839 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3840 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3841 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3842 FromTU, classTemplateSpecializationDecl());
3843 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3844 ToTU, classTemplateSpecializationDecl());
3846 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3847 EXPECT_EQ(ImportedSpec, ToSpec);
3848 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3849 ToTU, classTemplateSpecializationDecl()));
3852 TEST_P(ASTImporterOptionSpecificTestBase,
3853 ClassTemplateFullAndPartialSpecsShouldNotBeMixed) {
3854 std::string PrimaryTemplate =
3856 template<class T1, class T2, int I>
3857 class A {};
3859 auto PartialSpec =
3861 template<class T, int I>
3862 class A<T, T*, I> {};
3864 auto FullSpec =
3866 template<>
3867 class A<int, int, 1> {};
3869 Decl *ToTU = getToTuDecl(PrimaryTemplate + FullSpec, Lang_CXX11);
3870 Decl *FromTU = getTuDecl(PrimaryTemplate + PartialSpec, Lang_CXX11);
3871 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3872 FromTU, classTemplateSpecializationDecl());
3874 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3875 EXPECT_TRUE(ImportedSpec);
3876 // Check the number of partial specializations.
3877 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3878 ToTU, classTemplatePartialSpecializationDecl()));
3879 // Check the number of full specializations.
3880 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3881 ToTU, classTemplateSpecializationDecl(
3882 unless(classTemplatePartialSpecializationDecl()))));
3885 TEST_P(ASTImporterOptionSpecificTestBase,
3886 InitListExprValueKindShouldBeImported) {
3887 Decl *TU = getTuDecl(
3889 const int &init();
3890 void foo() { const int &a{init()}; }
3891 )", Lang_CXX11, "input0.cc");
3892 auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a")));
3893 ASSERT_TRUE(FromD->getAnyInitializer());
3894 auto *InitExpr = FromD->getAnyInitializer();
3895 ASSERT_TRUE(InitExpr);
3896 ASSERT_TRUE(InitExpr->isGLValue());
3898 auto *ToD = Import(FromD, Lang_CXX11);
3899 EXPECT_TRUE(ToD);
3900 auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer();
3901 EXPECT_TRUE(ToInitExpr);
3902 EXPECT_TRUE(ToInitExpr->isGLValue());
3905 struct ImportVariables : ASTImporterOptionSpecificTestBase {};
3907 TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) {
3908 Decl *FromTU = getTuDecl(
3910 struct A {
3911 static const int a = 1 + 2;
3913 const int A::a;
3915 Lang_CXX03, "input1.cc");
3917 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3918 FromTU, varDecl(hasName("a"))); // Decl with init
3919 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3920 FromTU, varDecl(hasName("a"))); // Decl with definition
3921 ASSERT_NE(FromDWithInit, FromDWithDef);
3922 ASSERT_EQ(FromDWithDef->getPreviousDecl(), FromDWithInit);
3924 auto *ToD0 = cast<VarDecl>(Import(FromDWithInit, Lang_CXX11));
3925 auto *ToD1 = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3926 ASSERT_TRUE(ToD0);
3927 ASSERT_TRUE(ToD1);
3928 EXPECT_NE(ToD0, ToD1);
3929 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
3932 TEST_P(ImportVariables, InitAndDefinitionAreInDifferentTUs) {
3933 auto StructA =
3935 struct A {
3936 static const int a = 1 + 2;
3939 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3940 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a;", Lang_CXX03,
3941 "input1.cc");
3943 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3944 FromTU, varDecl(hasName("a"))); // Decl with init
3945 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3946 FromTU, varDecl(hasName("a"))); // Decl with definition
3947 ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl());
3948 ASSERT_TRUE(FromDWithInit->getInit());
3949 ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition());
3950 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3951 ASSERT_FALSE(FromDWithDef->getInit());
3953 auto *ToD = FirstDeclMatcher<VarDecl>().match(
3954 ToTU, varDecl(hasName("a"))); // Decl with init
3955 ASSERT_TRUE(ToD->getInit());
3956 ASSERT_FALSE(ToD->getDefinition());
3958 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3959 EXPECT_TRUE(ImportedD->getAnyInitializer());
3960 EXPECT_TRUE(ImportedD->getDefinition());
3963 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) {
3964 auto StructA =
3966 struct A {
3967 static const int a;
3970 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3971 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a = 1 + 2;",
3972 Lang_CXX03, "input1.cc");
3974 auto *FromDDeclarationOnly = FirstDeclMatcher<VarDecl>().match(
3975 FromTU, varDecl(hasName("a")));
3976 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3977 FromTU, varDecl(hasName("a"))); // Decl with definition and with init.
3978 ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl());
3979 ASSERT_FALSE(FromDDeclarationOnly->getInit());
3980 ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition());
3981 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3982 ASSERT_TRUE(FromDWithDef->getInit());
3984 auto *ToD = FirstDeclMatcher<VarDecl>().match(
3985 ToTU, varDecl(hasName("a")));
3986 ASSERT_FALSE(ToD->getInit());
3987 ASSERT_FALSE(ToD->getDefinition());
3989 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3990 EXPECT_TRUE(ImportedD->getAnyInitializer());
3991 EXPECT_TRUE(ImportedD->getDefinition());
3994 TEST_P(ImportVariables, ImportBindingDecl) {
3995 Decl *From, *To;
3996 std::tie(From, To) = getImportedDecl(
3998 void declToImport() {
3999 int a[2] = {1,2};
4000 auto [x1,y1] = a;
4001 auto& [x2,y2] = a;
4003 struct S {
4004 mutable int x1 : 2;
4005 volatile double y1;
4007 S b;
4008 const auto [x3, y3] = b;
4011 Lang_CXX17, "", Lang_CXX17);
4013 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl();
4014 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
4015 FromTU, functionDecl(hasName("declToImport")));
4016 auto *ToF = Import(FromF, Lang_CXX17);
4017 EXPECT_TRUE(ToF);
4019 auto VerifyImport = [&](llvm::StringRef BindName) {
4020 auto *FromB = FirstDeclMatcher<BindingDecl>().match(
4021 FromF, bindingDecl(hasName(BindName)));
4022 ASSERT_TRUE(FromB);
4023 auto *ToB = Import(FromB, Lang_CXX17);
4024 EXPECT_TRUE(ToB);
4025 EXPECT_EQ(FromB->getBinding() != nullptr, ToB->getBinding() != nullptr);
4026 EXPECT_EQ(FromB->getDecomposedDecl() != nullptr,
4027 ToB->getDecomposedDecl() != nullptr);
4028 EXPECT_EQ(FromB->getHoldingVar() != nullptr,
4029 ToB->getHoldingVar() != nullptr);
4032 VerifyImport("x1");
4033 VerifyImport("y1");
4034 VerifyImport("x2");
4035 VerifyImport("y2");
4036 VerifyImport("x3");
4037 VerifyImport("y3");
4040 TEST_P(ImportVariables, ImportDecompositionDeclArray) {
4041 Decl *From, *To;
4042 std::tie(From, To) = getImportedDecl(
4044 void declToImport() {
4045 int a[2] = {1,2};
4046 auto [x1,y1] = a;
4049 Lang_CXX17, "", Lang_CXX17);
4051 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl();
4052 auto *FromDecomp =
4053 FirstDeclMatcher<DecompositionDecl>().match(FromTU, decompositionDecl());
4054 auto *ToDecomp = Import(FromDecomp, Lang_CXX17);
4055 EXPECT_TRUE(ToDecomp);
4057 ArrayRef<BindingDecl *> FromB = FromDecomp->bindings();
4058 ArrayRef<BindingDecl *> ToB = ToDecomp->bindings();
4059 EXPECT_EQ(FromB.size(), ToB.size());
4060 for (unsigned int I = 0; I < FromB.size(); ++I) {
4061 auto *ToBI = Import(FromB[I], Lang_CXX17);
4062 EXPECT_EQ(ToBI, ToB[I]);
4066 struct ImportClasses : ASTImporterOptionSpecificTestBase {};
4068 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {
4069 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C99);
4070 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
4071 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
4072 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4073 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
4075 Decl *ImportedDef = Import(FromDef, Lang_C99);
4077 EXPECT_NE(ImportedDef, ToProto);
4078 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
4079 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4080 EXPECT_TRUE(ImportedDef == ToDef);
4081 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
4082 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
4083 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
4086 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) {
4087 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03);
4088 Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX03, "input1.cc");
4089 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
4090 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4091 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
4093 Decl *ImportedDef = Import(FromDef, Lang_CXX03);
4095 EXPECT_NE(ImportedDef, ToProto);
4096 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
4097 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4098 EXPECT_TRUE(ImportedDef == ToDef);
4099 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
4100 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
4101 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
4104 TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) {
4105 Decl *FromTU0 =
4106 getTuDecl("struct A { struct X *Xp; };", Lang_C99, "input0.cc");
4107 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
4108 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
4109 auto FromProto = FirstDeclMatcher<RecordDecl>().match(FromTU0, Pattern);
4110 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
4112 Decl *ImportedProto = Import(FromProto, Lang_C99);
4113 Decl *ImportedDef = Import(FromDef, Lang_C99);
4114 Decl *ToTU = ImportedDef->getTranslationUnitDecl();
4116 EXPECT_NE(ImportedDef, ImportedProto);
4117 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
4118 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4119 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4120 EXPECT_TRUE(ImportedDef == ToDef);
4121 EXPECT_TRUE(ImportedProto == ToProto);
4122 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
4123 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
4124 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
4127 struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {
4128 void testRecursiveFriendClassTemplate(Decl *FromTu) {
4129 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4130 FromTu, classTemplateDecl());
4132 auto Pattern = classTemplateDecl(
4133 has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
4134 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
4136 auto *FromFriend =
4137 FirstDeclMatcher<FriendDecl>().match(FromD, friendDecl());
4138 auto *FromRecordOfFriend =
4139 cast<ClassTemplateDecl>(FromFriend->getFriendDecl())
4140 ->getTemplatedDecl();
4141 EXPECT_NE(FromRecordOfFriend, FromD->getTemplatedDecl());
4142 EXPECT_TRUE(FromRecordOfFriend->getPreviousDecl() == nullptr);
4144 auto *FromDC = FromRecordOfFriend->getDeclContext();
4145 auto *FromLexicalDC = FromRecordOfFriend->getLexicalDeclContext();
4146 ASSERT_EQ(FromDC, cast<DeclContext>(FromTu));
4147 ASSERT_EQ(FromLexicalDC, cast<DeclContext>(FromD->getTemplatedDecl()));
4149 ASSERT_FALSE(FromDC->containsDecl(FromRecordOfFriend));
4150 ASSERT_FALSE(FromLexicalDC->containsDecl(FromRecordOfFriend));
4151 ASSERT_FALSE(cast<RecordDecl>(FromRecordOfFriend)
4152 ->getLookupParent()
4153 ->lookup(FromRecordOfFriend->getDeclName())
4154 .empty());
4156 auto *ToD = Import(FromD, Lang_CXX03);
4157 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
4159 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl());
4160 auto *ToRecordOfFriend =
4161 cast<ClassTemplateDecl>(ToFriend->getFriendDecl())->getTemplatedDecl();
4163 EXPECT_NE(ToRecordOfFriend, ToD->getTemplatedDecl());
4164 EXPECT_TRUE(ToRecordOfFriend->getPreviousDecl() == nullptr);
4166 auto *ToDC = ToRecordOfFriend->getDeclContext();
4167 auto *ToLexicalDC = ToRecordOfFriend->getLexicalDeclContext();
4168 ASSERT_EQ(ToDC, cast<DeclContext>(ToD->getTranslationUnitDecl()));
4169 ASSERT_EQ(ToLexicalDC, cast<DeclContext>(ToD->getTemplatedDecl()));
4171 ASSERT_FALSE(ToDC->containsDecl(ToRecordOfFriend));
4172 ASSERT_FALSE(ToLexicalDC->containsDecl(ToRecordOfFriend));
4173 ASSERT_FALSE(cast<RecordDecl>(ToRecordOfFriend)
4174 ->getLookupParent()
4175 ->lookup(ToRecordOfFriend->getDeclName())
4176 .empty());
4179 void testRepeatedFriendImport(const char *Code) {
4180 Decl *ToTu = getToTuDecl(Code, Lang_CXX03);
4181 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc");
4183 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4184 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4185 auto *FromFriend1 =
4186 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4187 auto *FromFriend2 =
4188 LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4190 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03);
4191 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03);
4193 EXPECT_NE(ToImportedFriend1, ToImportedFriend2);
4194 EXPECT_EQ(ToFriend1, ToImportedFriend1);
4195 EXPECT_EQ(ToFriend2, ToImportedFriend2);
4199 TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) {
4200 Decl *FromTU = getTuDecl(
4202 class A {
4203 template <int I> class F {};
4204 class X {
4205 template <int I> friend class F;
4209 Lang_CXX03, "input0.cc");
4211 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
4212 FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
4213 auto *FromFriendClass = LastDeclMatcher<CXXRecordDecl>().match(
4214 FromTU, cxxRecordDecl(hasName("F")));
4216 ASSERT_TRUE(FromClass);
4217 ASSERT_TRUE(FromFriendClass);
4218 ASSERT_NE(FromClass, FromFriendClass);
4219 ASSERT_EQ(FromFriendClass->getDefinition(), FromClass);
4220 ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass);
4221 ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
4222 FromClass->getDescribedClassTemplate());
4224 auto *ToClass = cast<CXXRecordDecl>(Import(FromClass, Lang_CXX03));
4225 auto *ToFriendClass =
4226 cast<CXXRecordDecl>(Import(FromFriendClass, Lang_CXX03));
4228 EXPECT_TRUE(ToClass);
4229 EXPECT_TRUE(ToFriendClass);
4230 EXPECT_NE(ToClass, ToFriendClass);
4231 EXPECT_EQ(ToFriendClass->getDefinition(), ToClass);
4232 EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass);
4233 EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
4234 ToClass->getDescribedClassTemplate());
4237 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) {
4238 Decl *FromTu = getTuDecl(
4240 class declToImport {
4241 friend class declToImport;
4244 Lang_CXX03, "input.cc");
4246 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
4247 FromTu, cxxRecordDecl(hasName("declToImport")));
4248 auto *ToD = Import(FromD, Lang_CXX03);
4249 auto Pattern = cxxRecordDecl(has(friendDecl()));
4250 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
4251 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
4254 TEST_P(ImportFriendClasses, UndeclaredFriendClassShouldNotBeVisible) {
4255 Decl *FromTu =
4256 getTuDecl("class X { friend class Y; };", Lang_CXX03, "from.cc");
4257 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
4258 FromTu, cxxRecordDecl(hasName("X")));
4259 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4260 RecordDecl *FromRecordOfFriend =
4261 const_cast<RecordDecl *>(getRecordDeclOfFriend(FromFriend));
4263 ASSERT_EQ(FromRecordOfFriend->getDeclContext(), cast<DeclContext>(FromTu));
4264 ASSERT_EQ(FromRecordOfFriend->getLexicalDeclContext(),
4265 cast<DeclContext>(FromX));
4266 ASSERT_FALSE(
4267 FromRecordOfFriend->getDeclContext()->containsDecl(FromRecordOfFriend));
4268 ASSERT_FALSE(FromRecordOfFriend->getLexicalDeclContext()->containsDecl(
4269 FromRecordOfFriend));
4270 ASSERT_FALSE(FromRecordOfFriend->getLookupParent()
4271 ->lookup(FromRecordOfFriend->getDeclName())
4272 .empty());
4274 auto *ToX = Import(FromX, Lang_CXX03);
4275 ASSERT_TRUE(ToX);
4277 Decl *ToTu = ToX->getTranslationUnitDecl();
4278 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4279 RecordDecl *ToRecordOfFriend =
4280 const_cast<RecordDecl *>(getRecordDeclOfFriend(ToFriend));
4282 ASSERT_EQ(ToRecordOfFriend->getDeclContext(), cast<DeclContext>(ToTu));
4283 ASSERT_EQ(ToRecordOfFriend->getLexicalDeclContext(), cast<DeclContext>(ToX));
4284 EXPECT_FALSE(
4285 ToRecordOfFriend->getDeclContext()->containsDecl(ToRecordOfFriend));
4286 EXPECT_FALSE(ToRecordOfFriend->getLexicalDeclContext()->containsDecl(
4287 ToRecordOfFriend));
4288 EXPECT_FALSE(ToRecordOfFriend->getLookupParent()
4289 ->lookup(ToRecordOfFriend->getDeclName())
4290 .empty());
4293 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) {
4294 Decl *FromTu = getTuDecl(
4296 template<class A> class declToImport {
4297 template<class A1> friend class declToImport;
4300 Lang_CXX03, "input.cc");
4302 testRecursiveFriendClassTemplate(FromTu);
4305 TEST_P(ImportFriendClasses,
4306 ImportOfRecursiveFriendClassTemplateWithNonTypeParm) {
4307 Decl *FromTu = getTuDecl(
4309 template<class A1, A1 A> class declToImport {
4310 template<class B1, B1> friend class declToImport;
4313 Lang_CXX03, "input.cc");
4314 testRecursiveFriendClassTemplate(FromTu);
4317 TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) {
4318 auto Pattern = classTemplateSpecializationDecl(hasName("X"));
4320 ClassTemplateSpecializationDecl *Imported1;
4322 Decl *FromTU = getTuDecl("template<class T> class X;"
4323 "struct Y { friend class X<int>; };",
4324 Lang_CXX03, "input0.cc");
4325 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4326 FromTU, Pattern);
4328 Imported1 =
4329 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
4331 ClassTemplateSpecializationDecl *Imported2;
4333 Decl *FromTU = getTuDecl("template<class T> class X;"
4334 "template<> class X<int>{};"
4335 "struct Z { friend class X<int>; };",
4336 Lang_CXX03, "input1.cc");
4337 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4338 FromTU, Pattern);
4340 Imported2 =
4341 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
4344 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4345 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(ToTU, Pattern),
4346 2u);
4347 ASSERT_TRUE(Imported2->getPreviousDecl());
4348 EXPECT_EQ(Imported2->getPreviousDecl(), Imported1);
4351 TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) {
4352 Decl *FromTU0 = getTuDecl(
4354 class X {
4355 class Y;
4357 class X::Y {
4358 template <typename T>
4359 friend class F; // The decl context of F is the global namespace.
4362 Lang_CXX03, "input0.cc");
4363 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4364 FromTU0, classTemplateDecl(hasName("F")));
4365 auto *Imported0 = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
4366 Decl *FromTU1 = getTuDecl(
4368 template <typename T>
4369 class F {};
4371 Lang_CXX03, "input1.cc");
4372 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4373 FromTU1, classTemplateDecl(hasName("F")));
4374 auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4375 EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(),
4376 Imported1->getTemplatedDecl()->getTypeForDecl());
4379 TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) {
4380 Decl *From, *To;
4381 std::tie(From, To) =
4382 getImportedDecl("class declToImport {};", Lang_CXX03,
4383 "class Y { friend class declToImport; };", Lang_CXX03);
4384 auto *Imported = cast<CXXRecordDecl>(To);
4386 EXPECT_TRUE(Imported->getPreviousDecl());
4389 TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
4390 Decl *ToTU = getToTuDecl(
4392 template <class T, T U>
4393 class A;
4395 template <class T, T U>
4396 class A {
4397 public:
4398 template <class P, P Q>
4399 friend class A;
4401 A(T x) :x(x) {}
4403 private:
4404 T x;
4407 Lang_CXX11);
4409 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4410 ToTU,
4411 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4412 Decl *FromTU = getTuDecl(
4414 template <class T, T U>
4415 class A;
4417 template <class T, T U>
4418 class A {
4419 public:
4420 template <class P, P Q>
4421 friend class A;
4423 A(T x) : x(x) {}
4425 private:
4426 T x;
4429 A<int,3> a1(0);
4431 Lang_CXX11, "input1.cc");
4432 auto *FromA = FirstDeclMatcher<ClassTemplateDecl>().match(
4433 FromTU,
4434 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4435 auto *ToA = Import(FromA, Lang_CXX11);
4436 EXPECT_TRUE(ToA);
4437 EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
4438 ToA->getTemplatedDecl()->getTypeForDecl());
4441 TEST_P(ImportFriendClasses,
4442 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
4443 Decl *ToTU = getToTuDecl(
4445 class X {
4446 class Y;
4448 class X::Y {
4449 template <typename T>
4450 friend class F; // The decl context of F is the global namespace.
4453 Lang_CXX03);
4454 auto *ToDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
4455 ToTU, classTemplateDecl(hasName("F")));
4456 Decl *FromTU = getTuDecl(
4458 template <typename T>
4459 class F {};
4461 Lang_CXX03, "input0.cc");
4462 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4463 FromTU, classTemplateDecl(hasName("F")));
4464 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4465 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4466 EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl());
4467 EXPECT_EQ(ToDecl->getTemplatedDecl(),
4468 ImportedDef->getTemplatedDecl()->getPreviousDecl());
4471 TEST_P(ImportFriendClasses,
4472 ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) {
4473 Decl *FromTU0 = getTuDecl(
4475 class X {
4476 class Y;
4478 class X::Y {
4479 template <typename T>
4480 friend class F; // The decl context of F is the global namespace.
4483 Lang_CXX03, "input0.cc");
4484 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4485 FromTU0, classTemplateDecl(hasName("F")));
4486 auto *ImportedFwd = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
4487 Decl *FromTU1 = getTuDecl(
4489 template <typename T>
4490 class F {};
4492 Lang_CXX03, "input1.cc");
4493 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4494 FromTU1, classTemplateDecl(hasName("F")));
4495 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4496 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4497 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
4498 EXPECT_EQ(ImportedFwd->getTemplatedDecl(),
4499 ImportedDef->getTemplatedDecl()->getPreviousDecl());
4502 TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
4503 Decl *FromTU0 = getTuDecl(
4505 class X {
4506 class Y;
4508 class X::Y {
4509 friend class F; // The decl context of F is the global namespace.
4512 Lang_CXX03, "input0.cc");
4513 auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl());
4514 QualType FT = Friend->getFriendType()->getType();
4515 FT = FromTU0->getASTContext().getCanonicalType(FT);
4516 auto *Fwd = cast<TagType>(FT)->getDecl();
4517 auto *ImportedFwd = Import(Fwd, Lang_CXX03);
4518 Decl *FromTU1 = getTuDecl(
4520 class F {};
4522 Lang_CXX03, "input1.cc");
4523 auto *Definition = FirstDeclMatcher<CXXRecordDecl>().match(
4524 FromTU1, cxxRecordDecl(hasName("F")));
4525 auto *ImportedDef = Import(Definition, Lang_CXX03);
4526 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4527 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
4530 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) {
4531 const char *Code =
4533 class Container {
4534 friend class X;
4535 friend class X;
4538 testRepeatedFriendImport(Code);
4541 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) {
4542 const char *Code =
4544 class Container {
4545 friend void f();
4546 friend void f();
4549 testRepeatedFriendImport(Code);
4552 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendFunctionTemplateDecl) {
4553 const char *Code =
4555 template <class T>
4556 class Container {
4557 template <class U> friend void m();
4558 template <class U> friend void m();
4561 testRepeatedFriendImport(Code);
4564 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendClassTemplateDecl) {
4565 const char *Code =
4567 template <class T>
4568 class Container {
4569 template <class U> friend class X;
4570 template <class U> friend class X;
4573 testRepeatedFriendImport(Code);
4576 TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) {
4577 auto *Code = R"(
4578 template <class T>
4579 struct X {
4580 friend void foo(){}
4583 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
4584 auto *ToFoo = FirstDeclMatcher<FunctionDecl>().match(
4585 ToTU, functionDecl(hasName("foo")));
4587 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
4588 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
4589 FromTU, functionDecl(hasName("foo")));
4590 auto *ImportedFoo = Import(FromFoo, Lang_CXX03);
4591 EXPECT_EQ(ImportedFoo, ToFoo);
4594 struct DeclContextTest : ASTImporterOptionSpecificTestBase {};
4596 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
4597 Decl *TU = getTuDecl(
4599 namespace NS {
4601 template <typename T>
4602 struct S {};
4603 template struct S<int>;
4605 inline namespace INS {
4606 template <typename T>
4607 struct S {};
4608 template struct S<int>;
4612 )", Lang_CXX11, "input0.cc");
4613 auto *NS = FirstDeclMatcher<NamespaceDecl>().match(
4614 TU, namespaceDecl());
4615 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4616 TU, classTemplateSpecializationDecl());
4617 ASSERT_TRUE(NS->containsDecl(Spec));
4619 NS->removeDecl(Spec);
4620 EXPECT_FALSE(NS->containsDecl(Spec));
4623 TEST_P(DeclContextTest,
4624 removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) {
4625 Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX03);
4626 auto *A0 = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
4627 auto *A1 = LastDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
4629 // Investigate the list.
4630 auto *DC = A0->getDeclContext();
4631 ASSERT_TRUE(DC->containsDecl(A0));
4632 ASSERT_TRUE(DC->containsDecl(A1));
4634 // Investigate the lookup table.
4635 auto *Map = DC->getLookupPtr();
4636 ASSERT_TRUE(Map);
4637 auto I = Map->find(A0->getDeclName());
4638 ASSERT_NE(I, Map->end());
4639 StoredDeclsList &L = I->second;
4640 // The lookup table contains the most recent decl of A.
4641 ASSERT_NE(L.getAsDecl(), A0);
4642 ASSERT_EQ(L.getAsDecl(), A1);
4644 ASSERT_TRUE(L.getAsDecl());
4645 // Simulate the private function DeclContext::reconcileExternalVisibleStorage.
4646 // We do not have a list with one element.
4647 L.setHasExternalDecls();
4648 ASSERT_FALSE(L.getAsList());
4649 auto Results = L.getLookupResult();
4650 ASSERT_EQ(1u, std::distance(Results.begin(), Results.end()));
4652 // This asserts in the old implementation.
4653 DC->removeDecl(A0);
4654 EXPECT_FALSE(DC->containsDecl(A0));
4656 // Make sure we do not leave a StoredDeclsList with no entries.
4657 DC->removeDecl(A1);
4658 ASSERT_EQ(Map->find(A1->getDeclName()), Map->end());
4661 struct ImportFunctionTemplateSpecializations
4662 : ASTImporterOptionSpecificTestBase {};
4664 TEST_P(ImportFunctionTemplateSpecializations,
4665 TUshouldNotContainFunctionTemplateImplicitInstantiation) {
4667 Decl *FromTU = getTuDecl(
4669 template<class T>
4670 int f() { return 0; }
4671 void foo() { f<int>(); }
4673 Lang_CXX03, "input0.cc");
4675 // Check that the function template instantiation is NOT the child of the TU.
4676 auto Pattern = translationUnitDecl(
4677 unless(has(functionDecl(hasName("f"), isTemplateInstantiation()))));
4678 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4680 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
4681 FromTU, functionDecl(hasName("foo")));
4682 ASSERT_TRUE(Import(Foo, Lang_CXX03));
4684 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4685 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4688 TEST_P(ImportFunctionTemplateSpecializations,
4689 TUshouldNotContainFunctionTemplateExplicitInstantiation) {
4691 Decl *FromTU = getTuDecl(
4693 template<class T>
4694 int f() { return 0; }
4695 template int f<int>();
4697 Lang_CXX03, "input0.cc");
4699 // Check that the function template instantiation is NOT the child of the TU.
4700 auto Instantiation = functionDecl(hasName("f"), isTemplateInstantiation());
4701 auto Pattern = translationUnitDecl(unless(has(Instantiation)));
4702 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4704 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation),
4705 Lang_CXX03));
4707 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4708 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4711 TEST_P(ImportFunctionTemplateSpecializations,
4712 TUshouldContainFunctionTemplateSpecialization) {
4714 Decl *FromTU = getTuDecl(
4716 template<class T>
4717 int f() { return 0; }
4718 template <> int f<int>() { return 4; }
4720 Lang_CXX03, "input0.cc");
4722 // Check that the function template specialization is the child of the TU.
4723 auto Specialization =
4724 functionDecl(hasName("f"), isExplicitTemplateSpecialization());
4725 auto Pattern = translationUnitDecl(has(Specialization));
4726 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4728 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization),
4729 Lang_CXX03));
4731 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4732 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4735 TEST_P(ImportFunctionTemplateSpecializations,
4736 FunctionTemplateSpecializationRedeclChain) {
4738 Decl *FromTU = getTuDecl(
4740 template<class T>
4741 int f() { return 0; }
4742 template <> int f<int>() { return 4; }
4744 Lang_CXX03, "input0.cc");
4746 auto Spec = functionDecl(hasName("f"), isExplicitTemplateSpecialization(),
4747 hasParent(translationUnitDecl()));
4748 auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec);
4750 auto *TU = FromTU;
4751 auto *SpecD = FromSpecD;
4752 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4753 TU, functionTemplateDecl());
4754 auto *FirstSpecD = *(TemplateD->spec_begin());
4755 ASSERT_EQ(SpecD, FirstSpecD);
4756 ASSERT_TRUE(SpecD->getPreviousDecl());
4757 ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4758 ->doesThisDeclarationHaveABody());
4761 ASSERT_TRUE(Import(FromSpecD, Lang_CXX03));
4764 auto *TU = ToAST->getASTContext().getTranslationUnitDecl();
4765 auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec);
4766 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4767 TU, functionTemplateDecl());
4768 auto *FirstSpecD = *(TemplateD->spec_begin());
4769 EXPECT_EQ(SpecD, FirstSpecD);
4770 ASSERT_TRUE(SpecD->getPreviousDecl());
4771 EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4772 ->doesThisDeclarationHaveABody());
4776 TEST_P(ImportFunctionTemplateSpecializations,
4777 MatchNumberOfFunctionTemplateSpecializations) {
4779 Decl *FromTU = getTuDecl(
4781 template <typename T> constexpr int f() { return 0; }
4782 template <> constexpr int f<int>() { return 4; }
4783 void foo() {
4784 static_assert(f<char>() == 0, "");
4785 static_assert(f<int>() == 4, "");
4788 Lang_CXX11, "input0.cc");
4789 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
4790 FromTU, functionDecl(hasName("foo")));
4792 Import(FromD, Lang_CXX11);
4793 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4794 EXPECT_EQ(
4795 DeclCounter<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))),
4796 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))));
4799 TEST_P(ASTImporterOptionSpecificTestBase,
4800 ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
4802 Decl *FromTU = getTuDecl(
4804 template <typename T>
4805 struct B;
4807 Lang_CXX03, "input0.cc");
4808 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4809 FromTU, classTemplateDecl(hasName("B")));
4811 Import(FromD, Lang_CXX03);
4815 Decl *FromTU = getTuDecl(
4817 template <typename T>
4818 struct B {
4819 void f();
4820 B* b;
4823 Lang_CXX03, "input1.cc");
4824 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
4825 FromTU, functionDecl(hasName("f")));
4826 Import(FromD, Lang_CXX03);
4827 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
4828 FromTU, classTemplateDecl(hasName("B")));
4829 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
4830 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
4832 // We expect no (ODR) warning during the import.
4833 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4834 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
4838 TEST_P(ASTImporterOptionSpecificTestBase,
4839 ImportingTypedefShouldImportTheCompleteType) {
4840 // We already have an incomplete underlying type in the "To" context.
4841 auto Code =
4843 template <typename T>
4844 struct S {
4845 void foo();
4847 using U = S<int>;
4849 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
4850 auto *ToD = FirstDeclMatcher<TypedefNameDecl>().match(ToTU,
4851 typedefNameDecl(hasName("U")));
4852 ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType());
4854 // The "From" context has the same typedef, but the underlying type is
4855 // complete this time.
4856 Decl *FromTU = getTuDecl(std::string(Code) +
4858 void foo(U* u) {
4859 u->foo();
4861 )", Lang_CXX11);
4862 auto *FromD = FirstDeclMatcher<TypedefNameDecl>().match(FromTU,
4863 typedefNameDecl(hasName("U")));
4864 ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType());
4866 // The imported type should be complete.
4867 auto *ImportedD = cast<TypedefNameDecl>(Import(FromD, Lang_CXX11));
4868 EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType());
4871 TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) {
4872 auto Code =
4874 template<class T>
4875 int f() { return 0; }
4876 template <> int f<int>() { return 4; }
4879 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
4880 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU,
4881 functionDecl(hasName("f"), isExplicitTemplateSpecialization()));
4882 ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1u);
4884 auto *ToD = Import(FromD, Lang_CXX03);
4885 // The template parameter list should exist.
4886 EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1u);
4889 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl>
4890 varTemplateDecl;
4892 const internal::VariadicDynCastAllOfMatcher<
4893 Decl, VarTemplatePartialSpecializationDecl>
4894 varTemplatePartialSpecializationDecl;
4896 TEST_P(ASTImporterOptionSpecificTestBase,
4897 FunctionTemplateParameterDeclContext) {
4898 constexpr auto Code =
4900 template<class T>
4901 void f() {};
4904 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
4906 auto *FromD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4907 FromTU, functionTemplateDecl(hasName("f")));
4909 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(),
4910 FromD->getTemplatedDecl());
4912 auto *ToD = Import(FromD, Lang_CXX11);
4913 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(),
4914 ToD->getTemplatedDecl());
4915 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4916 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0)));
4919 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateParameterDeclContext) {
4920 constexpr auto Code =
4922 template<class T1, class T2>
4923 struct S {};
4924 template<class T2>
4925 struct S<int, T2> {};
4928 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
4930 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4931 FromTU, classTemplateDecl(hasName("S")));
4932 auto *FromDPart =
4933 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
4934 FromTU, classTemplatePartialSpecializationDecl(hasName("S")));
4936 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(),
4937 FromD->getTemplatedDecl());
4938 ASSERT_EQ(FromDPart->getTemplateParameters()->getParam(0)->getDeclContext(),
4939 FromDPart);
4941 auto *ToD = Import(FromD, Lang_CXX11);
4942 auto *ToDPart = Import(FromDPart, Lang_CXX11);
4944 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(),
4945 ToD->getTemplatedDecl());
4946 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4947 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0)));
4949 EXPECT_EQ(ToDPart->getTemplateParameters()->getParam(0)->getDeclContext(),
4950 ToDPart);
4951 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4952 ToDPart, ToDPart->getTemplateParameters()->getParam(0)));
4955 TEST_P(ASTImporterOptionSpecificTestBase,
4956 CXXDeductionGuideTemplateParameterDeclContext) {
4957 Decl *FromTU = getTuDecl(
4959 template <typename T> struct A {
4960 A(T);
4962 A a{(int)0};
4964 Lang_CXX17, "input.cc");
4965 // clang-format off
4967 |-ClassTemplateDecl 0x1fe5000 <input.cc:2:7, line:4:7> line:2:36 A
4968 | |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
4969 | |-CXXRecordDecl 0x1fe4f70 <col:29, line:4:7> line:2:36 struct A definition
4971 |-FunctionTemplateDecl 0x1fe5860 <line:2:7, line:3:12> col:9 implicit <deduction guide for A>
4972 | |-TemplateTypeParmDecl 0x1fe4eb0 <line:2:17, col:26> col:26 referenced typename depth 0 index 0 T
4973 | |-CXXDeductionGuideDecl 0x1fe57a8 <line:3:9, col:12> col:9 implicit <deduction guide for A> 'auto (T) -> A<T>'
4974 | | `-ParmVarDecl 0x1fe56b0 <col:11> col:12 'T'
4975 | `-CXXDeductionGuideDecl 0x20515d8 <col:9, col:12> col:9 implicit used <deduction guide for A> 'auto (int) -> A<int>'
4976 | |-TemplateArgument type 'int'
4977 | | `-BuiltinType 0x20587e0 'int'
4978 | `-ParmVarDecl 0x2051388 <col:11> col:12 'int'
4979 `-FunctionTemplateDecl 0x1fe5a78 <line:2:7, col:36> col:36 implicit <deduction guide for A>
4980 |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
4981 `-CXXDeductionGuideDecl 0x1fe59c0 <col:36> col:36 implicit <deduction guide for A> 'auto (A<T>) -> A<T>'
4982 `-ParmVarDecl 0x1fe5958 <col:36> col:36 'A<T>'
4984 // clang-format on
4985 auto *FromD1 = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
4986 FromTU, cxxDeductionGuideDecl());
4987 auto *FromD2 = LastDeclMatcher<CXXDeductionGuideDecl>().match(
4988 FromTU, cxxDeductionGuideDecl());
4990 NamedDecl *P1 =
4991 FromD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
4993 NamedDecl *P2 =
4994 FromD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
4996 DeclContext *DC = P1->getDeclContext();
4998 ASSERT_EQ(P1, P2);
4999 ASSERT_TRUE(DC == FromD1 || DC == FromD2);
5001 auto *ToD1 = Import(FromD1, Lang_CXX17);
5002 auto *ToD2 = Import(FromD2, Lang_CXX17);
5003 ASSERT_TRUE(ToD1 && ToD2);
5005 P1 = ToD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5007 P2 = ToD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5009 DC = P1->getDeclContext();
5011 EXPECT_EQ(P1, P2);
5012 EXPECT_TRUE(DC == ToD1 || DC == ToD2);
5014 ASTImporterLookupTable *Tbl = SharedStatePtr->getLookupTable();
5015 if (Tbl->contains(ToD1, P1)) {
5016 EXPECT_FALSE(Tbl->contains(ToD2, P1));
5017 } else {
5018 EXPECT_TRUE(Tbl->contains(ToD2, P1));
5022 TEST_P(ImportFriendClasses, RecordVarTemplateDecl) {
5023 Decl *ToTU = getToTuDecl(
5025 template <class T>
5026 class A {
5027 public:
5028 template <class U>
5029 static constexpr bool X = true;
5032 Lang_CXX14);
5034 auto *ToTUX = FirstDeclMatcher<VarTemplateDecl>().match(
5035 ToTU, varTemplateDecl(hasName("X")));
5036 Decl *FromTU = getTuDecl(
5038 template <class T>
5039 class A {
5040 public:
5041 template <class U>
5042 static constexpr bool X = true;
5045 Lang_CXX14, "input1.cc");
5046 auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match(
5047 FromTU, varTemplateDecl(hasName("X")));
5048 auto *ToX = Import(FromX, Lang_CXX11);
5049 EXPECT_TRUE(ToX);
5050 EXPECT_EQ(ToTUX, ToX);
5053 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) {
5054 constexpr auto Code =
5056 template<class T1, class T2>
5057 int X1;
5058 template<class T2>
5059 int X1<int, T2>;
5061 namespace Ns {
5062 template<class T1, class T2>
5063 int X2;
5064 template<class T2>
5065 int X2<int, T2>;
5069 Decl *FromTU = getTuDecl(Code, Lang_CXX14);
5071 auto *FromD1 = FirstDeclMatcher<VarTemplateDecl>().match(
5072 FromTU, varTemplateDecl(hasName("X1")));
5073 auto *FromD1Part =
5074 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match(
5075 FromTU, varTemplatePartialSpecializationDecl(hasName("X1")));
5076 auto *FromD2 = FirstDeclMatcher<VarTemplateDecl>().match(
5077 FromTU, varTemplateDecl(hasName("X2")));
5078 auto *FromD2Part =
5079 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match(
5080 FromTU, varTemplatePartialSpecializationDecl(hasName("X2")));
5082 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5083 FromD1->getDeclContext());
5084 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5085 FromD2->getDeclContext());
5087 ASSERT_EQ(FromD1Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5088 FromD1Part->getDeclContext());
5089 // FIXME: VarTemplatePartialSpecializationDecl does not update ("adopt")
5090 // template parameter decl context
5091 // ASSERT_EQ(FromD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5092 // FromD2Part->getDeclContext());
5094 auto *ToD1 = Import(FromD1, Lang_CXX14);
5095 auto *ToD2 = Import(FromD2, Lang_CXX14);
5097 auto *ToD1Part = Import(FromD1Part, Lang_CXX14);
5098 auto *ToD2Part = Import(FromD2Part, Lang_CXX14);
5100 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5101 ToD1->getDeclContext());
5102 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5103 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0)));
5104 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5105 ToD2->getDeclContext());
5106 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5107 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0)));
5109 EXPECT_EQ(ToD1Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5110 ToD1Part->getDeclContext());
5111 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5112 ToD1Part->getDeclContext(),
5113 ToD1Part->getTemplateParameters()->getParam(0)));
5114 // EXPECT_EQ(ToD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5115 // ToD2Part->getDeclContext());
5116 // EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5117 // ToD2Part->getDeclContext(),
5118 // ToD2Part->getTemplateParameters()->getParam(0)));
5119 (void)ToD2Part;
5122 TEST_P(ASTImporterOptionSpecificTestBase,
5123 TypeAliasTemplateParameterDeclContext) {
5124 constexpr auto Code =
5126 template<class T1, class T2>
5127 struct S {};
5128 template<class T> using S1 = S<T, int>;
5129 namespace Ns {
5130 template<class T> using S2 = S<T, int>;
5134 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
5136 auto *FromD1 = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
5137 FromTU, typeAliasTemplateDecl(hasName("S1")));
5138 auto *FromD2 = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
5139 FromTU, typeAliasTemplateDecl(hasName("S2")));
5141 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5142 FromD1->getDeclContext());
5143 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5144 FromD2->getDeclContext());
5146 auto *ToD1 = Import(FromD1, Lang_CXX11);
5147 auto *ToD2 = Import(FromD2, Lang_CXX11);
5149 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5150 ToD1->getDeclContext());
5151 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5152 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0)));
5153 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5154 ToD2->getDeclContext());
5155 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5156 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0)));
5159 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmType) {
5160 constexpr auto Code = R"(
5161 template <class A1, class... A2> struct A {
5162 using B = A1(A2...);
5164 template struct A<void, char, float, int, short>;
5166 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp");
5167 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5168 FromTU, classTemplateSpecializationDecl());
5170 auto testType = [&](ASTContext &Ctx, const char *Name,
5171 std::optional<unsigned> PackIndex) {
5172 const auto *Subst = selectFirst<SubstTemplateTypeParmType>(
5173 "sttp", match(substTemplateTypeParmType(
5174 hasReplacementType(hasCanonicalType(asString(Name))))
5175 .bind("sttp"),
5176 Ctx));
5177 const char *ExpectedTemplateParamName = PackIndex ? "A2" : "A1";
5178 ASSERT_TRUE(Subst);
5179 ASSERT_EQ(Subst->getReplacedParameter()->getIdentifier()->getName(),
5180 ExpectedTemplateParamName);
5181 ASSERT_EQ(Subst->getPackIndex(), PackIndex);
5183 auto tests = [&](ASTContext &Ctx) {
5184 testType(Ctx, "void", std::nullopt);
5185 testType(Ctx, "char", 3);
5186 testType(Ctx, "float", 2);
5187 testType(Ctx, "int", 1);
5188 testType(Ctx, "short", 0);
5191 tests(FromTU->getASTContext());
5193 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11);
5194 tests(ToClass->getASTContext());
5197 const AstTypeMatcher<SubstTemplateTypeParmPackType>
5198 substTemplateTypeParmPackType;
5200 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmPackType) {
5201 constexpr auto Code = R"(
5202 template<typename ...T> struct D {
5203 template<typename... U> using B = int(int (*...p)(T, U));
5204 template<typename U1, typename U2> D(B<U1, U2>*);
5206 int f(int(int, int), int(int, int));
5208 using asd = D<float, double, float>::B<int, long, int>;
5210 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp");
5211 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5212 FromTU, classTemplateSpecializationDecl());
5215 ASTContext &FromCtx = FromTU->getASTContext();
5216 const auto *FromSubstPack = selectFirst<SubstTemplateTypeParmPackType>(
5217 "pack", match(substTemplateTypeParmPackType().bind("pack"), FromCtx));
5219 ASSERT_TRUE(FromSubstPack);
5220 ASSERT_EQ(FromSubstPack->getIdentifier()->getName(), "T");
5221 ArrayRef<TemplateArgument> FromArgPack =
5222 FromSubstPack->getArgumentPack().pack_elements();
5223 ASSERT_EQ(FromArgPack.size(), 3u);
5224 ASSERT_EQ(FromArgPack[0].getAsType(), FromCtx.FloatTy);
5225 ASSERT_EQ(FromArgPack[1].getAsType(), FromCtx.DoubleTy);
5226 ASSERT_EQ(FromArgPack[2].getAsType(), FromCtx.FloatTy);
5229 // Let's do the import.
5230 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11);
5231 ASTContext &ToCtx = ToClass->getASTContext();
5233 const auto *ToSubstPack = selectFirst<SubstTemplateTypeParmPackType>(
5234 "pack", match(substTemplateTypeParmPackType().bind("pack"), ToCtx));
5236 // Check if it meets the requirements.
5237 ASSERT_TRUE(ToSubstPack);
5238 ASSERT_EQ(ToSubstPack->getIdentifier()->getName(), "T");
5239 ArrayRef<TemplateArgument> ToArgPack =
5240 ToSubstPack->getArgumentPack().pack_elements();
5241 ASSERT_EQ(ToArgPack.size(), 3u);
5242 ASSERT_EQ(ToArgPack[0].getAsType(), ToCtx.FloatTy);
5243 ASSERT_EQ(ToArgPack[1].getAsType(), ToCtx.DoubleTy);
5244 ASSERT_EQ(ToArgPack[2].getAsType(), ToCtx.FloatTy);
5248 struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {};
5250 TEST_P(ASTImporterLookupTableTest, OneDecl) {
5251 auto *ToTU = getToTuDecl("int a;", Lang_CXX03);
5252 auto *D = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("a")));
5253 ASTImporterLookupTable LT(*ToTU);
5254 auto Res = LT.lookup(ToTU, D->getDeclName());
5255 ASSERT_EQ(Res.size(), 1u);
5256 EXPECT_EQ(*Res.begin(), D);
5259 static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) {
5260 for (Decl *D : DC->decls()) {
5261 if (auto *ND = dyn_cast<NamedDecl>(D))
5262 if (ND->getDeclName() == Name)
5263 return ND;
5265 return nullptr;
5268 TEST_P(ASTImporterLookupTableTest,
5269 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) {
5270 auto *Code = R"(
5271 template <class T>
5272 struct X {
5273 friend void foo(){}
5276 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
5277 auto *X = FirstDeclMatcher<ClassTemplateDecl>().match(
5278 ToTU, classTemplateDecl(hasName("X")));
5279 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
5280 ToTU, functionDecl(hasName("foo")));
5281 DeclContext *FooDC = Foo->getDeclContext();
5282 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
5283 ASSERT_EQ(cast<Decl>(FooLexicalDC), X->getTemplatedDecl());
5284 ASSERT_EQ(cast<Decl>(FooDC), ToTU);
5285 DeclarationName FooName = Foo->getDeclName();
5287 // Cannot find in the LookupTable of its DC (TUDecl)
5288 SmallVector<NamedDecl *, 2> FoundDecls;
5289 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5290 EXPECT_EQ(FoundDecls.size(), 0u);
5292 // Cannot find in the LookupTable of its LexicalDC (X)
5293 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5294 EXPECT_EQ(FoundDecls.size(), 0u);
5296 // Can't find in the list of Decls of the DC.
5297 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
5299 // Can't find in the list of Decls of the LexicalDC
5300 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr);
5302 // ASTImporter specific lookup finds it.
5303 ASTImporterLookupTable LT(*ToTU);
5304 auto Res = LT.lookup(FooDC, Foo->getDeclName());
5305 ASSERT_EQ(Res.size(), 1u);
5306 EXPECT_EQ(*Res.begin(), Foo);
5309 TEST_P(ASTImporterLookupTableTest,
5310 FwdDeclStructShouldBeFoundByImporterSpecificLookup) {
5311 TranslationUnitDecl *ToTU =
5312 getToTuDecl("struct A { struct Foo *p; };", Lang_C99);
5313 auto *Foo =
5314 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("Foo")));
5315 auto *A =
5316 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
5317 DeclContext *FooDC = Foo->getDeclContext();
5318 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
5319 ASSERT_EQ(cast<Decl>(FooLexicalDC), A);
5320 ASSERT_EQ(cast<Decl>(FooDC), ToTU);
5321 DeclarationName FooName = Foo->getDeclName();
5323 // Cannot find in the LookupTable of its DC (TUDecl).
5324 SmallVector<NamedDecl *, 2> FoundDecls;
5325 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5326 EXPECT_EQ(FoundDecls.size(), 0u);
5328 // Finds via linear search of its LexicalDC (A).
5329 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5330 EXPECT_EQ(FoundDecls.size(), 1u);
5332 // Can't find in the list of Decls of the DC.
5333 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
5335 // Can find in the list of Decls of the LexicalDC.
5336 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo);
5338 // ASTImporter specific lookup finds it.
5339 ASTImporterLookupTable LT(*ToTU);
5340 auto Res = LT.lookup(FooDC, Foo->getDeclName());
5341 ASSERT_EQ(Res.size(), 1u);
5342 EXPECT_EQ(*Res.begin(), Foo);
5345 TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) {
5346 TranslationUnitDecl *ToTU =
5347 getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99);
5348 DeclarationName VName = FirstDeclMatcher<VarDecl>()
5349 .match(ToTU, varDecl(hasName("V")))
5350 ->getDeclName();
5351 auto *A =
5352 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
5353 auto *B =
5354 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("B")));
5356 ASTImporterLookupTable LT(*ToTU);
5358 auto Res = LT.lookup(cast<DeclContext>(A), VName);
5359 ASSERT_EQ(Res.size(), 1u);
5360 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
5361 ToTU, fieldDecl(hasName("V"),
5362 hasParent(recordDecl(hasName("A"))))));
5363 Res = LT.lookup(cast<DeclContext>(B), VName);
5364 ASSERT_EQ(Res.size(), 1u);
5365 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
5366 ToTU, fieldDecl(hasName("V"),
5367 hasParent(recordDecl(hasName("B"))))));
5368 Res = LT.lookup(ToTU, VName);
5369 ASSERT_EQ(Res.size(), 1u);
5370 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<VarDecl>().match(
5371 ToTU, varDecl(hasName("V"),
5372 hasParent(translationUnitDecl()))));
5375 TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) {
5376 TranslationUnitDecl *ToTU = getToTuDecl(
5378 void foo();
5379 void foo(int);
5380 void foo(int, int);
5382 Lang_CXX03);
5384 ASTImporterLookupTable LT(*ToTU);
5385 auto *F0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
5386 auto *F2 = LastDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
5387 DeclarationName Name = F0->getDeclName();
5388 auto Res = LT.lookup(ToTU, Name);
5389 EXPECT_EQ(Res.size(), 3u);
5390 EXPECT_EQ(Res.count(F0), 1u);
5391 EXPECT_EQ(Res.count(F2), 1u);
5394 TEST_P(ASTImporterLookupTableTest,
5395 DifferentOperatorsShouldHaveDifferentResultSet) {
5396 TranslationUnitDecl *ToTU = getToTuDecl(
5398 struct X{};
5399 void operator+(X, X);
5400 void operator-(X, X);
5402 Lang_CXX03);
5404 ASTImporterLookupTable LT(*ToTU);
5405 auto *FPlus = FirstDeclMatcher<FunctionDecl>().match(
5406 ToTU, functionDecl(hasOverloadedOperatorName("+")));
5407 auto *FMinus = FirstDeclMatcher<FunctionDecl>().match(
5408 ToTU, functionDecl(hasOverloadedOperatorName("-")));
5409 DeclarationName NamePlus = FPlus->getDeclName();
5410 auto ResPlus = LT.lookup(ToTU, NamePlus);
5411 EXPECT_EQ(ResPlus.size(), 1u);
5412 EXPECT_EQ(ResPlus.count(FPlus), 1u);
5413 EXPECT_EQ(ResPlus.count(FMinus), 0u);
5414 DeclarationName NameMinus = FMinus->getDeclName();
5415 auto ResMinus = LT.lookup(ToTU, NameMinus);
5416 EXPECT_EQ(ResMinus.size(), 1u);
5417 EXPECT_EQ(ResMinus.count(FMinus), 1u);
5418 EXPECT_EQ(ResMinus.count(FPlus), 0u);
5419 EXPECT_NE(*ResMinus.begin(), *ResPlus.begin());
5422 TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) {
5423 TranslationUnitDecl *ToTU = getToTuDecl(
5425 struct X {};
5426 void operator+(X, X);
5428 Lang_CXX03);
5429 auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match(
5430 ToTU, functionDecl(hasOverloadedOperatorName("+")));
5432 Decl *FromTU = getTuDecl(
5434 struct X {};
5435 void operator+(X, X);
5437 Lang_CXX03);
5438 auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match(
5439 FromTU, functionDecl(hasOverloadedOperatorName("+")));
5441 // FromPlus have a different TU, thus its DeclarationName is different too.
5442 ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName());
5444 ASTImporterLookupTable LT(*ToTU);
5445 auto Res = LT.lookup(ToTU, ToPlus->getDeclName());
5446 ASSERT_EQ(Res.size(), 1u);
5447 EXPECT_EQ(*Res.begin(), ToPlus);
5449 // FromPlus have a different TU, thus its DeclarationName is different too.
5450 Res = LT.lookup(ToTU, FromPlus->getDeclName());
5451 ASSERT_EQ(Res.size(), 0u);
5454 TEST_P(ASTImporterLookupTableTest,
5455 LookupFindsFwdFriendClassDeclWithElaboratedType) {
5456 TranslationUnitDecl *ToTU = getToTuDecl(
5458 class Y { friend class F; };
5460 Lang_CXX03);
5462 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5463 // So we must dig up the underlying CXXRecordDecl.
5464 ASTImporterLookupTable LT(*ToTU);
5465 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5466 const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
5467 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(
5468 ToTU, cxxRecordDecl(hasName("Y")));
5470 DeclarationName Name = RD->getDeclName();
5471 auto Res = LT.lookup(ToTU, Name);
5472 EXPECT_EQ(Res.size(), 1u);
5473 EXPECT_EQ(*Res.begin(), RD);
5475 Res = LT.lookup(Y, Name);
5476 EXPECT_EQ(Res.size(), 0u);
5479 TEST_P(ASTImporterLookupTableTest,
5480 LookupFindsFwdFriendClassDeclWithUnelaboratedType) {
5481 TranslationUnitDecl *ToTU = getToTuDecl(
5483 class F;
5484 class Y { friend F; };
5486 Lang_CXX11);
5488 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5489 // So we must dig up the underlying CXXRecordDecl.
5490 ASTImporterLookupTable LT(*ToTU);
5491 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5492 const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
5493 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, cxxRecordDecl(hasName("Y")));
5495 DeclarationName Name = RD->getDeclName();
5496 auto Res = LT.lookup(ToTU, Name);
5497 EXPECT_EQ(Res.size(), 1u);
5498 EXPECT_EQ(*Res.begin(), RD);
5500 Res = LT.lookup(Y, Name);
5501 EXPECT_EQ(Res.size(), 0u);
5504 TEST_P(ASTImporterLookupTableTest,
5505 LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert) {
5506 TranslationUnitDecl *ToTU = getToTuDecl(
5508 class F;
5509 using alias_of_f = F;
5510 class Y { friend alias_of_f; };
5512 Lang_CXX11);
5514 // ASTImporterLookupTable constructor handles using declarations correctly,
5515 // no assert is expected.
5516 ASTImporterLookupTable LT(*ToTU);
5518 auto *Alias = FirstDeclMatcher<TypeAliasDecl>().match(
5519 ToTU, typeAliasDecl(hasName("alias_of_f")));
5520 DeclarationName Name = Alias->getDeclName();
5521 auto Res = LT.lookup(ToTU, Name);
5522 EXPECT_EQ(Res.count(Alias), 1u);
5525 TEST_P(ASTImporterLookupTableTest,
5526 LookupFindsFriendClassDeclWithUsingTypeDoesNotAssert) {
5527 TranslationUnitDecl *ToTU = getToTuDecl(
5529 namespace a {
5530 namespace b { class InnerClass; }
5531 using b::InnerClass;
5533 class B {
5534 friend a::InnerClass;
5537 Lang_CXX11);
5539 // ASTImporterLookupTable constructor handles friend with using-type without
5540 // asserts.
5541 ASTImporterLookupTable LT(*ToTU);
5543 auto *Using = FirstDeclMatcher<UsingDecl>().match(
5544 ToTU, usingDecl(hasName("InnerClass")));
5545 DeclarationName Name = Using->getDeclName();
5546 auto Res = LT.lookup(ToTU, Name);
5547 EXPECT_EQ(Res.size(), 0u);
5548 auto *NsA = FirstDeclMatcher<NamespaceDecl>().match(
5549 ToTU, namespaceDecl(hasName("a")));
5550 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
5551 ToTU, cxxRecordDecl(hasName("B")));
5552 auto Res1 = LT.lookup(NsA, Name);
5553 EXPECT_EQ(Res1.count(Using), 1u);
5554 auto Res2 = LT.lookup(RecordB, Name);
5555 EXPECT_EQ(Res2.size(), 0u);
5558 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) {
5559 TranslationUnitDecl *ToTU = getToTuDecl(
5561 class Y { template <class T> friend class F; };
5563 Lang_CXX03);
5565 ASTImporterLookupTable LT(*ToTU);
5566 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5567 ToTU, classTemplateDecl(hasName("F")));
5568 DeclarationName Name = F->getDeclName();
5569 auto Res = LT.lookup(ToTU, Name);
5570 EXPECT_EQ(Res.size(), 2u);
5571 EXPECT_EQ(Res.count(F), 1u);
5572 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5575 TEST_P(ASTImporterLookupTableTest, DependentFriendClass) {
5576 TranslationUnitDecl *ToTU = getToTuDecl(
5578 template <typename T>
5579 class F;
5581 template <typename T>
5582 class Y {
5583 friend class F<T>;
5586 Lang_CXX03);
5588 ASTImporterLookupTable LT(*ToTU);
5589 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5590 ToTU, classTemplateDecl(hasName("F")));
5591 DeclarationName Name = F->getDeclName();
5592 auto Res = LT.lookup(ToTU, Name);
5593 EXPECT_EQ(Res.size(), 2u);
5594 EXPECT_EQ(Res.count(F), 1u);
5595 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5598 TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) {
5599 TranslationUnitDecl *ToTU = getToTuDecl(
5601 template <typename T>
5602 class F;
5604 class Y {
5605 friend class F<int>;
5608 Lang_CXX03);
5610 ASTImporterLookupTable LT(*ToTU);
5611 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5612 ToTU, classTemplateDecl(hasName("F")));
5613 DeclarationName Name = F->getDeclName();
5614 auto Res = LT.lookup(ToTU, Name);
5615 ASSERT_EQ(Res.size(), 3u);
5616 EXPECT_EQ(Res.count(F), 1u);
5617 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5618 EXPECT_EQ(Res.count(*F->spec_begin()), 1u);
5621 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) {
5622 TranslationUnitDecl *ToTU = getToTuDecl(
5624 class Y { friend void F(); };
5626 Lang_CXX03);
5628 ASTImporterLookupTable LT(*ToTU);
5629 auto *F =
5630 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("F")));
5631 DeclarationName Name = F->getDeclName();
5632 auto Res = LT.lookup(ToTU, Name);
5633 EXPECT_EQ(Res.size(), 1u);
5634 EXPECT_EQ(*Res.begin(), F);
5637 TEST_P(ASTImporterLookupTableTest,
5638 LookupFindsDeclsInClassTemplateSpecialization) {
5639 TranslationUnitDecl *ToTU = getToTuDecl(
5641 template <typename T>
5642 struct X {
5643 int F;
5645 void foo() {
5646 X<char> xc;
5649 Lang_CXX03);
5651 ASTImporterLookupTable LT(*ToTU);
5653 auto *Template = FirstDeclMatcher<ClassTemplateDecl>().match(
5654 ToTU, classTemplateDecl(hasName("X")));
5655 auto *FieldInTemplate = FirstDeclMatcher<FieldDecl>().match(
5656 ToTU,
5657 fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl())))));
5659 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5660 ToTU, classTemplateSpecializationDecl(hasName("X")));
5661 FieldDecl *FieldInSpec = *Spec->field_begin();
5662 ASSERT_TRUE(FieldInSpec);
5664 DeclarationName Name = FieldInSpec->getDeclName();
5665 auto TemplateDC = cast<DeclContext>(Template->getTemplatedDecl());
5667 SmallVector<NamedDecl *, 2> FoundDecls;
5668 TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
5669 EXPECT_EQ(FoundDecls.size(), 1u);
5670 EXPECT_EQ(FoundDecls[0], FieldInTemplate);
5672 auto Res = LT.lookup(TemplateDC, Name);
5673 ASSERT_EQ(Res.size(), 1u);
5674 EXPECT_EQ(*Res.begin(), FieldInTemplate);
5676 cast<DeclContext>(Spec)->getRedeclContext()->localUncachedLookup(Name,
5677 FoundDecls);
5678 EXPECT_EQ(FoundDecls.size(), 1u);
5679 EXPECT_EQ(FoundDecls[0], FieldInSpec);
5681 Res = LT.lookup(cast<DeclContext>(Spec), Name);
5682 ASSERT_EQ(Res.size(), 1u);
5683 EXPECT_EQ(*Res.begin(), FieldInSpec);
5686 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) {
5687 TranslationUnitDecl *ToTU = getToTuDecl(
5689 class Y { template <class T> friend void F(); };
5691 Lang_CXX03);
5693 ASTImporterLookupTable LT(*ToTU);
5694 auto *F = FirstDeclMatcher<FunctionTemplateDecl>().match(
5695 ToTU, functionTemplateDecl(hasName("F")));
5696 DeclarationName Name = F->getDeclName();
5697 auto Res = LT.lookup(ToTU, Name);
5698 EXPECT_EQ(Res.size(), 2u);
5699 EXPECT_EQ(Res.count(F), 1u);
5700 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5703 TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) {
5704 TranslationUnitDecl *ToTU = getToTuDecl(
5706 struct X;
5707 struct A {
5708 friend struct X;
5710 struct B {
5711 friend struct X;
5714 Lang_CXX03);
5716 ASTImporterLookupTable LT(*ToTU);
5717 auto *X = FirstDeclMatcher<CXXRecordDecl>().match(
5718 ToTU, cxxRecordDecl(hasName("X")));
5719 auto *FriendD0 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5720 auto *FriendD1 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5721 const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0);
5722 const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1);
5723 ASSERT_EQ(RD0, RD1);
5724 ASSERT_EQ(RD1, X);
5726 DeclarationName Name = X->getDeclName();
5727 auto Res = LT.lookup(ToTU, Name);
5728 EXPECT_EQ(Res.size(), 1u);
5729 EXPECT_EQ(*Res.begin(), X);
5732 TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) {
5733 TranslationUnitDecl *ToTU = getToTuDecl(
5735 enum E {
5740 Lang_C99);
5742 ASTImporterLookupTable LT(*ToTU);
5743 auto *E = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(hasName("E")));
5744 auto *A = FirstDeclMatcher<EnumConstantDecl>().match(
5745 ToTU, enumConstantDecl(hasName("A")));
5747 DeclarationName Name = A->getDeclName();
5748 // Redecl context is the TU.
5749 ASSERT_EQ(E->getRedeclContext(), ToTU);
5751 SmallVector<NamedDecl *, 2> FoundDecls;
5752 // Normal lookup finds in the DC.
5753 E->localUncachedLookup(Name, FoundDecls);
5754 EXPECT_EQ(FoundDecls.size(), 1u);
5756 // Normal lookup finds in the Redecl context.
5757 ToTU->localUncachedLookup(Name, FoundDecls);
5758 EXPECT_EQ(FoundDecls.size(), 1u);
5760 // Import specific lookup finds in the DC.
5761 auto Res = LT.lookup(E, Name);
5762 ASSERT_EQ(Res.size(), 1u);
5763 EXPECT_EQ(*Res.begin(), A);
5765 // Import specific lookup finds in the Redecl context.
5766 Res = LT.lookup(ToTU, Name);
5767 ASSERT_EQ(Res.size(), 1u);
5768 EXPECT_EQ(*Res.begin(), A);
5771 TEST_P(ASTImporterLookupTableTest, LookupSearchesInTheWholeRedeclChain) {
5772 TranslationUnitDecl *ToTU = getToTuDecl(
5774 namespace N {
5775 int A;
5777 namespace N {
5780 Lang_CXX03);
5781 auto *N1 =
5782 LastDeclMatcher<NamespaceDecl>().match(ToTU, namespaceDecl(hasName("N")));
5783 auto *A = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("A")));
5784 DeclarationName Name = A->getDeclName();
5786 ASTImporterLookupTable LT(*ToTU);
5787 auto Res = LT.lookup(N1, Name);
5788 ASSERT_EQ(Res.size(), 1u);
5789 EXPECT_EQ(*Res.begin(), A);
5792 TEST_P(ASTImporterOptionSpecificTestBase,
5793 RedeclChainShouldBeCorrectAmongstNamespaces) {
5794 Decl *FromTU = getTuDecl(
5796 namespace NS {
5797 struct X;
5798 struct Y {
5799 static const int I = 3;
5802 namespace NS {
5803 struct X { // <--- To be imported
5804 void method(int i = Y::I) {}
5805 int f;
5809 Lang_CXX03);
5810 auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match(
5811 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
5812 auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match(
5813 FromTU,
5814 cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit())));
5815 ASSERT_NE(FromFwd, FromDef);
5816 ASSERT_FALSE(FromFwd->isThisDeclarationADefinition());
5817 ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
5818 ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl());
5820 auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX03));
5821 auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX03));
5822 EXPECT_NE(ToFwd, ToDef);
5823 EXPECT_FALSE(ToFwd->isThisDeclarationADefinition());
5824 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
5825 EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl());
5826 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5827 // We expect no (ODR) warning during the import.
5828 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
5831 struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {};
5833 TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
5834 Decl *ToTU = getToTuDecl(
5836 class X {
5837 template <typename T> friend void foo();
5840 Lang_CXX03);
5841 auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match(
5842 ToTU, functionTemplateDecl(hasName("foo")));
5844 Decl *FromTU = getTuDecl(
5846 template <typename T> void foo();
5848 Lang_CXX03);
5849 auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match(
5850 FromTU, functionTemplateDecl(hasName("foo")));
5851 auto *Imported = Import(FromFoo, Lang_CXX03);
5853 EXPECT_EQ(Imported->getPreviousDecl(), Friend);
5856 TEST_P(ImportFriendFunctionTemplates, ImportFriendFunctionInsideClassTemplate) {
5857 Decl *From, *To;
5858 std::tie(From, To) = getImportedDecl(
5860 template <typename T> struct X {
5861 template <typename U> friend void f();
5864 Lang_CXX03, "", Lang_CXX03, "X");
5866 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(From, friendDecl());
5867 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(To, friendDecl());
5869 EXPECT_TRUE(FromFriend ==
5870 LastDeclMatcher<FriendDecl>().match(From, friendDecl()));
5871 EXPECT_TRUE(ToFriend ==
5872 LastDeclMatcher<FriendDecl>().match(To, friendDecl()));
5874 auto *FromDecl = FromFriend->getFriendDecl();
5875 auto *FromDC = FromFriend->getDeclContext();
5876 auto *FromLexicalDC = FromFriend->getLexicalDeclContext();
5878 EXPECT_TRUE(FromDC->containsDecl(FromFriend));
5879 EXPECT_FALSE(FromDC->containsDecl(FromDecl));
5880 EXPECT_TRUE(FromLexicalDC->containsDecl(FromFriend));
5881 EXPECT_FALSE(FromLexicalDC->containsDecl(FromDecl));
5883 auto *ToDecl = ToFriend->getFriendDecl();
5884 auto *ToDC = ToFriend->getDeclContext();
5885 auto *ToLexicalDC = ToFriend->getLexicalDeclContext();
5887 EXPECT_TRUE(ToDC->containsDecl(ToFriend));
5888 EXPECT_FALSE(ToDC->containsDecl(ToDecl));
5889 EXPECT_TRUE(ToLexicalDC->containsDecl(ToFriend));
5890 EXPECT_FALSE(ToLexicalDC->containsDecl(ToDecl));
5893 struct ASTImporterWithFakeErrors : ASTImporter {
5894 using ASTImporter::ASTImporter;
5895 bool returnWithErrorInTest() override { return true; }
5898 struct ErrorHandlingTest : ASTImporterOptionSpecificTestBase {
5899 ErrorHandlingTest() {
5900 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
5901 ASTContext &FromContext, FileManager &FromFileManager,
5902 bool MinimalImport,
5903 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
5904 return new ASTImporterWithFakeErrors(ToContext, ToFileManager,
5905 FromContext, FromFileManager,
5906 MinimalImport, SharedState);
5909 // In this test we purposely report an error (UnsupportedConstruct) when
5910 // importing the below stmt.
5911 static constexpr auto* ErroneousStmt = R"( asm(""); )";
5914 // Check a case when no new AST node is created in the AST before encountering
5915 // the error.
5916 TEST_P(ErrorHandlingTest, ErrorHappensBeforeCreatingANewNode) {
5917 TranslationUnitDecl *ToTU = getToTuDecl(
5919 template <typename T>
5920 class X {};
5921 template <>
5922 class X<int> { int a; };
5924 Lang_CXX03);
5925 TranslationUnitDecl *FromTU = getTuDecl(
5927 template <typename T>
5928 class X {};
5929 template <>
5930 class X<int> { double b; };
5932 Lang_CXX03);
5933 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5934 FromTU, classTemplateSpecializationDecl(hasName("X")));
5935 ClassTemplateSpecializationDecl *ImportedSpec = Import(FromSpec, Lang_CXX03);
5936 EXPECT_FALSE(ImportedSpec);
5938 // The original Decl is kept, no new decl is created.
5939 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(
5940 ToTU, classTemplateSpecializationDecl(hasName("X"))),
5941 1u);
5943 // But an error is set to the counterpart in the "from" context.
5944 ASTImporter *Importer = findFromTU(FromSpec)->Importer.get();
5945 std::optional<ASTImportError> OptErr =
5946 Importer->getImportDeclErrorIfAny(FromSpec);
5947 ASSERT_TRUE(OptErr);
5948 EXPECT_EQ(OptErr->Error, ASTImportError::NameConflict);
5951 // Check a case when a new AST node is created but not linked to the AST before
5952 // encountering the error.
5953 TEST_P(ErrorHandlingTest,
5954 ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST) {
5955 TranslationUnitDecl *FromTU = getTuDecl(
5956 std::string("void foo() { ") + ErroneousStmt + " }", Lang_CXX03);
5957 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
5958 FromTU, functionDecl(hasName("foo")));
5960 FunctionDecl *ImportedFoo = Import(FromFoo, Lang_CXX03);
5961 EXPECT_FALSE(ImportedFoo);
5963 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5964 // Created, but not linked.
5965 EXPECT_EQ(
5966 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("foo"))),
5967 0u);
5969 ASTImporter *Importer = findFromTU(FromFoo)->Importer.get();
5970 std::optional<ASTImportError> OptErr =
5971 Importer->getImportDeclErrorIfAny(FromFoo);
5972 ASSERT_TRUE(OptErr);
5973 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5976 // Check a case when a new AST node is created and linked to the AST before
5977 // encountering the error. The error is set for the counterpart of the nodes in
5978 // the "from" context.
5979 TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) {
5980 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5981 void f();
5982 void f() { )") + ErroneousStmt + R"( }
5984 Lang_CXX03);
5985 auto *FromProto = FirstDeclMatcher<FunctionDecl>().match(
5986 FromTU, functionDecl(hasName("f")));
5987 auto *FromDef =
5988 LastDeclMatcher<FunctionDecl>().match(FromTU, functionDecl(hasName("f")));
5989 FunctionDecl *ImportedProto = Import(FromProto, Lang_CXX03);
5990 EXPECT_FALSE(ImportedProto); // Could not import.
5991 // However, we created two nodes in the AST. 1) the fwd decl 2) the
5992 // definition. The definition is not added to its DC, but the fwd decl is
5993 // there.
5994 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5995 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
5996 1u);
5997 // Match the fwd decl.
5998 auto *ToProto =
5999 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("f")));
6000 EXPECT_TRUE(ToProto);
6001 // An error is set to the counterpart in the "from" context both for the fwd
6002 // decl and the definition.
6003 ASTImporter *Importer = findFromTU(FromProto)->Importer.get();
6004 std::optional<ASTImportError> OptErr =
6005 Importer->getImportDeclErrorIfAny(FromProto);
6006 ASSERT_TRUE(OptErr);
6007 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6008 OptErr = Importer->getImportDeclErrorIfAny(FromDef);
6009 ASSERT_TRUE(OptErr);
6010 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6013 // An error should be set for a class if we cannot import one member.
6014 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) {
6015 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6016 class X {
6017 void f() { )") + ErroneousStmt + R"( } // This member has the error
6018 // during import.
6019 void ok(); // The error should not prevent importing this.
6020 }; // An error will be set for X too.
6022 Lang_CXX03);
6023 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6024 FromTU, cxxRecordDecl(hasName("X")));
6025 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
6027 // An error is set for X.
6028 EXPECT_FALSE(ImportedX);
6029 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6030 std::optional<ASTImportError> OptErr =
6031 Importer->getImportDeclErrorIfAny(FromX);
6032 ASSERT_TRUE(OptErr);
6033 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6035 // An error is set for f().
6036 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
6037 FromTU, cxxMethodDecl(hasName("f")));
6038 OptErr = Importer->getImportDeclErrorIfAny(FromF);
6039 ASSERT_TRUE(OptErr);
6040 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6041 // And any subsequent import should fail.
6042 CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03);
6043 EXPECT_FALSE(ImportedF);
6045 // There is an error set for the other member too.
6046 auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match(
6047 FromTU, cxxMethodDecl(hasName("ok")));
6048 OptErr = Importer->getImportDeclErrorIfAny(FromOK);
6049 EXPECT_TRUE(OptErr);
6050 // Cannot import the other member.
6051 CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03);
6052 EXPECT_FALSE(ImportedOK);
6055 // Check that an error propagates to the dependent AST nodes.
6056 // In the below code it means that an error in X should propagate to A.
6057 // And even to F since the containing A is erroneous.
6058 // And to all AST nodes which we visit during the import process which finally
6059 // ends up in a failure (in the error() function).
6060 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) {
6061 Decl *FromTU = getTuDecl(std::string(R"(
6062 namespace NS {
6063 class A {
6064 template <int I> class F {};
6065 class X {
6066 template <int I> friend class F;
6067 void error() { )") +
6068 ErroneousStmt + R"( }
6072 class B {};
6073 } // NS
6075 Lang_CXX03, "input0.cc");
6077 auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match(
6078 FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
6079 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
6080 FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
6081 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match(
6082 FromTU, cxxRecordDecl(hasName("B"), isDefinition()));
6083 auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match(
6084 FromTU, namespaceDecl(hasName("NS")));
6086 // Start by importing the templated CXXRecordDecl of F.
6087 // Import fails for that.
6088 EXPECT_FALSE(Import(FromFRD, Lang_CXX03));
6089 // Import fails for A.
6090 EXPECT_FALSE(Import(FromA, Lang_CXX03));
6091 // But we should be able to import the independent B.
6092 EXPECT_TRUE(Import(FromB, Lang_CXX03));
6093 // And the namespace.
6094 EXPECT_TRUE(Import(FromNS, Lang_CXX03));
6096 // An error is set to the templated CXXRecordDecl of F.
6097 ASTImporter *Importer = findFromTU(FromFRD)->Importer.get();
6098 std::optional<ASTImportError> OptErr =
6099 Importer->getImportDeclErrorIfAny(FromFRD);
6100 EXPECT_TRUE(OptErr);
6102 // An error is set to A.
6103 OptErr = Importer->getImportDeclErrorIfAny(FromA);
6104 EXPECT_TRUE(OptErr);
6106 // There is no error set to B.
6107 OptErr = Importer->getImportDeclErrorIfAny(FromB);
6108 EXPECT_FALSE(OptErr);
6110 // There is no error set to NS.
6111 OptErr = Importer->getImportDeclErrorIfAny(FromNS);
6112 EXPECT_FALSE(OptErr);
6114 // Check some of those decls whose ancestor is X, they all should have an
6115 // error set if we visited them during an import process which finally failed.
6116 // These decls are part of a cycle in an ImportPath.
6117 // There would not be any error set for these decls if we hadn't follow the
6118 // ImportPaths and the cycles.
6119 OptErr = Importer->getImportDeclErrorIfAny(
6120 FirstDeclMatcher<ClassTemplateDecl>().match(
6121 FromTU, classTemplateDecl(hasName("F"))));
6122 // An error is set to the 'F' ClassTemplateDecl.
6123 EXPECT_TRUE(OptErr);
6124 // An error is set to the FriendDecl.
6125 OptErr = Importer->getImportDeclErrorIfAny(
6126 FirstDeclMatcher<FriendDecl>().match(
6127 FromTU, friendDecl()));
6128 EXPECT_TRUE(OptErr);
6129 // An error is set to the implicit class of A.
6130 OptErr =
6131 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
6132 FromTU, cxxRecordDecl(hasName("A"), isImplicit())));
6133 EXPECT_TRUE(OptErr);
6134 // An error is set to the implicit class of X.
6135 OptErr =
6136 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
6137 FromTU, cxxRecordDecl(hasName("X"), isImplicit())));
6138 EXPECT_TRUE(OptErr);
6141 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) {
6142 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6143 namespace X {
6144 void f() { )") + ErroneousStmt + R"( } // This member has the error
6145 // during import.
6146 void ok(); // The error should not prevent importing this.
6147 }; // An error will be set for X too.
6149 Lang_CXX03);
6150 auto *FromX = FirstDeclMatcher<NamespaceDecl>().match(
6151 FromTU, namespaceDecl(hasName("X")));
6152 NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03);
6154 // There is no error set for X.
6155 EXPECT_TRUE(ImportedX);
6156 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6157 std::optional<ASTImportError> OptErr =
6158 Importer->getImportDeclErrorIfAny(FromX);
6159 ASSERT_FALSE(OptErr);
6161 // An error is set for f().
6162 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
6163 FromTU, functionDecl(hasName("f")));
6164 OptErr = Importer->getImportDeclErrorIfAny(FromF);
6165 ASSERT_TRUE(OptErr);
6166 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6167 // And any subsequent import should fail.
6168 FunctionDecl *ImportedF = Import(FromF, Lang_CXX03);
6169 EXPECT_FALSE(ImportedF);
6171 // There is no error set for ok().
6172 auto *FromOK = FirstDeclMatcher<FunctionDecl>().match(
6173 FromTU, functionDecl(hasName("ok")));
6174 OptErr = Importer->getImportDeclErrorIfAny(FromOK);
6175 EXPECT_FALSE(OptErr);
6176 // And we should be able to import.
6177 FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03);
6178 EXPECT_TRUE(ImportedOK);
6181 TEST_P(ErrorHandlingTest, ODRViolationWithinTypedefDecls) {
6182 // Importing `z` should fail - instead of crashing - due to an ODR violation.
6183 // The `bar::e` typedef sets it's DeclContext after the import is done.
6184 // However, if the importation fails, it will be left as a nullptr.
6185 // During the cleanup of the failed import, we should check whether the
6186 // DeclContext is null or not - instead of dereferencing that unconditionally.
6187 constexpr auto ToTUCode = R"(
6188 namespace X {
6189 struct bar {
6190 int odr_violation;
6192 })";
6193 constexpr auto FromTUCode = R"(
6194 namespace X {
6195 enum b {};
6196 struct bar {
6197 typedef b e;
6198 static e d;
6201 int z = X::bar::d;
6203 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
6204 static_cast<void>(ToTU);
6205 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
6206 auto *FromZ =
6207 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("z")));
6208 ASSERT_TRUE(FromZ);
6209 ASSERT_TRUE(FromZ->hasInit());
6211 auto *ImportedZ = Import(FromZ, Lang_CXX11);
6212 EXPECT_FALSE(ImportedZ);
6215 // An error should be set for a class if it had a previous import with an error
6216 // from another TU.
6217 TEST_P(ErrorHandlingTest,
6218 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) {
6219 // We already have a fwd decl.
6220 TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03);
6221 // Then we import a definition.
6223 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6224 class X {
6225 void f() { )") + ErroneousStmt + R"( }
6226 void ok();
6229 Lang_CXX03);
6230 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6231 FromTU, cxxRecordDecl(hasName("X")));
6232 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
6234 // An error is set for X ...
6235 EXPECT_FALSE(ImportedX);
6236 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6237 std::optional<ASTImportError> OptErr =
6238 Importer->getImportDeclErrorIfAny(FromX);
6239 ASSERT_TRUE(OptErr);
6240 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6242 // ... but the node had been created.
6243 auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match(
6244 ToTU, cxxRecordDecl(hasName("X"), isDefinition()));
6245 // An error is set for "ToXDef" in the shared state.
6246 std::optional<ASTImportError> OptErr =
6247 SharedStatePtr->getImportDeclErrorIfAny(ToXDef);
6248 ASSERT_TRUE(OptErr);
6249 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6251 auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match(
6252 ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition())));
6253 // An error is NOT set for the fwd Decl of X in the shared state.
6254 OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd);
6255 ASSERT_FALSE(OptErr);
6257 // Try to import X again but from another TU.
6259 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6260 class X {
6261 void f() { )") + ErroneousStmt + R"( }
6262 void ok();
6265 Lang_CXX03, "input1.cc");
6267 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6268 FromTU, cxxRecordDecl(hasName("X")));
6269 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
6271 // If we did not save the errors for the "to" context then the below checks
6272 // would fail, because the lookup finds the fwd Decl of the existing
6273 // definition in the "to" context. We can reach the existing definition via
6274 // the found fwd Decl. That existing definition is structurally equivalent
6275 // (we check only the fields) with this one we want to import, so we return
6276 // with the existing definition, which is erroneous (one method is missing).
6278 // The import should fail.
6279 EXPECT_FALSE(ImportedX);
6280 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6281 std::optional<ASTImportError> OptErr =
6282 Importer->getImportDeclErrorIfAny(FromX);
6283 // And an error is set for this new X in the "from" ctx.
6284 ASSERT_TRUE(OptErr);
6285 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6289 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) {
6290 auto MatchFooA =
6291 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A"))));
6292 auto MatchFooB =
6293 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B"))));
6294 auto MatchFooC =
6295 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C"))));
6297 // Provoke import of a method that has overridden methods with import error.
6298 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6299 struct C;
6300 struct A {
6301 virtual void foo();
6302 void f1(C *);
6304 void A::foo() {
6305 )") + ErroneousStmt + R"(
6307 struct B : public A {
6308 void foo() override;
6310 struct C : public B {
6311 void foo() override;
6314 Lang_CXX11);
6315 auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA);
6316 auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB);
6317 auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC);
6319 EXPECT_FALSE(Import(FromFooA, Lang_CXX11));
6320 ASTImporter *Importer = findFromTU(FromFooA)->Importer.get();
6321 auto CheckError = [&Importer](Decl *FromD) {
6322 std::optional<ASTImportError> OptErr =
6323 Importer->getImportDeclErrorIfAny(FromD);
6324 ASSERT_TRUE(OptErr);
6325 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6327 CheckError(FromFooA);
6328 EXPECT_FALSE(Import(FromFooB, Lang_CXX11));
6329 CheckError(FromFooB);
6330 EXPECT_FALSE(Import(FromFooC, Lang_CXX11));
6331 CheckError(FromFooC);
6334 TEST_P(ErrorHandlingTest, ODRViolationWithinParmVarDecls) {
6335 // Importing of 'f' and parameter 'P' should cause an ODR error.
6336 // The error happens after the ParmVarDecl for 'P' was already created.
6337 // This is a special case because the ParmVarDecl has a temporary DeclContext.
6338 // Expected is no crash at error handling of ASTImporter.
6339 constexpr auto ToTUCode = R"(
6340 struct X {
6341 char A;
6344 constexpr auto FromTUCode = R"(
6345 struct X {
6346 enum Y { Z };
6348 void f(int P = X::Z);
6350 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
6351 static_cast<void>(ToTU);
6352 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
6353 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
6354 FromTU, functionDecl(hasName("f")));
6355 ASSERT_TRUE(FromF);
6357 auto *ImportedF = Import(FromF, Lang_CXX11);
6358 EXPECT_FALSE(ImportedF);
6361 TEST_P(ErrorHandlingTest, DoNotInheritErrorFromNonDependentChild) {
6362 // Declarations should not inherit an import error from a child object
6363 // if the declaration has no direct dependence to such a child.
6364 // For example a namespace should not get import error if one of the
6365 // declarations inside it fails to import.
6366 // There was a special case in error handling (when "import path circles" are
6367 // encountered) when this property was not held. This case is provoked by the
6368 // following code.
6369 constexpr auto ToTUCode = R"(
6370 namespace ns {
6371 struct Err {
6372 char A;
6376 constexpr auto FromTUCode = R"(
6377 namespace ns {
6378 struct A {
6379 using U = struct Err;
6382 namespace ns {
6383 struct Err {}; // ODR violation
6384 void f(A) {}
6388 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
6389 static_cast<void>(ToTU);
6390 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
6391 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
6392 FromTU, cxxRecordDecl(hasName("A"), hasDefinition()));
6393 ASSERT_TRUE(FromA);
6394 auto *ImportedA = Import(FromA, Lang_CXX11);
6395 // 'A' can not be imported: ODR error at 'Err'
6396 EXPECT_FALSE(ImportedA);
6397 // When import of 'A' failed there was a "saved import path circle" that
6398 // contained namespace 'ns' (A - U - Err - ns - f - A). This should not mean
6399 // that every object in this path fails to import.
6401 Decl *FromNS = FirstDeclMatcher<NamespaceDecl>().match(
6402 FromTU, namespaceDecl(hasName("ns")));
6403 EXPECT_TRUE(FromNS);
6404 auto *ImportedNS = Import(FromNS, Lang_CXX11);
6405 EXPECT_TRUE(ImportedNS);
6408 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) {
6409 Decl *FromTU = getTuDecl(
6411 void f() {
6412 auto L = [](){};
6415 Lang_CXX11, "input0.cc");
6416 auto Pattern = lambdaExpr();
6417 CXXRecordDecl *FromL =
6418 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6420 auto ToL = Import(FromL, Lang_CXX11);
6421 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
6422 unsigned FromLSize =
6423 std::distance(FromL->decls().begin(), FromL->decls().end());
6424 EXPECT_NE(ToLSize, 0u);
6425 EXPECT_EQ(ToLSize, FromLSize);
6426 EXPECT_FALSE(FromL->isDependentLambda());
6429 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
6430 Decl *FromTU = getTuDecl(
6432 template <typename F>
6433 void f(F L = [](){}) {}
6435 Lang_CXX11, "input0.cc");
6436 auto Pattern = lambdaExpr();
6437 CXXRecordDecl *FromL =
6438 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6440 auto ToL = Import(FromL, Lang_CXX11);
6441 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
6442 unsigned FromLSize =
6443 std::distance(FromL->decls().begin(), FromL->decls().end());
6444 EXPECT_NE(ToLSize, 0u);
6445 EXPECT_EQ(ToLSize, FromLSize);
6446 EXPECT_TRUE(FromL->isDependentLambda());
6449 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) {
6450 Decl *FromTU = getTuDecl(
6452 auto l1 = [](unsigned lp) { return 1; };
6453 auto l2 = [](int lp) { return 2; };
6454 int f(int p) {
6455 return l1(p) + l2(p);
6458 Lang_CXX11, "input0.cc");
6459 FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match(
6460 FromTU, functionDecl(hasName("f")));
6461 FunctionDecl *ToF = Import(FromF, Lang_CXX11);
6462 EXPECT_TRUE(ToF);
6465 TEST_P(ASTImporterOptionSpecificTestBase,
6466 ImportExistingFriendClassTemplateDef) {
6467 auto Code =
6469 template <class T1, class T2>
6470 struct Base {
6471 template <class U1, class U2>
6472 friend struct Class;
6474 template <class T1, class T2>
6475 struct Class { };
6478 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
6479 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
6481 auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
6482 ToTU, classTemplateDecl(hasName("Class")));
6483 auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
6484 ToTU, classTemplateDecl(hasName("Class")));
6485 ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition());
6486 ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition());
6487 // Previous friend decl is not linked to it!
6488 ASSERT_FALSE(ToClassDef->getPreviousDecl());
6489 ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef);
6490 ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto);
6492 auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
6493 FromTU, classTemplateDecl(hasName("Class")));
6494 auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
6495 FromTU, classTemplateDecl(hasName("Class")));
6496 ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition());
6497 ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition());
6498 ASSERT_FALSE(FromClassDef->getPreviousDecl());
6499 ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef);
6500 ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto);
6502 auto *ImportedDef = Import(FromClassDef, Lang_CXX03);
6503 // At import we should find the definition for 'Class' even if the
6504 // prototype (inside 'friend') for it comes first in the AST and is not
6505 // linked to the definition.
6506 EXPECT_EQ(ImportedDef, ToClassDef);
6509 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase {
6510 LLDBLookupTest() {
6511 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
6512 ASTContext &FromContext, FileManager &FromFileManager,
6513 bool MinimalImport,
6514 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
6515 return new ASTImporter(ToContext, ToFileManager, FromContext,
6516 FromFileManager, MinimalImport,
6517 // We use the regular lookup.
6518 /*SharedState=*/nullptr);
6523 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) {
6524 TranslationUnitDecl *ToTU = getToTuDecl(
6526 extern "C" {
6527 class X{};
6530 Lang_CXX03);
6531 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match(
6532 ToTU, cxxRecordDecl(hasName("X")));
6534 // Set up a stub external storage.
6535 ToTU->setHasExternalLexicalStorage(true);
6536 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true.
6537 ToTU->setMustBuildLookupTable();
6538 struct TestExternalASTSource : ExternalASTSource {};
6539 ToTU->getASTContext().setExternalSource(new TestExternalASTSource());
6541 Decl *FromTU = getTuDecl(
6543 class X;
6545 Lang_CXX03);
6546 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6547 FromTU, cxxRecordDecl(hasName("X")));
6548 auto *ImportedX = Import(FromX, Lang_CXX03);
6549 // The lookup must find the existing class definition in the LinkageSpecDecl.
6550 // Then the importer renders the existing and the new decl into one chain.
6551 EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl());
6554 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {};
6556 TEST_P(SVEBuiltins, ImportTypes) {
6557 static const char *const TypeNames[] = {
6558 "__SVInt8_t", "__SVInt16_t", "__SVInt32_t", "__SVInt64_t",
6559 "__SVUint8_t", "__SVUint16_t", "__SVUint32_t", "__SVUint64_t",
6560 "__SVFloat16_t", "__SVBfloat16_t", "__SVFloat32_t", "__SVFloat64_t",
6561 "__SVBool_t"};
6563 TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03);
6564 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc");
6565 for (auto *TypeName : TypeNames) {
6566 auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match(
6567 ToTU, typedefDecl(hasName(TypeName)));
6568 QualType ToType = ToTypedef->getUnderlyingType();
6570 auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match(
6571 FromTU, typedefDecl(hasName(TypeName)));
6572 QualType FromType = FromTypedef->getUnderlyingType();
6574 QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03);
6575 EXPECT_EQ(ImportedType, ToType);
6579 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) {
6580 // Test that import of implicit functions works and the functions
6581 // are merged into one chain.
6582 auto GetDeclToImport = [this](StringRef File) {
6583 Decl *FromTU = getTuDecl(
6585 struct X { };
6586 // Force generating some implicit operator definitions for X.
6587 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; }
6589 Lang_CXX11, File);
6590 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
6591 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
6592 // Destructor is picked as one example of implicit function.
6593 return FromD->getDestructor();
6596 auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11);
6597 ASSERT_TRUE(ToD1);
6599 auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11);
6600 ASSERT_TRUE(ToD2);
6602 EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl());
6605 TEST_P(ASTImporterOptionSpecificTestBase,
6606 ImportOfExplicitlyDefaultedOrDeleted) {
6607 Decl *FromTU = getTuDecl(
6609 struct X { X() = default; X(const X&) = delete; };
6611 Lang_CXX11);
6612 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6613 FromTU, cxxRecordDecl(hasName("X")));
6614 auto *ImportedX = Import(FromX, Lang_CXX11);
6615 auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match(
6616 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6617 auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match(
6618 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6620 ASSERT_TRUE(ImportedX);
6621 EXPECT_TRUE(Constr1->isDefaulted());
6622 EXPECT_TRUE(Constr1->isExplicitlyDefaulted());
6623 EXPECT_TRUE(Constr2->isDeletedAsWritten());
6624 EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate());
6627 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, SVEBuiltins,
6628 ::testing::Values(std::vector<std::string>{
6629 "-target", "aarch64-linux-gnu"}));
6631 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, DeclContextTest,
6632 ::testing::Values(std::vector<std::string>()));
6634 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CanonicalRedeclChain,
6635 ::testing::Values(std::vector<std::string>()));
6637 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) {
6638 Decl *FromTU = getTuDecl(
6640 void f() {
6641 auto L0 = [](){};
6642 auto L1 = [](){};
6645 Lang_CXX11, "input0.cc");
6646 auto Pattern = lambdaExpr();
6647 CXXRecordDecl *FromL0 =
6648 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6649 CXXRecordDecl *FromL1 =
6650 LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6651 ASSERT_NE(FromL0, FromL1);
6653 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
6654 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
6655 EXPECT_NE(ToL0, ToL1);
6658 TEST_P(ASTImporterOptionSpecificTestBase,
6659 LambdasInFunctionParamsAreDifferentiated) {
6660 Decl *FromTU = getTuDecl(
6662 template <typename F0, typename F1>
6663 void f(F0 L0 = [](){}, F1 L1 = [](){}) {}
6665 Lang_CXX11, "input0.cc");
6666 auto Pattern = cxxRecordDecl(isLambda());
6667 CXXRecordDecl *FromL0 =
6668 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6669 CXXRecordDecl *FromL1 =
6670 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6671 ASSERT_NE(FromL0, FromL1);
6673 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
6674 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
6675 ASSERT_NE(ToL0, ToL1);
6678 TEST_P(ASTImporterOptionSpecificTestBase,
6679 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) {
6680 Decl *FromTU = getTuDecl(
6682 #define LAMBDA [](){}
6683 template <typename F0, typename F1>
6684 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {}
6686 Lang_CXX11, "input0.cc");
6687 auto Pattern = cxxRecordDecl(isLambda());
6688 CXXRecordDecl *FromL0 =
6689 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6690 CXXRecordDecl *FromL1 =
6691 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6692 ASSERT_NE(FromL0, FromL1);
6694 Import(FromL0, Lang_CXX11);
6695 Import(FromL1, Lang_CXX11);
6696 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
6697 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
6698 ASSERT_NE(ToL0, ToL1);
6701 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) {
6702 Decl *FromTU = getTuDecl(
6704 void f() {
6705 auto x = []{} = {}; auto x2 = x;
6708 Lang_CXX20, "input0.cc");
6709 auto FromF = FirstDeclMatcher<FunctionDecl>().match(
6710 FromTU, functionDecl(hasName("f")));
6711 // We have only one lambda class.
6712 ASSERT_EQ(
6713 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
6714 1u);
6716 FunctionDecl *ToF = Import(FromF, Lang_CXX20);
6717 EXPECT_TRUE(ToF);
6718 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
6719 // We have only one lambda class after the import.
6720 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
6721 1u);
6724 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) {
6725 Decl *FromTU = getTuDecl(
6727 void f() {
6728 auto x = []{} = {};
6729 auto xb = []{} = {};
6732 Lang_CXX20, "input0.cc");
6733 auto FromF = FirstDeclMatcher<FunctionDecl>().match(
6734 FromTU, functionDecl(hasName("f")));
6735 // We have two lambda classes.
6736 ASSERT_EQ(
6737 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
6738 2u);
6740 FunctionDecl *ToF = Import(FromF, Lang_CXX20);
6741 EXPECT_TRUE(ToF);
6742 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
6743 // We have two lambda classes after the import.
6744 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
6745 2u);
6748 TEST_P(ASTImporterOptionSpecificTestBase,
6749 ImportFunctionDeclWithTypeSourceInfoWithSourceDecl) {
6750 // This code results in a lambda with implicit constructor.
6751 // The constructor's TypeSourceInfo points out the function prototype.
6752 // This prototype has an EST_Unevaluated in its exception information and a
6753 // SourceDecl that is the function declaration itself.
6754 // The test verifies that AST import of such AST does not crash.
6755 // (Here the function's TypeSourceInfo references the function itself.)
6756 Decl *FromTU = getTuDecl(
6758 template<typename T> void f(T) { auto X = [](){}; }
6759 void g() { f(10); }
6761 Lang_CXX11, "input0.cc");
6763 // Use LastDeclMatcher to find the LambdaExpr in the template specialization.
6764 CXXRecordDecl *FromL = LastDeclMatcher<LambdaExpr>()
6765 .match(FromTU, lambdaExpr())
6766 ->getLambdaClass();
6768 CXXConstructorDecl *FromCtor = *FromL->ctor_begin();
6769 ASSERT_TRUE(FromCtor->isCopyConstructor());
6770 ASSERT_TRUE(FromCtor->getTypeSourceInfo());
6771 const auto *FromFPT = FromCtor->getType()->getAs<FunctionProtoType>();
6772 ASSERT_TRUE(FromFPT);
6773 EXPECT_EQ(FromCtor->getTypeSourceInfo()->getType().getTypePtr(), FromFPT);
6774 FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
6775 // If type is EST_Unevaluated, SourceDecl should be set to the parent Decl.
6776 EXPECT_EQ(FromEPI.ExceptionSpec.Type, EST_Unevaluated);
6777 EXPECT_EQ(FromEPI.ExceptionSpec.SourceDecl, FromCtor);
6779 auto ToL = Import(FromL, Lang_CXX11);
6781 // Check if the import was correct.
6782 CXXConstructorDecl *ToCtor = *ToL->ctor_begin();
6783 EXPECT_TRUE(ToCtor->getTypeSourceInfo());
6784 const auto *ToFPT = ToCtor->getType()->getAs<FunctionProtoType>();
6785 ASSERT_TRUE(ToFPT);
6786 EXPECT_EQ(ToCtor->getTypeSourceInfo()->getType().getTypePtr(), ToFPT);
6787 FunctionProtoType::ExtProtoInfo ToEPI = ToFPT->getExtProtoInfo();
6788 EXPECT_EQ(ToEPI.ExceptionSpec.Type, EST_Unevaluated);
6789 EXPECT_EQ(ToEPI.ExceptionSpec.SourceDecl, ToCtor);
6792 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {
6793 void testImport(llvm::StringRef Code, clang::TestLanguage Lang = Lang_CXX14) {
6794 Decl *FromTU = getTuDecl(Code, Lang, "input0.cc");
6795 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6796 FromTU, functionDecl(hasName("foo")));
6798 FunctionDecl *To = Import(From, Lang);
6799 EXPECT_TRUE(To);
6800 // We check here only that the type is auto type.
6801 // These tests are to verify that no crash happens.
6802 // The crash possibility is the presence of a reference to a declaration
6803 // in the function's body from the return type, if the function has auto
6804 // return type.
6805 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6809 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate1) {
6810 testImport(
6812 template<class C>
6813 C f1() { return C(); }
6814 auto foo() {
6815 struct B {};
6816 return f1<B>();
6818 )");
6821 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate2) {
6822 testImport(
6824 template<class T>
6825 int f1(T t) { return 1; }
6826 auto foo() {
6827 struct B {};
6828 return f1(B());
6830 )");
6833 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate3) {
6834 testImport(
6836 template<class A> struct S1 {};
6837 template<class A> struct S2 {};
6838 template<class C>
6839 S1<C> f1() { return S1<C>(); }
6840 auto foo() {
6841 struct B {};
6842 return f1<S2<B *>>();
6844 )");
6847 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate4) {
6848 testImport(
6850 template<class... A> struct S1 {};
6851 template<class... A> struct S2 {};
6852 template<class... C>
6853 S1<C...> f1() { return S1<C...>(); }
6854 auto foo() {
6855 struct B {};
6856 return f1<S2<int, B *>, bool>();
6858 )");
6861 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate1) {
6862 testImport(
6864 template<class T> T X;
6865 auto foo() {
6866 struct A {};
6867 return X<A>;
6869 )");
6872 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate2) {
6873 testImport(
6875 template<class A> struct S1 {};
6876 template<class T> S1<T> X;
6877 auto foo() {
6878 struct A {};
6879 return X<S1<A>>;
6881 )");
6884 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate3) {
6885 testImport(
6887 template<class... A> struct S1 {};
6888 template<class... T> S1<T...> X;
6889 auto foo() {
6890 struct A {};
6891 return X<bool, S1<A, int>>;
6893 )");
6896 TEST_P(ImportAutoFunctions, ReturnWithAutoUnresolvedArg) {
6897 testImport(
6899 template<int A>
6900 auto foo() {
6901 return 22;
6903 )");
6906 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTemplateTemplateArg) {
6907 // FIXME: Is it possible to have the template arg inside the function?
6908 testImport(
6910 template<int> struct Tmpl {};
6911 template<template<int> class> struct TmplTmpl {};
6912 auto foo() {
6913 return TmplTmpl<Tmpl>();
6915 )");
6918 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithDeclarationTemplateArg) {
6919 // FIXME: Is it possible to have the template arg inside the function?
6920 testImport(
6922 template<const int *> struct Tmpl {};
6923 int A[10];
6924 auto foo() {
6925 return Tmpl<A>();
6927 )");
6930 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithNullPtrTemplateArg) {
6931 testImport(
6933 template<int *> struct Tmpl {};
6934 auto foo() {
6935 constexpr int* A = nullptr;
6936 return Tmpl<A>();
6938 )");
6941 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegralTemplateArg) {
6942 testImport(
6944 template<int> struct Tmpl {};
6945 auto foo() {
6946 using Int = int;
6947 constexpr Int A = 7;
6948 return Tmpl<A>();
6950 )");
6953 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithDecltypeTypeDeclaredInside) {
6954 testImport(
6956 template<class> struct Tmpl {};
6957 auto foo() {
6958 struct X {};
6959 X x;
6960 return Tmpl<decltype(x)>();
6962 )");
6965 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithUsingTypeDeclaredInside) {
6966 testImport(
6968 template<class> struct Tmpl {};
6969 namespace A { struct X {}; }
6970 auto foo() {
6971 using A::X;
6972 return Tmpl<X>();
6974 )");
6977 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithArrayTypeDeclaredInside) {
6978 testImport(
6980 template<class> struct Tmpl {};
6981 auto foo() {
6982 struct X {};
6983 return Tmpl<X[10]>();
6985 )");
6988 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithArraySizeExprDeclaredInside) {
6989 testImport(
6991 template<class> struct Tmpl {};
6992 auto foo() {
6993 constexpr int S = 10;
6994 return Tmpl<int[S]>();
6996 )");
6999 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithPackArgDeclaredInside) {
7000 testImport(
7002 template<class ...> struct Tmpl {};
7003 auto foo() {
7004 using X = bool;
7005 return Tmpl<int, X>();
7007 )");
7010 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegerArgDeclaredInside) {
7011 testImport(
7013 template<int> struct Tmpl {};
7014 auto foo() {
7015 constexpr int X = 1;
7016 return Tmpl<X>();
7018 )");
7021 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithPtrToStructDeclaredInside) {
7022 testImport(
7024 template<class> struct Tmpl {};
7025 auto foo() {
7026 struct X {};
7027 return Tmpl<X *>();
7029 )");
7032 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithRefToStructDeclaredInside) {
7033 testImport(
7035 template<class> struct Tmpl {};
7036 struct X {};
7037 auto foo() {
7038 using Y = X;
7039 return Tmpl<Y &>();
7041 )");
7044 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside1) {
7045 testImport(
7047 template<class> struct Tmpl {};
7048 auto foo() {
7049 struct X {};
7050 return Tmpl<X>();
7052 )");
7055 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside2) {
7056 testImport(
7058 template<class> struct Tmpl {};
7059 auto foo() {
7060 struct X {};
7061 return Tmpl<Tmpl<X>>();
7063 )");
7066 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTypedefDeclaredInside) {
7067 testImport(
7069 template<class> struct Tmpl {};
7070 auto foo() {
7071 struct X {};
7072 using x_type = X;
7073 return Tmpl<x_type>();
7075 )");
7078 TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) {
7079 Decl *FromTU = getTuDecl(
7081 auto X = [](long l) {
7082 using int_type = long;
7083 auto dur = 13;
7084 return static_cast<int_type>(dur);
7087 Lang_CXX14, "input0.cc");
7088 CXXMethodDecl *From =
7089 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl());
7091 // Explicitly set the return type of the lambda's operator() to the TypeAlias.
7092 // Normally the return type would be the built-in 'long' type. However, there
7093 // are cases when Clang does not use the canonical type and the TypeAlias is
7094 // used. I could not create such an AST from regular source code, it requires
7095 // some special state in the preprocessor. I've found such an AST when Clang
7096 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce
7097 // that with creduce, because after preprocessing, the AST no longer
7098 // contained the TypeAlias as a return type of the lambda.
7099 ASTContext &Ctx = From->getASTContext();
7100 TypeAliasDecl *FromTA =
7101 FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl());
7102 QualType TT = Ctx.getTypedefType(FromTA);
7103 const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType());
7104 QualType NewFunType =
7105 Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo());
7106 From->setType(NewFunType);
7108 CXXMethodDecl *To = Import(From, Lang_CXX14);
7109 EXPECT_TRUE(To);
7110 EXPECT_TRUE(isa<TypedefType>(To->getReturnType()));
7113 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) {
7114 testImport(
7116 auto foo() {
7117 struct X {};
7118 return X();
7120 )");
7123 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) {
7124 Decl *FromTU = getTuDecl(
7126 auto foo() {
7127 struct X {};
7128 return X();
7131 Lang_CXX14, "input0.cc");
7132 FunctionDecl *From =
7133 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
7135 // This time import the type directly.
7136 QualType ToT = ImportType(From->getType(), From, Lang_CXX14);
7137 const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT);
7138 EXPECT_TRUE(isa<AutoType>(FPT->getReturnType()));
7141 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside3) {
7142 Decl *FromTU = getTuDecl(
7144 struct S {
7145 constexpr auto foo();
7147 constexpr auto S::foo() {
7148 struct X {};
7149 return X();
7152 Lang_CXX14, "input0.cc");
7153 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
7154 FromTU, functionDecl(hasName("foo"), unless(hasBody(stmt()))));
7155 ASSERT_FALSE(From->isThisDeclarationADefinition());
7157 FunctionDecl *To = Import(From, Lang_CXX17);
7158 EXPECT_TRUE(To);
7159 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
7160 EXPECT_FALSE(To->isThisDeclarationADefinition());
7163 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) {
7164 testImport(
7166 auto foo() {
7167 struct X {};
7168 using Y = X;
7169 return Y();
7171 )");
7174 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) {
7175 testImport(
7177 auto foo() {
7178 struct X { struct Y{}; };
7179 return X::Y();
7181 )");
7184 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) {
7185 testImport(
7187 auto foo() {
7188 auto l = []() {
7189 struct X {};
7190 return X();
7192 return l();
7195 Lang_CXX17);
7198 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) {
7199 testImport(
7201 auto foo() {
7202 if (struct X {} x; true)
7203 return X();
7204 else
7205 return X();
7208 Lang_CXX17);
7211 TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) {
7212 testImport(
7214 auto foo() {
7215 for (struct X {} x;;)
7216 return X();
7219 Lang_CXX17);
7222 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) {
7223 testImport(
7225 auto foo() {
7226 switch (struct X {} x; 10) {
7227 case 10:
7228 return X();
7232 Lang_CXX17);
7235 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {};
7237 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) {
7238 // Tests that the FileID tree structure (with the links being the include
7239 // chains) is preserved while importing other files (which need to be
7240 // added to this structure with fake include locations.
7242 SourceLocation Location1;
7244 auto Pattern = varDecl(hasName("X"));
7245 Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c");
7246 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7248 Location1 = Import(FromD, Lang_C99)->getLocation();
7250 SourceLocation Location2;
7252 auto Pattern = varDecl(hasName("Y"));
7253 Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c");
7254 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7256 Location2 = Import(FromD, Lang_C99)->getLocation();
7259 SourceManager &ToSM = ToAST->getSourceManager();
7260 FileID FileID1 = ToSM.getFileID(Location1);
7261 FileID FileID2 = ToSM.getFileID(Location2);
7263 // Check that the imported files look like as if they were included from the
7264 // start of the main file.
7265 SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID());
7266 EXPECT_NE(FileID1, ToSM.getMainFileID());
7267 EXPECT_NE(FileID2, ToSM.getMainFileID());
7268 EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart);
7269 EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart);
7271 // Let the SourceManager check the order of the locations. The order should
7272 // be the order in which the declarations are imported.
7273 EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2));
7274 EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1));
7277 TEST_P(ImportSourceLocations, NormalFileBuffer) {
7278 // Test importing normal file buffers.
7280 std::string Path = "input0.c";
7281 std::string Source = "int X;";
7282 TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path);
7284 SourceLocation ImportedLoc;
7286 // Import the VarDecl to trigger the importing of the FileID.
7287 auto Pattern = varDecl(hasName("X"));
7288 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7289 ImportedLoc = Import(FromD, Lang_C99)->getLocation();
7292 // Make sure the imported buffer has the original contents.
7293 SourceManager &ToSM = ToAST->getSourceManager();
7294 FileID ImportedID = ToSM.getFileID(ImportedLoc);
7295 EXPECT_EQ(Source,
7296 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
7299 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) {
7300 // Test importing overwritten file buffers.
7302 std::string Path = "input0.c";
7303 TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path);
7305 // Overwrite the file buffer for our input file with new content.
7306 const std::string Contents = "overwritten contents";
7307 SourceLocation ImportedLoc;
7309 SourceManager &FromSM = FromTU->getASTContext().getSourceManager();
7310 clang::FileManager &FM = FromSM.getFileManager();
7311 clang::FileEntryRef FE =
7312 FM.getVirtualFileRef(Path, static_cast<off_t>(Contents.size()), 0);
7314 llvm::SmallVector<char, 64> Buffer;
7315 Buffer.append(Contents.begin(), Contents.end());
7316 auto FileContents = std::make_unique<llvm::SmallVectorMemoryBuffer>(
7317 std::move(Buffer), Path, /*RequiresNullTerminator=*/false);
7318 FromSM.overrideFileContents(FE, std::move(FileContents));
7320 // Import the VarDecl to trigger the importing of the FileID.
7321 auto Pattern = varDecl(hasName("X"));
7322 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7323 ImportedLoc = Import(FromD, Lang_C99)->getLocation();
7326 // Make sure the imported buffer has the overwritten contents.
7327 SourceManager &ToSM = ToAST->getSourceManager();
7328 FileID ImportedID = ToSM.getFileID(ImportedLoc);
7329 EXPECT_EQ(Contents,
7330 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
7333 struct ImportAttributes : public ASTImporterOptionSpecificTestBase {
7334 void checkAttrImportCommon(const Attr *From, const Attr *To,
7335 const Decl *ToD) {
7337 // Verify that dump does not crash because invalid data.
7338 ToD->dump(llvm::nulls());
7340 EXPECT_EQ(From->getParsedKind(), To->getParsedKind());
7341 EXPECT_EQ(From->getSyntax(), To->getSyntax());
7342 if (From->getAttrName()) {
7343 EXPECT_TRUE(To->getAttrName());
7344 EXPECT_STREQ(From->getAttrName()->getNameStart(),
7345 To->getAttrName()->getNameStart());
7346 } else {
7347 EXPECT_FALSE(To->getAttrName());
7349 if (From->getScopeName()) {
7350 EXPECT_TRUE(To->getScopeName());
7351 EXPECT_STREQ(From->getScopeName()->getNameStart(),
7352 To->getScopeName()->getNameStart());
7353 } else {
7354 EXPECT_FALSE(To->getScopeName());
7356 EXPECT_EQ(From->getSpellingListIndex(), To->getSpellingListIndex());
7357 EXPECT_STREQ(From->getSpelling(), To->getSpelling());
7358 EXPECT_EQ(From->isInherited(), To->isInherited());
7359 EXPECT_EQ(From->isImplicit(), To->isImplicit());
7360 EXPECT_EQ(From->isPackExpansion(), To->isPackExpansion());
7361 EXPECT_EQ(From->isLateParsed(), To->isLateParsed());
7364 template <class DT, class AT>
7365 void importAttr(const char *Code, AT *&FromAttr, AT *&ToAttr) {
7366 static_assert(std::is_base_of<Attr, AT>::value, "AT should be an Attr");
7367 static_assert(std::is_base_of<Decl, DT>::value, "DT should be a Decl");
7369 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cc");
7370 DT *FromD =
7371 FirstDeclMatcher<DT>().match(FromTU, namedDecl(hasName("test")));
7372 ASSERT_TRUE(FromD);
7374 DT *ToD = Import(FromD, Lang_CXX11);
7375 ASSERT_TRUE(ToD);
7377 FromAttr = FromD->template getAttr<AT>();
7378 ToAttr = ToD->template getAttr<AT>();
7379 ASSERT_TRUE(FromAttr);
7380 EXPECT_TRUE(ToAttr);
7382 checkAttrImportCommon(FromAttr, ToAttr, ToD);
7385 template <class T> void checkImported(const T *From, const T *To) {
7386 EXPECT_TRUE(To);
7387 EXPECT_NE(From, To);
7390 template <class T>
7391 void checkImportVariadicArg(const llvm::iterator_range<T **> &From,
7392 const llvm::iterator_range<T **> &To) {
7393 for (auto FromI = From.begin(), ToI = To.begin(); FromI != From.end();
7394 ++FromI, ++ToI) {
7395 ASSERT_NE(ToI, To.end());
7396 checkImported(*FromI, *ToI);
7401 template <>
7402 void ImportAttributes::checkImported<Decl>(const Decl *From, const Decl *To) {
7403 EXPECT_TRUE(To);
7404 EXPECT_NE(From, To);
7405 EXPECT_EQ(To->getTranslationUnitDecl(),
7406 ToAST->getASTContext().getTranslationUnitDecl());
7409 // FIXME: Use ImportAttributes for this test.
7410 TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) {
7411 // Test if import of these packed and aligned attributes does not trigger an
7412 // error situation where source location from 'From' context is referenced in
7413 // 'To' context through evaluation of the alignof attribute.
7414 // This happens if the 'alignof(A)' expression is not imported correctly.
7415 Decl *FromTU = getTuDecl(
7417 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; };
7418 struct alignas(alignof(A)) S {};
7420 Lang_CXX11, "input.cc");
7421 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
7422 FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit())));
7423 ASSERT_TRUE(FromD);
7425 auto *ToD = Import(FromD, Lang_CXX11);
7426 ASSERT_TRUE(ToD);
7428 auto *FromAttr = FromD->getAttr<AlignedAttr>();
7429 auto *ToAttr = ToD->getAttr<AlignedAttr>();
7430 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited());
7431 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion());
7432 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit());
7433 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax());
7434 EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling());
7435 EXPECT_TRUE(ToAttr->getAlignmentExpr());
7437 auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match(
7438 ToD->getTranslationUnitDecl(),
7439 cxxRecordDecl(hasName("A"), unless(isImplicit())));
7440 // Ensure that 'struct A' was imported (through reference from attribute of
7441 // 'S').
7442 EXPECT_TRUE(ToA);
7445 // FIXME: Use ImportAttributes for this test.
7446 TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) {
7447 Decl *FromTU = getTuDecl(
7449 int foo(const char * fmt, ...)
7450 __attribute__ ((__format__ (__scanf__, 1, 2)));
7452 Lang_CXX03, "input.cc");
7453 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
7454 FromTU, functionDecl(hasName("foo")));
7455 ASSERT_TRUE(FromD);
7457 auto *ToD = Import(FromD, Lang_CXX03);
7458 ASSERT_TRUE(ToD);
7459 ToD->dump(); // Should not crash!
7461 auto *FromAttr = FromD->getAttr<FormatAttr>();
7462 auto *ToAttr = ToD->getAttr<FormatAttr>();
7463 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited());
7464 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion());
7465 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit());
7466 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax());
7467 EXPECT_EQ(FromAttr->getAttributeSpellingListIndex(),
7468 ToAttr->getAttributeSpellingListIndex());
7469 EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName());
7472 TEST_P(ImportAttributes, ImportEnableIf) {
7473 EnableIfAttr *FromAttr, *ToAttr;
7474 importAttr<FunctionDecl>(
7475 "void test(int A) __attribute__((enable_if(A == 1, \"message\")));",
7476 FromAttr, ToAttr);
7477 checkImported(FromAttr->getCond(), ToAttr->getCond());
7478 EXPECT_EQ(FromAttr->getMessage(), ToAttr->getMessage());
7481 TEST_P(ImportAttributes, ImportGuardedVar) {
7482 GuardedVarAttr *FromAttr, *ToAttr;
7483 importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr,
7484 ToAttr);
7487 TEST_P(ImportAttributes, ImportPtGuardedVar) {
7488 PtGuardedVarAttr *FromAttr, *ToAttr;
7489 importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr,
7490 ToAttr);
7493 TEST_P(ImportAttributes, ImportScopedLockable) {
7494 ScopedLockableAttr *FromAttr, *ToAttr;
7495 importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};",
7496 FromAttr, ToAttr);
7499 TEST_P(ImportAttributes, ImportCapability) {
7500 CapabilityAttr *FromAttr, *ToAttr;
7501 importAttr<CXXRecordDecl>(
7502 "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr);
7503 EXPECT_EQ(FromAttr->getName(), ToAttr->getName());
7506 TEST_P(ImportAttributes, ImportAssertCapability) {
7507 AssertCapabilityAttr *FromAttr, *ToAttr;
7508 importAttr<FunctionDecl>(
7509 "void test(int A1, int A2) __attribute__((assert_capability(A1, A2)));",
7510 FromAttr, ToAttr);
7511 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7514 TEST_P(ImportAttributes, ImportAcquireCapability) {
7515 AcquireCapabilityAttr *FromAttr, *ToAttr;
7516 importAttr<FunctionDecl>(
7517 "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));",
7518 FromAttr, ToAttr);
7519 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7522 TEST_P(ImportAttributes, ImportTryAcquireCapability) {
7523 TryAcquireCapabilityAttr *FromAttr, *ToAttr;
7524 importAttr<FunctionDecl>(
7525 "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, "
7526 "A2)));",
7527 FromAttr, ToAttr);
7528 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
7529 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7532 TEST_P(ImportAttributes, ImportReleaseCapability) {
7533 ReleaseCapabilityAttr *FromAttr, *ToAttr;
7534 importAttr<FunctionDecl>(
7535 "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));",
7536 FromAttr, ToAttr);
7537 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7540 TEST_P(ImportAttributes, ImportRequiresCapability) {
7541 RequiresCapabilityAttr *FromAttr, *ToAttr;
7542 importAttr<FunctionDecl>(
7543 "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));",
7544 FromAttr, ToAttr);
7545 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7548 TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) {
7549 NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr;
7550 importAttr<FunctionDecl>(
7551 "void test() __attribute__((no_thread_safety_analysis));", FromAttr,
7552 ToAttr);
7555 TEST_P(ImportAttributes, ImportGuardedBy) {
7556 GuardedByAttr *FromAttr, *ToAttr;
7557 importAttr<VarDecl>(
7559 int G;
7560 int test __attribute__((guarded_by(G)));
7562 FromAttr, ToAttr);
7563 checkImported(FromAttr->getArg(), ToAttr->getArg());
7566 TEST_P(ImportAttributes, ImportPtGuardedBy) {
7567 PtGuardedByAttr *FromAttr, *ToAttr;
7568 importAttr<VarDecl>(
7570 int G;
7571 int *test __attribute__((pt_guarded_by(G)));
7573 FromAttr, ToAttr);
7574 checkImported(FromAttr->getArg(), ToAttr->getArg());
7577 TEST_P(ImportAttributes, ImportAcquiredAfter) {
7578 AcquiredAfterAttr *FromAttr, *ToAttr;
7579 importAttr<VarDecl>(
7581 struct __attribute__((lockable)) L {};
7582 L A1;
7583 L A2;
7584 L test __attribute__((acquired_after(A1, A2)));
7586 FromAttr, ToAttr);
7587 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7590 TEST_P(ImportAttributes, ImportAcquiredBefore) {
7591 AcquiredBeforeAttr *FromAttr, *ToAttr;
7592 importAttr<VarDecl>(
7594 struct __attribute__((lockable)) L {};
7595 L A1;
7596 L A2;
7597 L test __attribute__((acquired_before(A1, A2)));
7599 FromAttr, ToAttr);
7600 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7603 TEST_P(ImportAttributes, ImportAssertExclusiveLock) {
7604 AssertExclusiveLockAttr *FromAttr, *ToAttr;
7605 importAttr<FunctionDecl>("void test(int A1, int A2) "
7606 "__attribute__((assert_exclusive_lock(A1, A2)));",
7607 FromAttr, ToAttr);
7608 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7611 TEST_P(ImportAttributes, ImportAssertSharedLock) {
7612 AssertSharedLockAttr *FromAttr, *ToAttr;
7613 importAttr<FunctionDecl>(
7614 "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));",
7615 FromAttr, ToAttr);
7616 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7619 TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) {
7620 ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr;
7621 importAttr<FunctionDecl>(
7622 "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, "
7623 "A1, A2)));",
7624 FromAttr, ToAttr);
7625 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
7626 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7629 TEST_P(ImportAttributes, ImportSharedTrylockFunction) {
7630 SharedTrylockFunctionAttr *FromAttr, *ToAttr;
7631 importAttr<FunctionDecl>(
7632 "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, "
7633 "A2)));",
7634 FromAttr, ToAttr);
7635 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
7636 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7639 TEST_P(ImportAttributes, ImportLockReturned) {
7640 LockReturnedAttr *FromAttr, *ToAttr;
7641 importAttr<FunctionDecl>(
7642 "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr,
7643 ToAttr);
7644 checkImported(FromAttr->getArg(), ToAttr->getArg());
7647 TEST_P(ImportAttributes, ImportLocksExcluded) {
7648 LocksExcludedAttr *FromAttr, *ToAttr;
7649 importAttr<FunctionDecl>(
7650 "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));",
7651 FromAttr, ToAttr);
7652 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7655 template <typename T>
7656 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) {
7657 auto Copy = Values;
7658 for (std::vector<std::string> &ArgV : Copy) {
7659 for (const std::string &Arg : Args) {
7660 ArgV.push_back(Arg);
7663 return ::testing::ValuesIn(Copy);
7666 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase {
7667 ImportWithExternalSource() {
7668 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
7669 ASTContext &FromContext, FileManager &FromFileManager,
7670 bool MinimalImport,
7671 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
7672 return new ASTImporter(ToContext, ToFileManager, FromContext,
7673 // Use minimal import for these tests.
7674 FromFileManager, /*MinimalImport=*/true,
7675 // We use the regular lookup.
7676 /*SharedState=*/nullptr);
7681 /// An ExternalASTSource that keeps track of the tags is completed.
7682 struct SourceWithCompletedTagList : clang::ExternalASTSource {
7683 std::vector<clang::TagDecl *> &CompletedTags;
7684 SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags)
7685 : CompletedTags(CompletedTags) {}
7686 void CompleteType(TagDecl *Tag) override {
7687 auto *Record = cast<CXXRecordDecl>(Tag);
7688 Record->startDefinition();
7689 Record->completeDefinition();
7690 CompletedTags.push_back(Tag);
7692 using clang::ExternalASTSource::CompleteType;
7695 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) {
7696 // Create an empty TU.
7697 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp");
7699 // Create and add the test ExternalASTSource.
7700 std::vector<clang::TagDecl *> CompletedTags;
7701 IntrusiveRefCntPtr<ExternalASTSource> source =
7702 new SourceWithCompletedTagList(CompletedTags);
7703 clang::ASTContext &Context = FromTU->getASTContext();
7704 Context.setExternalSource(std::move(source));
7706 // Create a dummy class by hand with external lexical storage.
7707 IdentifierInfo &Ident = Context.Idents.get("test_class");
7708 auto *Record = CXXRecordDecl::Create(
7709 Context, TTK_Class, FromTU, SourceLocation(), SourceLocation(), &Ident);
7710 Record->setHasExternalLexicalStorage();
7711 FromTU->addDecl(Record);
7713 // Do a minimal import of the created class.
7714 EXPECT_EQ(0U, CompletedTags.size());
7715 Import(Record, Lang_CXX03);
7716 EXPECT_EQ(0U, CompletedTags.size());
7718 // Import the definition of the created class.
7719 llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record);
7720 EXPECT_FALSE((bool)Err);
7721 consumeError(std::move(Err));
7723 // Make sure the class was completed once.
7724 EXPECT_EQ(1U, CompletedTags.size());
7725 EXPECT_EQ(Record, CompletedTags.front());
7728 TEST_P(ImportFunctions, CTADImplicit) {
7729 Decl *FromTU = getTuDecl(
7731 template <typename T> struct A {
7732 A(T);
7734 A a{(int)0};
7736 Lang_CXX17, "input.cc");
7737 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7738 FromTU,
7739 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>")))));
7740 auto *ToD = Import(FromD, Lang_CXX17);
7741 ASSERT_TRUE(ToD);
7742 EXPECT_EQ(ToD->getDeductionCandidateKind(), DeductionCandidate::Copy);
7743 // Check that the deduced class template is also imported.
7744 EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull(
7745 FromD->getDeducedTemplate()));
7748 TEST_P(ImportFunctions, CTADUserDefinedExplicit) {
7749 Decl *FromTU = getTuDecl(
7751 template <typename T> struct A {
7752 A(T);
7754 template <typename T> explicit A(T) -> A<float>;
7755 A a{(int)0}; // calls A<float>::A(float)
7757 Lang_CXX17, "input.cc");
7758 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7759 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
7760 // Not-implicit: i.e. not compiler-generated, user defined.
7761 ASSERT_FALSE(FromD->isImplicit());
7762 ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword.
7763 auto *ToD = Import(FromD, Lang_CXX17);
7764 ASSERT_TRUE(ToD);
7765 EXPECT_FALSE(FromD->isImplicit());
7766 EXPECT_TRUE(ToD->isExplicit());
7769 TEST_P(ImportFunctions, CTADWithLocalTypedef) {
7770 Decl *TU = getTuDecl(
7772 template <typename T> struct A {
7773 typedef T U;
7774 A(U);
7776 A a{(int)0};
7778 Lang_CXX17, "input.cc");
7779 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7780 TU, cxxDeductionGuideDecl());
7781 auto *ToD = Import(FromD, Lang_CXX17);
7782 ASSERT_TRUE(ToD);
7785 TEST_P(ImportFunctions, ParmVarDeclDeclContext) {
7786 constexpr auto FromTUCode = R"(
7787 void f(int P);
7789 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
7790 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
7791 FromTU, functionDecl(hasName("f")));
7792 ASSERT_TRUE(FromF);
7794 auto *ImportedF = Import(FromF, Lang_CXX11);
7795 EXPECT_TRUE(ImportedF);
7796 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
7797 ImportedF, ImportedF->getParamDecl(0)));
7800 // FIXME Move these tests out of ASTImporterTest. For that we need to factor
7801 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase
7802 // into a new test Fixture. Then we should lift up this Fixture to its own
7803 // implementation file and only then could we reuse the Fixture in other AST
7804 // unitttests.
7805 struct CTAD : ASTImporterOptionSpecificTestBase {};
7807 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) {
7808 Decl *TU = getTuDecl(
7810 typedef int U;
7811 template <typename T> struct A {
7812 A(U, T);
7814 A a{(int)0, (int)0};
7816 Lang_CXX17, "input.cc");
7817 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7818 TU, cxxDeductionGuideDecl());
7819 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
7820 TU, typedefNameDecl(hasName("U")));
7821 ParmVarDecl *Param = Guide->getParamDecl(0);
7822 // The type of the first param (which is a typedef) should match the typedef
7823 // in the global scope.
7824 EXPECT_EQ(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
7827 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) {
7828 Decl *TU = getTuDecl(
7830 typedef int U;
7831 template <typename T> struct A {
7832 A(U*, T);
7834 A a{(int*)0, (int)0};
7836 Lang_CXX17, "input.cc");
7837 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7838 TU, cxxDeductionGuideDecl());
7839 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
7840 TU, typedefNameDecl(hasName("U")));
7841 ParmVarDecl *Param = Guide->getParamDecl(0);
7842 EXPECT_EQ(Param->getType()
7843 ->getAs<PointerType>()
7844 ->getPointeeType()
7845 ->getAs<TypedefType>()
7846 ->getDecl(),
7847 Typedef);
7850 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) {
7851 Decl *TU = getTuDecl(
7853 template <typename T> struct A {
7854 typedef T U;
7855 A(U, T);
7857 A a{(int)0, (int)0};
7859 Lang_CXX17, "input.cc");
7860 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7861 TU, cxxDeductionGuideDecl());
7862 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
7863 TU, typedefNameDecl(hasName("U")));
7864 ParmVarDecl *Param = Guide->getParamDecl(0);
7865 EXPECT_NE(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
7868 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CTAD,
7869 DefaultTestValuesForRunOptions);
7871 TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) {
7872 Decl *TU = getTuDecl(
7874 namespace N {
7875 typedef int X __attribute__((annotate("A")));
7878 Lang_CXX17, "input.cc");
7879 auto *FromD =
7880 FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X")));
7881 auto *ToD = Import(FromD, Lang_CXX17);
7882 ASSERT_TRUE(ToD);
7883 ASSERT_EQ(ToD->getAttrs().size(), 1U);
7884 auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]);
7885 ASSERT_TRUE(ToAttr);
7886 EXPECT_EQ(ToAttr->getAnnotation(), "A");
7889 TEST_P(ASTImporterOptionSpecificTestBase,
7890 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) {
7891 Decl *FromTU = getTuDecl(
7894 namespace std {
7895 template<typename T>
7896 class basic_stringbuf;
7898 namespace std {
7899 class char_traits;
7900 template<typename T = char_traits>
7901 class basic_stringbuf;
7903 namespace std {
7904 template<typename T>
7905 class basic_stringbuf {};
7909 Lang_CXX11);
7911 auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match(
7912 FromTU,
7913 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
7914 auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11));
7915 EXPECT_TRUE(To1);
7917 auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match(
7918 FromTU,
7919 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
7920 auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11));
7921 EXPECT_TRUE(To2);
7924 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) {
7925 Decl *FromTU = getTuDecl(
7927 void declToImport(int N) {
7928 int VLA[N];
7929 [&VLA] {}; // FieldDecl inside the lambda.
7932 Lang_CXX14);
7933 auto *FromFD = FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl());
7934 ASSERT_TRUE(FromFD);
7935 ASSERT_TRUE(FromFD->hasCapturedVLAType());
7937 auto *ToFD = Import(FromFD, Lang_CXX14);
7938 EXPECT_TRUE(ToFD);
7939 EXPECT_TRUE(ToFD->hasCapturedVLAType());
7940 EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType());
7943 TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) {
7944 Decl *FromTU = getTuDecl(
7946 template <class T> struct A {
7947 enum tagname { enumerator };
7949 template struct A<int>;
7951 Lang_CXX03);
7952 auto *FromD = FirstDeclMatcher<EnumDecl>().match(
7953 FromTU, enumDecl(hasName("tagname"),
7954 hasParent(classTemplateSpecializationDecl())));
7955 ASSERT_TRUE(FromD);
7956 ASSERT_TRUE(FromD->getMemberSpecializationInfo());
7958 auto *ToD = Import(FromD, Lang_CXX03);
7959 EXPECT_TRUE(ToD);
7960 EXPECT_TRUE(ToD->getMemberSpecializationInfo());
7961 EXPECT_EQ(FromD->getTemplateSpecializationKind(),
7962 ToD->getTemplateSpecializationKind());
7965 TEST_P(ASTImporterOptionSpecificTestBase, ImportIsInheritingConstructorBit) {
7966 Decl *FromTU = getTuDecl(
7968 struct A {
7969 A(int);
7971 struct B : A {
7972 using A::A; // Inherited ctor.
7974 void f() {
7975 (B(0));
7978 Lang_CXX11);
7979 auto *FromD = FirstDeclMatcher<CXXConstructorDecl>().match(
7980 FromTU, cxxConstructorDecl(isInheritingConstructor()));
7981 ASSERT_TRUE(FromD);
7982 ASSERT_TRUE(FromD->isInheritingConstructor());
7984 auto *ToD = Import(FromD, Lang_CXX11);
7985 ASSERT_TRUE(ToD);
7986 EXPECT_TRUE(ToD->isInheritingConstructor());
7989 TEST_P(ASTImporterOptionSpecificTestBase, ImportConstructorUsingShadow) {
7990 TranslationUnitDecl *FromTU = getTuDecl(
7992 struct A {
7993 A(int, int);
7995 struct B : A {
7996 using A::A;
7998 struct C : B {
7999 using B::B;
8002 Lang_CXX11);
8004 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordC) {
8005 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match(
8006 TU, cxxRecordDecl(hasName("A")));
8007 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
8008 TU, cxxRecordDecl(hasName("B")));
8009 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match(
8010 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)),
8011 parameterCountIs(2)));
8012 auto *ShadowBA = cast<ConstructorUsingShadowDecl>(
8013 FirstDeclMatcher<UsingShadowDecl>().match(
8014 TU, usingShadowDecl(hasParent(equalsNode(RecordB)),
8015 hasTargetDecl(equalsNode(ConstrA)))));
8016 auto *ShadowCA = cast<ConstructorUsingShadowDecl>(
8017 FirstDeclMatcher<UsingShadowDecl>().match(
8018 TU, usingShadowDecl(hasParent(equalsNode(RecordC)),
8019 hasTargetDecl(equalsNode(ConstrA)))));
8020 EXPECT_EQ(ShadowBA->getTargetDecl(), ConstrA);
8021 EXPECT_EQ(ShadowBA->getNominatedBaseClass(), RecordA);
8022 EXPECT_EQ(ShadowBA->getConstructedBaseClass(), RecordA);
8023 EXPECT_EQ(ShadowBA->getNominatedBaseClassShadowDecl(), nullptr);
8024 EXPECT_EQ(ShadowBA->getConstructedBaseClassShadowDecl(), nullptr);
8025 EXPECT_FALSE(ShadowBA->constructsVirtualBase());
8026 EXPECT_EQ(ShadowCA->getTargetDecl(), ConstrA);
8027 EXPECT_EQ(ShadowCA->getNominatedBaseClass(), RecordB);
8028 EXPECT_EQ(ShadowCA->getConstructedBaseClass(), RecordB);
8029 EXPECT_EQ(ShadowCA->getNominatedBaseClassShadowDecl(), ShadowBA);
8030 EXPECT_EQ(ShadowCA->getConstructedBaseClassShadowDecl(), ShadowBA);
8031 EXPECT_FALSE(ShadowCA->constructsVirtualBase());
8034 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match(
8035 FromTU, cxxRecordDecl(hasName("C")));
8037 auto *ToC = Import(FromC, Lang_CXX11);
8038 TranslationUnitDecl *ToTU = ToC->getTranslationUnitDecl();
8040 CheckAST(FromTU, FromC);
8041 CheckAST(ToTU, ToC);
8044 TEST_P(ASTImporterOptionSpecificTestBase,
8045 ImportFunctionDeclBitShouldNotOverwriteCtorDeclBits) {
8046 Decl *From, *To;
8047 std::tie(From, To) = getImportedDecl(
8048 R"s(
8049 struct A {
8050 A() : m() {}
8051 int m;
8054 A foo() { A a; return a; }
8055 A bar() { return {}; }
8056 )s",
8057 Lang_CXX17,
8058 R"s(
8059 struct A {
8060 A() : m() {}
8061 int m;
8063 A baz() { return {}; }
8064 )s",
8065 Lang_CXX17, "A");
8067 auto HasCtorInit =
8068 hasAnyConstructorInitializer(cxxCtorInitializer(isMemberInitializer()));
8069 auto ImpMoveCtor =
8070 cxxConstructorDecl(isMoveConstructor(), isImplicit(), HasCtorInit);
8072 auto *FromImpMoveCtor = FirstDeclMatcher<CXXConstructorDecl>().match(
8073 From, ImpMoveCtor);
8074 auto *ToImpMoveCtor = FirstDeclMatcher<CXXConstructorDecl>().match(
8075 To, ImpMoveCtor);
8077 EXPECT_TRUE(FromImpMoveCtor->getNumCtorInitializers() == 1);
8078 EXPECT_FALSE(FromImpMoveCtor->FriendConstraintRefersToEnclosingTemplate());
8080 EXPECT_TRUE(ToImpMoveCtor->getNumCtorInitializers() == 1);
8081 EXPECT_FALSE(ToImpMoveCtor->FriendConstraintRefersToEnclosingTemplate());
8082 EXPECT_TRUE(*ToImpMoveCtor->init_begin());
8085 AST_MATCHER_P(UsingShadowDecl, hasIntroducerDecl, internal::Matcher<NamedDecl>,
8086 InnerMatcher) {
8087 return InnerMatcher.matches(*Node.getIntroducer(), Finder, Builder);
8090 TEST_P(ASTImporterOptionSpecificTestBase,
8091 ImportConstructorUsingShadowVirtualBase) {
8092 TranslationUnitDecl *FromTU = getTuDecl(
8094 struct A { A(int, int); };
8095 struct B : A { using A::A; };
8097 struct V1 : virtual B { using B::B; };
8098 struct V2 : virtual B { using B::B; };
8100 struct D2 : V1, V2 {
8101 using V1::V1;
8102 using V2::V2;
8105 Lang_CXX11);
8107 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordD2) {
8108 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match(
8109 TU, cxxRecordDecl(hasName("A")));
8110 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
8111 TU, cxxRecordDecl(hasName("B")));
8112 auto *RecordV1 = FirstDeclMatcher<CXXRecordDecl>().match(
8113 TU, cxxRecordDecl(hasName("V1")));
8114 auto *RecordV2 = FirstDeclMatcher<CXXRecordDecl>().match(
8115 TU, cxxRecordDecl(hasName("V2")));
8116 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match(
8117 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)),
8118 parameterCountIs(2)));
8119 auto *ConstrB = FirstDeclMatcher<CXXConstructorDecl>().match(
8120 TU, cxxConstructorDecl(hasParent(equalsNode(RecordB)),
8121 isCopyConstructor()));
8122 auto *UsingD2V1 = FirstDeclMatcher<UsingDecl>().match(
8123 TU, usingDecl(hasParent(equalsNode(RecordD2))));
8124 auto *UsingD2V2 = LastDeclMatcher<UsingDecl>().match(
8125 TU, usingDecl(hasParent(equalsNode(RecordD2))));
8126 auto *ShadowBA = cast<ConstructorUsingShadowDecl>(
8127 FirstDeclMatcher<UsingShadowDecl>().match(
8128 TU, usingShadowDecl(hasParent(equalsNode(RecordB)),
8129 hasTargetDecl(equalsNode(ConstrA)))));
8130 auto *ShadowV1A = cast<ConstructorUsingShadowDecl>(
8131 FirstDeclMatcher<UsingShadowDecl>().match(
8132 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)),
8133 hasTargetDecl(equalsNode(ConstrA)))));
8134 auto *ShadowV1B = cast<ConstructorUsingShadowDecl>(
8135 FirstDeclMatcher<UsingShadowDecl>().match(
8136 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)),
8137 hasTargetDecl(equalsNode(ConstrB)))));
8138 auto *ShadowV2A = cast<ConstructorUsingShadowDecl>(
8139 FirstDeclMatcher<UsingShadowDecl>().match(
8140 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)),
8141 hasTargetDecl(equalsNode(ConstrA)))));
8142 auto *ShadowV2B = cast<ConstructorUsingShadowDecl>(
8143 FirstDeclMatcher<UsingShadowDecl>().match(
8144 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)),
8145 hasTargetDecl(equalsNode(ConstrB)))));
8146 auto *ShadowD2V1A = cast<ConstructorUsingShadowDecl>(
8147 FirstDeclMatcher<UsingShadowDecl>().match(
8148 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8149 hasIntroducerDecl(equalsNode(UsingD2V1)),
8150 hasTargetDecl(equalsNode(ConstrA)))));
8151 auto *ShadowD2V1B = cast<ConstructorUsingShadowDecl>(
8152 FirstDeclMatcher<UsingShadowDecl>().match(
8153 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8154 hasIntroducerDecl(equalsNode(UsingD2V1)),
8155 hasTargetDecl(equalsNode(ConstrB)))));
8156 auto *ShadowD2V2A = cast<ConstructorUsingShadowDecl>(
8157 FirstDeclMatcher<UsingShadowDecl>().match(
8158 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8159 hasIntroducerDecl(equalsNode(UsingD2V2)),
8160 hasTargetDecl(equalsNode(ConstrA)))));
8161 auto *ShadowD2V2B = cast<ConstructorUsingShadowDecl>(
8162 FirstDeclMatcher<UsingShadowDecl>().match(
8163 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8164 hasIntroducerDecl(equalsNode(UsingD2V2)),
8165 hasTargetDecl(equalsNode(ConstrB)))));
8167 EXPECT_EQ(ShadowD2V1A->getTargetDecl(), ConstrA);
8168 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClassShadowDecl(), ShadowV1A);
8169 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClass(), RecordV1);
8170 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClassShadowDecl(), ShadowBA);
8171 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClass(), RecordB);
8172 EXPECT_TRUE(ShadowD2V1A->constructsVirtualBase());
8173 EXPECT_EQ(ShadowD2V1B->getTargetDecl(), ConstrB);
8174 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClassShadowDecl(), ShadowV1B);
8175 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClass(), RecordV1);
8176 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClassShadowDecl(), nullptr);
8177 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClass(), RecordB);
8178 EXPECT_TRUE(ShadowD2V1B->constructsVirtualBase());
8179 EXPECT_EQ(ShadowD2V2A->getTargetDecl(), ConstrA);
8180 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClassShadowDecl(), ShadowV2A);
8181 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClass(), RecordV2);
8182 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClassShadowDecl(), ShadowBA);
8183 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClass(), RecordB);
8184 EXPECT_TRUE(ShadowD2V2A->constructsVirtualBase());
8185 EXPECT_EQ(ShadowD2V2B->getTargetDecl(), ConstrB);
8186 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClassShadowDecl(), ShadowV2B);
8187 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClass(), RecordV2);
8188 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClassShadowDecl(), nullptr);
8189 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClass(), RecordB);
8190 EXPECT_TRUE(ShadowD2V2B->constructsVirtualBase());
8192 EXPECT_TRUE(ShadowV1A->constructsVirtualBase());
8193 EXPECT_TRUE(ShadowV1B->constructsVirtualBase());
8194 EXPECT_TRUE(ShadowV2A->constructsVirtualBase());
8195 EXPECT_TRUE(ShadowV2B->constructsVirtualBase());
8196 EXPECT_FALSE(ShadowBA->constructsVirtualBase());
8199 auto *FromD2 = FirstDeclMatcher<CXXRecordDecl>().match(
8200 FromTU, cxxRecordDecl(hasName("D2")));
8202 auto *ToD2 = Import(FromD2, Lang_CXX11);
8203 TranslationUnitDecl *ToTU = ToD2->getTranslationUnitDecl();
8205 CheckAST(FromTU, FromD2);
8206 CheckAST(ToTU, ToD2);
8209 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingShadowList) {
8210 TranslationUnitDecl *FromTU = getTuDecl(
8212 struct A {
8213 void f();
8214 void f(int);
8216 struct B : A {
8217 using A::f;
8220 Lang_CXX11);
8222 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match(
8223 FromTU, cxxRecordDecl(hasName("B")));
8225 auto *ToB = Import(FromB, Lang_CXX11);
8226 TranslationUnitDecl *ToTU = ToB->getTranslationUnitDecl();
8228 auto *ToUsing = FirstDeclMatcher<UsingDecl>().match(
8229 ToTU, usingDecl(hasParent(equalsNode(ToB))));
8230 auto *ToUsingShadowF1 = FirstDeclMatcher<UsingShadowDecl>().match(
8231 ToTU, usingShadowDecl(hasTargetDecl(
8232 functionDecl(hasName("f"), parameterCountIs(0)))));
8233 auto *ToUsingShadowF2 = FirstDeclMatcher<UsingShadowDecl>().match(
8234 ToTU, usingShadowDecl(hasTargetDecl(
8235 functionDecl(hasName("f"), parameterCountIs(1)))));
8237 EXPECT_EQ(ToUsing->shadow_size(), 2u);
8238 auto ShadowI = ToUsing->shadow_begin();
8239 EXPECT_EQ(*ShadowI, ToUsingShadowF1);
8240 ++ShadowI;
8241 EXPECT_EQ(*ShadowI, ToUsingShadowF2);
8244 AST_MATCHER_P(FunctionTemplateDecl, templateParameterCountIs, unsigned, Cnt) {
8245 return Node.getTemplateParameters()->size() == Cnt;
8248 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuide) {
8249 TranslationUnitDecl *FromTU = getTuDecl(
8251 template<class> class A { };
8252 template<class T> class B {
8253 template<class T1, typename = A<T>> B(T1);
8255 template<class T>
8256 B(T, T) -> B<int>;
8258 Lang_CXX17);
8260 // Get the implicit deduction guide for (non-default) constructor of 'B'.
8261 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8262 FromTU, functionTemplateDecl(templateParameterCountIs(3)));
8263 // Implicit deduction guide for copy constructor of 'B'.
8264 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8265 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
8266 // User defined deduction guide.
8267 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8268 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
8270 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters();
8271 // Don't know why exactly but this is the DeclContext here.
8272 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(),
8273 FromDGCopyCtor->getTemplatedDecl());
8274 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(),
8275 FromDGCtor->getTemplatedDecl());
8276 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(),
8277 FromDGCtor->getTemplatedDecl());
8278 EXPECT_EQ(
8279 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8280 FromDGCopyCtor->getTemplatedDecl());
8281 EXPECT_EQ(FromDGOther->getDescribedTemplate()
8282 ->getTemplateParameters()
8283 ->getParam(0)
8284 ->getDeclContext(),
8285 FromDGOther);
8287 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17);
8288 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17);
8289 auto *ToDGOther = Import(FromDGOther, Lang_CXX17);
8290 ASSERT_TRUE(ToDGCtor);
8291 ASSERT_TRUE(ToDGCopyCtor);
8292 ASSERT_TRUE(ToDGOther);
8294 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters();
8295 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(),
8296 ToDGCopyCtor->getTemplatedDecl());
8297 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(),
8298 ToDGCtor->getTemplatedDecl());
8299 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(),
8300 ToDGCtor->getTemplatedDecl());
8301 EXPECT_EQ(
8302 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8303 ToDGCopyCtor->getTemplatedDecl());
8304 EXPECT_EQ(ToDGOther->getDescribedTemplate()
8305 ->getTemplateParameters()
8306 ->getParam(0)
8307 ->getDeclContext(),
8308 ToDGOther);
8311 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuideDifferentOrder) {
8312 // This test demonstrates that the DeclContext of the imported object is
8313 // dependent on the order of import. The test is an exact copy of the previous
8314 // one except at the indicated locations.
8315 TranslationUnitDecl *FromTU = getTuDecl(
8317 template<class> class A { };
8318 template<class T> class B {
8319 template<class T1, typename = A<T>> B(T1);
8321 template<class T>
8322 B(T, T) -> B<int>;
8324 Lang_CXX17);
8326 // Get the implicit deduction guide for (non-default) constructor of 'B'.
8327 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8328 FromTU, functionTemplateDecl(templateParameterCountIs(3)));
8329 // Implicit deduction guide for copy constructor of 'B'.
8330 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8331 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
8332 // User defined deduction guide.
8333 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8334 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
8336 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters();
8337 // Don't know why exactly but this is the DeclContext here.
8338 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(),
8339 FromDGCopyCtor->getTemplatedDecl());
8340 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(),
8341 FromDGCtor->getTemplatedDecl());
8342 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(),
8343 FromDGCtor->getTemplatedDecl());
8344 EXPECT_EQ(
8345 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8346 FromDGCopyCtor->getTemplatedDecl());
8347 EXPECT_EQ(FromDGOther->getDescribedTemplate()
8348 ->getTemplateParameters()
8349 ->getParam(0)
8350 ->getDeclContext(),
8351 FromDGOther);
8353 // Here the import of 'ToDGCopyCtor' and 'ToDGCtor' is reversed relative to
8354 // the previous test.
8355 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17);
8356 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17);
8357 auto *ToDGOther = Import(FromDGOther, Lang_CXX17);
8358 ASSERT_TRUE(ToDGCtor);
8359 ASSERT_TRUE(ToDGCopyCtor);
8360 ASSERT_TRUE(ToDGOther);
8362 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters();
8363 // Next line: DeclContext is different relative to the previous test.
8364 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(),
8365 ToDGCtor->getTemplatedDecl());
8366 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(),
8367 ToDGCtor->getTemplatedDecl());
8368 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(),
8369 ToDGCtor->getTemplatedDecl());
8370 // Next line: DeclContext is different relative to the previous test.
8371 EXPECT_EQ(
8372 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8373 ToDGCtor->getTemplatedDecl());
8374 EXPECT_EQ(ToDGOther->getDescribedTemplate()
8375 ->getTemplateParameters()
8376 ->getParam(0)
8377 ->getDeclContext(),
8378 ToDGOther);
8381 TEST_P(ASTImporterOptionSpecificTestBase,
8382 ImportFieldsFirstForCorrectRecordLayout) {
8383 // UnaryOperator(&) triggers RecordLayout computation, which relies on
8384 // correctly imported fields.
8385 auto Code =
8387 class A {
8388 int m() {
8389 return &((A *)0)->f1 - &((A *)0)->f2;
8391 int f1;
8392 int f2;
8395 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
8397 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
8398 FromTU, cxxMethodDecl(hasName("A::m")));
8399 Import(FromF, Lang_CXX11);
8402 TEST_P(ASTImporterOptionSpecificTestBase,
8403 ImportCirularRefFieldsWithoutCorruptedRecordLayoutCache) {
8404 // Import sequence: A => A.b => B => B.f() => ... => UnaryOperator(&) => ...
8406 // UnaryOperator(&) should not introduce invalid RecordLayout since 'A' is
8407 // still not completely imported.
8408 auto Code =
8410 class B;
8411 class A {
8412 B* b;
8413 int c;
8415 class B {
8416 A *f() { return &((B *)0)->a; }
8417 A a;
8421 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
8422 getTuDecl(Code, Lang_CXX11), cxxRecordDecl(hasName("A")));
8423 FromR = FromR->getDefinition();
8424 auto &FromAST = FromR->getASTContext();
8425 auto *ToR = Import(FromR, Lang_CXX11);
8426 auto &ToAST = ToR->getASTContext();
8428 uint64_t SecondFieldOffset = FromAST.getTypeSize(FromAST.VoidPtrTy);
8430 EXPECT_TRUE(FromR->isCompleteDefinition());
8431 const auto &FromLayout = FromAST.getASTRecordLayout(FromR);
8432 EXPECT_TRUE(FromLayout.getFieldOffset(0) == 0);
8433 EXPECT_TRUE(FromLayout.getFieldOffset(1) == SecondFieldOffset);
8435 EXPECT_TRUE(ToR->isCompleteDefinition());
8436 const auto &ToLayout = ToAST.getASTRecordLayout(ToR);
8437 EXPECT_TRUE(ToLayout.getFieldOffset(0) == 0);
8438 EXPECT_TRUE(ToLayout.getFieldOffset(1) == SecondFieldOffset);
8441 TEST_P(ASTImporterOptionSpecificTestBase,
8442 ImportRecordWithLayoutRequestingExpr) {
8443 TranslationUnitDecl *FromTU = getTuDecl(
8445 struct A {
8446 int idx;
8447 static void foo(A x) {
8448 (void)&"text"[x.idx];
8452 Lang_CXX11);
8454 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8455 FromTU, cxxRecordDecl(hasName("A")));
8457 // Test that during import of 'foo' the record layout can be obtained without
8458 // crash.
8459 auto *ToA = Import(FromA, Lang_CXX11);
8460 EXPECT_TRUE(ToA);
8461 EXPECT_TRUE(ToA->isCompleteDefinition());
8464 TEST_P(ASTImporterOptionSpecificTestBase,
8465 ImportRecordWithLayoutRequestingExprDifferentRecord) {
8466 TranslationUnitDecl *FromTU = getTuDecl(
8468 struct B;
8469 struct A {
8470 int idx;
8471 B *b;
8473 struct B {
8474 static void foo(A x) {
8475 (void)&"text"[x.idx];
8479 Lang_CXX11);
8481 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8482 FromTU, cxxRecordDecl(hasName("A")));
8484 // Test that during import of 'foo' the record layout (of 'A') can be obtained
8485 // without crash. It is not possible to have all of the fields of 'A' imported
8486 // at that time (without big code changes).
8487 auto *ToA = Import(FromA, Lang_CXX11);
8488 EXPECT_TRUE(ToA);
8489 EXPECT_TRUE(ToA->isCompleteDefinition());
8492 TEST_P(ASTImporterOptionSpecificTestBase, ImportInClassInitializerFromField) {
8493 // Encounter import of a field when the field already exists but has the
8494 // in-class initializer expression not yet set. Such case can occur in the AST
8495 // of generated template specializations.
8496 // The first code forces to create a template specialization of
8497 // `A<int>` but without implicit constructors.
8498 // The second ("From") code contains a variable of type `A<int>`, this
8499 // results in a template specialization that has constructors and
8500 // CXXDefaultInitExpr nodes.
8501 Decl *ToTU = getToTuDecl(
8503 void f();
8504 template<typename> struct A { int X = 1; };
8505 struct B { A<int> Y; };
8507 Lang_CXX11);
8508 auto *ToX = FirstDeclMatcher<FieldDecl>().match(
8509 ToTU,
8510 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8511 ASSERT_TRUE(ToX->hasInClassInitializer());
8512 ASSERT_FALSE(ToX->getInClassInitializer());
8514 Decl *FromTU = getTuDecl(
8516 void f();
8517 template<typename> struct A { int X = 1; };
8518 struct B { A<int> Y; };
8520 A<int> Z;
8522 Lang_CXX11, "input1.cc");
8523 auto *FromX = FirstDeclMatcher<FieldDecl>().match(
8524 FromTU,
8525 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8527 auto *ToXImported = Import(FromX, Lang_CXX11);
8528 EXPECT_EQ(ToXImported, ToX);
8529 EXPECT_TRUE(ToX->getInClassInitializer());
8532 TEST_P(ASTImporterOptionSpecificTestBase,
8533 ImportInClassInitializerFromCXXDefaultInitExpr) {
8534 // Encounter AST import of a CXXDefaultInitExpr where the "to-field"
8535 // of it exists but has the in-class initializer not set yet.
8536 Decl *ToTU = getToTuDecl(
8538 namespace N {
8539 template<typename> int b;
8540 struct X;
8542 template<typename> struct A { N::X *X = nullptr; };
8543 struct B { A<int> Y; };
8545 Lang_CXX14);
8546 auto *ToX = FirstDeclMatcher<FieldDecl>().match(
8547 ToTU,
8548 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8549 ASSERT_TRUE(ToX->hasInClassInitializer());
8550 ASSERT_FALSE(ToX->getInClassInitializer());
8552 Decl *FromTU = getTuDecl(
8554 namespace N {
8555 template<typename> int b;
8556 struct X;
8558 template<typename> struct A { N::X *X = nullptr; };
8559 struct B { A<int> Y; };
8561 void f() {
8562 (void)A<int>{};
8564 struct C {
8565 C(): attr(new A<int>{}){}
8566 A<int> *attr;
8567 const int value = N::b<C>;
8570 Lang_CXX14, "input1.cc");
8571 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
8572 FromTU, functionDecl(hasName("f"), isDefinition()));
8573 auto *ToF = Import(FromF, Lang_CXX11);
8574 EXPECT_TRUE(ToF);
8575 EXPECT_TRUE(ToX->getInClassInitializer());
8578 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) {
8579 const char *Code =
8581 struct AP_TECS;
8583 struct AP_Landing {
8584 AP_TECS *TECS_controller;
8587 struct AP_TECS {
8588 AP_Landing landing;
8591 class Plane {
8592 AP_TECS TECS_controller{landing};
8593 AP_Landing landing{&TECS_controller};
8596 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
8598 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
8599 FromTU, cxxRecordDecl(hasName("Plane")));
8600 for (FieldDecl *F : FromR->fields())
8601 EXPECT_TRUE(F->getInClassInitializer());
8602 auto *ToR = Import(FromR, Lang_CXX11);
8603 for (FieldDecl *F : ToR->fields())
8604 EXPECT_TRUE(F->getInClassInitializer());
8607 TEST_P(ASTImporterOptionSpecificTestBase, ImportFieldInitializerWithItself) {
8608 const char *Code =
8610 class A {
8611 int a{a};
8614 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
8615 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8616 FromTU, cxxRecordDecl(hasName("A")));
8617 EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
8618 auto *ToA = Import(FromA, Lang_CXX11);
8619 EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
8622 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer1) {
8623 // FIXME: This is a example of recursive field initialization that is not
8624 // supported.
8625 // The following import chain occurs (not complete):
8626 // import of A => A.a => in-class initializer of A.a => ref_B() => B => B.b
8627 // => in-class initializer of B.b => ref_A() => CXXConstructExpr for A =>
8628 // CXXDefaultInitExpr for A.a => in-class initializer of A.a
8629 // in-class initializer of A.a is created in two different instances in this
8630 // case (import of FieldDecl and CXXDefaultInitExpr). Probably not a big
8631 // problem because it is an Expr (the second construction can be ignored
8632 // instead of assert). But such recursive init code should not occur in
8633 // practice.
8634 const char *Code =
8636 static int ref_A();
8637 static int ref_B();
8638 struct A {
8639 int a = ref_B();
8641 struct B {
8642 int b = ref_A();
8644 int ref_B() { B b; return b.b; }
8645 int ref_A() { A a; return a.a; }
8647 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
8648 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8649 FromTU, cxxRecordDecl(hasName("A")));
8650 EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
8651 // auto *ToA = Import(FromA, Lang_CXX11);
8652 // EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
8655 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
8656 Decl *FromTU = getTuDecl(
8658 int bar() {
8659 return 0;
8661 void other() {
8662 bar();
8665 Lang_CXX11);
8666 Decl *ToTU = getToTuDecl(
8668 int bar() {
8669 return 0;
8672 Lang_CXX11);
8673 auto *FromOther = FirstDeclMatcher<FunctionDecl>().match(
8674 FromTU, functionDecl(hasName("other")));
8675 ASSERT_TRUE(FromOther);
8677 auto *ToOther = Import(FromOther, Lang_CXX11);
8678 ASSERT_TRUE(ToOther);
8680 auto *ToBar = FirstDeclMatcher<FunctionDecl>().match(
8681 ToTU, functionDecl(hasName("bar")));
8683 EXPECT_TRUE(SharedStatePtr->isNewDecl(ToOther));
8684 EXPECT_FALSE(SharedStatePtr->isNewDecl(ToBar));
8687 struct ImportInjectedClassNameType : public ASTImporterOptionSpecificTestBase {
8688 protected:
8689 const CXXRecordDecl *findInjected(const CXXRecordDecl *Parent) {
8690 for (Decl *Found : Parent->decls()) {
8691 const auto *Record = dyn_cast<CXXRecordDecl>(Found);
8692 if (Record && Record->isInjectedClassName())
8693 return Record;
8695 return nullptr;
8698 void checkInjType(const CXXRecordDecl *D) {
8699 // The whole redecl chain should have the same InjectedClassNameType
8700 // instance. The injected record declaration is a separate chain, this
8701 // should contain the same type too.
8702 const Type *Ty = nullptr;
8703 for (const Decl *ReD : D->redecls()) {
8704 const auto *ReRD = cast<CXXRecordDecl>(ReD);
8705 EXPECT_TRUE(ReRD->getTypeForDecl());
8706 EXPECT_TRUE(!Ty || Ty == ReRD->getTypeForDecl());
8707 Ty = ReRD->getTypeForDecl();
8709 ASSERT_TRUE(Ty);
8710 const auto *InjTy = Ty->castAs<InjectedClassNameType>();
8711 EXPECT_TRUE(InjTy);
8712 if (CXXRecordDecl *Def = D->getDefinition()) {
8713 const CXXRecordDecl *InjRD = findInjected(Def);
8714 EXPECT_TRUE(InjRD);
8715 EXPECT_EQ(InjRD->getTypeForDecl(), InjTy);
8719 void testImport(Decl *ToTU, Decl *FromTU, Decl *FromD) {
8720 checkInjType(cast<CXXRecordDecl>(FromD));
8721 Decl *ToD = Import(FromD, Lang_CXX11);
8722 if (auto *ToRD = dyn_cast<CXXRecordDecl>(ToD))
8723 checkInjType(ToRD);
8726 const char *ToCodeA =
8728 template <class T>
8729 struct A;
8731 const char *ToCodeADef =
8733 template <class T>
8734 struct A {
8735 typedef A T1;
8738 const char *ToCodeC =
8740 template <class T>
8741 struct C;
8743 const char *ToCodeCDef =
8745 template <class T>
8746 struct A {
8747 typedef A T1;
8750 template <class T1, class T2>
8751 struct B {};
8753 template<class T>
8754 struct C {
8755 typedef typename A<T>::T1 T1;
8756 typedef B<T1, T> T2;
8757 typedef B<T1, C> T3;
8760 const char *FromCode =
8762 template <class T>
8763 struct A;
8764 template <class T>
8765 struct A {
8766 typedef A T1;
8768 template <class T>
8769 struct A;
8771 template <class T1, class T2>
8772 struct B {};
8774 template <class T>
8775 struct C;
8776 template <class T>
8777 struct C {
8778 typedef typename A<T>::T1 T1;
8779 typedef B<T1, T> T2;
8780 typedef B<T1, C> T3;
8782 template <class T>
8783 struct C;
8785 template <class T>
8786 struct D {
8787 void f(typename C<T>::T3 *);
8792 TEST_P(ImportInjectedClassNameType, ImportADef) {
8793 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11);
8794 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8795 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8796 FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
8797 testImport(ToTU, FromTU, FromA);
8800 TEST_P(ImportInjectedClassNameType, ImportAFirst) {
8801 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11);
8802 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8803 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8804 FromTU, cxxRecordDecl(hasName("A")));
8805 testImport(ToTU, FromTU, FromA);
8808 TEST_P(ImportInjectedClassNameType, ImportALast) {
8809 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11);
8810 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8811 auto *FromA = LastDeclMatcher<CXXRecordDecl>().match(
8812 FromTU, cxxRecordDecl(hasName("A")));
8813 testImport(ToTU, FromTU, FromA);
8816 TEST_P(ImportInjectedClassNameType, ImportADefToDef) {
8817 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11);
8818 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8819 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8820 FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
8821 testImport(ToTU, FromTU, FromA);
8824 TEST_P(ImportInjectedClassNameType, ImportAFirstToDef) {
8825 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11);
8826 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8827 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8828 FromTU, cxxRecordDecl(hasName("A")));
8829 testImport(ToTU, FromTU, FromA);
8832 TEST_P(ImportInjectedClassNameType, ImportALastToDef) {
8833 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11);
8834 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8835 auto *FromA = LastDeclMatcher<CXXRecordDecl>().match(
8836 FromTU, cxxRecordDecl(hasName("A")));
8837 testImport(ToTU, FromTU, FromA);
8840 TEST_P(ImportInjectedClassNameType, ImportCDef) {
8841 Decl *ToTU = getToTuDecl(ToCodeC, Lang_CXX11);
8842 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8843 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match(
8844 FromTU, cxxRecordDecl(hasName("C"), isDefinition()));
8845 testImport(ToTU, FromTU, FromC);
8848 TEST_P(ImportInjectedClassNameType, ImportCLast) {
8849 Decl *ToTU = getToTuDecl(ToCodeC, Lang_CXX11);
8850 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8851 auto *FromC = LastDeclMatcher<CXXRecordDecl>().match(
8852 FromTU, cxxRecordDecl(hasName("C")));
8853 testImport(ToTU, FromTU, FromC);
8856 TEST_P(ImportInjectedClassNameType, ImportCDefToDef) {
8857 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11);
8858 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8859 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match(
8860 FromTU, cxxRecordDecl(hasName("C"), isDefinition()));
8861 testImport(ToTU, FromTU, FromC);
8864 TEST_P(ImportInjectedClassNameType, ImportCLastToDef) {
8865 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11);
8866 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8867 auto *FromC = LastDeclMatcher<CXXRecordDecl>().match(
8868 FromTU, cxxRecordDecl(hasName("C")));
8869 testImport(ToTU, FromTU, FromC);
8872 TEST_P(ImportInjectedClassNameType, ImportD) {
8873 Decl *ToTU = getToTuDecl("", Lang_CXX11);
8874 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8875 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
8876 FromTU, cxxRecordDecl(hasName("D"), isDefinition()));
8877 testImport(ToTU, FromTU, FromD);
8880 TEST_P(ImportInjectedClassNameType, ImportDToDef) {
8881 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11);
8882 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
8883 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
8884 FromTU, cxxRecordDecl(hasName("D"), isDefinition()));
8885 testImport(ToTU, FromTU, FromD);
8888 TEST_P(ImportInjectedClassNameType, ImportTypedefType) {
8889 Decl *ToTU = getToTuDecl(
8891 template <class T>
8892 struct A {
8893 typedef A A1;
8894 void f(A1 *);
8897 Lang_CXX11);
8898 Decl *FromTU = getTuDecl(
8900 template <class T>
8901 struct A {
8902 typedef A A1;
8903 void f(A1 *);
8905 template<class T>
8906 void A<T>::f(A::A1 *) {}
8908 Lang_CXX11);
8910 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
8911 FromTU, functionDecl(hasName("f"), isDefinition()));
8912 auto *ToF = Import(FromF, Lang_CXX11);
8913 EXPECT_TRUE(ToF);
8914 ASTContext &ToCtx = ToF->getDeclContext()->getParentASTContext();
8916 auto *ToA1 =
8917 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("A1")));
8918 QualType ToInjTypedef = ToA1->getUnderlyingType().getCanonicalType();
8919 QualType ToInjParmVar =
8920 ToF->parameters()[0]->getType().getDesugaredType(ToCtx);
8921 ToInjParmVar =
8922 ToInjParmVar->getAs<PointerType>()->getPointeeType().getCanonicalType();
8923 EXPECT_TRUE(isa<InjectedClassNameType>(ToInjTypedef));
8924 EXPECT_TRUE(isa<InjectedClassNameType>(ToInjParmVar));
8925 EXPECT_TRUE(ToCtx.hasSameType(ToInjTypedef, ToInjParmVar));
8928 TEST_P(ASTImporterOptionSpecificTestBase, ImportMacroQualifiedType) {
8929 Decl *From, *To;
8930 std::tie(From, To) = getImportedDecl(
8932 #define CDECL __attribute__((cdecl))
8933 typedef void (CDECL *X)();
8935 Lang_CXX03, "", Lang_CXX03, "X");
8937 auto *FromTy =
8938 FirstDeclMatcher<MacroQualifiedType>().match(From, macroQualifiedType());
8939 auto *ToTy =
8940 FirstDeclMatcher<MacroQualifiedType>().match(To, macroQualifiedType());
8942 EXPECT_TRUE(isa<AttributedType>(FromTy->getUnderlyingType()));
8943 EXPECT_TRUE(isa<AttributedType>(ToTy->getUnderlyingType()));
8946 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplateName) {
8947 constexpr auto TestCode = R"(
8948 template <class T>
8949 struct A;
8950 template <class T>
8951 struct A {};
8952 template <template<class> class T = A>
8953 struct B {};
8954 using C = B<>;
8956 Decl *ToTU = getToTuDecl(TestCode, Lang_CXX11);
8957 Decl *FromTU = getTuDecl(TestCode, Lang_CXX11);
8959 auto *ToUsingFirst = FirstDeclMatcher<TypeAliasDecl>().match(
8960 ToTU, typeAliasDecl(hasName("C")));
8962 auto *FromUsing = FirstDeclMatcher<TypeAliasDecl>().match(
8963 FromTU, typeAliasDecl(hasName("C")));
8964 auto *ToUsing = Import(FromUsing, Lang_CXX11);
8965 EXPECT_TRUE(ToUsing);
8967 auto *ToB = FirstDeclMatcher<ClassTemplateDecl>().match(
8968 ToTU, classTemplateDecl(hasName("B")));
8969 auto *ToB1 = LastDeclMatcher<ClassTemplateDecl>().match(
8970 ToTU, classTemplateDecl(hasName("B")));
8971 // One template definition of 'B' should exist.
8972 EXPECT_EQ(ToB, ToB1);
8974 // These declarations are imported separately.
8975 EXPECT_NE(ToUsingFirst, ToUsing);
8977 auto SpB = ToB->spec_begin();
8978 auto SpE = ToB->spec_end();
8979 EXPECT_TRUE(SpB != SpE);
8980 ClassTemplateSpecializationDecl *Spec1 = *SpB;
8981 ++SpB;
8982 // The template 'B' should have one specialization (with default argument).
8983 EXPECT_TRUE(SpB == SpE);
8985 // Even if 'B' has one specialization with the default arguments, the AST
8986 // contains after the import two specializations that are linked in the
8987 // declaration chain. The 'spec_begin' iteration does not find these because
8988 // the template arguments are the same. But the imported type alias has the
8989 // link to the second specialization. The template name object in these
8990 // specializations must point to the same (and one) instance of definition of
8991 // 'B'.
8992 auto *Spec2 = cast<ClassTemplateSpecializationDecl>(
8993 ToUsing->getUnderlyingType()
8994 ->getAs<TemplateSpecializationType>()
8995 ->getAsRecordDecl());
8996 EXPECT_NE(Spec1, Spec2);
8997 EXPECT_TRUE(Spec1->getPreviousDecl() == Spec2 ||
8998 Spec2->getPreviousDecl() == Spec1);
8999 TemplateDecl *Templ1 =
9000 Spec1->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl();
9001 TemplateDecl *Templ2 =
9002 Spec2->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl();
9003 EXPECT_EQ(Templ1, Templ2);
9006 TEST_P(ASTImporterOptionSpecificTestBase, VaListC) {
9007 Decl *FromTU = getTuDecl(R"(typedef __builtin_va_list va_list;)", Lang_C99);
9009 auto *FromVaList = FirstDeclMatcher<TypedefDecl>().match(
9010 FromTU, typedefDecl(hasName("va_list")));
9011 ASSERT_TRUE(FromVaList);
9013 auto *ToVaList = Import(FromVaList, Lang_C99);
9014 ASSERT_TRUE(ToVaList);
9016 auto *ToBuiltinVaList = FirstDeclMatcher<TypedefDecl>().match(
9017 ToAST->getASTContext().getTranslationUnitDecl(),
9018 typedefDecl(hasName("__builtin_va_list")));
9020 ASSERT_TRUE(ToAST->getASTContext().hasSameType(
9021 ToVaList->getUnderlyingType(), ToBuiltinVaList->getUnderlyingType()));
9024 TEST_P(ASTImporterOptionSpecificTestBase, VaListCpp) {
9025 Decl *FromTU = getTuDecl(R"(typedef __builtin_va_list va_list;)", Lang_CXX03);
9027 auto *FromVaList = FirstDeclMatcher<TypedefDecl>().match(
9028 FromTU, typedefDecl(hasName("va_list")));
9029 ASSERT_TRUE(FromVaList);
9031 auto *ToVaList = Import(FromVaList, Lang_CXX03);
9032 ASSERT_TRUE(ToVaList);
9034 auto *ToBuiltinVaList = FirstDeclMatcher<TypedefDecl>().match(
9035 ToAST->getASTContext().getTranslationUnitDecl(),
9036 typedefDecl(hasName("__builtin_va_list")));
9038 ASSERT_TRUE(ToAST->getASTContext().hasSameType(
9039 ToVaList->getUnderlyingType(), ToBuiltinVaList->getUnderlyingType()));
9042 TEST_P(ASTImporterOptionSpecificTestBase,
9043 ImportDefinitionOfEmptyClassWithNoUniqueAddressField) {
9044 Decl *FromTU = getTuDecl(
9046 struct B {};
9047 struct A { B b; };
9049 Lang_CXX20);
9051 CXXRecordDecl *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
9052 FromTU, cxxRecordDecl(hasName("A")));
9054 for (auto *FD : FromD->fields())
9055 FD->addAttr(clang::NoUniqueAddressAttr::Create(FromD->getASTContext(),
9056 clang::SourceRange()));
9057 FromD->markEmpty();
9059 CXXRecordDecl *ToD = Import(FromD, Lang_CXX20);
9060 EXPECT_TRUE(ToD->isEmpty());
9061 for (auto *FD : ToD->fields())
9062 EXPECT_EQ(true, FD->hasAttr<NoUniqueAddressAttr>());
9065 TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingTypedefToRecord) {
9066 const char *Code =
9068 struct S { int i; };
9069 typedef struct S T;
9070 extern T x;
9072 Decl *ToTU = getToTuDecl(Code, Lang_C99);
9073 Decl *FromTU = getTuDecl(Code, Lang_C99);
9075 auto *FromX =
9076 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x")));
9077 auto *ToX = Import(FromX, Lang_C99);
9078 EXPECT_TRUE(ToX);
9080 auto *Typedef1 =
9081 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9082 auto *Typedef2 =
9083 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9084 EXPECT_EQ(Typedef1, Typedef2);
9087 TEST_P(ASTImporterOptionSpecificTestBase,
9088 ImportExistingTypedefToUnnamedRecord) {
9089 const char *Code =
9091 typedef const struct { int f; } T;
9092 extern T x;
9094 Decl *ToTU = getToTuDecl(Code, Lang_C99);
9095 Decl *FromTU = getTuDecl(Code, Lang_C99);
9097 auto *FromX =
9098 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x")));
9099 auto *ToX = Import(FromX, Lang_C99);
9100 EXPECT_TRUE(ToX);
9102 auto *Typedef1 =
9103 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9104 auto *Typedef2 =
9105 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9106 EXPECT_NE(Typedef1, Typedef2);
9107 EXPECT_NE(Typedef1->getUnderlyingType().getTypePtr(),
9108 Typedef2->getUnderlyingType().getTypePtr());
9109 EXPECT_EQ(ToX->getType()->getAs<TypedefType>()->getDecl(), Typedef2);
9112 TEST_P(ASTImporterOptionSpecificTestBase, ImportTwoTypedefsToUnnamedRecord) {
9113 const char *Code =
9115 typedef struct { int f; } T1;
9116 typedef struct { int f; } T2;
9117 extern T1 x1;
9118 extern T2 x2;
9120 Decl *ToTU = getToTuDecl("", Lang_C99);
9121 Decl *FromTU = getTuDecl(Code, Lang_C99);
9123 auto *FromX1 =
9124 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x1")));
9125 auto *FromX2 =
9126 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x2")));
9127 auto *ToX1 = Import(FromX1, Lang_C99);
9128 EXPECT_TRUE(ToX1);
9129 auto *ToX2 = Import(FromX2, Lang_C99);
9130 EXPECT_TRUE(ToX2);
9132 auto *Typedef1 =
9133 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T1")));
9134 auto *Typedef2 =
9135 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T2")));
9136 EXPECT_NE(Typedef1->getUnderlyingType().getTypePtr(),
9137 Typedef2->getUnderlyingType().getTypePtr());
9140 TEST_P(ASTImporterOptionSpecificTestBase,
9141 ImportExistingTypedefToUnnamedRecordPtr) {
9142 const char *Code =
9144 typedef const struct { int fff; } * const T;
9145 extern T x;
9147 Decl *ToTU = getToTuDecl(Code, Lang_C99);
9148 Decl *FromTU = getTuDecl(Code, Lang_C99);
9150 auto *FromX =
9151 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x")));
9152 auto *ToX = Import(FromX, Lang_C99);
9153 EXPECT_TRUE(ToX);
9155 auto *Typedef1 =
9156 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9157 auto *Typedef2 =
9158 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9159 // FIXME: These should be imported separately, like in the test above.
9160 // Or: In the test above these should be merged too.
9161 EXPECT_EQ(Typedef1, Typedef2);
9163 auto *FromR = FirstDeclMatcher<RecordDecl>().match(
9164 FromTU, recordDecl(hasDescendant(fieldDecl(hasName("fff")))));
9165 auto *ToRExisting = FirstDeclMatcher<RecordDecl>().match(
9166 ToTU, recordDecl(hasDescendant(fieldDecl(hasName("fff")))));
9167 ASSERT_TRUE(FromR);
9168 auto *ToRImported = Import(FromR, Lang_C99);
9169 // FIXME: If typedefs are not imported separately, do not import ToRImported
9170 // separately.
9171 EXPECT_NE(ToRExisting, ToRImported);
9174 TEST_P(ASTImporterOptionSpecificTestBase,
9175 ImportTypedefWithDifferentUnderlyingType) {
9176 const char *Code =
9178 using X1 = int;
9179 using Y1 = int;
9181 using RPB1 = X1*;
9182 typedef RPB1 RPX1;
9183 using RPB1 = Y1*; // redeclared
9184 typedef RPB1 RPY1;
9186 auto X = 0 ? (RPX1){} : (RPY1){};
9188 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9190 auto *FromX =
9191 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("X")));
9193 auto *FromXType = FromX->getType()->getAs<TypedefType>();
9194 EXPECT_FALSE(FromXType->typeMatchesDecl());
9196 auto *ToX = Import(FromX, Lang_CXX11);
9197 auto *ToXType = ToX->getType()->getAs<TypedefType>();
9198 // FIXME: This should be false.
9199 EXPECT_TRUE(ToXType->typeMatchesDecl());
9202 TEST_P(ASTImporterOptionSpecificTestBase,
9203 ImportTemplateArgumentWithPointerToDifferentInstantiation) {
9204 const char *CodeTo =
9206 template<class A>
9207 A f1() {
9208 return A();
9210 template<class A, A (B)()>
9211 class X {};
9213 X<int, f1<int>> x;
9215 const char *CodeFrom =
9217 template<class A>
9218 A f1();
9219 template<class A, A (B)()>
9220 class X {};
9222 X<int, f1<int>> x;
9224 Decl *ToTU = getToTuDecl(CodeTo, Lang_CXX11);
9225 Decl *FromTU = getTuDecl(CodeFrom, Lang_CXX11);
9227 auto *ToF1 = FirstDeclMatcher<FunctionDecl>().match(
9228 ToTU, functionDecl(hasName("f1"), isInstantiated()));
9229 auto *FromF1 = FirstDeclMatcher<FunctionDecl>().match(
9230 FromTU, functionDecl(hasName("f1"), isInstantiated()));
9231 EXPECT_TRUE(ToF1->isThisDeclarationADefinition());
9232 EXPECT_FALSE(FromF1->isThisDeclarationADefinition());
9234 auto *ToX = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
9235 ToTU, classTemplateSpecializationDecl(hasName("X")));
9236 auto *FromX = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
9237 FromTU, classTemplateSpecializationDecl(hasName("X")));
9239 Decl *ToTArgF = ToX->getTemplateArgs().get(1).getAsDecl();
9240 Decl *FromTArgF = FromX->getTemplateArgs().get(1).getAsDecl();
9241 EXPECT_EQ(ToTArgF, ToF1);
9242 EXPECT_EQ(FromTArgF, FromF1);
9244 auto *ToXImported = Import(FromX, Lang_CXX11);
9245 // The template argument 1 of 'X' in the "From" code points to a function
9246 // that has no definition. The import must ensure that this template argument
9247 // is imported in a way that it will point to the existing 'f1' function, not
9248 // to the 'f1' that is imported. In this way when specialization of 'X' is
9249 // imported it will have the same template arguments as the existing one.
9250 EXPECT_EQ(ToXImported, ToX);
9251 // FIXME: This matcher causes a crash "Tried to match orphan node".
9252 // The code is removed until the problem is fixed.
9253 // auto *ToF1Imported =
9254 // LastDeclMatcher<FunctionDecl>().match(ToTU,
9255 // functionDecl(hasName("f1"),isInstantiated()));
9256 // EXPECT_NE(ToF1Imported, ToF1);
9257 // EXPECT_EQ(ToF1Imported->getPreviousDecl(), ToF1);
9260 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
9261 DefaultTestValuesForRunOptions);
9263 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportPath,
9264 ::testing::Values(std::vector<std::string>()));
9266 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportExpr,
9267 DefaultTestValuesForRunOptions);
9269 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFixedPointExpr,
9270 ExtendWithOptions(DefaultTestArrayForRunOptions,
9271 std::vector<std::string>{
9272 "-ffixed-point"}));
9274 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportBlock,
9275 ExtendWithOptions(DefaultTestArrayForRunOptions,
9276 std::vector<std::string>{
9277 "-fblocks"}));
9279 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportType,
9280 DefaultTestValuesForRunOptions);
9282 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportDecl,
9283 DefaultTestValuesForRunOptions);
9285 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase,
9286 DefaultTestValuesForRunOptions);
9288 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ErrorHandlingTest,
9289 DefaultTestValuesForRunOptions);
9291 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, RedirectingImporterTest,
9292 DefaultTestValuesForRunOptions);
9294 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctions,
9295 DefaultTestValuesForRunOptions);
9297 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAutoFunctions,
9298 DefaultTestValuesForRunOptions);
9300 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctionTemplates,
9301 DefaultTestValuesForRunOptions);
9303 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctionTemplates,
9304 DefaultTestValuesForRunOptions);
9306 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportClasses,
9307 DefaultTestValuesForRunOptions);
9309 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctions,
9310 DefaultTestValuesForRunOptions);
9312 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendClasses,
9313 DefaultTestValuesForRunOptions);
9315 INSTANTIATE_TEST_SUITE_P(ParameterizedTests,
9316 ImportFunctionTemplateSpecializations,
9317 DefaultTestValuesForRunOptions);
9319 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportImplicitMethods,
9320 DefaultTestValuesForRunOptions);
9322 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportVariables,
9323 DefaultTestValuesForRunOptions);
9325 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, LLDBLookupTest,
9326 DefaultTestValuesForRunOptions);
9328 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportSourceLocations,
9329 DefaultTestValuesForRunOptions);
9331 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportWithExternalSource,
9332 DefaultTestValuesForRunOptions);
9334 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAttributes,
9335 DefaultTestValuesForRunOptions);
9337 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportInjectedClassNameType,
9338 DefaultTestValuesForRunOptions);
9340 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportMatrixType,
9341 DefaultTestValuesForRunOptions);
9343 // FIXME: Make ImportOpenCLPipe test work.
9344 // INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportOpenCLPipe,
9345 // DefaultTestValuesForRunOptions);
9346 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImportOpenCLPipe);
9348 } // end namespace ast_matchers
9349 } // end namespace clang