1 //===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===//
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
7 //===----------------------------------------------------------------------===//
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"
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
));
81 struct RedirectingImporter
: public ASTImporter
{
82 using ASTImporter::ASTImporter
;
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
);
96 return ASTImporter::ImportImpl(FromD
);
102 struct RedirectingImporterTest
: ASTImporterOptionSpecificTestBase
{
103 RedirectingImporterTest() {
104 Creator
= [](ASTContext
&ToContext
, FileManager
&ToFileManager
,
105 ASTContext
&FromContext
, FileManager
&FromFileManager
,
107 const std::shared_ptr
<ASTImporterSharedState
> &SharedState
) {
108 return new RedirectingImporter(ToContext
, ToFileManager
, FromContext
,
109 FromFileManager
, MinimalImport
,
115 // Test that an ASTImporter subclass can intercept an import call.
116 TEST_P(RedirectingImporterTest
, InterceptImport
) {
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"));
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
) {
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"));
145 DeclCounterWithPredicate
<CXXRecordDecl
>().match(ToTU
, Pattern
);
146 EXPECT_EQ(0U, count
);
149 struct ImportPath
: ASTImporterOptionSpecificTestBase
{
151 FunctionDecl
*D0
, *D1
, *D2
;
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
;
164 EXPECT_FALSE(path
.hasCycleAtBack());
167 TEST_P(ImportPath
, SmallCycle
) {
168 ASTImporter::ImportPathTy path
;
171 EXPECT_TRUE(path
.hasCycleAtBack());
173 EXPECT_FALSE(path
.hasCycleAtBack());
175 EXPECT_TRUE(path
.hasCycleAtBack());
178 TEST_P(ImportPath
, GetSmallCycle
) {
179 ASTImporter::ImportPathTy path
;
182 EXPECT_TRUE(path
.hasCycleAtBack());
183 std::array
<Decl
* ,2> Res
;
185 for (Decl
*Di
: path
.getCycleAtBack()) {
189 EXPECT_EQ(Res
[0], D0
);
190 EXPECT_EQ(Res
[1], D0
);
193 TEST_P(ImportPath
, GetCycle
) {
194 ASTImporter::ImportPathTy path
;
199 EXPECT_TRUE(path
.hasCycleAtBack());
200 std::array
<Decl
* ,4> Res
;
202 for (Decl
*Di
: path
.getCycleAtBack()) {
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
;
220 EXPECT_TRUE(path
.hasCycleAtBack());
221 std::array
<Decl
* ,4> Res
;
223 for (Decl
*Di
: path
.getCycleAtBack()) {
227 EXPECT_EQ(Res
[0], D0
);
228 EXPECT_EQ(Res
[1], D2
);
229 EXPECT_EQ(Res
[2], D1
);
230 EXPECT_EQ(Res
[3], D0
);
235 EXPECT_TRUE(path
.hasCycleAtBack());
237 for (Decl
*Di
: path
.getCycleAtBack()) {
241 EXPECT_EQ(Res
[0], D0
);
242 EXPECT_EQ(Res
[1], D1
);
243 EXPECT_EQ(Res
[2], D0
);
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
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
>
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);
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
;
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
;
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
,
345 functionDecl(hasDescendant(
346 floatLiteral(equals(1.0), hasType(asString("double"))))));
347 testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99
, "", Lang_C99
,
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
;
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")),
378 hasType(asString("struct s")),
379 has(integerLiteral(equals(42), hasType(asString("int")))),
380 has(integerLiteral(equals(0), hasType(asString("long")))),
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
;
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(
431 hasBody(compoundStmt(has(declStmt(hasSingleDecl(varDecl(
432 hasInitializer(parenListExpr(has(unaryOperator(
433 hasOperatorName("*"),
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
;
449 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
450 Lang_C99
, "", Lang_C99
, Verifier
,
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
;
475 "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03
, "", Lang_CXX03
,
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
;
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,"
526 Lang_CXX03
, "", Lang_CXX03
, Verifier
,
527 functionDecl(hasDescendant(initListExpr(
528 has(cxxConstructExpr(requiresZeroInitialization())),
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
>
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())))))));
548 "struct X { int A = 5; }; X declToImport{};", Lang_CXX17
, "", Lang_CXX17
,
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
>
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
;
580 "void declToImport() { C c = C(); }",
581 Lang_CXX03
, "", Lang_CXX03
, Verifier
,
583 functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr(
584 has(materializeTemporaryExpr(has(implicitCastExpr(
585 has(cxxTemporaryObjectExpr()))))))))))));
588 TEST_P(ImportType
, ImportAtomicType
) {
589 MatchVerifier
<Decl
> Verifier
;
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
;
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
;
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
;
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() {"
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() {"
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
;
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
,
732 functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))),
734 translationUnitDecl(has(typeAliasDecl())))))));
737 const internal::VariadicDynCastAllOfMatcher
<Decl
, VarTemplateSpecializationDecl
>
738 varTemplateSpecializationDecl
;
740 TEST_P(ImportDecl
, ImportVarTemplate
) {
741 MatchVerifier
<Decl
> Verifier
;
743 "template <typename T>"
744 "T pi = T(3.1415926535897932385L);"
745 "void declToImport() { (void)pi<int>; }",
746 Lang_CXX14
, "", Lang_CXX14
, Verifier
,
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>"
757 " dummy(Args... args) {}"
758 " static const int i = 4;"
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>"
770 "template<typename T>"
771 "struct declToImport {"
772 " typename A<T>::template B<T> a;"
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
>
792 TEST_P(ImportExpr
, ImportSizeOfPackExpr
) {
793 MatchVerifier
<Decl
> Verifier
;
795 "template <typename... Ts>"
796 "void declToImport() {"
797 " const int i = sizeof...(Ts);"
799 "void g() { declToImport<int>(); }",
800 Lang_CXX11
, "", Lang_CXX11
, Verifier
,
801 functionTemplateDecl(hasDescendant(sizeOfPackExpr())));
803 "template <typename... Ts>"
804 "using X = int[sizeof...(Ts)];"
805 "template <typename... Us>"
807 " X<Us..., int, double, int, Us...> f;"
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())));
819 cxxFoldExpr(hasOperatorName("-"), isLeftFold(), hasFoldInit(expr()));
820 auto Match3
= cxxFoldExpr(hasOperatorName("*"), isRightFold(),
821 unless(hasFoldInit(expr())));
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);"
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
844 /// __builtin_types_compatible_p(int, int)
846 // will generate TypeTraitExpr <...> 'int'
847 const internal::VariadicDynCastAllOfMatcher
<Stmt
, TypeTraitExpr
> typeTraitExpr
;
849 TEST_P(ImportExpr
, ImportTypeTraitExpr
) {
850 MatchVerifier
<Decl
> Verifier
;
852 "void declToImport() { "
853 " (void)__builtin_types_compatible_p(int, int);"
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
;
864 "namespace std { class type_info {}; }"
865 "void declToImport() {"
867 " auto a = typeid(int); auto b = typeid(x);"
869 Lang_CXX11
, "", Lang_CXX11
, Verifier
,
873 hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant(
875 hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant(
876 cxxTypeidExpr())))))));
879 TEST_P(ImportExpr
, ImportTypeTraitExprValDep
) {
880 MatchVerifier
<Decl
> Verifier
;
882 "template<typename T> struct declToImport {"
883 " void m() { (void)__is_pod(T); }"
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;};"
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;};"
916 Lang_C99
, "input.c");
918 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("d")));
919 ASSERT_TRUE(FromVar
);
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")));
933 auto *To
= Import(From
, Lang_C99
);
934 EXPECT_EQ(To
, nullptr);
937 TEST_P(ASTImporterOptionSpecificTestBase
, ImportRecordDeclInFuncFromMacro
) {
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")));
945 auto *To
= Import(From
, Lang_C99
);
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.
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")));
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
;
973 "void declToImport(int *p) {"
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
;
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.
1029 /// namespace n { int f; }
1030 /// namespace declToImport { using n::f; }
1032 /// usingShadowDecl()
1033 /// matches \code f \endcode
1034 const internal::VariadicDynCastAllOfMatcher
<Decl
,
1035 UsingShadowDecl
> usingShadowDecl
;
1037 TEST_P(ImportDecl
, ImportUsingShadowDecl
) {
1038 MatchVerifier
<Decl
> Verifier
;
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() {"
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() {"
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() {"
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
;
1106 struct declToImport {
1107 template <typename T0> struct X;
1108 template <typename T0> struct X<T0 *> {};
1111 testImport(Code
, Lang_CXX03
, "", Lang_CXX03
, Verifier
,
1112 recordDecl(has(classTemplateDecl()),
1113 has(classTemplateSpecializationDecl())));
1116 TEST_P(ImportExpr
, CXXOperatorCallExpr
) {
1117 MatchVerifier
<Decl
> Verifier
;
1119 "class declToImport {"
1120 " void f() { *this = declToImport(); }"
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 {"
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;"
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()...; };"
1155 auto From
= FirstDeclMatcher
<UsingPackDecl
>().match(FromTU
, usingPackDecl());
1157 auto To
= cast
<UsingPackDecl
>(Import(From
, Lang_CXX20
));
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
) {
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
) {
1193 getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }",
1195 auto From
= FirstDeclMatcher
<FunctionDecl
>().match(
1196 FromTU
, functionDecl(hasName("f")));
1199 cast
<CStyleCastExpr
>(cast
<CompoundStmt
>(From
->getBody())->body_front())
1203 FunctionDecl
*To
= Import(From
, Lang_CXX03
);
1206 cast
<CStyleCastExpr
>(cast
<CompoundStmt
>(To
->getBody())->body_front())
1212 TEST_P(ASTImporterOptionSpecificTestBase
,
1213 TemplateTemplateParmDeclNoDefaultArg
) {
1214 Decl
*FromTU
= getTuDecl(R
"(
1215 template<template<typename> typename TT> struct Y {};
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 {};
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,
1269 template<typename> typename TT = X> struct S {};
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
);
1288 FirstDeclMatcher
<ClassTemplateDecl
>().match(FromTU
, classTemplateDecl());
1290 auto To
= cast
<ClassTemplateDecl
>(Import(From
, Lang_CXX03
));
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());
1304 auto To
= cast
<FunctionTemplateDecl
>(Import(From
, Lang_CXX03
));
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
);
1316 FirstDeclMatcher
<ClassTemplateDecl
>().match(FromTU
, classTemplateDecl());
1317 ASSERT_TRUE(FromFT
);
1320 cast
<CXXRecordDecl
>(Import(FromFT
->getTemplatedDecl(), Lang_CXX03
));
1321 EXPECT_TRUE(ToTemplated
);
1322 auto ToTU
= ToTemplated
->getTranslationUnitDecl();
1324 FirstDeclMatcher
<ClassTemplateDecl
>().match(ToTU
, classTemplateDecl());
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
);
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());
1344 TEST_P(ASTImporterOptionSpecificTestBase
, ImportCorrectTemplatedDecl
) {
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
);
1355 FirstDeclMatcher
<NamespaceDecl
>().match(FromTU
, namespaceDecl());
1356 auto ToNs
= cast
<NamespaceDecl
>(Import(FromNs
, Lang_CXX03
));
1359 FirstDeclMatcher
<ClassTemplateDecl
>().match(FromTU
,
1363 FirstDeclMatcher
<ClassTemplateDecl
>().match(ToNs
,
1368 auto ToTemplated
= To
->getTemplatedDecl();
1370 cast
<CXXRecordDecl
>(Import(From
->getTemplatedDecl(), Lang_CXX03
));
1371 EXPECT_TRUE(ToTemplated1
);
1372 ASSERT_EQ(ToTemplated1
, ToTemplated
);
1375 TEST_P(ASTImporterOptionSpecificTestBase
,
1376 ImportTemplateSpecializationStaticMember
) {
1379 template <typename H> class Test{
1381 static const unsigned int length;
1384 template<> const unsigned int Test<int>::length;
1385 template<> const unsigned int Test<int>::length = 0;
1389 template <typename H> class Test {
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()));
1406 EXPECT_EQ(ToX
, ToDecl
);
1409 TEST_P(ASTImporterOptionSpecificTestBase
, ImportChooseExpr
) {
1410 // This tests the import of isConditionTrue directly to make sure the importer
1413 std::tie(From
, To
) = getImportedDecl(
1414 "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", 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
) {
1434 std::tie(From
, To
) = getImportedDecl(
1435 "typedef double v4double __attribute__((__vector_size__(32)));"
1436 "typedef float v4float __attribute__((__vector_size__(16)));"
1438 "void declToImport() { (void)__builtin_convertvector(vf, v4double); }",
1439 Lang_CXX03
, "", Lang_CXX03
);
1442 match(convertVectorExpr().bind("convert"), To
->getASTContext());
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
) {
1457 std::tie(From
, To
) = getImportedDecl(
1459 int declToImport() {
1461 return _Generic(x, int: 0, default: 1);
1464 Lang_C99
, "", Lang_C99
);
1467 match(genericSelectionExpr().bind("expr"), To
->getASTContext());
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
) {
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> {
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
) {
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");
1535 ASSERT_TRUE(Check(From
));
1536 EXPECT_TRUE(Check(To
));
1539 TEST_P(ASTImporterOptionSpecificTestBase
,
1540 TUshouldNotContainTemplatedDeclOfClassTemplates
) {
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");
1561 ASSERT_TRUE(Check(From
));
1562 EXPECT_TRUE(Check(To
));
1565 TEST_P(ASTImporterOptionSpecificTestBase
,
1566 TUshouldNotContainTemplatedDeclOfTypeAlias
) {
1568 std::tie(From
, To
) =
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");
1589 ASSERT_TRUE(Check(From
));
1590 EXPECT_TRUE(Check(To
));
1593 TEST_P(ASTImporterOptionSpecificTestBase
,
1594 TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation
) {
1597 std::tie(From
, To
) = getImportedDecl(
1601 class declToImport : public Base<declToImport> {};
1603 Lang_CXX03
, "", Lang_CXX03
);
1605 // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU.
1607 translationUnitDecl(unless(has(classTemplateSpecializationDecl())));
1609 MatchVerifier
<Decl
>{}.match(From
->getTranslationUnitDecl(), Pattern
));
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()))));
1618 MatchVerifier
<Decl
>{}.match(From
->getTranslationUnitDecl(), Pattern
));
1620 MatchVerifier
<Decl
>{}.match(To
->getTranslationUnitDecl(), Pattern
));
1623 AST_MATCHER_P(RecordDecl
, hasFieldOrder
, std::vector
<StringRef
>, Order
) {
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())
1630 if (ND
->getName() != Order
[Index
])
1635 return Index
== Order
.size();
1638 TEST_P(ASTImporterOptionSpecificTestBase
,
1639 TUshouldContainClassTemplateSpecializationOfExplicitInstantiation
) {
1641 std::tie(From
, To
) = getImportedDecl(
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
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
) {
1668 std::tie(From
, To
) =
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
) {
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.
1685 struct declToImport {
1691 Lang_CXX11
, "", Lang_CXX11
);
1693 MatchVerifier
<Decl
> Verifier
;
1695 Verifier
.match(From
, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1697 Verifier
.match(To
, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1700 TEST_P(ASTImporterOptionSpecificTestBase
,
1701 CXXRecordDeclFieldAndIndirectFieldOrder
) {
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".
1707 struct declToImport {
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
) {
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
) {
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
) {
1762 std::tie(From
, To
) = getImportedDecl(
1766 class declToImport : public Base<declToImport> {};
1768 Lang_CXX03
, "", Lang_CXX03
);
1770 auto hasImplicitClass
= has(cxxRecordDecl());
1771 auto Pattern
= translationUnitDecl(has(classTemplateDecl(
1773 has(classTemplateSpecializationDecl(hasImplicitClass
)))));
1775 MatchVerifier
<Decl
>{}.match(From
->getTranslationUnitDecl(), Pattern
));
1777 MatchVerifier
<Decl
>{}.match(To
->getTranslationUnitDecl(), Pattern
));
1780 TEST_P(ASTImporterOptionSpecificTestBase
, IDNSOrdinary
) {
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(
1796 void operator<<(int, X);
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
) {
1807 std::tie(From
, To
) = getImportedDecl(
1810 class Base { int a; };
1811 class declToImport : Base<declToImport> {};
1813 Lang_CXX03
, "", Lang_CXX03
);
1815 auto Pattern
= translationUnitDecl(has(classTemplateDecl(
1817 has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a"))))))));
1819 MatchVerifier
<Decl
>{}.match(From
->getTranslationUnitDecl(), Pattern
));
1821 MatchVerifier
<Decl
>{}.match(To
->getTranslationUnitDecl(), Pattern
));
1824 TEST_P(ASTImporterOptionSpecificTestBase
,
1825 ImportDefinitionOfClassTemplateAfterFwdDecl
) {
1827 Decl
*FromTU
= getTuDecl(
1829 template <typename T>
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>
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>
1867 template <typename T>
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>
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(
1909 ASSERT_EQ(2u, DeclCounter
<CXXRecordDecl
>().match(
1910 ToTU
, cxxRecordDecl(unless(isImplicit()))));
1912 Decl
*FromTU
= getTuDecl(
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
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());
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
,
1965 CompareSourceRanges(ToLHS
->getSourceRange(), FromLHS
->getSourceRange(), ToSM
,
1967 CompareSourceRanges(ToRHS
->getSourceRange(), FromRHS
->getSourceRange(), ToSM
,
1971 TEST_P(ASTImporterOptionSpecificTestBase
, ImportNestedMacro
) {
1972 Decl
*FromTU
= getTuDecl(
1974 #define FUNC_INT void declToImport
1975 #define FUNC FUNC_INT
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
,
1989 ASTImporterOptionSpecificTestBase
,
1990 ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition
) {
1991 Decl
*ToTU
= getToTuDecl(
1993 template <typename T>
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>
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");
2041 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("object0")));
2042 auto *From0
= getRecordDecl(Obj0
);
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
);
2052 EXPECT_NE(To0
, To1
);
2053 EXPECT_NE(To0
->getCanonicalDecl(), To1
->getCanonicalDecl());
2056 TEST_P(ASTImporterOptionSpecificTestBase
, AnonymousRecords
) {
2064 Decl
*FromTU0
= getTuDecl(Code
, Lang_C99
, "input0.c");
2066 Decl
*FromTU1
= getTuDecl(Code
, Lang_C99
, "input1.c");
2069 FirstDeclMatcher
<RecordDecl
>().match(FromTU0
, recordDecl(hasName("X")));
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());
2079 DeclCounter
<RecordDecl
>().match(ToTU
, recordDecl(hasName("X"))));
2082 TEST_P(ASTImporterOptionSpecificTestBase
, AnonymousRecordsReversed
) {
2083 Decl
*FromTU0
= getTuDecl(
2090 Lang_C99
, "input0.c");
2092 Decl
*FromTU1
= getTuDecl(
2094 struct X { // reversed order
2099 Lang_C99
, "input1.c");
2102 FirstDeclMatcher
<RecordDecl
>().match(FromTU0
, recordDecl(hasName("X")));
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());
2112 DeclCounter
<RecordDecl
>().match(ToTU
, recordDecl(hasName("X"))));
2115 TEST_P(ASTImporterOptionSpecificTestBase
, ImportDoesUpdateUsedFlag
) {
2116 auto Pattern
= varDecl(hasName("x"));
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
));
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
,
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"));
2145 Decl
*ToTU
= getToTuDecl("int x = 1;", Lang_CXX03
);
2146 ExistingD
= FirstDeclMatcher
<VarDecl
>().match(ToTU
, Pattern
);
2148 EXPECT_FALSE(ExistingD
->isUsed(false));
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"));
2163 Decl
*ToTU
= getToTuDecl(
2166 static const int a = 1;
2170 ExistingD
= FirstDeclMatcher
<VarDecl
>().match(ToTU
, Pattern
);
2172 EXPECT_FALSE(ExistingD
->isUsed(false));
2174 Decl
*FromTU
= getTuDecl(
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));
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"));
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"));
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
) {
2250 struct B { virtual void f(); };
2252 struct D : B { void f(); };
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
) {
2268 struct B { virtual void f(); };
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(
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
);
2303 DeclCounterWithPredicate
<FunctionDecl
>([](const FunctionDecl
*FD
) {
2304 return FD
->doesThisDeclarationHaveABody();
2305 }).match(ToTU
, functionDecl()));
2308 TEST_P(ImportFunctions
, ImportOverriddenMethodTwice
) {
2311 struct B { virtual void f(); };
2312 struct D:B { void f(); };
2315 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
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(); };
2341 struct B { virtual void f(){}; };
2342 struct D:B { void f(){}; };
2345 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
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
) {
2377 struct B { virtual void f(); };
2378 struct D:B { void f(); };
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
) {
2423 struct B { virtual void f(); };
2424 struct D:B { void f(); };
2428 struct B { virtual void f(); };
2429 struct D:B { void f(); };
2432 void foo(B &b, D &d) { b.f(); d.f(); }
2436 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2437 auto BFDefP
= cxxMethodDecl(
2438 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
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()
2499 // C::f()'s ImportOverriddenMethods() asserts B::isVirtual(), so B::f()'s
2500 // ImportOverriddenMethods() should be completed before B::f()'s body
2513 void f() override {}
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
);
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
);
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
);
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"))),
2590 TEST_P(ImportFunctions
, ImportImplicitFunctionsInLambda
) {
2591 Decl
*FromTU
= getTuDecl(
2598 auto *FromD
= FirstDeclMatcher
<FunctionDecl
>().match(
2599 FromTU
, functionDecl(hasName("foo")));
2600 auto *ToD
= Import(FromD
, Lang_CXX03
);
2602 CXXRecordDecl
*LambdaRec
=
2603 cast
<LambdaExpr
>(cast
<CStyleCastExpr
>(
2604 *cast
<CompoundStmt
>(ToD
->getBody())->body_begin())
2607 EXPECT_TRUE(LambdaRec
->getDestructor());
2610 TEST_P(ImportFunctions
,
2611 CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs
) {
2612 Decl
*FromTU
= getTuDecl(
2615 template <typename T>
2624 auto *FromD
= FirstDeclMatcher
<FunctionDecl
>().match(
2625 FromTU
, functionDecl(hasName("f")));
2626 auto *ToD
= Import(FromD
, Lang_CXX03
);
2628 EXPECT_TRUE(MatchVerifier
<FunctionDecl
>().match(
2629 ToD
, functionDecl(hasName("f"), hasDescendant(declRefExpr()))));
2632 TEST_P(ImportFunctions
,
2633 DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs
) {
2634 Decl
*FromTU
= getTuDecl(
2637 template <typename T>
2640 template <typename T>
2650 auto *FromD
= FirstDeclMatcher
<FunctionDecl
>().match(
2651 FromTU
, functionDecl(hasName("g")));
2652 auto *ToD
= Import(FromD
, Lang_CXX03
);
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
) {
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
) {
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
) {
2707 template <typename T>
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
) {
2724 template <typename T>
2729 getToTuDecl(Code
, Lang_CXX03
);
2730 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX03
);
2732 LastDeclMatcher
<CXXConstructorDecl
>().match(FromTU
, cxxConstructorDecl());
2733 auto *ImportedD
= Import(FromD
, Lang_CXX03
);
2734 EXPECT_TRUE(ImportedD
);
2737 TEST_P(ImportFunctionTemplates
,
2738 ImportOperatorWhenThereIsAFunTemplateWithSameName
) {
2741 template <typename T>
2742 void operator<(T,T) {}
2744 void operator<(X, X);
2747 Decl
*FromTU
= getTuDecl(
2750 void operator<(X, X);
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(); };"
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(){} };"
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(); };"
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(
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())
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(
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
;
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
2958 Lang_CXX03
, "input0.cc");
2960 FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, FunctionPattern
);
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();
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");
3004 FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, FunctionPattern
);
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();
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");
3045 FirstDeclMatcher
<FunctionDecl
>().match(FromNormalTU
, Pattern
);
3046 TranslationUnitDecl
*FromFriendTU
=
3047 getTuDecl("class X { friend void f(); };", Lang_CXX03
, "input1.cc");
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(); };"
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
);
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();
3108 for (auto Fr
: ToFriends
) {
3109 EXPECT_EQ(Fr
, ToFriend
);
3115 AST_MATCHER_P(TagDecl
, hasTypedefForAnonDecl
, Matcher
<TypedefNameDecl
>,
3117 if (auto *Typedef
= Node
.getTypedefNameForAnonDecl())
3118 return InnerMatcher
.matches(*Typedef
, Finder
, Builder
);
3122 TEST_P(ImportDecl
, ImportEnumSequential
) {
3123 CodeFiles Samples
{{"main.c",
3126 "int main() { foo(); moo(); }",
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) {}",
3137 {"typedef enum { THING_VALUE } thing_t;"
3138 "void conflict(thing_t type);"
3139 "void moo() { conflict(THING_VALUE); }",
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"))};
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.
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 {"
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(){};"
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;"
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() {"
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
{
3220 static constexpr auto DefaultCode
= R
"(
3221 struct A { int x; };
3231 template <typename MatcherType
>
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);
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
),
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
) {
3304 struct A { A() { int x; } };
3306 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code
);
3309 TEST_P(ImportImplicitMethods
, DoNotImportDefault
) {
3311 struct A { A() = default; };
3313 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code
);
3316 TEST_P(ImportImplicitMethods
, DoNotImportDeleted
) {
3318 struct A { A() = delete; };
3320 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code
);
3323 TEST_P(ImportImplicitMethods
, DoNotImportOtherMethod
) {
3325 struct A { void f() { } };
3327 testNoImportOf(cxxMethodDecl(hasName("f")), Code
);
3330 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfEquivalentRecord
) {
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
);
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
) {
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
);
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
) {
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
);
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
);
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());
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() {
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
);
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
"(
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
);
3468 EXPECT_TRUE(ToVar
->isExplicitObjectParameter());
3469 EXPECT_NE(ToVar
->getExplicitObjectParamThisLoc(),
3470 FromVar
->getExplicitObjectParamThisLoc());
3473 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfNonEquivalentField
) {
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
);
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
) {
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
);
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
) {
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
);
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(
3546 Lang_C99
, "input0.cc");
3548 FirstDeclMatcher
<RecordDecl
>().match(FromTU
, recordDecl(hasName("A")));
3550 Import(From
, Lang_C99
);
3552 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
3554 FirstDeclMatcher
<FieldDecl
>().match(ToTU
, fieldDecl(hasName("entry0")));
3556 FirstDeclMatcher
<FieldDecl
>().match(ToTU
, fieldDecl(hasName("entry1")));
3557 auto *R0
= getRecordDecl(Entry0
);
3558 auto *R1
= getRecordDecl(Entry1
);
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
));
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
);
3598 EXPECT_EQ(FromIndex
, 3u);
3601 TEST_P(ASTImporterOptionSpecificTestBase
,
3602 MergeFieldDeclsOfClassTemplateSpecialization
) {
3603 std::string ClassTemplate
=
3605 template <typename T>
3607 int a{0}; // FieldDecl with InitListExpr
3608 X(char) : a(3) {} // (1)
3612 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3615 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr
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
+
3628 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr
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
3644 EXPECT_TRUE(ToField
->getInClassInitializer());
3647 TEST_P(ASTImporterOptionSpecificTestBase
,
3648 MergeFunctionOfClassTemplateSpecialization
) {
3649 std::string ClassTemplate
=
3651 template <typename T>
3657 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3664 Decl
*FromTU
= getTuDecl(ClassTemplate
+
3671 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3672 FromTU
, classTemplateSpecializationDecl(hasName("X")));
3673 auto FunPattern
= functionDecl(hasName("g"),
3674 hasParent(classTemplateSpecializationDecl()));
3676 FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, FunPattern
);
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; };
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>
3715 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3726 Decl
*FromTU
= getTuDecl(ClassTemplate
+
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
);
3749 DeclCounter
<ClassTemplateSpecializationDecl
>().match(
3750 ToTU
, classTemplateSpecializationDecl(hasName("X"))));
3753 TEST_P(ASTImporterOptionSpecificTestBase
,
3754 MergeCtorOfClassTemplateSpecialization
) {
3755 std::string ClassTemplate
=
3757 template <typename T>
3763 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3769 Decl
*FromTU
= getTuDecl(ClassTemplate
+
3775 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3776 FromTU
, classTemplateSpecializationDecl(hasName("X")));
3777 // Match the void(int) ctor.
3779 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))),
3780 hasParent(classTemplateSpecializationDecl()));
3782 FirstDeclMatcher
<CXXConstructorDecl
>().match(FromTU
, CtorPattern
);
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
) {
3798 template <class T> class X { friend T; };
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
) {
3820 template<class T1, class T2, int I>
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
);
3830 FirstDeclMatcher
<ClassTemplatePartialSpecializationDecl
>().match(
3831 FromTU
, classTemplatePartialSpecializationDecl());
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
) {
3847 template<class T1, class T2, int I>
3850 // full specialization
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>
3876 template<class T, int I>
3877 class A<T, T*, I> {};
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(
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
);
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(
3926 static const int a = 1 + 2;
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
));
3943 EXPECT_NE(ToD0
, ToD1
);
3944 EXPECT_EQ(ToD1
->getPreviousDecl(), ToD0
);
3947 TEST_P(ImportVariables
, InitAndDefinitionAreInDifferentTUs
) {
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
,
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
) {
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
) {
4011 std::tie(From
, To
) = getImportedDecl(
4013 void declToImport() {
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
);
4034 auto VerifyImport
= [&](llvm::StringRef BindName
) {
4035 auto *FromB
= FirstDeclMatcher
<BindingDecl
>().match(
4036 FromF
, bindingDecl(hasName(BindName
)));
4038 auto *ToB
= Import(FromB
, Lang_CXX17
);
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);
4055 TEST_P(ImportVariables
, ImportDecompositionDeclArray
) {
4057 std::tie(From
, To
) = getImportedDecl(
4059 void declToImport() {
4064 Lang_CXX17
, "", Lang_CXX17
);
4066 TranslationUnitDecl
*FromTU
= From
->getTranslationUnitDecl();
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
) {
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
));
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
)
4168 ->lookup(FromRecordOfFriend
->getDeclName())
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
)
4190 ->lookup(ToRecordOfFriend
->getDeclName())
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());
4201 FirstDeclMatcher
<FriendDecl
>().match(FromTu
, friendDecl());
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(
4218 template <int I> class F {};
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
) {
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
));
4282 FromRecordOfFriend
->getDeclContext()->containsDecl(FromRecordOfFriend
));
4283 ASSERT_FALSE(FromRecordOfFriend
->getLexicalDeclContext()->containsDecl(
4284 FromRecordOfFriend
));
4285 ASSERT_FALSE(FromRecordOfFriend
->getLookupParent()
4286 ->lookup(FromRecordOfFriend
->getDeclName())
4289 auto *ToX
= Import(FromX
, Lang_CXX03
);
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
));
4300 ToRecordOfFriend
->getDeclContext()->containsDecl(ToRecordOfFriend
));
4301 EXPECT_FALSE(ToRecordOfFriend
->getLexicalDeclContext()->containsDecl(
4303 EXPECT_FALSE(ToRecordOfFriend
->getLookupParent()
4304 ->lookup(ToRecordOfFriend
->getDeclName())
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(
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(
4356 cast
<ClassTemplateSpecializationDecl
>(Import(FromD
, Lang_CXX03
));
4359 Decl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4360 EXPECT_EQ(DeclCounter
<ClassTemplateSpecializationDecl
>().match(ToTU
, Pattern
),
4362 ASSERT_TRUE(Imported2
->getPreviousDecl());
4363 EXPECT_EQ(Imported2
->getPreviousDecl(), Imported1
);
4366 TEST_P(ImportFriendClasses
, TypeForDeclShouldBeSetInTemplated
) {
4367 Decl
*FromTU0
= getTuDecl(
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>
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
) {
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>
4410 template <class T, T U>
4413 template <class P, P Q>
4424 auto *Fwd
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4426 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4427 Decl
*FromTU
= getTuDecl(
4429 template <class T, T U>
4432 template <class T, T U>
4435 template <class P, P Q>
4446 Lang_CXX11
, "input1.cc");
4447 auto *FromA
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4449 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4450 auto *ToA
= Import(FromA
, Lang_CXX11
);
4452 EXPECT_EQ(Fwd
->getTemplatedDecl()->getTypeForDecl(),
4453 ToA
->getTemplatedDecl()->getTypeForDecl());
4456 TEST_P(ImportFriendClasses
,
4457 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend
) {
4458 Decl
*ToTU
= getToTuDecl(
4464 template <typename T>
4465 friend class F; // The decl context of F is the global namespace.
4469 auto *ToDecl
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4470 ToTU
, classTemplateDecl(hasName("F")));
4471 Decl
*FromTU
= getTuDecl(
4473 template <typename T>
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(
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>
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(
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(
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(
4556 auto *ToYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4557 ToTU
, classTemplateDecl(hasName("Y")));
4558 Decl
*FromTU
= getTuDecl(
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
) {
4583 Decl
*FromTU
= getTuDecl(
4585 template<class T1, class T2>
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(
4606 auto *ToYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4607 ToTU
, classTemplateDecl(hasName("Y")));
4608 Decl
*FromTU
= getTuDecl(
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
) {
4636 Decl
*FromTU
= getTuDecl(
4640 template<class T2, class T3>
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(
4659 auto *ToYDef
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4660 ToTU
, classTemplateDecl(hasName("Y")));
4661 Decl
*FromTU
= getTuDecl(
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
) {
4686 Decl
*FromTU
= getTuDecl(
4690 template<class T2, class T3>
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
) {
4709 testRepeatedFriendImport(Code
);
4712 TEST_P(ImportFriendClasses
, ImportOfRepeatedFriendDecl
) {
4720 testRepeatedFriendImport(Code
);
4723 TEST_P(ImportFriendClasses
, ImportOfRepeatedFriendFunctionTemplateDecl
) {
4728 template <class U> friend void m();
4729 template <class U> friend void m();
4732 testRepeatedFriendImport(Code
);
4735 TEST_P(ImportFriendClasses
, ImportOfRepeatedFriendClassTemplateDecl
) {
4740 template <class U> friend class X;
4741 template <class U> friend class X;
4744 testRepeatedFriendImport(Code
);
4747 TEST_P(ASTImporterOptionSpecificTestBase
, FriendFunInClassTemplate
) {
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(
4772 template <typename T>
4774 template struct S<int>;
4776 inline namespace INS {
4777 template <typename T>
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();
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.
4825 EXPECT_FALSE(DC
->containsDecl(A0
));
4827 // Make sure we do not leave a StoredDeclsList with no entries.
4829 ASSERT_EQ(Map
->find(A1
->getDeclName()), Map
->end());
4832 struct ImportFunctionTemplateSpecializations
4833 : ASTImporterOptionSpecificTestBase
{};
4835 TEST_P(ImportFunctionTemplateSpecializations
,
4836 TUshouldNotContainFunctionTemplateImplicitInstantiation
) {
4838 Decl
*FromTU
= getTuDecl(
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(
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
),
4878 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4879 EXPECT_TRUE(MatchVerifier
<Decl
>{}.match(ToTU
, Pattern
));
4882 TEST_P(ImportFunctionTemplateSpecializations
,
4883 TUshouldContainFunctionTemplateSpecialization
) {
4885 Decl
*FromTU
= getTuDecl(
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
),
4902 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4903 EXPECT_TRUE(MatchVerifier
<Decl
>{}.match(ToTU
, Pattern
));
4906 TEST_P(ImportFunctionTemplateSpecializations
,
4907 FunctionTemplateSpecializationRedeclChain
) {
4909 Decl
*FromTU
= getTuDecl(
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
);
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; }
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();
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>
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>
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.
5014 template <typename T>
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
) +
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
) {
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
>
5063 const internal::VariadicDynCastAllOfMatcher
<
5064 Decl
, VarTemplatePartialSpecializationDecl
>
5065 varTemplatePartialSpecializationDecl
;
5067 TEST_P(ASTImporterOptionSpecificTestBase
,
5068 FunctionTemplateParameterDeclContext
) {
5069 constexpr auto Code
=
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>
5096 struct S<int, T2> {};
5099 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
5101 auto *FromD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5102 FromTU
, classTemplateDecl(hasName("S")));
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(),
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(),
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 {
5135 Lang_CXX17
, "input.cc");
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>'
5156 auto *FromD1
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
5157 FromTU
, cxxDeductionGuideDecl());
5158 auto *FromD2
= LastDeclMatcher
<CXXDeductionGuideDecl
>().match(
5159 FromTU
, cxxDeductionGuideDecl());
5162 FromD1
->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5165 FromD2
->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5167 DeclContext
*DC
= P1
->getDeclContext();
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();
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
));
5189 EXPECT_TRUE(Tbl
->contains(ToD2
, P1
));
5193 TEST_P(ASTImporterOptionSpecificTestBase
, RecordVarTemplateDecl
) {
5194 Decl
*ToTU
= getToTuDecl(
5200 static constexpr bool X = true;
5205 auto *ToTUX
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5206 ToTU
, varTemplateDecl(hasName("X")));
5207 Decl
*FromTU
= getTuDecl(
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
);
5221 EXPECT_EQ(ToTUX
, ToX
);
5224 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateDeclConflict
) {
5228 constexpr int X = 1;
5232 Decl
*FromTU
= getTuDecl(
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.
5245 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateStaticDefinition
) {
5246 Decl
*ToTU
= getToTuDecl(
5254 auto *ToX
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5255 ToTU
, varTemplateDecl(hasName("X")));
5256 ASSERT_FALSE(ToX
->isThisDeclarationADefinition());
5258 Decl
*FromTU
= getTuDecl(
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(
5281 constexpr int X = U::Value;
5282 struct A { static constexpr int Value = 1; };
5283 constexpr int Y = X<A>;
5287 auto *ToTUX
= FirstDeclMatcher
<VarTemplateSpecializationDecl
>().match(
5288 ToTU
, varTemplateSpecializationDecl(hasName("X")));
5289 Decl
*FromTU
= getTuDecl(
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
);
5301 EXPECT_EQ(ToTUX
, ToX
);
5304 TEST_P(ASTImporterOptionSpecificTestBase
,
5305 VarTemplateSpecializationDeclValueConflict
) {
5309 constexpr int X = U::Value;
5310 struct A { static constexpr int Value = 1; };
5311 constexpr int Y = X<A>;
5315 Decl
*FromTU
= getTuDecl(
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
);
5329 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateDeclInlineWithCXX17
) {
5330 Decl
*FromTU
= getTuDecl(
5333 template <unsigned> static constexpr bool X = true;
5336 Lang_CXX17
, "input1.cc");
5337 Decl
*FromTU2
= getTuDecl(
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
);
5350 auto *FromX2
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5351 FromTU2
, varTemplateDecl(hasName("X")));
5352 auto *ToX2
= Import(FromX2
, Lang_CXX17
);
5354 EXPECT_EQ(ToX
, ToX2
);
5357 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateParameterDeclContext
) {
5358 constexpr auto Code
=
5360 template<class T1, class T2>
5366 template<class T1, class T2>
5373 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX14
);
5375 auto *FromD1
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5376 FromTU
, varTemplateDecl(hasName("X1")));
5378 FirstDeclMatcher
<VarTemplatePartialSpecializationDecl
>().match(
5379 FromTU
, varTemplatePartialSpecializationDecl(hasName("X1")));
5380 auto *FromD2
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5381 FromTU
, varTemplateDecl(hasName("X2")));
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)));
5426 TEST_P(ASTImporterOptionSpecificTestBase
,
5427 TypeAliasTemplateParameterDeclContext
) {
5428 constexpr auto Code
=
5430 template<class T1, class T2>
5432 template<class T> using S1 = S<T, int>;
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
))))
5481 const char *ExpectedTemplateParamName
= PackIndex
? "A2" : "A1";
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
)
5572 TEST_P(ASTImporterLookupTableTest
,
5573 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup
) {
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
);
5618 FirstDeclMatcher
<RecordDecl
>().match(ToTU
, recordDecl(hasName("Foo")));
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")))
5656 FirstDeclMatcher
<RecordDecl
>().match(ToTU
, recordDecl(hasName("A")));
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(
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(
5703 void operator+(X, X);
5704 void operator-(X, X);
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(
5730 void operator+(X, X);
5733 auto *ToPlus
= FirstDeclMatcher
<FunctionDecl
>().match(
5734 ToTU
, functionDecl(hasOverloadedOperatorName("+")));
5736 Decl
*FromTU
= getTuDecl(
5739 void operator+(X, X);
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; };
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(
5788 class Y { friend F; };
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(
5813 using alias_of_f = F;
5814 class Y { friend alias_of_f; };
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(
5834 namespace b { class InnerClass; }
5835 using b::InnerClass;
5838 friend a::InnerClass;
5843 // ASTImporterLookupTable constructor handles friend with using-type without
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; };
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>
5885 template <typename T>
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>
5909 friend class F<int>;
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(); };
5932 ASTImporterLookupTable
LT(*ToTU
);
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>
5955 ASTImporterLookupTable
LT(*ToTU
);
5957 auto *Template
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5958 ToTU
, classTemplateDecl(hasName("X")));
5959 auto *FieldInTemplate
= FirstDeclMatcher
<FieldDecl
>().match(
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
,
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(); };
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(
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
);
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(
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(
6085 auto *N1
= FirstDeclMatcher
<NamespaceDecl
>().match(
6086 ToTU
, namespaceDecl(hasName("N")));
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(
6106 static const int I = 3;
6110 struct X { // <--- To be imported
6111 void method(int i = Y::I) {}
6117 auto *FromFwd
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6118 FromTU
, cxxRecordDecl(hasName("X"), unless(isImplicit())));
6119 auto *FromDef
= LastDeclMatcher
<CXXRecordDecl
>().match(
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(
6144 template <typename T> friend void foo();
6148 auto *Friend
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
6149 ToTU
, functionTemplateDecl(hasName("foo")));
6151 Decl
*FromTU
= getTuDecl(
6153 template <typename T> void foo();
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
) {
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
,
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
6223 TEST_P(ErrorHandlingTest
, ErrorHappensBeforeCreatingANewNode
) {
6224 TranslationUnitDecl
*ToTU
= getToTuDecl(
6226 template <typename T>
6229 class X<int> { int a; };
6232 TranslationUnitDecl
*FromTU
= getTuDecl(
6234 template <typename T>
6237 class X<int> { double b; };
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"))),
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.
6273 DeclCounter
<FunctionDecl
>().match(ToTU
, functionDecl(hasName("foo"))),
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
"(
6289 void f() { )") + ErroneousStmt
+ R
"( }
6292 auto *FromProto
= FirstDeclMatcher
<FunctionDecl
>().match(
6293 FromTU
, functionDecl(hasName("f")));
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
6301 TranslationUnitDecl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
6302 EXPECT_EQ(DeclCounter
<FunctionDecl
>().match(ToTU
, functionDecl(hasName("f"))),
6304 // Match the fwd decl.
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
"(
6324 void f() { )") + ErroneousStmt
+ R
"( } // This member has the error
6326 void ok(); // The error should not prevent importing this.
6327 }; // An error will be set for X too.
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
"(
6371 template <int I> class F {};
6373 template <int I> friend class F;
6374 void error() { )") +
6375 ErroneousStmt
+ R
"( }
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.
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.
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
"(
6451 void f() { )") + ErroneousStmt
+ R
"( } // This member has the error
6453 void ok(); // The error should not prevent importing this.
6454 }; // An error will be set for X too.
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
"(
6500 constexpr auto FromTUCode
= R
"(
6510 Decl
*ToTU
= getToTuDecl(ToTUCode
, Lang_CXX11
);
6511 static_cast<void>(ToTU
);
6512 Decl
*FromTU
= getTuDecl(FromTUCode
, Lang_CXX11
);
6514 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("z")));
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
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
"(
6532 void f() { )") + ErroneousStmt
+ R
"( }
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
"(
6568 void f() { )") + ErroneousStmt
+ R
"( }
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
) {
6598 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A"))));
6600 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B"))));
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
"(
6612 )") + ErroneousStmt
+ R
"(
6614 struct B : public A {
6615 void foo() override;
6617 struct C : public B {
6618 void foo() override;
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
"(
6651 constexpr auto FromTUCode
= R
"(
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")));
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
6676 constexpr auto ToTUCode
= R
"(
6683 constexpr auto FromTUCode
= R
"(
6686 using U = struct Err;
6690 struct Err {}; // ODR violation
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()));
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(
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
) {
6739 std::tie(From
, To
) = getImportedDecl(
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
) {
6756 std::tie(From
, To
) = getImportedDecl(
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; };
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
);
6806 TEST_P(ASTImporterOptionSpecificTestBase
,
6807 ImportExistingFriendClassTemplateDef
) {
6810 template <class T1, class T2>
6812 template <class U1, class U2>
6813 friend struct Class;
6815 template <class T1, class T2>
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
{
6852 Creator
= [](ASTContext
&ToContext
, FileManager
&ToFileManager
,
6853 ASTContext
&FromContext
, FileManager
&FromFileManager
,
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(
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(
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",
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(
6927 // Force generating some implicit operator definitions for X.
6928 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; }
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
);
6940 auto *ToD2
= Import(GetDeclToImport("input2.cc"), Lang_CXX11
);
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; };
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(
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(
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.
7054 DeclCounter
<CXXRecordDecl
>().match(FromTU
, cxxRecordDecl(isLambda())),
7057 FunctionDecl
*ToF
= Import(FromF
, Lang_CXX20
);
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())),
7065 TEST_P(ASTImporterOptionSpecificTestBase
, ImportDefaultConstructibleLambdas
) {
7066 Decl
*FromTU
= getTuDecl(
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.
7078 DeclCounter
<CXXRecordDecl
>().match(FromTU
, cxxRecordDecl(isLambda())),
7081 FunctionDecl
*ToF
= Import(FromF
, Lang_CXX20
);
7083 TranslationUnitDecl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
7084 // We have two lambda classes after the import.
7085 EXPECT_EQ(DeclCounter
<CXXRecordDecl
>().match(ToTU
, cxxRecordDecl(isLambda())),
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 = [](){}; }
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())
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
>();
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
);
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
7149 EXPECT_TRUE(isa
<AutoType
>(To
->getReturnType()));
7153 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate1
) {
7157 C f1() { return C(); }
7165 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate2
) {
7169 int f1(T t) { return 1; }
7177 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate3
) {
7180 template<class A> struct S1 {};
7181 template<class A> struct S2 {};
7183 S1<C> f1() { return S1<C>(); }
7186 return f1<S2<B *>>();
7191 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate4
) {
7194 template<class... A> struct S1 {};
7195 template<class... A> struct S2 {};
7196 template<class... C>
7197 S1<C...> f1() { return S1<C...>(); }
7200 return f1<S2<int, B *>, bool>();
7205 TEST_P(ImportAutoFunctions
, ReturnWithVarTemplate1
) {
7208 template<class T> T X;
7216 TEST_P(ImportAutoFunctions
, ReturnWithVarTemplate2
) {
7219 template<class A> struct S1 {};
7220 template<class T> S1<T> X;
7228 TEST_P(ImportAutoFunctions
, ReturnWithVarTemplate3
) {
7231 template<class... A> struct S1 {};
7232 template<class... T> S1<T...> X;
7235 return X<bool, S1<A, int>>;
7240 TEST_P(ImportAutoFunctions
, ReturnWithAutoUnresolvedArg
) {
7250 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithTemplateTemplateArg
) {
7251 // FIXME: Is it possible to have the template arg inside the function?
7254 template<int> struct Tmpl {};
7255 template<template<int> class> struct TmplTmpl {};
7257 return TmplTmpl<Tmpl>();
7262 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithDeclarationTemplateArg
) {
7263 // FIXME: Is it possible to have the template arg inside the function?
7266 template<const int *> struct Tmpl {};
7274 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithNullPtrTemplateArg
) {
7277 template<int *> struct Tmpl {};
7279 constexpr int* A = nullptr;
7285 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithIntegralTemplateArg
) {
7288 template<int> struct Tmpl {};
7291 constexpr Int A = 7;
7297 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithDecltypeTypeDeclaredInside
) {
7300 template<class> struct Tmpl {};
7304 return Tmpl<decltype(x)>();
7309 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithUsingTypeDeclaredInside
) {
7312 template<class> struct Tmpl {};
7313 namespace A { struct X {}; }
7321 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithArrayTypeDeclaredInside
) {
7324 template<class> struct Tmpl {};
7327 return Tmpl<X[10]>();
7332 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithArraySizeExprDeclaredInside
) {
7335 template<class> struct Tmpl {};
7337 constexpr int S = 10;
7338 return Tmpl<int[S]>();
7343 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithPackArgDeclaredInside
) {
7346 template<class ...> struct Tmpl {};
7349 return Tmpl<int, X>();
7354 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithIntegerArgDeclaredInside
) {
7357 template<int> struct Tmpl {};
7359 constexpr int X = 1;
7365 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithPtrToStructDeclaredInside
) {
7368 template<class> struct Tmpl {};
7376 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithRefToStructDeclaredInside
) {
7379 template<class> struct Tmpl {};
7388 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithStructDeclaredInside1
) {
7391 template<class> struct Tmpl {};
7399 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithStructDeclaredInside2
) {
7402 template<class> struct Tmpl {};
7405 return Tmpl<Tmpl<X>>();
7410 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithTypedefDeclaredInside
) {
7413 template<class> struct Tmpl {};
7417 return Tmpl<x_type>();
7422 TEST_P(ImportAutoFunctions
, ReturnWithTypedefDeclaredInside
) {
7423 Decl
*FromTU
= getTuDecl(
7425 auto X = [](long l) {
7426 using int_type = long;
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
);
7454 EXPECT_TRUE(isa
<TypedefType
>(To
->getReturnType()));
7457 TEST_P(ImportAutoFunctions
, ReturnWithStructDeclaredInside
) {
7467 TEST_P(ImportAutoFunctions
, ReturnWithStructDeclaredInside2
) {
7468 Decl
*FromTU
= getTuDecl(
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(
7489 constexpr auto foo();
7491 constexpr auto S::foo() {
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
);
7503 EXPECT_TRUE(isa
<AutoType
>(To
->getReturnType()));
7504 EXPECT_FALSE(To
->isThisDeclarationADefinition());
7507 TEST_P(ImportAutoFunctions
, ReturnWithTypedefToStructDeclaredInside
) {
7518 TEST_P(ImportAutoFunctions
, ReturnWithStructDeclaredNestedInside
) {
7522 struct X { struct Y{}; };
7528 TEST_P(ImportAutoFunctions
, ReturnWithInternalLambdaType
) {
7542 TEST_P(ImportAutoFunctions
, ReturnWithTypeInIf
) {
7546 if (struct X {} x; true)
7555 TEST_P(ImportAutoFunctions
, ReturnWithTypeInFor
) {
7559 for (struct X {} x;;)
7566 TEST_P(ImportAutoFunctions
, ReturnWithTypeInSwitch
) {
7570 switch (struct X {} x; 10) {
7579 TEST_P(ImportAutoFunctions
, ReturnWithAutoTemplateType
) {
7588 auto a = foo<int>();
7590 Lang_CXX14
, /*FindLast=*/true);
7593 TEST_P(ImportAutoFunctions
, ReturnWithSubstNonTypeTemplateParmExpr
) {
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
);
7613 TEST_P(ImportAutoFunctions
, ReturnWithUnaryTransformType
) {
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
);
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
);
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
);
7727 ToSM
.getBufferOrFake(ImportedID
, SourceLocation()).getBuffer());
7730 struct ImportAttributes
: public ASTImporterOptionSpecificTestBase
{
7731 void checkAttrImportCommon(const Attr
*From
, const Attr
*To
,
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());
7744 EXPECT_FALSE(To
->getAttrName());
7746 if (From
->getScopeName()) {
7747 EXPECT_TRUE(To
->getScopeName());
7748 EXPECT_STREQ(From
->getScopeName()->getNameStart(),
7749 To
->getScopeName()->getNameStart());
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");
7769 FirstDeclMatcher
<DT
>().match(FromTU
, namedDecl(hasName("test")));
7772 DT
*ToD
= Import(FromD
, Lang_CXX11
);
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
) {
7785 EXPECT_NE(From
, To
);
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();
7793 ASSERT_NE(ToI
, To
.end());
7794 checkImported(*FromI
, *ToI
);
7800 void ImportAttributes::checkImported
<Decl
>(const Decl
*From
, const Decl
*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 {};
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
7825 TEST_P(ImportAttributes
, ImportAlignValue
) {
7826 AlignValueAttr
*FromAttr
, *ToAttr
;
7827 importAttr
<VarDecl
>(
7829 void *test __attribute__((align_value(64)));
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)));
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\")));",
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
,
7864 TEST_P(ImportAttributes
, ImportPtGuardedVar
) {
7865 PtGuardedVarAttr
*FromAttr
, *ToAttr
;
7866 importAttr
<VarDecl
>("int *test __attribute__((pt_guarded_var));", FromAttr
,
7870 TEST_P(ImportAttributes
, ImportScopedLockable
) {
7871 ScopedLockableAttr
*FromAttr
, *ToAttr
;
7872 importAttr
<CXXRecordDecl
>("struct __attribute__((scoped_lockable)) test {};",
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)));",
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)));",
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, "
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)));",
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)));",
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
,
7932 TEST_P(ImportAttributes
, ImportGuardedBy
) {
7933 GuardedByAttr
*FromAttr
, *ToAttr
;
7934 importAttr
<VarDecl
>(
7937 int test __attribute__((guarded_by(G)));
7940 checkImported(FromAttr
->getArg(), ToAttr
->getArg());
7943 TEST_P(ImportAttributes
, ImportPtGuardedBy
) {
7944 PtGuardedByAttr
*FromAttr
, *ToAttr
;
7945 importAttr
<VarDecl
>(
7948 int *test __attribute__((pt_guarded_by(G)));
7951 checkImported(FromAttr
->getArg(), ToAttr
->getArg());
7954 TEST_P(ImportAttributes
, ImportAcquiredAfter
) {
7955 AcquiredAfterAttr
*FromAttr
, *ToAttr
;
7956 importAttr
<VarDecl
>(
7958 struct __attribute__((lockable)) L {};
7961 L test __attribute__((acquired_after(A1, A2)));
7964 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7967 TEST_P(ImportAttributes
, ImportAcquiredBefore
) {
7968 AcquiredBeforeAttr
*FromAttr
, *ToAttr
;
7969 importAttr
<VarDecl
>(
7971 struct __attribute__((lockable)) L {};
7974 L test __attribute__((acquired_before(A1, A2)));
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)));",
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)));",
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, "
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, "
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
,
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)));",
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
) {
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
,
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");
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 {
8121 Lang_CXX17
, "input.cc");
8122 auto *FromD
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8124 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>")))));
8125 auto *ToD
= Import(FromD
, Lang_CXX17
);
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 {
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
);
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 {
8169 Lang_CXX17
, "input.cc");
8170 auto *FromD
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8171 TU
, cxxDeductionGuideDecl());
8172 auto *ToD
= Import(FromD
, Lang_CXX17
);
8176 TEST_P(ImportFunctions
, CTADAliasTemplate
) {
8177 Decl
*TU
= getTuDecl(
8179 template <typename T> struct A {
8182 template<typename T>
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
);
8191 EXPECT_TRUE(ToD
->getSourceDeductionGuideKind() ==
8192 CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias
);
8193 EXPECT_TRUE(ToD
->getSourceDeductionGuide());
8196 TEST_P(ImportFunctions
, ParmVarDeclDeclContext
) {
8197 constexpr auto FromTUCode
= R
"(
8200 Decl
*FromTU
= getTuDecl(FromTUCode
, Lang_CXX11
);
8201 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
8202 FromTU
, functionDecl(hasName("f")));
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
8216 struct CTAD
: ASTImporterOptionSpecificTestBase
{};
8218 TEST_P(CTAD
, DeductionGuideShouldReferToANonLocalTypedef
) {
8219 Decl
*TU
= getTuDecl(
8222 template <typename T> struct A {
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(
8242 template <typename T> struct A {
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
>()
8256 ->getAs
<TypedefType
>()
8261 TEST_P(CTAD
, DeductionGuideShouldCopyALocalTypedef
) {
8262 Decl
*TU
= getTuDecl(
8264 template <typename T> struct A {
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(
8286 typedef int X __attribute__((annotate("A
")));
8289 Lang_CXX17
, "input.cc");
8291 FirstDeclMatcher
<TypedefDecl
>().match(TU
, typedefDecl(hasName("X")));
8292 auto *ToD
= Import(FromD
, Lang_CXX17
);
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(
8306 template<typename T>
8307 class basic_stringbuf;
8311 template<typename T = char_traits>
8312 class basic_stringbuf;
8315 template<typename T>
8316 class basic_stringbuf {};
8322 auto *From1
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
8324 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
8325 auto *To1
= cast_or_null
<ClassTemplateDecl
>(Import(From1
, Lang_CXX11
));
8328 auto *From2
= LastDeclMatcher
<ClassTemplateDecl
>().match(
8330 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
8331 auto *To2
= cast_or_null
<ClassTemplateDecl
>(Import(From2
, Lang_CXX11
));
8335 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfCapturedVLAType
) {
8336 Decl
*FromTU
= getTuDecl(
8338 void declToImport(int N) {
8340 [&VLA] {}; // FieldDecl inside the lambda.
8344 auto *FromFD
= FirstDeclMatcher
<FieldDecl
>().match(FromTU
, fieldDecl());
8345 ASSERT_TRUE(FromFD
);
8346 ASSERT_TRUE(FromFD
->hasCapturedVLAType());
8348 auto *ToFD
= Import(FromFD
, Lang_CXX14
);
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>;
8363 auto *FromD
= FirstDeclMatcher
<EnumDecl
>().match(
8364 FromTU
, enumDecl(hasName("tagname"),
8365 hasParent(classTemplateSpecializationDecl())));
8367 ASSERT_TRUE(FromD
->getMemberSpecializationInfo());
8369 auto *ToD
= Import(FromD
, Lang_CXX03
);
8371 EXPECT_TRUE(ToD
->getMemberSpecializationInfo());
8372 EXPECT_EQ(FromD
->getTemplateSpecializationKind(),
8373 ToD
->getTemplateSpecializationKind());
8376 TEST_P(ASTImporterOptionSpecificTestBase
, ImportIsInheritingConstructorBit
) {
8377 Decl
*FromTU
= getTuDecl(
8383 using A::A; // Inherited ctor.
8390 auto *FromD
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8391 FromTU
, cxxConstructorDecl(isInheritingConstructor()));
8393 ASSERT_TRUE(FromD
->isInheritingConstructor());
8395 auto *ToD
= Import(FromD
, Lang_CXX11
);
8397 EXPECT_TRUE(ToD
->isInheritingConstructor());
8400 TEST_P(ASTImporterOptionSpecificTestBase
, ImportConstructorUsingShadow
) {
8401 TranslationUnitDecl
*FromTU
= getTuDecl(
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
) {
8458 std::tie(From
, To
) = getImportedDecl(
8465 A foo() { A a; return a; }
8466 A bar() { return {}; }
8474 A baz() { return {}; }
8479 hasAnyConstructorInitializer(cxxCtorInitializer(isMemberInitializer()));
8481 cxxConstructorDecl(isMoveConstructor(), isImplicit(), HasCtorInit
);
8483 auto *FromImpMoveCtor
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8485 auto *ToImpMoveCtor
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
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
>,
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 {
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(
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
);
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);
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());
8690 FromDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8691 FromDGCopyCtor
->getTemplatedDecl());
8692 EXPECT_EQ(FromDGOther
->getDescribedTemplate()
8693 ->getTemplateParameters()
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());
8713 ToDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8714 ToDGCopyCtor
->getTemplatedDecl());
8715 EXPECT_EQ(ToDGOther
->getDescribedTemplate()
8716 ->getTemplateParameters()
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);
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());
8756 FromDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8757 FromDGCopyCtor
->getTemplatedDecl());
8758 EXPECT_EQ(FromDGOther
->getDescribedTemplate()
8759 ->getTemplateParameters()
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.
8783 ToDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8784 ToDGCtor
->getTemplatedDecl());
8785 EXPECT_EQ(ToDGOther
->getDescribedTemplate()
8786 ->getTemplateParameters()
8792 TEST_P(ASTImporterOptionSpecificTestBase
,
8793 ImportFieldsFirstForCorrectRecordLayout
) {
8794 // UnaryOperator(&) triggers RecordLayout computation, which relies on
8795 // correctly imported fields.
8800 return &((A *)0)->f1 - &((A *)0)->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.
8827 A *f() { return &((B *)0)->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(
8858 static void foo(A x) {
8859 (void)&"text
"[x.idx];
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
8870 auto *ToA
= Import(FromA
, Lang_CXX11
);
8872 EXPECT_TRUE(ToA
->isCompleteDefinition());
8875 TEST_P(ASTImporterOptionSpecificTestBase
,
8876 ImportRecordWithLayoutRequestingExprDifferentRecord
) {
8877 TranslationUnitDecl
*FromTU
= getTuDecl(
8885 static void foo(A x) {
8886 (void)&"text
"[x.idx];
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
);
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(
8915 template<typename> struct A { int X = 1; };
8916 struct B { A<int> Y; };
8919 auto *ToX
= FirstDeclMatcher
<FieldDecl
>().match(
8921 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8922 ASSERT_TRUE(ToX
->hasInClassInitializer());
8923 ASSERT_FALSE(ToX
->getInClassInitializer());
8925 Decl
*FromTU
= getTuDecl(
8928 template<typename> struct A { int X = 1; };
8929 struct B { A<int> Y; };
8933 Lang_CXX11
, "input1.cc");
8934 auto *FromX
= FirstDeclMatcher
<FieldDecl
>().match(
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(
8950 template<typename> int b;
8953 template<typename> struct A { N::X *X = nullptr; };
8954 struct B { A<int> Y; };
8957 auto *ToX
= FirstDeclMatcher
<FieldDecl
>().match(
8959 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8960 ASSERT_TRUE(ToX
->hasInClassInitializer());
8961 ASSERT_FALSE(ToX
->getInClassInitializer());
8963 Decl
*FromTU
= getTuDecl(
8966 template<typename> int b;
8969 template<typename> struct A { N::X *X = nullptr; };
8970 struct B { A<int> Y; };
8976 C(): attr(new A<int>{}){}
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
);
8986 EXPECT_TRUE(ToX
->getInClassInitializer());
8989 TEST_P(ASTImporterOptionSpecificTestBase
, ImportRecursiveFieldInitializer
) {
8995 AP_TECS *TECS_controller;
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
) {
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
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
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(
9077 Decl
*ToTU
= getToTuDecl(
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
{
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())
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();
9121 const auto *InjTy
= Ty
->castAs
<InjectedClassNameType
>();
9123 if (CXXRecordDecl
*Def
= D
->getDefinition()) {
9124 const CXXRecordDecl
*InjRD
= findInjected(Def
);
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
))
9137 const char *ToCodeA
=
9142 const char *ToCodeADef
=
9149 const char *ToCodeC
=
9154 const char *ToCodeCDef
=
9161 template <class T1, class T2>
9166 typedef typename A<T>::T1 T1;
9167 typedef B<T1, T> T2;
9168 typedef B<T1, C> T3;
9171 const char *FromCode
=
9182 template <class T1, class T2>
9189 typedef typename A<T>::T1 T1;
9190 typedef B<T1, T> T2;
9191 typedef B<T1, C> T3;
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(
9309 Decl
*FromTU
= getTuDecl(
9317 void A<T>::f(A::A1 *) {}
9321 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
9322 FromTU
, functionDecl(hasName("f"), isDefinition()));
9323 auto *ToF
= Import(FromF
, Lang_CXX11
);
9325 ASTContext
&ToCtx
= ToF
->getDeclContext()->getParentASTContext();
9328 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("A1")));
9329 QualType ToInjTypedef
= ToA1
->getUnderlyingType().getCanonicalType();
9330 QualType ToInjParmVar
=
9331 ToF
->parameters()[0]->getType().getDesugaredType(ToCtx
);
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
) {
9341 std::tie(From
, To
) = getImportedDecl(
9343 #define CDECL __attribute__((cdecl))
9344 typedef void (CDECL *X)();
9346 Lang_CXX03
, "", Lang_CXX03
, "X");
9349 FirstDeclMatcher
<MacroQualifiedType
>().match(From
, macroQualifiedType());
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
"(
9363 template <template<class> class T = A>
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
;
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
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
) {
9456 struct S { int i; };
9460 Decl
*ToTU
= getToTuDecl(Code
, Lang_C99
);
9461 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9464 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x")));
9465 auto *ToX
= Import(FromX
, Lang_C99
);
9469 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9471 LastDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9472 EXPECT_EQ(Typedef1
, Typedef2
);
9475 TEST_P(ASTImporterOptionSpecificTestBase
,
9476 ImportExistingTypedefToUnnamedRecord
) {
9479 typedef const struct { int f; } T;
9482 Decl
*ToTU
= getToTuDecl(Code
, Lang_C99
);
9483 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9486 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x")));
9487 auto *ToX
= Import(FromX
, Lang_C99
);
9491 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
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
) {
9503 typedef struct { int f; } T1;
9504 typedef struct { int f; } T2;
9508 Decl
*ToTU
= getToTuDecl("", Lang_C99
);
9509 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9512 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x1")));
9514 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x2")));
9515 auto *ToX1
= Import(FromX1
, Lang_C99
);
9517 auto *ToX2
= Import(FromX2
, Lang_C99
);
9521 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T1")));
9523 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T2")));
9524 EXPECT_NE(Typedef1
->getUnderlyingType().getTypePtr(),
9525 Typedef2
->getUnderlyingType().getTypePtr());
9528 TEST_P(ASTImporterOptionSpecificTestBase
,
9529 ImportExistingTypedefToUnnamedRecordPtr
) {
9532 typedef const struct { int fff; } * const T;
9535 Decl
*ToTU
= getToTuDecl(Code
, Lang_C99
);
9536 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9539 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x")));
9540 auto *ToX
= Import(FromX
, Lang_C99
);
9544 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
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")))));
9556 auto *ToRImported
= Import(FromR
, Lang_C99
);
9557 // FIXME: If typedefs are not imported separately, do not import ToRImported
9559 EXPECT_NE(ToRExisting
, ToRImported
);
9562 TEST_P(ASTImporterOptionSpecificTestBase
,
9563 ImportTypedefWithDifferentUnderlyingType
) {
9571 using RPB1 = Y1*; // redeclared
9574 auto X = 0 ? (RPX1){} : (RPY1){};
9576 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
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
=
9598 template<class A, A (B)()>
9603 const char *CodeFrom
=
9607 template<class A, A (B)()>
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
) {
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
=
9676 template <typename, typename>
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();
9705 TEST_P(ASTImporterOptionSpecificTestBase
, ImportInstantiatedFromMember
) {
9708 template <typename> struct B {
9709 template <typename, bool = false> union D;
9710 template <typename T> union D<T> {};
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
)
9735 TEST_P(ASTImporterOptionSpecificTestBase
, ImportAnonymousEnums
) {
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
) {
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
=
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")));
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
=
9815 Decl
*ToTU
= getToTuDecl(ToCode
, Lang_CXX11
);
9816 auto *ToE1
= FirstDeclMatcher
<EnumDecl
>().match(ToTU
, enumDecl());
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(
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
);
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
9868 FirstDeclMatcher
<EnumDecl
>().match(ToTU
, enumDecl(has(EnumConstA
)));
9870 FirstDeclMatcher
<EnumDecl
>().match(ToTU
, enumDecl(has(EnumConstB
)));
9871 ASSERT_NE(ToEnumDeclA
, ToEnumDeclB
);
9874 struct ImportTemplateParmDeclDefaultValue
9875 : public ASTImporterOptionSpecificTestBase
{
9877 void checkTemplateParams(RedeclarableTemplateDecl
*D
,
9878 RedeclarableTemplateDecl
*InheritedFromD
) {
9880 cast
<NonTypeTemplateParmDecl
>(D
->getTemplateParameters()->getParam(0));
9882 cast
<TemplateTypeParmDecl
>(D
->getTemplateParameters()->getParam(1));
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));
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
>
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());
9929 GetTemplateParm(FromDInherited
)->getDefaultArgStorage().isInherited());
9931 auto *ToD
= Import(FromD
, Lang_CXX14
);
9934 auto *ToDInherited
= Import(FromDInherited
, Lang_CXX14
);
9935 EXPECT_TRUE(ToDInherited
);
9937 EXPECT_FALSE(GetTemplateParm(ToD
)->getDefaultArgStorage().isInherited());
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>
9954 template <int A, typename B, template<class> class C>
9956 template <int A, typename B, template<class> class C>
9960 const char *CodeClass
=
9963 template <class> struct X;
9965 template <int A = 2, typename B = int, template<class> class C = X>
9967 template <int A, typename B, template<class> class C>
9969 template <int A, typename B, template<class> class C>
9974 const char *CodeVar
=
9977 template <class> struct X;
9979 template <int A = 2, typename B = int, template<class> class C = X>
9981 template <int A, typename B, template<class> class C>
9983 template <int A, typename B, template<class> class C>
9989 TEST_P(ImportTemplateParmDeclDefaultValue
, InvisibleInheritedFrom
) {
9990 const char *ToCode
=
9992 template <int P = 1>
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>
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
10023 EXPECT_NE(Parm
->getDefaultArgStorage().getInheritedFrom(),
10024 ToFDef
->getTemplateParameters()->getParam(0));
10027 TEST_P(ImportTemplateParmDeclDefaultValue
, DefValImportError
) {
10028 const char *ToCode
=
10034 getToTuDecl(ToCode
, Lang_CXX14
);
10036 const char *FromCode
=
10040 template <typename P = X>
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
) {
10126 static const int x = 1;
10129 template <int P1 = Y::x>
10134 static const int A = 1;
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
) {
10163 template <typename T1 = Y>
10166 template <typename T2>
10168 static const int A = 1;
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
,
10187 TEST_P(ImportTemplateParmDeclDefaultValue
,
10188 TemplateTemplateParmDeclCircularDependency
) {
10198 template <template <int> class T1 = Y>
10201 template <template <int> class T2>
10203 static const int A = 1;
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
=
10228 struct X { int A; };
10231 getToTuDecl(ToCode
, Lang_CXX11
);
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
=
10249 struct X { int A; };
10254 getToTuDecl(ToCode
, Lang_CXX11
);
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
=
10274 struct X { int A; };
10277 Decl
*ToTU
= getToTuDecl(ToCode
, Lang_CXX11
);
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
=
10297 struct X { int A; };
10302 Decl
*ToTU
= getToTuDecl(ToCode
, Lang_CXX11
);
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
=
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())
10334 ASSERT_TRUE(SharedStatePtr
->getLookupTable()->contains(
10335 ToX
->getTemplatedDecl(), ToParm
));
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())
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>
10376 template <class A1, A1>
10381 Decl
*FromTU
= getTuDecl(
10383 template <class A, A>
10388 template <class A1, A1>
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>
10428 template <class A1, A1>
10435 Decl
*FromTU
= getTuDecl(
10437 template <class A, A>
10442 template <class A1, A1>
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
>{
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