[Github] Label lldb-dap PRs (#125139)
[llvm-project.git] / clang / unittests / AST / ASTImporterTest.cpp
blob114d0b461dae88058f674e4f903ddbf5bc0daa32
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 "clang/Testing/CommandLineArgs.h"
16 #include "llvm/Support/SmallVectorMemoryBuffer.h"
18 #include "clang/AST/DeclContextInternals.h"
19 #include "gtest/gtest.h"
21 #include "ASTImporterFixtures.h"
22 #include <optional>
24 namespace clang {
25 namespace ast_matchers {
27 using internal::Matcher;
29 static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) {
30 QualType Ty = FD->getFriendType()->getType().getCanonicalType();
31 return cast<RecordType>(Ty)->getDecl();
34 struct ImportExpr : TestImportBase {};
35 struct ImportType : TestImportBase {};
36 struct ImportDecl : TestImportBase {};
37 struct ImportFixedPointExpr : ImportExpr {};
39 struct CanonicalRedeclChain : ASTImporterOptionSpecificTestBase {};
41 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers) {
42 Decl *FromTU = getTuDecl("void f();", Lang_CXX03);
43 auto Pattern = functionDecl(hasName("f"));
44 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
46 auto Redecls = getCanonicalForwardRedeclChain(D0);
47 ASSERT_EQ(Redecls.size(), 1u);
48 EXPECT_EQ(D0, Redecls[0]);
51 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers2) {
52 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
53 auto Pattern = functionDecl(hasName("f"));
54 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
55 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
56 FunctionDecl *D1 = D2->getPreviousDecl();
58 auto Redecls = getCanonicalForwardRedeclChain(D0);
59 ASSERT_EQ(Redecls.size(), 3u);
60 EXPECT_EQ(D0, Redecls[0]);
61 EXPECT_EQ(D1, Redecls[1]);
62 EXPECT_EQ(D2, Redecls[2]);
65 TEST_P(CanonicalRedeclChain, ShouldBeSameForAllDeclInTheChain) {
66 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
67 auto Pattern = functionDecl(hasName("f"));
68 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
69 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
70 FunctionDecl *D1 = D2->getPreviousDecl();
72 auto RedeclsD0 = getCanonicalForwardRedeclChain(D0);
73 auto RedeclsD1 = getCanonicalForwardRedeclChain(D1);
74 auto RedeclsD2 = getCanonicalForwardRedeclChain(D2);
76 EXPECT_THAT(RedeclsD0, ::testing::ContainerEq(RedeclsD1));
77 EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2));
80 namespace {
81 struct RedirectingImporter : public ASTImporter {
82 using ASTImporter::ASTImporter;
84 protected:
85 llvm::Expected<Decl *> ImportImpl(Decl *FromD) override {
86 auto *ND = dyn_cast<NamedDecl>(FromD);
87 if (!ND || ND->getName() != "shouldNotBeImported")
88 return ASTImporter::ImportImpl(FromD);
89 for (Decl *D : getToContext().getTranslationUnitDecl()->decls()) {
90 if (auto *ND = dyn_cast<NamedDecl>(D))
91 if (ND->getName() == "realDecl") {
92 RegisterImportedDecl(FromD, ND);
93 return ND;
96 return ASTImporter::ImportImpl(FromD);
100 } // namespace
102 struct RedirectingImporterTest : ASTImporterOptionSpecificTestBase {
103 RedirectingImporterTest() {
104 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
105 ASTContext &FromContext, FileManager &FromFileManager,
106 bool MinimalImport,
107 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
108 return new RedirectingImporter(ToContext, ToFileManager, FromContext,
109 FromFileManager, MinimalImport,
110 SharedState);
115 // Test that an ASTImporter subclass can intercept an import call.
116 TEST_P(RedirectingImporterTest, InterceptImport) {
117 Decl *From, *To;
118 std::tie(From, To) =
119 getImportedDecl("class shouldNotBeImported {};", Lang_CXX03,
120 "class realDecl {};", Lang_CXX03, "shouldNotBeImported");
121 auto *Imported = cast<CXXRecordDecl>(To);
122 EXPECT_EQ(Imported->getQualifiedNameAsString(), "realDecl");
124 // Make sure our importer prevented the importing of the decl.
125 auto *ToTU = Imported->getTranslationUnitDecl();
126 auto Pattern = functionDecl(hasName("shouldNotBeImported"));
127 unsigned count =
128 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
129 EXPECT_EQ(0U, count);
132 // Test that when we indirectly import a declaration the custom ASTImporter
133 // is still intercepting the import.
134 TEST_P(RedirectingImporterTest, InterceptIndirectImport) {
135 Decl *From, *To;
136 std::tie(From, To) =
137 getImportedDecl("class shouldNotBeImported {};"
138 "class F { shouldNotBeImported f; };",
139 Lang_CXX03, "class realDecl {};", Lang_CXX03, "F");
141 // Make sure our ASTImporter prevented the importing of the decl.
142 auto *ToTU = To->getTranslationUnitDecl();
143 auto Pattern = functionDecl(hasName("shouldNotBeImported"));
144 unsigned count =
145 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
146 EXPECT_EQ(0U, count);
149 struct ImportPath : ASTImporterOptionSpecificTestBase {
150 Decl *FromTU;
151 FunctionDecl *D0, *D1, *D2;
152 ImportPath() {
153 FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
154 auto Pattern = functionDecl(hasName("f"));
155 D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
156 D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
157 D1 = D2->getPreviousDecl();
161 TEST_P(ImportPath, Push) {
162 ASTImporter::ImportPathTy path;
163 path.push(D0);
164 EXPECT_FALSE(path.hasCycleAtBack());
167 TEST_P(ImportPath, SmallCycle) {
168 ASTImporter::ImportPathTy path;
169 path.push(D0);
170 path.push(D0);
171 EXPECT_TRUE(path.hasCycleAtBack());
172 path.pop();
173 EXPECT_FALSE(path.hasCycleAtBack());
174 path.push(D0);
175 EXPECT_TRUE(path.hasCycleAtBack());
178 TEST_P(ImportPath, GetSmallCycle) {
179 ASTImporter::ImportPathTy path;
180 path.push(D0);
181 path.push(D0);
182 EXPECT_TRUE(path.hasCycleAtBack());
183 std::array<Decl* ,2> Res;
184 int i = 0;
185 for (Decl *Di : path.getCycleAtBack()) {
186 Res[i++] = Di;
188 ASSERT_EQ(i, 2);
189 EXPECT_EQ(Res[0], D0);
190 EXPECT_EQ(Res[1], D0);
193 TEST_P(ImportPath, GetCycle) {
194 ASTImporter::ImportPathTy path;
195 path.push(D0);
196 path.push(D1);
197 path.push(D2);
198 path.push(D0);
199 EXPECT_TRUE(path.hasCycleAtBack());
200 std::array<Decl* ,4> Res;
201 int i = 0;
202 for (Decl *Di : path.getCycleAtBack()) {
203 Res[i++] = Di;
205 ASSERT_EQ(i, 4);
206 EXPECT_EQ(Res[0], D0);
207 EXPECT_EQ(Res[1], D2);
208 EXPECT_EQ(Res[2], D1);
209 EXPECT_EQ(Res[3], D0);
212 TEST_P(ImportPath, CycleAfterCycle) {
213 ASTImporter::ImportPathTy path;
214 path.push(D0);
215 path.push(D1);
216 path.push(D0);
217 path.push(D1);
218 path.push(D2);
219 path.push(D0);
220 EXPECT_TRUE(path.hasCycleAtBack());
221 std::array<Decl* ,4> Res;
222 int i = 0;
223 for (Decl *Di : path.getCycleAtBack()) {
224 Res[i++] = Di;
226 ASSERT_EQ(i, 4);
227 EXPECT_EQ(Res[0], D0);
228 EXPECT_EQ(Res[1], D2);
229 EXPECT_EQ(Res[2], D1);
230 EXPECT_EQ(Res[3], D0);
232 path.pop();
233 path.pop();
234 path.pop();
235 EXPECT_TRUE(path.hasCycleAtBack());
236 i = 0;
237 for (Decl *Di : path.getCycleAtBack()) {
238 Res[i++] = Di;
240 ASSERT_EQ(i, 3);
241 EXPECT_EQ(Res[0], D0);
242 EXPECT_EQ(Res[1], D1);
243 EXPECT_EQ(Res[2], D0);
245 path.pop();
246 EXPECT_FALSE(path.hasCycleAtBack());
249 const internal::VariadicDynCastAllOfMatcher<Stmt, SourceLocExpr> sourceLocExpr;
251 AST_MATCHER_P(SourceLocExpr, hasBuiltinStr, StringRef, Str) {
252 return Node.getBuiltinStr() == Str;
255 TEST_P(ImportExpr, ImportSourceLocExpr) {
256 MatchVerifier<Decl> Verifier;
257 testImport("void declToImport() { (void)__builtin_FILE(); }", Lang_CXX03, "",
258 Lang_CXX03, Verifier,
259 functionDecl(hasDescendant(
260 sourceLocExpr(hasBuiltinStr("__builtin_FILE")))));
261 testImport("void declToImport() { (void)__builtin_FILE_NAME(); }", Lang_CXX03,
262 "", Lang_CXX03, Verifier,
263 functionDecl(hasDescendant(
264 sourceLocExpr(hasBuiltinStr("__builtin_FILE_NAME")))));
265 testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03,
266 "", Lang_CXX03, Verifier,
267 functionDecl(hasDescendant(
268 sourceLocExpr(hasBuiltinStr("__builtin_COLUMN")))));
271 TEST_P(ImportExpr, ImportStringLiteral) {
272 MatchVerifier<Decl> Verifier;
273 testImport("void declToImport() { (void)\"foo\"; }", Lang_CXX03, "",
274 Lang_CXX03, Verifier,
275 functionDecl(hasDescendant(
276 stringLiteral(hasType(asString("const char[4]"))))));
277 testImport("void declToImport() { (void)L\"foo\"; }", Lang_CXX03, "",
278 Lang_CXX03, Verifier,
279 functionDecl(hasDescendant(
280 stringLiteral(hasType(asString("const wchar_t[4]"))))));
281 testImport("void declToImport() { (void) \"foo\" \"bar\"; }", Lang_CXX03, "",
282 Lang_CXX03, Verifier,
283 functionDecl(hasDescendant(
284 stringLiteral(hasType(asString("const char[7]"))))));
287 TEST_P(ImportExpr, ImportChooseExpr) {
288 MatchVerifier<Decl> Verifier;
290 // This case tests C code that is not condition-dependent and has a true
291 // condition.
292 testImport("void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }",
293 Lang_C99, "", Lang_C99, Verifier,
294 functionDecl(hasDescendant(chooseExpr())));
297 const internal::VariadicDynCastAllOfMatcher<Stmt, ShuffleVectorExpr>
298 shuffleVectorExpr;
300 TEST_P(ImportExpr, ImportShuffleVectorExpr) {
301 MatchVerifier<Decl> Verifier;
302 constexpr auto Code = R"code(
303 typedef double vector4double __attribute__((__vector_size__(32)));
304 vector4double declToImport(vector4double a, vector4double b) {
305 return __builtin_shufflevector(a, b, 0, 1, 2, 3);
307 )code";
308 const auto Pattern = functionDecl(hasDescendant(shuffleVectorExpr(
309 allOf(has(declRefExpr(to(parmVarDecl(hasName("a"))))),
310 has(declRefExpr(to(parmVarDecl(hasName("b"))))),
311 has(integerLiteral(equals(0))), has(integerLiteral(equals(1))),
312 has(integerLiteral(equals(2))), has(integerLiteral(equals(3)))))));
313 testImport(Code, Lang_C99, "", Lang_C99, Verifier, Pattern);
316 TEST_P(ImportExpr, ImportGNUNullExpr) {
317 MatchVerifier<Decl> Verifier;
318 testImport("void declToImport() { (void)__null; }", Lang_CXX03, "",
319 Lang_CXX03, Verifier,
320 functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger())))));
323 TEST_P(ImportExpr, ImportGenericSelectionExpr) {
324 MatchVerifier<Decl> Verifier;
326 testImport(
327 "void declToImport() { int x; (void)_Generic(x, int: 0, float: 1); }",
328 Lang_C99, "", Lang_C99, Verifier,
329 functionDecl(hasDescendant(genericSelectionExpr())));
332 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) {
333 MatchVerifier<Decl> Verifier;
334 testImport(
335 "void declToImport() { (void)nullptr; }",
336 Lang_CXX11, "", Lang_CXX11, Verifier,
337 functionDecl(hasDescendant(cxxNullPtrLiteralExpr())));
341 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) {
342 MatchVerifier<Decl> Verifier;
343 testImport("void declToImport() { (void)1.0; }", Lang_C99, "", Lang_C99,
344 Verifier,
345 functionDecl(hasDescendant(
346 floatLiteral(equals(1.0), hasType(asString("double"))))));
347 testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99, "", Lang_C99,
348 Verifier,
349 functionDecl(hasDescendant(
350 floatLiteral(equals(1.0e-5f), hasType(asString("float"))))));
353 TEST_P(ImportFixedPointExpr, ImportFixedPointerLiteralExpr) {
354 MatchVerifier<Decl> Verifier;
355 testImport("void declToImport() { (void)1.0k; }", Lang_C99, "", Lang_C99,
356 Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
357 testImport("void declToImport() { (void)0.75r; }", Lang_C99, "", Lang_C99,
358 Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
361 TEST_P(ImportExpr, ImportImaginaryLiteralExpr) {
362 MatchVerifier<Decl> Verifier;
363 testImport(
364 "void declToImport() { (void)1.0i; }",
365 Lang_CXX14, "", Lang_CXX14, Verifier,
366 functionDecl(hasDescendant(imaginaryLiteral())));
369 TEST_P(ImportExpr, ImportCompoundLiteralExpr) {
370 MatchVerifier<Decl> Verifier;
371 testImport("void declToImport() {"
372 " struct s { int x; long y; unsigned z; }; "
373 " (void)(struct s){ 42, 0L, 1U }; }",
374 Lang_CXX03, "", Lang_CXX03, Verifier,
375 functionDecl(hasDescendant(compoundLiteralExpr(
376 hasType(asString("struct s")),
377 has(initListExpr(
378 hasType(asString("struct s")),
379 has(integerLiteral(equals(42), hasType(asString("int")))),
380 has(integerLiteral(equals(0), hasType(asString("long")))),
381 has(integerLiteral(
382 equals(1), hasType(asString("unsigned int"))))))))));
385 TEST_P(ImportExpr, ImportCXXThisExpr) {
386 MatchVerifier<Decl> Verifier;
387 testImport("class declToImport { void f() { (void)this; } };", Lang_CXX03, "",
388 Lang_CXX03, Verifier,
389 cxxRecordDecl(hasMethod(hasDescendant(
390 cxxThisExpr(hasType(asString("class declToImport *")))))));
393 TEST_P(ImportExpr, ImportAtomicExpr) {
394 MatchVerifier<Decl> Verifier;
395 testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }",
396 Lang_C99, "", Lang_C99, Verifier,
397 functionDecl(hasDescendant(atomicExpr(
398 has(ignoringParenImpCasts(
399 declRefExpr(hasDeclaration(varDecl(hasName("ptr"))),
400 hasType(asString("int *"))))),
401 has(integerLiteral(equals(1), hasType(asString("int"))))))));
404 TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) {
405 MatchVerifier<Decl> Verifier;
406 testImport("void declToImport() { loop: goto loop; (void)&&loop; }", Lang_C99,
407 "", Lang_C99, Verifier,
408 functionDecl(hasDescendant(labelStmt(
409 hasDeclaration(labelDecl(hasName("loop"))))),
410 hasDescendant(addrLabelExpr(
411 hasDeclaration(labelDecl(hasName("loop")))))));
414 AST_MATCHER_P(TemplateDecl, hasTemplateDecl,
415 internal::Matcher<NamedDecl>, InnerMatcher) {
416 const NamedDecl *Template = Node.getTemplatedDecl();
417 return Template && InnerMatcher.matches(*Template, Finder, Builder);
420 TEST_P(ImportExpr, ImportParenListExpr) {
421 MatchVerifier<Decl> Verifier;
422 testImport(
423 "template<typename T> class dummy { void f() { dummy X(*this); } };"
424 "typedef dummy<int> declToImport;"
425 "template class dummy<int>;",
426 Lang_CXX03, "", Lang_CXX03, Verifier,
427 typedefDecl(hasType(elaboratedType(namesType(templateSpecializationType(
428 hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate(
429 classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(
430 allOf(hasName("f"),
431 hasBody(compoundStmt(has(declStmt(hasSingleDecl(varDecl(
432 hasInitializer(parenListExpr(has(unaryOperator(
433 hasOperatorName("*"),
434 hasUnaryOperand(
435 cxxThisExpr())))))))))))))))))))))))));
438 TEST_P(ImportExpr, ImportSwitch) {
439 MatchVerifier<Decl> Verifier;
440 testImport("void declToImport() { int b; switch (b) { case 1: break; } }",
441 Lang_C99, "", Lang_C99, Verifier,
442 functionDecl(hasDescendant(
443 switchStmt(has(compoundStmt(has(caseStmt())))))));
446 TEST_P(ImportExpr, ImportStmtExpr) {
447 MatchVerifier<Decl> Verifier;
448 testImport(
449 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
450 Lang_C99, "", Lang_C99, Verifier,
451 traverse(TK_AsIs,
452 functionDecl(hasDescendant(varDecl(
453 hasName("C"), hasType(asString("int")),
454 hasInitializer(stmtExpr(
455 hasAnySubstatement(declStmt(hasSingleDecl(varDecl(
456 hasName("X"), hasType(asString("int")),
457 hasInitializer(integerLiteral(equals(4))))))),
458 hasDescendant(implicitCastExpr()))))))));
461 TEST_P(ImportExpr, ImportConditionalOperator) {
462 MatchVerifier<Decl> Verifier;
463 testImport("void declToImport() { (void)(true ? 1 : -5); }", Lang_CXX03, "",
464 Lang_CXX03, Verifier,
465 functionDecl(hasDescendant(conditionalOperator(
466 hasCondition(cxxBoolLiteral(equals(true))),
467 hasTrueExpression(integerLiteral(equals(1))),
468 hasFalseExpression(unaryOperator(
469 hasUnaryOperand(integerLiteral(equals(5)))))))));
472 TEST_P(ImportExpr, ImportBinaryConditionalOperator) {
473 MatchVerifier<Decl> Verifier;
474 testImport(
475 "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03, "", Lang_CXX03,
476 Verifier,
477 traverse(TK_AsIs,
478 functionDecl(hasDescendant(binaryConditionalOperator(
479 hasCondition(implicitCastExpr(
480 hasSourceExpression(opaqueValueExpr(
481 hasSourceExpression(integerLiteral(equals(1))))),
482 hasType(booleanType()))),
483 hasTrueExpression(opaqueValueExpr(
484 hasSourceExpression(integerLiteral(equals(1))))),
485 hasFalseExpression(unaryOperator(
486 hasOperatorName("-"),
487 hasUnaryOperand(integerLiteral(equals(5))))))))));
490 TEST_P(ImportExpr, ImportDesignatedInitExpr) {
491 MatchVerifier<Decl> Verifier;
492 testImport(
493 "void declToImport() {"
494 " struct point { double x; double y; };"
495 " struct point ptarray[10] = "
496 "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }",
497 Lang_C99, "", Lang_C99, Verifier,
498 functionDecl(hasDescendant(initListExpr(
499 has(designatedInitExpr(designatorCountIs(2),
500 hasDescendant(floatLiteral(equals(1.0))),
501 hasDescendant(integerLiteral(equals(2))))),
502 has(designatedInitExpr(designatorCountIs(2),
503 hasDescendant(floatLiteral(equals(2.0))),
504 hasDescendant(integerLiteral(equals(2))))),
505 has(designatedInitExpr(designatorCountIs(2),
506 hasDescendant(floatLiteral(equals(1.0))),
507 hasDescendant(integerLiteral(equals(0)))))))));
510 TEST_P(ImportExpr, ImportPredefinedExpr) {
511 MatchVerifier<Decl> Verifier;
512 // __func__ expands as StringLiteral("declToImport")
513 testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "",
514 Lang_CXX03, Verifier,
515 functionDecl(hasDescendant(predefinedExpr(
516 hasType(asString("const char[13]")),
517 has(stringLiteral(hasType(asString("const char[13]"))))))));
520 TEST_P(ImportExpr, ImportInitListExpr) {
521 MatchVerifier<Decl> Verifier;
522 testImport("void declToImport() {"
523 " struct point { double x; double y; };"
524 " point ptarray[10] = { [2].y = 1.0, [2].x = 2.0,"
525 " [0].x = 1.0 }; }",
526 Lang_CXX03, "", Lang_CXX03, Verifier,
527 functionDecl(hasDescendant(initListExpr(
528 has(cxxConstructExpr(requiresZeroInitialization())),
529 has(initListExpr(
530 hasType(asString("point")), has(floatLiteral(equals(1.0))),
531 has(implicitValueInitExpr(hasType(asString("double")))))),
532 has(initListExpr(hasType(asString("point")),
533 has(floatLiteral(equals(2.0))),
534 has(floatLiteral(equals(1.0)))))))));
537 const internal::VariadicDynCastAllOfMatcher<Expr, CXXDefaultInitExpr>
538 cxxDefaultInitExpr;
540 TEST_P(ImportExpr, ImportCXXDefaultInitExpr) {
541 MatchVerifier<Decl> Verifier;
542 testImport("class declToImport { int DefInit = 5; }; declToImport X;",
543 Lang_CXX11, "", Lang_CXX11, Verifier,
544 cxxRecordDecl(hasDescendant(cxxConstructorDecl(
545 hasAnyConstructorInitializer(cxxCtorInitializer(
546 withInitializer(cxxDefaultInitExpr())))))));
547 testImport(
548 "struct X { int A = 5; }; X declToImport{};", Lang_CXX17, "", Lang_CXX17,
549 Verifier,
550 varDecl(hasInitializer(initListExpr(hasInit(0, cxxDefaultInitExpr())))));
553 const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr;
555 TEST_P(ImportExpr, ImportVAArgExpr) {
556 MatchVerifier<Decl> Verifier;
557 testImport("void declToImport(__builtin_va_list list, ...) {"
558 " (void)__builtin_va_arg(list, int); }",
559 Lang_CXX03, "", Lang_CXX03, Verifier,
560 functionDecl(hasDescendant(
561 cStyleCastExpr(hasSourceExpression(vaArgExpr())))));
564 const internal::VariadicDynCastAllOfMatcher<Stmt, BuiltinBitCastExpr>
565 builtinBitCastExpr;
567 TEST_P(ImportExpr, ImportBuiltinBitCastExpr) {
568 MatchVerifier<Decl> Verifier;
569 testImport("void declToImport(int X) {"
570 " (void)__builtin_bit_cast(float, X); }",
571 Lang_CXX20, "", Lang_CXX20, Verifier,
572 functionDecl(hasDescendant(
573 cStyleCastExpr(hasSourceExpression(builtinBitCastExpr())))));
576 TEST_P(ImportExpr, CXXTemporaryObjectExpr) {
577 MatchVerifier<Decl> Verifier;
578 testImport(
579 "struct C {};"
580 "void declToImport() { C c = C(); }",
581 Lang_CXX03, "", Lang_CXX03, Verifier,
582 traverse(TK_AsIs,
583 functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr(
584 has(materializeTemporaryExpr(has(implicitCastExpr(
585 has(cxxTemporaryObjectExpr()))))))))))));
588 TEST_P(ImportType, ImportAtomicType) {
589 MatchVerifier<Decl> Verifier;
590 testImport(
591 "void declToImport() { typedef _Atomic(int) a_int; }",
592 Lang_CXX11, "", Lang_CXX11, Verifier,
593 functionDecl(hasDescendant(typedefDecl(has(atomicType())))));
596 TEST_P(ImportType, ImportBitIntType) {
597 const AstTypeMatcher<BitIntType> bitIntType;
598 MatchVerifier<Decl> Verifier;
599 testImport("_BitInt(10) declToImport;", Lang_CXX11, "", Lang_CXX11, Verifier,
600 varDecl(hasType(bitIntType())));
603 TEST_P(ImportType, ImportDependentBitIntType) {
604 const AstTypeMatcher<DependentBitIntType> dependentBitIntType;
605 MatchVerifier<Decl> Verifier;
606 testImport("template<int Width> using declToImport = _BitInt(Width);",
607 Lang_CXX11, "", Lang_CXX11, Verifier,
608 typeAliasTemplateDecl(
609 has(typeAliasDecl(hasType(dependentBitIntType())))));
612 TEST_P(ImportType, ImportDependentAddressSpaceType) {
613 const AstTypeMatcher<DependentAddressSpaceType> dependentAddressSpaceType;
614 MatchVerifier<Decl> Verifier;
615 testImport(
617 template<typename T, int AddrSpace>
618 using declToImport = T __attribute__((address_space(AddrSpace)));
620 Lang_CXX11, "", Lang_CXX11, Verifier,
621 typeAliasTemplateDecl(
622 has(typeAliasDecl(hasType(dependentAddressSpaceType())))));
625 TEST_P(ImportType, ImportVectorType) {
626 const AstTypeMatcher<VectorType> vectorType;
627 MatchVerifier<Decl> Verifier;
628 testImport("typedef int __attribute__((vector_size(12))) declToImport;",
629 Lang_CXX11, "", Lang_CXX11, Verifier,
630 typedefDecl(hasType(vectorType())));
633 TEST_P(ImportType, ImportDependentVectorType) {
634 const AstTypeMatcher<DependentVectorType> dependentVectorType;
635 MatchVerifier<Decl> Verifier;
636 testImport(
638 template<typename T, int Size>
639 using declToImport = T __attribute__((vector_size(Size)));
641 Lang_CXX11, "", Lang_CXX11, Verifier,
642 typeAliasTemplateDecl(
643 has(typeAliasDecl(hasType(dependentVectorType())))));
646 struct ImportOpenCLPipe : ImportType {
647 std::vector<std::string> getExtraArgs() const override {
648 return {"-x", "cl", "-cl-no-stdinc", "-cl-std=CL2.0"};
652 TEST_P(ImportOpenCLPipe, ImportPipeType) {
653 const AstTypeMatcher<PipeType> pipeType;
654 MatchVerifier<Decl> Verifier;
655 testImport("typedef pipe int declToImport;", Lang_OpenCL, "", Lang_OpenCL,
656 Verifier, typedefDecl(hasType(pipeType())));
659 struct ImportMatrixType : ImportType {
660 std::vector<std::string> getExtraArgs() const override {
661 return {"-fenable-matrix"};
665 TEST_P(ImportMatrixType, ImportConstantMatrixType) {
666 const AstTypeMatcher<ConstantMatrixType> constantMatrixType;
667 MatchVerifier<Decl> Verifier;
668 testImport("typedef int __attribute__((matrix_type(5, 5))) declToImport;",
669 Lang_CXX11, "", Lang_CXX11, Verifier,
670 typedefDecl(hasType(constantMatrixType())));
673 TEST_P(ImportMatrixType, ImportDependentSizedMatrixType) {
674 const AstTypeMatcher<DependentSizedMatrixType> dependentSizedMatrixType;
675 MatchVerifier<Decl> Verifier;
676 testImport(
678 template<typename T, int Rows, int Cols>
679 using declToImport = T __attribute__((matrix_type(Rows, Cols)));
681 Lang_CXX11, "", Lang_CXX11, Verifier,
682 typeAliasTemplateDecl(
683 has(typeAliasDecl(hasType(dependentSizedMatrixType())))));
686 TEST_P(ImportType, ImportUsingType) {
687 MatchVerifier<Decl> Verifier;
688 testImport("struct C {};"
689 "void declToImport() { using ::C; new C{}; }",
690 Lang_CXX11, "", Lang_CXX11, Verifier,
691 functionDecl(hasDescendant(cxxNewExpr(hasType(pointerType(
692 pointee(elaboratedType(namesType(usingType())))))))));
695 TEST_P(ImportDecl, ImportFunctionTemplateDecl) {
696 MatchVerifier<Decl> Verifier;
697 testImport("template <typename T> void declToImport() { };", Lang_CXX03, "",
698 Lang_CXX03, Verifier, functionTemplateDecl());
701 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) {
702 MatchVerifier<Decl> Verifier;
703 testImport("template <typename T> struct C { T t; };"
704 "template <typename T> void declToImport() {"
705 " C<T> d;"
706 " (void)d.t;"
708 "void instantiate() { declToImport<int>(); }",
709 Lang_CXX03, "", Lang_CXX03, Verifier,
710 functionTemplateDecl(hasDescendant(
711 cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
712 testImport("template <typename T> struct C { T t; };"
713 "template <typename T> void declToImport() {"
714 " C<T> d;"
715 " (void)(&d)->t;"
717 "void instantiate() { declToImport<int>(); }",
718 Lang_CXX03, "", Lang_CXX03, Verifier,
719 functionTemplateDecl(hasDescendant(
720 cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
723 TEST_P(ImportType, ImportTypeAliasTemplate) {
724 MatchVerifier<Decl> Verifier;
725 testImport(
726 "template <int K>"
727 "struct dummy { static const int i = K; };"
728 "template <int K> using dummy2 = dummy<K>;"
729 "int declToImport() { return dummy2<3>::i; }",
730 Lang_CXX11, "", Lang_CXX11, Verifier,
731 traverse(TK_AsIs,
732 functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))),
733 unless(hasAncestor(
734 translationUnitDecl(has(typeAliasDecl())))))));
737 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl>
738 varTemplateSpecializationDecl;
740 TEST_P(ImportDecl, ImportVarTemplate) {
741 MatchVerifier<Decl> Verifier;
742 testImport(
743 "template <typename T>"
744 "T pi = T(3.1415926535897932385L);"
745 "void declToImport() { (void)pi<int>; }",
746 Lang_CXX14, "", Lang_CXX14, Verifier,
747 functionDecl(
748 hasDescendant(declRefExpr(to(varTemplateSpecializationDecl()))),
749 unless(hasAncestor(translationUnitDecl(has(varDecl(
750 hasName("pi"), unless(varTemplateSpecializationDecl()))))))));
753 TEST_P(ImportType, ImportPackExpansion) {
754 MatchVerifier<Decl> Verifier;
755 testImport("template <typename... Args>"
756 "struct dummy {"
757 " dummy(Args... args) {}"
758 " static const int i = 4;"
759 "};"
760 "int declToImport() { return dummy<int>::i; }",
761 Lang_CXX11, "", Lang_CXX11, Verifier,
762 traverse(TK_AsIs, functionDecl(hasDescendant(returnStmt(has(
763 implicitCastExpr(has(declRefExpr()))))))));
766 TEST_P(ImportType, ImportDependentTemplateSpecialization) {
767 MatchVerifier<Decl> Verifier;
768 testImport("template<typename T>"
769 "struct A;"
770 "template<typename T>"
771 "struct declToImport {"
772 " typename A<T>::template B<T> a;"
773 "};",
774 Lang_CXX03, "", Lang_CXX03, Verifier,
775 classTemplateDecl(has(cxxRecordDecl(has(
776 fieldDecl(hasType(dependentTemplateSpecializationType())))))));
779 TEST_P(ImportType, ImportDeducedTemplateSpecialization) {
780 MatchVerifier<Decl> Verifier;
781 testImport("template <typename T>"
782 "class C { public: C(T); };"
783 "C declToImport(123);",
784 Lang_CXX17, "", Lang_CXX17, Verifier,
785 varDecl(hasType(elaboratedType(
786 namesType(deducedTemplateSpecializationType())))));
789 const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr>
790 sizeOfPackExpr;
792 TEST_P(ImportExpr, ImportSizeOfPackExpr) {
793 MatchVerifier<Decl> Verifier;
794 testImport(
795 "template <typename... Ts>"
796 "void declToImport() {"
797 " const int i = sizeof...(Ts);"
798 "};"
799 "void g() { declToImport<int>(); }",
800 Lang_CXX11, "", Lang_CXX11, Verifier,
801 functionTemplateDecl(hasDescendant(sizeOfPackExpr())));
802 testImport(
803 "template <typename... Ts>"
804 "using X = int[sizeof...(Ts)];"
805 "template <typename... Us>"
806 "struct Y {"
807 " X<Us..., int, double, int, Us...> f;"
808 "};"
809 "Y<float, int> declToImport;",
810 Lang_CXX11, "", Lang_CXX11, Verifier,
811 varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType(
812 hasUnqualifiedDesugaredType(constantArrayType(hasSize(7))))))))));
815 TEST_P(ImportExpr, ImportCXXFoldExpr) {
816 auto Match1 = cxxFoldExpr(hasOperatorName("+"), isLeftFold(),
817 unless(hasFoldInit(expr())));
818 auto Match2 =
819 cxxFoldExpr(hasOperatorName("-"), isLeftFold(), hasFoldInit(expr()));
820 auto Match3 = cxxFoldExpr(hasOperatorName("*"), isRightFold(),
821 unless(hasFoldInit(expr())));
822 auto Match4 =
823 cxxFoldExpr(hasOperatorName("/"), isRightFold(), hasFoldInit(expr()));
825 MatchVerifier<Decl> Verifier;
826 testImport("template <typename... Ts>"
827 "void declToImport(Ts... args) {"
828 " const int i1 = (... + args);"
829 " const int i2 = (1 - ... - args);"
830 " const int i3 = (args * ...);"
831 " const int i4 = (args / ... / 1);"
832 "};"
833 "void g() { declToImport(1, 2, 3, 4, 5); }",
834 Lang_CXX17, "", Lang_CXX17, Verifier,
835 functionTemplateDecl(hasDescendant(Match1), hasDescendant(Match2),
836 hasDescendant(Match3),
837 hasDescendant(Match4)));
840 /// \brief Matches __builtin_types_compatible_p:
841 /// GNU extension to check equivalent types
842 /// Given
843 /// \code
844 /// __builtin_types_compatible_p(int, int)
845 /// \endcode
846 // will generate TypeTraitExpr <...> 'int'
847 const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr;
849 TEST_P(ImportExpr, ImportTypeTraitExpr) {
850 MatchVerifier<Decl> Verifier;
851 testImport(
852 "void declToImport() { "
853 " (void)__builtin_types_compatible_p(int, int);"
854 "}",
855 Lang_C99, "", Lang_C99, Verifier,
856 functionDecl(hasDescendant(typeTraitExpr(hasType(asString("int"))))));
859 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr;
861 TEST_P(ImportExpr, ImportCXXTypeidExpr) {
862 MatchVerifier<Decl> Verifier;
863 testImport(
864 "namespace std { class type_info {}; }"
865 "void declToImport() {"
866 " int x;"
867 " auto a = typeid(int); auto b = typeid(x);"
868 "}",
869 Lang_CXX11, "", Lang_CXX11, Verifier,
870 traverse(
871 TK_AsIs,
872 functionDecl(
873 hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant(
874 cxxTypeidExpr())))),
875 hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant(
876 cxxTypeidExpr())))))));
879 TEST_P(ImportExpr, ImportTypeTraitExprValDep) {
880 MatchVerifier<Decl> Verifier;
881 testImport(
882 "template<typename T> struct declToImport {"
883 " void m() { (void)__is_pod(T); }"
884 "};"
885 "void f() { declToImport<int>().m(); }",
886 Lang_CXX11, "", Lang_CXX11, Verifier,
887 classTemplateDecl(has(cxxRecordDecl(has(
888 functionDecl(hasDescendant(
889 typeTraitExpr(hasType(booleanType())))))))));
892 TEST_P(ImportDecl, ImportRecordDeclInFunc) {
893 MatchVerifier<Decl> Verifier;
894 testImport("int declToImport() { "
895 " struct data_t {int a;int b;};"
896 " struct data_t d;"
897 " return 0;"
898 "}",
899 Lang_C99, "", Lang_C99, Verifier,
900 functionDecl(hasBody(compoundStmt(
901 has(declStmt(hasSingleDecl(varDecl(hasName("d")))))))));
904 TEST_P(ImportDecl, ImportedVarDeclPreservesThreadLocalStorage) {
905 MatchVerifier<Decl> Verifier;
906 testImport("thread_local int declToImport;", Lang_CXX11, "", Lang_CXX11,
907 Verifier, varDecl(hasThreadStorageDuration()));
910 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) {
911 Decl *FromTU = getTuDecl("int declToImport() { "
912 " struct data_t {int a;int b;};"
913 " struct data_t d;"
914 " return 0;"
915 "}",
916 Lang_C99, "input.c");
917 auto *FromVar =
918 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d")));
919 ASSERT_TRUE(FromVar);
920 auto ToType =
921 ImportType(FromVar->getType().getCanonicalType(), FromVar, Lang_C99);
922 EXPECT_FALSE(ToType.isNull());
925 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) {
926 // This construct is not supported by ASTImporter.
927 Decl *FromTU = getTuDecl(
928 "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }",
929 Lang_C99, "input.c");
930 auto *From = FirstDeclMatcher<FunctionDecl>().match(
931 FromTU, functionDecl(hasName("declToImport")));
932 ASSERT_TRUE(From);
933 auto *To = Import(From, Lang_C99);
934 EXPECT_EQ(To, nullptr);
937 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) {
938 Decl *FromTU =
939 getTuDecl("#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n"
940 "int declToImport(){ return NONAME_SIZEOF(int); }",
941 Lang_C99, "input.c");
942 auto *From = FirstDeclMatcher<FunctionDecl>().match(
943 FromTU, functionDecl(hasName("declToImport")));
944 ASSERT_TRUE(From);
945 auto *To = Import(From, Lang_C99);
946 ASSERT_TRUE(To);
947 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
948 To, functionDecl(hasName("declToImport"),
949 hasDescendant(unaryExprOrTypeTraitExpr()))));
952 TEST_P(ASTImporterOptionSpecificTestBase,
953 ImportRecordDeclInFuncParamsFromMacro) {
954 // This construct is not supported by ASTImporter.
955 Decl *FromTU =
956 getTuDecl("#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n"
957 "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }",
958 Lang_C99, "input.c");
959 auto *From = FirstDeclMatcher<FunctionDecl>().match(
960 FromTU, functionDecl(hasName("declToImport")));
961 ASSERT_TRUE(From);
962 auto *To = Import(From, Lang_C99);
963 EXPECT_EQ(To, nullptr);
966 const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr>
967 cxxPseudoDestructorExpr;
969 TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) {
970 MatchVerifier<Decl> Verifier;
971 testImport(
972 "typedef int T;"
973 "void declToImport(int *p) {"
974 " T t;"
975 " p->T::~T();"
976 "}",
977 Lang_CXX03, "", Lang_CXX03, Verifier,
978 functionDecl(hasDescendant(callExpr(has(cxxPseudoDestructorExpr())))));
981 TEST_P(ImportDecl, ImportUsingDecl) {
982 MatchVerifier<Decl> Verifier;
983 testImport("namespace foo { int bar; }"
984 "void declToImport() { using foo::bar; }",
985 Lang_CXX03, "", Lang_CXX03, Verifier,
986 functionDecl(hasDescendant(usingDecl(hasName("bar")))));
989 TEST_P(ImportDecl, ImportUsingTemplate) {
990 MatchVerifier<Decl> Verifier;
991 testImport("namespace ns { template <typename T> struct S {}; }"
992 "template <template <typename> class T> class X {};"
993 "void declToImport() {"
994 "using ns::S; X<S> xi; }",
995 Lang_CXX11, "", Lang_CXX11, Verifier,
996 functionDecl(hasDescendant(varDecl(hasTypeLoc(elaboratedTypeLoc(
997 hasNamedTypeLoc(templateSpecializationTypeLoc(
998 hasAnyTemplateArgumentLoc(templateArgumentLoc())))))))));
1001 TEST_P(ImportDecl, ImportUsingEnumDecl) {
1002 MatchVerifier<Decl> Verifier;
1003 testImport("namespace foo { enum bar { baz, toto, quux }; }"
1004 "void declToImport() { using enum foo::bar; }",
1005 Lang_CXX20, "", Lang_CXX20, Verifier,
1006 functionDecl(hasDescendant(usingEnumDecl(hasName("bar")))));
1009 const internal::VariadicDynCastAllOfMatcher<Decl, UsingPackDecl> usingPackDecl;
1011 TEST_P(ImportDecl, ImportUsingPackDecl) {
1012 MatchVerifier<Decl> Verifier;
1013 testImport(
1014 "struct A { int operator()() { return 1; } };"
1015 "struct B { int operator()() { return 2; } };"
1016 "template<typename ...T> struct C : T... { using T::operator()...; };"
1017 "C<A, B> declToImport;",
1018 Lang_CXX20, "", Lang_CXX20, Verifier,
1019 varDecl(hasType(elaboratedType(namesType(templateSpecializationType(
1020 hasDeclaration(classTemplateSpecializationDecl(
1021 hasDescendant(usingPackDecl())))))))));
1024 /// \brief Matches shadow declarations introduced into a scope by a
1025 /// (resolved) using declaration.
1027 /// Given
1028 /// \code
1029 /// namespace n { int f; }
1030 /// namespace declToImport { using n::f; }
1031 /// \endcode
1032 /// usingShadowDecl()
1033 /// matches \code f \endcode
1034 const internal::VariadicDynCastAllOfMatcher<Decl,
1035 UsingShadowDecl> usingShadowDecl;
1037 TEST_P(ImportDecl, ImportUsingShadowDecl) {
1038 MatchVerifier<Decl> Verifier;
1039 // from using-decl
1040 testImport("namespace foo { int bar; }"
1041 "namespace declToImport { using foo::bar; }",
1042 Lang_CXX03, "", Lang_CXX03, Verifier,
1043 namespaceDecl(has(usingShadowDecl(hasName("bar")))));
1044 // from using-enum-decl
1045 testImport("namespace foo { enum bar {baz, toto, quux }; }"
1046 "namespace declToImport { using enum foo::bar; }",
1047 Lang_CXX20, "", Lang_CXX20, Verifier,
1048 namespaceDecl(has(usingShadowDecl(hasName("baz")))));
1051 TEST_P(ImportExpr, ImportUnresolvedLookupExpr) {
1052 MatchVerifier<Decl> Verifier;
1053 testImport("template<typename T> int foo();"
1054 "template <typename T> void declToImport() {"
1055 " (void)::foo<T>;"
1056 " (void)::template foo<T>;"
1058 "void instantiate() { declToImport<int>(); }",
1059 Lang_CXX03, "", Lang_CXX03, Verifier,
1060 functionTemplateDecl(hasDescendant(unresolvedLookupExpr())));
1063 TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) {
1064 MatchVerifier<Decl> Verifier;
1065 testImport("template <typename T> struct C { T t; };"
1066 "template <typename T> void declToImport() {"
1067 " C<T> d;"
1068 " d.t = T();"
1070 "void instantiate() { declToImport<int>(); }",
1071 Lang_CXX03, "", Lang_CXX03, Verifier,
1072 functionTemplateDecl(hasDescendant(
1073 binaryOperator(has(cxxUnresolvedConstructExpr())))));
1074 testImport("template <typename T> struct C { T t; };"
1075 "template <typename T> void declToImport() {"
1076 " C<T> d;"
1077 " (&d)->t = T();"
1079 "void instantiate() { declToImport<int>(); }",
1080 Lang_CXX03, "", Lang_CXX03, Verifier,
1081 functionTemplateDecl(hasDescendant(
1082 binaryOperator(has(cxxUnresolvedConstructExpr())))));
1085 /// Check that function "declToImport()" (which is the templated function
1086 /// for corresponding FunctionTemplateDecl) is not added into DeclContext.
1087 /// Same for class template declarations.
1088 TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) {
1089 MatchVerifier<Decl> Verifier;
1090 testImport("template <typename T> void declToImport() { T a = 1; }"
1091 "void instantiate() { declToImport<int>(); }",
1092 Lang_CXX03, "", Lang_CXX03, Verifier,
1093 functionTemplateDecl(hasAncestor(translationUnitDecl(
1094 unless(has(functionDecl(hasName("declToImport"))))))));
1095 testImport("template <typename T> struct declToImport { T t; };"
1096 "void instantiate() { declToImport<int>(); }",
1097 Lang_CXX03, "", Lang_CXX03, Verifier,
1098 classTemplateDecl(hasAncestor(translationUnitDecl(
1099 unless(has(cxxRecordDecl(hasName("declToImport"))))))));
1102 TEST_P(ImportDecl, ImportClassTemplatePartialSpecialization) {
1103 MatchVerifier<Decl> Verifier;
1104 auto Code =
1105 R"s(
1106 struct declToImport {
1107 template <typename T0> struct X;
1108 template <typename T0> struct X<T0 *> {};
1110 )s";
1111 testImport(Code, Lang_CXX03, "", Lang_CXX03, Verifier,
1112 recordDecl(has(classTemplateDecl()),
1113 has(classTemplateSpecializationDecl())));
1116 TEST_P(ImportExpr, CXXOperatorCallExpr) {
1117 MatchVerifier<Decl> Verifier;
1118 testImport(
1119 "class declToImport {"
1120 " void f() { *this = declToImport(); }"
1121 "};",
1122 Lang_CXX03, "", Lang_CXX03, Verifier,
1123 cxxRecordDecl(has(cxxMethodDecl(hasDescendant(cxxOperatorCallExpr())))));
1126 TEST_P(ImportExpr, DependentSizedArrayType) {
1127 MatchVerifier<Decl> Verifier;
1128 testImport("template<typename T, int Size> class declToImport {"
1129 " T data[Size];"
1130 "};",
1131 Lang_CXX03, "", Lang_CXX03, Verifier,
1132 classTemplateDecl(has(cxxRecordDecl(
1133 has(fieldDecl(hasType(dependentSizedArrayType())))))));
1136 TEST_P(ImportExpr, DependentSizedExtVectorType) {
1137 MatchVerifier<Decl> Verifier;
1138 testImport("template<typename T, int Size>"
1139 "class declToImport {"
1140 " typedef T __attribute__((ext_vector_type(Size))) type;"
1141 "};",
1142 Lang_CXX03, "", Lang_CXX03, Verifier,
1143 classTemplateDecl(has(cxxRecordDecl(
1144 has(typedefDecl(hasType(dependentSizedExtVectorType())))))));
1147 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingPackDecl) {
1148 Decl *FromTU = getTuDecl(
1149 "struct A { int operator()() { return 1; } };"
1150 "struct B { int operator()() { return 2; } };"
1151 "template<typename ...T> struct C : T... { using T::operator()...; };"
1152 "C<A, B> Var;",
1153 Lang_CXX20);
1155 auto From = FirstDeclMatcher<UsingPackDecl>().match(FromTU, usingPackDecl());
1156 ASSERT_TRUE(From);
1157 auto To = cast<UsingPackDecl>(Import(From, Lang_CXX20));
1158 ASSERT_TRUE(To);
1160 ArrayRef<NamedDecl *> FromExpansions = From->expansions();
1161 ArrayRef<NamedDecl *> ToExpansions = To->expansions();
1162 ASSERT_EQ(FromExpansions.size(), ToExpansions.size());
1163 for (unsigned int I = 0; I < FromExpansions.size(); ++I) {
1164 auto ImportedExpansion = Import(FromExpansions[I], Lang_CXX20);
1165 EXPECT_EQ(ImportedExpansion, ToExpansions[I]);
1168 auto ImportedDC = cast<Decl>(Import(From->getDeclContext(), Lang_CXX20));
1169 EXPECT_EQ(ImportedDC, cast<Decl>(To->getDeclContext()));
1172 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) {
1173 Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03);
1174 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
1175 FromTU, templateTypeParmDecl(hasName("T")));
1176 TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
1177 ASSERT_FALSE(To->hasDefaultArgument());
1180 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) {
1181 Decl *FromTU =
1182 getTuDecl("template<typename T = int> struct X {};", Lang_CXX03);
1183 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
1184 FromTU, templateTypeParmDecl(hasName("T")));
1185 TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
1186 ASSERT_TRUE(To->hasDefaultArgument());
1187 QualType ToArg = To->getDefaultArgument().getArgument().getAsType();
1188 ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy));
1191 TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) {
1192 Decl *FromTU =
1193 getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }",
1194 Lang_CXX03);
1195 auto From = FirstDeclMatcher<FunctionDecl>().match(
1196 FromTU, functionDecl(hasName("f")));
1197 ASSERT_TRUE(From);
1198 ASSERT_TRUE(
1199 cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front())
1200 ->getSubExpr()
1201 ->getBeginLoc()
1202 .isValid());
1203 FunctionDecl *To = Import(From, Lang_CXX03);
1204 ASSERT_TRUE(To);
1205 ASSERT_TRUE(
1206 cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front())
1207 ->getSubExpr()
1208 ->getBeginLoc()
1209 .isValid());
1212 TEST_P(ASTImporterOptionSpecificTestBase,
1213 TemplateTemplateParmDeclNoDefaultArg) {
1214 Decl *FromTU = getTuDecl(R"(
1215 template<template<typename> typename TT> struct Y {};
1217 Lang_CXX17);
1218 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
1219 FromTU, templateTemplateParmDecl(hasName("TT")));
1220 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
1221 ASSERT_FALSE(To->hasDefaultArgument());
1224 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) {
1225 Decl *FromTU = getTuDecl(R"(
1226 template<typename T> struct X {};
1227 template<template<typename> typename TT = X> struct Y {};
1229 Lang_CXX17);
1230 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
1231 FromTU, templateTemplateParmDecl(hasName("TT")));
1232 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
1233 ASSERT_TRUE(To->hasDefaultArgument());
1234 const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument();
1235 ASSERT_TRUE(To->isTemplateDecl());
1236 TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl();
1238 // Find the default argument template 'X' in the AST and compare it against
1239 // the default argument we got.
1240 auto ToExpectedDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
1241 To->getTranslationUnitDecl(), classTemplateDecl(hasName("X")));
1242 ASSERT_EQ(ToTemplate, ToExpectedDecl);
1245 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclNoDefaultArg) {
1246 Decl *FromTU = getTuDecl("template<int N> struct X {};", Lang_CXX03);
1247 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
1248 FromTU, nonTypeTemplateParmDecl(hasName("N")));
1249 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
1250 ASSERT_FALSE(To->hasDefaultArgument());
1253 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclDefaultArg) {
1254 Decl *FromTU = getTuDecl("template<int S = 1> struct X {};", Lang_CXX03);
1255 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
1256 FromTU, nonTypeTemplateParmDecl(hasName("S")));
1257 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
1258 ASSERT_TRUE(To->hasDefaultArgument());
1259 Stmt *ToArg = To->getDefaultArgument().getArgument().getAsExpr();
1260 ASSERT_TRUE(isa<IntegerLiteral>(ToArg));
1261 ASSERT_EQ(cast<IntegerLiteral>(ToArg)->getValue().getLimitedValue(), 1U);
1264 TEST_P(ASTImporterOptionSpecificTestBase, TemplateArgumentsDefaulted) {
1265 Decl *FromTU = getTuDecl(R"(
1266 template<typename T> struct X {};
1267 template<typename TP = double,
1268 int NTTP = 50,
1269 template<typename> typename TT = X> struct S {};
1270 S<> s;
1272 Lang_CXX17);
1273 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
1274 FromTU, classTemplateSpecializationDecl(hasName("S")));
1275 ASSERT_TRUE(FromSpec);
1276 auto *ToSpec = Import(FromSpec, Lang_CXX03);
1277 ASSERT_TRUE(ToSpec);
1278 auto const &TList = ToSpec->getTemplateArgs();
1279 for (auto const &Arg : TList.asArray()) {
1280 ASSERT_TRUE(Arg.getIsDefaulted());
1284 TEST_P(ASTImporterOptionSpecificTestBase,
1285 ImportOfTemplatedDeclOfClassTemplateDecl) {
1286 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
1287 auto From =
1288 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
1289 ASSERT_TRUE(From);
1290 auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX03));
1291 ASSERT_TRUE(To);
1292 Decl *ToTemplated = To->getTemplatedDecl();
1293 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
1294 EXPECT_TRUE(ToTemplated1);
1295 EXPECT_EQ(ToTemplated1, ToTemplated);
1298 TEST_P(ASTImporterOptionSpecificTestBase,
1299 ImportOfTemplatedDeclOfFunctionTemplateDecl) {
1300 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
1301 auto From = FirstDeclMatcher<FunctionTemplateDecl>().match(
1302 FromTU, functionTemplateDecl());
1303 ASSERT_TRUE(From);
1304 auto To = cast<FunctionTemplateDecl>(Import(From, Lang_CXX03));
1305 ASSERT_TRUE(To);
1306 Decl *ToTemplated = To->getTemplatedDecl();
1307 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
1308 EXPECT_TRUE(ToTemplated1);
1309 EXPECT_EQ(ToTemplated1, ToTemplated);
1312 TEST_P(ASTImporterOptionSpecificTestBase,
1313 ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) {
1314 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
1315 auto FromFT =
1316 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
1317 ASSERT_TRUE(FromFT);
1319 auto ToTemplated =
1320 cast<CXXRecordDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1321 EXPECT_TRUE(ToTemplated);
1322 auto ToTU = ToTemplated->getTranslationUnitDecl();
1323 auto ToFT =
1324 FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, classTemplateDecl());
1325 EXPECT_TRUE(ToFT);
1328 TEST_P(ASTImporterOptionSpecificTestBase,
1329 ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
1330 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
1331 auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1332 FromTU, functionTemplateDecl());
1333 ASSERT_TRUE(FromFT);
1335 auto ToTemplated =
1336 cast<FunctionDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1337 EXPECT_TRUE(ToTemplated);
1338 auto ToTU = ToTemplated->getTranslationUnitDecl();
1339 auto ToFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1340 ToTU, functionTemplateDecl());
1341 EXPECT_TRUE(ToFT);
1344 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) {
1345 auto Code =
1347 namespace x {
1348 template<class X> struct S1{};
1349 template<class X> struct S2{};
1350 template<class X> struct S3{};
1353 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
1354 auto FromNs =
1355 FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl());
1356 auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX03));
1357 ASSERT_TRUE(ToNs);
1358 auto From =
1359 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU,
1360 classTemplateDecl(
1361 hasName("S2")));
1362 auto To =
1363 FirstDeclMatcher<ClassTemplateDecl>().match(ToNs,
1364 classTemplateDecl(
1365 hasName("S2")));
1366 ASSERT_TRUE(From);
1367 ASSERT_TRUE(To);
1368 auto ToTemplated = To->getTemplatedDecl();
1369 auto ToTemplated1 =
1370 cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX03));
1371 EXPECT_TRUE(ToTemplated1);
1372 ASSERT_EQ(ToTemplated1, ToTemplated);
1375 TEST_P(ASTImporterOptionSpecificTestBase,
1376 ImportTemplateSpecializationStaticMember) {
1377 auto FromCode =
1379 template <typename H> class Test{
1380 public:
1381 static const unsigned int length;
1384 template<> const unsigned int Test<int>::length;
1385 template<> const unsigned int Test<int>::length = 0;
1387 auto ToCode =
1389 template <typename H> class Test {
1390 public:
1391 static const unsigned int length;
1394 template <> const unsigned int Test<int>::length;
1396 void foo() { int i = 1 / Test<int>::length; }
1398 Decl *FromTU = getTuDecl(FromCode, Lang_CXX14);
1399 auto FromDecl = FirstDeclMatcher<VarDecl>().match(
1400 FromTU, varDecl(hasName("length"), isDefinition()));
1401 Decl *ToTu = getToTuDecl(ToCode, Lang_CXX14);
1402 auto ToX = Import(FromDecl, Lang_CXX03);
1403 auto ToDecl = FirstDeclMatcher<VarDecl>().match(
1404 ToTu, varDecl(hasName("length"), isDefinition()));
1405 EXPECT_TRUE(ToX);
1406 EXPECT_EQ(ToX, ToDecl);
1409 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) {
1410 // This tests the import of isConditionTrue directly to make sure the importer
1411 // gets it right.
1412 Decl *From, *To;
1413 std::tie(From, To) = getImportedDecl(
1414 "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", Lang_C99,
1415 "", Lang_C99);
1417 auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext());
1418 auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext());
1420 const ChooseExpr *FromChooseExpr =
1421 selectFirst<ChooseExpr>("choose", FromResults);
1422 ASSERT_TRUE(FromChooseExpr);
1424 const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults);
1425 ASSERT_TRUE(ToChooseExpr);
1427 EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue());
1428 EXPECT_EQ(FromChooseExpr->isConditionDependent(),
1429 ToChooseExpr->isConditionDependent());
1432 TEST_P(ASTImporterOptionSpecificTestBase, ImportConvertVectorExpr) {
1433 Decl *From, *To;
1434 std::tie(From, To) = getImportedDecl(
1435 "typedef double v4double __attribute__((__vector_size__(32)));"
1436 "typedef float v4float __attribute__((__vector_size__(16)));"
1437 "v4float vf;"
1438 "void declToImport() { (void)__builtin_convertvector(vf, v4double); }",
1439 Lang_CXX03, "", Lang_CXX03);
1441 auto ToResults =
1442 match(convertVectorExpr().bind("convert"), To->getASTContext());
1443 auto FromResults =
1444 match(convertVectorExpr().bind("convert"), From->getASTContext());
1446 const ConvertVectorExpr *FromConvertVectorExpr =
1447 selectFirst<ConvertVectorExpr>("convert", FromResults);
1448 ASSERT_TRUE(FromConvertVectorExpr);
1450 const ConvertVectorExpr *ToConvertVectorExpr =
1451 selectFirst<ConvertVectorExpr>("convert", ToResults);
1452 ASSERT_TRUE(ToConvertVectorExpr);
1455 TEST_P(ASTImporterOptionSpecificTestBase, ImportGenericSelectionExpr) {
1456 Decl *From, *To;
1457 std::tie(From, To) = getImportedDecl(
1459 int declToImport() {
1460 int x;
1461 return _Generic(x, int: 0, default: 1);
1464 Lang_C99, "", Lang_C99);
1466 auto ToResults =
1467 match(genericSelectionExpr().bind("expr"), To->getASTContext());
1468 auto FromResults =
1469 match(genericSelectionExpr().bind("expr"), From->getASTContext());
1471 const GenericSelectionExpr *FromGenericSelectionExpr =
1472 selectFirst<GenericSelectionExpr>("expr", FromResults);
1473 ASSERT_TRUE(FromGenericSelectionExpr);
1475 const GenericSelectionExpr *ToGenericSelectionExpr =
1476 selectFirst<GenericSelectionExpr>("expr", ToResults);
1477 ASSERT_TRUE(ToGenericSelectionExpr);
1479 EXPECT_EQ(FromGenericSelectionExpr->isResultDependent(),
1480 ToGenericSelectionExpr->isResultDependent());
1481 EXPECT_EQ(FromGenericSelectionExpr->getResultIndex(),
1482 ToGenericSelectionExpr->getResultIndex());
1485 TEST_P(ASTImporterOptionSpecificTestBase,
1486 ImportFunctionWithBackReferringParameter) {
1487 Decl *From, *To;
1488 std::tie(From, To) = getImportedDecl(
1490 template <typename T> struct X {};
1492 void declToImport(int y, X<int> &x) {}
1494 template <> struct X<int> {
1495 void g() {
1496 X<int> x;
1497 declToImport(0, x);
1501 Lang_CXX03, "", Lang_CXX03);
1503 MatchVerifier<Decl> Verifier;
1504 auto Matcher = functionDecl(hasName("declToImport"),
1505 parameterCountIs(2),
1506 hasParameter(0, hasName("y")),
1507 hasParameter(1, hasName("x")),
1508 hasParameter(1, hasType(asString("X<int> &"))));
1509 ASSERT_TRUE(Verifier.match(From, Matcher));
1510 EXPECT_TRUE(Verifier.match(To, Matcher));
1513 TEST_P(ASTImporterOptionSpecificTestBase,
1514 TUshouldNotContainTemplatedDeclOfFunctionTemplates) {
1515 Decl *From, *To;
1516 std::tie(From, To) =
1517 getImportedDecl("template <typename T> void declToImport() { T a = 1; }"
1518 "void instantiate() { declToImport<int>(); }",
1519 Lang_CXX03, "", Lang_CXX03);
1521 auto Check = [](Decl *D) -> bool {
1522 auto TU = D->getTranslationUnitDecl();
1523 for (auto Child : TU->decls()) {
1524 if (auto *FD = dyn_cast<FunctionDecl>(Child)) {
1525 if (FD->getNameAsString() == "declToImport") {
1526 GTEST_NONFATAL_FAILURE_(
1527 "TU should not contain any FunctionDecl with name declToImport");
1528 return false;
1532 return true;
1535 ASSERT_TRUE(Check(From));
1536 EXPECT_TRUE(Check(To));
1539 TEST_P(ASTImporterOptionSpecificTestBase,
1540 TUshouldNotContainTemplatedDeclOfClassTemplates) {
1541 Decl *From, *To;
1542 std::tie(From, To) =
1543 getImportedDecl("template <typename T> struct declToImport { T t; };"
1544 "void instantiate() { declToImport<int>(); }",
1545 Lang_CXX03, "", Lang_CXX03);
1547 auto Check = [](Decl *D) -> bool {
1548 auto TU = D->getTranslationUnitDecl();
1549 for (auto Child : TU->decls()) {
1550 if (auto *RD = dyn_cast<CXXRecordDecl>(Child)) {
1551 if (RD->getNameAsString() == "declToImport") {
1552 GTEST_NONFATAL_FAILURE_(
1553 "TU should not contain any CXXRecordDecl with name declToImport");
1554 return false;
1558 return true;
1561 ASSERT_TRUE(Check(From));
1562 EXPECT_TRUE(Check(To));
1565 TEST_P(ASTImporterOptionSpecificTestBase,
1566 TUshouldNotContainTemplatedDeclOfTypeAlias) {
1567 Decl *From, *To;
1568 std::tie(From, To) =
1569 getImportedDecl(
1570 "template <typename T> struct X {};"
1571 "template <typename T> using declToImport = X<T>;"
1572 "void instantiate() { declToImport<int> a; }",
1573 Lang_CXX11, "", Lang_CXX11);
1575 auto Check = [](Decl *D) -> bool {
1576 auto TU = D->getTranslationUnitDecl();
1577 for (auto Child : TU->decls()) {
1578 if (auto *AD = dyn_cast<TypeAliasDecl>(Child)) {
1579 if (AD->getNameAsString() == "declToImport") {
1580 GTEST_NONFATAL_FAILURE_(
1581 "TU should not contain any TypeAliasDecl with name declToImport");
1582 return false;
1586 return true;
1589 ASSERT_TRUE(Check(From));
1590 EXPECT_TRUE(Check(To));
1593 TEST_P(ASTImporterOptionSpecificTestBase,
1594 TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
1596 Decl *From, *To;
1597 std::tie(From, To) = getImportedDecl(
1599 template<class T>
1600 class Base {};
1601 class declToImport : public Base<declToImport> {};
1603 Lang_CXX03, "", Lang_CXX03);
1605 // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU.
1606 auto Pattern =
1607 translationUnitDecl(unless(has(classTemplateSpecializationDecl())));
1608 ASSERT_TRUE(
1609 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1610 EXPECT_TRUE(
1611 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1613 // Check that the ClassTemplateSpecializationDecl is the child of the
1614 // ClassTemplateDecl.
1615 Pattern = translationUnitDecl(has(classTemplateDecl(
1616 hasName("Base"), has(classTemplateSpecializationDecl()))));
1617 ASSERT_TRUE(
1618 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1619 EXPECT_TRUE(
1620 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1623 AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
1624 size_t Index = 0;
1625 for (Decl *D : Node.decls()) {
1626 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
1627 auto *ND = cast<NamedDecl>(D);
1628 if (Index == Order.size())
1629 return false;
1630 if (ND->getName() != Order[Index])
1631 return false;
1632 ++Index;
1635 return Index == Order.size();
1638 TEST_P(ASTImporterOptionSpecificTestBase,
1639 TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) {
1640 Decl *From, *To;
1641 std::tie(From, To) = getImportedDecl(
1643 namespace NS {
1644 template<class T>
1645 class X {};
1646 template class X<int>;
1649 Lang_CXX03, "", Lang_CXX03, "NS");
1651 // Check that the ClassTemplateSpecializationDecl is NOT the child of the
1652 // ClassTemplateDecl.
1653 auto Pattern = namespaceDecl(has(classTemplateDecl(
1654 hasName("X"), unless(has(classTemplateSpecializationDecl())))));
1655 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1656 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1658 // Check that the ClassTemplateSpecializationDecl is the child of the
1659 // NamespaceDecl.
1660 Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X"))));
1661 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1662 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1665 TEST_P(ASTImporterOptionSpecificTestBase,
1666 CXXRecordDeclFieldsShouldBeInCorrectOrder) {
1667 Decl *From, *To;
1668 std::tie(From, To) =
1669 getImportedDecl(
1670 "struct declToImport { int a; int b; };",
1671 Lang_CXX11, "", Lang_CXX11);
1673 MatchVerifier<Decl> Verifier;
1674 ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1675 EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1678 TEST_P(ASTImporterOptionSpecificTestBase,
1679 CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) {
1680 Decl *From, *To;
1681 std::tie(From, To) = getImportedDecl(
1682 // The original recursive algorithm of ASTImporter first imports 'c' then
1683 // 'b' and lastly 'a'. Therefore we must restore the order somehow.
1684 R"s(
1685 struct declToImport {
1686 int a = c + b;
1687 int b = 1;
1688 int c = 2;
1690 )s",
1691 Lang_CXX11, "", Lang_CXX11);
1693 MatchVerifier<Decl> Verifier;
1694 ASSERT_TRUE(
1695 Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1696 EXPECT_TRUE(
1697 Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1700 TEST_P(ASTImporterOptionSpecificTestBase,
1701 CXXRecordDeclFieldAndIndirectFieldOrder) {
1702 Decl *From, *To;
1703 std::tie(From, To) = getImportedDecl(
1704 // First field is "a", then the field for unnamed union, then "b" and "c"
1705 // from it (indirect fields), then "d".
1706 R"s(
1707 struct declToImport {
1708 int a = d;
1709 union {
1710 int b;
1711 int c;
1713 int d;
1715 )s",
1716 Lang_CXX11, "", Lang_CXX11);
1718 MatchVerifier<Decl> Verifier;
1719 ASSERT_TRUE(Verifier.match(
1720 From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1721 EXPECT_TRUE(Verifier.match(
1722 To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1725 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) {
1726 Decl *From, *To;
1727 std::tie(From, To) = getImportedDecl(
1729 struct declToImport {
1732 Lang_CXX03, "", Lang_CXX03);
1734 MatchVerifier<Decl> Verifier;
1735 // Match the implicit Decl.
1736 auto Matcher = cxxRecordDecl(has(cxxRecordDecl()));
1737 ASSERT_TRUE(Verifier.match(From, Matcher));
1738 EXPECT_TRUE(Verifier.match(To, Matcher));
1741 TEST_P(ASTImporterOptionSpecificTestBase,
1742 ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
1743 Decl *From, *To;
1744 std::tie(From, To) = getImportedDecl(
1746 template <typename U>
1747 struct declToImport {
1750 Lang_CXX03, "", Lang_CXX03);
1752 MatchVerifier<Decl> Verifier;
1753 // Match the implicit Decl.
1754 auto Matcher = classTemplateDecl(has(cxxRecordDecl(has(cxxRecordDecl()))));
1755 ASSERT_TRUE(Verifier.match(From, Matcher));
1756 EXPECT_TRUE(Verifier.match(To, Matcher));
1759 TEST_P(ASTImporterOptionSpecificTestBase,
1760 ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
1761 Decl *From, *To;
1762 std::tie(From, To) = getImportedDecl(
1764 template<class T>
1765 class Base {};
1766 class declToImport : public Base<declToImport> {};
1768 Lang_CXX03, "", Lang_CXX03);
1770 auto hasImplicitClass = has(cxxRecordDecl());
1771 auto Pattern = translationUnitDecl(has(classTemplateDecl(
1772 hasName("Base"),
1773 has(classTemplateSpecializationDecl(hasImplicitClass)))));
1774 ASSERT_TRUE(
1775 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1776 EXPECT_TRUE(
1777 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1780 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) {
1781 Decl *From, *To;
1782 std::tie(From, To) =
1783 getImportedDecl("void declToImport() {}", Lang_CXX03, "", Lang_CXX03);
1785 MatchVerifier<Decl> Verifier;
1786 auto Matcher = functionDecl();
1787 ASSERT_TRUE(Verifier.match(From, Matcher));
1788 EXPECT_TRUE(Verifier.match(To, Matcher));
1789 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1792 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) {
1793 Decl *FromTU = getTuDecl(
1795 struct X {};
1796 void operator<<(int, X);
1798 Lang_CXX03);
1799 Decl *From = LastDeclMatcher<Decl>{}.match(FromTU, functionDecl());
1800 const Decl *To = Import(From, Lang_CXX03);
1801 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1804 TEST_P(ASTImporterOptionSpecificTestBase,
1805 ShouldImportMembersOfClassTemplateSpecializationDecl) {
1806 Decl *From, *To;
1807 std::tie(From, To) = getImportedDecl(
1809 template<class T>
1810 class Base { int a; };
1811 class declToImport : Base<declToImport> {};
1813 Lang_CXX03, "", Lang_CXX03);
1815 auto Pattern = translationUnitDecl(has(classTemplateDecl(
1816 hasName("Base"),
1817 has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a"))))))));
1818 ASSERT_TRUE(
1819 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1820 EXPECT_TRUE(
1821 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1824 TEST_P(ASTImporterOptionSpecificTestBase,
1825 ImportDefinitionOfClassTemplateAfterFwdDecl) {
1827 Decl *FromTU = getTuDecl(
1829 template <typename T>
1830 struct B;
1832 Lang_CXX03, "input0.cc");
1833 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1834 FromTU, classTemplateDecl(hasName("B")));
1836 Import(FromD, Lang_CXX03);
1840 Decl *FromTU = getTuDecl(
1842 template <typename T>
1843 struct B {
1844 void f();
1847 Lang_CXX03, "input1.cc");
1848 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
1849 FromTU, functionDecl(hasName("f")));
1850 Import(FromD, Lang_CXX03);
1851 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
1852 FromTU, classTemplateDecl(hasName("B")));
1853 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
1854 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
1858 TEST_P(ASTImporterOptionSpecificTestBase,
1859 ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) {
1860 Decl *ToTU = getToTuDecl(
1862 template <typename T>
1863 struct B {
1864 void f();
1867 template <typename T>
1868 struct B;
1870 Lang_CXX03);
1871 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1872 [](const ClassTemplateDecl *T) {
1873 return T->isThisDeclarationADefinition();
1875 .match(ToTU, classTemplateDecl()));
1877 Decl *FromTU = getTuDecl(
1879 template <typename T>
1880 struct B {
1881 void f();
1884 Lang_CXX03, "input1.cc");
1885 ClassTemplateDecl *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1886 FromTU, classTemplateDecl(hasName("B")));
1888 Import(FromD, Lang_CXX03);
1890 // We should have only one definition.
1891 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1892 [](const ClassTemplateDecl *T) {
1893 return T->isThisDeclarationADefinition();
1895 .match(ToTU, classTemplateDecl()));
1898 TEST_P(ASTImporterOptionSpecificTestBase,
1899 ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) {
1900 Decl *ToTU = getToTuDecl(
1902 struct B {
1903 void f();
1906 struct B;
1908 Lang_CXX03);
1909 ASSERT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1910 ToTU, cxxRecordDecl(unless(isImplicit()))));
1912 Decl *FromTU = getTuDecl(
1914 struct B {
1915 void f();
1918 Lang_CXX03, "input1.cc");
1919 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
1920 FromTU, cxxRecordDecl(hasName("B")));
1922 Import(FromD, Lang_CXX03);
1924 EXPECT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1925 ToTU, cxxRecordDecl(unless(isImplicit()))));
1928 static void CompareSourceLocs(FullSourceLoc Loc1, FullSourceLoc Loc2) {
1929 EXPECT_EQ(Loc1.getExpansionLineNumber(), Loc2.getExpansionLineNumber());
1930 EXPECT_EQ(Loc1.getExpansionColumnNumber(), Loc2.getExpansionColumnNumber());
1931 EXPECT_EQ(Loc1.getSpellingLineNumber(), Loc2.getSpellingLineNumber());
1932 EXPECT_EQ(Loc1.getSpellingColumnNumber(), Loc2.getSpellingColumnNumber());
1934 static void CompareSourceRanges(SourceRange Range1, SourceRange Range2,
1935 SourceManager &SM1, SourceManager &SM2) {
1936 CompareSourceLocs(FullSourceLoc{ Range1.getBegin(), SM1 },
1937 FullSourceLoc{ Range2.getBegin(), SM2 });
1938 CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 },
1939 FullSourceLoc{ Range2.getEnd(), SM2 });
1941 TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) {
1942 Decl *FromTU = getTuDecl(
1944 #define MFOO(arg) arg = arg + 1
1946 void foo() {
1947 int a = 5;
1948 MFOO(a);
1951 Lang_CXX03);
1952 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1953 auto ToD = Import(FromD, Lang_CXX03);
1955 auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr());
1956 auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr());
1957 auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral());
1958 auto FromRHS =
1959 LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral());
1961 SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1962 SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1963 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1964 FromSM);
1965 CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM,
1966 FromSM);
1967 CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM,
1968 FromSM);
1971 TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) {
1972 Decl *FromTU = getTuDecl(
1974 #define FUNC_INT void declToImport
1975 #define FUNC FUNC_INT
1976 FUNC(int a);
1978 Lang_CXX03);
1979 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1980 auto ToD = Import(FromD, Lang_CXX03);
1982 SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1983 SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1984 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1985 FromSM);
1988 TEST_P(
1989 ASTImporterOptionSpecificTestBase,
1990 ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) {
1991 Decl *ToTU = getToTuDecl(
1993 template <typename T>
1994 struct B;
1996 template <>
1997 struct B<int> {};
1999 template <>
2000 struct B<int>;
2002 Lang_CXX03);
2003 // We should have only one definition.
2004 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
2005 [](const ClassTemplateSpecializationDecl *T) {
2006 return T->isThisDeclarationADefinition();
2008 .match(ToTU, classTemplateSpecializationDecl()));
2010 Decl *FromTU = getTuDecl(
2012 template <typename T>
2013 struct B;
2015 template <>
2016 struct B<int> {};
2018 Lang_CXX03, "input1.cc");
2019 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
2020 FromTU, classTemplateSpecializationDecl(hasName("B")));
2022 Import(FromD, Lang_CXX03);
2024 // We should have only one definition.
2025 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
2026 [](const ClassTemplateSpecializationDecl *T) {
2027 return T->isThisDeclarationADefinition();
2029 .match(ToTU, classTemplateSpecializationDecl()));
2032 TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) {
2033 Decl *FromTU = getTuDecl(
2035 struct { int a; int b; } object0 = { 2, 3 };
2036 struct { int x; int y; int z; } object1;
2038 Lang_CXX03, "input0.cc");
2040 auto *Obj0 =
2041 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object0")));
2042 auto *From0 = getRecordDecl(Obj0);
2043 auto *Obj1 =
2044 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object1")));
2045 auto *From1 = getRecordDecl(Obj1);
2047 auto *To0 = Import(From0, Lang_CXX03);
2048 auto *To1 = Import(From1, Lang_CXX03);
2050 EXPECT_TRUE(To0);
2051 EXPECT_TRUE(To1);
2052 EXPECT_NE(To0, To1);
2053 EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl());
2056 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) {
2057 auto *Code =
2059 struct X {
2060 struct { int a; };
2061 struct { int b; };
2064 Decl *FromTU0 = getTuDecl(Code, Lang_C99, "input0.c");
2066 Decl *FromTU1 = getTuDecl(Code, Lang_C99, "input1.c");
2068 auto *X0 =
2069 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
2070 auto *X1 =
2071 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
2072 Import(X0, Lang_C99);
2073 Import(X1, Lang_C99);
2075 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2076 // We expect no (ODR) warning during the import.
2077 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
2078 EXPECT_EQ(1u,
2079 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
2082 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) {
2083 Decl *FromTU0 = getTuDecl(
2085 struct X {
2086 struct { int a; };
2087 struct { int b; };
2090 Lang_C99, "input0.c");
2092 Decl *FromTU1 = getTuDecl(
2094 struct X { // reversed order
2095 struct { int b; };
2096 struct { int a; };
2099 Lang_C99, "input1.c");
2101 auto *X0 =
2102 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
2103 auto *X1 =
2104 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
2105 Import(X0, Lang_C99);
2106 Import(X1, Lang_C99);
2108 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2109 // We expect one (ODR) warning during the import.
2110 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
2111 EXPECT_EQ(1u,
2112 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
2115 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) {
2116 auto Pattern = varDecl(hasName("x"));
2117 VarDecl *Imported1;
2119 Decl *FromTU = getTuDecl("extern int x;", Lang_CXX03, "input0.cc");
2120 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2121 Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2123 VarDecl *Imported2;
2125 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input1.cc");
2126 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2127 Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2129 EXPECT_EQ(Imported1->getCanonicalDecl(), Imported2->getCanonicalDecl());
2130 EXPECT_FALSE(Imported2->isUsed(false));
2132 Decl *FromTU = getTuDecl("extern int x; int f() { return x; }", Lang_CXX03,
2133 "input2.cc");
2134 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2135 FromTU, functionDecl(hasName("f")));
2136 Import(FromD, Lang_CXX03);
2138 EXPECT_TRUE(Imported2->isUsed(false));
2141 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) {
2142 auto Pattern = varDecl(hasName("x"));
2143 VarDecl *ExistingD;
2145 Decl *ToTU = getToTuDecl("int x = 1;", Lang_CXX03);
2146 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
2148 EXPECT_FALSE(ExistingD->isUsed(false));
2150 Decl *FromTU =
2151 getTuDecl("int x = 1; int f() { return x; }", Lang_CXX03, "input1.cc");
2152 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2153 FromTU, functionDecl(hasName("f")));
2154 Import(FromD, Lang_CXX03);
2156 EXPECT_TRUE(ExistingD->isUsed(false));
2159 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) {
2160 auto Pattern = varDecl(hasName("a"));
2161 VarDecl *ExistingD;
2163 Decl *ToTU = getToTuDecl(
2165 struct A {
2166 static const int a = 1;
2169 Lang_CXX03);
2170 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
2172 EXPECT_FALSE(ExistingD->isUsed(false));
2174 Decl *FromTU = getTuDecl(
2176 struct A {
2177 static const int a = 1;
2179 const int *f() { return &A::a; } // requires storage,
2180 // thus used flag will be set
2182 Lang_CXX03, "input1.cc");
2183 auto *FromFunD = FirstDeclMatcher<FunctionDecl>().match(
2184 FromTU, functionDecl(hasName("f")));
2185 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2186 ASSERT_TRUE(FromD->isUsed(false));
2187 Import(FromFunD, Lang_CXX03);
2189 EXPECT_TRUE(ExistingD->isUsed(false));
2192 TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) {
2193 auto Pattern = varDecl(hasName("x"));
2195 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input0.cc");
2196 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2198 auto *Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2200 ASSERT_FALSE(Imported1->isUsed(false));
2202 FromD->setIsUsed();
2203 auto *Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2205 EXPECT_EQ(Imported1, Imported2);
2206 EXPECT_TRUE(Imported2->isUsed(false));
2209 struct ImportFunctions : ASTImporterOptionSpecificTestBase {};
2211 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
2212 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
2213 auto Pattern = functionDecl(hasName("f"));
2214 auto *From =
2215 FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto
2217 Decl *ImportedD = Import(From, Lang_CXX03);
2218 Decl *ToTU = ImportedD->getTranslationUnitDecl();
2220 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2221 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2222 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2223 EXPECT_TRUE(ImportedD == To0);
2224 EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
2225 EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
2226 EXPECT_EQ(To1->getPreviousDecl(), To0);
2229 TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) {
2230 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
2231 auto Pattern = functionDecl(hasName("f"));
2232 auto *From =
2233 LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def
2235 Decl *ImportedD = Import(From, Lang_CXX03);
2236 Decl *ToTU = ImportedD->getTranslationUnitDecl();
2238 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2239 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2240 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2241 EXPECT_TRUE(ImportedD == To1);
2242 EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
2243 EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
2244 EXPECT_EQ(To1->getPreviousDecl(), To0);
2247 TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) {
2248 auto Code =
2250 struct B { virtual void f(); };
2251 void B::f() {}
2252 struct D : B { void f(); };
2254 auto Pattern =
2255 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2256 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2257 CXXMethodDecl *Proto =
2258 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2260 ASSERT_EQ(Proto->size_overridden_methods(), 1u);
2261 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
2262 EXPECT_EQ(To->size_overridden_methods(), 1u);
2265 TEST_P(ImportFunctions, VirtualFlagShouldBePreservedWhenImportingPrototype) {
2266 auto Code =
2268 struct B { virtual void f(); };
2269 void B::f() {}
2271 auto Pattern =
2272 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2273 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2274 CXXMethodDecl *Proto =
2275 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2276 CXXMethodDecl *Def = LastDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2278 ASSERT_TRUE(Proto->isVirtual());
2279 ASSERT_TRUE(Def->isVirtual());
2280 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
2281 EXPECT_TRUE(To->isVirtual());
2284 TEST_P(ImportFunctions,
2285 ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) {
2286 Decl *ToTU = getToTuDecl(
2288 void f() {}
2289 void f();
2291 Lang_CXX03);
2292 ASSERT_EQ(1u,
2293 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
2294 return FD->doesThisDeclarationHaveABody();
2295 }).match(ToTU, functionDecl()));
2297 Decl *FromTU = getTuDecl("void f() {}", Lang_CXX03, "input0.cc");
2298 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
2300 Import(FromD, Lang_CXX03);
2302 EXPECT_EQ(1u,
2303 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
2304 return FD->doesThisDeclarationHaveABody();
2305 }).match(ToTU, functionDecl()));
2308 TEST_P(ImportFunctions, ImportOverriddenMethodTwice) {
2309 auto Code =
2311 struct B { virtual void f(); };
2312 struct D:B { void f(); };
2314 auto BFP =
2315 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2316 auto DFP =
2317 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2319 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
2320 auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2321 Import(DF, Lang_CXX03);
2323 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2324 auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
2325 Import(BF, Lang_CXX03);
2327 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2329 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2330 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2333 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) {
2334 auto CodeWithoutDef =
2336 struct B { virtual void f(); };
2337 struct D:B { void f(); };
2339 auto CodeWithDef =
2341 struct B { virtual void f(){}; };
2342 struct D:B { void f(){}; };
2344 auto BFP =
2345 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2346 auto DFP =
2347 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2348 auto BFDefP = cxxMethodDecl(
2349 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2350 auto DFDefP = cxxMethodDecl(
2351 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
2352 auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition());
2355 Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX03, "input0.cc");
2356 auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP);
2357 Import(FromD, Lang_CXX03);
2360 Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX03, "input1.cc");
2361 auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP);
2362 Import(FromB, Lang_CXX03);
2365 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2367 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2368 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2369 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u);
2370 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u);
2371 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u);
2374 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) {
2375 auto Code =
2377 struct B { virtual void f(); };
2378 struct D:B { void f(); };
2379 void B::f(){};
2382 auto BFP =
2383 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2384 auto BFDefP = cxxMethodDecl(
2385 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2386 auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))),
2387 unless(isDefinition()));
2389 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
2390 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2391 Import(D, Lang_CXX03);
2393 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2394 auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
2395 Import(B, Lang_CXX03);
2397 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2399 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2400 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2402 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2403 ToTU, cxxRecordDecl(hasName("B")));
2404 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2405 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2406 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2408 // The definition should be out-of-class.
2409 EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2410 EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2411 ToBFOutOfClass->getLexicalDeclContext());
2412 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2413 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2415 // Check that the redecl chain is intact.
2416 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2419 TEST_P(ImportFunctions,
2420 ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) {
2421 auto CodeTU0 =
2423 struct B { virtual void f(); };
2424 struct D:B { void f(); };
2426 auto CodeTU1 =
2428 struct B { virtual void f(); };
2429 struct D:B { void f(); };
2430 void B::f(){}
2431 void D::f(){}
2432 void foo(B &b, D &d) { b.f(); d.f(); }
2435 auto BFP =
2436 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2437 auto BFDefP = cxxMethodDecl(
2438 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2439 auto DFP =
2440 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2441 auto DFDefP = cxxMethodDecl(
2442 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
2443 auto FooDef = functionDecl(hasName("foo"));
2446 Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX03, "input0.cc");
2447 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2448 Import(D, Lang_CXX03);
2452 Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX03, "input1.cc");
2453 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef);
2454 Import(Foo, Lang_CXX03);
2457 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2459 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2460 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2461 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2462 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u);
2464 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2465 ToTU, cxxRecordDecl(hasName("B")));
2466 auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match(
2467 ToTU, cxxRecordDecl(hasName("D")));
2468 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2469 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2470 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2471 auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP);
2472 auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match(
2473 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2475 // The definition should be out-of-class.
2476 EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2477 EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2478 ToBFOutOfClass->getLexicalDeclContext());
2479 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2480 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2482 EXPECT_NE(ToDFInClass, ToDFOutOfClass);
2483 EXPECT_NE(ToDFInClass->getLexicalDeclContext(),
2484 ToDFOutOfClass->getLexicalDeclContext());
2485 EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD);
2486 EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU);
2488 // Check that the redecl chain is intact.
2489 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2490 EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass);
2493 TEST_P(ASTImporterOptionSpecificTestBase,
2494 ImportVirtualOverriddenMethodOnALoop) {
2495 // B::f() calls => f1() ==> C ==> C::f()
2496 // \
2497 // \---- A::f()
2499 // C::f()'s ImportOverriddenMethods() asserts B::isVirtual(), so B::f()'s
2500 // ImportOverriddenMethods() should be completed before B::f()'s body
2501 const char *Code =
2503 void f1();
2504 class A {
2505 virtual void f(){}
2507 class B: public A {
2508 void f() override {
2509 f1();
2512 class C: public B {
2513 void f() override {}
2515 void f1() { C c; }
2517 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
2519 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
2520 FromTU, cxxMethodDecl(hasName("B::f")));
2522 auto *ToBF = Import(FromF, Lang_CXX11);
2523 EXPECT_TRUE(ToBF->isVirtual());
2525 auto *ToCF = FirstDeclMatcher<CXXMethodDecl>().match(
2526 ToBF->getTranslationUnitDecl(), cxxMethodDecl(hasName("C::f")));
2527 EXPECT_TRUE(ToCF->isVirtual());
2530 TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) {
2531 std::string Code = "static int v; static int v = 0;";
2532 auto Pattern = varDecl(hasName("v"));
2534 TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C99, "input0.c");
2536 auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern);
2537 auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern);
2539 auto *To0 = Import(From0, Lang_C99);
2540 auto *To1 = Import(From1, Lang_C99);
2542 EXPECT_TRUE(To0);
2543 ASSERT_TRUE(To1);
2544 EXPECT_NE(To0, To1);
2545 EXPECT_EQ(To1->getPreviousDecl(), To0);
2548 TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) {
2549 TranslationUnitDecl *FromTu =
2550 getTuDecl("namespace NS0 { namespace { void f(); } }"
2551 "namespace NS1 { namespace { void f(); } }",
2552 Lang_CXX03, "input0.cc");
2553 auto Pattern = functionDecl(hasName("f"));
2555 auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2556 auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2558 auto *ToF0 = Import(FromF0, Lang_CXX03);
2559 auto *ToF1 = Import(FromF1, Lang_CXX03);
2561 EXPECT_TRUE(ToF0);
2562 ASSERT_TRUE(ToF1);
2563 EXPECT_NE(ToF0, ToF1);
2564 EXPECT_FALSE(ToF1->getPreviousDecl());
2567 TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) {
2569 Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }",
2570 Lang_CXX03, "input0.cc");
2571 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2572 FromTU, functionDecl(hasName("g0")));
2574 Import(FromD, Lang_CXX03);
2577 Decl *FromTU =
2578 getTuDecl("namespace { void f() { int a; } } void g1() { f(); }",
2579 Lang_CXX03, "input1.cc");
2580 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2581 FromTU, functionDecl(hasName("g1")));
2582 Import(FromD, Lang_CXX03);
2585 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2586 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
2587 2u);
2590 TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) {
2591 Decl *FromTU = getTuDecl(
2593 void foo() {
2594 (void)[]() { ; };
2597 Lang_CXX11);
2598 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2599 FromTU, functionDecl(hasName("foo")));
2600 auto *ToD = Import(FromD, Lang_CXX03);
2601 EXPECT_TRUE(ToD);
2602 CXXRecordDecl *LambdaRec =
2603 cast<LambdaExpr>(cast<CStyleCastExpr>(
2604 *cast<CompoundStmt>(ToD->getBody())->body_begin())
2605 ->getSubExpr())
2606 ->getLambdaClass();
2607 EXPECT_TRUE(LambdaRec->getDestructor());
2610 TEST_P(ImportFunctions,
2611 CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2612 Decl *FromTU = getTuDecl(
2614 struct X {
2615 template <typename T>
2616 void foo(){}
2618 void f() {
2619 X x;
2620 x.foo<int>();
2623 Lang_CXX03);
2624 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2625 FromTU, functionDecl(hasName("f")));
2626 auto *ToD = Import(FromD, Lang_CXX03);
2627 EXPECT_TRUE(ToD);
2628 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
2629 ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr()))));
2632 TEST_P(ImportFunctions,
2633 DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2634 Decl *FromTU = getTuDecl(
2636 struct X {
2637 template <typename T>
2638 void foo(){}
2640 template <typename T>
2641 void f() {
2642 X x;
2643 x.foo<T>();
2645 void g() {
2646 f<int>();
2649 Lang_CXX03);
2650 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2651 FromTU, functionDecl(hasName("g")));
2652 auto *ToD = Import(FromD, Lang_CXX03);
2653 EXPECT_TRUE(ToD);
2654 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2655 EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match(
2656 ToTU, translationUnitDecl(hasDescendant(
2657 functionDecl(hasName("f"), hasDescendant(declRefExpr()))))));
2660 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {};
2662 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) {
2663 auto Code =
2665 class X {
2666 template <class T>
2667 void f(T t);
2670 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2671 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2672 FromTU1, functionTemplateDecl(hasName("f")));
2673 auto *ToD1 = Import(FromD1, Lang_CXX03);
2674 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2675 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2676 FromTU2, functionTemplateDecl(hasName("f")));
2677 auto *ToD2 = Import(FromD2, Lang_CXX03);
2678 EXPECT_EQ(ToD1, ToD2);
2681 TEST_P(ImportFunctionTemplates,
2682 ImportFunctionTemplateWithDefInRecordDeclTwice) {
2683 auto Code =
2685 class X {
2686 template <class T>
2687 void f(T t);
2689 template <class T>
2690 void X::f(T t) {};
2692 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2693 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2694 FromTU1, functionTemplateDecl(hasName("f")));
2695 auto *ToD1 = Import(FromD1, Lang_CXX03);
2696 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2697 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2698 FromTU2, functionTemplateDecl(hasName("f")));
2699 auto *ToD2 = Import(FromD2, Lang_CXX03);
2700 EXPECT_EQ(ToD1, ToD2);
2703 TEST_P(ImportFunctionTemplates,
2704 ImportFunctionWhenThereIsAFunTemplateWithSameName) {
2705 getToTuDecl(
2707 template <typename T>
2708 void foo(T) {}
2709 void foo();
2711 Lang_CXX03);
2712 Decl *FromTU = getTuDecl("void foo();", Lang_CXX03);
2713 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2714 FromTU, functionDecl(hasName("foo")));
2715 auto *ImportedD = Import(FromD, Lang_CXX03);
2716 EXPECT_TRUE(ImportedD);
2719 TEST_P(ImportFunctionTemplates,
2720 ImportConstructorWhenThereIsAFunTemplateWithSameName) {
2721 auto Code =
2723 struct Foo {
2724 template <typename T>
2725 Foo(T) {}
2726 Foo();
2729 getToTuDecl(Code, Lang_CXX03);
2730 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2731 auto *FromD =
2732 LastDeclMatcher<CXXConstructorDecl>().match(FromTU, cxxConstructorDecl());
2733 auto *ImportedD = Import(FromD, Lang_CXX03);
2734 EXPECT_TRUE(ImportedD);
2737 TEST_P(ImportFunctionTemplates,
2738 ImportOperatorWhenThereIsAFunTemplateWithSameName) {
2739 getToTuDecl(
2741 template <typename T>
2742 void operator<(T,T) {}
2743 struct X{};
2744 void operator<(X, X);
2746 Lang_CXX03);
2747 Decl *FromTU = getTuDecl(
2749 struct X{};
2750 void operator<(X, X);
2752 Lang_CXX03);
2753 auto *FromD = LastDeclMatcher<FunctionDecl>().match(
2754 FromTU, functionDecl(hasOverloadedOperatorName("<")));
2755 auto *ImportedD = Import(FromD, Lang_CXX03);
2756 EXPECT_TRUE(ImportedD);
2759 struct ImportFriendFunctions : ImportFunctions {};
2761 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {
2762 auto Pattern = functionDecl(hasName("f"));
2764 Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2765 "void f();",
2766 Lang_CXX03, "input0.cc");
2767 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2769 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2770 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2771 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2772 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2773 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2774 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2775 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2778 TEST_P(ImportFriendFunctions,
2779 ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) {
2780 auto Pattern = functionDecl(hasName("f"));
2782 Decl *FromTU = getTuDecl("void f();"
2783 "struct X { friend void f(); };",
2784 Lang_CXX03, "input0.cc");
2785 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2787 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2788 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2789 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2790 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2791 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2792 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2793 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2796 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) {
2797 auto Pattern = functionDecl(hasName("f"));
2799 Decl *FromTU = getTuDecl("struct X { friend void f(){} };"
2800 "void f();",
2801 Lang_CXX03, "input0.cc");
2802 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2804 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2805 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2806 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2807 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2808 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2809 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2810 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2813 TEST_P(ImportFriendFunctions,
2814 ImportFriendFunctionRedeclChainDef_OutOfClassDef) {
2815 auto Pattern = functionDecl(hasName("f"));
2817 Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2818 "void f(){}",
2819 Lang_CXX03, "input0.cc");
2820 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2822 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2823 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2824 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2825 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2826 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2827 EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody());
2828 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2831 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) {
2832 auto Pattern = functionDecl(hasName("f"));
2834 Decl *FromTU = getTuDecl(
2836 class X;
2837 void f(X *x){}
2838 class X{
2839 friend void f(X *x);
2842 Lang_CXX03, "input0.cc");
2843 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2845 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2846 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2847 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2848 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2849 auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>()
2850 .match(ToTU, friendDecl())
2851 ->getFriendDecl());
2852 EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody());
2853 EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD);
2854 // The parameters must refer the same type
2855 EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(),
2856 (*ImportedD->param_begin())->getOriginalType());
2859 TEST_P(ImportFriendFunctions,
2860 ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) {
2861 auto Pattern = functionDecl(hasName("f"));
2863 Decl *FromTU = getTuDecl(
2865 class X;
2866 void f(X *x){}
2867 class X{
2868 friend void f(X *x);
2871 Lang_CXX03, "input0.cc");
2872 auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2874 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2875 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2876 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2877 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2878 auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match(
2879 ToTU, functionDecl(unless(hasParent(friendDecl()))));
2881 EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody());
2882 EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD);
2883 // The parameters must refer the same type
2884 EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(),
2885 (*ImportedD->param_begin())->getOriginalType());
2888 TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) {
2889 auto Pattern = functionDecl(hasName("f"));
2891 FunctionDecl *ImportedD;
2893 Decl *FromTU =
2894 getTuDecl("struct X { friend void f(){} };", Lang_CXX03, "input0.cc");
2895 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2896 ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2898 FunctionDecl *ImportedD1;
2900 Decl *FromTU = getTuDecl("void f();", Lang_CXX03, "input1.cc");
2901 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2902 ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2905 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2906 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2907 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2908 EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody());
2909 EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD);
2912 TEST_P(ImportFriendFunctions, Lookup) {
2913 auto FunctionPattern = functionDecl(hasName("f"));
2914 auto ClassPattern = cxxRecordDecl(hasName("X"));
2916 TranslationUnitDecl *FromTU =
2917 getTuDecl("struct X { friend void f(); };", Lang_CXX03, "input0.cc");
2918 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2919 ASSERT_TRUE(FromD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2920 ASSERT_FALSE(FromD->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2922 auto FromName = FromD->getDeclName();
2923 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2924 auto LookupRes = Class->noload_lookup(FromName);
2925 ASSERT_TRUE(LookupRes.empty());
2926 LookupRes = FromTU->noload_lookup(FromName);
2927 ASSERT_TRUE(LookupRes.isSingleResult());
2930 auto *ToD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2931 auto ToName = ToD->getDeclName();
2933 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2934 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2935 auto LookupRes = Class->noload_lookup(ToName);
2936 EXPECT_TRUE(LookupRes.empty());
2937 LookupRes = ToTU->noload_lookup(ToName);
2938 EXPECT_TRUE(LookupRes.isSingleResult());
2940 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 1u);
2941 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2942 EXPECT_TRUE(To0->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2943 EXPECT_FALSE(To0->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2946 TEST_P(ImportFriendFunctions, LookupWithProtoAfter) {
2947 auto FunctionPattern = functionDecl(hasName("f"));
2948 auto ClassPattern = cxxRecordDecl(hasName("X"));
2950 TranslationUnitDecl *FromTU =
2951 getTuDecl("struct X { friend void f(); };"
2952 // This proto decl makes f available to normal
2953 // lookup, otherwise it is hidden.
2954 // Normal C++ lookup (implemented in
2955 // `clang::Sema::CppLookupName()` and in `LookupDirect()`)
2956 // returns the found `NamedDecl` only if the set IDNS is matched
2957 "void f();",
2958 Lang_CXX03, "input0.cc");
2959 auto *FromFriend =
2960 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2961 auto *FromNormal =
2962 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2963 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2964 ASSERT_FALSE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2965 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2966 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2968 auto FromName = FromFriend->getDeclName();
2969 auto *FromClass =
2970 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2971 auto LookupRes = FromClass->noload_lookup(FromName);
2972 ASSERT_TRUE(LookupRes.empty());
2973 LookupRes = FromTU->noload_lookup(FromName);
2974 ASSERT_TRUE(LookupRes.isSingleResult());
2976 auto *ToFriend = cast<FunctionDecl>(Import(FromFriend, Lang_CXX03));
2977 auto ToName = ToFriend->getDeclName();
2979 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2980 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2981 LookupRes = ToClass->noload_lookup(ToName);
2982 EXPECT_TRUE(LookupRes.empty());
2983 LookupRes = ToTU->noload_lookup(ToName);
2984 // Test is disabled because this result is 2.
2985 EXPECT_TRUE(LookupRes.isSingleResult());
2987 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
2988 ToFriend = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2989 auto *ToNormal = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2990 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2991 EXPECT_FALSE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2992 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2993 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2996 TEST_P(ImportFriendFunctions, LookupWithProtoBefore) {
2997 auto FunctionPattern = functionDecl(hasName("f"));
2998 auto ClassPattern = cxxRecordDecl(hasName("X"));
3000 TranslationUnitDecl *FromTU = getTuDecl("void f();"
3001 "struct X { friend void f(); };",
3002 Lang_CXX03, "input0.cc");
3003 auto *FromNormal =
3004 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
3005 auto *FromFriend =
3006 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
3007 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3008 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3009 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3010 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3012 auto FromName = FromNormal->getDeclName();
3013 auto *FromClass =
3014 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
3015 auto LookupRes = FromClass->noload_lookup(FromName);
3016 ASSERT_TRUE(LookupRes.empty());
3017 LookupRes = FromTU->noload_lookup(FromName);
3018 ASSERT_TRUE(LookupRes.isSingleResult());
3020 auto *ToNormal = cast<FunctionDecl>(Import(FromNormal, Lang_CXX03));
3021 auto ToName = ToNormal->getDeclName();
3022 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3024 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
3025 LookupRes = ToClass->noload_lookup(ToName);
3026 EXPECT_TRUE(LookupRes.empty());
3027 LookupRes = ToTU->noload_lookup(ToName);
3028 EXPECT_TRUE(LookupRes.isSingleResult());
3030 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
3031 ToNormal = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
3032 auto *ToFriend = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
3033 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3034 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3035 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3036 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3039 TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) {
3040 auto Pattern = functionDecl(hasName("f"));
3042 TranslationUnitDecl *FromNormalTU =
3043 getTuDecl("void f();", Lang_CXX03, "input0.cc");
3044 auto *FromNormalF =
3045 FirstDeclMatcher<FunctionDecl>().match(FromNormalTU, Pattern);
3046 TranslationUnitDecl *FromFriendTU =
3047 getTuDecl("class X { friend void f(); };", Lang_CXX03, "input1.cc");
3048 auto *FromFriendF =
3049 FirstDeclMatcher<FunctionDecl>().match(FromFriendTU, Pattern);
3050 auto FromNormalName = FromNormalF->getDeclName();
3051 auto FromFriendName = FromFriendF->getDeclName();
3053 ASSERT_TRUE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3054 ASSERT_FALSE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3055 ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3056 ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3057 auto LookupRes = FromNormalTU->noload_lookup(FromNormalName);
3058 ASSERT_TRUE(LookupRes.isSingleResult());
3059 LookupRes = FromFriendTU->noload_lookup(FromFriendName);
3060 ASSERT_TRUE(LookupRes.isSingleResult());
3062 auto *ToNormalF = cast<FunctionDecl>(Import(FromNormalF, Lang_CXX03));
3063 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3064 auto ToName = ToNormalF->getDeclName();
3065 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3066 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3067 LookupRes = ToTU->noload_lookup(ToName);
3068 EXPECT_TRUE(LookupRes.isSingleResult());
3069 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
3071 auto *ToFriendF = cast<FunctionDecl>(Import(FromFriendF, Lang_CXX03));
3072 LookupRes = ToTU->noload_lookup(ToName);
3073 EXPECT_TRUE(LookupRes.isSingleResult());
3074 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
3076 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3077 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3079 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
3080 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
3083 TEST_P(ImportFriendFunctions, ImportFriendList) {
3084 TranslationUnitDecl *FromTU = getTuDecl("struct X { friend void f(); };"
3085 "void f();",
3086 Lang_CXX03, "input0.cc");
3087 auto *FromFriendF = FirstDeclMatcher<FunctionDecl>().match(
3088 FromTU, functionDecl(hasName("f")));
3090 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
3091 FromTU, cxxRecordDecl(hasName("X")));
3092 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl());
3093 auto FromFriends = FromClass->friends();
3094 unsigned int FrN = 0;
3095 for (auto Fr : FromFriends) {
3096 ASSERT_EQ(Fr, FromFriend);
3097 ++FrN;
3099 ASSERT_EQ(FrN, 1u);
3101 Import(FromFriendF, Lang_CXX03);
3102 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3103 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
3104 ToTU, cxxRecordDecl(hasName("X")));
3105 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
3106 auto ToFriends = ToClass->friends();
3107 FrN = 0;
3108 for (auto Fr : ToFriends) {
3109 EXPECT_EQ(Fr, ToFriend);
3110 ++FrN;
3112 EXPECT_EQ(FrN, 1u);
3115 AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>,
3116 InnerMatcher) {
3117 if (auto *Typedef = Node.getTypedefNameForAnonDecl())
3118 return InnerMatcher.matches(*Typedef, Finder, Builder);
3119 return false;
3122 TEST_P(ImportDecl, ImportEnumSequential) {
3123 CodeFiles Samples{{"main.c",
3124 {"void foo();"
3125 "void moo();"
3126 "int main() { foo(); moo(); }",
3127 Lang_C99}},
3129 {"foo.c",
3130 {"typedef enum { THING_VALUE } thing_t;"
3131 "void conflict(thing_t type);"
3132 "void foo() { (void)THING_VALUE; }"
3133 "void conflict(thing_t type) {}",
3134 Lang_C99}},
3136 {"moo.c",
3137 {"typedef enum { THING_VALUE } thing_t;"
3138 "void conflict(thing_t type);"
3139 "void moo() { conflict(THING_VALUE); }",
3140 Lang_C99}}};
3142 auto VerificationMatcher =
3143 enumDecl(has(enumConstantDecl(hasName("THING_VALUE"))),
3144 hasTypedefForAnonDecl(hasName("thing_t")));
3146 ImportAction ImportFoo{"foo.c", "main.c", functionDecl(hasName("foo"))},
3147 ImportMoo{"moo.c", "main.c", functionDecl(hasName("moo"))};
3149 testImportSequence(
3150 Samples, {ImportFoo, ImportMoo}, // "foo", them "moo".
3151 // Just check that there is only one enum decl in the result AST.
3152 "main.c", enumDecl(), VerificationMatcher);
3154 // For different import order, result should be the same.
3155 testImportSequence(
3156 Samples, {ImportMoo, ImportFoo}, // "moo", them "foo".
3157 // Check that there is only one enum decl in the result AST.
3158 "main.c", enumDecl(), VerificationMatcher);
3161 TEST_P(ImportDecl, ImportFieldOrder) {
3162 MatchVerifier<Decl> Verifier;
3163 testImport("struct declToImport {"
3164 " int b = a + 2;"
3165 " int a = 5;"
3166 "};",
3167 Lang_CXX11, "", Lang_CXX11, Verifier,
3168 recordDecl(hasFieldOrder({"b", "a"})));
3171 TEST_P(ImportExpr, DependentScopeDeclRefExpr) {
3172 MatchVerifier<Decl> Verifier;
3173 testImport("template <typename T> struct S { static T foo; };"
3174 "template <typename T> void declToImport() {"
3175 " (void) S<T>::foo;"
3177 "void instantiate() { declToImport<int>(); }"
3178 "template <typename T> T S<T>::foo;",
3179 Lang_CXX11, "", Lang_CXX11, Verifier,
3180 functionTemplateDecl(has(functionDecl(has(compoundStmt(
3181 has(cStyleCastExpr(has(dependentScopeDeclRefExpr())))))))));
3183 testImport("template <typename T> struct S {"
3184 "template<typename S> static void foo(){};"
3185 "};"
3186 "template <typename T> void declToImport() {"
3187 " S<T>::template foo<T>();"
3189 "void instantiate() { declToImport<int>(); }",
3190 Lang_CXX11, "", Lang_CXX11, Verifier,
3191 functionTemplateDecl(has(functionDecl(has(compoundStmt(
3192 has(callExpr(has(dependentScopeDeclRefExpr())))))))));
3195 TEST_P(ImportExpr, DependentNameType) {
3196 MatchVerifier<Decl> Verifier;
3197 testImport("template <typename T> struct declToImport {"
3198 " typedef typename T::type dependent_name;"
3199 "};",
3200 Lang_CXX11, "", Lang_CXX11, Verifier,
3201 classTemplateDecl(has(
3202 cxxRecordDecl(has(typedefDecl(has(dependentNameType())))))));
3205 TEST_P(ImportExpr, UnresolvedMemberExpr) {
3206 MatchVerifier<Decl> Verifier;
3207 testImport("struct S { template <typename T> void mem(); };"
3208 "template <typename U> void declToImport() {"
3209 " S s;"
3210 " s.mem<U>();"
3212 "void instantiate() { declToImport<int>(); }",
3213 Lang_CXX11, "", Lang_CXX11, Verifier,
3214 functionTemplateDecl(has(functionDecl(has(
3215 compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
3218 class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
3219 public:
3220 static constexpr auto DefaultCode = R"(
3221 struct A { int x; };
3222 void f() {
3223 A a;
3224 A a1(a);
3225 A a2(A{});
3226 a = a1;
3227 a = A{};
3228 a.~A();
3229 })";
3231 template <typename MatcherType>
3232 void testImportOf(
3233 const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
3234 test(MethodMatcher, Code, /*ExpectedCount=*/1u);
3237 template <typename MatcherType>
3238 void testNoImportOf(
3239 const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
3240 test(MethodMatcher, Code, /*ExpectedCount=*/0u);
3243 private:
3244 template <typename MatcherType>
3245 void test(const MatcherType &MethodMatcher,
3246 const char *Code, unsigned int ExpectedCount) {
3247 auto ClassMatcher = cxxRecordDecl(unless(isImplicit()));
3249 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3250 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
3251 ToTU, ClassMatcher);
3253 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1u);
3256 CXXMethodDecl *Method =
3257 FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher);
3258 ToClass->removeDecl(Method);
3259 SharedStatePtr->getLookupTable()->remove(Method);
3262 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0u);
3264 Decl *ImportedClass = nullptr;
3266 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc");
3267 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
3268 FromTU, ClassMatcher);
3269 ImportedClass = Import(FromClass, Lang_CXX11);
3272 EXPECT_EQ(ToClass, ImportedClass);
3273 EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher),
3274 ExpectedCount);
3278 TEST_P(ImportImplicitMethods, DefaultConstructor) {
3279 testImportOf(cxxConstructorDecl(isDefaultConstructor()));
3282 TEST_P(ImportImplicitMethods, CopyConstructor) {
3283 testImportOf(cxxConstructorDecl(isCopyConstructor()));
3286 TEST_P(ImportImplicitMethods, MoveConstructor) {
3287 testImportOf(cxxConstructorDecl(isMoveConstructor()));
3290 TEST_P(ImportImplicitMethods, Destructor) {
3291 testImportOf(cxxDestructorDecl());
3294 TEST_P(ImportImplicitMethods, CopyAssignment) {
3295 testImportOf(cxxMethodDecl(isCopyAssignmentOperator()));
3298 TEST_P(ImportImplicitMethods, MoveAssignment) {
3299 testImportOf(cxxMethodDecl(isMoveAssignmentOperator()));
3302 TEST_P(ImportImplicitMethods, DoNotImportUserProvided) {
3303 auto Code = R"(
3304 struct A { A() { int x; } };
3306 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3309 TEST_P(ImportImplicitMethods, DoNotImportDefault) {
3310 auto Code = R"(
3311 struct A { A() = default; };
3313 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3316 TEST_P(ImportImplicitMethods, DoNotImportDeleted) {
3317 auto Code = R"(
3318 struct A { A() = delete; };
3320 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3323 TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) {
3324 auto Code = R"(
3325 struct A { void f() { } };
3327 testNoImportOf(cxxMethodDecl(hasName("f")), Code);
3330 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) {
3331 Decl *ToR1;
3333 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input0.cc");
3334 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3335 FromTU, cxxRecordDecl(hasName("A")));
3337 ToR1 = Import(FromR, Lang_CXX03);
3340 Decl *ToR2;
3342 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input1.cc");
3343 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3344 FromTU, cxxRecordDecl(hasName("A")));
3346 ToR2 = Import(FromR, Lang_CXX03);
3349 EXPECT_EQ(ToR1, ToR2);
3352 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) {
3353 Decl *ToR1;
3355 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3356 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3357 FromTU, cxxRecordDecl(hasName("A")));
3358 ToR1 = Import(FromR, Lang_CXX03);
3360 Decl *ToR2;
3362 Decl *FromTU =
3363 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
3364 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3365 FromTU, cxxRecordDecl(hasName("A")));
3366 ToR2 = Import(FromR, Lang_CXX03);
3368 EXPECT_NE(ToR1, ToR2);
3371 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) {
3372 Decl *ToF1;
3374 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3375 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3376 FromTU, fieldDecl(hasName("x")));
3377 ToF1 = Import(FromF, Lang_CXX03);
3379 Decl *ToF2;
3381 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input1.cc");
3382 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3383 FromTU, fieldDecl(hasName("x")));
3384 ToF2 = Import(FromF, Lang_CXX03);
3386 EXPECT_EQ(ToF1, ToF2);
3389 TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) {
3390 Decl *FromTU = getTuDecl("struct A { unsigned x : 3; };", Lang_CXX03);
3391 auto *FromF =
3392 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x")));
3394 ASSERT_TRUE(FromF->isBitField());
3395 ASSERT_EQ(3u, FromF->getBitWidthValue());
3396 auto *ToField = Import(FromF, Lang_CXX03);
3398 EXPECT_TRUE(ToField->isBitField());
3399 EXPECT_EQ(3u, ToField->getBitWidthValue());
3401 const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>();
3402 const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>();
3403 ASSERT_TRUE(FromBT);
3404 ASSERT_EQ(BuiltinType::Int, FromBT->getKind());
3405 EXPECT_TRUE(ToBT);
3406 EXPECT_EQ(BuiltinType::Int, ToBT->getKind());
3409 struct ImportBlock : ASTImporterOptionSpecificTestBase {};
3410 TEST_P(ImportBlock, ImportBlocksAreUnsupported) {
3411 const auto *Code = R"(
3412 void test_block__capture_null() {
3413 int *p = 0;
3414 ^(){
3415 *p = 1;
3416 }();
3417 })";
3418 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
3419 auto *FromBlock = FirstDeclMatcher<BlockDecl>().match(FromTU, blockDecl());
3420 ASSERT_TRUE(FromBlock);
3422 auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03);
3424 const auto ExpectUnsupportedConstructError = [](const ASTImportError &Error) {
3425 EXPECT_EQ(ASTImportError::UnsupportedConstruct, Error.Error);
3427 llvm::handleAllErrors(ToBlockOrError.takeError(),
3428 ExpectUnsupportedConstructError);
3431 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl) {
3432 const auto *Code = R"(
3433 template <typename T> struct Wrapper {
3434 Wrapper(T Value = {}) {}
3436 template class Wrapper<int>;
3438 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3439 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match(
3440 FromTU, parmVarDecl(hasType(asString("int"))));
3441 ASSERT_TRUE(FromVar);
3442 ASSERT_TRUE(FromVar->hasUninstantiatedDefaultArg());
3443 ASSERT_TRUE(FromVar->getUninstantiatedDefaultArg());
3444 ASSERT_FALSE(FromVar->isExplicitObjectParameter());
3446 const auto *ToVar = Import(FromVar, Lang_CXX11);
3447 EXPECT_TRUE(ToVar);
3448 EXPECT_TRUE(ToVar->hasUninstantiatedDefaultArg());
3449 EXPECT_TRUE(ToVar->getUninstantiatedDefaultArg());
3450 EXPECT_NE(FromVar->getUninstantiatedDefaultArg(),
3451 ToVar->getUninstantiatedDefaultArg());
3452 EXPECT_FALSE(ToVar->isExplicitObjectParameter());
3455 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl_Explicit) {
3456 const auto *Code = R"(
3457 struct Wrapper {
3458 void func(this Wrapper) {}
3461 Decl *FromTU = getTuDecl(Code, Lang_CXX23);
3462 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match(FromTU, parmVarDecl());
3463 ASSERT_TRUE(FromVar);
3464 ASSERT_TRUE(FromVar->isExplicitObjectParameter());
3466 const auto *ToVar = Import(FromVar, Lang_CXX23);
3467 EXPECT_TRUE(ToVar);
3468 EXPECT_TRUE(ToVar->isExplicitObjectParameter());
3469 EXPECT_NE(ToVar->getExplicitObjectParamThisLoc(),
3470 FromVar->getExplicitObjectParamThisLoc());
3473 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) {
3474 Decl *ToF1;
3476 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3477 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3478 FromTU, fieldDecl(hasName("x")));
3479 ToF1 = Import(FromF, Lang_CXX03);
3481 Decl *ToF2;
3483 Decl *FromTU =
3484 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
3485 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3486 FromTU, fieldDecl(hasName("x")));
3487 ToF2 = Import(FromF, Lang_CXX03);
3489 EXPECT_NE(ToF1, ToF2);
3492 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) {
3493 Decl *ToM1;
3495 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3496 Lang_CXX03, "input0.cc");
3497 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3498 FromTU, functionDecl(hasName("x"), isDefinition()));
3499 ToM1 = Import(FromM, Lang_CXX03);
3501 Decl *ToM2;
3503 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3504 Lang_CXX03, "input1.cc");
3505 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3506 FromTU, functionDecl(hasName("x"), isDefinition()));
3507 ToM2 = Import(FromM, Lang_CXX03);
3509 EXPECT_EQ(ToM1, ToM2);
3512 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) {
3513 Decl *ToM1;
3515 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3516 Lang_CXX03, "input0.cc");
3517 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3518 FromTU, functionDecl(hasName("x"), isDefinition()));
3519 ToM1 = Import(FromM, Lang_CXX03);
3521 Decl *ToM2;
3523 Decl *FromTU =
3524 getTuDecl("struct A { void x() const; }; void A::x() const { }",
3525 Lang_CXX03, "input1.cc");
3526 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3527 FromTU, functionDecl(hasName("x"), isDefinition()));
3528 ToM2 = Import(FromM, Lang_CXX03);
3530 EXPECT_NE(ToM1, ToM2);
3533 TEST_P(ASTImporterOptionSpecificTestBase,
3534 ImportUnnamedStructsWithRecursingField) {
3535 Decl *FromTU = getTuDecl(
3537 struct A {
3538 struct {
3539 struct A *next;
3540 } entry0;
3541 struct {
3542 struct A *next;
3543 } entry1;
3546 Lang_C99, "input0.cc");
3547 auto *From =
3548 FirstDeclMatcher<RecordDecl>().match(FromTU, recordDecl(hasName("A")));
3550 Import(From, Lang_C99);
3552 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3553 auto *Entry0 =
3554 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
3555 auto *Entry1 =
3556 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry1")));
3557 auto *R0 = getRecordDecl(Entry0);
3558 auto *R1 = getRecordDecl(Entry1);
3559 EXPECT_NE(R0, R1);
3560 EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3561 R0, recordDecl(has(fieldDecl(hasName("next"))))));
3562 EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3563 R1, recordDecl(has(fieldDecl(hasName("next"))))));
3566 TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) {
3567 Decl *FromTU = getTuDecl(
3569 void f(int X, int Y, bool Z) {
3570 (void)[X, Y, Z] { (void)Z; };
3573 Lang_CXX11, "input0.cc");
3574 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
3575 FromTU, functionDecl(hasName("f")));
3576 auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11));
3577 EXPECT_TRUE(ToF);
3579 CXXRecordDecl *FromLambda =
3580 cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>(
3581 FromF->getBody())->body_front())->getSubExpr())->getLambdaClass();
3583 auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11));
3584 EXPECT_TRUE(ToLambda);
3586 // Check if the fields of the lambda class are imported in correct order.
3587 unsigned FromIndex = 0u;
3588 for (auto *FromField : FromLambda->fields()) {
3589 ASSERT_FALSE(FromField->getDeclName());
3590 auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11));
3591 EXPECT_TRUE(ToField);
3592 std::optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField);
3593 EXPECT_TRUE(ToIndex);
3594 EXPECT_EQ(*ToIndex, FromIndex);
3595 ++FromIndex;
3598 EXPECT_EQ(FromIndex, 3u);
3601 TEST_P(ASTImporterOptionSpecificTestBase,
3602 MergeFieldDeclsOfClassTemplateSpecialization) {
3603 std::string ClassTemplate =
3605 template <typename T>
3606 struct X {
3607 int a{0}; // FieldDecl with InitListExpr
3608 X(char) : a(3) {} // (1)
3609 X(int) {} // (2)
3612 Decl *ToTU = getToTuDecl(ClassTemplate +
3614 void foo() {
3615 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr
3616 X<char> xc('c');
3618 )", Lang_CXX11);
3619 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3620 ToTU, classTemplateSpecializationDecl(hasName("X")));
3621 // FieldDecl without InitlistExpr:
3622 auto *ToField = *ToSpec->field_begin();
3623 ASSERT_TRUE(ToField);
3624 ASSERT_FALSE(ToField->getInClassInitializer());
3625 Decl *FromTU = getTuDecl(ClassTemplate +
3627 void bar() {
3628 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr
3629 X<char> xc(1);
3631 )", Lang_CXX11);
3632 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3633 FromTU, classTemplateSpecializationDecl(hasName("X")));
3634 // FieldDecl with InitlistExpr:
3635 auto *FromField = *FromSpec->field_begin();
3636 ASSERT_TRUE(FromField);
3637 ASSERT_TRUE(FromField->getInClassInitializer());
3639 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3640 ASSERT_TRUE(ImportedSpec);
3641 EXPECT_EQ(ImportedSpec, ToSpec);
3642 // After the import, the FieldDecl has to be merged, thus it should have the
3643 // InitListExpr.
3644 EXPECT_TRUE(ToField->getInClassInitializer());
3647 TEST_P(ASTImporterOptionSpecificTestBase,
3648 MergeFunctionOfClassTemplateSpecialization) {
3649 std::string ClassTemplate =
3651 template <typename T>
3652 struct X {
3653 void f() {}
3654 void g() {}
3657 Decl *ToTU = getToTuDecl(ClassTemplate +
3659 void foo() {
3660 X<char> x;
3661 x.f();
3663 )", Lang_CXX11);
3664 Decl *FromTU = getTuDecl(ClassTemplate +
3666 void bar() {
3667 X<char> x;
3668 x.g();
3670 )", Lang_CXX11);
3671 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3672 FromTU, classTemplateSpecializationDecl(hasName("X")));
3673 auto FunPattern = functionDecl(hasName("g"),
3674 hasParent(classTemplateSpecializationDecl()));
3675 auto *FromFun =
3676 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunPattern);
3677 auto *ToFun =
3678 FirstDeclMatcher<FunctionDecl>().match(ToTU, FunPattern);
3679 ASSERT_TRUE(FromFun->hasBody());
3680 ASSERT_FALSE(ToFun->hasBody());
3681 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3682 ASSERT_TRUE(ImportedSpec);
3683 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3684 ToTU, classTemplateSpecializationDecl(hasName("X")));
3685 EXPECT_EQ(ImportedSpec, ToSpec);
3686 EXPECT_TRUE(ToFun->hasBody());
3689 TEST_P(ASTImporterOptionSpecificTestBase, MergeTemplateSpecWithForwardDecl) {
3690 std::string ClassTemplate =
3692 template<typename T>
3693 struct X { int m; };
3694 template<>
3695 struct X<int> { int m; };
3697 // Append a forward decl for our template specialization.
3698 getToTuDecl(ClassTemplate + "template<> struct X<int>;", Lang_CXX11);
3699 Decl *FromTU = getTuDecl(ClassTemplate, Lang_CXX11);
3700 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3701 FromTU, classTemplateSpecializationDecl(hasName("X"), isDefinition()));
3702 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3703 // Check that our definition got merged with the existing definition.
3704 EXPECT_TRUE(FromSpec->isThisDeclarationADefinition());
3705 EXPECT_TRUE(ImportedSpec->isThisDeclarationADefinition());
3708 TEST_P(ASTImporterOptionSpecificTestBase,
3709 ODRViolationOfClassTemplateSpecializationsShouldBeReported) {
3710 std::string ClassTemplate =
3712 template <typename T>
3713 struct X {};
3715 Decl *ToTU = getToTuDecl(ClassTemplate +
3717 template <>
3718 struct X<char> {
3719 int a;
3721 void foo() {
3722 X<char> x;
3725 Lang_CXX11);
3726 Decl *FromTU = getTuDecl(ClassTemplate +
3728 template <>
3729 struct X<char> {
3730 int b;
3732 void foo() {
3733 X<char> x;
3736 Lang_CXX11);
3737 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3738 FromTU, classTemplateSpecializationDecl(hasName("X")));
3739 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3741 // We expect one (ODR) warning during the import.
3742 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
3744 // The second specialization is different from the first, thus it violates
3745 // ODR, consequently we expect to keep the first specialization only, which is
3746 // already in the "To" context.
3747 EXPECT_FALSE(ImportedSpec);
3748 EXPECT_EQ(1u,
3749 DeclCounter<ClassTemplateSpecializationDecl>().match(
3750 ToTU, classTemplateSpecializationDecl(hasName("X"))));
3753 TEST_P(ASTImporterOptionSpecificTestBase,
3754 MergeCtorOfClassTemplateSpecialization) {
3755 std::string ClassTemplate =
3757 template <typename T>
3758 struct X {
3759 X(char) {}
3760 X(int) {}
3763 Decl *ToTU = getToTuDecl(ClassTemplate +
3765 void foo() {
3766 X<char> x('c');
3768 )", Lang_CXX11);
3769 Decl *FromTU = getTuDecl(ClassTemplate +
3771 void bar() {
3772 X<char> x(1);
3774 )", Lang_CXX11);
3775 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3776 FromTU, classTemplateSpecializationDecl(hasName("X")));
3777 // Match the void(int) ctor.
3778 auto CtorPattern =
3779 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))),
3780 hasParent(classTemplateSpecializationDecl()));
3781 auto *FromCtor =
3782 FirstDeclMatcher<CXXConstructorDecl>().match(FromTU, CtorPattern);
3783 auto *ToCtor =
3784 FirstDeclMatcher<CXXConstructorDecl>().match(ToTU, CtorPattern);
3785 ASSERT_TRUE(FromCtor->hasBody());
3786 ASSERT_FALSE(ToCtor->hasBody());
3787 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3788 ASSERT_TRUE(ImportedSpec);
3789 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3790 ToTU, classTemplateSpecializationDecl(hasName("X")));
3791 EXPECT_EQ(ImportedSpec, ToSpec);
3792 EXPECT_TRUE(ToCtor->hasBody());
3795 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) {
3796 const auto *Code =
3798 template <class T> class X { friend T; };
3799 struct Y {};
3800 template class X<Y>;
3802 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3803 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3804 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3805 FromTU, classTemplateSpecializationDecl());
3806 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3807 ToTU, classTemplateSpecializationDecl());
3809 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3810 EXPECT_EQ(ImportedSpec, ToSpec);
3811 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3812 ToTU, classTemplateSpecializationDecl()));
3815 TEST_P(ASTImporterOptionSpecificTestBase,
3816 ClassTemplatePartialSpecializationsShouldNotBeDuplicated) {
3817 auto Code =
3819 // primary template
3820 template<class T1, class T2, int I>
3821 class A {};
3823 // partial specialization
3824 template<class T, int I>
3825 class A<T, T*, I> {};
3827 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3828 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3829 auto *FromSpec =
3830 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3831 FromTU, classTemplatePartialSpecializationDecl());
3832 auto *ToSpec =
3833 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3834 ToTU, classTemplatePartialSpecializationDecl());
3836 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3837 EXPECT_EQ(ImportedSpec, ToSpec);
3838 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3839 ToTU, classTemplatePartialSpecializationDecl()));
3842 TEST_P(ASTImporterOptionSpecificTestBase,
3843 ClassTemplateSpecializationsShouldNotBeDuplicated) {
3844 auto Code =
3846 // primary template
3847 template<class T1, class T2, int I>
3848 class A {};
3850 // full specialization
3851 template<>
3852 class A<int, int, 1> {};
3854 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3855 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3856 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3857 FromTU, classTemplateSpecializationDecl());
3858 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3859 ToTU, classTemplateSpecializationDecl());
3861 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3862 EXPECT_EQ(ImportedSpec, ToSpec);
3863 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3864 ToTU, classTemplateSpecializationDecl()));
3867 TEST_P(ASTImporterOptionSpecificTestBase,
3868 ClassTemplateFullAndPartialSpecsShouldNotBeMixed) {
3869 std::string PrimaryTemplate =
3871 template<class T1, class T2, int I>
3872 class A {};
3874 auto PartialSpec =
3876 template<class T, int I>
3877 class A<T, T*, I> {};
3879 auto FullSpec =
3881 template<>
3882 class A<int, int, 1> {};
3884 Decl *ToTU = getToTuDecl(PrimaryTemplate + FullSpec, Lang_CXX11);
3885 Decl *FromTU = getTuDecl(PrimaryTemplate + PartialSpec, Lang_CXX11);
3886 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3887 FromTU, classTemplateSpecializationDecl());
3889 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3890 EXPECT_TRUE(ImportedSpec);
3891 // Check the number of partial specializations.
3892 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3893 ToTU, classTemplatePartialSpecializationDecl()));
3894 // Check the number of full specializations.
3895 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3896 ToTU, classTemplateSpecializationDecl(
3897 unless(classTemplatePartialSpecializationDecl()))));
3900 TEST_P(ASTImporterOptionSpecificTestBase,
3901 InitListExprValueKindShouldBeImported) {
3902 Decl *TU = getTuDecl(
3904 const int &init();
3905 void foo() { const int &a{init()}; }
3906 )", Lang_CXX11, "input0.cc");
3907 auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a")));
3908 ASSERT_TRUE(FromD->getAnyInitializer());
3909 auto *InitExpr = FromD->getAnyInitializer();
3910 ASSERT_TRUE(InitExpr);
3911 ASSERT_TRUE(InitExpr->isGLValue());
3913 auto *ToD = Import(FromD, Lang_CXX11);
3914 EXPECT_TRUE(ToD);
3915 auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer();
3916 EXPECT_TRUE(ToInitExpr);
3917 EXPECT_TRUE(ToInitExpr->isGLValue());
3920 struct ImportVariables : ASTImporterOptionSpecificTestBase {};
3922 TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) {
3923 Decl *FromTU = getTuDecl(
3925 struct A {
3926 static const int a = 1 + 2;
3928 const int A::a;
3930 Lang_CXX03, "input1.cc");
3932 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3933 FromTU, varDecl(hasName("a"))); // Decl with init
3934 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3935 FromTU, varDecl(hasName("a"))); // Decl with definition
3936 ASSERT_NE(FromDWithInit, FromDWithDef);
3937 ASSERT_EQ(FromDWithDef->getPreviousDecl(), FromDWithInit);
3939 auto *ToD0 = cast<VarDecl>(Import(FromDWithInit, Lang_CXX11));
3940 auto *ToD1 = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3941 ASSERT_TRUE(ToD0);
3942 ASSERT_TRUE(ToD1);
3943 EXPECT_NE(ToD0, ToD1);
3944 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
3947 TEST_P(ImportVariables, InitAndDefinitionAreInDifferentTUs) {
3948 auto StructA =
3950 struct A {
3951 static const int a = 1 + 2;
3954 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3955 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a;", Lang_CXX03,
3956 "input1.cc");
3958 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3959 FromTU, varDecl(hasName("a"))); // Decl with init
3960 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3961 FromTU, varDecl(hasName("a"))); // Decl with definition
3962 ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl());
3963 ASSERT_TRUE(FromDWithInit->getInit());
3964 ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition());
3965 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3966 ASSERT_FALSE(FromDWithDef->getInit());
3968 auto *ToD = FirstDeclMatcher<VarDecl>().match(
3969 ToTU, varDecl(hasName("a"))); // Decl with init
3970 ASSERT_TRUE(ToD->getInit());
3971 ASSERT_FALSE(ToD->getDefinition());
3973 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3974 EXPECT_TRUE(ImportedD->getAnyInitializer());
3975 EXPECT_TRUE(ImportedD->getDefinition());
3978 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) {
3979 auto StructA =
3981 struct A {
3982 static const int a;
3985 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3986 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a = 1 + 2;",
3987 Lang_CXX03, "input1.cc");
3989 auto *FromDDeclarationOnly = FirstDeclMatcher<VarDecl>().match(
3990 FromTU, varDecl(hasName("a")));
3991 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3992 FromTU, varDecl(hasName("a"))); // Decl with definition and with init.
3993 ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl());
3994 ASSERT_FALSE(FromDDeclarationOnly->getInit());
3995 ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition());
3996 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3997 ASSERT_TRUE(FromDWithDef->getInit());
3999 auto *ToD = FirstDeclMatcher<VarDecl>().match(
4000 ToTU, varDecl(hasName("a")));
4001 ASSERT_FALSE(ToD->getInit());
4002 ASSERT_FALSE(ToD->getDefinition());
4004 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
4005 EXPECT_TRUE(ImportedD->getAnyInitializer());
4006 EXPECT_TRUE(ImportedD->getDefinition());
4009 TEST_P(ImportVariables, ImportBindingDecl) {
4010 Decl *From, *To;
4011 std::tie(From, To) = getImportedDecl(
4013 void declToImport() {
4014 int a[2] = {1,2};
4015 auto [x1,y1] = a;
4016 auto& [x2,y2] = a;
4018 struct S {
4019 mutable int x1 : 2;
4020 volatile double y1;
4022 S b;
4023 const auto [x3, y3] = b;
4026 Lang_CXX17, "", Lang_CXX17);
4028 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl();
4029 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
4030 FromTU, functionDecl(hasName("declToImport")));
4031 auto *ToF = Import(FromF, Lang_CXX17);
4032 EXPECT_TRUE(ToF);
4034 auto VerifyImport = [&](llvm::StringRef BindName) {
4035 auto *FromB = FirstDeclMatcher<BindingDecl>().match(
4036 FromF, bindingDecl(hasName(BindName)));
4037 ASSERT_TRUE(FromB);
4038 auto *ToB = Import(FromB, Lang_CXX17);
4039 EXPECT_TRUE(ToB);
4040 EXPECT_EQ(FromB->getBinding() != nullptr, ToB->getBinding() != nullptr);
4041 EXPECT_EQ(FromB->getDecomposedDecl() != nullptr,
4042 ToB->getDecomposedDecl() != nullptr);
4043 EXPECT_EQ(FromB->getHoldingVar() != nullptr,
4044 ToB->getHoldingVar() != nullptr);
4047 VerifyImport("x1");
4048 VerifyImport("y1");
4049 VerifyImport("x2");
4050 VerifyImport("y2");
4051 VerifyImport("x3");
4052 VerifyImport("y3");
4055 TEST_P(ImportVariables, ImportDecompositionDeclArray) {
4056 Decl *From, *To;
4057 std::tie(From, To) = getImportedDecl(
4059 void declToImport() {
4060 int a[2] = {1,2};
4061 auto [x1,y1] = a;
4064 Lang_CXX17, "", Lang_CXX17);
4066 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl();
4067 auto *FromDecomp =
4068 FirstDeclMatcher<DecompositionDecl>().match(FromTU, decompositionDecl());
4069 auto *ToDecomp = Import(FromDecomp, Lang_CXX17);
4070 EXPECT_TRUE(ToDecomp);
4072 ArrayRef<BindingDecl *> FromB = FromDecomp->bindings();
4073 ArrayRef<BindingDecl *> ToB = ToDecomp->bindings();
4074 EXPECT_EQ(FromB.size(), ToB.size());
4075 for (unsigned int I = 0; I < FromB.size(); ++I) {
4076 auto *ToBI = Import(FromB[I], Lang_CXX17);
4077 EXPECT_EQ(ToBI, ToB[I]);
4081 struct ImportClasses : ASTImporterOptionSpecificTestBase {};
4083 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {
4084 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C99);
4085 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
4086 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
4087 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4088 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
4090 Decl *ImportedDef = Import(FromDef, Lang_C99);
4092 EXPECT_NE(ImportedDef, ToProto);
4093 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
4094 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4095 EXPECT_TRUE(ImportedDef == ToDef);
4096 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
4097 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
4098 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
4101 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) {
4102 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03);
4103 Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX03, "input1.cc");
4104 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
4105 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4106 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
4108 Decl *ImportedDef = Import(FromDef, Lang_CXX03);
4110 EXPECT_NE(ImportedDef, ToProto);
4111 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
4112 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4113 EXPECT_TRUE(ImportedDef == ToDef);
4114 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
4115 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
4116 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
4119 TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) {
4120 Decl *FromTU0 =
4121 getTuDecl("struct A { struct X *Xp; };", Lang_C99, "input0.cc");
4122 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
4123 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
4124 auto FromProto = FirstDeclMatcher<RecordDecl>().match(FromTU0, Pattern);
4125 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
4127 Decl *ImportedProto = Import(FromProto, Lang_C99);
4128 Decl *ImportedDef = Import(FromDef, Lang_C99);
4129 Decl *ToTU = ImportedDef->getTranslationUnitDecl();
4131 EXPECT_NE(ImportedDef, ImportedProto);
4132 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
4133 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4134 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
4135 EXPECT_TRUE(ImportedDef == ToDef);
4136 EXPECT_TRUE(ImportedProto == ToProto);
4137 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
4138 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
4139 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
4142 struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {
4143 void testRecursiveFriendClassTemplate(Decl *FromTu) {
4144 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4145 FromTu, classTemplateDecl());
4147 auto Pattern = classTemplateDecl(
4148 has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
4149 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
4151 auto *FromFriend =
4152 FirstDeclMatcher<FriendDecl>().match(FromD, friendDecl());
4153 auto *FromRecordOfFriend =
4154 cast<ClassTemplateDecl>(FromFriend->getFriendDecl())
4155 ->getTemplatedDecl();
4156 EXPECT_NE(FromRecordOfFriend, FromD->getTemplatedDecl());
4157 EXPECT_TRUE(FromRecordOfFriend->getPreviousDecl() == nullptr);
4159 auto *FromDC = FromRecordOfFriend->getDeclContext();
4160 auto *FromLexicalDC = FromRecordOfFriend->getLexicalDeclContext();
4161 ASSERT_EQ(FromDC, cast<DeclContext>(FromTu));
4162 ASSERT_EQ(FromLexicalDC, cast<DeclContext>(FromD->getTemplatedDecl()));
4164 ASSERT_FALSE(FromDC->containsDecl(FromRecordOfFriend));
4165 ASSERT_FALSE(FromLexicalDC->containsDecl(FromRecordOfFriend));
4166 ASSERT_FALSE(cast<RecordDecl>(FromRecordOfFriend)
4167 ->getLookupParent()
4168 ->lookup(FromRecordOfFriend->getDeclName())
4169 .empty());
4171 auto *ToD = Import(FromD, Lang_CXX03);
4172 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
4174 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl());
4175 auto *ToRecordOfFriend =
4176 cast<ClassTemplateDecl>(ToFriend->getFriendDecl())->getTemplatedDecl();
4178 EXPECT_NE(ToRecordOfFriend, ToD->getTemplatedDecl());
4179 EXPECT_TRUE(ToRecordOfFriend->getPreviousDecl() == nullptr);
4181 auto *ToDC = ToRecordOfFriend->getDeclContext();
4182 auto *ToLexicalDC = ToRecordOfFriend->getLexicalDeclContext();
4183 ASSERT_EQ(ToDC, cast<DeclContext>(ToD->getTranslationUnitDecl()));
4184 ASSERT_EQ(ToLexicalDC, cast<DeclContext>(ToD->getTemplatedDecl()));
4186 ASSERT_FALSE(ToDC->containsDecl(ToRecordOfFriend));
4187 ASSERT_FALSE(ToLexicalDC->containsDecl(ToRecordOfFriend));
4188 ASSERT_FALSE(cast<RecordDecl>(ToRecordOfFriend)
4189 ->getLookupParent()
4190 ->lookup(ToRecordOfFriend->getDeclName())
4191 .empty());
4194 void testRepeatedFriendImport(const char *Code) {
4195 Decl *ToTu = getToTuDecl(Code, Lang_CXX03);
4196 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc");
4198 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4199 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4200 auto *FromFriend1 =
4201 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4202 auto *FromFriend2 =
4203 LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4205 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03);
4206 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03);
4208 EXPECT_NE(ToImportedFriend1, ToImportedFriend2);
4209 EXPECT_EQ(ToFriend1, ToImportedFriend1);
4210 EXPECT_EQ(ToFriend2, ToImportedFriend2);
4214 TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) {
4215 Decl *FromTU = getTuDecl(
4217 class A {
4218 template <int I> class F {};
4219 class X {
4220 template <int I> friend class F;
4224 Lang_CXX03, "input0.cc");
4226 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
4227 FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
4228 auto *FromFriendClass = LastDeclMatcher<CXXRecordDecl>().match(
4229 FromTU, cxxRecordDecl(hasName("F")));
4231 ASSERT_TRUE(FromClass);
4232 ASSERT_TRUE(FromFriendClass);
4233 ASSERT_NE(FromClass, FromFriendClass);
4234 ASSERT_EQ(FromFriendClass->getDefinition(), FromClass);
4235 ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass);
4236 ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
4237 FromClass->getDescribedClassTemplate());
4239 auto *ToClass = cast<CXXRecordDecl>(Import(FromClass, Lang_CXX03));
4240 auto *ToFriendClass =
4241 cast<CXXRecordDecl>(Import(FromFriendClass, Lang_CXX03));
4243 EXPECT_TRUE(ToClass);
4244 EXPECT_TRUE(ToFriendClass);
4245 EXPECT_NE(ToClass, ToFriendClass);
4246 EXPECT_EQ(ToFriendClass->getDefinition(), ToClass);
4247 EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass);
4248 EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
4249 ToClass->getDescribedClassTemplate());
4252 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) {
4253 Decl *FromTu = getTuDecl(
4255 class declToImport {
4256 friend class declToImport;
4259 Lang_CXX03, "input.cc");
4261 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
4262 FromTu, cxxRecordDecl(hasName("declToImport")));
4263 auto *ToD = Import(FromD, Lang_CXX03);
4264 auto Pattern = cxxRecordDecl(has(friendDecl()));
4265 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
4266 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
4269 TEST_P(ImportFriendClasses, UndeclaredFriendClassShouldNotBeVisible) {
4270 Decl *FromTu =
4271 getTuDecl("class X { friend class Y; };", Lang_CXX03, "from.cc");
4272 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
4273 FromTu, cxxRecordDecl(hasName("X")));
4274 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4275 RecordDecl *FromRecordOfFriend =
4276 const_cast<RecordDecl *>(getRecordDeclOfFriend(FromFriend));
4278 ASSERT_EQ(FromRecordOfFriend->getDeclContext(), cast<DeclContext>(FromTu));
4279 ASSERT_EQ(FromRecordOfFriend->getLexicalDeclContext(),
4280 cast<DeclContext>(FromX));
4281 ASSERT_FALSE(
4282 FromRecordOfFriend->getDeclContext()->containsDecl(FromRecordOfFriend));
4283 ASSERT_FALSE(FromRecordOfFriend->getLexicalDeclContext()->containsDecl(
4284 FromRecordOfFriend));
4285 ASSERT_FALSE(FromRecordOfFriend->getLookupParent()
4286 ->lookup(FromRecordOfFriend->getDeclName())
4287 .empty());
4289 auto *ToX = Import(FromX, Lang_CXX03);
4290 ASSERT_TRUE(ToX);
4292 Decl *ToTu = ToX->getTranslationUnitDecl();
4293 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4294 RecordDecl *ToRecordOfFriend =
4295 const_cast<RecordDecl *>(getRecordDeclOfFriend(ToFriend));
4297 ASSERT_EQ(ToRecordOfFriend->getDeclContext(), cast<DeclContext>(ToTu));
4298 ASSERT_EQ(ToRecordOfFriend->getLexicalDeclContext(), cast<DeclContext>(ToX));
4299 EXPECT_FALSE(
4300 ToRecordOfFriend->getDeclContext()->containsDecl(ToRecordOfFriend));
4301 EXPECT_FALSE(ToRecordOfFriend->getLexicalDeclContext()->containsDecl(
4302 ToRecordOfFriend));
4303 EXPECT_FALSE(ToRecordOfFriend->getLookupParent()
4304 ->lookup(ToRecordOfFriend->getDeclName())
4305 .empty());
4308 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) {
4309 Decl *FromTu = getTuDecl(
4311 template<class A> class declToImport {
4312 template<class A1> friend class declToImport;
4315 Lang_CXX03, "input.cc");
4317 testRecursiveFriendClassTemplate(FromTu);
4320 TEST_P(ImportFriendClasses,
4321 ImportOfRecursiveFriendClassTemplateWithNonTypeParm) {
4322 Decl *FromTu = getTuDecl(
4324 template<class A1, A1 A> class declToImport {
4325 template<class B1, B1> friend class declToImport;
4328 Lang_CXX03, "input.cc");
4329 testRecursiveFriendClassTemplate(FromTu);
4332 TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) {
4333 auto Pattern = classTemplateSpecializationDecl(hasName("X"));
4335 ClassTemplateSpecializationDecl *Imported1;
4337 Decl *FromTU = getTuDecl("template<class T> class X;"
4338 "struct Y { friend class X<int>; };",
4339 Lang_CXX03, "input0.cc");
4340 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4341 FromTU, Pattern);
4343 Imported1 =
4344 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
4346 ClassTemplateSpecializationDecl *Imported2;
4348 Decl *FromTU = getTuDecl("template<class T> class X;"
4349 "template<> class X<int>{};"
4350 "struct Z { friend class X<int>; };",
4351 Lang_CXX03, "input1.cc");
4352 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4353 FromTU, Pattern);
4355 Imported2 =
4356 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
4359 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4360 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(ToTU, Pattern),
4361 2u);
4362 ASSERT_TRUE(Imported2->getPreviousDecl());
4363 EXPECT_EQ(Imported2->getPreviousDecl(), Imported1);
4366 TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) {
4367 Decl *FromTU0 = getTuDecl(
4369 class X {
4370 class Y;
4372 class X::Y {
4373 template <typename T>
4374 friend class F; // The decl context of F is the global namespace.
4377 Lang_CXX03, "input0.cc");
4378 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4379 FromTU0, classTemplateDecl(hasName("F")));
4380 auto *Imported0 = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
4381 Decl *FromTU1 = getTuDecl(
4383 template <typename T>
4384 class F {};
4386 Lang_CXX03, "input1.cc");
4387 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4388 FromTU1, classTemplateDecl(hasName("F")));
4389 auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4390 EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(),
4391 Imported1->getTemplatedDecl()->getTypeForDecl());
4394 TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) {
4395 Decl *From, *To;
4396 std::tie(From, To) =
4397 getImportedDecl("class declToImport {};", Lang_CXX03,
4398 "class Y { friend class declToImport; };", Lang_CXX03);
4399 auto *Imported = cast<CXXRecordDecl>(To);
4401 EXPECT_TRUE(Imported->getPreviousDecl());
4404 TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
4405 Decl *ToTU = getToTuDecl(
4407 template <class T, T U>
4408 class A;
4410 template <class T, T U>
4411 class A {
4412 public:
4413 template <class P, P Q>
4414 friend class A;
4416 A(T x) :x(x) {}
4418 private:
4419 T x;
4422 Lang_CXX11);
4424 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4425 ToTU,
4426 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4427 Decl *FromTU = getTuDecl(
4429 template <class T, T U>
4430 class A;
4432 template <class T, T U>
4433 class A {
4434 public:
4435 template <class P, P Q>
4436 friend class A;
4438 A(T x) : x(x) {}
4440 private:
4441 T x;
4444 A<int,3> a1(0);
4446 Lang_CXX11, "input1.cc");
4447 auto *FromA = FirstDeclMatcher<ClassTemplateDecl>().match(
4448 FromTU,
4449 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4450 auto *ToA = Import(FromA, Lang_CXX11);
4451 EXPECT_TRUE(ToA);
4452 EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
4453 ToA->getTemplatedDecl()->getTypeForDecl());
4456 TEST_P(ImportFriendClasses,
4457 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
4458 Decl *ToTU = getToTuDecl(
4460 class X {
4461 class Y;
4463 class X::Y {
4464 template <typename T>
4465 friend class F; // The decl context of F is the global namespace.
4468 Lang_CXX03);
4469 auto *ToDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
4470 ToTU, classTemplateDecl(hasName("F")));
4471 Decl *FromTU = getTuDecl(
4473 template <typename T>
4474 class F {};
4476 Lang_CXX03, "input0.cc");
4477 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4478 FromTU, classTemplateDecl(hasName("F")));
4479 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4480 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4481 EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl());
4482 EXPECT_EQ(ToDecl->getTemplatedDecl(),
4483 ImportedDef->getTemplatedDecl()->getPreviousDecl());
4486 TEST_P(ImportFriendClasses,
4487 ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) {
4488 Decl *FromTU0 = getTuDecl(
4490 class X {
4491 class Y;
4493 class X::Y {
4494 template <typename T>
4495 friend class F; // The decl context of F is the global namespace.
4498 Lang_CXX03, "input0.cc");
4499 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4500 FromTU0, classTemplateDecl(hasName("F")));
4501 auto *ImportedFwd = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
4502 Decl *FromTU1 = getTuDecl(
4504 template <typename T>
4505 class F {};
4507 Lang_CXX03, "input1.cc");
4508 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4509 FromTU1, classTemplateDecl(hasName("F")));
4510 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4511 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4512 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
4513 EXPECT_EQ(ImportedFwd->getTemplatedDecl(),
4514 ImportedDef->getTemplatedDecl()->getPreviousDecl());
4517 TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
4518 Decl *FromTU0 = getTuDecl(
4520 class X {
4521 class Y;
4523 class X::Y {
4524 friend class F; // The decl context of F is the global namespace.
4527 Lang_CXX03, "input0.cc");
4528 auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl());
4529 QualType FT = Friend->getFriendType()->getType();
4530 FT = FromTU0->getASTContext().getCanonicalType(FT);
4531 auto *Fwd = cast<TagType>(FT)->getDecl();
4532 auto *ImportedFwd = Import(Fwd, Lang_CXX03);
4533 Decl *FromTU1 = getTuDecl(
4535 class F {};
4537 Lang_CXX03, "input1.cc");
4538 auto *Definition = FirstDeclMatcher<CXXRecordDecl>().match(
4539 FromTU1, cxxRecordDecl(hasName("F")));
4540 auto *ImportedDef = Import(Definition, Lang_CXX03);
4541 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4542 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
4545 TEST_P(ImportFriendClasses,
4546 ImportFriendTemplatesInDependentContext_DefToFriend) {
4547 Decl *ToTU = getToTuDecl(
4549 template<class T1>
4550 struct X {
4551 template<class T2>
4552 friend struct Y;
4555 Lang_CXX03);
4556 auto *ToYFriend = FirstDeclMatcher<ClassTemplateDecl>().match(
4557 ToTU, classTemplateDecl(hasName("Y")));
4558 Decl *FromTU = getTuDecl(
4560 template<class T1>
4561 struct Y {};
4563 Lang_CXX03, "input0.cc");
4564 auto *FromYDef = FirstDeclMatcher<ClassTemplateDecl>().match(
4565 FromTU, classTemplateDecl(hasName("Y")));
4566 auto *ImportedYDef = Import(FromYDef, Lang_CXX03);
4567 EXPECT_TRUE(ImportedYDef);
4568 EXPECT_FALSE(ImportedYDef->getPreviousDecl());
4569 EXPECT_NE(ImportedYDef, ToYFriend);
4572 TEST_P(ImportFriendClasses,
4573 ImportFriendTemplatesInDependentContext_DefToFriend_NE) {
4574 getToTuDecl(
4576 template<class T1>
4577 struct X {
4578 template<class T2>
4579 friend struct Y;
4582 Lang_CXX03);
4583 Decl *FromTU = getTuDecl(
4585 template<class T1, class T2>
4586 struct Y {};
4588 Lang_CXX03, "input0.cc");
4589 auto *FromYDef = FirstDeclMatcher<ClassTemplateDecl>().match(
4590 FromTU, classTemplateDecl(hasName("Y")));
4591 auto *ImportedYDef = Import(FromYDef, Lang_CXX03);
4592 EXPECT_FALSE(ImportedYDef);
4595 TEST_P(ImportFriendClasses,
4596 ImportFriendTemplatesInDependentContext_FriendToFriend) {
4597 Decl *ToTU = getToTuDecl(
4599 template<class T1>
4600 struct X {
4601 template<class T2>
4602 friend struct Y;
4605 Lang_CXX03);
4606 auto *ToYFriend = FirstDeclMatcher<ClassTemplateDecl>().match(
4607 ToTU, classTemplateDecl(hasName("Y")));
4608 Decl *FromTU = getTuDecl(
4610 template<class T1>
4611 struct X {
4612 template<class T2>
4613 friend struct Y;
4616 Lang_CXX03, "input0.cc");
4617 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match(
4618 FromTU, classTemplateDecl(hasName("Y")));
4619 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03);
4620 EXPECT_TRUE(ImportedYFriend);
4621 EXPECT_FALSE(ImportedYFriend->getPreviousDecl());
4622 EXPECT_NE(ImportedYFriend, ToYFriend);
4625 TEST_P(ImportFriendClasses,
4626 ImportFriendTemplatesInDependentContext_FriendToFriend_NE) {
4627 getToTuDecl(
4629 template<class T1>
4630 struct X {
4631 template<class T2>
4632 friend struct Y;
4635 Lang_CXX03);
4636 Decl *FromTU = getTuDecl(
4638 template<class T1>
4639 struct X {
4640 template<class T2, class T3>
4641 friend struct Y;
4644 Lang_CXX03, "input0.cc");
4645 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match(
4646 FromTU, classTemplateDecl(hasName("Y")));
4647 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03);
4648 EXPECT_FALSE(ImportedYFriend);
4651 TEST_P(ImportFriendClasses,
4652 ImportFriendTemplatesInDependentContext_FriendToDef) {
4653 Decl *ToTU = getToTuDecl(
4655 template<class T1>
4656 struct Y {};
4658 Lang_CXX03);
4659 auto *ToYDef = FirstDeclMatcher<ClassTemplateDecl>().match(
4660 ToTU, classTemplateDecl(hasName("Y")));
4661 Decl *FromTU = getTuDecl(
4663 template<class T1>
4664 struct X {
4665 template<class T2>
4666 friend struct Y;
4669 Lang_CXX03, "input0.cc");
4670 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match(
4671 FromTU, classTemplateDecl(hasName("Y")));
4672 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03);
4673 EXPECT_TRUE(ImportedYFriend);
4674 EXPECT_FALSE(ImportedYFriend->getPreviousDecl());
4675 EXPECT_NE(ImportedYFriend, ToYDef);
4678 TEST_P(ImportFriendClasses,
4679 ImportFriendTemplatesInDependentContext_FriendToDef_NE) {
4680 getToTuDecl(
4682 template<class T1>
4683 struct Y {};
4685 Lang_CXX03);
4686 Decl *FromTU = getTuDecl(
4688 template<class T1>
4689 struct X {
4690 template<class T2, class T3>
4691 friend struct Y;
4694 Lang_CXX03, "input0.cc");
4695 auto *FromYFriend = FirstDeclMatcher<ClassTemplateDecl>().match(
4696 FromTU, classTemplateDecl(hasName("Y")));
4697 auto *ImportedYFriend = Import(FromYFriend, Lang_CXX03);
4698 EXPECT_FALSE(ImportedYFriend);
4701 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) {
4702 const char *Code =
4704 class Container {
4705 friend class X;
4706 friend class X;
4709 testRepeatedFriendImport(Code);
4712 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) {
4713 const char *Code =
4715 class Container {
4716 friend void f();
4717 friend void f();
4720 testRepeatedFriendImport(Code);
4723 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendFunctionTemplateDecl) {
4724 const char *Code =
4726 template <class T>
4727 class Container {
4728 template <class U> friend void m();
4729 template <class U> friend void m();
4732 testRepeatedFriendImport(Code);
4735 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendClassTemplateDecl) {
4736 const char *Code =
4738 template <class T>
4739 class Container {
4740 template <class U> friend class X;
4741 template <class U> friend class X;
4744 testRepeatedFriendImport(Code);
4747 TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) {
4748 auto *Code = R"(
4749 template <class T>
4750 struct X {
4751 friend void foo(){}
4754 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
4755 auto *ToFoo = FirstDeclMatcher<FunctionDecl>().match(
4756 ToTU, functionDecl(hasName("foo")));
4758 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
4759 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
4760 FromTU, functionDecl(hasName("foo")));
4761 auto *ImportedFoo = Import(FromFoo, Lang_CXX03);
4762 EXPECT_EQ(ImportedFoo, ToFoo);
4765 struct DeclContextTest : ASTImporterOptionSpecificTestBase {};
4767 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
4768 Decl *TU = getTuDecl(
4770 namespace NS {
4772 template <typename T>
4773 struct S {};
4774 template struct S<int>;
4776 inline namespace INS {
4777 template <typename T>
4778 struct S {};
4779 template struct S<int>;
4783 )", Lang_CXX11, "input0.cc");
4784 auto *NS = FirstDeclMatcher<NamespaceDecl>().match(
4785 TU, namespaceDecl());
4786 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4787 TU, classTemplateSpecializationDecl());
4788 ASSERT_TRUE(NS->containsDecl(Spec));
4790 NS->removeDecl(Spec);
4791 EXPECT_FALSE(NS->containsDecl(Spec));
4794 TEST_P(DeclContextTest,
4795 removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) {
4796 Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX03);
4797 auto *A0 = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
4798 auto *A1 = LastDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
4800 // Investigate the list.
4801 auto *DC = A0->getDeclContext();
4802 ASSERT_TRUE(DC->containsDecl(A0));
4803 ASSERT_TRUE(DC->containsDecl(A1));
4805 // Investigate the lookup table.
4806 auto *Map = DC->getLookupPtr();
4807 ASSERT_TRUE(Map);
4808 auto I = Map->find(A0->getDeclName());
4809 ASSERT_NE(I, Map->end());
4810 StoredDeclsList &L = I->second;
4811 // The lookup table contains the most recent decl of A.
4812 ASSERT_NE(L.getAsDecl(), A0);
4813 ASSERT_EQ(L.getAsDecl(), A1);
4815 ASSERT_TRUE(L.getAsDecl());
4816 // Simulate the private function DeclContext::reconcileExternalVisibleStorage.
4817 // We do not have a list with one element.
4818 L.setHasExternalDecls();
4819 ASSERT_FALSE(L.getAsList());
4820 auto Results = L.getLookupResult();
4821 ASSERT_EQ(1u, std::distance(Results.begin(), Results.end()));
4823 // This asserts in the old implementation.
4824 DC->removeDecl(A0);
4825 EXPECT_FALSE(DC->containsDecl(A0));
4827 // Make sure we do not leave a StoredDeclsList with no entries.
4828 DC->removeDecl(A1);
4829 ASSERT_EQ(Map->find(A1->getDeclName()), Map->end());
4832 struct ImportFunctionTemplateSpecializations
4833 : ASTImporterOptionSpecificTestBase {};
4835 TEST_P(ImportFunctionTemplateSpecializations,
4836 TUshouldNotContainFunctionTemplateImplicitInstantiation) {
4838 Decl *FromTU = getTuDecl(
4840 template<class T>
4841 int f() { return 0; }
4842 void foo() { f<int>(); }
4844 Lang_CXX03, "input0.cc");
4846 // Check that the function template instantiation is NOT the child of the TU.
4847 auto Pattern = translationUnitDecl(
4848 unless(has(functionDecl(hasName("f"), isTemplateInstantiation()))));
4849 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4851 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
4852 FromTU, functionDecl(hasName("foo")));
4853 ASSERT_TRUE(Import(Foo, Lang_CXX03));
4855 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4856 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4859 TEST_P(ImportFunctionTemplateSpecializations,
4860 TUshouldNotContainFunctionTemplateExplicitInstantiation) {
4862 Decl *FromTU = getTuDecl(
4864 template<class T>
4865 int f() { return 0; }
4866 template int f<int>();
4868 Lang_CXX03, "input0.cc");
4870 // Check that the function template instantiation is NOT the child of the TU.
4871 auto Instantiation = functionDecl(hasName("f"), isTemplateInstantiation());
4872 auto Pattern = translationUnitDecl(unless(has(Instantiation)));
4873 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4875 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation),
4876 Lang_CXX03));
4878 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4879 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4882 TEST_P(ImportFunctionTemplateSpecializations,
4883 TUshouldContainFunctionTemplateSpecialization) {
4885 Decl *FromTU = getTuDecl(
4887 template<class T>
4888 int f() { return 0; }
4889 template <> int f<int>() { return 4; }
4891 Lang_CXX03, "input0.cc");
4893 // Check that the function template specialization is the child of the TU.
4894 auto Specialization =
4895 functionDecl(hasName("f"), isExplicitTemplateSpecialization());
4896 auto Pattern = translationUnitDecl(has(Specialization));
4897 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4899 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization),
4900 Lang_CXX03));
4902 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4903 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4906 TEST_P(ImportFunctionTemplateSpecializations,
4907 FunctionTemplateSpecializationRedeclChain) {
4909 Decl *FromTU = getTuDecl(
4911 template<class T>
4912 int f() { return 0; }
4913 template <> int f<int>() { return 4; }
4915 Lang_CXX03, "input0.cc");
4917 auto Spec = functionDecl(hasName("f"), isExplicitTemplateSpecialization(),
4918 hasParent(translationUnitDecl()));
4919 auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec);
4921 auto *TU = FromTU;
4922 auto *SpecD = FromSpecD;
4923 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4924 TU, functionTemplateDecl());
4925 auto *FirstSpecD = *(TemplateD->spec_begin());
4926 ASSERT_EQ(SpecD, FirstSpecD);
4927 ASSERT_TRUE(SpecD->getPreviousDecl());
4928 ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4929 ->doesThisDeclarationHaveABody());
4932 ASSERT_TRUE(Import(FromSpecD, Lang_CXX03));
4935 auto *TU = ToAST->getASTContext().getTranslationUnitDecl();
4936 auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec);
4937 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4938 TU, functionTemplateDecl());
4939 auto *FirstSpecD = *(TemplateD->spec_begin());
4940 EXPECT_EQ(SpecD, FirstSpecD);
4941 ASSERT_TRUE(SpecD->getPreviousDecl());
4942 EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4943 ->doesThisDeclarationHaveABody());
4947 TEST_P(ImportFunctionTemplateSpecializations,
4948 MatchNumberOfFunctionTemplateSpecializations) {
4950 Decl *FromTU = getTuDecl(
4952 template <typename T> constexpr int f() { return 0; }
4953 template <> constexpr int f<int>() { return 4; }
4954 void foo() {
4955 static_assert(f<char>() == 0, "");
4956 static_assert(f<int>() == 4, "");
4959 Lang_CXX11, "input0.cc");
4960 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
4961 FromTU, functionDecl(hasName("foo")));
4963 Import(FromD, Lang_CXX11);
4964 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4965 EXPECT_EQ(
4966 DeclCounter<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))),
4967 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))));
4970 TEST_P(ASTImporterOptionSpecificTestBase,
4971 ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
4973 Decl *FromTU = getTuDecl(
4975 template <typename T>
4976 struct B;
4978 Lang_CXX03, "input0.cc");
4979 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4980 FromTU, classTemplateDecl(hasName("B")));
4982 Import(FromD, Lang_CXX03);
4986 Decl *FromTU = getTuDecl(
4988 template <typename T>
4989 struct B {
4990 void f();
4991 B* b;
4994 Lang_CXX03, "input1.cc");
4995 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
4996 FromTU, functionDecl(hasName("f")));
4997 Import(FromD, Lang_CXX03);
4998 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
4999 FromTU, classTemplateDecl(hasName("B")));
5000 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
5001 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
5003 // We expect no (ODR) warning during the import.
5004 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5005 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
5009 TEST_P(ASTImporterOptionSpecificTestBase,
5010 ImportingTypedefShouldImportTheCompleteType) {
5011 // We already have an incomplete underlying type in the "To" context.
5012 auto Code =
5014 template <typename T>
5015 struct S {
5016 void foo();
5018 using U = S<int>;
5020 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
5021 auto *ToD = FirstDeclMatcher<TypedefNameDecl>().match(ToTU,
5022 typedefNameDecl(hasName("U")));
5023 ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType());
5025 // The "From" context has the same typedef, but the underlying type is
5026 // complete this time.
5027 Decl *FromTU = getTuDecl(std::string(Code) +
5029 void foo(U* u) {
5030 u->foo();
5032 )", Lang_CXX11);
5033 auto *FromD = FirstDeclMatcher<TypedefNameDecl>().match(FromTU,
5034 typedefNameDecl(hasName("U")));
5035 ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType());
5037 // The imported type should be complete.
5038 auto *ImportedD = cast<TypedefNameDecl>(Import(FromD, Lang_CXX11));
5039 EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType());
5042 TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) {
5043 auto Code =
5045 template<class T>
5046 int f() { return 0; }
5047 template <> int f<int>() { return 4; }
5050 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
5051 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU,
5052 functionDecl(hasName("f"), isExplicitTemplateSpecialization()));
5053 ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1u);
5055 auto *ToD = Import(FromD, Lang_CXX03);
5056 // The template parameter list should exist.
5057 EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1u);
5060 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl>
5061 varTemplateDecl;
5063 const internal::VariadicDynCastAllOfMatcher<
5064 Decl, VarTemplatePartialSpecializationDecl>
5065 varTemplatePartialSpecializationDecl;
5067 TEST_P(ASTImporterOptionSpecificTestBase,
5068 FunctionTemplateParameterDeclContext) {
5069 constexpr auto Code =
5071 template<class T>
5072 void f() {};
5075 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
5077 auto *FromD = FirstDeclMatcher<FunctionTemplateDecl>().match(
5078 FromTU, functionTemplateDecl(hasName("f")));
5080 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(),
5081 FromD->getTemplatedDecl());
5083 auto *ToD = Import(FromD, Lang_CXX11);
5084 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(),
5085 ToD->getTemplatedDecl());
5086 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5087 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0)));
5090 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateParameterDeclContext) {
5091 constexpr auto Code =
5093 template<class T1, class T2>
5094 struct S {};
5095 template<class T2>
5096 struct S<int, T2> {};
5099 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
5101 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
5102 FromTU, classTemplateDecl(hasName("S")));
5103 auto *FromDPart =
5104 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
5105 FromTU, classTemplatePartialSpecializationDecl(hasName("S")));
5107 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(),
5108 FromD->getTemplatedDecl());
5109 ASSERT_EQ(FromDPart->getTemplateParameters()->getParam(0)->getDeclContext(),
5110 FromDPart);
5112 auto *ToD = Import(FromD, Lang_CXX11);
5113 auto *ToDPart = Import(FromDPart, Lang_CXX11);
5115 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(),
5116 ToD->getTemplatedDecl());
5117 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5118 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0)));
5120 EXPECT_EQ(ToDPart->getTemplateParameters()->getParam(0)->getDeclContext(),
5121 ToDPart);
5122 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5123 ToDPart, ToDPart->getTemplateParameters()->getParam(0)));
5126 TEST_P(ASTImporterOptionSpecificTestBase,
5127 CXXDeductionGuideTemplateParameterDeclContext) {
5128 Decl *FromTU = getTuDecl(
5130 template <typename T> struct A {
5131 A(T);
5133 A a{(int)0};
5135 Lang_CXX17, "input.cc");
5136 // clang-format off
5138 |-ClassTemplateDecl 0x1fe5000 <input.cc:2:7, line:4:7> line:2:36 A
5139 | |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
5140 | |-CXXRecordDecl 0x1fe4f70 <col:29, line:4:7> line:2:36 struct A definition
5142 |-FunctionTemplateDecl 0x1fe5860 <line:2:7, line:3:12> col:9 implicit <deduction guide for A>
5143 | |-TemplateTypeParmDecl 0x1fe4eb0 <line:2:17, col:26> col:26 referenced typename depth 0 index 0 T
5144 | |-CXXDeductionGuideDecl 0x1fe57a8 <line:3:9, col:12> col:9 implicit <deduction guide for A> 'auto (T) -> A<T>'
5145 | | `-ParmVarDecl 0x1fe56b0 <col:11> col:12 'T'
5146 | `-CXXDeductionGuideDecl 0x20515d8 <col:9, col:12> col:9 implicit used <deduction guide for A> 'auto (int) -> A<int>'
5147 | |-TemplateArgument type 'int'
5148 | | `-BuiltinType 0x20587e0 'int'
5149 | `-ParmVarDecl 0x2051388 <col:11> col:12 'int'
5150 `-FunctionTemplateDecl 0x1fe5a78 <line:2:7, col:36> col:36 implicit <deduction guide for A>
5151 |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
5152 `-CXXDeductionGuideDecl 0x1fe59c0 <col:36> col:36 implicit <deduction guide for A> 'auto (A<T>) -> A<T>'
5153 `-ParmVarDecl 0x1fe5958 <col:36> col:36 'A<T>'
5155 // clang-format on
5156 auto *FromD1 = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
5157 FromTU, cxxDeductionGuideDecl());
5158 auto *FromD2 = LastDeclMatcher<CXXDeductionGuideDecl>().match(
5159 FromTU, cxxDeductionGuideDecl());
5161 NamedDecl *P1 =
5162 FromD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5164 NamedDecl *P2 =
5165 FromD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5167 DeclContext *DC = P1->getDeclContext();
5169 ASSERT_EQ(P1, P2);
5170 ASSERT_TRUE(DC == FromD1 || DC == FromD2);
5172 auto *ToD1 = Import(FromD1, Lang_CXX17);
5173 auto *ToD2 = Import(FromD2, Lang_CXX17);
5174 ASSERT_TRUE(ToD1 && ToD2);
5176 P1 = ToD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5178 P2 = ToD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5180 DC = P1->getDeclContext();
5182 EXPECT_EQ(P1, P2);
5183 EXPECT_TRUE(DC == ToD1 || DC == ToD2);
5185 ASTImporterLookupTable *Tbl = SharedStatePtr->getLookupTable();
5186 if (Tbl->contains(ToD1, P1)) {
5187 EXPECT_FALSE(Tbl->contains(ToD2, P1));
5188 } else {
5189 EXPECT_TRUE(Tbl->contains(ToD2, P1));
5193 TEST_P(ASTImporterOptionSpecificTestBase, RecordVarTemplateDecl) {
5194 Decl *ToTU = getToTuDecl(
5196 template <class T>
5197 class A {
5198 public:
5199 template <class U>
5200 static constexpr bool X = true;
5203 Lang_CXX14);
5205 auto *ToTUX = FirstDeclMatcher<VarTemplateDecl>().match(
5206 ToTU, varTemplateDecl(hasName("X")));
5207 Decl *FromTU = getTuDecl(
5209 template <class T>
5210 class A {
5211 public:
5212 template <class U>
5213 static constexpr bool X = true;
5216 Lang_CXX14, "input1.cc");
5217 auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match(
5218 FromTU, varTemplateDecl(hasName("X")));
5219 auto *ToX = Import(FromX, Lang_CXX11);
5220 EXPECT_TRUE(ToX);
5221 EXPECT_EQ(ToTUX, ToX);
5224 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclConflict) {
5225 getToTuDecl(
5227 template <class U>
5228 constexpr int X = 1;
5230 Lang_CXX14);
5232 Decl *FromTU = getTuDecl(
5234 template <class U>
5235 constexpr int X = 2;
5237 Lang_CXX14, "input1.cc");
5238 auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match(
5239 FromTU, varTemplateDecl(hasName("X")));
5240 auto *ToX = Import(FromX, Lang_CXX11);
5241 // FIXME: This import should fail.
5242 EXPECT_TRUE(ToX);
5245 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateStaticDefinition) {
5246 Decl *ToTU = getToTuDecl(
5248 struct A {
5249 template <class U>
5250 static int X;
5253 Lang_CXX14);
5254 auto *ToX = FirstDeclMatcher<VarTemplateDecl>().match(
5255 ToTU, varTemplateDecl(hasName("X")));
5256 ASSERT_FALSE(ToX->isThisDeclarationADefinition());
5258 Decl *FromTU = getTuDecl(
5260 struct A {
5261 template <class U>
5262 static int X;
5264 template <class U>
5265 int A::X = 2;
5267 Lang_CXX14, "input1.cc");
5268 auto *FromXDef = LastDeclMatcher<VarTemplateDecl>().match(
5269 FromTU, varTemplateDecl(hasName("X")));
5270 ASSERT_TRUE(FromXDef->isThisDeclarationADefinition());
5271 auto *ToXDef = Import(FromXDef, Lang_CXX14);
5272 EXPECT_TRUE(ToXDef);
5273 EXPECT_TRUE(ToXDef->isThisDeclarationADefinition());
5274 EXPECT_EQ(ToXDef->getPreviousDecl(), ToX);
5277 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateSpecializationDeclValue) {
5278 Decl *ToTU = getToTuDecl(
5280 template <class U>
5281 constexpr int X = U::Value;
5282 struct A { static constexpr int Value = 1; };
5283 constexpr int Y = X<A>;
5285 Lang_CXX14);
5287 auto *ToTUX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match(
5288 ToTU, varTemplateSpecializationDecl(hasName("X")));
5289 Decl *FromTU = getTuDecl(
5291 template <class U>
5292 constexpr int X = U::Value;
5293 struct A { static constexpr int Value = 1; };
5294 constexpr int Y = X<A>;
5296 Lang_CXX14, "input1.cc");
5297 auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match(
5298 FromTU, varTemplateSpecializationDecl(hasName("X")));
5299 auto *ToX = Import(FromX, Lang_CXX14);
5300 EXPECT_TRUE(ToX);
5301 EXPECT_EQ(ToTUX, ToX);
5304 TEST_P(ASTImporterOptionSpecificTestBase,
5305 VarTemplateSpecializationDeclValueConflict) {
5306 getToTuDecl(
5308 template <class U>
5309 constexpr int X = U::Value;
5310 struct A { static constexpr int Value = 1; };
5311 constexpr int Y = X<A>;
5313 Lang_CXX14);
5315 Decl *FromTU = getTuDecl(
5317 template <class U>
5318 constexpr int X = U::Value;
5319 struct A { static constexpr int Value = 2; };
5320 constexpr int Y = X<A>;
5322 Lang_CXX14, "input1.cc");
5323 auto *FromX = FirstDeclMatcher<VarTemplateSpecializationDecl>().match(
5324 FromTU, varTemplateSpecializationDecl(hasName("X")));
5325 auto *ToX = Import(FromX, Lang_CXX14);
5326 EXPECT_FALSE(ToX);
5329 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclInlineWithCXX17) {
5330 Decl *FromTU = getTuDecl(
5332 struct S {
5333 template <unsigned> static constexpr bool X = true;
5336 Lang_CXX17, "input1.cc");
5337 Decl *FromTU2 = getTuDecl(
5339 struct S {
5340 template <unsigned> static constexpr bool X = true;
5341 template <typename T> void get() { X<sizeof(T)>; }
5343 template <typename U> U qvariant_cast(const S &v) { return v.get; }
5345 Lang_CXX17, "input2.cc");
5346 auto *FromX = FirstDeclMatcher<VarTemplateDecl>().match(
5347 FromTU, varTemplateDecl(hasName("X")));
5348 auto *ToX = Import(FromX, Lang_CXX17);
5349 ASSERT_TRUE(ToX);
5350 auto *FromX2 = FirstDeclMatcher<VarTemplateDecl>().match(
5351 FromTU2, varTemplateDecl(hasName("X")));
5352 auto *ToX2 = Import(FromX2, Lang_CXX17);
5353 EXPECT_TRUE(ToX2);
5354 EXPECT_EQ(ToX, ToX2);
5357 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) {
5358 constexpr auto Code =
5360 template<class T1, class T2>
5361 int X1;
5362 template<class T2>
5363 int X1<int, T2>;
5365 namespace Ns {
5366 template<class T1, class T2>
5367 int X2;
5368 template<class T2>
5369 int X2<int, T2>;
5373 Decl *FromTU = getTuDecl(Code, Lang_CXX14);
5375 auto *FromD1 = FirstDeclMatcher<VarTemplateDecl>().match(
5376 FromTU, varTemplateDecl(hasName("X1")));
5377 auto *FromD1Part =
5378 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match(
5379 FromTU, varTemplatePartialSpecializationDecl(hasName("X1")));
5380 auto *FromD2 = FirstDeclMatcher<VarTemplateDecl>().match(
5381 FromTU, varTemplateDecl(hasName("X2")));
5382 auto *FromD2Part =
5383 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match(
5384 FromTU, varTemplatePartialSpecializationDecl(hasName("X2")));
5386 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5387 FromD1->getDeclContext());
5388 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5389 FromD2->getDeclContext());
5391 ASSERT_EQ(FromD1Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5392 FromD1Part->getDeclContext());
5393 // FIXME: VarTemplatePartialSpecializationDecl does not update ("adopt")
5394 // template parameter decl context
5395 // ASSERT_EQ(FromD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5396 // FromD2Part->getDeclContext());
5398 auto *ToD1 = Import(FromD1, Lang_CXX14);
5399 auto *ToD2 = Import(FromD2, Lang_CXX14);
5401 auto *ToD1Part = Import(FromD1Part, Lang_CXX14);
5402 auto *ToD2Part = Import(FromD2Part, Lang_CXX14);
5404 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5405 ToD1->getDeclContext());
5406 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5407 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0)));
5408 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5409 ToD2->getDeclContext());
5410 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5411 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0)));
5413 EXPECT_EQ(ToD1Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5414 ToD1Part->getDeclContext());
5415 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5416 ToD1Part->getDeclContext(),
5417 ToD1Part->getTemplateParameters()->getParam(0)));
5418 // EXPECT_EQ(ToD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5419 // ToD2Part->getDeclContext());
5420 // EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5421 // ToD2Part->getDeclContext(),
5422 // ToD2Part->getTemplateParameters()->getParam(0)));
5423 (void)ToD2Part;
5426 TEST_P(ASTImporterOptionSpecificTestBase,
5427 TypeAliasTemplateParameterDeclContext) {
5428 constexpr auto Code =
5430 template<class T1, class T2>
5431 struct S {};
5432 template<class T> using S1 = S<T, int>;
5433 namespace Ns {
5434 template<class T> using S2 = S<T, int>;
5438 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
5440 auto *FromD1 = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
5441 FromTU, typeAliasTemplateDecl(hasName("S1")));
5442 auto *FromD2 = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
5443 FromTU, typeAliasTemplateDecl(hasName("S2")));
5445 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5446 FromD1->getDeclContext());
5447 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5448 FromD2->getDeclContext());
5450 auto *ToD1 = Import(FromD1, Lang_CXX11);
5451 auto *ToD2 = Import(FromD2, Lang_CXX11);
5453 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(),
5454 ToD1->getDeclContext());
5455 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5456 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0)));
5457 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(),
5458 ToD2->getDeclContext());
5459 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5460 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0)));
5463 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmType) {
5464 constexpr auto Code = R"(
5465 template <class A1, class... A2> struct A {
5466 using B = A1(A2...);
5468 template struct A<void, char, float, int, short>;
5470 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp");
5471 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5472 FromTU, classTemplateSpecializationDecl());
5474 auto testType = [&](ASTContext &Ctx, const char *Name,
5475 std::optional<unsigned> PackIndex) {
5476 const auto *Subst = selectFirst<SubstTemplateTypeParmType>(
5477 "sttp", match(substTemplateTypeParmType(
5478 hasReplacementType(hasCanonicalType(asString(Name))))
5479 .bind("sttp"),
5480 Ctx));
5481 const char *ExpectedTemplateParamName = PackIndex ? "A2" : "A1";
5482 ASSERT_TRUE(Subst);
5483 ASSERT_EQ(Subst->getReplacedParameter()->getIdentifier()->getName(),
5484 ExpectedTemplateParamName);
5485 ASSERT_EQ(Subst->getPackIndex(), PackIndex);
5487 auto tests = [&](ASTContext &Ctx) {
5488 testType(Ctx, "void", std::nullopt);
5489 testType(Ctx, "char", 3);
5490 testType(Ctx, "float", 2);
5491 testType(Ctx, "int", 1);
5492 testType(Ctx, "short", 0);
5495 tests(FromTU->getASTContext());
5497 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11);
5498 tests(ToClass->getASTContext());
5501 const AstTypeMatcher<SubstTemplateTypeParmPackType>
5502 substTemplateTypeParmPackType;
5504 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmPackType) {
5505 constexpr auto Code = R"(
5506 template<typename ...T> struct D {
5507 template<typename... U> using B = int(int (*...p)(T, U));
5508 template<typename U1, typename U2> D(B<U1, U2>*);
5510 int f(int(int, int), int(int, int));
5512 using asd = D<float, double, float>::B<int, long, int>;
5514 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp");
5515 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5516 FromTU, classTemplateSpecializationDecl());
5519 ASTContext &FromCtx = FromTU->getASTContext();
5520 const auto *FromSubstPack = selectFirst<SubstTemplateTypeParmPackType>(
5521 "pack", match(substTemplateTypeParmPackType().bind("pack"), FromCtx));
5523 ASSERT_TRUE(FromSubstPack);
5524 ASSERT_EQ(FromSubstPack->getIdentifier()->getName(), "T");
5525 ArrayRef<TemplateArgument> FromArgPack =
5526 FromSubstPack->getArgumentPack().pack_elements();
5527 ASSERT_EQ(FromArgPack.size(), 3u);
5528 ASSERT_EQ(FromArgPack[0].getAsType(), FromCtx.FloatTy);
5529 ASSERT_EQ(FromArgPack[1].getAsType(), FromCtx.DoubleTy);
5530 ASSERT_EQ(FromArgPack[2].getAsType(), FromCtx.FloatTy);
5533 // Let's do the import.
5534 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11);
5535 ASTContext &ToCtx = ToClass->getASTContext();
5537 const auto *ToSubstPack = selectFirst<SubstTemplateTypeParmPackType>(
5538 "pack", match(substTemplateTypeParmPackType().bind("pack"), ToCtx));
5540 // Check if it meets the requirements.
5541 ASSERT_TRUE(ToSubstPack);
5542 ASSERT_EQ(ToSubstPack->getIdentifier()->getName(), "T");
5543 ArrayRef<TemplateArgument> ToArgPack =
5544 ToSubstPack->getArgumentPack().pack_elements();
5545 ASSERT_EQ(ToArgPack.size(), 3u);
5546 ASSERT_EQ(ToArgPack[0].getAsType(), ToCtx.FloatTy);
5547 ASSERT_EQ(ToArgPack[1].getAsType(), ToCtx.DoubleTy);
5548 ASSERT_EQ(ToArgPack[2].getAsType(), ToCtx.FloatTy);
5552 struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {};
5554 TEST_P(ASTImporterLookupTableTest, OneDecl) {
5555 auto *ToTU = getToTuDecl("int a;", Lang_CXX03);
5556 auto *D = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("a")));
5557 ASTImporterLookupTable LT(*ToTU);
5558 auto Res = LT.lookup(ToTU, D->getDeclName());
5559 ASSERT_EQ(Res.size(), 1u);
5560 EXPECT_EQ(*Res.begin(), D);
5563 static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) {
5564 for (Decl *D : DC->decls()) {
5565 if (auto *ND = dyn_cast<NamedDecl>(D))
5566 if (ND->getDeclName() == Name)
5567 return ND;
5569 return nullptr;
5572 TEST_P(ASTImporterLookupTableTest,
5573 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) {
5574 auto *Code = R"(
5575 template <class T>
5576 struct X {
5577 friend void foo(){}
5580 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
5581 auto *X = FirstDeclMatcher<ClassTemplateDecl>().match(
5582 ToTU, classTemplateDecl(hasName("X")));
5583 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
5584 ToTU, functionDecl(hasName("foo")));
5585 DeclContext *FooDC = Foo->getDeclContext();
5586 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
5587 ASSERT_EQ(cast<Decl>(FooLexicalDC), X->getTemplatedDecl());
5588 ASSERT_EQ(cast<Decl>(FooDC), ToTU);
5589 DeclarationName FooName = Foo->getDeclName();
5591 // Cannot find in the LookupTable of its DC (TUDecl)
5592 SmallVector<NamedDecl *, 2> FoundDecls;
5593 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5594 EXPECT_EQ(FoundDecls.size(), 0u);
5596 // Cannot find in the LookupTable of its LexicalDC (X)
5597 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5598 EXPECT_EQ(FoundDecls.size(), 0u);
5600 // Can't find in the list of Decls of the DC.
5601 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
5603 // Can't find in the list of Decls of the LexicalDC
5604 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr);
5606 // ASTImporter specific lookup finds it.
5607 ASTImporterLookupTable LT(*ToTU);
5608 auto Res = LT.lookup(FooDC, Foo->getDeclName());
5609 ASSERT_EQ(Res.size(), 1u);
5610 EXPECT_EQ(*Res.begin(), Foo);
5613 TEST_P(ASTImporterLookupTableTest,
5614 FwdDeclStructShouldBeFoundByImporterSpecificLookup) {
5615 TranslationUnitDecl *ToTU =
5616 getToTuDecl("struct A { struct Foo *p; };", Lang_C99);
5617 auto *Foo =
5618 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("Foo")));
5619 auto *A =
5620 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
5621 DeclContext *FooDC = Foo->getDeclContext();
5622 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
5623 ASSERT_EQ(cast<Decl>(FooLexicalDC), A);
5624 ASSERT_EQ(cast<Decl>(FooDC), ToTU);
5625 DeclarationName FooName = Foo->getDeclName();
5627 // Cannot find in the LookupTable of its DC (TUDecl).
5628 SmallVector<NamedDecl *, 2> FoundDecls;
5629 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5630 EXPECT_EQ(FoundDecls.size(), 0u);
5632 // Finds via linear search of its LexicalDC (A).
5633 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
5634 EXPECT_EQ(FoundDecls.size(), 1u);
5636 // Can't find in the list of Decls of the DC.
5637 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
5639 // Can find in the list of Decls of the LexicalDC.
5640 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo);
5642 // ASTImporter specific lookup finds it.
5643 ASTImporterLookupTable LT(*ToTU);
5644 auto Res = LT.lookup(FooDC, Foo->getDeclName());
5645 ASSERT_EQ(Res.size(), 1u);
5646 EXPECT_EQ(*Res.begin(), Foo);
5649 TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) {
5650 TranslationUnitDecl *ToTU =
5651 getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99);
5652 DeclarationName VName = FirstDeclMatcher<VarDecl>()
5653 .match(ToTU, varDecl(hasName("V")))
5654 ->getDeclName();
5655 auto *A =
5656 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
5657 auto *B =
5658 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("B")));
5660 ASTImporterLookupTable LT(*ToTU);
5662 auto Res = LT.lookup(cast<DeclContext>(A), VName);
5663 ASSERT_EQ(Res.size(), 1u);
5664 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
5665 ToTU, fieldDecl(hasName("V"),
5666 hasParent(recordDecl(hasName("A"))))));
5667 Res = LT.lookup(cast<DeclContext>(B), VName);
5668 ASSERT_EQ(Res.size(), 1u);
5669 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
5670 ToTU, fieldDecl(hasName("V"),
5671 hasParent(recordDecl(hasName("B"))))));
5672 Res = LT.lookup(ToTU, VName);
5673 ASSERT_EQ(Res.size(), 1u);
5674 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<VarDecl>().match(
5675 ToTU, varDecl(hasName("V"),
5676 hasParent(translationUnitDecl()))));
5679 TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) {
5680 TranslationUnitDecl *ToTU = getToTuDecl(
5682 void foo();
5683 void foo(int);
5684 void foo(int, int);
5686 Lang_CXX03);
5688 ASTImporterLookupTable LT(*ToTU);
5689 auto *F0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
5690 auto *F2 = LastDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
5691 DeclarationName Name = F0->getDeclName();
5692 auto Res = LT.lookup(ToTU, Name);
5693 EXPECT_EQ(Res.size(), 3u);
5694 EXPECT_EQ(Res.count(F0), 1u);
5695 EXPECT_EQ(Res.count(F2), 1u);
5698 TEST_P(ASTImporterLookupTableTest,
5699 DifferentOperatorsShouldHaveDifferentResultSet) {
5700 TranslationUnitDecl *ToTU = getToTuDecl(
5702 struct X{};
5703 void operator+(X, X);
5704 void operator-(X, X);
5706 Lang_CXX03);
5708 ASTImporterLookupTable LT(*ToTU);
5709 auto *FPlus = FirstDeclMatcher<FunctionDecl>().match(
5710 ToTU, functionDecl(hasOverloadedOperatorName("+")));
5711 auto *FMinus = FirstDeclMatcher<FunctionDecl>().match(
5712 ToTU, functionDecl(hasOverloadedOperatorName("-")));
5713 DeclarationName NamePlus = FPlus->getDeclName();
5714 auto ResPlus = LT.lookup(ToTU, NamePlus);
5715 EXPECT_EQ(ResPlus.size(), 1u);
5716 EXPECT_EQ(ResPlus.count(FPlus), 1u);
5717 EXPECT_EQ(ResPlus.count(FMinus), 0u);
5718 DeclarationName NameMinus = FMinus->getDeclName();
5719 auto ResMinus = LT.lookup(ToTU, NameMinus);
5720 EXPECT_EQ(ResMinus.size(), 1u);
5721 EXPECT_EQ(ResMinus.count(FMinus), 1u);
5722 EXPECT_EQ(ResMinus.count(FPlus), 0u);
5723 EXPECT_NE(*ResMinus.begin(), *ResPlus.begin());
5726 TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) {
5727 TranslationUnitDecl *ToTU = getToTuDecl(
5729 struct X {};
5730 void operator+(X, X);
5732 Lang_CXX03);
5733 auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match(
5734 ToTU, functionDecl(hasOverloadedOperatorName("+")));
5736 Decl *FromTU = getTuDecl(
5738 struct X {};
5739 void operator+(X, X);
5741 Lang_CXX03);
5742 auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match(
5743 FromTU, functionDecl(hasOverloadedOperatorName("+")));
5745 // FromPlus have a different TU, thus its DeclarationName is different too.
5746 ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName());
5748 ASTImporterLookupTable LT(*ToTU);
5749 auto Res = LT.lookup(ToTU, ToPlus->getDeclName());
5750 ASSERT_EQ(Res.size(), 1u);
5751 EXPECT_EQ(*Res.begin(), ToPlus);
5753 // FromPlus have a different TU, thus its DeclarationName is different too.
5754 Res = LT.lookup(ToTU, FromPlus->getDeclName());
5755 ASSERT_EQ(Res.size(), 0u);
5758 TEST_P(ASTImporterLookupTableTest,
5759 LookupFindsFwdFriendClassDeclWithElaboratedType) {
5760 TranslationUnitDecl *ToTU = getToTuDecl(
5762 class Y { friend class F; };
5764 Lang_CXX03);
5766 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5767 // So we must dig up the underlying CXXRecordDecl.
5768 ASTImporterLookupTable LT(*ToTU);
5769 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5770 const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
5771 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(
5772 ToTU, cxxRecordDecl(hasName("Y")));
5774 DeclarationName Name = RD->getDeclName();
5775 auto Res = LT.lookup(ToTU, Name);
5776 EXPECT_EQ(Res.size(), 1u);
5777 EXPECT_EQ(*Res.begin(), RD);
5779 Res = LT.lookup(Y, Name);
5780 EXPECT_EQ(Res.size(), 0u);
5783 TEST_P(ASTImporterLookupTableTest,
5784 LookupFindsFwdFriendClassDeclWithUnelaboratedType) {
5785 TranslationUnitDecl *ToTU = getToTuDecl(
5787 class F;
5788 class Y { friend F; };
5790 Lang_CXX11);
5792 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5793 // So we must dig up the underlying CXXRecordDecl.
5794 ASTImporterLookupTable LT(*ToTU);
5795 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5796 const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
5797 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, cxxRecordDecl(hasName("Y")));
5799 DeclarationName Name = RD->getDeclName();
5800 auto Res = LT.lookup(ToTU, Name);
5801 EXPECT_EQ(Res.size(), 1u);
5802 EXPECT_EQ(*Res.begin(), RD);
5804 Res = LT.lookup(Y, Name);
5805 EXPECT_EQ(Res.size(), 0u);
5808 TEST_P(ASTImporterLookupTableTest,
5809 LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert) {
5810 TranslationUnitDecl *ToTU = getToTuDecl(
5812 class F;
5813 using alias_of_f = F;
5814 class Y { friend alias_of_f; };
5816 Lang_CXX11);
5818 // ASTImporterLookupTable constructor handles using declarations correctly,
5819 // no assert is expected.
5820 ASTImporterLookupTable LT(*ToTU);
5822 auto *Alias = FirstDeclMatcher<TypeAliasDecl>().match(
5823 ToTU, typeAliasDecl(hasName("alias_of_f")));
5824 DeclarationName Name = Alias->getDeclName();
5825 auto Res = LT.lookup(ToTU, Name);
5826 EXPECT_EQ(Res.count(Alias), 1u);
5829 TEST_P(ASTImporterLookupTableTest,
5830 LookupFindsFriendClassDeclWithUsingTypeDoesNotAssert) {
5831 TranslationUnitDecl *ToTU = getToTuDecl(
5833 namespace a {
5834 namespace b { class InnerClass; }
5835 using b::InnerClass;
5837 class B {
5838 friend a::InnerClass;
5841 Lang_CXX11);
5843 // ASTImporterLookupTable constructor handles friend with using-type without
5844 // asserts.
5845 ASTImporterLookupTable LT(*ToTU);
5847 auto *Using = FirstDeclMatcher<UsingDecl>().match(
5848 ToTU, usingDecl(hasName("InnerClass")));
5849 DeclarationName Name = Using->getDeclName();
5850 auto Res = LT.lookup(ToTU, Name);
5851 EXPECT_EQ(Res.size(), 0u);
5852 auto *NsA = FirstDeclMatcher<NamespaceDecl>().match(
5853 ToTU, namespaceDecl(hasName("a")));
5854 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
5855 ToTU, cxxRecordDecl(hasName("B")));
5856 auto Res1 = LT.lookup(NsA, Name);
5857 EXPECT_EQ(Res1.count(Using), 1u);
5858 auto Res2 = LT.lookup(RecordB, Name);
5859 EXPECT_EQ(Res2.size(), 0u);
5862 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) {
5863 TranslationUnitDecl *ToTU = getToTuDecl(
5865 class Y { template <class T> friend class F; };
5867 Lang_CXX03);
5869 ASTImporterLookupTable LT(*ToTU);
5870 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5871 ToTU, classTemplateDecl(hasName("F")));
5872 DeclarationName Name = F->getDeclName();
5873 auto Res = LT.lookup(ToTU, Name);
5874 EXPECT_EQ(Res.size(), 2u);
5875 EXPECT_EQ(Res.count(F), 1u);
5876 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5879 TEST_P(ASTImporterLookupTableTest, DependentFriendClass) {
5880 TranslationUnitDecl *ToTU = getToTuDecl(
5882 template <typename T>
5883 class F;
5885 template <typename T>
5886 class Y {
5887 friend class F<T>;
5890 Lang_CXX03);
5892 ASTImporterLookupTable LT(*ToTU);
5893 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5894 ToTU, classTemplateDecl(hasName("F")));
5895 DeclarationName Name = F->getDeclName();
5896 auto Res = LT.lookup(ToTU, Name);
5897 EXPECT_EQ(Res.size(), 2u);
5898 EXPECT_EQ(Res.count(F), 1u);
5899 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5902 TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) {
5903 TranslationUnitDecl *ToTU = getToTuDecl(
5905 template <typename T>
5906 class F;
5908 class Y {
5909 friend class F<int>;
5912 Lang_CXX03);
5914 ASTImporterLookupTable LT(*ToTU);
5915 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5916 ToTU, classTemplateDecl(hasName("F")));
5917 DeclarationName Name = F->getDeclName();
5918 auto Res = LT.lookup(ToTU, Name);
5919 ASSERT_EQ(Res.size(), 3u);
5920 EXPECT_EQ(Res.count(F), 1u);
5921 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5922 EXPECT_EQ(Res.count(*F->spec_begin()), 1u);
5925 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) {
5926 TranslationUnitDecl *ToTU = getToTuDecl(
5928 class Y { friend void F(); };
5930 Lang_CXX03);
5932 ASTImporterLookupTable LT(*ToTU);
5933 auto *F =
5934 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("F")));
5935 DeclarationName Name = F->getDeclName();
5936 auto Res = LT.lookup(ToTU, Name);
5937 EXPECT_EQ(Res.size(), 1u);
5938 EXPECT_EQ(*Res.begin(), F);
5941 TEST_P(ASTImporterLookupTableTest,
5942 LookupFindsDeclsInClassTemplateSpecialization) {
5943 TranslationUnitDecl *ToTU = getToTuDecl(
5945 template <typename T>
5946 struct X {
5947 int F;
5949 void foo() {
5950 X<char> xc;
5953 Lang_CXX03);
5955 ASTImporterLookupTable LT(*ToTU);
5957 auto *Template = FirstDeclMatcher<ClassTemplateDecl>().match(
5958 ToTU, classTemplateDecl(hasName("X")));
5959 auto *FieldInTemplate = FirstDeclMatcher<FieldDecl>().match(
5960 ToTU,
5961 fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl())))));
5963 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5964 ToTU, classTemplateSpecializationDecl(hasName("X")));
5965 FieldDecl *FieldInSpec = *Spec->field_begin();
5966 ASSERT_TRUE(FieldInSpec);
5968 DeclarationName Name = FieldInSpec->getDeclName();
5969 auto TemplateDC = cast<DeclContext>(Template->getTemplatedDecl());
5971 SmallVector<NamedDecl *, 2> FoundDecls;
5972 TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
5973 EXPECT_EQ(FoundDecls.size(), 1u);
5974 EXPECT_EQ(FoundDecls[0], FieldInTemplate);
5976 auto Res = LT.lookup(TemplateDC, Name);
5977 ASSERT_EQ(Res.size(), 1u);
5978 EXPECT_EQ(*Res.begin(), FieldInTemplate);
5980 cast<DeclContext>(Spec)->getRedeclContext()->localUncachedLookup(Name,
5981 FoundDecls);
5982 EXPECT_EQ(FoundDecls.size(), 1u);
5983 EXPECT_EQ(FoundDecls[0], FieldInSpec);
5985 Res = LT.lookup(cast<DeclContext>(Spec), Name);
5986 ASSERT_EQ(Res.size(), 1u);
5987 EXPECT_EQ(*Res.begin(), FieldInSpec);
5990 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) {
5991 TranslationUnitDecl *ToTU = getToTuDecl(
5993 class Y { template <class T> friend void F(); };
5995 Lang_CXX03);
5997 ASTImporterLookupTable LT(*ToTU);
5998 auto *F = FirstDeclMatcher<FunctionTemplateDecl>().match(
5999 ToTU, functionTemplateDecl(hasName("F")));
6000 DeclarationName Name = F->getDeclName();
6001 auto Res = LT.lookup(ToTU, Name);
6002 EXPECT_EQ(Res.size(), 2u);
6003 EXPECT_EQ(Res.count(F), 1u);
6004 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
6007 TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) {
6008 TranslationUnitDecl *ToTU = getToTuDecl(
6010 struct X;
6011 struct A {
6012 friend struct X;
6014 struct B {
6015 friend struct X;
6018 Lang_CXX03);
6020 ASTImporterLookupTable LT(*ToTU);
6021 auto *X = FirstDeclMatcher<CXXRecordDecl>().match(
6022 ToTU, cxxRecordDecl(hasName("X")));
6023 auto *FriendD0 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
6024 auto *FriendD1 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
6025 const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0);
6026 const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1);
6027 ASSERT_EQ(RD0, RD1);
6028 ASSERT_EQ(RD1, X);
6030 DeclarationName Name = X->getDeclName();
6031 auto Res = LT.lookup(ToTU, Name);
6032 EXPECT_EQ(Res.size(), 1u);
6033 EXPECT_EQ(*Res.begin(), X);
6036 TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) {
6037 TranslationUnitDecl *ToTU = getToTuDecl(
6039 enum E {
6044 Lang_C99);
6046 ASTImporterLookupTable LT(*ToTU);
6047 auto *E = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(hasName("E")));
6048 auto *A = FirstDeclMatcher<EnumConstantDecl>().match(
6049 ToTU, enumConstantDecl(hasName("A")));
6051 DeclarationName Name = A->getDeclName();
6052 // Redecl context is the TU.
6053 ASSERT_EQ(E->getRedeclContext(), ToTU);
6055 SmallVector<NamedDecl *, 2> FoundDecls;
6056 // Normal lookup finds in the DC.
6057 E->localUncachedLookup(Name, FoundDecls);
6058 EXPECT_EQ(FoundDecls.size(), 1u);
6060 // Normal lookup finds in the Redecl context.
6061 ToTU->localUncachedLookup(Name, FoundDecls);
6062 EXPECT_EQ(FoundDecls.size(), 1u);
6064 // Import specific lookup finds in the DC.
6065 auto Res = LT.lookup(E, Name);
6066 ASSERT_EQ(Res.size(), 1u);
6067 EXPECT_EQ(*Res.begin(), A);
6069 // Import specific lookup finds in the Redecl context.
6070 Res = LT.lookup(ToTU, Name);
6071 ASSERT_EQ(Res.size(), 1u);
6072 EXPECT_EQ(*Res.begin(), A);
6075 TEST_P(ASTImporterLookupTableTest, LookupSearchesInActualNamespaceOnly) {
6076 TranslationUnitDecl *ToTU = getToTuDecl(
6078 namespace N {
6079 int A;
6081 namespace N {
6084 Lang_CXX03);
6085 auto *N1 = FirstDeclMatcher<NamespaceDecl>().match(
6086 ToTU, namespaceDecl(hasName("N")));
6087 auto *N2 =
6088 LastDeclMatcher<NamespaceDecl>().match(ToTU, namespaceDecl(hasName("N")));
6089 auto *A = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("A")));
6090 DeclarationName Name = A->getDeclName();
6092 ASTImporterLookupTable LT(*ToTU);
6093 auto Res = LT.lookup(N1, Name);
6094 ASSERT_EQ(Res.size(), 1u);
6095 EXPECT_EQ(*Res.begin(), A);
6096 EXPECT_TRUE(LT.lookup(N2, Name).empty());
6099 TEST_P(ASTImporterOptionSpecificTestBase,
6100 RedeclChainShouldBeCorrectAmongstNamespaces) {
6101 Decl *FromTU = getTuDecl(
6103 namespace NS {
6104 struct X;
6105 struct Y {
6106 static const int I = 3;
6109 namespace NS {
6110 struct X { // <--- To be imported
6111 void method(int i = Y::I) {}
6112 int f;
6116 Lang_CXX03);
6117 auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match(
6118 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
6119 auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match(
6120 FromTU,
6121 cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit())));
6122 ASSERT_NE(FromFwd, FromDef);
6123 ASSERT_FALSE(FromFwd->isThisDeclarationADefinition());
6124 ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
6125 ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl());
6127 auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX03));
6128 auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX03));
6129 EXPECT_NE(ToFwd, ToDef);
6130 EXPECT_FALSE(ToFwd->isThisDeclarationADefinition());
6131 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
6132 EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl());
6133 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
6134 // We expect no (ODR) warning during the import.
6135 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
6138 struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {};
6140 TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
6141 Decl *ToTU = getToTuDecl(
6143 class X {
6144 template <typename T> friend void foo();
6147 Lang_CXX03);
6148 auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match(
6149 ToTU, functionTemplateDecl(hasName("foo")));
6151 Decl *FromTU = getTuDecl(
6153 template <typename T> void foo();
6155 Lang_CXX03);
6156 auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match(
6157 FromTU, functionTemplateDecl(hasName("foo")));
6158 auto *Imported = Import(FromFoo, Lang_CXX03);
6160 EXPECT_EQ(Imported->getPreviousDecl(), Friend);
6163 TEST_P(ImportFriendFunctionTemplates, ImportFriendFunctionInsideClassTemplate) {
6164 Decl *From, *To;
6165 std::tie(From, To) = getImportedDecl(
6167 template <typename T> struct X {
6168 template <typename U> friend void f();
6171 Lang_CXX03, "", Lang_CXX03, "X");
6173 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(From, friendDecl());
6174 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(To, friendDecl());
6176 EXPECT_TRUE(FromFriend ==
6177 LastDeclMatcher<FriendDecl>().match(From, friendDecl()));
6178 EXPECT_TRUE(ToFriend ==
6179 LastDeclMatcher<FriendDecl>().match(To, friendDecl()));
6181 auto *FromDecl = FromFriend->getFriendDecl();
6182 auto *FromDC = FromFriend->getDeclContext();
6183 auto *FromLexicalDC = FromFriend->getLexicalDeclContext();
6185 EXPECT_TRUE(FromDC->containsDecl(FromFriend));
6186 EXPECT_FALSE(FromDC->containsDecl(FromDecl));
6187 EXPECT_TRUE(FromLexicalDC->containsDecl(FromFriend));
6188 EXPECT_FALSE(FromLexicalDC->containsDecl(FromDecl));
6190 auto *ToDecl = ToFriend->getFriendDecl();
6191 auto *ToDC = ToFriend->getDeclContext();
6192 auto *ToLexicalDC = ToFriend->getLexicalDeclContext();
6194 EXPECT_TRUE(ToDC->containsDecl(ToFriend));
6195 EXPECT_FALSE(ToDC->containsDecl(ToDecl));
6196 EXPECT_TRUE(ToLexicalDC->containsDecl(ToFriend));
6197 EXPECT_FALSE(ToLexicalDC->containsDecl(ToDecl));
6200 struct ASTImporterWithFakeErrors : ASTImporter {
6201 using ASTImporter::ASTImporter;
6202 bool returnWithErrorInTest() override { return true; }
6205 struct ErrorHandlingTest : ASTImporterOptionSpecificTestBase {
6206 ErrorHandlingTest() {
6207 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
6208 ASTContext &FromContext, FileManager &FromFileManager,
6209 bool MinimalImport,
6210 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
6211 return new ASTImporterWithFakeErrors(ToContext, ToFileManager,
6212 FromContext, FromFileManager,
6213 MinimalImport, SharedState);
6216 // In this test we purposely report an error (UnsupportedConstruct) when
6217 // importing the below stmt.
6218 static constexpr auto* ErroneousStmt = R"( asm(""); )";
6221 // Check a case when no new AST node is created in the AST before encountering
6222 // the error.
6223 TEST_P(ErrorHandlingTest, ErrorHappensBeforeCreatingANewNode) {
6224 TranslationUnitDecl *ToTU = getToTuDecl(
6226 template <typename T>
6227 class X {};
6228 template <>
6229 class X<int> { int a; };
6231 Lang_CXX03);
6232 TranslationUnitDecl *FromTU = getTuDecl(
6234 template <typename T>
6235 class X {};
6236 template <>
6237 class X<int> { double b; };
6239 Lang_CXX03);
6240 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
6241 FromTU, classTemplateSpecializationDecl(hasName("X")));
6242 ClassTemplateSpecializationDecl *ImportedSpec = Import(FromSpec, Lang_CXX03);
6243 EXPECT_FALSE(ImportedSpec);
6245 // The original Decl is kept, no new decl is created.
6246 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(
6247 ToTU, classTemplateSpecializationDecl(hasName("X"))),
6248 1u);
6250 // But an error is set to the counterpart in the "from" context.
6251 ASTImporter *Importer = findFromTU(FromSpec)->Importer.get();
6252 std::optional<ASTImportError> OptErr =
6253 Importer->getImportDeclErrorIfAny(FromSpec);
6254 ASSERT_TRUE(OptErr);
6255 EXPECT_EQ(OptErr->Error, ASTImportError::NameConflict);
6258 // Check a case when a new AST node is created but not linked to the AST before
6259 // encountering the error.
6260 TEST_P(ErrorHandlingTest,
6261 ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST) {
6262 TranslationUnitDecl *FromTU = getTuDecl(
6263 std::string("void foo() { ") + ErroneousStmt + " }", Lang_CXX03);
6264 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
6265 FromTU, functionDecl(hasName("foo")));
6267 FunctionDecl *ImportedFoo = Import(FromFoo, Lang_CXX03);
6268 EXPECT_FALSE(ImportedFoo);
6270 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
6271 // Created, but not linked.
6272 EXPECT_EQ(
6273 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("foo"))),
6274 0u);
6276 ASTImporter *Importer = findFromTU(FromFoo)->Importer.get();
6277 std::optional<ASTImportError> OptErr =
6278 Importer->getImportDeclErrorIfAny(FromFoo);
6279 ASSERT_TRUE(OptErr);
6280 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6283 // Check a case when a new AST node is created and linked to the AST before
6284 // encountering the error. The error is set for the counterpart of the nodes in
6285 // the "from" context.
6286 TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) {
6287 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6288 void f();
6289 void f() { )") + ErroneousStmt + R"( }
6291 Lang_CXX03);
6292 auto *FromProto = FirstDeclMatcher<FunctionDecl>().match(
6293 FromTU, functionDecl(hasName("f")));
6294 auto *FromDef =
6295 LastDeclMatcher<FunctionDecl>().match(FromTU, functionDecl(hasName("f")));
6296 FunctionDecl *ImportedProto = Import(FromProto, Lang_CXX03);
6297 EXPECT_FALSE(ImportedProto); // Could not import.
6298 // However, we created two nodes in the AST. 1) the fwd decl 2) the
6299 // definition. The definition is not added to its DC, but the fwd decl is
6300 // there.
6301 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
6302 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
6303 1u);
6304 // Match the fwd decl.
6305 auto *ToProto =
6306 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("f")));
6307 EXPECT_TRUE(ToProto);
6308 // An error is set to the counterpart in the "from" context both for the fwd
6309 // decl and the definition.
6310 ASTImporter *Importer = findFromTU(FromProto)->Importer.get();
6311 std::optional<ASTImportError> OptErr =
6312 Importer->getImportDeclErrorIfAny(FromProto);
6313 ASSERT_TRUE(OptErr);
6314 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6315 OptErr = Importer->getImportDeclErrorIfAny(FromDef);
6316 ASSERT_TRUE(OptErr);
6317 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6320 // An error should be set for a class if we cannot import one member.
6321 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) {
6322 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6323 class X {
6324 void f() { )") + ErroneousStmt + R"( } // This member has the error
6325 // during import.
6326 void ok(); // The error should not prevent importing this.
6327 }; // An error will be set for X too.
6329 Lang_CXX03);
6330 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6331 FromTU, cxxRecordDecl(hasName("X")));
6332 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
6334 // An error is set for X.
6335 EXPECT_FALSE(ImportedX);
6336 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6337 std::optional<ASTImportError> OptErr =
6338 Importer->getImportDeclErrorIfAny(FromX);
6339 ASSERT_TRUE(OptErr);
6340 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6342 // An error is set for f().
6343 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
6344 FromTU, cxxMethodDecl(hasName("f")));
6345 OptErr = Importer->getImportDeclErrorIfAny(FromF);
6346 ASSERT_TRUE(OptErr);
6347 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6348 // And any subsequent import should fail.
6349 CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03);
6350 EXPECT_FALSE(ImportedF);
6352 // There is an error set for the other member too.
6353 auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match(
6354 FromTU, cxxMethodDecl(hasName("ok")));
6355 OptErr = Importer->getImportDeclErrorIfAny(FromOK);
6356 EXPECT_TRUE(OptErr);
6357 // Cannot import the other member.
6358 CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03);
6359 EXPECT_FALSE(ImportedOK);
6362 // Check that an error propagates to the dependent AST nodes.
6363 // In the below code it means that an error in X should propagate to A.
6364 // And even to F since the containing A is erroneous.
6365 // And to all AST nodes which we visit during the import process which finally
6366 // ends up in a failure (in the error() function).
6367 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) {
6368 Decl *FromTU = getTuDecl(std::string(R"(
6369 namespace NS {
6370 class A {
6371 template <int I> class F {};
6372 class X {
6373 template <int I> friend class F;
6374 void error() { )") +
6375 ErroneousStmt + R"( }
6379 class B {};
6380 } // NS
6382 Lang_CXX03, "input0.cc");
6384 auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match(
6385 FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
6386 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
6387 FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
6388 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match(
6389 FromTU, cxxRecordDecl(hasName("B"), isDefinition()));
6390 auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match(
6391 FromTU, namespaceDecl(hasName("NS")));
6393 // Start by importing the templated CXXRecordDecl of F.
6394 // Import fails for that.
6395 EXPECT_FALSE(Import(FromFRD, Lang_CXX03));
6396 // Import fails for A.
6397 EXPECT_FALSE(Import(FromA, Lang_CXX03));
6398 // But we should be able to import the independent B.
6399 EXPECT_TRUE(Import(FromB, Lang_CXX03));
6400 // And the namespace.
6401 EXPECT_TRUE(Import(FromNS, Lang_CXX03));
6403 // An error is set to the templated CXXRecordDecl of F.
6404 ASTImporter *Importer = findFromTU(FromFRD)->Importer.get();
6405 std::optional<ASTImportError> OptErr =
6406 Importer->getImportDeclErrorIfAny(FromFRD);
6407 EXPECT_TRUE(OptErr);
6409 // An error is set to A.
6410 OptErr = Importer->getImportDeclErrorIfAny(FromA);
6411 EXPECT_TRUE(OptErr);
6413 // There is no error set to B.
6414 OptErr = Importer->getImportDeclErrorIfAny(FromB);
6415 EXPECT_FALSE(OptErr);
6417 // There is no error set to NS.
6418 OptErr = Importer->getImportDeclErrorIfAny(FromNS);
6419 EXPECT_FALSE(OptErr);
6421 // Check some of those decls whose ancestor is X, they all should have an
6422 // error set if we visited them during an import process which finally failed.
6423 // These decls are part of a cycle in an ImportPath.
6424 // There would not be any error set for these decls if we hadn't follow the
6425 // ImportPaths and the cycles.
6426 OptErr = Importer->getImportDeclErrorIfAny(
6427 FirstDeclMatcher<ClassTemplateDecl>().match(
6428 FromTU, classTemplateDecl(hasName("F"))));
6429 // An error is set to the 'F' ClassTemplateDecl.
6430 EXPECT_TRUE(OptErr);
6431 // An error is set to the FriendDecl.
6432 OptErr = Importer->getImportDeclErrorIfAny(
6433 FirstDeclMatcher<FriendDecl>().match(
6434 FromTU, friendDecl()));
6435 EXPECT_TRUE(OptErr);
6436 // An error is set to the implicit class of A.
6437 OptErr =
6438 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
6439 FromTU, cxxRecordDecl(hasName("A"), isImplicit())));
6440 EXPECT_TRUE(OptErr);
6441 // An error is set to the implicit class of X.
6442 OptErr =
6443 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
6444 FromTU, cxxRecordDecl(hasName("X"), isImplicit())));
6445 EXPECT_TRUE(OptErr);
6448 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) {
6449 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6450 namespace X {
6451 void f() { )") + ErroneousStmt + R"( } // This member has the error
6452 // during import.
6453 void ok(); // The error should not prevent importing this.
6454 }; // An error will be set for X too.
6456 Lang_CXX03);
6457 auto *FromX = FirstDeclMatcher<NamespaceDecl>().match(
6458 FromTU, namespaceDecl(hasName("X")));
6459 NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03);
6461 // There is no error set for X.
6462 EXPECT_TRUE(ImportedX);
6463 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6464 std::optional<ASTImportError> OptErr =
6465 Importer->getImportDeclErrorIfAny(FromX);
6466 ASSERT_FALSE(OptErr);
6468 // An error is set for f().
6469 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
6470 FromTU, functionDecl(hasName("f")));
6471 OptErr = Importer->getImportDeclErrorIfAny(FromF);
6472 ASSERT_TRUE(OptErr);
6473 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6474 // And any subsequent import should fail.
6475 FunctionDecl *ImportedF = Import(FromF, Lang_CXX03);
6476 EXPECT_FALSE(ImportedF);
6478 // There is no error set for ok().
6479 auto *FromOK = FirstDeclMatcher<FunctionDecl>().match(
6480 FromTU, functionDecl(hasName("ok")));
6481 OptErr = Importer->getImportDeclErrorIfAny(FromOK);
6482 EXPECT_FALSE(OptErr);
6483 // And we should be able to import.
6484 FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03);
6485 EXPECT_TRUE(ImportedOK);
6488 TEST_P(ErrorHandlingTest, ODRViolationWithinTypedefDecls) {
6489 // Importing `z` should fail - instead of crashing - due to an ODR violation.
6490 // The `bar::e` typedef sets it's DeclContext after the import is done.
6491 // However, if the importation fails, it will be left as a nullptr.
6492 // During the cleanup of the failed import, we should check whether the
6493 // DeclContext is null or not - instead of dereferencing that unconditionally.
6494 constexpr auto ToTUCode = R"(
6495 namespace X {
6496 struct bar {
6497 int odr_violation;
6499 })";
6500 constexpr auto FromTUCode = R"(
6501 namespace X {
6502 enum b {};
6503 struct bar {
6504 typedef b e;
6505 static e d;
6508 int z = X::bar::d;
6510 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
6511 static_cast<void>(ToTU);
6512 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
6513 auto *FromZ =
6514 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("z")));
6515 ASSERT_TRUE(FromZ);
6516 ASSERT_TRUE(FromZ->hasInit());
6518 auto *ImportedZ = Import(FromZ, Lang_CXX11);
6519 EXPECT_FALSE(ImportedZ);
6522 // An error should be set for a class if it had a previous import with an error
6523 // from another TU.
6524 TEST_P(ErrorHandlingTest,
6525 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) {
6526 // We already have a fwd decl.
6527 TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03);
6528 // Then we import a definition.
6530 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6531 class X {
6532 void f() { )") + ErroneousStmt + R"( }
6533 void ok();
6536 Lang_CXX03);
6537 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6538 FromTU, cxxRecordDecl(hasName("X")));
6539 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
6541 // An error is set for X ...
6542 EXPECT_FALSE(ImportedX);
6543 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6544 std::optional<ASTImportError> OptErr =
6545 Importer->getImportDeclErrorIfAny(FromX);
6546 ASSERT_TRUE(OptErr);
6547 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6549 // ... but the node had been created.
6550 auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match(
6551 ToTU, cxxRecordDecl(hasName("X"), isDefinition()));
6552 // An error is set for "ToXDef" in the shared state.
6553 std::optional<ASTImportError> OptErr =
6554 SharedStatePtr->getImportDeclErrorIfAny(ToXDef);
6555 ASSERT_TRUE(OptErr);
6556 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6558 auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match(
6559 ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition())));
6560 // An error is NOT set for the fwd Decl of X in the shared state.
6561 OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd);
6562 ASSERT_FALSE(OptErr);
6564 // Try to import X again but from another TU.
6566 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6567 class X {
6568 void f() { )") + ErroneousStmt + R"( }
6569 void ok();
6572 Lang_CXX03, "input1.cc");
6574 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6575 FromTU, cxxRecordDecl(hasName("X")));
6576 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
6578 // If we did not save the errors for the "to" context then the below checks
6579 // would fail, because the lookup finds the fwd Decl of the existing
6580 // definition in the "to" context. We can reach the existing definition via
6581 // the found fwd Decl. That existing definition is structurally equivalent
6582 // (we check only the fields) with this one we want to import, so we return
6583 // with the existing definition, which is erroneous (one method is missing).
6585 // The import should fail.
6586 EXPECT_FALSE(ImportedX);
6587 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
6588 std::optional<ASTImportError> OptErr =
6589 Importer->getImportDeclErrorIfAny(FromX);
6590 // And an error is set for this new X in the "from" ctx.
6591 ASSERT_TRUE(OptErr);
6592 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6596 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) {
6597 auto MatchFooA =
6598 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A"))));
6599 auto MatchFooB =
6600 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B"))));
6601 auto MatchFooC =
6602 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C"))));
6604 // Provoke import of a method that has overridden methods with import error.
6605 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
6606 struct C;
6607 struct A {
6608 virtual void foo();
6609 void f1(C *);
6611 void A::foo() {
6612 )") + ErroneousStmt + R"(
6614 struct B : public A {
6615 void foo() override;
6617 struct C : public B {
6618 void foo() override;
6621 Lang_CXX11);
6622 auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA);
6623 auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB);
6624 auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC);
6626 EXPECT_FALSE(Import(FromFooA, Lang_CXX11));
6627 ASTImporter *Importer = findFromTU(FromFooA)->Importer.get();
6628 auto CheckError = [&Importer](Decl *FromD) {
6629 std::optional<ASTImportError> OptErr =
6630 Importer->getImportDeclErrorIfAny(FromD);
6631 ASSERT_TRUE(OptErr);
6632 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
6634 CheckError(FromFooA);
6635 EXPECT_FALSE(Import(FromFooB, Lang_CXX11));
6636 CheckError(FromFooB);
6637 EXPECT_FALSE(Import(FromFooC, Lang_CXX11));
6638 CheckError(FromFooC);
6641 TEST_P(ErrorHandlingTest, ODRViolationWithinParmVarDecls) {
6642 // Importing of 'f' and parameter 'P' should cause an ODR error.
6643 // The error happens after the ParmVarDecl for 'P' was already created.
6644 // This is a special case because the ParmVarDecl has a temporary DeclContext.
6645 // Expected is no crash at error handling of ASTImporter.
6646 constexpr auto ToTUCode = R"(
6647 struct X {
6648 char A;
6651 constexpr auto FromTUCode = R"(
6652 struct X {
6653 enum Y { Z };
6655 void f(int P = X::Z);
6657 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
6658 static_cast<void>(ToTU);
6659 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
6660 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
6661 FromTU, functionDecl(hasName("f")));
6662 ASSERT_TRUE(FromF);
6664 auto *ImportedF = Import(FromF, Lang_CXX11);
6665 EXPECT_FALSE(ImportedF);
6668 TEST_P(ErrorHandlingTest, DoNotInheritErrorFromNonDependentChild) {
6669 // Declarations should not inherit an import error from a child object
6670 // if the declaration has no direct dependence to such a child.
6671 // For example a namespace should not get import error if one of the
6672 // declarations inside it fails to import.
6673 // There was a special case in error handling (when "import path circles" are
6674 // encountered) when this property was not held. This case is provoked by the
6675 // following code.
6676 constexpr auto ToTUCode = R"(
6677 namespace ns {
6678 struct Err {
6679 char A;
6683 constexpr auto FromTUCode = R"(
6684 namespace ns {
6685 struct A {
6686 using U = struct Err;
6689 namespace ns {
6690 struct Err {}; // ODR violation
6691 void f(A) {}
6695 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
6696 static_cast<void>(ToTU);
6697 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
6698 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
6699 FromTU, cxxRecordDecl(hasName("A"), hasDefinition()));
6700 ASSERT_TRUE(FromA);
6701 auto *ImportedA = Import(FromA, Lang_CXX11);
6702 // 'A' can not be imported: ODR error at 'Err'
6703 EXPECT_FALSE(ImportedA);
6704 // When import of 'A' failed there was a "saved import path circle" that
6705 // contained namespace 'ns' (A - U - Err - ns - f - A). This should not mean
6706 // that every object in this path fails to import.
6708 Decl *FromNS = FirstDeclMatcher<NamespaceDecl>().match(
6709 FromTU, namespaceDecl(hasName("ns")));
6710 EXPECT_TRUE(FromNS);
6711 auto *ImportedNS = Import(FromNS, Lang_CXX11);
6712 EXPECT_TRUE(ImportedNS);
6715 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) {
6716 Decl *FromTU = getTuDecl(
6718 void f() {
6719 auto L = [](){};
6722 Lang_CXX11, "input0.cc");
6723 auto Pattern = lambdaExpr();
6724 CXXRecordDecl *FromL =
6725 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6727 auto ToL = Import(FromL, Lang_CXX11);
6728 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
6729 unsigned FromLSize =
6730 std::distance(FromL->decls().begin(), FromL->decls().end());
6731 EXPECT_NE(ToLSize, 0u);
6732 EXPECT_EQ(ToLSize, FromLSize);
6733 EXPECT_FALSE(FromL->isDependentLambda());
6736 TEST_P(ASTImporterOptionSpecificTestBase,
6737 ReturnTypeDeclaredInsideOfCXX11LambdaWithoutTrailingReturn) {
6738 Decl *From, *To;
6739 std::tie(From, To) = getImportedDecl(
6741 void foo() {
6742 (void) []() {
6743 struct X {};
6744 return X();
6748 Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only
6749 auto *ToLambda = FirstDeclMatcher<LambdaExpr>().match(To, lambdaExpr());
6750 EXPECT_TRUE(ToLambda);
6753 TEST_P(ASTImporterOptionSpecificTestBase,
6754 ReturnTypeDeclaredInsideOfCXX11LambdaWithTrailingReturn) {
6755 Decl *From, *To;
6756 std::tie(From, To) = getImportedDecl(
6758 void foo() {
6759 (void) [] {
6760 struct X {};
6761 return X();
6765 Lang_CXX11, "", Lang_CXX11, "foo"); // c++11 only
6766 auto *ToLambda = FirstDeclMatcher<LambdaExpr>().match(To, lambdaExpr());
6767 EXPECT_TRUE(ToLambda);
6770 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
6771 Decl *FromTU = getTuDecl(
6773 template <typename F>
6774 void f(F L = [](){}) {}
6776 Lang_CXX11, "input0.cc");
6777 auto Pattern = lambdaExpr();
6778 CXXRecordDecl *FromL =
6779 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6781 auto ToL = Import(FromL, Lang_CXX11);
6782 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
6783 unsigned FromLSize =
6784 std::distance(FromL->decls().begin(), FromL->decls().end());
6785 EXPECT_NE(ToLSize, 0u);
6786 EXPECT_EQ(ToLSize, FromLSize);
6787 EXPECT_TRUE(FromL->isDependentLambda());
6790 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) {
6791 Decl *FromTU = getTuDecl(
6793 auto l1 = [](unsigned lp) { return 1; };
6794 auto l2 = [](int lp) { return 2; };
6795 int f(int p) {
6796 return l1(p) + l2(p);
6799 Lang_CXX11, "input0.cc");
6800 FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match(
6801 FromTU, functionDecl(hasName("f")));
6802 FunctionDecl *ToF = Import(FromF, Lang_CXX11);
6803 EXPECT_TRUE(ToF);
6806 TEST_P(ASTImporterOptionSpecificTestBase,
6807 ImportExistingFriendClassTemplateDef) {
6808 auto Code =
6810 template <class T1, class T2>
6811 struct Base {
6812 template <class U1, class U2>
6813 friend struct Class;
6815 template <class T1, class T2>
6816 struct Class { };
6819 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
6820 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
6822 auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
6823 ToTU, classTemplateDecl(hasName("Class")));
6824 auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
6825 ToTU, classTemplateDecl(hasName("Class")));
6826 ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition());
6827 ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition());
6828 // Previous friend decl is not linked to it!
6829 ASSERT_FALSE(ToClassDef->getPreviousDecl());
6830 ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef);
6831 ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto);
6833 auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
6834 FromTU, classTemplateDecl(hasName("Class")));
6835 auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
6836 FromTU, classTemplateDecl(hasName("Class")));
6837 ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition());
6838 ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition());
6839 ASSERT_FALSE(FromClassDef->getPreviousDecl());
6840 ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef);
6841 ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto);
6843 auto *ImportedDef = Import(FromClassDef, Lang_CXX03);
6844 // At import we should find the definition for 'Class' even if the
6845 // prototype (inside 'friend') for it comes first in the AST and is not
6846 // linked to the definition.
6847 EXPECT_EQ(ImportedDef, ToClassDef);
6850 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase {
6851 LLDBLookupTest() {
6852 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
6853 ASTContext &FromContext, FileManager &FromFileManager,
6854 bool MinimalImport,
6855 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
6856 return new ASTImporter(ToContext, ToFileManager, FromContext,
6857 FromFileManager, MinimalImport,
6858 // We use the regular lookup.
6859 /*SharedState=*/nullptr);
6864 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) {
6865 TranslationUnitDecl *ToTU = getToTuDecl(
6867 extern "C" {
6868 class X{};
6871 Lang_CXX03);
6872 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match(
6873 ToTU, cxxRecordDecl(hasName("X")));
6875 // Set up a stub external storage.
6876 ToTU->setHasExternalLexicalStorage(true);
6877 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true.
6878 ToTU->setMustBuildLookupTable();
6879 struct TestExternalASTSource : ExternalASTSource {};
6880 ToTU->getASTContext().setExternalSource(new TestExternalASTSource());
6882 Decl *FromTU = getTuDecl(
6884 class X;
6886 Lang_CXX03);
6887 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6888 FromTU, cxxRecordDecl(hasName("X")));
6889 auto *ImportedX = Import(FromX, Lang_CXX03);
6890 // The lookup must find the existing class definition in the LinkageSpecDecl.
6891 // Then the importer renders the existing and the new decl into one chain.
6892 EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl());
6895 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {};
6897 TEST_P(SVEBuiltins, ImportTypes) {
6898 static const char *const TypeNames[] = {
6899 "__SVInt8_t", "__SVInt16_t", "__SVInt32_t", "__SVInt64_t",
6900 "__SVUint8_t", "__SVUint16_t", "__SVUint32_t", "__SVUint64_t",
6901 "__SVFloat16_t", "__SVBfloat16_t", "__SVFloat32_t", "__SVFloat64_t",
6902 "__SVBool_t"};
6904 TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03);
6905 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc");
6906 for (auto *TypeName : TypeNames) {
6907 auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match(
6908 ToTU, typedefDecl(hasName(TypeName)));
6909 QualType ToType = ToTypedef->getUnderlyingType();
6911 auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match(
6912 FromTU, typedefDecl(hasName(TypeName)));
6913 QualType FromType = FromTypedef->getUnderlyingType();
6915 QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03);
6916 EXPECT_EQ(ImportedType, ToType);
6920 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) {
6921 // Test that import of implicit functions works and the functions
6922 // are merged into one chain.
6923 auto GetDeclToImport = [this](StringRef File) {
6924 Decl *FromTU = getTuDecl(
6926 struct X { };
6927 // Force generating some implicit operator definitions for X.
6928 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; }
6930 Lang_CXX11, File);
6931 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
6932 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
6933 // Destructor is picked as one example of implicit function.
6934 return FromD->getDestructor();
6937 auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11);
6938 ASSERT_TRUE(ToD1);
6940 auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11);
6941 ASSERT_TRUE(ToD2);
6943 EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl());
6946 TEST_P(ASTImporterOptionSpecificTestBase,
6947 ImportOfExplicitlyDefaultedOrDeleted) {
6948 Decl *FromTU = getTuDecl(
6950 struct X { X() = default; X(const X&) = delete; };
6952 Lang_CXX11);
6953 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6954 FromTU, cxxRecordDecl(hasName("X")));
6955 auto *ImportedX = Import(FromX, Lang_CXX11);
6956 auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match(
6957 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6958 auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match(
6959 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6961 ASSERT_TRUE(ImportedX);
6962 EXPECT_TRUE(Constr1->isDefaulted());
6963 EXPECT_TRUE(Constr1->isExplicitlyDefaulted());
6964 EXPECT_TRUE(Constr2->isDeletedAsWritten());
6965 EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate());
6968 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, SVEBuiltins,
6969 ::testing::Values(std::vector<std::string>{
6970 "-target", "aarch64-linux-gnu"}));
6972 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, DeclContextTest,
6973 ::testing::Values(std::vector<std::string>()));
6975 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CanonicalRedeclChain,
6976 ::testing::Values(std::vector<std::string>()));
6978 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) {
6979 Decl *FromTU = getTuDecl(
6981 void f() {
6982 auto L0 = [](){};
6983 auto L1 = [](){};
6986 Lang_CXX11, "input0.cc");
6987 auto Pattern = lambdaExpr();
6988 CXXRecordDecl *FromL0 =
6989 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6990 CXXRecordDecl *FromL1 =
6991 LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6992 ASSERT_NE(FromL0, FromL1);
6994 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
6995 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
6996 EXPECT_NE(ToL0, ToL1);
6999 TEST_P(ASTImporterOptionSpecificTestBase,
7000 LambdasInFunctionParamsAreDifferentiated) {
7001 Decl *FromTU = getTuDecl(
7003 template <typename F0, typename F1>
7004 void f(F0 L0 = [](){}, F1 L1 = [](){}) {}
7006 Lang_CXX11, "input0.cc");
7007 auto Pattern = cxxRecordDecl(isLambda());
7008 CXXRecordDecl *FromL0 =
7009 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
7010 CXXRecordDecl *FromL1 =
7011 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
7012 ASSERT_NE(FromL0, FromL1);
7014 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
7015 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
7016 ASSERT_NE(ToL0, ToL1);
7019 TEST_P(ASTImporterOptionSpecificTestBase,
7020 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) {
7021 Decl *FromTU = getTuDecl(
7023 #define LAMBDA [](){}
7024 template <typename F0, typename F1>
7025 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {}
7027 Lang_CXX11, "input0.cc");
7028 auto Pattern = cxxRecordDecl(isLambda());
7029 CXXRecordDecl *FromL0 =
7030 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
7031 CXXRecordDecl *FromL1 =
7032 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
7033 ASSERT_NE(FromL0, FromL1);
7035 Import(FromL0, Lang_CXX11);
7036 Import(FromL1, Lang_CXX11);
7037 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
7038 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
7039 ASSERT_NE(ToL0, ToL1);
7042 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) {
7043 Decl *FromTU = getTuDecl(
7045 void f() {
7046 auto x = []{} = {}; auto x2 = x;
7049 Lang_CXX20, "input0.cc");
7050 auto FromF = FirstDeclMatcher<FunctionDecl>().match(
7051 FromTU, functionDecl(hasName("f")));
7052 // We have only one lambda class.
7053 ASSERT_EQ(
7054 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
7055 1u);
7057 FunctionDecl *ToF = Import(FromF, Lang_CXX20);
7058 EXPECT_TRUE(ToF);
7059 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
7060 // We have only one lambda class after the import.
7061 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
7062 1u);
7065 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) {
7066 Decl *FromTU = getTuDecl(
7068 void f() {
7069 auto x = []{} = {};
7070 auto xb = []{} = {};
7073 Lang_CXX20, "input0.cc");
7074 auto FromF = FirstDeclMatcher<FunctionDecl>().match(
7075 FromTU, functionDecl(hasName("f")));
7076 // We have two lambda classes.
7077 ASSERT_EQ(
7078 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
7079 2u);
7081 FunctionDecl *ToF = Import(FromF, Lang_CXX20);
7082 EXPECT_TRUE(ToF);
7083 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
7084 // We have two lambda classes after the import.
7085 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
7086 2u);
7089 TEST_P(ASTImporterOptionSpecificTestBase,
7090 ImportFunctionDeclWithTypeSourceInfoWithSourceDecl) {
7091 // This code results in a lambda with implicit constructor.
7092 // The constructor's TypeSourceInfo points out the function prototype.
7093 // This prototype has an EST_Unevaluated in its exception information and a
7094 // SourceDecl that is the function declaration itself.
7095 // The test verifies that AST import of such AST does not crash.
7096 // (Here the function's TypeSourceInfo references the function itself.)
7097 Decl *FromTU = getTuDecl(
7099 template<typename T> void f(T) { auto X = [](){}; }
7100 void g() { f(10); }
7102 Lang_CXX11, "input0.cc");
7104 // Use LastDeclMatcher to find the LambdaExpr in the template specialization.
7105 CXXRecordDecl *FromL = LastDeclMatcher<LambdaExpr>()
7106 .match(FromTU, lambdaExpr())
7107 ->getLambdaClass();
7109 CXXConstructorDecl *FromCtor = *FromL->ctor_begin();
7110 ASSERT_TRUE(FromCtor->isCopyConstructor());
7111 ASSERT_TRUE(FromCtor->getTypeSourceInfo());
7112 const auto *FromFPT = FromCtor->getType()->getAs<FunctionProtoType>();
7113 ASSERT_TRUE(FromFPT);
7114 EXPECT_EQ(FromCtor->getTypeSourceInfo()->getType().getTypePtr(), FromFPT);
7115 FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
7116 // If type is EST_Unevaluated, SourceDecl should be set to the parent Decl.
7117 EXPECT_EQ(FromEPI.ExceptionSpec.Type, EST_Unevaluated);
7118 EXPECT_EQ(FromEPI.ExceptionSpec.SourceDecl, FromCtor);
7120 auto ToL = Import(FromL, Lang_CXX11);
7122 // Check if the import was correct.
7123 CXXConstructorDecl *ToCtor = *ToL->ctor_begin();
7124 EXPECT_TRUE(ToCtor->getTypeSourceInfo());
7125 const auto *ToFPT = ToCtor->getType()->getAs<FunctionProtoType>();
7126 ASSERT_TRUE(ToFPT);
7127 EXPECT_EQ(ToCtor->getTypeSourceInfo()->getType().getTypePtr(), ToFPT);
7128 FunctionProtoType::ExtProtoInfo ToEPI = ToFPT->getExtProtoInfo();
7129 EXPECT_EQ(ToEPI.ExceptionSpec.Type, EST_Unevaluated);
7130 EXPECT_EQ(ToEPI.ExceptionSpec.SourceDecl, ToCtor);
7133 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {
7134 void testImport(llvm::StringRef Code, clang::TestLanguage Lang = Lang_CXX14,
7135 bool FindLast = false) {
7136 Decl *FromTU = getTuDecl(Code, Lang, "input0.cc");
7137 FunctionDecl *From = FindLast ? LastDeclMatcher<FunctionDecl>().match(
7138 FromTU, functionDecl(hasName("foo")))
7139 : FirstDeclMatcher<FunctionDecl>().match(
7140 FromTU, functionDecl(hasName("foo")));
7142 FunctionDecl *To = Import(From, Lang);
7143 EXPECT_TRUE(To);
7144 // We check here only that the type is auto type.
7145 // These tests are to verify that no crash happens.
7146 // The crash possibility is the presence of a reference to a declaration
7147 // in the function's body from the return type, if the function has auto
7148 // return type.
7149 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
7153 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate1) {
7154 testImport(
7156 template<class C>
7157 C f1() { return C(); }
7158 auto foo() {
7159 struct B {};
7160 return f1<B>();
7162 )");
7165 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate2) {
7166 testImport(
7168 template<class T>
7169 int f1(T t) { return 1; }
7170 auto foo() {
7171 struct B {};
7172 return f1(B());
7174 )");
7177 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate3) {
7178 testImport(
7180 template<class A> struct S1 {};
7181 template<class A> struct S2 {};
7182 template<class C>
7183 S1<C> f1() { return S1<C>(); }
7184 auto foo() {
7185 struct B {};
7186 return f1<S2<B *>>();
7188 )");
7191 TEST_P(ImportAutoFunctions, ReturnWithFunctionTemplate4) {
7192 testImport(
7194 template<class... A> struct S1 {};
7195 template<class... A> struct S2 {};
7196 template<class... C>
7197 S1<C...> f1() { return S1<C...>(); }
7198 auto foo() {
7199 struct B {};
7200 return f1<S2<int, B *>, bool>();
7202 )");
7205 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate1) {
7206 testImport(
7208 template<class T> T X;
7209 auto foo() {
7210 struct A {};
7211 return X<A>;
7213 )");
7216 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate2) {
7217 testImport(
7219 template<class A> struct S1 {};
7220 template<class T> S1<T> X;
7221 auto foo() {
7222 struct A {};
7223 return X<S1<A>>;
7225 )");
7228 TEST_P(ImportAutoFunctions, ReturnWithVarTemplate3) {
7229 testImport(
7231 template<class... A> struct S1 {};
7232 template<class... T> S1<T...> X;
7233 auto foo() {
7234 struct A {};
7235 return X<bool, S1<A, int>>;
7237 )");
7240 TEST_P(ImportAutoFunctions, ReturnWithAutoUnresolvedArg) {
7241 testImport(
7243 template<int A>
7244 auto foo() {
7245 return 22;
7247 )");
7250 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTemplateTemplateArg) {
7251 // FIXME: Is it possible to have the template arg inside the function?
7252 testImport(
7254 template<int> struct Tmpl {};
7255 template<template<int> class> struct TmplTmpl {};
7256 auto foo() {
7257 return TmplTmpl<Tmpl>();
7259 )");
7262 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithDeclarationTemplateArg) {
7263 // FIXME: Is it possible to have the template arg inside the function?
7264 testImport(
7266 template<const int *> struct Tmpl {};
7267 int A[10];
7268 auto foo() {
7269 return Tmpl<A>();
7271 )");
7274 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithNullPtrTemplateArg) {
7275 testImport(
7277 template<int *> struct Tmpl {};
7278 auto foo() {
7279 constexpr int* A = nullptr;
7280 return Tmpl<A>();
7282 )");
7285 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegralTemplateArg) {
7286 testImport(
7288 template<int> struct Tmpl {};
7289 auto foo() {
7290 using Int = int;
7291 constexpr Int A = 7;
7292 return Tmpl<A>();
7294 )");
7297 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithDecltypeTypeDeclaredInside) {
7298 testImport(
7300 template<class> struct Tmpl {};
7301 auto foo() {
7302 struct X {};
7303 X x;
7304 return Tmpl<decltype(x)>();
7306 )");
7309 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithUsingTypeDeclaredInside) {
7310 testImport(
7312 template<class> struct Tmpl {};
7313 namespace A { struct X {}; }
7314 auto foo() {
7315 using A::X;
7316 return Tmpl<X>();
7318 )");
7321 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithArrayTypeDeclaredInside) {
7322 testImport(
7324 template<class> struct Tmpl {};
7325 auto foo() {
7326 struct X {};
7327 return Tmpl<X[10]>();
7329 )");
7332 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithArraySizeExprDeclaredInside) {
7333 testImport(
7335 template<class> struct Tmpl {};
7336 auto foo() {
7337 constexpr int S = 10;
7338 return Tmpl<int[S]>();
7340 )");
7343 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithPackArgDeclaredInside) {
7344 testImport(
7346 template<class ...> struct Tmpl {};
7347 auto foo() {
7348 using X = bool;
7349 return Tmpl<int, X>();
7351 )");
7354 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegerArgDeclaredInside) {
7355 testImport(
7357 template<int> struct Tmpl {};
7358 auto foo() {
7359 constexpr int X = 1;
7360 return Tmpl<X>();
7362 )");
7365 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithPtrToStructDeclaredInside) {
7366 testImport(
7368 template<class> struct Tmpl {};
7369 auto foo() {
7370 struct X {};
7371 return Tmpl<X *>();
7373 )");
7376 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithRefToStructDeclaredInside) {
7377 testImport(
7379 template<class> struct Tmpl {};
7380 struct X {};
7381 auto foo() {
7382 using Y = X;
7383 return Tmpl<Y &>();
7385 )");
7388 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside1) {
7389 testImport(
7391 template<class> struct Tmpl {};
7392 auto foo() {
7393 struct X {};
7394 return Tmpl<X>();
7396 )");
7399 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside2) {
7400 testImport(
7402 template<class> struct Tmpl {};
7403 auto foo() {
7404 struct X {};
7405 return Tmpl<Tmpl<X>>();
7407 )");
7410 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTypedefDeclaredInside) {
7411 testImport(
7413 template<class> struct Tmpl {};
7414 auto foo() {
7415 struct X {};
7416 using x_type = X;
7417 return Tmpl<x_type>();
7419 )");
7422 TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) {
7423 Decl *FromTU = getTuDecl(
7425 auto X = [](long l) {
7426 using int_type = long;
7427 auto dur = 13;
7428 return static_cast<int_type>(dur);
7431 Lang_CXX14, "input0.cc");
7432 CXXMethodDecl *From =
7433 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl());
7435 // Explicitly set the return type of the lambda's operator() to the TypeAlias.
7436 // Normally the return type would be the built-in 'long' type. However, there
7437 // are cases when Clang does not use the canonical type and the TypeAlias is
7438 // used. I could not create such an AST from regular source code, it requires
7439 // some special state in the preprocessor. I've found such an AST when Clang
7440 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce
7441 // that with creduce, because after preprocessing, the AST no longer
7442 // contained the TypeAlias as a return type of the lambda.
7443 ASTContext &Ctx = From->getASTContext();
7444 TypeAliasDecl *FromTA =
7445 FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl());
7446 QualType TT = Ctx.getTypedefType(FromTA);
7447 const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType());
7448 QualType NewFunType =
7449 Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo());
7450 From->setType(NewFunType);
7452 CXXMethodDecl *To = Import(From, Lang_CXX14);
7453 EXPECT_TRUE(To);
7454 EXPECT_TRUE(isa<TypedefType>(To->getReturnType()));
7457 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) {
7458 testImport(
7460 auto foo() {
7461 struct X {};
7462 return X();
7464 )");
7467 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) {
7468 Decl *FromTU = getTuDecl(
7470 auto foo() {
7471 struct X {};
7472 return X();
7475 Lang_CXX14, "input0.cc");
7476 FunctionDecl *From =
7477 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
7479 // This time import the type directly.
7480 QualType ToT = ImportType(From->getType(), From, Lang_CXX14);
7481 const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT);
7482 EXPECT_TRUE(isa<AutoType>(FPT->getReturnType()));
7485 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside3) {
7486 Decl *FromTU = getTuDecl(
7488 struct S {
7489 constexpr auto foo();
7491 constexpr auto S::foo() {
7492 struct X {};
7493 return X();
7496 Lang_CXX14, "input0.cc");
7497 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
7498 FromTU, functionDecl(hasName("foo"), unless(hasBody(stmt()))));
7499 ASSERT_FALSE(From->isThisDeclarationADefinition());
7501 FunctionDecl *To = Import(From, Lang_CXX17);
7502 EXPECT_TRUE(To);
7503 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
7504 EXPECT_FALSE(To->isThisDeclarationADefinition());
7507 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) {
7508 testImport(
7510 auto foo() {
7511 struct X {};
7512 using Y = X;
7513 return Y();
7515 )");
7518 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) {
7519 testImport(
7521 auto foo() {
7522 struct X { struct Y{}; };
7523 return X::Y();
7525 )");
7528 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) {
7529 testImport(
7531 auto foo() {
7532 auto l = []() {
7533 struct X {};
7534 return X();
7536 return l();
7539 Lang_CXX17);
7542 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) {
7543 testImport(
7545 auto foo() {
7546 if (struct X {} x; true)
7547 return X();
7548 else
7549 return X();
7552 Lang_CXX17);
7555 TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) {
7556 testImport(
7558 auto foo() {
7559 for (struct X {} x;;)
7560 return X();
7563 Lang_CXX17);
7566 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) {
7567 testImport(
7569 auto foo() {
7570 switch (struct X {} x; 10) {
7571 case 10:
7572 return X();
7576 Lang_CXX17);
7579 TEST_P(ImportAutoFunctions, ReturnWithAutoTemplateType) {
7580 testImport(
7582 template<class T>
7583 struct S {};
7584 template<class T>
7585 auto foo() {
7586 return S<T>{};
7588 auto a = foo<int>();
7590 Lang_CXX14, /*FindLast=*/true);
7593 TEST_P(ImportAutoFunctions, ReturnWithSubstNonTypeTemplateParmExpr) {
7594 const char *Code =
7596 template<int>
7597 struct array {};
7599 template <int N>
7600 auto foo() { return array<N>(); }
7602 void bar() { foo<0>(); }
7604 Decl *FromTU = getTuDecl(Code, Lang_CXX17);
7606 auto *FromBar = FirstDeclMatcher<FunctionDecl>().match(
7607 FromTU, functionDecl(hasName("bar")));
7609 auto *ToBar = Import(FromBar, Lang_CXX17);
7610 EXPECT_TRUE(ToBar);
7613 TEST_P(ImportAutoFunctions, ReturnWithUnaryTransformType) {
7614 const char *Code =
7616 enum E { E1 };
7618 template<typename T>
7619 auto foo(T v) { return static_cast<__underlying_type(T)>(v); }
7621 bool bar() { return foo(E1); }
7623 Decl *FromTU = getTuDecl(Code, Lang_CXX17);
7625 auto *FromBar = FirstDeclMatcher<FunctionDecl>().match(
7626 FromTU, functionDecl(hasName("bar")));
7628 auto *ToBar = Import(FromBar, Lang_CXX17);
7629 EXPECT_TRUE(ToBar);
7632 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {};
7634 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) {
7635 // Tests that the FileID tree structure (with the links being the include
7636 // chains) is preserved while importing other files (which need to be
7637 // added to this structure with fake include locations.
7639 SourceLocation Location1;
7641 auto Pattern = varDecl(hasName("X"));
7642 Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c");
7643 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7645 Location1 = Import(FromD, Lang_C99)->getLocation();
7647 SourceLocation Location2;
7649 auto Pattern = varDecl(hasName("Y"));
7650 Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c");
7651 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7653 Location2 = Import(FromD, Lang_C99)->getLocation();
7656 SourceManager &ToSM = ToAST->getSourceManager();
7657 FileID FileID1 = ToSM.getFileID(Location1);
7658 FileID FileID2 = ToSM.getFileID(Location2);
7660 // Check that the imported files look like as if they were included from the
7661 // start of the main file.
7662 SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID());
7663 EXPECT_NE(FileID1, ToSM.getMainFileID());
7664 EXPECT_NE(FileID2, ToSM.getMainFileID());
7665 EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart);
7666 EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart);
7668 // Let the SourceManager check the order of the locations. The order should
7669 // be the order in which the declarations are imported.
7670 EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2));
7671 EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1));
7674 TEST_P(ImportSourceLocations, NormalFileBuffer) {
7675 // Test importing normal file buffers.
7677 std::string Path = "input0.c";
7678 std::string Source = "int X;";
7679 TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path);
7681 SourceLocation ImportedLoc;
7683 // Import the VarDecl to trigger the importing of the FileID.
7684 auto Pattern = varDecl(hasName("X"));
7685 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7686 ImportedLoc = Import(FromD, Lang_C99)->getLocation();
7689 // Make sure the imported buffer has the original contents.
7690 SourceManager &ToSM = ToAST->getSourceManager();
7691 FileID ImportedID = ToSM.getFileID(ImportedLoc);
7692 EXPECT_EQ(Source,
7693 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
7696 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) {
7697 // Test importing overwritten file buffers.
7699 std::string Path = "input0.c";
7700 TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path);
7702 // Overwrite the file buffer for our input file with new content.
7703 const std::string Contents = "overwritten contents";
7704 SourceLocation ImportedLoc;
7706 SourceManager &FromSM = FromTU->getASTContext().getSourceManager();
7707 clang::FileManager &FM = FromSM.getFileManager();
7708 clang::FileEntryRef FE =
7709 FM.getVirtualFileRef(Path, static_cast<off_t>(Contents.size()), 0);
7711 llvm::SmallVector<char, 64> Buffer;
7712 Buffer.append(Contents.begin(), Contents.end());
7713 auto FileContents = std::make_unique<llvm::SmallVectorMemoryBuffer>(
7714 std::move(Buffer), Path, /*RequiresNullTerminator=*/false);
7715 FromSM.overrideFileContents(FE, std::move(FileContents));
7717 // Import the VarDecl to trigger the importing of the FileID.
7718 auto Pattern = varDecl(hasName("X"));
7719 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
7720 ImportedLoc = Import(FromD, Lang_C99)->getLocation();
7723 // Make sure the imported buffer has the overwritten contents.
7724 SourceManager &ToSM = ToAST->getSourceManager();
7725 FileID ImportedID = ToSM.getFileID(ImportedLoc);
7726 EXPECT_EQ(Contents,
7727 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
7730 struct ImportAttributes : public ASTImporterOptionSpecificTestBase {
7731 void checkAttrImportCommon(const Attr *From, const Attr *To,
7732 const Decl *ToD) {
7734 // Verify that dump does not crash because invalid data.
7735 ToD->dump(llvm::nulls());
7737 EXPECT_EQ(From->getParsedKind(), To->getParsedKind());
7738 EXPECT_EQ(From->getSyntax(), To->getSyntax());
7739 if (From->getAttrName()) {
7740 EXPECT_TRUE(To->getAttrName());
7741 EXPECT_STREQ(From->getAttrName()->getNameStart(),
7742 To->getAttrName()->getNameStart());
7743 } else {
7744 EXPECT_FALSE(To->getAttrName());
7746 if (From->getScopeName()) {
7747 EXPECT_TRUE(To->getScopeName());
7748 EXPECT_STREQ(From->getScopeName()->getNameStart(),
7749 To->getScopeName()->getNameStart());
7750 } else {
7751 EXPECT_FALSE(To->getScopeName());
7753 EXPECT_EQ(From->getSpellingListIndex(), To->getSpellingListIndex());
7754 EXPECT_STREQ(From->getSpelling(), To->getSpelling());
7755 EXPECT_EQ(From->isInherited(), To->isInherited());
7756 EXPECT_EQ(From->isImplicit(), To->isImplicit());
7757 EXPECT_EQ(From->isPackExpansion(), To->isPackExpansion());
7758 EXPECT_EQ(From->isLateParsed(), To->isLateParsed());
7761 template <class DT, class AT>
7762 void importAttr(const char *Code, AT *&FromAttr, AT *&ToAttr,
7763 TestLanguage Lang = Lang_CXX11) {
7764 static_assert(std::is_base_of<Attr, AT>::value, "AT should be an Attr");
7765 static_assert(std::is_base_of<Decl, DT>::value, "DT should be a Decl");
7767 Decl *FromTU = getTuDecl(Code, Lang, "input.cc");
7768 DT *FromD =
7769 FirstDeclMatcher<DT>().match(FromTU, namedDecl(hasName("test")));
7770 ASSERT_TRUE(FromD);
7772 DT *ToD = Import(FromD, Lang_CXX11);
7773 ASSERT_TRUE(ToD);
7775 FromAttr = FromD->template getAttr<AT>();
7776 ToAttr = ToD->template getAttr<AT>();
7777 ASSERT_TRUE(FromAttr);
7778 EXPECT_TRUE(ToAttr);
7780 checkAttrImportCommon(FromAttr, ToAttr, ToD);
7783 template <class T> void checkImported(const T *From, const T *To) {
7784 EXPECT_TRUE(To);
7785 EXPECT_NE(From, To);
7788 template <class T>
7789 void checkImportVariadicArg(const llvm::iterator_range<T **> &From,
7790 const llvm::iterator_range<T **> &To) {
7791 for (auto FromI = From.begin(), ToI = To.begin(); FromI != From.end();
7792 ++FromI, ++ToI) {
7793 ASSERT_NE(ToI, To.end());
7794 checkImported(*FromI, *ToI);
7799 template <>
7800 void ImportAttributes::checkImported<Decl>(const Decl *From, const Decl *To) {
7801 EXPECT_TRUE(To);
7802 EXPECT_NE(From, To);
7803 EXPECT_EQ(To->getTranslationUnitDecl(),
7804 ToAST->getASTContext().getTranslationUnitDecl());
7807 TEST_P(ImportAttributes, ImportAligned) {
7808 AlignedAttr *FromAttr, *ToAttr;
7809 importAttr<RecordDecl>(
7811 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; };
7812 struct alignas(alignof(A)) test {};
7814 FromAttr, ToAttr);
7815 checkImported(FromAttr->getAlignmentExpr(), ToAttr->getAlignmentExpr());
7817 auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match(
7818 ToAST->getASTContext().getTranslationUnitDecl(),
7819 cxxRecordDecl(hasName("A"), unless(isImplicit())));
7820 // Ensure that 'struct A' was imported (through reference from attribute of
7821 // struct 'test').
7822 EXPECT_TRUE(ToA);
7825 TEST_P(ImportAttributes, ImportAlignValue) {
7826 AlignValueAttr *FromAttr, *ToAttr;
7827 importAttr<VarDecl>(
7829 void *test __attribute__((align_value(64)));
7831 FromAttr, ToAttr);
7832 checkImported(FromAttr->getAlignment(), ToAttr->getAlignment());
7835 TEST_P(ImportAttributes, ImportFormat) {
7836 FormatAttr *FromAttr, *ToAttr;
7837 importAttr<FunctionDecl>(
7839 int test(const char * fmt, ...)
7840 __attribute__ ((__format__ (__scanf__, 1, 2)));
7842 FromAttr, ToAttr);
7844 EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName());
7845 EXPECT_EQ(FromAttr->getFirstArg(), ToAttr->getFirstArg());
7846 EXPECT_EQ(FromAttr->getFormatIdx(), ToAttr->getFormatIdx());
7849 TEST_P(ImportAttributes, ImportEnableIf) {
7850 EnableIfAttr *FromAttr, *ToAttr;
7851 importAttr<FunctionDecl>(
7852 "void test(int A) __attribute__((enable_if(A == 1, \"message\")));",
7853 FromAttr, ToAttr);
7854 checkImported(FromAttr->getCond(), ToAttr->getCond());
7855 EXPECT_EQ(FromAttr->getMessage(), ToAttr->getMessage());
7858 TEST_P(ImportAttributes, ImportGuardedVar) {
7859 GuardedVarAttr *FromAttr, *ToAttr;
7860 importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr,
7861 ToAttr);
7864 TEST_P(ImportAttributes, ImportPtGuardedVar) {
7865 PtGuardedVarAttr *FromAttr, *ToAttr;
7866 importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr,
7867 ToAttr);
7870 TEST_P(ImportAttributes, ImportScopedLockable) {
7871 ScopedLockableAttr *FromAttr, *ToAttr;
7872 importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};",
7873 FromAttr, ToAttr);
7876 TEST_P(ImportAttributes, ImportCapability) {
7877 CapabilityAttr *FromAttr, *ToAttr;
7878 importAttr<CXXRecordDecl>(
7879 "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr);
7880 EXPECT_EQ(FromAttr->getName(), ToAttr->getName());
7883 TEST_P(ImportAttributes, ImportAssertCapability) {
7884 AssertCapabilityAttr *FromAttr, *ToAttr;
7885 importAttr<FunctionDecl>(
7886 "void test(int A1, int A2) __attribute__((assert_capability(A1, A2)));",
7887 FromAttr, ToAttr);
7888 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7891 TEST_P(ImportAttributes, ImportAcquireCapability) {
7892 AcquireCapabilityAttr *FromAttr, *ToAttr;
7893 importAttr<FunctionDecl>(
7894 "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));",
7895 FromAttr, ToAttr);
7896 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7899 TEST_P(ImportAttributes, ImportTryAcquireCapability) {
7900 TryAcquireCapabilityAttr *FromAttr, *ToAttr;
7901 importAttr<FunctionDecl>(
7902 "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, "
7903 "A2)));",
7904 FromAttr, ToAttr);
7905 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
7906 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7909 TEST_P(ImportAttributes, ImportReleaseCapability) {
7910 ReleaseCapabilityAttr *FromAttr, *ToAttr;
7911 importAttr<FunctionDecl>(
7912 "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));",
7913 FromAttr, ToAttr);
7914 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7917 TEST_P(ImportAttributes, ImportRequiresCapability) {
7918 RequiresCapabilityAttr *FromAttr, *ToAttr;
7919 importAttr<FunctionDecl>(
7920 "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));",
7921 FromAttr, ToAttr);
7922 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7925 TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) {
7926 NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr;
7927 importAttr<FunctionDecl>(
7928 "void test() __attribute__((no_thread_safety_analysis));", FromAttr,
7929 ToAttr);
7932 TEST_P(ImportAttributes, ImportGuardedBy) {
7933 GuardedByAttr *FromAttr, *ToAttr;
7934 importAttr<VarDecl>(
7936 int G;
7937 int test __attribute__((guarded_by(G)));
7939 FromAttr, ToAttr);
7940 checkImported(FromAttr->getArg(), ToAttr->getArg());
7943 TEST_P(ImportAttributes, ImportPtGuardedBy) {
7944 PtGuardedByAttr *FromAttr, *ToAttr;
7945 importAttr<VarDecl>(
7947 int G;
7948 int *test __attribute__((pt_guarded_by(G)));
7950 FromAttr, ToAttr);
7951 checkImported(FromAttr->getArg(), ToAttr->getArg());
7954 TEST_P(ImportAttributes, ImportAcquiredAfter) {
7955 AcquiredAfterAttr *FromAttr, *ToAttr;
7956 importAttr<VarDecl>(
7958 struct __attribute__((lockable)) L {};
7959 L A1;
7960 L A2;
7961 L test __attribute__((acquired_after(A1, A2)));
7963 FromAttr, ToAttr);
7964 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7967 TEST_P(ImportAttributes, ImportAcquiredBefore) {
7968 AcquiredBeforeAttr *FromAttr, *ToAttr;
7969 importAttr<VarDecl>(
7971 struct __attribute__((lockable)) L {};
7972 L A1;
7973 L A2;
7974 L test __attribute__((acquired_before(A1, A2)));
7976 FromAttr, ToAttr);
7977 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7980 TEST_P(ImportAttributes, ImportAssertExclusiveLock) {
7981 AssertExclusiveLockAttr *FromAttr, *ToAttr;
7982 importAttr<FunctionDecl>("void test(int A1, int A2) "
7983 "__attribute__((assert_exclusive_lock(A1, A2)));",
7984 FromAttr, ToAttr);
7985 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7988 TEST_P(ImportAttributes, ImportAssertSharedLock) {
7989 AssertSharedLockAttr *FromAttr, *ToAttr;
7990 importAttr<FunctionDecl>(
7991 "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));",
7992 FromAttr, ToAttr);
7993 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
7996 TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) {
7997 ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr;
7998 importAttr<FunctionDecl>(
7999 "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, "
8000 "A1, A2)));",
8001 FromAttr, ToAttr);
8002 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
8003 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
8006 TEST_P(ImportAttributes, ImportSharedTrylockFunction) {
8007 SharedTrylockFunctionAttr *FromAttr, *ToAttr;
8008 importAttr<FunctionDecl>(
8009 "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, "
8010 "A2)));",
8011 FromAttr, ToAttr);
8012 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
8013 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
8016 TEST_P(ImportAttributes, ImportLockReturned) {
8017 LockReturnedAttr *FromAttr, *ToAttr;
8018 importAttr<FunctionDecl>(
8019 "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr,
8020 ToAttr);
8021 checkImported(FromAttr->getArg(), ToAttr->getArg());
8024 TEST_P(ImportAttributes, ImportLocksExcluded) {
8025 LocksExcludedAttr *FromAttr, *ToAttr;
8026 importAttr<FunctionDecl>(
8027 "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));",
8028 FromAttr, ToAttr);
8029 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
8032 TEST_P(ImportAttributes, ImportC99NoThrowAttr) {
8033 NoThrowAttr *FromAttr, *ToAttr;
8034 importAttr<FunctionDecl>("void test () __attribute__ ((__nothrow__));",
8035 FromAttr, ToAttr, Lang_C99);
8036 checkImported(FromAttr->getAttrName(), ToAttr->getAttrName());
8039 template <typename T>
8040 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) {
8041 auto Copy = Values;
8042 for (std::vector<std::string> &ArgV : Copy) {
8043 for (const std::string &Arg : Args) {
8044 ArgV.push_back(Arg);
8047 return ::testing::ValuesIn(Copy);
8050 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase {
8051 ImportWithExternalSource() {
8052 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
8053 ASTContext &FromContext, FileManager &FromFileManager,
8054 bool MinimalImport,
8055 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
8056 return new ASTImporter(ToContext, ToFileManager, FromContext,
8057 // Use minimal import for these tests.
8058 FromFileManager, /*MinimalImport=*/true,
8059 // We use the regular lookup.
8060 /*SharedState=*/nullptr);
8065 /// An ExternalASTSource that keeps track of the tags is completed.
8066 struct SourceWithCompletedTagList : clang::ExternalASTSource {
8067 std::vector<clang::TagDecl *> &CompletedTags;
8068 SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags)
8069 : CompletedTags(CompletedTags) {}
8070 void CompleteType(TagDecl *Tag) override {
8071 auto *Record = cast<CXXRecordDecl>(Tag);
8072 Record->startDefinition();
8073 Record->completeDefinition();
8074 CompletedTags.push_back(Tag);
8076 using clang::ExternalASTSource::CompleteType;
8079 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) {
8080 // Create an empty TU.
8081 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp");
8083 // Create and add the test ExternalASTSource.
8084 std::vector<clang::TagDecl *> CompletedTags;
8085 IntrusiveRefCntPtr<ExternalASTSource> source =
8086 new SourceWithCompletedTagList(CompletedTags);
8087 clang::ASTContext &Context = FromTU->getASTContext();
8088 Context.setExternalSource(std::move(source));
8090 // Create a dummy class by hand with external lexical storage.
8091 IdentifierInfo &Ident = Context.Idents.get("test_class");
8092 auto *Record =
8093 CXXRecordDecl::Create(Context, TagTypeKind::Class, FromTU,
8094 SourceLocation(), SourceLocation(), &Ident);
8095 Record->setHasExternalLexicalStorage();
8096 FromTU->addDecl(Record);
8098 // Do a minimal import of the created class.
8099 EXPECT_EQ(0U, CompletedTags.size());
8100 Import(Record, Lang_CXX03);
8101 EXPECT_EQ(0U, CompletedTags.size());
8103 // Import the definition of the created class.
8104 llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record);
8105 EXPECT_FALSE((bool)Err);
8106 consumeError(std::move(Err));
8108 // Make sure the class was completed once.
8109 EXPECT_EQ(1U, CompletedTags.size());
8110 EXPECT_EQ(Record, CompletedTags.front());
8113 TEST_P(ImportFunctions, CTADImplicit) {
8114 Decl *FromTU = getTuDecl(
8116 template <typename T> struct A {
8117 A(T);
8119 A a{(int)0};
8121 Lang_CXX17, "input.cc");
8122 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8123 FromTU,
8124 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>")))));
8125 auto *ToD = Import(FromD, Lang_CXX17);
8126 ASSERT_TRUE(ToD);
8127 EXPECT_EQ(ToD->getDeductionCandidateKind(), DeductionCandidate::Copy);
8128 EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr);
8129 EXPECT_EQ(ToD->getSourceDeductionGuideKind(),
8130 CXXDeductionGuideDecl::SourceDeductionGuideKind::None);
8131 // Check that the deduced class template is also imported.
8132 EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull(
8133 FromD->getDeducedTemplate()));
8136 TEST_P(ImportFunctions, CTADUserDefinedExplicit) {
8137 Decl *FromTU = getTuDecl(
8139 template <typename T> struct A {
8140 A(T);
8142 template <typename T> explicit A(T) -> A<float>;
8143 A a{(int)0}; // calls A<float>::A(float)
8145 Lang_CXX17, "input.cc");
8146 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8147 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
8148 // Not-implicit: i.e. not compiler-generated, user defined.
8149 ASSERT_FALSE(FromD->isImplicit());
8150 ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword.
8151 auto *ToD = Import(FromD, Lang_CXX17);
8152 ASSERT_TRUE(ToD);
8153 EXPECT_FALSE(FromD->isImplicit());
8154 EXPECT_TRUE(ToD->isExplicit());
8155 EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr);
8156 EXPECT_EQ(ToD->getSourceDeductionGuideKind(),
8157 CXXDeductionGuideDecl::SourceDeductionGuideKind::None);
8160 TEST_P(ImportFunctions, CTADWithLocalTypedef) {
8161 Decl *TU = getTuDecl(
8163 template <typename T> struct A {
8164 typedef T U;
8165 A(U);
8167 A a{(int)0};
8169 Lang_CXX17, "input.cc");
8170 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8171 TU, cxxDeductionGuideDecl());
8172 auto *ToD = Import(FromD, Lang_CXX17);
8173 ASSERT_TRUE(ToD);
8176 TEST_P(ImportFunctions, CTADAliasTemplate) {
8177 Decl *TU = getTuDecl(
8179 template <typename T> struct A {
8180 A(T);
8182 template<typename T>
8183 using B = A<T>;
8184 B b{(int)0};
8186 Lang_CXX20, "input.cc");
8187 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8188 TU, cxxDeductionGuideDecl(hasParameter(0, hasType(asString("int")))));
8189 auto *ToD = Import(FromD, Lang_CXX20);
8190 ASSERT_TRUE(ToD);
8191 EXPECT_TRUE(ToD->getSourceDeductionGuideKind() ==
8192 CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias);
8193 EXPECT_TRUE(ToD->getSourceDeductionGuide());
8196 TEST_P(ImportFunctions, ParmVarDeclDeclContext) {
8197 constexpr auto FromTUCode = R"(
8198 void f(int P);
8200 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
8201 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
8202 FromTU, functionDecl(hasName("f")));
8203 ASSERT_TRUE(FromF);
8205 auto *ImportedF = Import(FromF, Lang_CXX11);
8206 EXPECT_TRUE(ImportedF);
8207 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
8208 ImportedF, ImportedF->getParamDecl(0)));
8211 // FIXME Move these tests out of ASTImporterTest. For that we need to factor
8212 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase
8213 // into a new test Fixture. Then we should lift up this Fixture to its own
8214 // implementation file and only then could we reuse the Fixture in other AST
8215 // unitttests.
8216 struct CTAD : ASTImporterOptionSpecificTestBase {};
8218 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) {
8219 Decl *TU = getTuDecl(
8221 typedef int U;
8222 template <typename T> struct A {
8223 A(U, T);
8225 A a{(int)0, (int)0};
8227 Lang_CXX17, "input.cc");
8228 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8229 TU, cxxDeductionGuideDecl());
8230 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
8231 TU, typedefNameDecl(hasName("U")));
8232 ParmVarDecl *Param = Guide->getParamDecl(0);
8233 // The type of the first param (which is a typedef) should match the typedef
8234 // in the global scope.
8235 EXPECT_EQ(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
8238 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) {
8239 Decl *TU = getTuDecl(
8241 typedef int U;
8242 template <typename T> struct A {
8243 A(U*, T);
8245 A a{(int*)0, (int)0};
8247 Lang_CXX17, "input.cc");
8248 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8249 TU, cxxDeductionGuideDecl());
8250 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
8251 TU, typedefNameDecl(hasName("U")));
8252 ParmVarDecl *Param = Guide->getParamDecl(0);
8253 EXPECT_EQ(Param->getType()
8254 ->getAs<PointerType>()
8255 ->getPointeeType()
8256 ->getAs<TypedefType>()
8257 ->getDecl(),
8258 Typedef);
8261 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) {
8262 Decl *TU = getTuDecl(
8264 template <typename T> struct A {
8265 typedef T U;
8266 A(U, T);
8268 A a{(int)0, (int)0};
8270 Lang_CXX17, "input.cc");
8271 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8272 TU, cxxDeductionGuideDecl());
8273 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
8274 TU, typedefNameDecl(hasName("U")));
8275 ParmVarDecl *Param = Guide->getParamDecl(0);
8276 EXPECT_NE(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
8279 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CTAD,
8280 DefaultTestValuesForRunOptions);
8282 TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) {
8283 Decl *TU = getTuDecl(
8285 namespace N {
8286 typedef int X __attribute__((annotate("A")));
8289 Lang_CXX17, "input.cc");
8290 auto *FromD =
8291 FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X")));
8292 auto *ToD = Import(FromD, Lang_CXX17);
8293 ASSERT_TRUE(ToD);
8294 ASSERT_EQ(ToD->getAttrs().size(), 1U);
8295 auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]);
8296 ASSERT_TRUE(ToAttr);
8297 EXPECT_EQ(ToAttr->getAnnotation(), "A");
8300 TEST_P(ASTImporterOptionSpecificTestBase,
8301 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) {
8302 Decl *FromTU = getTuDecl(
8305 namespace std {
8306 template<typename T>
8307 class basic_stringbuf;
8309 namespace std {
8310 class char_traits;
8311 template<typename T = char_traits>
8312 class basic_stringbuf;
8314 namespace std {
8315 template<typename T>
8316 class basic_stringbuf {};
8320 Lang_CXX11);
8322 auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match(
8323 FromTU,
8324 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
8325 auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11));
8326 EXPECT_TRUE(To1);
8328 auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match(
8329 FromTU,
8330 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
8331 auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11));
8332 EXPECT_TRUE(To2);
8335 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) {
8336 Decl *FromTU = getTuDecl(
8338 void declToImport(int N) {
8339 int VLA[N];
8340 [&VLA] {}; // FieldDecl inside the lambda.
8343 Lang_CXX14);
8344 auto *FromFD = FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl());
8345 ASSERT_TRUE(FromFD);
8346 ASSERT_TRUE(FromFD->hasCapturedVLAType());
8348 auto *ToFD = Import(FromFD, Lang_CXX14);
8349 EXPECT_TRUE(ToFD);
8350 EXPECT_TRUE(ToFD->hasCapturedVLAType());
8351 EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType());
8354 TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) {
8355 Decl *FromTU = getTuDecl(
8357 template <class T> struct A {
8358 enum tagname { enumerator };
8360 template struct A<int>;
8362 Lang_CXX03);
8363 auto *FromD = FirstDeclMatcher<EnumDecl>().match(
8364 FromTU, enumDecl(hasName("tagname"),
8365 hasParent(classTemplateSpecializationDecl())));
8366 ASSERT_TRUE(FromD);
8367 ASSERT_TRUE(FromD->getMemberSpecializationInfo());
8369 auto *ToD = Import(FromD, Lang_CXX03);
8370 EXPECT_TRUE(ToD);
8371 EXPECT_TRUE(ToD->getMemberSpecializationInfo());
8372 EXPECT_EQ(FromD->getTemplateSpecializationKind(),
8373 ToD->getTemplateSpecializationKind());
8376 TEST_P(ASTImporterOptionSpecificTestBase, ImportIsInheritingConstructorBit) {
8377 Decl *FromTU = getTuDecl(
8379 struct A {
8380 A(int);
8382 struct B : A {
8383 using A::A; // Inherited ctor.
8385 void f() {
8386 (B(0));
8389 Lang_CXX11);
8390 auto *FromD = FirstDeclMatcher<CXXConstructorDecl>().match(
8391 FromTU, cxxConstructorDecl(isInheritingConstructor()));
8392 ASSERT_TRUE(FromD);
8393 ASSERT_TRUE(FromD->isInheritingConstructor());
8395 auto *ToD = Import(FromD, Lang_CXX11);
8396 ASSERT_TRUE(ToD);
8397 EXPECT_TRUE(ToD->isInheritingConstructor());
8400 TEST_P(ASTImporterOptionSpecificTestBase, ImportConstructorUsingShadow) {
8401 TranslationUnitDecl *FromTU = getTuDecl(
8403 struct A {
8404 A(int, int);
8406 struct B : A {
8407 using A::A;
8409 struct C : B {
8410 using B::B;
8413 Lang_CXX11);
8415 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordC) {
8416 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match(
8417 TU, cxxRecordDecl(hasName("A")));
8418 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
8419 TU, cxxRecordDecl(hasName("B")));
8420 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match(
8421 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)),
8422 parameterCountIs(2)));
8423 auto *ShadowBA = cast<ConstructorUsingShadowDecl>(
8424 FirstDeclMatcher<UsingShadowDecl>().match(
8425 TU, usingShadowDecl(hasParent(equalsNode(RecordB)),
8426 hasTargetDecl(equalsNode(ConstrA)))));
8427 auto *ShadowCA = cast<ConstructorUsingShadowDecl>(
8428 FirstDeclMatcher<UsingShadowDecl>().match(
8429 TU, usingShadowDecl(hasParent(equalsNode(RecordC)),
8430 hasTargetDecl(equalsNode(ConstrA)))));
8431 EXPECT_EQ(ShadowBA->getTargetDecl(), ConstrA);
8432 EXPECT_EQ(ShadowBA->getNominatedBaseClass(), RecordA);
8433 EXPECT_EQ(ShadowBA->getConstructedBaseClass(), RecordA);
8434 EXPECT_EQ(ShadowBA->getNominatedBaseClassShadowDecl(), nullptr);
8435 EXPECT_EQ(ShadowBA->getConstructedBaseClassShadowDecl(), nullptr);
8436 EXPECT_FALSE(ShadowBA->constructsVirtualBase());
8437 EXPECT_EQ(ShadowCA->getTargetDecl(), ConstrA);
8438 EXPECT_EQ(ShadowCA->getNominatedBaseClass(), RecordB);
8439 EXPECT_EQ(ShadowCA->getConstructedBaseClass(), RecordB);
8440 EXPECT_EQ(ShadowCA->getNominatedBaseClassShadowDecl(), ShadowBA);
8441 EXPECT_EQ(ShadowCA->getConstructedBaseClassShadowDecl(), ShadowBA);
8442 EXPECT_FALSE(ShadowCA->constructsVirtualBase());
8445 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match(
8446 FromTU, cxxRecordDecl(hasName("C")));
8448 auto *ToC = Import(FromC, Lang_CXX11);
8449 TranslationUnitDecl *ToTU = ToC->getTranslationUnitDecl();
8451 CheckAST(FromTU, FromC);
8452 CheckAST(ToTU, ToC);
8455 TEST_P(ASTImporterOptionSpecificTestBase,
8456 ImportFunctionDeclBitShouldNotOverwriteCtorDeclBits) {
8457 Decl *From, *To;
8458 std::tie(From, To) = getImportedDecl(
8459 R"s(
8460 struct A {
8461 A() : m() {}
8462 int m;
8465 A foo() { A a; return a; }
8466 A bar() { return {}; }
8467 )s",
8468 Lang_CXX17,
8469 R"s(
8470 struct A {
8471 A() : m() {}
8472 int m;
8474 A baz() { return {}; }
8475 )s",
8476 Lang_CXX17, "A");
8478 auto HasCtorInit =
8479 hasAnyConstructorInitializer(cxxCtorInitializer(isMemberInitializer()));
8480 auto ImpMoveCtor =
8481 cxxConstructorDecl(isMoveConstructor(), isImplicit(), HasCtorInit);
8483 auto *FromImpMoveCtor = FirstDeclMatcher<CXXConstructorDecl>().match(
8484 From, ImpMoveCtor);
8485 auto *ToImpMoveCtor = FirstDeclMatcher<CXXConstructorDecl>().match(
8486 To, ImpMoveCtor);
8488 EXPECT_TRUE(FromImpMoveCtor->getNumCtorInitializers() == 1);
8489 EXPECT_FALSE(FromImpMoveCtor->FriendConstraintRefersToEnclosingTemplate());
8491 EXPECT_TRUE(ToImpMoveCtor->getNumCtorInitializers() == 1);
8492 EXPECT_FALSE(ToImpMoveCtor->FriendConstraintRefersToEnclosingTemplate());
8493 EXPECT_TRUE(*ToImpMoveCtor->init_begin());
8496 AST_MATCHER_P(UsingShadowDecl, hasIntroducerDecl, internal::Matcher<NamedDecl>,
8497 InnerMatcher) {
8498 return InnerMatcher.matches(*Node.getIntroducer(), Finder, Builder);
8501 TEST_P(ASTImporterOptionSpecificTestBase,
8502 ImportConstructorUsingShadowVirtualBase) {
8503 TranslationUnitDecl *FromTU = getTuDecl(
8505 struct A { A(int, int); };
8506 struct B : A { using A::A; };
8508 struct V1 : virtual B { using B::B; };
8509 struct V2 : virtual B { using B::B; };
8511 struct D2 : V1, V2 {
8512 using V1::V1;
8513 using V2::V2;
8516 Lang_CXX11);
8518 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordD2) {
8519 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match(
8520 TU, cxxRecordDecl(hasName("A")));
8521 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
8522 TU, cxxRecordDecl(hasName("B")));
8523 auto *RecordV1 = FirstDeclMatcher<CXXRecordDecl>().match(
8524 TU, cxxRecordDecl(hasName("V1")));
8525 auto *RecordV2 = FirstDeclMatcher<CXXRecordDecl>().match(
8526 TU, cxxRecordDecl(hasName("V2")));
8527 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match(
8528 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)),
8529 parameterCountIs(2)));
8530 auto *ConstrB = FirstDeclMatcher<CXXConstructorDecl>().match(
8531 TU, cxxConstructorDecl(hasParent(equalsNode(RecordB)),
8532 isCopyConstructor()));
8533 auto *UsingD2V1 = FirstDeclMatcher<UsingDecl>().match(
8534 TU, usingDecl(hasParent(equalsNode(RecordD2))));
8535 auto *UsingD2V2 = LastDeclMatcher<UsingDecl>().match(
8536 TU, usingDecl(hasParent(equalsNode(RecordD2))));
8537 auto *ShadowBA = cast<ConstructorUsingShadowDecl>(
8538 FirstDeclMatcher<UsingShadowDecl>().match(
8539 TU, usingShadowDecl(hasParent(equalsNode(RecordB)),
8540 hasTargetDecl(equalsNode(ConstrA)))));
8541 auto *ShadowV1A = cast<ConstructorUsingShadowDecl>(
8542 FirstDeclMatcher<UsingShadowDecl>().match(
8543 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)),
8544 hasTargetDecl(equalsNode(ConstrA)))));
8545 auto *ShadowV1B = cast<ConstructorUsingShadowDecl>(
8546 FirstDeclMatcher<UsingShadowDecl>().match(
8547 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)),
8548 hasTargetDecl(equalsNode(ConstrB)))));
8549 auto *ShadowV2A = cast<ConstructorUsingShadowDecl>(
8550 FirstDeclMatcher<UsingShadowDecl>().match(
8551 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)),
8552 hasTargetDecl(equalsNode(ConstrA)))));
8553 auto *ShadowV2B = cast<ConstructorUsingShadowDecl>(
8554 FirstDeclMatcher<UsingShadowDecl>().match(
8555 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)),
8556 hasTargetDecl(equalsNode(ConstrB)))));
8557 auto *ShadowD2V1A = cast<ConstructorUsingShadowDecl>(
8558 FirstDeclMatcher<UsingShadowDecl>().match(
8559 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8560 hasIntroducerDecl(equalsNode(UsingD2V1)),
8561 hasTargetDecl(equalsNode(ConstrA)))));
8562 auto *ShadowD2V1B = cast<ConstructorUsingShadowDecl>(
8563 FirstDeclMatcher<UsingShadowDecl>().match(
8564 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8565 hasIntroducerDecl(equalsNode(UsingD2V1)),
8566 hasTargetDecl(equalsNode(ConstrB)))));
8567 auto *ShadowD2V2A = cast<ConstructorUsingShadowDecl>(
8568 FirstDeclMatcher<UsingShadowDecl>().match(
8569 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8570 hasIntroducerDecl(equalsNode(UsingD2V2)),
8571 hasTargetDecl(equalsNode(ConstrA)))));
8572 auto *ShadowD2V2B = cast<ConstructorUsingShadowDecl>(
8573 FirstDeclMatcher<UsingShadowDecl>().match(
8574 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
8575 hasIntroducerDecl(equalsNode(UsingD2V2)),
8576 hasTargetDecl(equalsNode(ConstrB)))));
8578 EXPECT_EQ(ShadowD2V1A->getTargetDecl(), ConstrA);
8579 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClassShadowDecl(), ShadowV1A);
8580 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClass(), RecordV1);
8581 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClassShadowDecl(), ShadowBA);
8582 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClass(), RecordB);
8583 EXPECT_TRUE(ShadowD2V1A->constructsVirtualBase());
8584 EXPECT_EQ(ShadowD2V1B->getTargetDecl(), ConstrB);
8585 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClassShadowDecl(), ShadowV1B);
8586 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClass(), RecordV1);
8587 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClassShadowDecl(), nullptr);
8588 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClass(), RecordB);
8589 EXPECT_TRUE(ShadowD2V1B->constructsVirtualBase());
8590 EXPECT_EQ(ShadowD2V2A->getTargetDecl(), ConstrA);
8591 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClassShadowDecl(), ShadowV2A);
8592 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClass(), RecordV2);
8593 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClassShadowDecl(), ShadowBA);
8594 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClass(), RecordB);
8595 EXPECT_TRUE(ShadowD2V2A->constructsVirtualBase());
8596 EXPECT_EQ(ShadowD2V2B->getTargetDecl(), ConstrB);
8597 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClassShadowDecl(), ShadowV2B);
8598 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClass(), RecordV2);
8599 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClassShadowDecl(), nullptr);
8600 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClass(), RecordB);
8601 EXPECT_TRUE(ShadowD2V2B->constructsVirtualBase());
8603 EXPECT_TRUE(ShadowV1A->constructsVirtualBase());
8604 EXPECT_TRUE(ShadowV1B->constructsVirtualBase());
8605 EXPECT_TRUE(ShadowV2A->constructsVirtualBase());
8606 EXPECT_TRUE(ShadowV2B->constructsVirtualBase());
8607 EXPECT_FALSE(ShadowBA->constructsVirtualBase());
8610 auto *FromD2 = FirstDeclMatcher<CXXRecordDecl>().match(
8611 FromTU, cxxRecordDecl(hasName("D2")));
8613 auto *ToD2 = Import(FromD2, Lang_CXX11);
8614 TranslationUnitDecl *ToTU = ToD2->getTranslationUnitDecl();
8616 CheckAST(FromTU, FromD2);
8617 CheckAST(ToTU, ToD2);
8620 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingShadowList) {
8621 TranslationUnitDecl *FromTU = getTuDecl(
8623 struct A {
8624 void f();
8625 void f(int);
8627 struct B : A {
8628 using A::f;
8631 Lang_CXX11);
8633 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match(
8634 FromTU, cxxRecordDecl(hasName("B")));
8636 auto *ToB = Import(FromB, Lang_CXX11);
8637 TranslationUnitDecl *ToTU = ToB->getTranslationUnitDecl();
8639 auto *ToUsing = FirstDeclMatcher<UsingDecl>().match(
8640 ToTU, usingDecl(hasParent(equalsNode(ToB))));
8641 auto *ToUsingShadowF1 = FirstDeclMatcher<UsingShadowDecl>().match(
8642 ToTU, usingShadowDecl(hasTargetDecl(
8643 functionDecl(hasName("f"), parameterCountIs(0)))));
8644 auto *ToUsingShadowF2 = FirstDeclMatcher<UsingShadowDecl>().match(
8645 ToTU, usingShadowDecl(hasTargetDecl(
8646 functionDecl(hasName("f"), parameterCountIs(1)))));
8648 EXPECT_EQ(ToUsing->shadow_size(), 2u);
8649 auto ShadowI = ToUsing->shadow_begin();
8650 EXPECT_EQ(*ShadowI, ToUsingShadowF1);
8651 ++ShadowI;
8652 EXPECT_EQ(*ShadowI, ToUsingShadowF2);
8655 AST_MATCHER_P(FunctionTemplateDecl, templateParameterCountIs, unsigned, Cnt) {
8656 return Node.getTemplateParameters()->size() == Cnt;
8659 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuide) {
8660 TranslationUnitDecl *FromTU = getTuDecl(
8662 template<class> class A { };
8663 template<class T> class B {
8664 template<class T1, typename = A<T>> B(T1);
8666 template<class T>
8667 B(T, T) -> B<int>;
8669 Lang_CXX17);
8671 // Get the implicit deduction guide for (non-default) constructor of 'B'.
8672 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8673 FromTU, functionTemplateDecl(templateParameterCountIs(3)));
8674 // Implicit deduction guide for copy constructor of 'B'.
8675 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8676 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
8677 // User defined deduction guide.
8678 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8679 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
8681 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters();
8682 // Don't know why exactly but this is the DeclContext here.
8683 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(),
8684 FromDGCopyCtor->getTemplatedDecl());
8685 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(),
8686 FromDGCtor->getTemplatedDecl());
8687 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(),
8688 FromDGCtor->getTemplatedDecl());
8689 EXPECT_EQ(
8690 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8691 FromDGCopyCtor->getTemplatedDecl());
8692 EXPECT_EQ(FromDGOther->getDescribedTemplate()
8693 ->getTemplateParameters()
8694 ->getParam(0)
8695 ->getDeclContext(),
8696 FromDGOther);
8698 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17);
8699 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17);
8700 auto *ToDGOther = Import(FromDGOther, Lang_CXX17);
8701 ASSERT_TRUE(ToDGCtor);
8702 ASSERT_TRUE(ToDGCopyCtor);
8703 ASSERT_TRUE(ToDGOther);
8705 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters();
8706 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(),
8707 ToDGCopyCtor->getTemplatedDecl());
8708 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(),
8709 ToDGCtor->getTemplatedDecl());
8710 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(),
8711 ToDGCtor->getTemplatedDecl());
8712 EXPECT_EQ(
8713 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8714 ToDGCopyCtor->getTemplatedDecl());
8715 EXPECT_EQ(ToDGOther->getDescribedTemplate()
8716 ->getTemplateParameters()
8717 ->getParam(0)
8718 ->getDeclContext(),
8719 ToDGOther);
8722 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuideDifferentOrder) {
8723 // This test demonstrates that the DeclContext of the imported object is
8724 // dependent on the order of import. The test is an exact copy of the previous
8725 // one except at the indicated locations.
8726 TranslationUnitDecl *FromTU = getTuDecl(
8728 template<class> class A { };
8729 template<class T> class B {
8730 template<class T1, typename = A<T>> B(T1);
8732 template<class T>
8733 B(T, T) -> B<int>;
8735 Lang_CXX17);
8737 // Get the implicit deduction guide for (non-default) constructor of 'B'.
8738 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8739 FromTU, functionTemplateDecl(templateParameterCountIs(3)));
8740 // Implicit deduction guide for copy constructor of 'B'.
8741 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
8742 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
8743 // User defined deduction guide.
8744 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
8745 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
8747 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters();
8748 // Don't know why exactly but this is the DeclContext here.
8749 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(),
8750 FromDGCopyCtor->getTemplatedDecl());
8751 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(),
8752 FromDGCtor->getTemplatedDecl());
8753 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(),
8754 FromDGCtor->getTemplatedDecl());
8755 EXPECT_EQ(
8756 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8757 FromDGCopyCtor->getTemplatedDecl());
8758 EXPECT_EQ(FromDGOther->getDescribedTemplate()
8759 ->getTemplateParameters()
8760 ->getParam(0)
8761 ->getDeclContext(),
8762 FromDGOther);
8764 // Here the import of 'ToDGCopyCtor' and 'ToDGCtor' is reversed relative to
8765 // the previous test.
8766 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17);
8767 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17);
8768 auto *ToDGOther = Import(FromDGOther, Lang_CXX17);
8769 ASSERT_TRUE(ToDGCtor);
8770 ASSERT_TRUE(ToDGCopyCtor);
8771 ASSERT_TRUE(ToDGOther);
8773 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters();
8774 // Next line: DeclContext is different relative to the previous test.
8775 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(),
8776 ToDGCtor->getTemplatedDecl());
8777 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(),
8778 ToDGCtor->getTemplatedDecl());
8779 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(),
8780 ToDGCtor->getTemplatedDecl());
8781 // Next line: DeclContext is different relative to the previous test.
8782 EXPECT_EQ(
8783 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
8784 ToDGCtor->getTemplatedDecl());
8785 EXPECT_EQ(ToDGOther->getDescribedTemplate()
8786 ->getTemplateParameters()
8787 ->getParam(0)
8788 ->getDeclContext(),
8789 ToDGOther);
8792 TEST_P(ASTImporterOptionSpecificTestBase,
8793 ImportFieldsFirstForCorrectRecordLayout) {
8794 // UnaryOperator(&) triggers RecordLayout computation, which relies on
8795 // correctly imported fields.
8796 auto Code =
8798 class A {
8799 int m() {
8800 return &((A *)0)->f1 - &((A *)0)->f2;
8802 int f1;
8803 int f2;
8806 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
8808 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
8809 FromTU, cxxMethodDecl(hasName("A::m")));
8810 Import(FromF, Lang_CXX11);
8813 TEST_P(ASTImporterOptionSpecificTestBase,
8814 ImportCirularRefFieldsWithoutCorruptedRecordLayoutCache) {
8815 // Import sequence: A => A.b => B => B.f() => ... => UnaryOperator(&) => ...
8817 // UnaryOperator(&) should not introduce invalid RecordLayout since 'A' is
8818 // still not completely imported.
8819 auto Code =
8821 class B;
8822 class A {
8823 B* b;
8824 int c;
8826 class B {
8827 A *f() { return &((B *)0)->a; }
8828 A a;
8832 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
8833 getTuDecl(Code, Lang_CXX11), cxxRecordDecl(hasName("A")));
8834 FromR = FromR->getDefinition();
8835 auto &FromAST = FromR->getASTContext();
8836 auto *ToR = Import(FromR, Lang_CXX11);
8837 auto &ToAST = ToR->getASTContext();
8839 uint64_t SecondFieldOffset = FromAST.getTypeSize(FromAST.VoidPtrTy);
8841 EXPECT_TRUE(FromR->isCompleteDefinition());
8842 const auto &FromLayout = FromAST.getASTRecordLayout(FromR);
8843 EXPECT_TRUE(FromLayout.getFieldOffset(0) == 0);
8844 EXPECT_TRUE(FromLayout.getFieldOffset(1) == SecondFieldOffset);
8846 EXPECT_TRUE(ToR->isCompleteDefinition());
8847 const auto &ToLayout = ToAST.getASTRecordLayout(ToR);
8848 EXPECT_TRUE(ToLayout.getFieldOffset(0) == 0);
8849 EXPECT_TRUE(ToLayout.getFieldOffset(1) == SecondFieldOffset);
8852 TEST_P(ASTImporterOptionSpecificTestBase,
8853 ImportRecordWithLayoutRequestingExpr) {
8854 TranslationUnitDecl *FromTU = getTuDecl(
8856 struct A {
8857 int idx;
8858 static void foo(A x) {
8859 (void)&"text"[x.idx];
8863 Lang_CXX11);
8865 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8866 FromTU, cxxRecordDecl(hasName("A")));
8868 // Test that during import of 'foo' the record layout can be obtained without
8869 // crash.
8870 auto *ToA = Import(FromA, Lang_CXX11);
8871 EXPECT_TRUE(ToA);
8872 EXPECT_TRUE(ToA->isCompleteDefinition());
8875 TEST_P(ASTImporterOptionSpecificTestBase,
8876 ImportRecordWithLayoutRequestingExprDifferentRecord) {
8877 TranslationUnitDecl *FromTU = getTuDecl(
8879 struct B;
8880 struct A {
8881 int idx;
8882 B *b;
8884 struct B {
8885 static void foo(A x) {
8886 (void)&"text"[x.idx];
8890 Lang_CXX11);
8892 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
8893 FromTU, cxxRecordDecl(hasName("A")));
8895 // Test that during import of 'foo' the record layout (of 'A') can be obtained
8896 // without crash. It is not possible to have all of the fields of 'A' imported
8897 // at that time (without big code changes).
8898 auto *ToA = Import(FromA, Lang_CXX11);
8899 EXPECT_TRUE(ToA);
8900 EXPECT_TRUE(ToA->isCompleteDefinition());
8903 TEST_P(ASTImporterOptionSpecificTestBase, ImportInClassInitializerFromField) {
8904 // Encounter import of a field when the field already exists but has the
8905 // in-class initializer expression not yet set. Such case can occur in the AST
8906 // of generated template specializations.
8907 // The first code forces to create a template specialization of
8908 // `A<int>` but without implicit constructors.
8909 // The second ("From") code contains a variable of type `A<int>`, this
8910 // results in a template specialization that has constructors and
8911 // CXXDefaultInitExpr nodes.
8912 Decl *ToTU = getToTuDecl(
8914 void f();
8915 template<typename> struct A { int X = 1; };
8916 struct B { A<int> Y; };
8918 Lang_CXX11);
8919 auto *ToX = FirstDeclMatcher<FieldDecl>().match(
8920 ToTU,
8921 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8922 ASSERT_TRUE(ToX->hasInClassInitializer());
8923 ASSERT_FALSE(ToX->getInClassInitializer());
8925 Decl *FromTU = getTuDecl(
8927 void f();
8928 template<typename> struct A { int X = 1; };
8929 struct B { A<int> Y; };
8931 A<int> Z;
8933 Lang_CXX11, "input1.cc");
8934 auto *FromX = FirstDeclMatcher<FieldDecl>().match(
8935 FromTU,
8936 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8938 auto *ToXImported = Import(FromX, Lang_CXX11);
8939 EXPECT_EQ(ToXImported, ToX);
8940 EXPECT_TRUE(ToX->getInClassInitializer());
8943 TEST_P(ASTImporterOptionSpecificTestBase,
8944 ImportInClassInitializerFromCXXDefaultInitExpr) {
8945 // Encounter AST import of a CXXDefaultInitExpr where the "to-field"
8946 // of it exists but has the in-class initializer not set yet.
8947 Decl *ToTU = getToTuDecl(
8949 namespace N {
8950 template<typename> int b;
8951 struct X;
8953 template<typename> struct A { N::X *X = nullptr; };
8954 struct B { A<int> Y; };
8956 Lang_CXX14);
8957 auto *ToX = FirstDeclMatcher<FieldDecl>().match(
8958 ToTU,
8959 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8960 ASSERT_TRUE(ToX->hasInClassInitializer());
8961 ASSERT_FALSE(ToX->getInClassInitializer());
8963 Decl *FromTU = getTuDecl(
8965 namespace N {
8966 template<typename> int b;
8967 struct X;
8969 template<typename> struct A { N::X *X = nullptr; };
8970 struct B { A<int> Y; };
8972 void f() {
8973 (void)A<int>{};
8975 struct C {
8976 C(): attr(new A<int>{}){}
8977 A<int> *attr;
8978 const int value = N::b<C>;
8981 Lang_CXX14, "input1.cc");
8982 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
8983 FromTU, functionDecl(hasName("f"), isDefinition()));
8984 auto *ToF = Import(FromF, Lang_CXX11);
8985 EXPECT_TRUE(ToF);
8986 EXPECT_TRUE(ToX->getInClassInitializer());
8989 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) {
8990 const char *Code =
8992 struct AP_TECS;
8994 struct AP_Landing {
8995 AP_TECS *TECS_controller;
8998 struct AP_TECS {
8999 AP_Landing landing;
9002 class Plane {
9003 AP_TECS TECS_controller{landing};
9004 AP_Landing landing{&TECS_controller};
9007 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9009 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
9010 FromTU, cxxRecordDecl(hasName("Plane")));
9011 for (FieldDecl *F : FromR->fields())
9012 EXPECT_TRUE(F->getInClassInitializer());
9013 auto *ToR = Import(FromR, Lang_CXX11);
9014 for (FieldDecl *F : ToR->fields())
9015 EXPECT_TRUE(F->getInClassInitializer());
9018 TEST_P(ASTImporterOptionSpecificTestBase, ImportFieldInitializerWithItself) {
9019 const char *Code =
9021 class A {
9022 int a{a};
9025 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9026 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
9027 FromTU, cxxRecordDecl(hasName("A")));
9028 EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
9029 auto *ToA = Import(FromA, Lang_CXX11);
9030 EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
9033 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer1) {
9034 // FIXME: This is a example of recursive field initialization that is not
9035 // supported.
9036 // The following import chain occurs (not complete):
9037 // import of A => A.a => in-class initializer of A.a => ref_B() => B => B.b
9038 // => in-class initializer of B.b => ref_A() => CXXConstructExpr for A =>
9039 // CXXDefaultInitExpr for A.a => in-class initializer of A.a
9040 // in-class initializer of A.a is created in two different instances in this
9041 // case (import of FieldDecl and CXXDefaultInitExpr). Probably not a big
9042 // problem because it is an Expr (the second construction can be ignored
9043 // instead of assert). But such recursive init code should not occur in
9044 // practice.
9045 const char *Code =
9047 static int ref_A();
9048 static int ref_B();
9049 struct A {
9050 int a = ref_B();
9052 struct B {
9053 int b = ref_A();
9055 int ref_B() { B b; return b.b; }
9056 int ref_A() { A a; return a.a; }
9058 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9059 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
9060 FromTU, cxxRecordDecl(hasName("A")));
9061 EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
9062 // auto *ToA = Import(FromA, Lang_CXX11);
9063 // EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
9066 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
9067 Decl *FromTU = getTuDecl(
9069 int bar() {
9070 return 0;
9072 void other() {
9073 bar();
9076 Lang_CXX11);
9077 Decl *ToTU = getToTuDecl(
9079 int bar() {
9080 return 0;
9083 Lang_CXX11);
9084 auto *FromOther = FirstDeclMatcher<FunctionDecl>().match(
9085 FromTU, functionDecl(hasName("other")));
9086 ASSERT_TRUE(FromOther);
9088 auto *ToOther = Import(FromOther, Lang_CXX11);
9089 ASSERT_TRUE(ToOther);
9091 auto *ToBar = FirstDeclMatcher<FunctionDecl>().match(
9092 ToTU, functionDecl(hasName("bar")));
9094 EXPECT_TRUE(SharedStatePtr->isNewDecl(ToOther));
9095 EXPECT_FALSE(SharedStatePtr->isNewDecl(ToBar));
9098 struct ImportInjectedClassNameType : public ASTImporterOptionSpecificTestBase {
9099 protected:
9100 const CXXRecordDecl *findInjected(const CXXRecordDecl *Parent) {
9101 for (Decl *Found : Parent->decls()) {
9102 const auto *Record = dyn_cast<CXXRecordDecl>(Found);
9103 if (Record && Record->isInjectedClassName())
9104 return Record;
9106 return nullptr;
9109 void checkInjType(const CXXRecordDecl *D) {
9110 // The whole redecl chain should have the same InjectedClassNameType
9111 // instance. The injected record declaration is a separate chain, this
9112 // should contain the same type too.
9113 const Type *Ty = nullptr;
9114 for (const Decl *ReD : D->redecls()) {
9115 const auto *ReRD = cast<CXXRecordDecl>(ReD);
9116 EXPECT_TRUE(ReRD->getTypeForDecl());
9117 EXPECT_TRUE(!Ty || Ty == ReRD->getTypeForDecl());
9118 Ty = ReRD->getTypeForDecl();
9120 ASSERT_TRUE(Ty);
9121 const auto *InjTy = Ty->castAs<InjectedClassNameType>();
9122 EXPECT_TRUE(InjTy);
9123 if (CXXRecordDecl *Def = D->getDefinition()) {
9124 const CXXRecordDecl *InjRD = findInjected(Def);
9125 EXPECT_TRUE(InjRD);
9126 EXPECT_EQ(InjRD->getTypeForDecl(), InjTy);
9130 void testImport(Decl *ToTU, Decl *FromTU, Decl *FromD) {
9131 checkInjType(cast<CXXRecordDecl>(FromD));
9132 Decl *ToD = Import(FromD, Lang_CXX11);
9133 if (auto *ToRD = dyn_cast<CXXRecordDecl>(ToD))
9134 checkInjType(ToRD);
9137 const char *ToCodeA =
9139 template <class T>
9140 struct A;
9142 const char *ToCodeADef =
9144 template <class T>
9145 struct A {
9146 typedef A T1;
9149 const char *ToCodeC =
9151 template <class T>
9152 struct C;
9154 const char *ToCodeCDef =
9156 template <class T>
9157 struct A {
9158 typedef A T1;
9161 template <class T1, class T2>
9162 struct B {};
9164 template<class T>
9165 struct C {
9166 typedef typename A<T>::T1 T1;
9167 typedef B<T1, T> T2;
9168 typedef B<T1, C> T3;
9171 const char *FromCode =
9173 template <class T>
9174 struct A;
9175 template <class T>
9176 struct A {
9177 typedef A T1;
9179 template <class T>
9180 struct A;
9182 template <class T1, class T2>
9183 struct B {};
9185 template <class T>
9186 struct C;
9187 template <class T>
9188 struct C {
9189 typedef typename A<T>::T1 T1;
9190 typedef B<T1, T> T2;
9191 typedef B<T1, C> T3;
9193 template <class T>
9194 struct C;
9196 template <class T>
9197 struct D {
9198 void f(typename C<T>::T3 *);
9203 TEST_P(ImportInjectedClassNameType, ImportADef) {
9204 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11);
9205 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9206 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
9207 FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
9208 testImport(ToTU, FromTU, FromA);
9211 TEST_P(ImportInjectedClassNameType, ImportAFirst) {
9212 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11);
9213 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9214 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
9215 FromTU, cxxRecordDecl(hasName("A")));
9216 testImport(ToTU, FromTU, FromA);
9219 TEST_P(ImportInjectedClassNameType, ImportALast) {
9220 Decl *ToTU = getToTuDecl(ToCodeA, Lang_CXX11);
9221 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9222 auto *FromA = LastDeclMatcher<CXXRecordDecl>().match(
9223 FromTU, cxxRecordDecl(hasName("A")));
9224 testImport(ToTU, FromTU, FromA);
9227 TEST_P(ImportInjectedClassNameType, ImportADefToDef) {
9228 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11);
9229 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9230 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
9231 FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
9232 testImport(ToTU, FromTU, FromA);
9235 TEST_P(ImportInjectedClassNameType, ImportAFirstToDef) {
9236 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11);
9237 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9238 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
9239 FromTU, cxxRecordDecl(hasName("A")));
9240 testImport(ToTU, FromTU, FromA);
9243 TEST_P(ImportInjectedClassNameType, ImportALastToDef) {
9244 Decl *ToTU = getToTuDecl(ToCodeADef, Lang_CXX11);
9245 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9246 auto *FromA = LastDeclMatcher<CXXRecordDecl>().match(
9247 FromTU, cxxRecordDecl(hasName("A")));
9248 testImport(ToTU, FromTU, FromA);
9251 TEST_P(ImportInjectedClassNameType, ImportCDef) {
9252 Decl *ToTU = getToTuDecl(ToCodeC, Lang_CXX11);
9253 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9254 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match(
9255 FromTU, cxxRecordDecl(hasName("C"), isDefinition()));
9256 testImport(ToTU, FromTU, FromC);
9259 TEST_P(ImportInjectedClassNameType, ImportCLast) {
9260 Decl *ToTU = getToTuDecl(ToCodeC, Lang_CXX11);
9261 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9262 auto *FromC = LastDeclMatcher<CXXRecordDecl>().match(
9263 FromTU, cxxRecordDecl(hasName("C")));
9264 testImport(ToTU, FromTU, FromC);
9267 TEST_P(ImportInjectedClassNameType, ImportCDefToDef) {
9268 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11);
9269 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9270 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match(
9271 FromTU, cxxRecordDecl(hasName("C"), isDefinition()));
9272 testImport(ToTU, FromTU, FromC);
9275 TEST_P(ImportInjectedClassNameType, ImportCLastToDef) {
9276 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11);
9277 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9278 auto *FromC = LastDeclMatcher<CXXRecordDecl>().match(
9279 FromTU, cxxRecordDecl(hasName("C")));
9280 testImport(ToTU, FromTU, FromC);
9283 TEST_P(ImportInjectedClassNameType, ImportD) {
9284 Decl *ToTU = getToTuDecl("", Lang_CXX11);
9285 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9286 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
9287 FromTU, cxxRecordDecl(hasName("D"), isDefinition()));
9288 testImport(ToTU, FromTU, FromD);
9291 TEST_P(ImportInjectedClassNameType, ImportDToDef) {
9292 Decl *ToTU = getToTuDecl(ToCodeCDef, Lang_CXX11);
9293 Decl *FromTU = getTuDecl(FromCode, Lang_CXX11);
9294 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
9295 FromTU, cxxRecordDecl(hasName("D"), isDefinition()));
9296 testImport(ToTU, FromTU, FromD);
9299 TEST_P(ImportInjectedClassNameType, ImportTypedefType) {
9300 Decl *ToTU = getToTuDecl(
9302 template <class T>
9303 struct A {
9304 typedef A A1;
9305 void f(A1 *);
9308 Lang_CXX11);
9309 Decl *FromTU = getTuDecl(
9311 template <class T>
9312 struct A {
9313 typedef A A1;
9314 void f(A1 *);
9316 template<class T>
9317 void A<T>::f(A::A1 *) {}
9319 Lang_CXX11);
9321 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
9322 FromTU, functionDecl(hasName("f"), isDefinition()));
9323 auto *ToF = Import(FromF, Lang_CXX11);
9324 EXPECT_TRUE(ToF);
9325 ASTContext &ToCtx = ToF->getDeclContext()->getParentASTContext();
9327 auto *ToA1 =
9328 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("A1")));
9329 QualType ToInjTypedef = ToA1->getUnderlyingType().getCanonicalType();
9330 QualType ToInjParmVar =
9331 ToF->parameters()[0]->getType().getDesugaredType(ToCtx);
9332 ToInjParmVar =
9333 ToInjParmVar->getAs<PointerType>()->getPointeeType().getCanonicalType();
9334 EXPECT_TRUE(isa<InjectedClassNameType>(ToInjTypedef));
9335 EXPECT_TRUE(isa<InjectedClassNameType>(ToInjParmVar));
9336 EXPECT_TRUE(ToCtx.hasSameType(ToInjTypedef, ToInjParmVar));
9339 TEST_P(ASTImporterOptionSpecificTestBase, ImportMacroQualifiedType) {
9340 Decl *From, *To;
9341 std::tie(From, To) = getImportedDecl(
9343 #define CDECL __attribute__((cdecl))
9344 typedef void (CDECL *X)();
9346 Lang_CXX03, "", Lang_CXX03, "X");
9348 auto *FromTy =
9349 FirstDeclMatcher<MacroQualifiedType>().match(From, macroQualifiedType());
9350 auto *ToTy =
9351 FirstDeclMatcher<MacroQualifiedType>().match(To, macroQualifiedType());
9353 EXPECT_TRUE(isa<AttributedType>(FromTy->getUnderlyingType()));
9354 EXPECT_TRUE(isa<AttributedType>(ToTy->getUnderlyingType()));
9357 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplateName) {
9358 constexpr auto TestCode = R"(
9359 template <class T>
9360 struct A;
9361 template <class T>
9362 struct A {};
9363 template <template<class> class T = A>
9364 struct B {};
9365 using C = B<>;
9367 Decl *ToTU = getToTuDecl(TestCode, Lang_CXX11);
9368 Decl *FromTU = getTuDecl(TestCode, Lang_CXX11);
9370 auto *ToUsingFirst = FirstDeclMatcher<TypeAliasDecl>().match(
9371 ToTU, typeAliasDecl(hasName("C")));
9373 auto *FromUsing = FirstDeclMatcher<TypeAliasDecl>().match(
9374 FromTU, typeAliasDecl(hasName("C")));
9375 auto *ToUsing = Import(FromUsing, Lang_CXX11);
9376 EXPECT_TRUE(ToUsing);
9378 auto *ToB = FirstDeclMatcher<ClassTemplateDecl>().match(
9379 ToTU, classTemplateDecl(hasName("B")));
9380 auto *ToB1 = LastDeclMatcher<ClassTemplateDecl>().match(
9381 ToTU, classTemplateDecl(hasName("B")));
9382 // One template definition of 'B' should exist.
9383 EXPECT_EQ(ToB, ToB1);
9385 // These declarations are imported separately.
9386 EXPECT_NE(ToUsingFirst, ToUsing);
9388 auto SpB = ToB->spec_begin();
9389 auto SpE = ToB->spec_end();
9390 EXPECT_TRUE(SpB != SpE);
9391 ClassTemplateSpecializationDecl *Spec1 = *SpB;
9392 ++SpB;
9393 // The template 'B' should have one specialization (with default argument).
9394 EXPECT_TRUE(SpB == SpE);
9396 // Even if 'B' has one specialization with the default arguments, the AST
9397 // contains after the import two specializations that are linked in the
9398 // declaration chain. The 'spec_begin' iteration does not find these because
9399 // the template arguments are the same. But the imported type alias has the
9400 // link to the second specialization. The template name object in these
9401 // specializations must point to the same (and one) instance of definition of
9402 // 'B'.
9403 auto *Spec2 = cast<ClassTemplateSpecializationDecl>(
9404 ToUsing->getUnderlyingType()
9405 ->getAs<TemplateSpecializationType>()
9406 ->getAsRecordDecl());
9407 EXPECT_NE(Spec1, Spec2);
9408 EXPECT_TRUE(Spec1->getPreviousDecl() == Spec2 ||
9409 Spec2->getPreviousDecl() == Spec1);
9410 TemplateDecl *Templ1 =
9411 Spec1->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl();
9412 TemplateDecl *Templ2 =
9413 Spec2->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl();
9414 EXPECT_EQ(Templ1, Templ2);
9417 TEST_P(ASTImporterOptionSpecificTestBase, VaListC) {
9418 Decl *FromTU = getTuDecl(R"(typedef __builtin_va_list va_list;)", Lang_C99);
9420 auto *FromVaList = FirstDeclMatcher<TypedefDecl>().match(
9421 FromTU, typedefDecl(hasName("va_list")));
9422 ASSERT_TRUE(FromVaList);
9424 auto *ToVaList = Import(FromVaList, Lang_C99);
9425 ASSERT_TRUE(ToVaList);
9427 auto *ToBuiltinVaList = FirstDeclMatcher<TypedefDecl>().match(
9428 ToAST->getASTContext().getTranslationUnitDecl(),
9429 typedefDecl(hasName("__builtin_va_list")));
9431 ASSERT_TRUE(ToAST->getASTContext().hasSameType(
9432 ToVaList->getUnderlyingType(), ToBuiltinVaList->getUnderlyingType()));
9435 TEST_P(ASTImporterOptionSpecificTestBase, VaListCpp) {
9436 Decl *FromTU = getTuDecl(R"(typedef __builtin_va_list va_list;)", Lang_CXX03);
9438 auto *FromVaList = FirstDeclMatcher<TypedefDecl>().match(
9439 FromTU, typedefDecl(hasName("va_list")));
9440 ASSERT_TRUE(FromVaList);
9442 auto *ToVaList = Import(FromVaList, Lang_CXX03);
9443 ASSERT_TRUE(ToVaList);
9445 auto *ToBuiltinVaList = FirstDeclMatcher<TypedefDecl>().match(
9446 ToAST->getASTContext().getTranslationUnitDecl(),
9447 typedefDecl(hasName("__builtin_va_list")));
9449 ASSERT_TRUE(ToAST->getASTContext().hasSameType(
9450 ToVaList->getUnderlyingType(), ToBuiltinVaList->getUnderlyingType()));
9453 TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingTypedefToRecord) {
9454 const char *Code =
9456 struct S { int i; };
9457 typedef struct S T;
9458 extern T x;
9460 Decl *ToTU = getToTuDecl(Code, Lang_C99);
9461 Decl *FromTU = getTuDecl(Code, Lang_C99);
9463 auto *FromX =
9464 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x")));
9465 auto *ToX = Import(FromX, Lang_C99);
9466 EXPECT_TRUE(ToX);
9468 auto *Typedef1 =
9469 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9470 auto *Typedef2 =
9471 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9472 EXPECT_EQ(Typedef1, Typedef2);
9475 TEST_P(ASTImporterOptionSpecificTestBase,
9476 ImportExistingTypedefToUnnamedRecord) {
9477 const char *Code =
9479 typedef const struct { int f; } T;
9480 extern T x;
9482 Decl *ToTU = getToTuDecl(Code, Lang_C99);
9483 Decl *FromTU = getTuDecl(Code, Lang_C99);
9485 auto *FromX =
9486 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x")));
9487 auto *ToX = Import(FromX, Lang_C99);
9488 EXPECT_TRUE(ToX);
9490 auto *Typedef1 =
9491 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9492 auto *Typedef2 =
9493 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9494 EXPECT_NE(Typedef1, Typedef2);
9495 EXPECT_NE(Typedef1->getUnderlyingType().getTypePtr(),
9496 Typedef2->getUnderlyingType().getTypePtr());
9497 EXPECT_EQ(ToX->getType()->getAs<TypedefType>()->getDecl(), Typedef2);
9500 TEST_P(ASTImporterOptionSpecificTestBase, ImportTwoTypedefsToUnnamedRecord) {
9501 const char *Code =
9503 typedef struct { int f; } T1;
9504 typedef struct { int f; } T2;
9505 extern T1 x1;
9506 extern T2 x2;
9508 Decl *ToTU = getToTuDecl("", Lang_C99);
9509 Decl *FromTU = getTuDecl(Code, Lang_C99);
9511 auto *FromX1 =
9512 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x1")));
9513 auto *FromX2 =
9514 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x2")));
9515 auto *ToX1 = Import(FromX1, Lang_C99);
9516 EXPECT_TRUE(ToX1);
9517 auto *ToX2 = Import(FromX2, Lang_C99);
9518 EXPECT_TRUE(ToX2);
9520 auto *Typedef1 =
9521 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T1")));
9522 auto *Typedef2 =
9523 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T2")));
9524 EXPECT_NE(Typedef1->getUnderlyingType().getTypePtr(),
9525 Typedef2->getUnderlyingType().getTypePtr());
9528 TEST_P(ASTImporterOptionSpecificTestBase,
9529 ImportExistingTypedefToUnnamedRecordPtr) {
9530 const char *Code =
9532 typedef const struct { int fff; } * const T;
9533 extern T x;
9535 Decl *ToTU = getToTuDecl(Code, Lang_C99);
9536 Decl *FromTU = getTuDecl(Code, Lang_C99);
9538 auto *FromX =
9539 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("x")));
9540 auto *ToX = Import(FromX, Lang_C99);
9541 EXPECT_TRUE(ToX);
9543 auto *Typedef1 =
9544 FirstDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9545 auto *Typedef2 =
9546 LastDeclMatcher<TypedefDecl>().match(ToTU, typedefDecl(hasName("T")));
9547 // FIXME: These should be imported separately, like in the test above.
9548 // Or: In the test above these should be merged too.
9549 EXPECT_EQ(Typedef1, Typedef2);
9551 auto *FromR = FirstDeclMatcher<RecordDecl>().match(
9552 FromTU, recordDecl(hasDescendant(fieldDecl(hasName("fff")))));
9553 auto *ToRExisting = FirstDeclMatcher<RecordDecl>().match(
9554 ToTU, recordDecl(hasDescendant(fieldDecl(hasName("fff")))));
9555 ASSERT_TRUE(FromR);
9556 auto *ToRImported = Import(FromR, Lang_C99);
9557 // FIXME: If typedefs are not imported separately, do not import ToRImported
9558 // separately.
9559 EXPECT_NE(ToRExisting, ToRImported);
9562 TEST_P(ASTImporterOptionSpecificTestBase,
9563 ImportTypedefWithDifferentUnderlyingType) {
9564 const char *Code =
9566 using X1 = int;
9567 using Y1 = int;
9569 using RPB1 = X1*;
9570 typedef RPB1 RPX1;
9571 using RPB1 = Y1*; // redeclared
9572 typedef RPB1 RPY1;
9574 auto X = 0 ? (RPX1){} : (RPY1){};
9576 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9578 auto *FromX =
9579 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("X")));
9581 auto *FromXType = FromX->getType()->getAs<TypedefType>();
9582 EXPECT_FALSE(FromXType->typeMatchesDecl());
9584 auto *ToX = Import(FromX, Lang_CXX11);
9585 auto *ToXType = ToX->getType()->getAs<TypedefType>();
9586 // FIXME: This should be false.
9587 EXPECT_TRUE(ToXType->typeMatchesDecl());
9590 TEST_P(ASTImporterOptionSpecificTestBase,
9591 ImportTemplateArgumentWithPointerToDifferentInstantiation) {
9592 const char *CodeTo =
9594 template<class A>
9595 A f1() {
9596 return A();
9598 template<class A, A (B)()>
9599 class X {};
9601 X<int, f1<int>> x;
9603 const char *CodeFrom =
9605 template<class A>
9606 A f1();
9607 template<class A, A (B)()>
9608 class X {};
9610 X<int, f1<int>> x;
9612 Decl *ToTU = getToTuDecl(CodeTo, Lang_CXX11);
9613 Decl *FromTU = getTuDecl(CodeFrom, Lang_CXX11);
9615 auto *ToF1 = FirstDeclMatcher<FunctionDecl>().match(
9616 ToTU, functionDecl(hasName("f1"), isInstantiated()));
9617 auto *FromF1 = FirstDeclMatcher<FunctionDecl>().match(
9618 FromTU, functionDecl(hasName("f1"), isInstantiated()));
9619 EXPECT_TRUE(ToF1->isThisDeclarationADefinition());
9620 EXPECT_FALSE(FromF1->isThisDeclarationADefinition());
9622 auto *ToX = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
9623 ToTU, classTemplateSpecializationDecl(hasName("X")));
9624 auto *FromX = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
9625 FromTU, classTemplateSpecializationDecl(hasName("X")));
9627 Decl *ToTArgF = ToX->getTemplateArgs().get(1).getAsDecl();
9628 Decl *FromTArgF = FromX->getTemplateArgs().get(1).getAsDecl();
9629 EXPECT_EQ(ToTArgF, ToF1);
9630 EXPECT_EQ(FromTArgF, FromF1);
9632 auto *ToXImported = Import(FromX, Lang_CXX11);
9633 // The template argument 1 of 'X' in the "From" code points to a function
9634 // that has no definition. The import must ensure that this template argument
9635 // is imported in a way that it will point to the existing 'f1' function, not
9636 // to the 'f1' that is imported. In this way when specialization of 'X' is
9637 // imported it will have the same template arguments as the existing one.
9638 EXPECT_EQ(ToXImported, ToX);
9639 // FIXME: This matcher causes a crash "Tried to match orphan node".
9640 // The code is removed until the problem is fixed.
9641 // auto *ToF1Imported =
9642 // LastDeclMatcher<FunctionDecl>().match(ToTU,
9643 // functionDecl(hasName("f1"),isInstantiated()));
9644 // EXPECT_NE(ToF1Imported, ToF1);
9645 // EXPECT_EQ(ToF1Imported->getPreviousDecl(), ToF1);
9648 TEST_P(ASTImporterOptionSpecificTestBase,
9649 ImportTypeAliasTemplateAfterSimilarCalledTemplateTypeParm) {
9650 const char *Code =
9652 struct S;
9653 template <typename>
9654 using Callable = S;
9655 template <typename Callable>
9656 int bindingFunctionVTable;
9658 Decl *FromTU = getTuDecl(Code, Lang_CXX17);
9660 auto *FromCallable = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
9661 FromTU, typeAliasTemplateDecl(hasName("Callable")));
9663 auto *FromCallableParm = FirstDeclMatcher<TemplateTypeParmDecl>().match(
9664 FromTU, templateTypeParmDecl(hasName("Callable")));
9666 auto *ToFromCallableParm = Import(FromCallableParm, Lang_CXX17);
9667 auto *ToCallable = Import(FromCallable, Lang_CXX17);
9668 EXPECT_TRUE(ToFromCallableParm);
9669 EXPECT_TRUE(ToCallable);
9672 TEST_P(ASTImporterOptionSpecificTestBase, ImportConflictTypeAliasTemplate) {
9673 const char *ToCode =
9675 struct S;
9676 template <typename, typename>
9677 using Callable = S;
9679 const char *Code =
9681 struct S;
9682 template <typename>
9683 using Callable = S;
9685 (void)getToTuDecl(ToCode, Lang_CXX17);
9686 Decl *FromTU = getTuDecl(Code, Lang_CXX17);
9688 auto *FromCallable = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
9689 FromTU, typeAliasTemplateDecl(hasName("Callable")));
9691 auto *ImportedCallable = Import(FromCallable, Lang_CXX17);
9692 EXPECT_FALSE(ImportedCallable);
9695 AST_MATCHER(ClassTemplateSpecializationDecl, hasInstantiatedFromMember) {
9696 if (auto Instantiate = Node.getInstantiatedFrom()) {
9697 if (auto *FromPartialSpecialization =
9698 cast<ClassTemplatePartialSpecializationDecl *>(Instantiate)) {
9699 return nullptr != FromPartialSpecialization->getInstantiatedFromMember();
9702 return false;
9705 TEST_P(ASTImporterOptionSpecificTestBase, ImportInstantiatedFromMember) {
9706 const char *Code =
9708 template <typename> struct B {
9709 template <typename, bool = false> union D;
9710 template <typename T> union D<T> {};
9711 D<int> d;
9713 B<int> b;
9715 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9716 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
9717 FromTU, classTemplateSpecializationDecl(hasName("D"),
9718 hasInstantiatedFromMember()));
9719 auto *FromPartialSpecialization =
9720 cast<ClassTemplatePartialSpecializationDecl *>(
9721 FromD->getInstantiatedFrom());
9722 ASSERT_TRUE(FromPartialSpecialization->getInstantiatedFromMember());
9723 auto *ImportedPartialSpecialization =
9724 Import(FromPartialSpecialization, Lang_CXX11);
9725 EXPECT_TRUE(ImportedPartialSpecialization->getInstantiatedFromMember());
9728 AST_MATCHER_P(EnumDecl, hasEnumConstName, StringRef, ConstName) {
9729 for (EnumConstantDecl *D : Node.enumerators())
9730 if (D->getName() == ConstName)
9731 return true;
9732 return false;
9735 TEST_P(ASTImporterOptionSpecificTestBase, ImportAnonymousEnums) {
9736 const char *Code =
9738 struct A {
9739 enum { E1, E2 } x;
9740 enum { E3, E4 } y;
9743 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9744 auto *FromEnumE1 = FirstDeclMatcher<EnumDecl>().match(
9745 FromTU, enumDecl(hasEnumConstName("E1")));
9746 auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
9747 EXPECT_TRUE(ImportedEnumE1);
9748 auto *FromEnumE3 = FirstDeclMatcher<EnumDecl>().match(
9749 FromTU, enumDecl(hasEnumConstName("E3")));
9750 auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
9751 EXPECT_TRUE(ImportedEnumE3);
9752 EXPECT_NE(ImportedEnumE1, ImportedEnumE3);
9755 TEST_P(ASTImporterOptionSpecificTestBase, ImportFreeStandingAnonymousEnums) {
9756 const char *Code =
9758 struct A {
9759 enum { E1, E2 };
9760 enum { E3, E4 };
9763 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9764 auto *FromEnumE1 = FirstDeclMatcher<EnumDecl>().match(
9765 FromTU, enumDecl(hasEnumConstName("E1")));
9766 auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
9767 EXPECT_TRUE(ImportedEnumE1);
9768 auto *FromEnumE3 = FirstDeclMatcher<EnumDecl>().match(
9769 FromTU, enumDecl(hasEnumConstName("E3")));
9770 auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
9771 EXPECT_TRUE(ImportedEnumE3);
9772 EXPECT_NE(ImportedEnumE1, ImportedEnumE3);
9775 TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingAnonymousEnums) {
9776 const char *ToCode =
9778 struct A {
9779 enum { E1, E2 } x;
9780 enum { E3, E4 } y;
9783 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
9784 auto *ToEnumE1 = FirstDeclMatcher<EnumDecl>().match(
9785 ToTU, enumDecl(hasEnumConstName("E1")));
9786 auto *ToEnumE3 = FirstDeclMatcher<EnumDecl>().match(
9787 ToTU, enumDecl(hasEnumConstName("E3")));
9788 const char *Code =
9790 struct A {
9791 enum { E1, E2 } x;
9792 enum { E3, E4 } y;
9795 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9796 auto *FromEnumE1 = FirstDeclMatcher<EnumDecl>().match(
9797 FromTU, enumDecl(hasEnumConstName("E1")));
9798 auto *ImportedEnumE1 = Import(FromEnumE1, Lang_CXX11);
9799 ASSERT_TRUE(ImportedEnumE1);
9800 EXPECT_EQ(ImportedEnumE1, ToEnumE1);
9801 auto *FromEnumE3 = FirstDeclMatcher<EnumDecl>().match(
9802 FromTU, enumDecl(hasEnumConstName("E3")));
9803 auto *ImportedEnumE3 = Import(FromEnumE3, Lang_CXX11);
9804 ASSERT_TRUE(ImportedEnumE3);
9805 EXPECT_EQ(ImportedEnumE3, ToEnumE3);
9808 TEST_P(ASTImporterOptionSpecificTestBase, ImportExistingEmptyAnonymousEnums) {
9809 const char *ToCode =
9811 struct A {
9812 enum {};
9815 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
9816 auto *ToE1 = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl());
9817 const char *Code =
9819 struct A {
9820 enum {};
9821 enum {};
9824 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
9825 auto *FromE1 = FirstDeclMatcher<EnumDecl>().match(FromTU, enumDecl());
9826 auto *ImportedE1 = Import(FromE1, Lang_CXX11);
9827 ASSERT_TRUE(ImportedE1);
9828 EXPECT_EQ(ImportedE1, ToE1);
9829 auto *FromE2 = LastDeclMatcher<EnumDecl>().match(FromTU, enumDecl());
9830 ASSERT_NE(FromE1, FromE2);
9831 auto *ImportedE2 = Import(FromE2, Lang_CXX11);
9832 ASSERT_TRUE(ImportedE2);
9833 // FIXME: These should not be equal, or the import should fail.
9834 EXPECT_EQ(ImportedE2, ToE1);
9837 TEST_P(ASTImporterOptionSpecificTestBase, ImportMultipleAnonymousEnumDecls) {
9838 Decl *ToTU = getToTuDecl("", Lang_CXX03);
9839 Decl *FromTU = getTuDecl(
9841 struct foo {
9842 enum { A };
9843 enum { B };
9846 Lang_CXX03);
9848 auto EnumConstA = enumConstantDecl(hasName("A"));
9849 auto EnumConstB = enumConstantDecl(hasName("B"));
9851 auto *FromA = FirstDeclMatcher<EnumConstantDecl>().match(FromTU, EnumConstA);
9852 auto *FromB = FirstDeclMatcher<EnumConstantDecl>().match(FromTU, EnumConstB);
9854 auto *ToA = Import(FromA, Lang_CXX03);
9855 auto *ToB = Import(FromB, Lang_CXX03);
9857 ASSERT_TRUE(ToA);
9858 ASSERT_TRUE(ToB);
9860 auto *ToFooA = FirstDeclMatcher<CXXRecordDecl>().match(
9861 ToTU, tagDecl(has(enumDecl(has(EnumConstA)))));
9862 auto *ToFooB = FirstDeclMatcher<CXXRecordDecl>().match(
9863 ToTU, tagDecl(has(enumDecl(has(EnumConstB)))));
9864 ASSERT_EQ(ToFooA, ToFooB);
9866 // different EnumDecl
9867 auto *ToEnumDeclA =
9868 FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(has(EnumConstA)));
9869 auto *ToEnumDeclB =
9870 FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(has(EnumConstB)));
9871 ASSERT_NE(ToEnumDeclA, ToEnumDeclB);
9874 struct ImportTemplateParmDeclDefaultValue
9875 : public ASTImporterOptionSpecificTestBase {
9876 protected:
9877 void checkTemplateParams(RedeclarableTemplateDecl *D,
9878 RedeclarableTemplateDecl *InheritedFromD) {
9879 auto *NonTypeP =
9880 cast<NonTypeTemplateParmDecl>(D->getTemplateParameters()->getParam(0));
9881 auto *TypeP =
9882 cast<TemplateTypeParmDecl>(D->getTemplateParameters()->getParam(1));
9883 auto *TemplateP =
9884 cast<TemplateTemplateParmDecl>(D->getTemplateParameters()->getParam(2));
9885 if (InheritedFromD) {
9886 EXPECT_TRUE(NonTypeP->getDefaultArgStorage().isInherited());
9887 EXPECT_TRUE(TypeP->getDefaultArgStorage().isInherited());
9888 EXPECT_TRUE(TemplateP->getDefaultArgStorage().isInherited());
9889 EXPECT_EQ(NonTypeP->getDefaultArgStorage().getInheritedFrom(),
9890 InheritedFromD->getTemplateParameters()->getParam(0));
9891 EXPECT_EQ(TypeP->getDefaultArgStorage().getInheritedFrom(),
9892 InheritedFromD->getTemplateParameters()->getParam(1));
9893 EXPECT_EQ(TemplateP->getDefaultArgStorage().getInheritedFrom(),
9894 InheritedFromD->getTemplateParameters()->getParam(2));
9895 } else {
9896 EXPECT_FALSE(NonTypeP->getDefaultArgStorage().isInherited());
9897 EXPECT_FALSE(TypeP->getDefaultArgStorage().isInherited());
9898 EXPECT_FALSE(TemplateP->getDefaultArgStorage().isInherited());
9902 void testImport(RedeclarableTemplateDecl *FromD1,
9903 RedeclarableTemplateDecl *FromD2,
9904 RedeclarableTemplateDecl *FromD3,
9905 RedeclarableTemplateDecl *ToExistingD1) {
9906 auto *ToD1 = Import(FromD1, Lang_CXX14);
9907 auto *ToD2 = Import(FromD2, Lang_CXX14);
9908 auto *ToD3 = Import(FromD3, Lang_CXX14);
9909 checkTemplateParams(ToD1, nullptr);
9910 checkTemplateParams(ToD2, ToD1);
9911 checkTemplateParams(ToD3, ToExistingD1 ? ToExistingD1 : ToD1);
9914 // In these tests a circular dependency is created between the template
9915 // parameter default value and the template declaration (with the same
9916 // template parameter).
9917 template <class TemplateParmDeclT>
9918 void
9919 testTemplateParmDeclCircularDependency(ClassTemplateDecl *FromD,
9920 ClassTemplateDecl *FromDInherited) {
9921 auto GetTemplateParm =
9922 [](ClassTemplateDecl *D) -> const TemplateParmDeclT * {
9923 return dyn_cast<TemplateParmDeclT>(
9924 D->getTemplateParameters()->getParam(0));
9927 ASSERT_FALSE(GetTemplateParm(FromD)->getDefaultArgStorage().isInherited());
9928 ASSERT_TRUE(
9929 GetTemplateParm(FromDInherited)->getDefaultArgStorage().isInherited());
9931 auto *ToD = Import(FromD, Lang_CXX14);
9932 EXPECT_TRUE(ToD);
9934 auto *ToDInherited = Import(FromDInherited, Lang_CXX14);
9935 EXPECT_TRUE(ToDInherited);
9937 EXPECT_FALSE(GetTemplateParm(ToD)->getDefaultArgStorage().isInherited());
9938 EXPECT_TRUE(
9939 GetTemplateParm(ToDInherited)->getDefaultArgStorage().isInherited());
9940 EXPECT_EQ(GetTemplateParm(ToDInherited)
9941 ->getDefaultArgStorage()
9942 .getInheritedFrom(),
9943 GetTemplateParm(ToD));
9945 EXPECT_EQ(ToD->getPreviousDecl(), ToDInherited);
9948 const char *CodeFunction =
9950 template <class> struct X;
9952 template <int A = 2, typename B = int, template<class> class C = X>
9953 void test();
9954 template <int A, typename B, template<class> class C>
9955 void test();
9956 template <int A, typename B, template<class> class C>
9957 void test() {}
9960 const char *CodeClass =
9962 namespace N {
9963 template <class> struct X;
9965 template <int A = 2, typename B = int, template<class> class C = X>
9966 struct test;
9967 template <int A, typename B, template<class> class C>
9968 struct test;
9969 template <int A, typename B, template<class> class C>
9970 struct test {};
9974 const char *CodeVar =
9976 namespace N {
9977 template <class> struct X;
9979 template <int A = 2, typename B = int, template<class> class C = X>
9980 extern int test;
9981 template <int A, typename B, template<class> class C>
9982 extern int test;
9983 template <int A, typename B, template<class> class C>
9984 int test = A;
9989 TEST_P(ImportTemplateParmDeclDefaultValue, InvisibleInheritedFrom) {
9990 const char *ToCode =
9992 template <int P = 1>
9993 void f() {}
9995 TranslationUnitDecl *ToTU = getToTuDecl(ToCode, Lang_CXX14);
9996 auto *ToFDef = FirstDeclMatcher<FunctionTemplateDecl>().match(
9997 ToTU, functionTemplateDecl(hasName("f")));
9999 const char *FromCode =
10001 template <int P = 1>
10002 void f() {}
10003 template <int P>
10004 void f();
10006 TranslationUnitDecl *FromTU = getTuDecl(FromCode, Lang_CXX14);
10007 auto *FromFDef = FirstDeclMatcher<FunctionTemplateDecl>().match(
10008 FromTU, functionTemplateDecl(hasName("f")));
10009 auto *FromF = LastDeclMatcher<FunctionTemplateDecl>().match(
10010 FromTU, functionTemplateDecl(hasName("f")));
10012 auto *ToFDefImported = Import(FromFDef, Lang_CXX14);
10013 EXPECT_EQ(ToFDefImported, ToFDef);
10014 auto *ToF = Import(FromF, Lang_CXX14);
10015 EXPECT_NE(ToF, ToFDef);
10016 const auto *Parm = dyn_cast<NonTypeTemplateParmDecl>(
10017 ToF->getTemplateParameters()->getParam(0));
10018 EXPECT_TRUE(Parm->defaultArgumentWasInherited());
10019 // FIXME: This behavior may be confusing:
10020 // Default value is not inherited from the existing declaration, instead a new
10021 // is created at import that is similar to the existing but not reachable from
10022 // the AST.
10023 EXPECT_NE(Parm->getDefaultArgStorage().getInheritedFrom(),
10024 ToFDef->getTemplateParameters()->getParam(0));
10027 TEST_P(ImportTemplateParmDeclDefaultValue, DefValImportError) {
10028 const char *ToCode =
10030 class X {
10031 int A;
10034 getToTuDecl(ToCode, Lang_CXX14);
10036 const char *FromCode =
10038 class X;
10040 template <typename P = X>
10041 void f() {}
10043 class X {
10044 char A;
10047 TranslationUnitDecl *FromTU = getTuDecl(FromCode, Lang_CXX14);
10048 auto *FromF = FirstDeclMatcher<FunctionTemplateDecl>().match(
10049 FromTU, functionTemplateDecl(hasName("f")));
10051 auto *ToFImported = Import(FromF, Lang_CXX14);
10052 EXPECT_FALSE(ToFImported);
10055 TEST_P(ImportTemplateParmDeclDefaultValue, ImportFunctionTemplate) {
10056 TranslationUnitDecl *FromTU = getTuDecl(CodeFunction, Lang_CXX14);
10057 auto *D3 = LastDeclMatcher<FunctionTemplateDecl>().match(
10058 FromTU, functionTemplateDecl(hasName("test") /*, hasBody(stmt())*/));
10059 auto *D2 = dyn_cast<FunctionTemplateDecl>(D3->getPreviousDecl());
10060 auto *D1 = dyn_cast<FunctionTemplateDecl>(D2->getPreviousDecl());
10061 testImport(D1, D2, D3, nullptr);
10064 TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingFunctionTemplate) {
10065 TranslationUnitDecl *ToTU = getToTuDecl(CodeFunction, Lang_CXX14);
10066 auto *ToD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
10067 ToTU, functionTemplateDecl(hasName("test")));
10068 TranslationUnitDecl *FromTU = getTuDecl(CodeFunction, Lang_CXX14);
10069 auto *D3 = LastDeclMatcher<FunctionTemplateDecl>().match(
10070 FromTU, functionTemplateDecl(hasName("test")));
10071 auto *D2 = dyn_cast<FunctionTemplateDecl>(D3->getPreviousDecl());
10072 auto *D1 = dyn_cast<FunctionTemplateDecl>(D2->getPreviousDecl());
10073 testImport(D1, D2, D3, ToD1);
10076 TEST_P(ImportTemplateParmDeclDefaultValue, ImportClassTemplate) {
10077 TranslationUnitDecl *FromTU = getTuDecl(CodeClass, Lang_CXX14);
10078 auto *D3 = LastDeclMatcher<ClassTemplateDecl>().match(
10079 FromTU, classTemplateDecl(hasName("test")));
10080 auto *D2 = dyn_cast<ClassTemplateDecl>(D3->getPreviousDecl());
10081 auto *D1 = dyn_cast<ClassTemplateDecl>(D2->getPreviousDecl());
10082 testImport(D1, D2, D3, nullptr);
10085 TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingClassTemplate) {
10086 TranslationUnitDecl *ToTU = getToTuDecl(CodeClass, Lang_CXX14);
10087 auto *ToD1 = FirstDeclMatcher<ClassTemplateDecl>().match(
10088 ToTU, classTemplateDecl(hasName("test")));
10089 TranslationUnitDecl *FromTU = getTuDecl(CodeClass, Lang_CXX14);
10090 auto *D3 = LastDeclMatcher<ClassTemplateDecl>().match(
10091 FromTU, classTemplateDecl(hasName("test")));
10092 auto *D2 = dyn_cast<ClassTemplateDecl>(D3->getPreviousDecl());
10093 auto *D1 = dyn_cast<ClassTemplateDecl>(D2->getPreviousDecl());
10094 testImport(D1, D2, D3, ToD1);
10097 TEST_P(ImportTemplateParmDeclDefaultValue, ImportVarTemplate) {
10098 TranslationUnitDecl *FromTU = getTuDecl(CodeVar, Lang_CXX14);
10099 auto *D3 = LastDeclMatcher<VarTemplateDecl>().match(
10100 FromTU, varTemplateDecl(hasName("test")));
10101 auto *D2 = dyn_cast<VarTemplateDecl>(D3->getPreviousDecl());
10102 auto *D1 = dyn_cast<VarTemplateDecl>(D2->getPreviousDecl());
10103 testImport(D1, D2, D3, nullptr);
10106 TEST_P(ImportTemplateParmDeclDefaultValue, ImportExistingVarTemplate) {
10107 TranslationUnitDecl *ToTU = getToTuDecl(CodeVar, Lang_CXX14);
10108 auto *ToD1 = FirstDeclMatcher<VarTemplateDecl>().match(
10109 ToTU, varTemplateDecl(hasName("test")));
10110 TranslationUnitDecl *FromTU = getTuDecl(CodeVar, Lang_CXX14);
10111 auto *D3 = LastDeclMatcher<VarTemplateDecl>().match(
10112 FromTU, varTemplateDecl(hasName("test")));
10113 auto *D2 = dyn_cast<VarTemplateDecl>(D3->getPreviousDecl());
10114 auto *D1 = dyn_cast<VarTemplateDecl>(D2->getPreviousDecl());
10115 testImport(D1, D2, D3, ToD1);
10118 TEST_P(ImportTemplateParmDeclDefaultValue,
10119 NonTypeTemplateParmDeclCircularDependency) {
10120 const char *Code =
10122 struct Z;
10124 struct Y {
10125 Z *z;
10126 static const int x = 1;
10129 template <int P1 = Y::x>
10130 struct X;
10132 template <int P2>
10133 struct X {
10134 static const int A = 1;
10137 struct Z {
10138 template<int P>
10139 void f(int A = X<P>::A);
10143 Decl *FromTU = getTuDecl(Code, Lang_CXX14);
10144 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
10145 FromTU, classTemplateDecl(hasName("X")));
10146 auto *FromDInherited = LastDeclMatcher<ClassTemplateDecl>().match(
10147 FromTU, classTemplateDecl(hasName("X")));
10149 testTemplateParmDeclCircularDependency<NonTypeTemplateParmDecl>(
10150 FromD, FromDInherited);
10153 TEST_P(ImportTemplateParmDeclDefaultValue,
10154 TemplateTypeParmDeclCircularDependency) {
10155 const char *Code =
10157 struct Z;
10159 struct Y {
10160 Z *z;
10163 template <typename T1 = Y>
10164 struct X;
10166 template <typename T2>
10167 struct X {
10168 static const int A = 1;
10171 struct Z {
10172 template<typename T>
10173 void f(int A = X<T>::A);
10177 Decl *FromTU = getTuDecl(Code, Lang_CXX14);
10178 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
10179 FromTU, classTemplateDecl(hasName("X")));
10180 auto *FromDInherited = LastDeclMatcher<ClassTemplateDecl>().match(
10181 FromTU, classTemplateDecl(hasName("X")));
10183 testTemplateParmDeclCircularDependency<TemplateTypeParmDecl>(FromD,
10184 FromDInherited);
10187 TEST_P(ImportTemplateParmDeclDefaultValue,
10188 TemplateTemplateParmDeclCircularDependency) {
10189 const char *Code =
10191 struct Z;
10193 template <int>
10194 struct Y {
10195 Z *z;
10198 template <template <int> class T1 = Y>
10199 struct X;
10201 template <template <int> class T2>
10202 struct X {
10203 static const int A = 1;
10206 struct Z {
10207 template <template <int> class T>
10208 void f(int A = X<T>::A);
10212 Decl *FromTU = getTuDecl(Code, Lang_CXX14);
10213 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
10214 FromTU, classTemplateDecl(hasName("X")));
10215 auto *FromDInherited = LastDeclMatcher<ClassTemplateDecl>().match(
10216 FromTU, classTemplateDecl(hasName("X")));
10218 testTemplateParmDeclCircularDependency<TemplateTemplateParmDecl>(
10219 FromD, FromDInherited);
10222 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceNoMatch1) {
10223 const char *ToCode =
10225 namespace a {
10227 namespace a {
10228 struct X { int A; };
10231 getToTuDecl(ToCode, Lang_CXX11);
10232 const char *Code =
10234 namespace a {
10235 struct X { char A; };
10238 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
10239 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
10240 FromTU, cxxRecordDecl(hasName("X")));
10241 auto *ImportedX = Import(FromX, Lang_CXX11);
10242 EXPECT_FALSE(ImportedX);
10245 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceNoMatch2) {
10246 const char *ToCode =
10248 namespace a {
10249 struct X { int A; };
10251 namespace a {
10254 getToTuDecl(ToCode, Lang_CXX11);
10255 const char *Code =
10257 namespace a {
10258 struct X { char A; };
10261 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
10262 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
10263 FromTU, cxxRecordDecl(hasName("X")));
10264 auto *ImportedX = Import(FromX, Lang_CXX11);
10265 EXPECT_FALSE(ImportedX);
10268 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceMatch1) {
10269 const char *ToCode =
10271 namespace a {
10273 namespace a {
10274 struct X { int A; };
10277 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
10278 const char *Code =
10280 namespace a {
10281 struct X { int A; };
10284 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
10285 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
10286 FromTU, cxxRecordDecl(hasName("X")));
10287 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match(
10288 ToTU, cxxRecordDecl(hasName("X")));
10289 auto *ImportedX = Import(FromX, Lang_CXX11);
10290 EXPECT_EQ(ImportedX, ToX);
10293 TEST_P(ASTImporterOptionSpecificTestBase, ImportIntoReopenedNamespaceMatch2) {
10294 const char *ToCode =
10296 namespace a {
10297 struct X { int A; };
10299 namespace a {
10302 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
10303 const char *Code =
10305 namespace a {
10306 struct X { int A; };
10309 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
10310 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
10311 FromTU, cxxRecordDecl(hasName("X")));
10312 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match(
10313 ToTU, cxxRecordDecl(hasName("X")));
10314 auto *ImportedX = Import(FromX, Lang_CXX11);
10315 EXPECT_EQ(ImportedX, ToX);
10318 TEST_P(ASTImporterLookupTableTest, PrimaryDCChangeAtImport) {
10319 const char *ToCode =
10321 template <class T>
10322 struct X;
10324 Decl *ToTU = getToTuDecl(ToCode, Lang_CXX11);
10325 auto *ToX = FirstDeclMatcher<ClassTemplateDecl>().match(
10326 ToTU, classTemplateDecl(hasName("X")));
10327 NamedDecl *ToParm = ToX->getTemplateParameters()->getParam(0);
10328 DeclContext *OldPrimaryDC = ToX->getTemplatedDecl()->getPrimaryContext();
10329 ASSERT_EQ(ToParm->getDeclContext(), ToX->getTemplatedDecl());
10330 ASSERT_EQ(SharedStatePtr->getLookupTable()
10331 ->lookup(ToX->getTemplatedDecl(), ToParm->getDeclName())
10332 .size(),
10333 1u);
10334 ASSERT_TRUE(SharedStatePtr->getLookupTable()->contains(
10335 ToX->getTemplatedDecl(), ToParm));
10337 const char *Code =
10339 template <class T>
10340 struct X;
10341 template <class T>
10342 struct X {};
10344 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
10345 auto *FromX = LastDeclMatcher<ClassTemplateDecl>().match(
10346 FromTU, classTemplateDecl(hasName("X")));
10348 auto *ImportedX = Import(FromX, Lang_CXX11);
10350 EXPECT_TRUE(ImportedX);
10351 EXPECT_EQ(ImportedX->getTemplateParameters()->getParam(0)->getDeclContext(),
10352 ImportedX->getTemplatedDecl());
10354 // ToX did not change at the import.
10355 // Verify that primary context has changed after import of class definition.
10356 DeclContext *NewPrimaryDC = ToX->getTemplatedDecl()->getPrimaryContext();
10357 EXPECT_NE(OldPrimaryDC, NewPrimaryDC);
10358 // The lookup table should not be different than it was before.
10359 EXPECT_EQ(SharedStatePtr->getLookupTable()
10360 ->lookup(ToX->getTemplatedDecl(), ToParm->getDeclName())
10361 .size(),
10362 1u);
10363 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
10364 ToX->getTemplatedDecl(), ToParm));
10367 TEST_P(ASTImporterOptionSpecificTestBase,
10368 ExistingUndeclaredImportDeclaredFriend) {
10369 Decl *ToTU = getToTuDecl(
10371 template <class A, A>
10372 struct foo;
10374 template <class A>
10375 struct X {
10376 template <class A1, A1>
10377 friend struct foo;
10380 Lang_CXX11);
10381 Decl *FromTU = getTuDecl(
10383 template <class A, A>
10384 struct foo;
10386 template <class A>
10387 struct X {
10388 template <class A1, A1>
10389 friend struct foo;
10392 X<int> x;
10394 Lang_CXX11);
10396 auto *ToFr1 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
10397 auto *ToFrD1 = ToFr1->getFriendDecl();
10399 auto *FromFr1 = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl());
10400 auto *FromFr2 = LastDeclMatcher<FriendDecl>().match(FromTU, friendDecl());
10402 auto *FromFrD1 = FromFr1->getFriendDecl();
10403 auto *FromFrD2 = FromFr2->getFriendDecl();
10405 auto *Ctx1 = cast<Decl>(FromFrD1->getDeclContext());
10406 auto *Ctx2 = cast<Decl>(FromFrD2->getDeclContext());
10408 ASSERT_EQ(Ctx1, Ctx2);
10409 ASSERT_EQ(ToFrD1->getTemplateDepth(), 1u);
10410 ASSERT_EQ(FromFrD2->getTemplateDepth(), 0u);
10411 ASSERT_EQ(ToFrD1->getFriendObjectKind(), Decl::FOK_Undeclared);
10412 ASSERT_EQ(FromFrD2->getFriendObjectKind(), Decl::FOK_Declared);
10414 auto *ToFr2Imp = Import(FromFr2, Lang_CXX11);
10416 EXPECT_TRUE(ToFr2Imp);
10419 TEST_P(ASTImporterOptionSpecificTestBase,
10420 ExistingDeclaredImportUndeclaredFriend) {
10421 Decl *ToTU = getToTuDecl(
10423 template <class A, A>
10424 struct foo;
10426 template <class A>
10427 struct X {
10428 template <class A1, A1>
10429 friend struct foo;
10432 X<int> x;
10434 Lang_CXX11);
10435 Decl *FromTU = getTuDecl(
10437 template <class A, A>
10438 struct foo;
10440 template <class A>
10441 struct X {
10442 template <class A1, A1>
10443 friend struct foo;
10446 Lang_CXX11);
10448 auto *ToFr1 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
10449 auto *ToFr2 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
10451 auto *ToFrD1 = ToFr1->getFriendDecl();
10452 auto *ToFrD2 = ToFr2->getFriendDecl();
10454 auto *FromFr1 = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl());
10455 auto *FromFrD1 = FromFr1->getFriendDecl();
10457 auto *Ctx1 = cast<Decl>(ToFrD1->getDeclContext());
10458 auto *Ctx2 = cast<Decl>(ToFrD2->getDeclContext());
10460 ASSERT_EQ(Ctx1, Ctx2);
10461 ASSERT_EQ(FromFrD1->getTemplateDepth(), 1u);
10462 ASSERT_EQ(ToFrD2->getTemplateDepth(), 0u);
10463 ASSERT_EQ(FromFrD1->getFriendObjectKind(), Decl::FOK_Undeclared);
10464 ASSERT_EQ(ToFrD2->getFriendObjectKind(), Decl::FOK_Declared);
10466 auto *ToFr1Imp = Import(FromFr1, Lang_CXX11);
10468 EXPECT_TRUE(ToFr1Imp);
10469 EXPECT_EQ(ToFr1Imp, ToFr1);
10472 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
10473 DefaultTestValuesForRunOptions);
10475 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportPath,
10476 ::testing::Values(std::vector<std::string>()));
10478 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportExpr,
10479 DefaultTestValuesForRunOptions);
10481 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFixedPointExpr,
10482 ExtendWithOptions(DefaultTestArrayForRunOptions,
10483 std::vector<std::string>{
10484 "-ffixed-point"}));
10486 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportBlock,
10487 ExtendWithOptions(DefaultTestArrayForRunOptions,
10488 std::vector<std::string>{
10489 "-fblocks"}));
10491 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportType,
10492 DefaultTestValuesForRunOptions);
10494 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportDecl,
10495 DefaultTestValuesForRunOptions);
10497 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase,
10498 DefaultTestValuesForRunOptions);
10500 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ErrorHandlingTest,
10501 DefaultTestValuesForRunOptions);
10503 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, RedirectingImporterTest,
10504 DefaultTestValuesForRunOptions);
10506 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctions,
10507 DefaultTestValuesForRunOptions);
10509 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAutoFunctions,
10510 DefaultTestValuesForRunOptions);
10512 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctionTemplates,
10513 DefaultTestValuesForRunOptions);
10515 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctionTemplates,
10516 DefaultTestValuesForRunOptions);
10518 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportClasses,
10519 DefaultTestValuesForRunOptions);
10521 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctions,
10522 DefaultTestValuesForRunOptions);
10524 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendClasses,
10525 DefaultTestValuesForRunOptions);
10527 INSTANTIATE_TEST_SUITE_P(ParameterizedTests,
10528 ImportFunctionTemplateSpecializations,
10529 DefaultTestValuesForRunOptions);
10531 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportImplicitMethods,
10532 DefaultTestValuesForRunOptions);
10534 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportVariables,
10535 DefaultTestValuesForRunOptions);
10537 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, LLDBLookupTest,
10538 DefaultTestValuesForRunOptions);
10540 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportSourceLocations,
10541 DefaultTestValuesForRunOptions);
10543 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportWithExternalSource,
10544 DefaultTestValuesForRunOptions);
10546 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAttributes,
10547 DefaultTestValuesForRunOptions);
10549 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportInjectedClassNameType,
10550 DefaultTestValuesForRunOptions);
10552 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportMatrixType,
10553 DefaultTestValuesForRunOptions);
10555 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportTemplateParmDeclDefaultValue,
10556 DefaultTestValuesForRunOptions);
10558 // FIXME: Make ImportOpenCLPipe test work.
10559 // INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportOpenCLPipe,
10560 // DefaultTestValuesForRunOptions);
10561 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImportOpenCLPipe);
10563 } // end namespace ast_matchers
10564 } // end namespace clang