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(FromTU
->getASTContext()));
3396 auto *ToField
= Import(FromF
, Lang_CXX03
);
3397 auto *ToTU
= ToField
->getTranslationUnitDecl();
3399 EXPECT_TRUE(ToField
->isBitField());
3400 EXPECT_EQ(3u, ToField
->getBitWidthValue(ToTU
->getASTContext()));
3402 const auto *FromBT
= FromF
->getBitWidth()->getType()->getAs
<BuiltinType
>();
3403 const auto *ToBT
= ToField
->getBitWidth()->getType()->getAs
<BuiltinType
>();
3404 ASSERT_TRUE(FromBT
);
3405 ASSERT_EQ(BuiltinType::Int
, FromBT
->getKind());
3407 EXPECT_EQ(BuiltinType::Int
, ToBT
->getKind());
3410 struct ImportBlock
: ASTImporterOptionSpecificTestBase
{};
3411 TEST_P(ImportBlock
, ImportBlocksAreUnsupported
) {
3412 const auto *Code
= R
"(
3413 void test_block__capture_null() {
3419 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX03
);
3420 auto *FromBlock
= FirstDeclMatcher
<BlockDecl
>().match(FromTU
, blockDecl());
3421 ASSERT_TRUE(FromBlock
);
3423 auto ToBlockOrError
= importOrError(FromBlock
, Lang_CXX03
);
3425 const auto ExpectUnsupportedConstructError
= [](const ASTImportError
&Error
) {
3426 EXPECT_EQ(ASTImportError::UnsupportedConstruct
, Error
.Error
);
3428 llvm::handleAllErrors(ToBlockOrError
.takeError(),
3429 ExpectUnsupportedConstructError
);
3432 TEST_P(ASTImporterOptionSpecificTestBase
, ImportParmVarDecl
) {
3433 const auto *Code
= R
"(
3434 template <typename T> struct Wrapper {
3435 Wrapper(T Value = {}) {}
3437 template class Wrapper<int>;
3439 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
3440 auto *FromVar
= FirstDeclMatcher
<ParmVarDecl
>().match(
3441 FromTU
, parmVarDecl(hasType(asString("int"))));
3442 ASSERT_TRUE(FromVar
);
3443 ASSERT_TRUE(FromVar
->hasUninstantiatedDefaultArg());
3444 ASSERT_TRUE(FromVar
->getUninstantiatedDefaultArg());
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());
3454 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfNonEquivalentField
) {
3457 Decl
*FromTU
= getTuDecl("struct A { int x; };", Lang_CXX03
, "input0.cc");
3458 auto *FromF
= FirstDeclMatcher
<FieldDecl
>().match(
3459 FromTU
, fieldDecl(hasName("x")));
3460 ToF1
= Import(FromF
, Lang_CXX03
);
3465 getTuDecl("struct A { unsigned x; };", Lang_CXX03
, "input1.cc");
3466 auto *FromF
= FirstDeclMatcher
<FieldDecl
>().match(
3467 FromTU
, fieldDecl(hasName("x")));
3468 ToF2
= Import(FromF
, Lang_CXX03
);
3470 EXPECT_NE(ToF1
, ToF2
);
3473 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfEquivalentMethod
) {
3476 Decl
*FromTU
= getTuDecl("struct A { void x(); }; void A::x() { }",
3477 Lang_CXX03
, "input0.cc");
3478 auto *FromM
= FirstDeclMatcher
<FunctionDecl
>().match(
3479 FromTU
, functionDecl(hasName("x"), isDefinition()));
3480 ToM1
= Import(FromM
, Lang_CXX03
);
3484 Decl
*FromTU
= getTuDecl("struct A { void x(); }; void A::x() { }",
3485 Lang_CXX03
, "input1.cc");
3486 auto *FromM
= FirstDeclMatcher
<FunctionDecl
>().match(
3487 FromTU
, functionDecl(hasName("x"), isDefinition()));
3488 ToM2
= Import(FromM
, Lang_CXX03
);
3490 EXPECT_EQ(ToM1
, ToM2
);
3493 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfNonEquivalentMethod
) {
3496 Decl
*FromTU
= getTuDecl("struct A { void x(); }; void A::x() { }",
3497 Lang_CXX03
, "input0.cc");
3498 auto *FromM
= FirstDeclMatcher
<FunctionDecl
>().match(
3499 FromTU
, functionDecl(hasName("x"), isDefinition()));
3500 ToM1
= Import(FromM
, Lang_CXX03
);
3505 getTuDecl("struct A { void x() const; }; void A::x() const { }",
3506 Lang_CXX03
, "input1.cc");
3507 auto *FromM
= FirstDeclMatcher
<FunctionDecl
>().match(
3508 FromTU
, functionDecl(hasName("x"), isDefinition()));
3509 ToM2
= Import(FromM
, Lang_CXX03
);
3511 EXPECT_NE(ToM1
, ToM2
);
3514 TEST_P(ASTImporterOptionSpecificTestBase
,
3515 ImportUnnamedStructsWithRecursingField
) {
3516 Decl
*FromTU
= getTuDecl(
3527 Lang_C99
, "input0.cc");
3529 FirstDeclMatcher
<RecordDecl
>().match(FromTU
, recordDecl(hasName("A")));
3531 Import(From
, Lang_C99
);
3533 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
3535 FirstDeclMatcher
<FieldDecl
>().match(ToTU
, fieldDecl(hasName("entry0")));
3537 FirstDeclMatcher
<FieldDecl
>().match(ToTU
, fieldDecl(hasName("entry1")));
3538 auto *R0
= getRecordDecl(Entry0
);
3539 auto *R1
= getRecordDecl(Entry1
);
3541 EXPECT_TRUE(MatchVerifier
<RecordDecl
>().match(
3542 R0
, recordDecl(has(fieldDecl(hasName("next"))))));
3543 EXPECT_TRUE(MatchVerifier
<RecordDecl
>().match(
3544 R1
, recordDecl(has(fieldDecl(hasName("next"))))));
3547 TEST_P(ASTImporterOptionSpecificTestBase
, ImportUnnamedFieldsInCorrectOrder
) {
3548 Decl
*FromTU
= getTuDecl(
3550 void f(int X, int Y, bool Z) {
3551 (void)[X, Y, Z] { (void)Z; };
3554 Lang_CXX11
, "input0.cc");
3555 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
3556 FromTU
, functionDecl(hasName("f")));
3557 auto *ToF
= cast_or_null
<FunctionDecl
>(Import(FromF
, Lang_CXX11
));
3560 CXXRecordDecl
*FromLambda
=
3561 cast
<LambdaExpr
>(cast
<CStyleCastExpr
>(cast
<CompoundStmt
>(
3562 FromF
->getBody())->body_front())->getSubExpr())->getLambdaClass();
3564 auto *ToLambda
= cast_or_null
<CXXRecordDecl
>(Import(FromLambda
, Lang_CXX11
));
3565 EXPECT_TRUE(ToLambda
);
3567 // Check if the fields of the lambda class are imported in correct order.
3568 unsigned FromIndex
= 0u;
3569 for (auto *FromField
: FromLambda
->fields()) {
3570 ASSERT_FALSE(FromField
->getDeclName());
3571 auto *ToField
= cast_or_null
<FieldDecl
>(Import(FromField
, Lang_CXX11
));
3572 EXPECT_TRUE(ToField
);
3573 std::optional
<unsigned> ToIndex
= ASTImporter::getFieldIndex(ToField
);
3574 EXPECT_TRUE(ToIndex
);
3575 EXPECT_EQ(*ToIndex
, FromIndex
);
3579 EXPECT_EQ(FromIndex
, 3u);
3582 TEST_P(ASTImporterOptionSpecificTestBase
,
3583 MergeFieldDeclsOfClassTemplateSpecialization
) {
3584 std::string ClassTemplate
=
3586 template <typename T>
3588 int a{0}; // FieldDecl with InitListExpr
3589 X(char) : a(3) {} // (1)
3593 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3596 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr
3600 auto *ToSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3601 ToTU
, classTemplateSpecializationDecl(hasName("X")));
3602 // FieldDecl without InitlistExpr:
3603 auto *ToField
= *ToSpec
->field_begin();
3604 ASSERT_TRUE(ToField
);
3605 ASSERT_FALSE(ToField
->getInClassInitializer());
3606 Decl
*FromTU
= getTuDecl(ClassTemplate
+
3609 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr
3613 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3614 FromTU
, classTemplateSpecializationDecl(hasName("X")));
3615 // FieldDecl with InitlistExpr:
3616 auto *FromField
= *FromSpec
->field_begin();
3617 ASSERT_TRUE(FromField
);
3618 ASSERT_TRUE(FromField
->getInClassInitializer());
3620 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3621 ASSERT_TRUE(ImportedSpec
);
3622 EXPECT_EQ(ImportedSpec
, ToSpec
);
3623 // After the import, the FieldDecl has to be merged, thus it should have the
3625 EXPECT_TRUE(ToField
->getInClassInitializer());
3628 TEST_P(ASTImporterOptionSpecificTestBase
,
3629 MergeFunctionOfClassTemplateSpecialization
) {
3630 std::string ClassTemplate
=
3632 template <typename T>
3638 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3645 Decl
*FromTU
= getTuDecl(ClassTemplate
+
3652 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3653 FromTU
, classTemplateSpecializationDecl(hasName("X")));
3654 auto FunPattern
= functionDecl(hasName("g"),
3655 hasParent(classTemplateSpecializationDecl()));
3657 FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, FunPattern
);
3659 FirstDeclMatcher
<FunctionDecl
>().match(ToTU
, FunPattern
);
3660 ASSERT_TRUE(FromFun
->hasBody());
3661 ASSERT_FALSE(ToFun
->hasBody());
3662 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3663 ASSERT_TRUE(ImportedSpec
);
3664 auto *ToSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3665 ToTU
, classTemplateSpecializationDecl(hasName("X")));
3666 EXPECT_EQ(ImportedSpec
, ToSpec
);
3667 EXPECT_TRUE(ToFun
->hasBody());
3670 TEST_P(ASTImporterOptionSpecificTestBase
, MergeTemplateSpecWithForwardDecl
) {
3671 std::string ClassTemplate
=
3673 template<typename T>
3674 struct X { int m; };
3676 struct X<int> { int m; };
3678 // Append a forward decl for our template specialization.
3679 getToTuDecl(ClassTemplate
+ "template<> struct X<int>;", Lang_CXX11
);
3680 Decl
*FromTU
= getTuDecl(ClassTemplate
, Lang_CXX11
);
3681 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3682 FromTU
, classTemplateSpecializationDecl(hasName("X"), isDefinition()));
3683 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3684 // Check that our definition got merged with the existing definition.
3685 EXPECT_TRUE(FromSpec
->isThisDeclarationADefinition());
3686 EXPECT_TRUE(ImportedSpec
->isThisDeclarationADefinition());
3689 TEST_P(ASTImporterOptionSpecificTestBase
,
3690 ODRViolationOfClassTemplateSpecializationsShouldBeReported
) {
3691 std::string ClassTemplate
=
3693 template <typename T>
3696 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3707 Decl
*FromTU
= getTuDecl(ClassTemplate
+
3718 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3719 FromTU
, classTemplateSpecializationDecl(hasName("X")));
3720 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3722 // We expect one (ODR) warning during the import.
3723 EXPECT_EQ(1u, ToTU
->getASTContext().getDiagnostics().getNumWarnings());
3725 // The second specialization is different from the first, thus it violates
3726 // ODR, consequently we expect to keep the first specialization only, which is
3727 // already in the "To" context.
3728 EXPECT_FALSE(ImportedSpec
);
3730 DeclCounter
<ClassTemplateSpecializationDecl
>().match(
3731 ToTU
, classTemplateSpecializationDecl(hasName("X"))));
3734 TEST_P(ASTImporterOptionSpecificTestBase
,
3735 MergeCtorOfClassTemplateSpecialization
) {
3736 std::string ClassTemplate
=
3738 template <typename T>
3744 Decl
*ToTU
= getToTuDecl(ClassTemplate
+
3750 Decl
*FromTU
= getTuDecl(ClassTemplate
+
3756 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3757 FromTU
, classTemplateSpecializationDecl(hasName("X")));
3758 // Match the void(int) ctor.
3760 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))),
3761 hasParent(classTemplateSpecializationDecl()));
3763 FirstDeclMatcher
<CXXConstructorDecl
>().match(FromTU
, CtorPattern
);
3765 FirstDeclMatcher
<CXXConstructorDecl
>().match(ToTU
, CtorPattern
);
3766 ASSERT_TRUE(FromCtor
->hasBody());
3767 ASSERT_FALSE(ToCtor
->hasBody());
3768 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3769 ASSERT_TRUE(ImportedSpec
);
3770 auto *ToSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3771 ToTU
, classTemplateSpecializationDecl(hasName("X")));
3772 EXPECT_EQ(ImportedSpec
, ToSpec
);
3773 EXPECT_TRUE(ToCtor
->hasBody());
3776 TEST_P(ASTImporterOptionSpecificTestBase
, ClassTemplateFriendDecl
) {
3779 template <class T> class X { friend T; };
3781 template class X<Y>;
3783 Decl
*ToTU
= getToTuDecl(Code
, Lang_CXX11
);
3784 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
3785 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3786 FromTU
, classTemplateSpecializationDecl());
3787 auto *ToSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3788 ToTU
, classTemplateSpecializationDecl());
3790 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3791 EXPECT_EQ(ImportedSpec
, ToSpec
);
3792 EXPECT_EQ(1u, DeclCounter
<ClassTemplateSpecializationDecl
>().match(
3793 ToTU
, classTemplateSpecializationDecl()));
3796 TEST_P(ASTImporterOptionSpecificTestBase
,
3797 ClassTemplatePartialSpecializationsShouldNotBeDuplicated
) {
3801 template<class T1, class T2, int I>
3804 // partial specialization
3805 template<class T, int I>
3806 class A<T, T*, I> {};
3808 Decl
*ToTU
= getToTuDecl(Code
, Lang_CXX11
);
3809 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
3811 FirstDeclMatcher
<ClassTemplatePartialSpecializationDecl
>().match(
3812 FromTU
, classTemplatePartialSpecializationDecl());
3814 FirstDeclMatcher
<ClassTemplatePartialSpecializationDecl
>().match(
3815 ToTU
, classTemplatePartialSpecializationDecl());
3817 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3818 EXPECT_EQ(ImportedSpec
, ToSpec
);
3819 EXPECT_EQ(1u, DeclCounter
<ClassTemplatePartialSpecializationDecl
>().match(
3820 ToTU
, classTemplatePartialSpecializationDecl()));
3823 TEST_P(ASTImporterOptionSpecificTestBase
,
3824 ClassTemplateSpecializationsShouldNotBeDuplicated
) {
3828 template<class T1, class T2, int I>
3831 // full specialization
3833 class A<int, int, 1> {};
3835 Decl
*ToTU
= getToTuDecl(Code
, Lang_CXX11
);
3836 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
3837 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3838 FromTU
, classTemplateSpecializationDecl());
3839 auto *ToSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3840 ToTU
, classTemplateSpecializationDecl());
3842 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3843 EXPECT_EQ(ImportedSpec
, ToSpec
);
3844 EXPECT_EQ(1u, DeclCounter
<ClassTemplateSpecializationDecl
>().match(
3845 ToTU
, classTemplateSpecializationDecl()));
3848 TEST_P(ASTImporterOptionSpecificTestBase
,
3849 ClassTemplateFullAndPartialSpecsShouldNotBeMixed
) {
3850 std::string PrimaryTemplate
=
3852 template<class T1, class T2, int I>
3857 template<class T, int I>
3858 class A<T, T*, I> {};
3863 class A<int, int, 1> {};
3865 Decl
*ToTU
= getToTuDecl(PrimaryTemplate
+ FullSpec
, Lang_CXX11
);
3866 Decl
*FromTU
= getTuDecl(PrimaryTemplate
+ PartialSpec
, Lang_CXX11
);
3867 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
3868 FromTU
, classTemplateSpecializationDecl());
3870 auto *ImportedSpec
= Import(FromSpec
, Lang_CXX11
);
3871 EXPECT_TRUE(ImportedSpec
);
3872 // Check the number of partial specializations.
3873 EXPECT_EQ(1u, DeclCounter
<ClassTemplatePartialSpecializationDecl
>().match(
3874 ToTU
, classTemplatePartialSpecializationDecl()));
3875 // Check the number of full specializations.
3876 EXPECT_EQ(1u, DeclCounter
<ClassTemplateSpecializationDecl
>().match(
3877 ToTU
, classTemplateSpecializationDecl(
3878 unless(classTemplatePartialSpecializationDecl()))));
3881 TEST_P(ASTImporterOptionSpecificTestBase
,
3882 InitListExprValueKindShouldBeImported
) {
3883 Decl
*TU
= getTuDecl(
3886 void foo() { const int &a{init()}; }
3887 )", Lang_CXX11
, "input0.cc");
3888 auto *FromD
= FirstDeclMatcher
<VarDecl
>().match(TU
, varDecl(hasName("a")));
3889 ASSERT_TRUE(FromD
->getAnyInitializer());
3890 auto *InitExpr
= FromD
->getAnyInitializer();
3891 ASSERT_TRUE(InitExpr
);
3892 ASSERT_TRUE(InitExpr
->isGLValue());
3894 auto *ToD
= Import(FromD
, Lang_CXX11
);
3896 auto *ToInitExpr
= cast
<VarDecl
>(ToD
)->getAnyInitializer();
3897 EXPECT_TRUE(ToInitExpr
);
3898 EXPECT_TRUE(ToInitExpr
->isGLValue());
3901 struct ImportVariables
: ASTImporterOptionSpecificTestBase
{};
3903 TEST_P(ImportVariables
, ImportOfOneDeclBringsInTheWholeChain
) {
3904 Decl
*FromTU
= getTuDecl(
3907 static const int a = 1 + 2;
3911 Lang_CXX03
, "input1.cc");
3913 auto *FromDWithInit
= FirstDeclMatcher
<VarDecl
>().match(
3914 FromTU
, varDecl(hasName("a"))); // Decl with init
3915 auto *FromDWithDef
= LastDeclMatcher
<VarDecl
>().match(
3916 FromTU
, varDecl(hasName("a"))); // Decl with definition
3917 ASSERT_NE(FromDWithInit
, FromDWithDef
);
3918 ASSERT_EQ(FromDWithDef
->getPreviousDecl(), FromDWithInit
);
3920 auto *ToD0
= cast
<VarDecl
>(Import(FromDWithInit
, Lang_CXX11
));
3921 auto *ToD1
= cast
<VarDecl
>(Import(FromDWithDef
, Lang_CXX11
));
3924 EXPECT_NE(ToD0
, ToD1
);
3925 EXPECT_EQ(ToD1
->getPreviousDecl(), ToD0
);
3928 TEST_P(ImportVariables
, InitAndDefinitionAreInDifferentTUs
) {
3932 static const int a = 1 + 2;
3935 Decl
*ToTU
= getToTuDecl(StructA
, Lang_CXX03
);
3936 Decl
*FromTU
= getTuDecl(std::string(StructA
) + "const int A::a;", Lang_CXX03
,
3939 auto *FromDWithInit
= FirstDeclMatcher
<VarDecl
>().match(
3940 FromTU
, varDecl(hasName("a"))); // Decl with init
3941 auto *FromDWithDef
= LastDeclMatcher
<VarDecl
>().match(
3942 FromTU
, varDecl(hasName("a"))); // Decl with definition
3943 ASSERT_EQ(FromDWithInit
, FromDWithDef
->getPreviousDecl());
3944 ASSERT_TRUE(FromDWithInit
->getInit());
3945 ASSERT_FALSE(FromDWithInit
->isThisDeclarationADefinition());
3946 ASSERT_TRUE(FromDWithDef
->isThisDeclarationADefinition());
3947 ASSERT_FALSE(FromDWithDef
->getInit());
3949 auto *ToD
= FirstDeclMatcher
<VarDecl
>().match(
3950 ToTU
, varDecl(hasName("a"))); // Decl with init
3951 ASSERT_TRUE(ToD
->getInit());
3952 ASSERT_FALSE(ToD
->getDefinition());
3954 auto *ImportedD
= cast
<VarDecl
>(Import(FromDWithDef
, Lang_CXX11
));
3955 EXPECT_TRUE(ImportedD
->getAnyInitializer());
3956 EXPECT_TRUE(ImportedD
->getDefinition());
3959 TEST_P(ImportVariables
, InitAndDefinitionAreInTheFromContext
) {
3966 Decl
*ToTU
= getToTuDecl(StructA
, Lang_CXX03
);
3967 Decl
*FromTU
= getTuDecl(std::string(StructA
) + "const int A::a = 1 + 2;",
3968 Lang_CXX03
, "input1.cc");
3970 auto *FromDDeclarationOnly
= FirstDeclMatcher
<VarDecl
>().match(
3971 FromTU
, varDecl(hasName("a")));
3972 auto *FromDWithDef
= LastDeclMatcher
<VarDecl
>().match(
3973 FromTU
, varDecl(hasName("a"))); // Decl with definition and with init.
3974 ASSERT_EQ(FromDDeclarationOnly
, FromDWithDef
->getPreviousDecl());
3975 ASSERT_FALSE(FromDDeclarationOnly
->getInit());
3976 ASSERT_FALSE(FromDDeclarationOnly
->isThisDeclarationADefinition());
3977 ASSERT_TRUE(FromDWithDef
->isThisDeclarationADefinition());
3978 ASSERT_TRUE(FromDWithDef
->getInit());
3980 auto *ToD
= FirstDeclMatcher
<VarDecl
>().match(
3981 ToTU
, varDecl(hasName("a")));
3982 ASSERT_FALSE(ToD
->getInit());
3983 ASSERT_FALSE(ToD
->getDefinition());
3985 auto *ImportedD
= cast
<VarDecl
>(Import(FromDWithDef
, Lang_CXX11
));
3986 EXPECT_TRUE(ImportedD
->getAnyInitializer());
3987 EXPECT_TRUE(ImportedD
->getDefinition());
3990 TEST_P(ImportVariables
, ImportBindingDecl
) {
3992 std::tie(From
, To
) = getImportedDecl(
3994 void declToImport() {
4004 const auto [x3, y3] = b;
4007 Lang_CXX17
, "", Lang_CXX17
);
4009 TranslationUnitDecl
*FromTU
= From
->getTranslationUnitDecl();
4010 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
4011 FromTU
, functionDecl(hasName("declToImport")));
4012 auto *ToF
= Import(FromF
, Lang_CXX17
);
4015 auto VerifyImport
= [&](llvm::StringRef BindName
) {
4016 auto *FromB
= FirstDeclMatcher
<BindingDecl
>().match(
4017 FromF
, bindingDecl(hasName(BindName
)));
4019 auto *ToB
= Import(FromB
, Lang_CXX17
);
4021 EXPECT_EQ(FromB
->getBinding() != nullptr, ToB
->getBinding() != nullptr);
4022 EXPECT_EQ(FromB
->getDecomposedDecl() != nullptr,
4023 ToB
->getDecomposedDecl() != nullptr);
4024 EXPECT_EQ(FromB
->getHoldingVar() != nullptr,
4025 ToB
->getHoldingVar() != nullptr);
4036 TEST_P(ImportVariables
, ImportDecompositionDeclArray
) {
4038 std::tie(From
, To
) = getImportedDecl(
4040 void declToImport() {
4045 Lang_CXX17
, "", Lang_CXX17
);
4047 TranslationUnitDecl
*FromTU
= From
->getTranslationUnitDecl();
4049 FirstDeclMatcher
<DecompositionDecl
>().match(FromTU
, decompositionDecl());
4050 auto *ToDecomp
= Import(FromDecomp
, Lang_CXX17
);
4051 EXPECT_TRUE(ToDecomp
);
4053 ArrayRef
<BindingDecl
*> FromB
= FromDecomp
->bindings();
4054 ArrayRef
<BindingDecl
*> ToB
= ToDecomp
->bindings();
4055 EXPECT_EQ(FromB
.size(), ToB
.size());
4056 for (unsigned int I
= 0; I
< FromB
.size(); ++I
) {
4057 auto *ToBI
= Import(FromB
[I
], Lang_CXX17
);
4058 EXPECT_EQ(ToBI
, ToB
[I
]);
4062 struct ImportClasses
: ASTImporterOptionSpecificTestBase
{};
4064 TEST_P(ImportClasses
, ImportDefinitionWhenProtoIsInNestedToContext
) {
4065 Decl
*ToTU
= getToTuDecl("struct A { struct X *Xp; };", Lang_C99
);
4066 Decl
*FromTU1
= getTuDecl("struct X {};", Lang_C99
, "input1.cc");
4067 auto Pattern
= recordDecl(hasName("X"), unless(isImplicit()));
4068 auto ToProto
= FirstDeclMatcher
<RecordDecl
>().match(ToTU
, Pattern
);
4069 auto FromDef
= FirstDeclMatcher
<RecordDecl
>().match(FromTU1
, Pattern
);
4071 Decl
*ImportedDef
= Import(FromDef
, Lang_C99
);
4073 EXPECT_NE(ImportedDef
, ToProto
);
4074 EXPECT_EQ(DeclCounter
<RecordDecl
>().match(ToTU
, Pattern
), 2u);
4075 auto ToDef
= LastDeclMatcher
<RecordDecl
>().match(ToTU
, Pattern
);
4076 EXPECT_TRUE(ImportedDef
== ToDef
);
4077 EXPECT_TRUE(ToDef
->isThisDeclarationADefinition());
4078 EXPECT_FALSE(ToProto
->isThisDeclarationADefinition());
4079 EXPECT_EQ(ToDef
->getPreviousDecl(), ToProto
);
4082 TEST_P(ImportClasses
, ImportDefinitionWhenProtoIsInNestedToContextCXX
) {
4083 Decl
*ToTU
= getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03
);
4084 Decl
*FromTU1
= getTuDecl("struct X {};", Lang_CXX03
, "input1.cc");
4085 auto Pattern
= recordDecl(hasName("X"), unless(isImplicit()));
4086 auto ToProto
= FirstDeclMatcher
<RecordDecl
>().match(ToTU
, Pattern
);
4087 auto FromDef
= FirstDeclMatcher
<RecordDecl
>().match(FromTU1
, Pattern
);
4089 Decl
*ImportedDef
= Import(FromDef
, Lang_CXX03
);
4091 EXPECT_NE(ImportedDef
, ToProto
);
4092 EXPECT_EQ(DeclCounter
<RecordDecl
>().match(ToTU
, Pattern
), 2u);
4093 auto ToDef
= LastDeclMatcher
<RecordDecl
>().match(ToTU
, Pattern
);
4094 EXPECT_TRUE(ImportedDef
== ToDef
);
4095 EXPECT_TRUE(ToDef
->isThisDeclarationADefinition());
4096 EXPECT_FALSE(ToProto
->isThisDeclarationADefinition());
4097 EXPECT_EQ(ToDef
->getPreviousDecl(), ToProto
);
4100 TEST_P(ImportClasses
, ImportNestedPrototypeThenDefinition
) {
4102 getTuDecl("struct A { struct X *Xp; };", Lang_C99
, "input0.cc");
4103 Decl
*FromTU1
= getTuDecl("struct X {};", Lang_C99
, "input1.cc");
4104 auto Pattern
= recordDecl(hasName("X"), unless(isImplicit()));
4105 auto FromProto
= FirstDeclMatcher
<RecordDecl
>().match(FromTU0
, Pattern
);
4106 auto FromDef
= FirstDeclMatcher
<RecordDecl
>().match(FromTU1
, Pattern
);
4108 Decl
*ImportedProto
= Import(FromProto
, Lang_C99
);
4109 Decl
*ImportedDef
= Import(FromDef
, Lang_C99
);
4110 Decl
*ToTU
= ImportedDef
->getTranslationUnitDecl();
4112 EXPECT_NE(ImportedDef
, ImportedProto
);
4113 EXPECT_EQ(DeclCounter
<RecordDecl
>().match(ToTU
, Pattern
), 2u);
4114 auto ToProto
= FirstDeclMatcher
<RecordDecl
>().match(ToTU
, Pattern
);
4115 auto ToDef
= LastDeclMatcher
<RecordDecl
>().match(ToTU
, Pattern
);
4116 EXPECT_TRUE(ImportedDef
== ToDef
);
4117 EXPECT_TRUE(ImportedProto
== ToProto
);
4118 EXPECT_TRUE(ToDef
->isThisDeclarationADefinition());
4119 EXPECT_FALSE(ToProto
->isThisDeclarationADefinition());
4120 EXPECT_EQ(ToDef
->getPreviousDecl(), ToProto
);
4123 struct ImportFriendClasses
: ASTImporterOptionSpecificTestBase
{
4124 void testRecursiveFriendClassTemplate(Decl
*FromTu
) {
4125 auto *FromD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4126 FromTu
, classTemplateDecl());
4128 auto Pattern
= classTemplateDecl(
4129 has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
4130 ASSERT_TRUE(MatchVerifier
<Decl
>{}.match(FromD
, Pattern
));
4133 FirstDeclMatcher
<FriendDecl
>().match(FromD
, friendDecl());
4134 auto *FromRecordOfFriend
=
4135 cast
<ClassTemplateDecl
>(FromFriend
->getFriendDecl())
4136 ->getTemplatedDecl();
4137 EXPECT_NE(FromRecordOfFriend
, FromD
->getTemplatedDecl());
4138 EXPECT_TRUE(FromRecordOfFriend
->getPreviousDecl() == nullptr);
4140 auto *FromDC
= FromRecordOfFriend
->getDeclContext();
4141 auto *FromLexicalDC
= FromRecordOfFriend
->getLexicalDeclContext();
4142 ASSERT_EQ(FromDC
, cast
<DeclContext
>(FromTu
));
4143 ASSERT_EQ(FromLexicalDC
, cast
<DeclContext
>(FromD
->getTemplatedDecl()));
4145 ASSERT_FALSE(FromDC
->containsDecl(FromRecordOfFriend
));
4146 ASSERT_FALSE(FromLexicalDC
->containsDecl(FromRecordOfFriend
));
4147 ASSERT_FALSE(cast
<RecordDecl
>(FromRecordOfFriend
)
4149 ->lookup(FromRecordOfFriend
->getDeclName())
4152 auto *ToD
= Import(FromD
, Lang_CXX03
);
4153 EXPECT_TRUE(MatchVerifier
<Decl
>{}.match(ToD
, Pattern
));
4155 auto *ToFriend
= FirstDeclMatcher
<FriendDecl
>().match(ToD
, friendDecl());
4156 auto *ToRecordOfFriend
=
4157 cast
<ClassTemplateDecl
>(ToFriend
->getFriendDecl())->getTemplatedDecl();
4159 EXPECT_NE(ToRecordOfFriend
, ToD
->getTemplatedDecl());
4160 EXPECT_TRUE(ToRecordOfFriend
->getPreviousDecl() == nullptr);
4162 auto *ToDC
= ToRecordOfFriend
->getDeclContext();
4163 auto *ToLexicalDC
= ToRecordOfFriend
->getLexicalDeclContext();
4164 ASSERT_EQ(ToDC
, cast
<DeclContext
>(ToD
->getTranslationUnitDecl()));
4165 ASSERT_EQ(ToLexicalDC
, cast
<DeclContext
>(ToD
->getTemplatedDecl()));
4167 ASSERT_FALSE(ToDC
->containsDecl(ToRecordOfFriend
));
4168 ASSERT_FALSE(ToLexicalDC
->containsDecl(ToRecordOfFriend
));
4169 ASSERT_FALSE(cast
<RecordDecl
>(ToRecordOfFriend
)
4171 ->lookup(ToRecordOfFriend
->getDeclName())
4175 void testRepeatedFriendImport(const char *Code
) {
4176 Decl
*ToTu
= getToTuDecl(Code
, Lang_CXX03
);
4177 Decl
*FromTu
= getTuDecl(Code
, Lang_CXX03
, "from.cc");
4179 auto *ToFriend1
= FirstDeclMatcher
<FriendDecl
>().match(ToTu
, friendDecl());
4180 auto *ToFriend2
= LastDeclMatcher
<FriendDecl
>().match(ToTu
, friendDecl());
4182 FirstDeclMatcher
<FriendDecl
>().match(FromTu
, friendDecl());
4184 LastDeclMatcher
<FriendDecl
>().match(FromTu
, friendDecl());
4186 FriendDecl
*ToImportedFriend1
= Import(FromFriend1
, Lang_CXX03
);
4187 FriendDecl
*ToImportedFriend2
= Import(FromFriend2
, Lang_CXX03
);
4189 EXPECT_NE(ToImportedFriend1
, ToImportedFriend2
);
4190 EXPECT_EQ(ToFriend1
, ToImportedFriend1
);
4191 EXPECT_EQ(ToFriend2
, ToImportedFriend2
);
4195 TEST_P(ImportFriendClasses
, ImportOfFriendRecordDoesNotMergeDefinition
) {
4196 Decl
*FromTU
= getTuDecl(
4199 template <int I> class F {};
4201 template <int I> friend class F;
4205 Lang_CXX03
, "input0.cc");
4207 auto *FromClass
= FirstDeclMatcher
<CXXRecordDecl
>().match(
4208 FromTU
, cxxRecordDecl(hasName("F"), isDefinition()));
4209 auto *FromFriendClass
= LastDeclMatcher
<CXXRecordDecl
>().match(
4210 FromTU
, cxxRecordDecl(hasName("F")));
4212 ASSERT_TRUE(FromClass
);
4213 ASSERT_TRUE(FromFriendClass
);
4214 ASSERT_NE(FromClass
, FromFriendClass
);
4215 ASSERT_EQ(FromFriendClass
->getDefinition(), FromClass
);
4216 ASSERT_EQ(FromFriendClass
->getPreviousDecl(), FromClass
);
4217 ASSERT_EQ(FromFriendClass
->getDescribedClassTemplate()->getPreviousDecl(),
4218 FromClass
->getDescribedClassTemplate());
4220 auto *ToClass
= cast
<CXXRecordDecl
>(Import(FromClass
, Lang_CXX03
));
4221 auto *ToFriendClass
=
4222 cast
<CXXRecordDecl
>(Import(FromFriendClass
, Lang_CXX03
));
4224 EXPECT_TRUE(ToClass
);
4225 EXPECT_TRUE(ToFriendClass
);
4226 EXPECT_NE(ToClass
, ToFriendClass
);
4227 EXPECT_EQ(ToFriendClass
->getDefinition(), ToClass
);
4228 EXPECT_EQ(ToFriendClass
->getPreviousDecl(), ToClass
);
4229 EXPECT_EQ(ToFriendClass
->getDescribedClassTemplate()->getPreviousDecl(),
4230 ToClass
->getDescribedClassTemplate());
4233 TEST_P(ImportFriendClasses
, ImportOfRecursiveFriendClass
) {
4234 Decl
*FromTu
= getTuDecl(
4236 class declToImport {
4237 friend class declToImport;
4240 Lang_CXX03
, "input.cc");
4242 auto *FromD
= FirstDeclMatcher
<CXXRecordDecl
>().match(
4243 FromTu
, cxxRecordDecl(hasName("declToImport")));
4244 auto *ToD
= Import(FromD
, Lang_CXX03
);
4245 auto Pattern
= cxxRecordDecl(has(friendDecl()));
4246 ASSERT_TRUE(MatchVerifier
<Decl
>{}.match(FromD
, Pattern
));
4247 EXPECT_TRUE(MatchVerifier
<Decl
>{}.match(ToD
, Pattern
));
4250 TEST_P(ImportFriendClasses
, UndeclaredFriendClassShouldNotBeVisible
) {
4252 getTuDecl("class X { friend class Y; };", Lang_CXX03
, "from.cc");
4253 auto *FromX
= FirstDeclMatcher
<CXXRecordDecl
>().match(
4254 FromTu
, cxxRecordDecl(hasName("X")));
4255 auto *FromFriend
= FirstDeclMatcher
<FriendDecl
>().match(FromTu
, friendDecl());
4256 RecordDecl
*FromRecordOfFriend
=
4257 const_cast<RecordDecl
*>(getRecordDeclOfFriend(FromFriend
));
4259 ASSERT_EQ(FromRecordOfFriend
->getDeclContext(), cast
<DeclContext
>(FromTu
));
4260 ASSERT_EQ(FromRecordOfFriend
->getLexicalDeclContext(),
4261 cast
<DeclContext
>(FromX
));
4263 FromRecordOfFriend
->getDeclContext()->containsDecl(FromRecordOfFriend
));
4264 ASSERT_FALSE(FromRecordOfFriend
->getLexicalDeclContext()->containsDecl(
4265 FromRecordOfFriend
));
4266 ASSERT_FALSE(FromRecordOfFriend
->getLookupParent()
4267 ->lookup(FromRecordOfFriend
->getDeclName())
4270 auto *ToX
= Import(FromX
, Lang_CXX03
);
4273 Decl
*ToTu
= ToX
->getTranslationUnitDecl();
4274 auto *ToFriend
= FirstDeclMatcher
<FriendDecl
>().match(ToTu
, friendDecl());
4275 RecordDecl
*ToRecordOfFriend
=
4276 const_cast<RecordDecl
*>(getRecordDeclOfFriend(ToFriend
));
4278 ASSERT_EQ(ToRecordOfFriend
->getDeclContext(), cast
<DeclContext
>(ToTu
));
4279 ASSERT_EQ(ToRecordOfFriend
->getLexicalDeclContext(), cast
<DeclContext
>(ToX
));
4281 ToRecordOfFriend
->getDeclContext()->containsDecl(ToRecordOfFriend
));
4282 EXPECT_FALSE(ToRecordOfFriend
->getLexicalDeclContext()->containsDecl(
4284 EXPECT_FALSE(ToRecordOfFriend
->getLookupParent()
4285 ->lookup(ToRecordOfFriend
->getDeclName())
4289 TEST_P(ImportFriendClasses
, ImportOfRecursiveFriendClassTemplate
) {
4290 Decl
*FromTu
= getTuDecl(
4292 template<class A> class declToImport {
4293 template<class A1> friend class declToImport;
4296 Lang_CXX03
, "input.cc");
4298 testRecursiveFriendClassTemplate(FromTu
);
4301 TEST_P(ImportFriendClasses
,
4302 ImportOfRecursiveFriendClassTemplateWithNonTypeParm
) {
4303 Decl
*FromTu
= getTuDecl(
4305 template<class A1, A1 A> class declToImport {
4306 template<class B1, B1> friend class declToImport;
4309 Lang_CXX03
, "input.cc");
4310 testRecursiveFriendClassTemplate(FromTu
);
4313 TEST_P(ImportFriendClasses
, ProperPrevDeclForClassTemplateDecls
) {
4314 auto Pattern
= classTemplateSpecializationDecl(hasName("X"));
4316 ClassTemplateSpecializationDecl
*Imported1
;
4318 Decl
*FromTU
= getTuDecl("template<class T> class X;"
4319 "struct Y { friend class X<int>; };",
4320 Lang_CXX03
, "input0.cc");
4321 auto *FromD
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
4325 cast
<ClassTemplateSpecializationDecl
>(Import(FromD
, Lang_CXX03
));
4327 ClassTemplateSpecializationDecl
*Imported2
;
4329 Decl
*FromTU
= getTuDecl("template<class T> class X;"
4330 "template<> class X<int>{};"
4331 "struct Z { friend class X<int>; };",
4332 Lang_CXX03
, "input1.cc");
4333 auto *FromD
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
4337 cast
<ClassTemplateSpecializationDecl
>(Import(FromD
, Lang_CXX03
));
4340 Decl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4341 EXPECT_EQ(DeclCounter
<ClassTemplateSpecializationDecl
>().match(ToTU
, Pattern
),
4343 ASSERT_TRUE(Imported2
->getPreviousDecl());
4344 EXPECT_EQ(Imported2
->getPreviousDecl(), Imported1
);
4347 TEST_P(ImportFriendClasses
, TypeForDeclShouldBeSetInTemplated
) {
4348 Decl
*FromTU0
= getTuDecl(
4354 template <typename T>
4355 friend class F; // The decl context of F is the global namespace.
4358 Lang_CXX03
, "input0.cc");
4359 auto *Fwd
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4360 FromTU0
, classTemplateDecl(hasName("F")));
4361 auto *Imported0
= cast
<ClassTemplateDecl
>(Import(Fwd
, Lang_CXX03
));
4362 Decl
*FromTU1
= getTuDecl(
4364 template <typename T>
4367 Lang_CXX03
, "input1.cc");
4368 auto *Definition
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4369 FromTU1
, classTemplateDecl(hasName("F")));
4370 auto *Imported1
= cast
<ClassTemplateDecl
>(Import(Definition
, Lang_CXX03
));
4371 EXPECT_EQ(Imported0
->getTemplatedDecl()->getTypeForDecl(),
4372 Imported1
->getTemplatedDecl()->getTypeForDecl());
4375 TEST_P(ImportFriendClasses
, DeclsFromFriendsShouldBeInRedeclChains
) {
4377 std::tie(From
, To
) =
4378 getImportedDecl("class declToImport {};", Lang_CXX03
,
4379 "class Y { friend class declToImport; };", Lang_CXX03
);
4380 auto *Imported
= cast
<CXXRecordDecl
>(To
);
4382 EXPECT_TRUE(Imported
->getPreviousDecl());
4385 TEST_P(ImportFriendClasses
, SkipComparingFriendTemplateDepth
) {
4386 Decl
*ToTU
= getToTuDecl(
4388 template <class T, T U>
4391 template <class T, T U>
4394 template <class P, P Q>
4405 auto *Fwd
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4407 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4408 Decl
*FromTU
= getTuDecl(
4410 template <class T, T U>
4413 template <class T, T U>
4416 template <class P, P Q>
4427 Lang_CXX11
, "input1.cc");
4428 auto *FromA
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4430 classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
4431 auto *ToA
= Import(FromA
, Lang_CXX11
);
4433 EXPECT_EQ(Fwd
->getTemplatedDecl()->getTypeForDecl(),
4434 ToA
->getTemplatedDecl()->getTypeForDecl());
4437 TEST_P(ImportFriendClasses
,
4438 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend
) {
4439 Decl
*ToTU
= getToTuDecl(
4445 template <typename T>
4446 friend class F; // The decl context of F is the global namespace.
4450 auto *ToDecl
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4451 ToTU
, classTemplateDecl(hasName("F")));
4452 Decl
*FromTU
= getTuDecl(
4454 template <typename T>
4457 Lang_CXX03
, "input0.cc");
4458 auto *Definition
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4459 FromTU
, classTemplateDecl(hasName("F")));
4460 auto *ImportedDef
= cast
<ClassTemplateDecl
>(Import(Definition
, Lang_CXX03
));
4461 EXPECT_TRUE(ImportedDef
->getPreviousDecl());
4462 EXPECT_EQ(ToDecl
, ImportedDef
->getPreviousDecl());
4463 EXPECT_EQ(ToDecl
->getTemplatedDecl(),
4464 ImportedDef
->getTemplatedDecl()->getPreviousDecl());
4467 TEST_P(ImportFriendClasses
,
4468 ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked
) {
4469 Decl
*FromTU0
= getTuDecl(
4475 template <typename T>
4476 friend class F; // The decl context of F is the global namespace.
4479 Lang_CXX03
, "input0.cc");
4480 auto *Fwd
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4481 FromTU0
, classTemplateDecl(hasName("F")));
4482 auto *ImportedFwd
= cast
<ClassTemplateDecl
>(Import(Fwd
, Lang_CXX03
));
4483 Decl
*FromTU1
= getTuDecl(
4485 template <typename T>
4488 Lang_CXX03
, "input1.cc");
4489 auto *Definition
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4490 FromTU1
, classTemplateDecl(hasName("F")));
4491 auto *ImportedDef
= cast
<ClassTemplateDecl
>(Import(Definition
, Lang_CXX03
));
4492 EXPECT_TRUE(ImportedDef
->getPreviousDecl());
4493 EXPECT_EQ(ImportedFwd
, ImportedDef
->getPreviousDecl());
4494 EXPECT_EQ(ImportedFwd
->getTemplatedDecl(),
4495 ImportedDef
->getTemplatedDecl()->getPreviousDecl());
4498 TEST_P(ImportFriendClasses
, ImportOfClassDefinitionAndFwdFriendShouldBeLinked
) {
4499 Decl
*FromTU0
= getTuDecl(
4505 friend class F; // The decl context of F is the global namespace.
4508 Lang_CXX03
, "input0.cc");
4509 auto *Friend
= FirstDeclMatcher
<FriendDecl
>().match(FromTU0
, friendDecl());
4510 QualType FT
= Friend
->getFriendType()->getType();
4511 FT
= FromTU0
->getASTContext().getCanonicalType(FT
);
4512 auto *Fwd
= cast
<TagType
>(FT
)->getDecl();
4513 auto *ImportedFwd
= Import(Fwd
, Lang_CXX03
);
4514 Decl
*FromTU1
= getTuDecl(
4518 Lang_CXX03
, "input1.cc");
4519 auto *Definition
= FirstDeclMatcher
<CXXRecordDecl
>().match(
4520 FromTU1
, cxxRecordDecl(hasName("F")));
4521 auto *ImportedDef
= Import(Definition
, Lang_CXX03
);
4522 EXPECT_TRUE(ImportedDef
->getPreviousDecl());
4523 EXPECT_EQ(ImportedFwd
, ImportedDef
->getPreviousDecl());
4526 TEST_P(ImportFriendClasses
,
4527 ImportFriendTemplatesInDependentContext_DefToFriend
) {
4528 Decl
*ToTU
= getToTuDecl(
4537 auto *ToYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4538 ToTU
, classTemplateDecl(hasName("Y")));
4539 Decl
*FromTU
= getTuDecl(
4544 Lang_CXX03
, "input0.cc");
4545 auto *FromYDef
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4546 FromTU
, classTemplateDecl(hasName("Y")));
4547 auto *ImportedYDef
= Import(FromYDef
, Lang_CXX03
);
4548 EXPECT_TRUE(ImportedYDef
);
4549 EXPECT_FALSE(ImportedYDef
->getPreviousDecl());
4550 EXPECT_NE(ImportedYDef
, ToYFriend
);
4553 TEST_P(ImportFriendClasses
,
4554 ImportFriendTemplatesInDependentContext_DefToFriend_NE
) {
4564 Decl
*FromTU
= getTuDecl(
4566 template<class T1, class T2>
4569 Lang_CXX03
, "input0.cc");
4570 auto *FromYDef
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4571 FromTU
, classTemplateDecl(hasName("Y")));
4572 auto *ImportedYDef
= Import(FromYDef
, Lang_CXX03
);
4573 EXPECT_FALSE(ImportedYDef
);
4576 TEST_P(ImportFriendClasses
,
4577 ImportFriendTemplatesInDependentContext_FriendToFriend
) {
4578 Decl
*ToTU
= getToTuDecl(
4587 auto *ToYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4588 ToTU
, classTemplateDecl(hasName("Y")));
4589 Decl
*FromTU
= getTuDecl(
4597 Lang_CXX03
, "input0.cc");
4598 auto *FromYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4599 FromTU
, classTemplateDecl(hasName("Y")));
4600 auto *ImportedYFriend
= Import(FromYFriend
, Lang_CXX03
);
4601 EXPECT_TRUE(ImportedYFriend
);
4602 EXPECT_FALSE(ImportedYFriend
->getPreviousDecl());
4603 EXPECT_NE(ImportedYFriend
, ToYFriend
);
4606 TEST_P(ImportFriendClasses
,
4607 ImportFriendTemplatesInDependentContext_FriendToFriend_NE
) {
4617 Decl
*FromTU
= getTuDecl(
4621 template<class T2, class T3>
4625 Lang_CXX03
, "input0.cc");
4626 auto *FromYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4627 FromTU
, classTemplateDecl(hasName("Y")));
4628 auto *ImportedYFriend
= Import(FromYFriend
, Lang_CXX03
);
4629 EXPECT_FALSE(ImportedYFriend
);
4632 TEST_P(ImportFriendClasses
,
4633 ImportFriendTemplatesInDependentContext_FriendToDef
) {
4634 Decl
*ToTU
= getToTuDecl(
4640 auto *ToYDef
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4641 ToTU
, classTemplateDecl(hasName("Y")));
4642 Decl
*FromTU
= getTuDecl(
4650 Lang_CXX03
, "input0.cc");
4651 auto *FromYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4652 FromTU
, classTemplateDecl(hasName("Y")));
4653 auto *ImportedYFriend
= Import(FromYFriend
, Lang_CXX03
);
4654 EXPECT_TRUE(ImportedYFriend
);
4655 EXPECT_FALSE(ImportedYFriend
->getPreviousDecl());
4656 EXPECT_NE(ImportedYFriend
, ToYDef
);
4659 TEST_P(ImportFriendClasses
,
4660 ImportFriendTemplatesInDependentContext_FriendToDef_NE
) {
4667 Decl
*FromTU
= getTuDecl(
4671 template<class T2, class T3>
4675 Lang_CXX03
, "input0.cc");
4676 auto *FromYFriend
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4677 FromTU
, classTemplateDecl(hasName("Y")));
4678 auto *ImportedYFriend
= Import(FromYFriend
, Lang_CXX03
);
4679 EXPECT_FALSE(ImportedYFriend
);
4682 TEST_P(ImportFriendClasses
, ImportOfRepeatedFriendType
) {
4690 testRepeatedFriendImport(Code
);
4693 TEST_P(ImportFriendClasses
, ImportOfRepeatedFriendDecl
) {
4701 testRepeatedFriendImport(Code
);
4704 TEST_P(ImportFriendClasses
, ImportOfRepeatedFriendFunctionTemplateDecl
) {
4709 template <class U> friend void m();
4710 template <class U> friend void m();
4713 testRepeatedFriendImport(Code
);
4716 TEST_P(ImportFriendClasses
, ImportOfRepeatedFriendClassTemplateDecl
) {
4721 template <class U> friend class X;
4722 template <class U> friend class X;
4725 testRepeatedFriendImport(Code
);
4728 TEST_P(ASTImporterOptionSpecificTestBase
, FriendFunInClassTemplate
) {
4735 TranslationUnitDecl
*ToTU
= getToTuDecl(Code
, Lang_CXX03
);
4736 auto *ToFoo
= FirstDeclMatcher
<FunctionDecl
>().match(
4737 ToTU
, functionDecl(hasName("foo")));
4739 TranslationUnitDecl
*FromTU
= getTuDecl(Code
, Lang_CXX03
, "input.cc");
4740 auto *FromFoo
= FirstDeclMatcher
<FunctionDecl
>().match(
4741 FromTU
, functionDecl(hasName("foo")));
4742 auto *ImportedFoo
= Import(FromFoo
, Lang_CXX03
);
4743 EXPECT_EQ(ImportedFoo
, ToFoo
);
4746 struct DeclContextTest
: ASTImporterOptionSpecificTestBase
{};
4748 TEST_P(DeclContextTest
, removeDeclOfClassTemplateSpecialization
) {
4749 Decl
*TU
= getTuDecl(
4753 template <typename T>
4755 template struct S<int>;
4757 inline namespace INS {
4758 template <typename T>
4760 template struct S<int>;
4764 )", Lang_CXX11
, "input0.cc");
4765 auto *NS
= FirstDeclMatcher
<NamespaceDecl
>().match(
4766 TU
, namespaceDecl());
4767 auto *Spec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
4768 TU
, classTemplateSpecializationDecl());
4769 ASSERT_TRUE(NS
->containsDecl(Spec
));
4771 NS
->removeDecl(Spec
);
4772 EXPECT_FALSE(NS
->containsDecl(Spec
));
4775 TEST_P(DeclContextTest
,
4776 removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage
) {
4777 Decl
*TU
= getTuDecl("extern int A; int A;", Lang_CXX03
);
4778 auto *A0
= FirstDeclMatcher
<VarDecl
>().match(TU
, varDecl(hasName("A")));
4779 auto *A1
= LastDeclMatcher
<VarDecl
>().match(TU
, varDecl(hasName("A")));
4781 // Investigate the list.
4782 auto *DC
= A0
->getDeclContext();
4783 ASSERT_TRUE(DC
->containsDecl(A0
));
4784 ASSERT_TRUE(DC
->containsDecl(A1
));
4786 // Investigate the lookup table.
4787 auto *Map
= DC
->getLookupPtr();
4789 auto I
= Map
->find(A0
->getDeclName());
4790 ASSERT_NE(I
, Map
->end());
4791 StoredDeclsList
&L
= I
->second
;
4792 // The lookup table contains the most recent decl of A.
4793 ASSERT_NE(L
.getAsDecl(), A0
);
4794 ASSERT_EQ(L
.getAsDecl(), A1
);
4796 ASSERT_TRUE(L
.getAsDecl());
4797 // Simulate the private function DeclContext::reconcileExternalVisibleStorage.
4798 // We do not have a list with one element.
4799 L
.setHasExternalDecls();
4800 ASSERT_FALSE(L
.getAsList());
4801 auto Results
= L
.getLookupResult();
4802 ASSERT_EQ(1u, std::distance(Results
.begin(), Results
.end()));
4804 // This asserts in the old implementation.
4806 EXPECT_FALSE(DC
->containsDecl(A0
));
4808 // Make sure we do not leave a StoredDeclsList with no entries.
4810 ASSERT_EQ(Map
->find(A1
->getDeclName()), Map
->end());
4813 struct ImportFunctionTemplateSpecializations
4814 : ASTImporterOptionSpecificTestBase
{};
4816 TEST_P(ImportFunctionTemplateSpecializations
,
4817 TUshouldNotContainFunctionTemplateImplicitInstantiation
) {
4819 Decl
*FromTU
= getTuDecl(
4822 int f() { return 0; }
4823 void foo() { f<int>(); }
4825 Lang_CXX03
, "input0.cc");
4827 // Check that the function template instantiation is NOT the child of the TU.
4828 auto Pattern
= translationUnitDecl(
4829 unless(has(functionDecl(hasName("f"), isTemplateInstantiation()))));
4830 ASSERT_TRUE(MatchVerifier
<Decl
>{}.match(FromTU
, Pattern
));
4832 auto *Foo
= FirstDeclMatcher
<FunctionDecl
>().match(
4833 FromTU
, functionDecl(hasName("foo")));
4834 ASSERT_TRUE(Import(Foo
, Lang_CXX03
));
4836 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4837 EXPECT_TRUE(MatchVerifier
<Decl
>{}.match(ToTU
, Pattern
));
4840 TEST_P(ImportFunctionTemplateSpecializations
,
4841 TUshouldNotContainFunctionTemplateExplicitInstantiation
) {
4843 Decl
*FromTU
= getTuDecl(
4846 int f() { return 0; }
4847 template int f<int>();
4849 Lang_CXX03
, "input0.cc");
4851 // Check that the function template instantiation is NOT the child of the TU.
4852 auto Instantiation
= functionDecl(hasName("f"), isTemplateInstantiation());
4853 auto Pattern
= translationUnitDecl(unless(has(Instantiation
)));
4854 ASSERT_TRUE(MatchVerifier
<Decl
>{}.match(FromTU
, Pattern
));
4856 ASSERT_TRUE(Import(FirstDeclMatcher
<Decl
>().match(FromTU
, Instantiation
),
4859 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4860 EXPECT_TRUE(MatchVerifier
<Decl
>{}.match(ToTU
, Pattern
));
4863 TEST_P(ImportFunctionTemplateSpecializations
,
4864 TUshouldContainFunctionTemplateSpecialization
) {
4866 Decl
*FromTU
= getTuDecl(
4869 int f() { return 0; }
4870 template <> int f<int>() { return 4; }
4872 Lang_CXX03
, "input0.cc");
4874 // Check that the function template specialization is the child of the TU.
4875 auto Specialization
=
4876 functionDecl(hasName("f"), isExplicitTemplateSpecialization());
4877 auto Pattern
= translationUnitDecl(has(Specialization
));
4878 ASSERT_TRUE(MatchVerifier
<Decl
>{}.match(FromTU
, Pattern
));
4880 ASSERT_TRUE(Import(FirstDeclMatcher
<Decl
>().match(FromTU
, Specialization
),
4883 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4884 EXPECT_TRUE(MatchVerifier
<Decl
>{}.match(ToTU
, Pattern
));
4887 TEST_P(ImportFunctionTemplateSpecializations
,
4888 FunctionTemplateSpecializationRedeclChain
) {
4890 Decl
*FromTU
= getTuDecl(
4893 int f() { return 0; }
4894 template <> int f<int>() { return 4; }
4896 Lang_CXX03
, "input0.cc");
4898 auto Spec
= functionDecl(hasName("f"), isExplicitTemplateSpecialization(),
4899 hasParent(translationUnitDecl()));
4900 auto *FromSpecD
= FirstDeclMatcher
<Decl
>().match(FromTU
, Spec
);
4903 auto *SpecD
= FromSpecD
;
4904 auto *TemplateD
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
4905 TU
, functionTemplateDecl());
4906 auto *FirstSpecD
= *(TemplateD
->spec_begin());
4907 ASSERT_EQ(SpecD
, FirstSpecD
);
4908 ASSERT_TRUE(SpecD
->getPreviousDecl());
4909 ASSERT_FALSE(cast
<FunctionDecl
>(SpecD
->getPreviousDecl())
4910 ->doesThisDeclarationHaveABody());
4913 ASSERT_TRUE(Import(FromSpecD
, Lang_CXX03
));
4916 auto *TU
= ToAST
->getASTContext().getTranslationUnitDecl();
4917 auto *SpecD
= FirstDeclMatcher
<Decl
>().match(TU
, Spec
);
4918 auto *TemplateD
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
4919 TU
, functionTemplateDecl());
4920 auto *FirstSpecD
= *(TemplateD
->spec_begin());
4921 EXPECT_EQ(SpecD
, FirstSpecD
);
4922 ASSERT_TRUE(SpecD
->getPreviousDecl());
4923 EXPECT_FALSE(cast
<FunctionDecl
>(SpecD
->getPreviousDecl())
4924 ->doesThisDeclarationHaveABody());
4928 TEST_P(ImportFunctionTemplateSpecializations
,
4929 MatchNumberOfFunctionTemplateSpecializations
) {
4931 Decl
*FromTU
= getTuDecl(
4933 template <typename T> constexpr int f() { return 0; }
4934 template <> constexpr int f<int>() { return 4; }
4936 static_assert(f<char>() == 0, "");
4937 static_assert(f<int>() == 4, "");
4940 Lang_CXX11
, "input0.cc");
4941 auto *FromD
= FirstDeclMatcher
<FunctionDecl
>().match(
4942 FromTU
, functionDecl(hasName("foo")));
4944 Import(FromD
, Lang_CXX11
);
4945 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4947 DeclCounter
<FunctionDecl
>().match(FromTU
, functionDecl(hasName("f"))),
4948 DeclCounter
<FunctionDecl
>().match(ToTU
, functionDecl(hasName("f"))));
4951 TEST_P(ASTImporterOptionSpecificTestBase
,
4952 ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined
) {
4954 Decl
*FromTU
= getTuDecl(
4956 template <typename T>
4959 Lang_CXX03
, "input0.cc");
4960 auto *FromD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4961 FromTU
, classTemplateDecl(hasName("B")));
4963 Import(FromD
, Lang_CXX03
);
4967 Decl
*FromTU
= getTuDecl(
4969 template <typename T>
4975 Lang_CXX03
, "input1.cc");
4976 FunctionDecl
*FromD
= FirstDeclMatcher
<FunctionDecl
>().match(
4977 FromTU
, functionDecl(hasName("f")));
4978 Import(FromD
, Lang_CXX03
);
4979 auto *FromCTD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
4980 FromTU
, classTemplateDecl(hasName("B")));
4981 auto *ToCTD
= cast
<ClassTemplateDecl
>(Import(FromCTD
, Lang_CXX03
));
4982 EXPECT_TRUE(ToCTD
->isThisDeclarationADefinition());
4984 // We expect no (ODR) warning during the import.
4985 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
4986 EXPECT_EQ(0u, ToTU
->getASTContext().getDiagnostics().getNumWarnings());
4990 TEST_P(ASTImporterOptionSpecificTestBase
,
4991 ImportingTypedefShouldImportTheCompleteType
) {
4992 // We already have an incomplete underlying type in the "To" context.
4995 template <typename T>
5001 Decl
*ToTU
= getToTuDecl(Code
, Lang_CXX11
);
5002 auto *ToD
= FirstDeclMatcher
<TypedefNameDecl
>().match(ToTU
,
5003 typedefNameDecl(hasName("U")));
5004 ASSERT_TRUE(ToD
->getUnderlyingType()->isIncompleteType());
5006 // The "From" context has the same typedef, but the underlying type is
5007 // complete this time.
5008 Decl
*FromTU
= getTuDecl(std::string(Code
) +
5014 auto *FromD
= FirstDeclMatcher
<TypedefNameDecl
>().match(FromTU
,
5015 typedefNameDecl(hasName("U")));
5016 ASSERT_FALSE(FromD
->getUnderlyingType()->isIncompleteType());
5018 // The imported type should be complete.
5019 auto *ImportedD
= cast
<TypedefNameDecl
>(Import(FromD
, Lang_CXX11
));
5020 EXPECT_FALSE(ImportedD
->getUnderlyingType()->isIncompleteType());
5023 TEST_P(ASTImporterOptionSpecificTestBase
, ImportTemplateParameterLists
) {
5027 int f() { return 0; }
5028 template <> int f<int>() { return 4; }
5031 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX03
);
5032 auto *FromD
= FirstDeclMatcher
<FunctionDecl
>().match(FromTU
,
5033 functionDecl(hasName("f"), isExplicitTemplateSpecialization()));
5034 ASSERT_EQ(FromD
->getNumTemplateParameterLists(), 1u);
5036 auto *ToD
= Import(FromD
, Lang_CXX03
);
5037 // The template parameter list should exist.
5038 EXPECT_EQ(ToD
->getNumTemplateParameterLists(), 1u);
5041 const internal::VariadicDynCastAllOfMatcher
<Decl
, VarTemplateDecl
>
5044 const internal::VariadicDynCastAllOfMatcher
<
5045 Decl
, VarTemplatePartialSpecializationDecl
>
5046 varTemplatePartialSpecializationDecl
;
5048 TEST_P(ASTImporterOptionSpecificTestBase
,
5049 FunctionTemplateParameterDeclContext
) {
5050 constexpr auto Code
=
5056 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
5058 auto *FromD
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
5059 FromTU
, functionTemplateDecl(hasName("f")));
5061 ASSERT_EQ(FromD
->getTemplateParameters()->getParam(0)->getDeclContext(),
5062 FromD
->getTemplatedDecl());
5064 auto *ToD
= Import(FromD
, Lang_CXX11
);
5065 EXPECT_EQ(ToD
->getTemplateParameters()->getParam(0)->getDeclContext(),
5066 ToD
->getTemplatedDecl());
5067 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5068 ToD
->getTemplatedDecl(), ToD
->getTemplateParameters()->getParam(0)));
5071 TEST_P(ASTImporterOptionSpecificTestBase
, ClassTemplateParameterDeclContext
) {
5072 constexpr auto Code
=
5074 template<class T1, class T2>
5077 struct S<int, T2> {};
5080 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
5082 auto *FromD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5083 FromTU
, classTemplateDecl(hasName("S")));
5085 FirstDeclMatcher
<ClassTemplatePartialSpecializationDecl
>().match(
5086 FromTU
, classTemplatePartialSpecializationDecl(hasName("S")));
5088 ASSERT_EQ(FromD
->getTemplateParameters()->getParam(0)->getDeclContext(),
5089 FromD
->getTemplatedDecl());
5090 ASSERT_EQ(FromDPart
->getTemplateParameters()->getParam(0)->getDeclContext(),
5093 auto *ToD
= Import(FromD
, Lang_CXX11
);
5094 auto *ToDPart
= Import(FromDPart
, Lang_CXX11
);
5096 EXPECT_EQ(ToD
->getTemplateParameters()->getParam(0)->getDeclContext(),
5097 ToD
->getTemplatedDecl());
5098 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5099 ToD
->getTemplatedDecl(), ToD
->getTemplateParameters()->getParam(0)));
5101 EXPECT_EQ(ToDPart
->getTemplateParameters()->getParam(0)->getDeclContext(),
5103 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5104 ToDPart
, ToDPart
->getTemplateParameters()->getParam(0)));
5107 TEST_P(ASTImporterOptionSpecificTestBase
,
5108 CXXDeductionGuideTemplateParameterDeclContext
) {
5109 Decl
*FromTU
= getTuDecl(
5111 template <typename T> struct A {
5116 Lang_CXX17
, "input.cc");
5119 |-ClassTemplateDecl 0x1fe5000 <input.cc:2:7, line:4:7> line:2:36 A
5120 | |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
5121 | |-CXXRecordDecl 0x1fe4f70 <col:29, line:4:7> line:2:36 struct A definition
5123 |-FunctionTemplateDecl 0x1fe5860 <line:2:7, line:3:12> col:9 implicit <deduction guide for A>
5124 | |-TemplateTypeParmDecl 0x1fe4eb0 <line:2:17, col:26> col:26 referenced typename depth 0 index 0 T
5125 | |-CXXDeductionGuideDecl 0x1fe57a8 <line:3:9, col:12> col:9 implicit <deduction guide for A> 'auto (T) -> A<T>'
5126 | | `-ParmVarDecl 0x1fe56b0 <col:11> col:12 'T'
5127 | `-CXXDeductionGuideDecl 0x20515d8 <col:9, col:12> col:9 implicit used <deduction guide for A> 'auto (int) -> A<int>'
5128 | |-TemplateArgument type 'int'
5129 | | `-BuiltinType 0x20587e0 'int'
5130 | `-ParmVarDecl 0x2051388 <col:11> col:12 'int'
5131 `-FunctionTemplateDecl 0x1fe5a78 <line:2:7, col:36> col:36 implicit <deduction guide for A>
5132 |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
5133 `-CXXDeductionGuideDecl 0x1fe59c0 <col:36> col:36 implicit <deduction guide for A> 'auto (A<T>) -> A<T>'
5134 `-ParmVarDecl 0x1fe5958 <col:36> col:36 'A<T>'
5137 auto *FromD1
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
5138 FromTU
, cxxDeductionGuideDecl());
5139 auto *FromD2
= LastDeclMatcher
<CXXDeductionGuideDecl
>().match(
5140 FromTU
, cxxDeductionGuideDecl());
5143 FromD1
->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5146 FromD2
->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5148 DeclContext
*DC
= P1
->getDeclContext();
5151 ASSERT_TRUE(DC
== FromD1
|| DC
== FromD2
);
5153 auto *ToD1
= Import(FromD1
, Lang_CXX17
);
5154 auto *ToD2
= Import(FromD2
, Lang_CXX17
);
5155 ASSERT_TRUE(ToD1
&& ToD2
);
5157 P1
= ToD1
->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5159 P2
= ToD2
->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
5161 DC
= P1
->getDeclContext();
5164 EXPECT_TRUE(DC
== ToD1
|| DC
== ToD2
);
5166 ASTImporterLookupTable
*Tbl
= SharedStatePtr
->getLookupTable();
5167 if (Tbl
->contains(ToD1
, P1
)) {
5168 EXPECT_FALSE(Tbl
->contains(ToD2
, P1
));
5170 EXPECT_TRUE(Tbl
->contains(ToD2
, P1
));
5174 TEST_P(ASTImporterOptionSpecificTestBase
, RecordVarTemplateDecl
) {
5175 Decl
*ToTU
= getToTuDecl(
5181 static constexpr bool X = true;
5186 auto *ToTUX
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5187 ToTU
, varTemplateDecl(hasName("X")));
5188 Decl
*FromTU
= getTuDecl(
5194 static constexpr bool X = true;
5197 Lang_CXX14
, "input1.cc");
5198 auto *FromX
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5199 FromTU
, varTemplateDecl(hasName("X")));
5200 auto *ToX
= Import(FromX
, Lang_CXX11
);
5202 EXPECT_EQ(ToTUX
, ToX
);
5205 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateDeclConflict
) {
5209 constexpr int X = 1;
5213 Decl
*FromTU
= getTuDecl(
5216 constexpr int X = 2;
5218 Lang_CXX14
, "input1.cc");
5219 auto *FromX
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5220 FromTU
, varTemplateDecl(hasName("X")));
5221 auto *ToX
= Import(FromX
, Lang_CXX11
);
5222 // FIXME: This import should fail.
5226 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateStaticDefinition
) {
5227 Decl
*ToTU
= getToTuDecl(
5235 auto *ToX
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5236 ToTU
, varTemplateDecl(hasName("X")));
5237 ASSERT_FALSE(ToX
->isThisDeclarationADefinition());
5239 Decl
*FromTU
= getTuDecl(
5248 Lang_CXX14
, "input1.cc");
5249 auto *FromXDef
= LastDeclMatcher
<VarTemplateDecl
>().match(
5250 FromTU
, varTemplateDecl(hasName("X")));
5251 ASSERT_TRUE(FromXDef
->isThisDeclarationADefinition());
5252 auto *ToXDef
= Import(FromXDef
, Lang_CXX14
);
5253 EXPECT_TRUE(ToXDef
);
5254 EXPECT_TRUE(ToXDef
->isThisDeclarationADefinition());
5255 EXPECT_EQ(ToXDef
->getPreviousDecl(), ToX
);
5258 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateSpecializationDeclValue
) {
5259 Decl
*ToTU
= getToTuDecl(
5262 constexpr int X = U::Value;
5263 struct A { static constexpr int Value = 1; };
5264 constexpr int Y = X<A>;
5268 auto *ToTUX
= FirstDeclMatcher
<VarTemplateSpecializationDecl
>().match(
5269 ToTU
, varTemplateSpecializationDecl(hasName("X")));
5270 Decl
*FromTU
= getTuDecl(
5273 constexpr int X = U::Value;
5274 struct A { static constexpr int Value = 1; };
5275 constexpr int Y = X<A>;
5277 Lang_CXX14
, "input1.cc");
5278 auto *FromX
= FirstDeclMatcher
<VarTemplateSpecializationDecl
>().match(
5279 FromTU
, varTemplateSpecializationDecl(hasName("X")));
5280 auto *ToX
= Import(FromX
, Lang_CXX14
);
5282 EXPECT_EQ(ToTUX
, ToX
);
5285 TEST_P(ASTImporterOptionSpecificTestBase
,
5286 VarTemplateSpecializationDeclValueConflict
) {
5290 constexpr int X = U::Value;
5291 struct A { static constexpr int Value = 1; };
5292 constexpr int Y = X<A>;
5296 Decl
*FromTU
= getTuDecl(
5299 constexpr int X = U::Value;
5300 struct A { static constexpr int Value = 2; };
5301 constexpr int Y = X<A>;
5303 Lang_CXX14
, "input1.cc");
5304 auto *FromX
= FirstDeclMatcher
<VarTemplateSpecializationDecl
>().match(
5305 FromTU
, varTemplateSpecializationDecl(hasName("X")));
5306 auto *ToX
= Import(FromX
, Lang_CXX14
);
5310 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateDeclInlineWithCXX17
) {
5311 Decl
*FromTU
= getTuDecl(
5314 template <unsigned> static constexpr bool X = true;
5317 Lang_CXX17
, "input1.cc");
5318 Decl
*FromTU2
= getTuDecl(
5321 template <unsigned> static constexpr bool X = true;
5322 template <typename T> void get() { X<sizeof(T)>; }
5324 template <typename U> U qvariant_cast(const S &v) { return v.get; }
5326 Lang_CXX17
, "input2.cc");
5327 auto *FromX
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5328 FromTU
, varTemplateDecl(hasName("X")));
5329 auto *ToX
= Import(FromX
, Lang_CXX17
);
5331 auto *FromX2
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5332 FromTU2
, varTemplateDecl(hasName("X")));
5333 auto *ToX2
= Import(FromX2
, Lang_CXX17
);
5335 EXPECT_EQ(ToX
, ToX2
);
5338 TEST_P(ASTImporterOptionSpecificTestBase
, VarTemplateParameterDeclContext
) {
5339 constexpr auto Code
=
5341 template<class T1, class T2>
5347 template<class T1, class T2>
5354 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX14
);
5356 auto *FromD1
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5357 FromTU
, varTemplateDecl(hasName("X1")));
5359 FirstDeclMatcher
<VarTemplatePartialSpecializationDecl
>().match(
5360 FromTU
, varTemplatePartialSpecializationDecl(hasName("X1")));
5361 auto *FromD2
= FirstDeclMatcher
<VarTemplateDecl
>().match(
5362 FromTU
, varTemplateDecl(hasName("X2")));
5364 FirstDeclMatcher
<VarTemplatePartialSpecializationDecl
>().match(
5365 FromTU
, varTemplatePartialSpecializationDecl(hasName("X2")));
5367 ASSERT_EQ(FromD1
->getTemplateParameters()->getParam(0)->getDeclContext(),
5368 FromD1
->getDeclContext());
5369 ASSERT_EQ(FromD2
->getTemplateParameters()->getParam(0)->getDeclContext(),
5370 FromD2
->getDeclContext());
5372 ASSERT_EQ(FromD1Part
->getTemplateParameters()->getParam(0)->getDeclContext(),
5373 FromD1Part
->getDeclContext());
5374 // FIXME: VarTemplatePartialSpecializationDecl does not update ("adopt")
5375 // template parameter decl context
5376 // ASSERT_EQ(FromD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5377 // FromD2Part->getDeclContext());
5379 auto *ToD1
= Import(FromD1
, Lang_CXX14
);
5380 auto *ToD2
= Import(FromD2
, Lang_CXX14
);
5382 auto *ToD1Part
= Import(FromD1Part
, Lang_CXX14
);
5383 auto *ToD2Part
= Import(FromD2Part
, Lang_CXX14
);
5385 EXPECT_EQ(ToD1
->getTemplateParameters()->getParam(0)->getDeclContext(),
5386 ToD1
->getDeclContext());
5387 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5388 ToD1
->getDeclContext(), ToD1
->getTemplateParameters()->getParam(0)));
5389 EXPECT_EQ(ToD2
->getTemplateParameters()->getParam(0)->getDeclContext(),
5390 ToD2
->getDeclContext());
5391 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5392 ToD2
->getDeclContext(), ToD2
->getTemplateParameters()->getParam(0)));
5394 EXPECT_EQ(ToD1Part
->getTemplateParameters()->getParam(0)->getDeclContext(),
5395 ToD1Part
->getDeclContext());
5396 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5397 ToD1Part
->getDeclContext(),
5398 ToD1Part
->getTemplateParameters()->getParam(0)));
5399 // EXPECT_EQ(ToD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
5400 // ToD2Part->getDeclContext());
5401 // EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
5402 // ToD2Part->getDeclContext(),
5403 // ToD2Part->getTemplateParameters()->getParam(0)));
5407 TEST_P(ASTImporterOptionSpecificTestBase
,
5408 TypeAliasTemplateParameterDeclContext
) {
5409 constexpr auto Code
=
5411 template<class T1, class T2>
5413 template<class T> using S1 = S<T, int>;
5415 template<class T> using S2 = S<T, int>;
5419 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
5421 auto *FromD1
= FirstDeclMatcher
<TypeAliasTemplateDecl
>().match(
5422 FromTU
, typeAliasTemplateDecl(hasName("S1")));
5423 auto *FromD2
= FirstDeclMatcher
<TypeAliasTemplateDecl
>().match(
5424 FromTU
, typeAliasTemplateDecl(hasName("S2")));
5426 ASSERT_EQ(FromD1
->getTemplateParameters()->getParam(0)->getDeclContext(),
5427 FromD1
->getDeclContext());
5428 ASSERT_EQ(FromD2
->getTemplateParameters()->getParam(0)->getDeclContext(),
5429 FromD2
->getDeclContext());
5431 auto *ToD1
= Import(FromD1
, Lang_CXX11
);
5432 auto *ToD2
= Import(FromD2
, Lang_CXX11
);
5434 EXPECT_EQ(ToD1
->getTemplateParameters()->getParam(0)->getDeclContext(),
5435 ToD1
->getDeclContext());
5436 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5437 ToD1
->getDeclContext(), ToD1
->getTemplateParameters()->getParam(0)));
5438 EXPECT_EQ(ToD2
->getTemplateParameters()->getParam(0)->getDeclContext(),
5439 ToD2
->getDeclContext());
5440 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
5441 ToD2
->getDeclContext(), ToD2
->getTemplateParameters()->getParam(0)));
5444 TEST_P(ASTImporterOptionSpecificTestBase
, ImportSubstTemplateTypeParmType
) {
5445 constexpr auto Code
= R
"(
5446 template <class A1, class... A2> struct A {
5447 using B = A1(A2...);
5449 template struct A<void, char, float, int, short>;
5451 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
, "input.cpp");
5452 auto *FromClass
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
5453 FromTU
, classTemplateSpecializationDecl());
5455 auto testType
= [&](ASTContext
&Ctx
, const char *Name
,
5456 std::optional
<unsigned> PackIndex
) {
5457 const auto *Subst
= selectFirst
<SubstTemplateTypeParmType
>(
5458 "sttp", match(substTemplateTypeParmType(
5459 hasReplacementType(hasCanonicalType(asString(Name
))))
5462 const char *ExpectedTemplateParamName
= PackIndex
? "A2" : "A1";
5464 ASSERT_EQ(Subst
->getReplacedParameter()->getIdentifier()->getName(),
5465 ExpectedTemplateParamName
);
5466 ASSERT_EQ(Subst
->getPackIndex(), PackIndex
);
5468 auto tests
= [&](ASTContext
&Ctx
) {
5469 testType(Ctx
, "void", std::nullopt
);
5470 testType(Ctx
, "char", 3);
5471 testType(Ctx
, "float", 2);
5472 testType(Ctx
, "int", 1);
5473 testType(Ctx
, "short", 0);
5476 tests(FromTU
->getASTContext());
5478 ClassTemplateSpecializationDecl
*ToClass
= Import(FromClass
, Lang_CXX11
);
5479 tests(ToClass
->getASTContext());
5482 const AstTypeMatcher
<SubstTemplateTypeParmPackType
>
5483 substTemplateTypeParmPackType
;
5485 TEST_P(ASTImporterOptionSpecificTestBase
, ImportSubstTemplateTypeParmPackType
) {
5486 constexpr auto Code
= R
"(
5487 template<typename ...T> struct D {
5488 template<typename... U> using B = int(int (*...p)(T, U));
5489 template<typename U1, typename U2> D(B<U1, U2>*);
5491 int f(int(int, int), int(int, int));
5493 using asd = D<float, double, float>::B<int, long, int>;
5495 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
, "input.cpp");
5496 auto *FromClass
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
5497 FromTU
, classTemplateSpecializationDecl());
5500 ASTContext
&FromCtx
= FromTU
->getASTContext();
5501 const auto *FromSubstPack
= selectFirst
<SubstTemplateTypeParmPackType
>(
5502 "pack", match(substTemplateTypeParmPackType().bind("pack"), FromCtx
));
5504 ASSERT_TRUE(FromSubstPack
);
5505 ASSERT_EQ(FromSubstPack
->getIdentifier()->getName(), "T");
5506 ArrayRef
<TemplateArgument
> FromArgPack
=
5507 FromSubstPack
->getArgumentPack().pack_elements();
5508 ASSERT_EQ(FromArgPack
.size(), 3u);
5509 ASSERT_EQ(FromArgPack
[0].getAsType(), FromCtx
.FloatTy
);
5510 ASSERT_EQ(FromArgPack
[1].getAsType(), FromCtx
.DoubleTy
);
5511 ASSERT_EQ(FromArgPack
[2].getAsType(), FromCtx
.FloatTy
);
5514 // Let's do the import.
5515 ClassTemplateSpecializationDecl
*ToClass
= Import(FromClass
, Lang_CXX11
);
5516 ASTContext
&ToCtx
= ToClass
->getASTContext();
5518 const auto *ToSubstPack
= selectFirst
<SubstTemplateTypeParmPackType
>(
5519 "pack", match(substTemplateTypeParmPackType().bind("pack"), ToCtx
));
5521 // Check if it meets the requirements.
5522 ASSERT_TRUE(ToSubstPack
);
5523 ASSERT_EQ(ToSubstPack
->getIdentifier()->getName(), "T");
5524 ArrayRef
<TemplateArgument
> ToArgPack
=
5525 ToSubstPack
->getArgumentPack().pack_elements();
5526 ASSERT_EQ(ToArgPack
.size(), 3u);
5527 ASSERT_EQ(ToArgPack
[0].getAsType(), ToCtx
.FloatTy
);
5528 ASSERT_EQ(ToArgPack
[1].getAsType(), ToCtx
.DoubleTy
);
5529 ASSERT_EQ(ToArgPack
[2].getAsType(), ToCtx
.FloatTy
);
5533 struct ASTImporterLookupTableTest
: ASTImporterOptionSpecificTestBase
{};
5535 TEST_P(ASTImporterLookupTableTest
, OneDecl
) {
5536 auto *ToTU
= getToTuDecl("int a;", Lang_CXX03
);
5537 auto *D
= FirstDeclMatcher
<VarDecl
>().match(ToTU
, varDecl(hasName("a")));
5538 ASTImporterLookupTable
LT(*ToTU
);
5539 auto Res
= LT
.lookup(ToTU
, D
->getDeclName());
5540 ASSERT_EQ(Res
.size(), 1u);
5541 EXPECT_EQ(*Res
.begin(), D
);
5544 static Decl
*findInDeclListOfDC(DeclContext
*DC
, DeclarationName Name
) {
5545 for (Decl
*D
: DC
->decls()) {
5546 if (auto *ND
= dyn_cast
<NamedDecl
>(D
))
5547 if (ND
->getDeclName() == Name
)
5553 TEST_P(ASTImporterLookupTableTest
,
5554 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup
) {
5561 TranslationUnitDecl
*ToTU
= getToTuDecl(Code
, Lang_CXX03
);
5562 auto *X
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5563 ToTU
, classTemplateDecl(hasName("X")));
5564 auto *Foo
= FirstDeclMatcher
<FunctionDecl
>().match(
5565 ToTU
, functionDecl(hasName("foo")));
5566 DeclContext
*FooDC
= Foo
->getDeclContext();
5567 DeclContext
*FooLexicalDC
= Foo
->getLexicalDeclContext();
5568 ASSERT_EQ(cast
<Decl
>(FooLexicalDC
), X
->getTemplatedDecl());
5569 ASSERT_EQ(cast
<Decl
>(FooDC
), ToTU
);
5570 DeclarationName FooName
= Foo
->getDeclName();
5572 // Cannot find in the LookupTable of its DC (TUDecl)
5573 SmallVector
<NamedDecl
*, 2> FoundDecls
;
5574 FooDC
->getRedeclContext()->localUncachedLookup(FooName
, FoundDecls
);
5575 EXPECT_EQ(FoundDecls
.size(), 0u);
5577 // Cannot find in the LookupTable of its LexicalDC (X)
5578 FooLexicalDC
->getRedeclContext()->localUncachedLookup(FooName
, FoundDecls
);
5579 EXPECT_EQ(FoundDecls
.size(), 0u);
5581 // Can't find in the list of Decls of the DC.
5582 EXPECT_EQ(findInDeclListOfDC(FooDC
, FooName
), nullptr);
5584 // Can't find in the list of Decls of the LexicalDC
5585 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC
, FooName
), nullptr);
5587 // ASTImporter specific lookup finds it.
5588 ASTImporterLookupTable
LT(*ToTU
);
5589 auto Res
= LT
.lookup(FooDC
, Foo
->getDeclName());
5590 ASSERT_EQ(Res
.size(), 1u);
5591 EXPECT_EQ(*Res
.begin(), Foo
);
5594 TEST_P(ASTImporterLookupTableTest
,
5595 FwdDeclStructShouldBeFoundByImporterSpecificLookup
) {
5596 TranslationUnitDecl
*ToTU
=
5597 getToTuDecl("struct A { struct Foo *p; };", Lang_C99
);
5599 FirstDeclMatcher
<RecordDecl
>().match(ToTU
, recordDecl(hasName("Foo")));
5601 FirstDeclMatcher
<RecordDecl
>().match(ToTU
, recordDecl(hasName("A")));
5602 DeclContext
*FooDC
= Foo
->getDeclContext();
5603 DeclContext
*FooLexicalDC
= Foo
->getLexicalDeclContext();
5604 ASSERT_EQ(cast
<Decl
>(FooLexicalDC
), A
);
5605 ASSERT_EQ(cast
<Decl
>(FooDC
), ToTU
);
5606 DeclarationName FooName
= Foo
->getDeclName();
5608 // Cannot find in the LookupTable of its DC (TUDecl).
5609 SmallVector
<NamedDecl
*, 2> FoundDecls
;
5610 FooDC
->getRedeclContext()->localUncachedLookup(FooName
, FoundDecls
);
5611 EXPECT_EQ(FoundDecls
.size(), 0u);
5613 // Finds via linear search of its LexicalDC (A).
5614 FooLexicalDC
->getRedeclContext()->localUncachedLookup(FooName
, FoundDecls
);
5615 EXPECT_EQ(FoundDecls
.size(), 1u);
5617 // Can't find in the list of Decls of the DC.
5618 EXPECT_EQ(findInDeclListOfDC(FooDC
, FooName
), nullptr);
5620 // Can find in the list of Decls of the LexicalDC.
5621 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC
, FooName
), Foo
);
5623 // ASTImporter specific lookup finds it.
5624 ASTImporterLookupTable
LT(*ToTU
);
5625 auto Res
= LT
.lookup(FooDC
, Foo
->getDeclName());
5626 ASSERT_EQ(Res
.size(), 1u);
5627 EXPECT_EQ(*Res
.begin(), Foo
);
5630 TEST_P(ASTImporterLookupTableTest
, LookupFindsNamesInDifferentDC
) {
5631 TranslationUnitDecl
*ToTU
=
5632 getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99
);
5633 DeclarationName VName
= FirstDeclMatcher
<VarDecl
>()
5634 .match(ToTU
, varDecl(hasName("V")))
5637 FirstDeclMatcher
<RecordDecl
>().match(ToTU
, recordDecl(hasName("A")));
5639 FirstDeclMatcher
<RecordDecl
>().match(ToTU
, recordDecl(hasName("B")));
5641 ASTImporterLookupTable
LT(*ToTU
);
5643 auto Res
= LT
.lookup(cast
<DeclContext
>(A
), VName
);
5644 ASSERT_EQ(Res
.size(), 1u);
5645 EXPECT_EQ(*Res
.begin(), FirstDeclMatcher
<FieldDecl
>().match(
5646 ToTU
, fieldDecl(hasName("V"),
5647 hasParent(recordDecl(hasName("A"))))));
5648 Res
= LT
.lookup(cast
<DeclContext
>(B
), VName
);
5649 ASSERT_EQ(Res
.size(), 1u);
5650 EXPECT_EQ(*Res
.begin(), FirstDeclMatcher
<FieldDecl
>().match(
5651 ToTU
, fieldDecl(hasName("V"),
5652 hasParent(recordDecl(hasName("B"))))));
5653 Res
= LT
.lookup(ToTU
, VName
);
5654 ASSERT_EQ(Res
.size(), 1u);
5655 EXPECT_EQ(*Res
.begin(), FirstDeclMatcher
<VarDecl
>().match(
5656 ToTU
, varDecl(hasName("V"),
5657 hasParent(translationUnitDecl()))));
5660 TEST_P(ASTImporterLookupTableTest
, LookupFindsOverloadedNames
) {
5661 TranslationUnitDecl
*ToTU
= getToTuDecl(
5669 ASTImporterLookupTable
LT(*ToTU
);
5670 auto *F0
= FirstDeclMatcher
<FunctionDecl
>().match(ToTU
, functionDecl());
5671 auto *F2
= LastDeclMatcher
<FunctionDecl
>().match(ToTU
, functionDecl());
5672 DeclarationName Name
= F0
->getDeclName();
5673 auto Res
= LT
.lookup(ToTU
, Name
);
5674 EXPECT_EQ(Res
.size(), 3u);
5675 EXPECT_EQ(Res
.count(F0
), 1u);
5676 EXPECT_EQ(Res
.count(F2
), 1u);
5679 TEST_P(ASTImporterLookupTableTest
,
5680 DifferentOperatorsShouldHaveDifferentResultSet
) {
5681 TranslationUnitDecl
*ToTU
= getToTuDecl(
5684 void operator+(X, X);
5685 void operator-(X, X);
5689 ASTImporterLookupTable
LT(*ToTU
);
5690 auto *FPlus
= FirstDeclMatcher
<FunctionDecl
>().match(
5691 ToTU
, functionDecl(hasOverloadedOperatorName("+")));
5692 auto *FMinus
= FirstDeclMatcher
<FunctionDecl
>().match(
5693 ToTU
, functionDecl(hasOverloadedOperatorName("-")));
5694 DeclarationName NamePlus
= FPlus
->getDeclName();
5695 auto ResPlus
= LT
.lookup(ToTU
, NamePlus
);
5696 EXPECT_EQ(ResPlus
.size(), 1u);
5697 EXPECT_EQ(ResPlus
.count(FPlus
), 1u);
5698 EXPECT_EQ(ResPlus
.count(FMinus
), 0u);
5699 DeclarationName NameMinus
= FMinus
->getDeclName();
5700 auto ResMinus
= LT
.lookup(ToTU
, NameMinus
);
5701 EXPECT_EQ(ResMinus
.size(), 1u);
5702 EXPECT_EQ(ResMinus
.count(FMinus
), 1u);
5703 EXPECT_EQ(ResMinus
.count(FPlus
), 0u);
5704 EXPECT_NE(*ResMinus
.begin(), *ResPlus
.begin());
5707 TEST_P(ASTImporterLookupTableTest
, LookupDeclNamesFromDifferentTUs
) {
5708 TranslationUnitDecl
*ToTU
= getToTuDecl(
5711 void operator+(X, X);
5714 auto *ToPlus
= FirstDeclMatcher
<FunctionDecl
>().match(
5715 ToTU
, functionDecl(hasOverloadedOperatorName("+")));
5717 Decl
*FromTU
= getTuDecl(
5720 void operator+(X, X);
5723 auto *FromPlus
= FirstDeclMatcher
<FunctionDecl
>().match(
5724 FromTU
, functionDecl(hasOverloadedOperatorName("+")));
5726 // FromPlus have a different TU, thus its DeclarationName is different too.
5727 ASSERT_NE(ToPlus
->getDeclName(), FromPlus
->getDeclName());
5729 ASTImporterLookupTable
LT(*ToTU
);
5730 auto Res
= LT
.lookup(ToTU
, ToPlus
->getDeclName());
5731 ASSERT_EQ(Res
.size(), 1u);
5732 EXPECT_EQ(*Res
.begin(), ToPlus
);
5734 // FromPlus have a different TU, thus its DeclarationName is different too.
5735 Res
= LT
.lookup(ToTU
, FromPlus
->getDeclName());
5736 ASSERT_EQ(Res
.size(), 0u);
5739 TEST_P(ASTImporterLookupTableTest
,
5740 LookupFindsFwdFriendClassDeclWithElaboratedType
) {
5741 TranslationUnitDecl
*ToTU
= getToTuDecl(
5743 class Y { friend class F; };
5747 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5748 // So we must dig up the underlying CXXRecordDecl.
5749 ASTImporterLookupTable
LT(*ToTU
);
5750 auto *FriendD
= FirstDeclMatcher
<FriendDecl
>().match(ToTU
, friendDecl());
5751 const RecordDecl
*RD
= getRecordDeclOfFriend(FriendD
);
5752 auto *Y
= FirstDeclMatcher
<CXXRecordDecl
>().match(
5753 ToTU
, cxxRecordDecl(hasName("Y")));
5755 DeclarationName Name
= RD
->getDeclName();
5756 auto Res
= LT
.lookup(ToTU
, Name
);
5757 EXPECT_EQ(Res
.size(), 1u);
5758 EXPECT_EQ(*Res
.begin(), RD
);
5760 Res
= LT
.lookup(Y
, Name
);
5761 EXPECT_EQ(Res
.size(), 0u);
5764 TEST_P(ASTImporterLookupTableTest
,
5765 LookupFindsFwdFriendClassDeclWithUnelaboratedType
) {
5766 TranslationUnitDecl
*ToTU
= getToTuDecl(
5769 class Y { friend F; };
5773 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5774 // So we must dig up the underlying CXXRecordDecl.
5775 ASTImporterLookupTable
LT(*ToTU
);
5776 auto *FriendD
= FirstDeclMatcher
<FriendDecl
>().match(ToTU
, friendDecl());
5777 const RecordDecl
*RD
= getRecordDeclOfFriend(FriendD
);
5778 auto *Y
= FirstDeclMatcher
<CXXRecordDecl
>().match(ToTU
, cxxRecordDecl(hasName("Y")));
5780 DeclarationName Name
= RD
->getDeclName();
5781 auto Res
= LT
.lookup(ToTU
, Name
);
5782 EXPECT_EQ(Res
.size(), 1u);
5783 EXPECT_EQ(*Res
.begin(), RD
);
5785 Res
= LT
.lookup(Y
, Name
);
5786 EXPECT_EQ(Res
.size(), 0u);
5789 TEST_P(ASTImporterLookupTableTest
,
5790 LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert
) {
5791 TranslationUnitDecl
*ToTU
= getToTuDecl(
5794 using alias_of_f = F;
5795 class Y { friend alias_of_f; };
5799 // ASTImporterLookupTable constructor handles using declarations correctly,
5800 // no assert is expected.
5801 ASTImporterLookupTable
LT(*ToTU
);
5803 auto *Alias
= FirstDeclMatcher
<TypeAliasDecl
>().match(
5804 ToTU
, typeAliasDecl(hasName("alias_of_f")));
5805 DeclarationName Name
= Alias
->getDeclName();
5806 auto Res
= LT
.lookup(ToTU
, Name
);
5807 EXPECT_EQ(Res
.count(Alias
), 1u);
5810 TEST_P(ASTImporterLookupTableTest
,
5811 LookupFindsFriendClassDeclWithUsingTypeDoesNotAssert
) {
5812 TranslationUnitDecl
*ToTU
= getToTuDecl(
5815 namespace b { class InnerClass; }
5816 using b::InnerClass;
5819 friend a::InnerClass;
5824 // ASTImporterLookupTable constructor handles friend with using-type without
5826 ASTImporterLookupTable
LT(*ToTU
);
5828 auto *Using
= FirstDeclMatcher
<UsingDecl
>().match(
5829 ToTU
, usingDecl(hasName("InnerClass")));
5830 DeclarationName Name
= Using
->getDeclName();
5831 auto Res
= LT
.lookup(ToTU
, Name
);
5832 EXPECT_EQ(Res
.size(), 0u);
5833 auto *NsA
= FirstDeclMatcher
<NamespaceDecl
>().match(
5834 ToTU
, namespaceDecl(hasName("a")));
5835 auto *RecordB
= FirstDeclMatcher
<CXXRecordDecl
>().match(
5836 ToTU
, cxxRecordDecl(hasName("B")));
5837 auto Res1
= LT
.lookup(NsA
, Name
);
5838 EXPECT_EQ(Res1
.count(Using
), 1u);
5839 auto Res2
= LT
.lookup(RecordB
, Name
);
5840 EXPECT_EQ(Res2
.size(), 0u);
5843 TEST_P(ASTImporterLookupTableTest
, LookupFindsFwdFriendClassTemplateDecl
) {
5844 TranslationUnitDecl
*ToTU
= getToTuDecl(
5846 class Y { template <class T> friend class F; };
5850 ASTImporterLookupTable
LT(*ToTU
);
5851 auto *F
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5852 ToTU
, classTemplateDecl(hasName("F")));
5853 DeclarationName Name
= F
->getDeclName();
5854 auto Res
= LT
.lookup(ToTU
, Name
);
5855 EXPECT_EQ(Res
.size(), 2u);
5856 EXPECT_EQ(Res
.count(F
), 1u);
5857 EXPECT_EQ(Res
.count(F
->getTemplatedDecl()), 1u);
5860 TEST_P(ASTImporterLookupTableTest
, DependentFriendClass
) {
5861 TranslationUnitDecl
*ToTU
= getToTuDecl(
5863 template <typename T>
5866 template <typename T>
5873 ASTImporterLookupTable
LT(*ToTU
);
5874 auto *F
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5875 ToTU
, classTemplateDecl(hasName("F")));
5876 DeclarationName Name
= F
->getDeclName();
5877 auto Res
= LT
.lookup(ToTU
, Name
);
5878 EXPECT_EQ(Res
.size(), 2u);
5879 EXPECT_EQ(Res
.count(F
), 1u);
5880 EXPECT_EQ(Res
.count(F
->getTemplatedDecl()), 1u);
5883 TEST_P(ASTImporterLookupTableTest
, FriendClassTemplateSpecialization
) {
5884 TranslationUnitDecl
*ToTU
= getToTuDecl(
5886 template <typename T>
5890 friend class F<int>;
5895 ASTImporterLookupTable
LT(*ToTU
);
5896 auto *F
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5897 ToTU
, classTemplateDecl(hasName("F")));
5898 DeclarationName Name
= F
->getDeclName();
5899 auto Res
= LT
.lookup(ToTU
, Name
);
5900 ASSERT_EQ(Res
.size(), 3u);
5901 EXPECT_EQ(Res
.count(F
), 1u);
5902 EXPECT_EQ(Res
.count(F
->getTemplatedDecl()), 1u);
5903 EXPECT_EQ(Res
.count(*F
->spec_begin()), 1u);
5906 TEST_P(ASTImporterLookupTableTest
, LookupFindsFwdFriendFunctionDecl
) {
5907 TranslationUnitDecl
*ToTU
= getToTuDecl(
5909 class Y { friend void F(); };
5913 ASTImporterLookupTable
LT(*ToTU
);
5915 FirstDeclMatcher
<FunctionDecl
>().match(ToTU
, functionDecl(hasName("F")));
5916 DeclarationName Name
= F
->getDeclName();
5917 auto Res
= LT
.lookup(ToTU
, Name
);
5918 EXPECT_EQ(Res
.size(), 1u);
5919 EXPECT_EQ(*Res
.begin(), F
);
5922 TEST_P(ASTImporterLookupTableTest
,
5923 LookupFindsDeclsInClassTemplateSpecialization
) {
5924 TranslationUnitDecl
*ToTU
= getToTuDecl(
5926 template <typename T>
5936 ASTImporterLookupTable
LT(*ToTU
);
5938 auto *Template
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
5939 ToTU
, classTemplateDecl(hasName("X")));
5940 auto *FieldInTemplate
= FirstDeclMatcher
<FieldDecl
>().match(
5942 fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl())))));
5944 auto *Spec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
5945 ToTU
, classTemplateSpecializationDecl(hasName("X")));
5946 FieldDecl
*FieldInSpec
= *Spec
->field_begin();
5947 ASSERT_TRUE(FieldInSpec
);
5949 DeclarationName Name
= FieldInSpec
->getDeclName();
5950 auto TemplateDC
= cast
<DeclContext
>(Template
->getTemplatedDecl());
5952 SmallVector
<NamedDecl
*, 2> FoundDecls
;
5953 TemplateDC
->getRedeclContext()->localUncachedLookup(Name
, FoundDecls
);
5954 EXPECT_EQ(FoundDecls
.size(), 1u);
5955 EXPECT_EQ(FoundDecls
[0], FieldInTemplate
);
5957 auto Res
= LT
.lookup(TemplateDC
, Name
);
5958 ASSERT_EQ(Res
.size(), 1u);
5959 EXPECT_EQ(*Res
.begin(), FieldInTemplate
);
5961 cast
<DeclContext
>(Spec
)->getRedeclContext()->localUncachedLookup(Name
,
5963 EXPECT_EQ(FoundDecls
.size(), 1u);
5964 EXPECT_EQ(FoundDecls
[0], FieldInSpec
);
5966 Res
= LT
.lookup(cast
<DeclContext
>(Spec
), Name
);
5967 ASSERT_EQ(Res
.size(), 1u);
5968 EXPECT_EQ(*Res
.begin(), FieldInSpec
);
5971 TEST_P(ASTImporterLookupTableTest
, LookupFindsFwdFriendFunctionTemplateDecl
) {
5972 TranslationUnitDecl
*ToTU
= getToTuDecl(
5974 class Y { template <class T> friend void F(); };
5978 ASTImporterLookupTable
LT(*ToTU
);
5979 auto *F
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
5980 ToTU
, functionTemplateDecl(hasName("F")));
5981 DeclarationName Name
= F
->getDeclName();
5982 auto Res
= LT
.lookup(ToTU
, Name
);
5983 EXPECT_EQ(Res
.size(), 2u);
5984 EXPECT_EQ(Res
.count(F
), 1u);
5985 EXPECT_EQ(Res
.count(F
->getTemplatedDecl()), 1u);
5988 TEST_P(ASTImporterLookupTableTest
, MultipleBefriendingClasses
) {
5989 TranslationUnitDecl
*ToTU
= getToTuDecl(
6001 ASTImporterLookupTable
LT(*ToTU
);
6002 auto *X
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6003 ToTU
, cxxRecordDecl(hasName("X")));
6004 auto *FriendD0
= FirstDeclMatcher
<FriendDecl
>().match(ToTU
, friendDecl());
6005 auto *FriendD1
= LastDeclMatcher
<FriendDecl
>().match(ToTU
, friendDecl());
6006 const RecordDecl
*RD0
= getRecordDeclOfFriend(FriendD0
);
6007 const RecordDecl
*RD1
= getRecordDeclOfFriend(FriendD1
);
6008 ASSERT_EQ(RD0
, RD1
);
6011 DeclarationName Name
= X
->getDeclName();
6012 auto Res
= LT
.lookup(ToTU
, Name
);
6013 EXPECT_EQ(Res
.size(), 1u);
6014 EXPECT_EQ(*Res
.begin(), X
);
6017 TEST_P(ASTImporterLookupTableTest
, EnumConstantDecl
) {
6018 TranslationUnitDecl
*ToTU
= getToTuDecl(
6027 ASTImporterLookupTable
LT(*ToTU
);
6028 auto *E
= FirstDeclMatcher
<EnumDecl
>().match(ToTU
, enumDecl(hasName("E")));
6029 auto *A
= FirstDeclMatcher
<EnumConstantDecl
>().match(
6030 ToTU
, enumConstantDecl(hasName("A")));
6032 DeclarationName Name
= A
->getDeclName();
6033 // Redecl context is the TU.
6034 ASSERT_EQ(E
->getRedeclContext(), ToTU
);
6036 SmallVector
<NamedDecl
*, 2> FoundDecls
;
6037 // Normal lookup finds in the DC.
6038 E
->localUncachedLookup(Name
, FoundDecls
);
6039 EXPECT_EQ(FoundDecls
.size(), 1u);
6041 // Normal lookup finds in the Redecl context.
6042 ToTU
->localUncachedLookup(Name
, FoundDecls
);
6043 EXPECT_EQ(FoundDecls
.size(), 1u);
6045 // Import specific lookup finds in the DC.
6046 auto Res
= LT
.lookup(E
, Name
);
6047 ASSERT_EQ(Res
.size(), 1u);
6048 EXPECT_EQ(*Res
.begin(), A
);
6050 // Import specific lookup finds in the Redecl context.
6051 Res
= LT
.lookup(ToTU
, Name
);
6052 ASSERT_EQ(Res
.size(), 1u);
6053 EXPECT_EQ(*Res
.begin(), A
);
6056 TEST_P(ASTImporterLookupTableTest
, LookupSearchesInTheWholeRedeclChain
) {
6057 TranslationUnitDecl
*ToTU
= getToTuDecl(
6067 LastDeclMatcher
<NamespaceDecl
>().match(ToTU
, namespaceDecl(hasName("N")));
6068 auto *A
= FirstDeclMatcher
<VarDecl
>().match(ToTU
, varDecl(hasName("A")));
6069 DeclarationName Name
= A
->getDeclName();
6071 ASTImporterLookupTable
LT(*ToTU
);
6072 auto Res
= LT
.lookup(N1
, Name
);
6073 ASSERT_EQ(Res
.size(), 1u);
6074 EXPECT_EQ(*Res
.begin(), A
);
6077 TEST_P(ASTImporterOptionSpecificTestBase
,
6078 RedeclChainShouldBeCorrectAmongstNamespaces
) {
6079 Decl
*FromTU
= getTuDecl(
6084 static const int I = 3;
6088 struct X { // <--- To be imported
6089 void method(int i = Y::I) {}
6095 auto *FromFwd
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6096 FromTU
, cxxRecordDecl(hasName("X"), unless(isImplicit())));
6097 auto *FromDef
= LastDeclMatcher
<CXXRecordDecl
>().match(
6099 cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit())));
6100 ASSERT_NE(FromFwd
, FromDef
);
6101 ASSERT_FALSE(FromFwd
->isThisDeclarationADefinition());
6102 ASSERT_TRUE(FromDef
->isThisDeclarationADefinition());
6103 ASSERT_EQ(FromFwd
->getCanonicalDecl(), FromDef
->getCanonicalDecl());
6105 auto *ToDef
= cast_or_null
<CXXRecordDecl
>(Import(FromDef
, Lang_CXX03
));
6106 auto *ToFwd
= cast_or_null
<CXXRecordDecl
>(Import(FromFwd
, Lang_CXX03
));
6107 EXPECT_NE(ToFwd
, ToDef
);
6108 EXPECT_FALSE(ToFwd
->isThisDeclarationADefinition());
6109 EXPECT_TRUE(ToDef
->isThisDeclarationADefinition());
6110 EXPECT_EQ(ToFwd
->getCanonicalDecl(), ToDef
->getCanonicalDecl());
6111 auto *ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
6112 // We expect no (ODR) warning during the import.
6113 EXPECT_EQ(0u, ToTU
->getASTContext().getDiagnostics().getNumWarnings());
6116 struct ImportFriendFunctionTemplates
: ASTImporterOptionSpecificTestBase
{};
6118 TEST_P(ImportFriendFunctionTemplates
, LookupShouldFindPreviousFriend
) {
6119 Decl
*ToTU
= getToTuDecl(
6122 template <typename T> friend void foo();
6126 auto *Friend
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
6127 ToTU
, functionTemplateDecl(hasName("foo")));
6129 Decl
*FromTU
= getTuDecl(
6131 template <typename T> void foo();
6134 auto *FromFoo
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
6135 FromTU
, functionTemplateDecl(hasName("foo")));
6136 auto *Imported
= Import(FromFoo
, Lang_CXX03
);
6138 EXPECT_EQ(Imported
->getPreviousDecl(), Friend
);
6141 TEST_P(ImportFriendFunctionTemplates
, ImportFriendFunctionInsideClassTemplate
) {
6143 std::tie(From
, To
) = getImportedDecl(
6145 template <typename T> struct X {
6146 template <typename U> friend void f();
6149 Lang_CXX03
, "", Lang_CXX03
, "X");
6151 auto *FromFriend
= FirstDeclMatcher
<FriendDecl
>().match(From
, friendDecl());
6152 auto *ToFriend
= FirstDeclMatcher
<FriendDecl
>().match(To
, friendDecl());
6154 EXPECT_TRUE(FromFriend
==
6155 LastDeclMatcher
<FriendDecl
>().match(From
, friendDecl()));
6156 EXPECT_TRUE(ToFriend
==
6157 LastDeclMatcher
<FriendDecl
>().match(To
, friendDecl()));
6159 auto *FromDecl
= FromFriend
->getFriendDecl();
6160 auto *FromDC
= FromFriend
->getDeclContext();
6161 auto *FromLexicalDC
= FromFriend
->getLexicalDeclContext();
6163 EXPECT_TRUE(FromDC
->containsDecl(FromFriend
));
6164 EXPECT_FALSE(FromDC
->containsDecl(FromDecl
));
6165 EXPECT_TRUE(FromLexicalDC
->containsDecl(FromFriend
));
6166 EXPECT_FALSE(FromLexicalDC
->containsDecl(FromDecl
));
6168 auto *ToDecl
= ToFriend
->getFriendDecl();
6169 auto *ToDC
= ToFriend
->getDeclContext();
6170 auto *ToLexicalDC
= ToFriend
->getLexicalDeclContext();
6172 EXPECT_TRUE(ToDC
->containsDecl(ToFriend
));
6173 EXPECT_FALSE(ToDC
->containsDecl(ToDecl
));
6174 EXPECT_TRUE(ToLexicalDC
->containsDecl(ToFriend
));
6175 EXPECT_FALSE(ToLexicalDC
->containsDecl(ToDecl
));
6178 struct ASTImporterWithFakeErrors
: ASTImporter
{
6179 using ASTImporter::ASTImporter
;
6180 bool returnWithErrorInTest() override
{ return true; }
6183 struct ErrorHandlingTest
: ASTImporterOptionSpecificTestBase
{
6184 ErrorHandlingTest() {
6185 Creator
= [](ASTContext
&ToContext
, FileManager
&ToFileManager
,
6186 ASTContext
&FromContext
, FileManager
&FromFileManager
,
6188 const std::shared_ptr
<ASTImporterSharedState
> &SharedState
) {
6189 return new ASTImporterWithFakeErrors(ToContext
, ToFileManager
,
6190 FromContext
, FromFileManager
,
6191 MinimalImport
, SharedState
);
6194 // In this test we purposely report an error (UnsupportedConstruct) when
6195 // importing the below stmt.
6196 static constexpr auto* ErroneousStmt
= R
"( asm(""); )";
6199 // Check a case when no new AST node is created in the AST before encountering
6201 TEST_P(ErrorHandlingTest
, ErrorHappensBeforeCreatingANewNode
) {
6202 TranslationUnitDecl
*ToTU
= getToTuDecl(
6204 template <typename T>
6207 class X<int> { int a; };
6210 TranslationUnitDecl
*FromTU
= getTuDecl(
6212 template <typename T>
6215 class X<int> { double b; };
6218 auto *FromSpec
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
6219 FromTU
, classTemplateSpecializationDecl(hasName("X")));
6220 ClassTemplateSpecializationDecl
*ImportedSpec
= Import(FromSpec
, Lang_CXX03
);
6221 EXPECT_FALSE(ImportedSpec
);
6223 // The original Decl is kept, no new decl is created.
6224 EXPECT_EQ(DeclCounter
<ClassTemplateSpecializationDecl
>().match(
6225 ToTU
, classTemplateSpecializationDecl(hasName("X"))),
6228 // But an error is set to the counterpart in the "from" context.
6229 ASTImporter
*Importer
= findFromTU(FromSpec
)->Importer
.get();
6230 std::optional
<ASTImportError
> OptErr
=
6231 Importer
->getImportDeclErrorIfAny(FromSpec
);
6232 ASSERT_TRUE(OptErr
);
6233 EXPECT_EQ(OptErr
->Error
, ASTImportError::NameConflict
);
6236 // Check a case when a new AST node is created but not linked to the AST before
6237 // encountering the error.
6238 TEST_P(ErrorHandlingTest
,
6239 ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST
) {
6240 TranslationUnitDecl
*FromTU
= getTuDecl(
6241 std::string("void foo() { ") + ErroneousStmt
+ " }", Lang_CXX03
);
6242 auto *FromFoo
= FirstDeclMatcher
<FunctionDecl
>().match(
6243 FromTU
, functionDecl(hasName("foo")));
6245 FunctionDecl
*ImportedFoo
= Import(FromFoo
, Lang_CXX03
);
6246 EXPECT_FALSE(ImportedFoo
);
6248 TranslationUnitDecl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
6249 // Created, but not linked.
6251 DeclCounter
<FunctionDecl
>().match(ToTU
, functionDecl(hasName("foo"))),
6254 ASTImporter
*Importer
= findFromTU(FromFoo
)->Importer
.get();
6255 std::optional
<ASTImportError
> OptErr
=
6256 Importer
->getImportDeclErrorIfAny(FromFoo
);
6257 ASSERT_TRUE(OptErr
);
6258 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6261 // Check a case when a new AST node is created and linked to the AST before
6262 // encountering the error. The error is set for the counterpart of the nodes in
6263 // the "from" context.
6264 TEST_P(ErrorHandlingTest
, ErrorHappensAfterNodeIsCreatedAndLinked
) {
6265 TranslationUnitDecl
*FromTU
= getTuDecl(std::string(R
"(
6267 void f() { )") + ErroneousStmt
+ R
"( }
6270 auto *FromProto
= FirstDeclMatcher
<FunctionDecl
>().match(
6271 FromTU
, functionDecl(hasName("f")));
6273 LastDeclMatcher
<FunctionDecl
>().match(FromTU
, functionDecl(hasName("f")));
6274 FunctionDecl
*ImportedProto
= Import(FromProto
, Lang_CXX03
);
6275 EXPECT_FALSE(ImportedProto
); // Could not import.
6276 // However, we created two nodes in the AST. 1) the fwd decl 2) the
6277 // definition. The definition is not added to its DC, but the fwd decl is
6279 TranslationUnitDecl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
6280 EXPECT_EQ(DeclCounter
<FunctionDecl
>().match(ToTU
, functionDecl(hasName("f"))),
6282 // Match the fwd decl.
6284 FirstDeclMatcher
<FunctionDecl
>().match(ToTU
, functionDecl(hasName("f")));
6285 EXPECT_TRUE(ToProto
);
6286 // An error is set to the counterpart in the "from" context both for the fwd
6287 // decl and the definition.
6288 ASTImporter
*Importer
= findFromTU(FromProto
)->Importer
.get();
6289 std::optional
<ASTImportError
> OptErr
=
6290 Importer
->getImportDeclErrorIfAny(FromProto
);
6291 ASSERT_TRUE(OptErr
);
6292 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6293 OptErr
= Importer
->getImportDeclErrorIfAny(FromDef
);
6294 ASSERT_TRUE(OptErr
);
6295 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6298 // An error should be set for a class if we cannot import one member.
6299 TEST_P(ErrorHandlingTest
, ErrorIsPropagatedFromMemberToClass
) {
6300 TranslationUnitDecl
*FromTU
= getTuDecl(std::string(R
"(
6302 void f() { )") + ErroneousStmt
+ R
"( } // This member has the error
6304 void ok(); // The error should not prevent importing this.
6305 }; // An error will be set for X too.
6308 auto *FromX
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6309 FromTU
, cxxRecordDecl(hasName("X")));
6310 CXXRecordDecl
*ImportedX
= Import(FromX
, Lang_CXX03
);
6312 // An error is set for X.
6313 EXPECT_FALSE(ImportedX
);
6314 ASTImporter
*Importer
= findFromTU(FromX
)->Importer
.get();
6315 std::optional
<ASTImportError
> OptErr
=
6316 Importer
->getImportDeclErrorIfAny(FromX
);
6317 ASSERT_TRUE(OptErr
);
6318 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6320 // An error is set for f().
6321 auto *FromF
= FirstDeclMatcher
<CXXMethodDecl
>().match(
6322 FromTU
, cxxMethodDecl(hasName("f")));
6323 OptErr
= Importer
->getImportDeclErrorIfAny(FromF
);
6324 ASSERT_TRUE(OptErr
);
6325 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6326 // And any subsequent import should fail.
6327 CXXMethodDecl
*ImportedF
= Import(FromF
, Lang_CXX03
);
6328 EXPECT_FALSE(ImportedF
);
6330 // There is an error set for the other member too.
6331 auto *FromOK
= FirstDeclMatcher
<CXXMethodDecl
>().match(
6332 FromTU
, cxxMethodDecl(hasName("ok")));
6333 OptErr
= Importer
->getImportDeclErrorIfAny(FromOK
);
6334 EXPECT_TRUE(OptErr
);
6335 // Cannot import the other member.
6336 CXXMethodDecl
*ImportedOK
= Import(FromOK
, Lang_CXX03
);
6337 EXPECT_FALSE(ImportedOK
);
6340 // Check that an error propagates to the dependent AST nodes.
6341 // In the below code it means that an error in X should propagate to A.
6342 // And even to F since the containing A is erroneous.
6343 // And to all AST nodes which we visit during the import process which finally
6344 // ends up in a failure (in the error() function).
6345 TEST_P(ErrorHandlingTest
, ErrorPropagatesThroughImportCycles
) {
6346 Decl
*FromTU
= getTuDecl(std::string(R
"(
6349 template <int I> class F {};
6351 template <int I> friend class F;
6352 void error() { )") +
6353 ErroneousStmt
+ R
"( }
6360 Lang_CXX03
, "input0.cc");
6362 auto *FromFRD
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6363 FromTU
, cxxRecordDecl(hasName("F"), isDefinition()));
6364 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6365 FromTU
, cxxRecordDecl(hasName("A"), isDefinition()));
6366 auto *FromB
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6367 FromTU
, cxxRecordDecl(hasName("B"), isDefinition()));
6368 auto *FromNS
= FirstDeclMatcher
<NamespaceDecl
>().match(
6369 FromTU
, namespaceDecl(hasName("NS")));
6371 // Start by importing the templated CXXRecordDecl of F.
6372 // Import fails for that.
6373 EXPECT_FALSE(Import(FromFRD
, Lang_CXX03
));
6374 // Import fails for A.
6375 EXPECT_FALSE(Import(FromA
, Lang_CXX03
));
6376 // But we should be able to import the independent B.
6377 EXPECT_TRUE(Import(FromB
, Lang_CXX03
));
6378 // And the namespace.
6379 EXPECT_TRUE(Import(FromNS
, Lang_CXX03
));
6381 // An error is set to the templated CXXRecordDecl of F.
6382 ASTImporter
*Importer
= findFromTU(FromFRD
)->Importer
.get();
6383 std::optional
<ASTImportError
> OptErr
=
6384 Importer
->getImportDeclErrorIfAny(FromFRD
);
6385 EXPECT_TRUE(OptErr
);
6387 // An error is set to A.
6388 OptErr
= Importer
->getImportDeclErrorIfAny(FromA
);
6389 EXPECT_TRUE(OptErr
);
6391 // There is no error set to B.
6392 OptErr
= Importer
->getImportDeclErrorIfAny(FromB
);
6393 EXPECT_FALSE(OptErr
);
6395 // There is no error set to NS.
6396 OptErr
= Importer
->getImportDeclErrorIfAny(FromNS
);
6397 EXPECT_FALSE(OptErr
);
6399 // Check some of those decls whose ancestor is X, they all should have an
6400 // error set if we visited them during an import process which finally failed.
6401 // These decls are part of a cycle in an ImportPath.
6402 // There would not be any error set for these decls if we hadn't follow the
6403 // ImportPaths and the cycles.
6404 OptErr
= Importer
->getImportDeclErrorIfAny(
6405 FirstDeclMatcher
<ClassTemplateDecl
>().match(
6406 FromTU
, classTemplateDecl(hasName("F"))));
6407 // An error is set to the 'F' ClassTemplateDecl.
6408 EXPECT_TRUE(OptErr
);
6409 // An error is set to the FriendDecl.
6410 OptErr
= Importer
->getImportDeclErrorIfAny(
6411 FirstDeclMatcher
<FriendDecl
>().match(
6412 FromTU
, friendDecl()));
6413 EXPECT_TRUE(OptErr
);
6414 // An error is set to the implicit class of A.
6416 Importer
->getImportDeclErrorIfAny(FirstDeclMatcher
<CXXRecordDecl
>().match(
6417 FromTU
, cxxRecordDecl(hasName("A"), isImplicit())));
6418 EXPECT_TRUE(OptErr
);
6419 // An error is set to the implicit class of X.
6421 Importer
->getImportDeclErrorIfAny(FirstDeclMatcher
<CXXRecordDecl
>().match(
6422 FromTU
, cxxRecordDecl(hasName("X"), isImplicit())));
6423 EXPECT_TRUE(OptErr
);
6426 TEST_P(ErrorHandlingTest
, ErrorIsNotPropagatedFromMemberToNamespace
) {
6427 TranslationUnitDecl
*FromTU
= getTuDecl(std::string(R
"(
6429 void f() { )") + ErroneousStmt
+ R
"( } // This member has the error
6431 void ok(); // The error should not prevent importing this.
6432 }; // An error will be set for X too.
6435 auto *FromX
= FirstDeclMatcher
<NamespaceDecl
>().match(
6436 FromTU
, namespaceDecl(hasName("X")));
6437 NamespaceDecl
*ImportedX
= Import(FromX
, Lang_CXX03
);
6439 // There is no error set for X.
6440 EXPECT_TRUE(ImportedX
);
6441 ASTImporter
*Importer
= findFromTU(FromX
)->Importer
.get();
6442 std::optional
<ASTImportError
> OptErr
=
6443 Importer
->getImportDeclErrorIfAny(FromX
);
6444 ASSERT_FALSE(OptErr
);
6446 // An error is set for f().
6447 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
6448 FromTU
, functionDecl(hasName("f")));
6449 OptErr
= Importer
->getImportDeclErrorIfAny(FromF
);
6450 ASSERT_TRUE(OptErr
);
6451 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6452 // And any subsequent import should fail.
6453 FunctionDecl
*ImportedF
= Import(FromF
, Lang_CXX03
);
6454 EXPECT_FALSE(ImportedF
);
6456 // There is no error set for ok().
6457 auto *FromOK
= FirstDeclMatcher
<FunctionDecl
>().match(
6458 FromTU
, functionDecl(hasName("ok")));
6459 OptErr
= Importer
->getImportDeclErrorIfAny(FromOK
);
6460 EXPECT_FALSE(OptErr
);
6461 // And we should be able to import.
6462 FunctionDecl
*ImportedOK
= Import(FromOK
, Lang_CXX03
);
6463 EXPECT_TRUE(ImportedOK
);
6466 TEST_P(ErrorHandlingTest
, ODRViolationWithinTypedefDecls
) {
6467 // Importing `z` should fail - instead of crashing - due to an ODR violation.
6468 // The `bar::e` typedef sets it's DeclContext after the import is done.
6469 // However, if the importation fails, it will be left as a nullptr.
6470 // During the cleanup of the failed import, we should check whether the
6471 // DeclContext is null or not - instead of dereferencing that unconditionally.
6472 constexpr auto ToTUCode
= R
"(
6478 constexpr auto FromTUCode
= R
"(
6488 Decl
*ToTU
= getToTuDecl(ToTUCode
, Lang_CXX11
);
6489 static_cast<void>(ToTU
);
6490 Decl
*FromTU
= getTuDecl(FromTUCode
, Lang_CXX11
);
6492 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("z")));
6494 ASSERT_TRUE(FromZ
->hasInit());
6496 auto *ImportedZ
= Import(FromZ
, Lang_CXX11
);
6497 EXPECT_FALSE(ImportedZ
);
6500 // An error should be set for a class if it had a previous import with an error
6502 TEST_P(ErrorHandlingTest
,
6503 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt
) {
6504 // We already have a fwd decl.
6505 TranslationUnitDecl
*ToTU
= getToTuDecl("class X;", Lang_CXX03
);
6506 // Then we import a definition.
6508 TranslationUnitDecl
*FromTU
= getTuDecl(std::string(R
"(
6510 void f() { )") + ErroneousStmt
+ R
"( }
6515 auto *FromX
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6516 FromTU
, cxxRecordDecl(hasName("X")));
6517 CXXRecordDecl
*ImportedX
= Import(FromX
, Lang_CXX03
);
6519 // An error is set for X ...
6520 EXPECT_FALSE(ImportedX
);
6521 ASTImporter
*Importer
= findFromTU(FromX
)->Importer
.get();
6522 std::optional
<ASTImportError
> OptErr
=
6523 Importer
->getImportDeclErrorIfAny(FromX
);
6524 ASSERT_TRUE(OptErr
);
6525 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6527 // ... but the node had been created.
6528 auto *ToXDef
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6529 ToTU
, cxxRecordDecl(hasName("X"), isDefinition()));
6530 // An error is set for "ToXDef" in the shared state.
6531 std::optional
<ASTImportError
> OptErr
=
6532 SharedStatePtr
->getImportDeclErrorIfAny(ToXDef
);
6533 ASSERT_TRUE(OptErr
);
6534 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6536 auto *ToXFwd
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6537 ToTU
, cxxRecordDecl(hasName("X"), unless(isDefinition())));
6538 // An error is NOT set for the fwd Decl of X in the shared state.
6539 OptErr
= SharedStatePtr
->getImportDeclErrorIfAny(ToXFwd
);
6540 ASSERT_FALSE(OptErr
);
6542 // Try to import X again but from another TU.
6544 TranslationUnitDecl
*FromTU
= getTuDecl(std::string(R
"(
6546 void f() { )") + ErroneousStmt
+ R
"( }
6550 Lang_CXX03
, "input1.cc");
6552 auto *FromX
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6553 FromTU
, cxxRecordDecl(hasName("X")));
6554 CXXRecordDecl
*ImportedX
= Import(FromX
, Lang_CXX03
);
6556 // If we did not save the errors for the "to" context then the below checks
6557 // would fail, because the lookup finds the fwd Decl of the existing
6558 // definition in the "to" context. We can reach the existing definition via
6559 // the found fwd Decl. That existing definition is structurally equivalent
6560 // (we check only the fields) with this one we want to import, so we return
6561 // with the existing definition, which is erroneous (one method is missing).
6563 // The import should fail.
6564 EXPECT_FALSE(ImportedX
);
6565 ASTImporter
*Importer
= findFromTU(FromX
)->Importer
.get();
6566 std::optional
<ASTImportError
> OptErr
=
6567 Importer
->getImportDeclErrorIfAny(FromX
);
6568 // And an error is set for this new X in the "from" ctx.
6569 ASSERT_TRUE(OptErr
);
6570 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6574 TEST_P(ErrorHandlingTest
, ImportOfOverriddenMethods
) {
6576 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A"))));
6578 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B"))));
6580 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C"))));
6582 // Provoke import of a method that has overridden methods with import error.
6583 TranslationUnitDecl
*FromTU
= getTuDecl(std::string(R
"(
6590 )") + ErroneousStmt
+ R
"(
6592 struct B : public A {
6593 void foo() override;
6595 struct C : public B {
6596 void foo() override;
6600 auto *FromFooA
= FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, MatchFooA
);
6601 auto *FromFooB
= FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, MatchFooB
);
6602 auto *FromFooC
= FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, MatchFooC
);
6604 EXPECT_FALSE(Import(FromFooA
, Lang_CXX11
));
6605 ASTImporter
*Importer
= findFromTU(FromFooA
)->Importer
.get();
6606 auto CheckError
= [&Importer
](Decl
*FromD
) {
6607 std::optional
<ASTImportError
> OptErr
=
6608 Importer
->getImportDeclErrorIfAny(FromD
);
6609 ASSERT_TRUE(OptErr
);
6610 EXPECT_EQ(OptErr
->Error
, ASTImportError::UnsupportedConstruct
);
6612 CheckError(FromFooA
);
6613 EXPECT_FALSE(Import(FromFooB
, Lang_CXX11
));
6614 CheckError(FromFooB
);
6615 EXPECT_FALSE(Import(FromFooC
, Lang_CXX11
));
6616 CheckError(FromFooC
);
6619 TEST_P(ErrorHandlingTest
, ODRViolationWithinParmVarDecls
) {
6620 // Importing of 'f' and parameter 'P' should cause an ODR error.
6621 // The error happens after the ParmVarDecl for 'P' was already created.
6622 // This is a special case because the ParmVarDecl has a temporary DeclContext.
6623 // Expected is no crash at error handling of ASTImporter.
6624 constexpr auto ToTUCode
= R
"(
6629 constexpr auto FromTUCode
= R
"(
6633 void f(int P = X::Z);
6635 Decl
*ToTU
= getToTuDecl(ToTUCode
, Lang_CXX11
);
6636 static_cast<void>(ToTU
);
6637 Decl
*FromTU
= getTuDecl(FromTUCode
, Lang_CXX11
);
6638 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
6639 FromTU
, functionDecl(hasName("f")));
6642 auto *ImportedF
= Import(FromF
, Lang_CXX11
);
6643 EXPECT_FALSE(ImportedF
);
6646 TEST_P(ErrorHandlingTest
, DoNotInheritErrorFromNonDependentChild
) {
6647 // Declarations should not inherit an import error from a child object
6648 // if the declaration has no direct dependence to such a child.
6649 // For example a namespace should not get import error if one of the
6650 // declarations inside it fails to import.
6651 // There was a special case in error handling (when "import path circles" are
6652 // encountered) when this property was not held. This case is provoked by the
6654 constexpr auto ToTUCode
= R
"(
6661 constexpr auto FromTUCode
= R
"(
6664 using U = struct Err;
6668 struct Err {}; // ODR violation
6673 Decl
*ToTU
= getToTuDecl(ToTUCode
, Lang_CXX11
);
6674 static_cast<void>(ToTU
);
6675 Decl
*FromTU
= getTuDecl(FromTUCode
, Lang_CXX11
);
6676 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6677 FromTU
, cxxRecordDecl(hasName("A"), hasDefinition()));
6679 auto *ImportedA
= Import(FromA
, Lang_CXX11
);
6680 // 'A' can not be imported: ODR error at 'Err'
6681 EXPECT_FALSE(ImportedA
);
6682 // When import of 'A' failed there was a "saved import path circle" that
6683 // contained namespace 'ns' (A - U - Err - ns - f - A). This should not mean
6684 // that every object in this path fails to import.
6686 Decl
*FromNS
= FirstDeclMatcher
<NamespaceDecl
>().match(
6687 FromTU
, namespaceDecl(hasName("ns")));
6688 EXPECT_TRUE(FromNS
);
6689 auto *ImportedNS
= Import(FromNS
, Lang_CXX11
);
6690 EXPECT_TRUE(ImportedNS
);
6693 TEST_P(ASTImporterOptionSpecificTestBase
, LambdaInFunctionBody
) {
6694 Decl
*FromTU
= getTuDecl(
6700 Lang_CXX11
, "input0.cc");
6701 auto Pattern
= lambdaExpr();
6702 CXXRecordDecl
*FromL
=
6703 FirstDeclMatcher
<LambdaExpr
>().match(FromTU
, Pattern
)->getLambdaClass();
6705 auto ToL
= Import(FromL
, Lang_CXX11
);
6706 unsigned ToLSize
= std::distance(ToL
->decls().begin(), ToL
->decls().end());
6707 unsigned FromLSize
=
6708 std::distance(FromL
->decls().begin(), FromL
->decls().end());
6709 EXPECT_NE(ToLSize
, 0u);
6710 EXPECT_EQ(ToLSize
, FromLSize
);
6711 EXPECT_FALSE(FromL
->isDependentLambda());
6714 TEST_P(ASTImporterOptionSpecificTestBase
,
6715 ReturnTypeDeclaredInsideOfCXX11LambdaWithoutTrailingReturn
) {
6717 std::tie(From
, To
) = getImportedDecl(
6726 Lang_CXX11
, "", Lang_CXX11
, "foo"); // c++11 only
6727 auto *ToLambda
= FirstDeclMatcher
<LambdaExpr
>().match(To
, lambdaExpr());
6728 EXPECT_TRUE(ToLambda
);
6731 TEST_P(ASTImporterOptionSpecificTestBase
,
6732 ReturnTypeDeclaredInsideOfCXX11LambdaWithTrailingReturn
) {
6734 std::tie(From
, To
) = getImportedDecl(
6743 Lang_CXX11
, "", Lang_CXX11
, "foo"); // c++11 only
6744 auto *ToLambda
= FirstDeclMatcher
<LambdaExpr
>().match(To
, lambdaExpr());
6745 EXPECT_TRUE(ToLambda
);
6748 TEST_P(ASTImporterOptionSpecificTestBase
, LambdaInFunctionParam
) {
6749 Decl
*FromTU
= getTuDecl(
6751 template <typename F>
6752 void f(F L = [](){}) {}
6754 Lang_CXX11
, "input0.cc");
6755 auto Pattern
= lambdaExpr();
6756 CXXRecordDecl
*FromL
=
6757 FirstDeclMatcher
<LambdaExpr
>().match(FromTU
, Pattern
)->getLambdaClass();
6759 auto ToL
= Import(FromL
, Lang_CXX11
);
6760 unsigned ToLSize
= std::distance(ToL
->decls().begin(), ToL
->decls().end());
6761 unsigned FromLSize
=
6762 std::distance(FromL
->decls().begin(), FromL
->decls().end());
6763 EXPECT_NE(ToLSize
, 0u);
6764 EXPECT_EQ(ToLSize
, FromLSize
);
6765 EXPECT_TRUE(FromL
->isDependentLambda());
6768 TEST_P(ASTImporterOptionSpecificTestBase
, LambdaInGlobalScope
) {
6769 Decl
*FromTU
= getTuDecl(
6771 auto l1 = [](unsigned lp) { return 1; };
6772 auto l2 = [](int lp) { return 2; };
6774 return l1(p) + l2(p);
6777 Lang_CXX11
, "input0.cc");
6778 FunctionDecl
*FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
6779 FromTU
, functionDecl(hasName("f")));
6780 FunctionDecl
*ToF
= Import(FromF
, Lang_CXX11
);
6784 TEST_P(ASTImporterOptionSpecificTestBase
,
6785 ImportExistingFriendClassTemplateDef
) {
6788 template <class T1, class T2>
6790 template <class U1, class U2>
6791 friend struct Class;
6793 template <class T1, class T2>
6797 TranslationUnitDecl
*ToTU
= getToTuDecl(Code
, Lang_CXX03
);
6798 TranslationUnitDecl
*FromTU
= getTuDecl(Code
, Lang_CXX03
, "input.cc");
6800 auto *ToClassProto
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
6801 ToTU
, classTemplateDecl(hasName("Class")));
6802 auto *ToClassDef
= LastDeclMatcher
<ClassTemplateDecl
>().match(
6803 ToTU
, classTemplateDecl(hasName("Class")));
6804 ASSERT_FALSE(ToClassProto
->isThisDeclarationADefinition());
6805 ASSERT_TRUE(ToClassDef
->isThisDeclarationADefinition());
6806 // Previous friend decl is not linked to it!
6807 ASSERT_FALSE(ToClassDef
->getPreviousDecl());
6808 ASSERT_EQ(ToClassDef
->getMostRecentDecl(), ToClassDef
);
6809 ASSERT_EQ(ToClassProto
->getMostRecentDecl(), ToClassProto
);
6811 auto *FromClassProto
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
6812 FromTU
, classTemplateDecl(hasName("Class")));
6813 auto *FromClassDef
= LastDeclMatcher
<ClassTemplateDecl
>().match(
6814 FromTU
, classTemplateDecl(hasName("Class")));
6815 ASSERT_FALSE(FromClassProto
->isThisDeclarationADefinition());
6816 ASSERT_TRUE(FromClassDef
->isThisDeclarationADefinition());
6817 ASSERT_FALSE(FromClassDef
->getPreviousDecl());
6818 ASSERT_EQ(FromClassDef
->getMostRecentDecl(), FromClassDef
);
6819 ASSERT_EQ(FromClassProto
->getMostRecentDecl(), FromClassProto
);
6821 auto *ImportedDef
= Import(FromClassDef
, Lang_CXX03
);
6822 // At import we should find the definition for 'Class' even if the
6823 // prototype (inside 'friend') for it comes first in the AST and is not
6824 // linked to the definition.
6825 EXPECT_EQ(ImportedDef
, ToClassDef
);
6828 struct LLDBLookupTest
: ASTImporterOptionSpecificTestBase
{
6830 Creator
= [](ASTContext
&ToContext
, FileManager
&ToFileManager
,
6831 ASTContext
&FromContext
, FileManager
&FromFileManager
,
6833 const std::shared_ptr
<ASTImporterSharedState
> &SharedState
) {
6834 return new ASTImporter(ToContext
, ToFileManager
, FromContext
,
6835 FromFileManager
, MinimalImport
,
6836 // We use the regular lookup.
6837 /*SharedState=*/nullptr);
6842 TEST_P(LLDBLookupTest
, ImporterShouldFindInTransparentContext
) {
6843 TranslationUnitDecl
*ToTU
= getToTuDecl(
6850 auto *ToX
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6851 ToTU
, cxxRecordDecl(hasName("X")));
6853 // Set up a stub external storage.
6854 ToTU
->setHasExternalLexicalStorage(true);
6855 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true.
6856 ToTU
->setMustBuildLookupTable();
6857 struct TestExternalASTSource
: ExternalASTSource
{};
6858 ToTU
->getASTContext().setExternalSource(new TestExternalASTSource());
6860 Decl
*FromTU
= getTuDecl(
6865 auto *FromX
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6866 FromTU
, cxxRecordDecl(hasName("X")));
6867 auto *ImportedX
= Import(FromX
, Lang_CXX03
);
6868 // The lookup must find the existing class definition in the LinkageSpecDecl.
6869 // Then the importer renders the existing and the new decl into one chain.
6870 EXPECT_EQ(ImportedX
->getCanonicalDecl(), ToX
->getCanonicalDecl());
6873 struct SVEBuiltins
: ASTImporterOptionSpecificTestBase
{};
6875 TEST_P(SVEBuiltins
, ImportTypes
) {
6876 static const char *const TypeNames
[] = {
6877 "__SVInt8_t", "__SVInt16_t", "__SVInt32_t", "__SVInt64_t",
6878 "__SVUint8_t", "__SVUint16_t", "__SVUint32_t", "__SVUint64_t",
6879 "__SVFloat16_t", "__SVBfloat16_t", "__SVFloat32_t", "__SVFloat64_t",
6882 TranslationUnitDecl
*ToTU
= getToTuDecl("", Lang_CXX03
);
6883 TranslationUnitDecl
*FromTU
= getTuDecl("", Lang_CXX03
, "input.cc");
6884 for (auto *TypeName
: TypeNames
) {
6885 auto *ToTypedef
= FirstDeclMatcher
<TypedefDecl
>().match(
6886 ToTU
, typedefDecl(hasName(TypeName
)));
6887 QualType ToType
= ToTypedef
->getUnderlyingType();
6889 auto *FromTypedef
= FirstDeclMatcher
<TypedefDecl
>().match(
6890 FromTU
, typedefDecl(hasName(TypeName
)));
6891 QualType FromType
= FromTypedef
->getUnderlyingType();
6893 QualType ImportedType
= ImportType(FromType
, FromTypedef
, Lang_CXX03
);
6894 EXPECT_EQ(ImportedType
, ToType
);
6898 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfDefaultImplicitFunctions
) {
6899 // Test that import of implicit functions works and the functions
6900 // are merged into one chain.
6901 auto GetDeclToImport
= [this](StringRef File
) {
6902 Decl
*FromTU
= getTuDecl(
6905 // Force generating some implicit operator definitions for X.
6906 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; }
6909 auto *FromD
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6910 FromTU
, cxxRecordDecl(hasName("X"), unless(isImplicit())));
6911 // Destructor is picked as one example of implicit function.
6912 return FromD
->getDestructor();
6915 auto *ToD1
= Import(GetDeclToImport("input1.cc"), Lang_CXX11
);
6918 auto *ToD2
= Import(GetDeclToImport("input2.cc"), Lang_CXX11
);
6921 EXPECT_EQ(ToD1
->getCanonicalDecl(), ToD2
->getCanonicalDecl());
6924 TEST_P(ASTImporterOptionSpecificTestBase
,
6925 ImportOfExplicitlyDefaultedOrDeleted
) {
6926 Decl
*FromTU
= getTuDecl(
6928 struct X { X() = default; X(const X&) = delete; };
6931 auto *FromX
= FirstDeclMatcher
<CXXRecordDecl
>().match(
6932 FromTU
, cxxRecordDecl(hasName("X")));
6933 auto *ImportedX
= Import(FromX
, Lang_CXX11
);
6934 auto *Constr1
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
6935 ImportedX
, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6936 auto *Constr2
= LastDeclMatcher
<CXXConstructorDecl
>().match(
6937 ImportedX
, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6939 ASSERT_TRUE(ImportedX
);
6940 EXPECT_TRUE(Constr1
->isDefaulted());
6941 EXPECT_TRUE(Constr1
->isExplicitlyDefaulted());
6942 EXPECT_TRUE(Constr2
->isDeletedAsWritten());
6943 EXPECT_EQ(ImportedX
->isAggregate(), FromX
->isAggregate());
6946 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, SVEBuiltins
,
6947 ::testing::Values(std::vector
<std::string
>{
6948 "-target", "aarch64-linux-gnu"}));
6950 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, DeclContextTest
,
6951 ::testing::Values(std::vector
<std::string
>()));
6953 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, CanonicalRedeclChain
,
6954 ::testing::Values(std::vector
<std::string
>()));
6956 TEST_P(ASTImporterOptionSpecificTestBase
, LambdasAreDifferentiated
) {
6957 Decl
*FromTU
= getTuDecl(
6964 Lang_CXX11
, "input0.cc");
6965 auto Pattern
= lambdaExpr();
6966 CXXRecordDecl
*FromL0
=
6967 FirstDeclMatcher
<LambdaExpr
>().match(FromTU
, Pattern
)->getLambdaClass();
6968 CXXRecordDecl
*FromL1
=
6969 LastDeclMatcher
<LambdaExpr
>().match(FromTU
, Pattern
)->getLambdaClass();
6970 ASSERT_NE(FromL0
, FromL1
);
6972 CXXRecordDecl
*ToL0
= Import(FromL0
, Lang_CXX11
);
6973 CXXRecordDecl
*ToL1
= Import(FromL1
, Lang_CXX11
);
6974 EXPECT_NE(ToL0
, ToL1
);
6977 TEST_P(ASTImporterOptionSpecificTestBase
,
6978 LambdasInFunctionParamsAreDifferentiated
) {
6979 Decl
*FromTU
= getTuDecl(
6981 template <typename F0, typename F1>
6982 void f(F0 L0 = [](){}, F1 L1 = [](){}) {}
6984 Lang_CXX11
, "input0.cc");
6985 auto Pattern
= cxxRecordDecl(isLambda());
6986 CXXRecordDecl
*FromL0
=
6987 FirstDeclMatcher
<CXXRecordDecl
>().match(FromTU
, Pattern
);
6988 CXXRecordDecl
*FromL1
=
6989 LastDeclMatcher
<CXXRecordDecl
>().match(FromTU
, Pattern
);
6990 ASSERT_NE(FromL0
, FromL1
);
6992 CXXRecordDecl
*ToL0
= Import(FromL0
, Lang_CXX11
);
6993 CXXRecordDecl
*ToL1
= Import(FromL1
, Lang_CXX11
);
6994 ASSERT_NE(ToL0
, ToL1
);
6997 TEST_P(ASTImporterOptionSpecificTestBase
,
6998 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed
) {
6999 Decl
*FromTU
= getTuDecl(
7001 #define LAMBDA [](){}
7002 template <typename F0, typename F1>
7003 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {}
7005 Lang_CXX11
, "input0.cc");
7006 auto Pattern
= cxxRecordDecl(isLambda());
7007 CXXRecordDecl
*FromL0
=
7008 FirstDeclMatcher
<CXXRecordDecl
>().match(FromTU
, Pattern
);
7009 CXXRecordDecl
*FromL1
=
7010 LastDeclMatcher
<CXXRecordDecl
>().match(FromTU
, Pattern
);
7011 ASSERT_NE(FromL0
, FromL1
);
7013 Import(FromL0
, Lang_CXX11
);
7014 Import(FromL1
, Lang_CXX11
);
7015 CXXRecordDecl
*ToL0
= Import(FromL0
, Lang_CXX11
);
7016 CXXRecordDecl
*ToL1
= Import(FromL1
, Lang_CXX11
);
7017 ASSERT_NE(ToL0
, ToL1
);
7020 TEST_P(ASTImporterOptionSpecificTestBase
, ImportAssignedLambda
) {
7021 Decl
*FromTU
= getTuDecl(
7024 auto x = []{} = {}; auto x2 = x;
7027 Lang_CXX20
, "input0.cc");
7028 auto FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
7029 FromTU
, functionDecl(hasName("f")));
7030 // We have only one lambda class.
7032 DeclCounter
<CXXRecordDecl
>().match(FromTU
, cxxRecordDecl(isLambda())),
7035 FunctionDecl
*ToF
= Import(FromF
, Lang_CXX20
);
7037 TranslationUnitDecl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
7038 // We have only one lambda class after the import.
7039 EXPECT_EQ(DeclCounter
<CXXRecordDecl
>().match(ToTU
, cxxRecordDecl(isLambda())),
7043 TEST_P(ASTImporterOptionSpecificTestBase
, ImportDefaultConstructibleLambdas
) {
7044 Decl
*FromTU
= getTuDecl(
7048 auto xb = []{} = {};
7051 Lang_CXX20
, "input0.cc");
7052 auto FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
7053 FromTU
, functionDecl(hasName("f")));
7054 // We have two lambda classes.
7056 DeclCounter
<CXXRecordDecl
>().match(FromTU
, cxxRecordDecl(isLambda())),
7059 FunctionDecl
*ToF
= Import(FromF
, Lang_CXX20
);
7061 TranslationUnitDecl
*ToTU
= ToAST
->getASTContext().getTranslationUnitDecl();
7062 // We have two lambda classes after the import.
7063 EXPECT_EQ(DeclCounter
<CXXRecordDecl
>().match(ToTU
, cxxRecordDecl(isLambda())),
7067 TEST_P(ASTImporterOptionSpecificTestBase
,
7068 ImportFunctionDeclWithTypeSourceInfoWithSourceDecl
) {
7069 // This code results in a lambda with implicit constructor.
7070 // The constructor's TypeSourceInfo points out the function prototype.
7071 // This prototype has an EST_Unevaluated in its exception information and a
7072 // SourceDecl that is the function declaration itself.
7073 // The test verifies that AST import of such AST does not crash.
7074 // (Here the function's TypeSourceInfo references the function itself.)
7075 Decl
*FromTU
= getTuDecl(
7077 template<typename T> void f(T) { auto X = [](){}; }
7080 Lang_CXX11
, "input0.cc");
7082 // Use LastDeclMatcher to find the LambdaExpr in the template specialization.
7083 CXXRecordDecl
*FromL
= LastDeclMatcher
<LambdaExpr
>()
7084 .match(FromTU
, lambdaExpr())
7087 CXXConstructorDecl
*FromCtor
= *FromL
->ctor_begin();
7088 ASSERT_TRUE(FromCtor
->isCopyConstructor());
7089 ASSERT_TRUE(FromCtor
->getTypeSourceInfo());
7090 const auto *FromFPT
= FromCtor
->getType()->getAs
<FunctionProtoType
>();
7091 ASSERT_TRUE(FromFPT
);
7092 EXPECT_EQ(FromCtor
->getTypeSourceInfo()->getType().getTypePtr(), FromFPT
);
7093 FunctionProtoType::ExtProtoInfo FromEPI
= FromFPT
->getExtProtoInfo();
7094 // If type is EST_Unevaluated, SourceDecl should be set to the parent Decl.
7095 EXPECT_EQ(FromEPI
.ExceptionSpec
.Type
, EST_Unevaluated
);
7096 EXPECT_EQ(FromEPI
.ExceptionSpec
.SourceDecl
, FromCtor
);
7098 auto ToL
= Import(FromL
, Lang_CXX11
);
7100 // Check if the import was correct.
7101 CXXConstructorDecl
*ToCtor
= *ToL
->ctor_begin();
7102 EXPECT_TRUE(ToCtor
->getTypeSourceInfo());
7103 const auto *ToFPT
= ToCtor
->getType()->getAs
<FunctionProtoType
>();
7105 EXPECT_EQ(ToCtor
->getTypeSourceInfo()->getType().getTypePtr(), ToFPT
);
7106 FunctionProtoType::ExtProtoInfo ToEPI
= ToFPT
->getExtProtoInfo();
7107 EXPECT_EQ(ToEPI
.ExceptionSpec
.Type
, EST_Unevaluated
);
7108 EXPECT_EQ(ToEPI
.ExceptionSpec
.SourceDecl
, ToCtor
);
7111 struct ImportAutoFunctions
: ASTImporterOptionSpecificTestBase
{
7112 void testImport(llvm::StringRef Code
, clang::TestLanguage Lang
= Lang_CXX14
,
7113 bool FindLast
= false) {
7114 Decl
*FromTU
= getTuDecl(Code
, Lang
, "input0.cc");
7115 FunctionDecl
*From
= FindLast
? LastDeclMatcher
<FunctionDecl
>().match(
7116 FromTU
, functionDecl(hasName("foo")))
7117 : FirstDeclMatcher
<FunctionDecl
>().match(
7118 FromTU
, functionDecl(hasName("foo")));
7120 FunctionDecl
*To
= Import(From
, Lang
);
7122 // We check here only that the type is auto type.
7123 // These tests are to verify that no crash happens.
7124 // The crash possibility is the presence of a reference to a declaration
7125 // in the function's body from the return type, if the function has auto
7127 EXPECT_TRUE(isa
<AutoType
>(To
->getReturnType()));
7131 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate1
) {
7135 C f1() { return C(); }
7143 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate2
) {
7147 int f1(T t) { return 1; }
7155 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate3
) {
7158 template<class A> struct S1 {};
7159 template<class A> struct S2 {};
7161 S1<C> f1() { return S1<C>(); }
7164 return f1<S2<B *>>();
7169 TEST_P(ImportAutoFunctions
, ReturnWithFunctionTemplate4
) {
7172 template<class... A> struct S1 {};
7173 template<class... A> struct S2 {};
7174 template<class... C>
7175 S1<C...> f1() { return S1<C...>(); }
7178 return f1<S2<int, B *>, bool>();
7183 TEST_P(ImportAutoFunctions
, ReturnWithVarTemplate1
) {
7186 template<class T> T X;
7194 TEST_P(ImportAutoFunctions
, ReturnWithVarTemplate2
) {
7197 template<class A> struct S1 {};
7198 template<class T> S1<T> X;
7206 TEST_P(ImportAutoFunctions
, ReturnWithVarTemplate3
) {
7209 template<class... A> struct S1 {};
7210 template<class... T> S1<T...> X;
7213 return X<bool, S1<A, int>>;
7218 TEST_P(ImportAutoFunctions
, ReturnWithAutoUnresolvedArg
) {
7228 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithTemplateTemplateArg
) {
7229 // FIXME: Is it possible to have the template arg inside the function?
7232 template<int> struct Tmpl {};
7233 template<template<int> class> struct TmplTmpl {};
7235 return TmplTmpl<Tmpl>();
7240 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithDeclarationTemplateArg
) {
7241 // FIXME: Is it possible to have the template arg inside the function?
7244 template<const int *> struct Tmpl {};
7252 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithNullPtrTemplateArg
) {
7255 template<int *> struct Tmpl {};
7257 constexpr int* A = nullptr;
7263 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithIntegralTemplateArg
) {
7266 template<int> struct Tmpl {};
7269 constexpr Int A = 7;
7275 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithDecltypeTypeDeclaredInside
) {
7278 template<class> struct Tmpl {};
7282 return Tmpl<decltype(x)>();
7287 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithUsingTypeDeclaredInside
) {
7290 template<class> struct Tmpl {};
7291 namespace A { struct X {}; }
7299 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithArrayTypeDeclaredInside
) {
7302 template<class> struct Tmpl {};
7305 return Tmpl<X[10]>();
7310 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithArraySizeExprDeclaredInside
) {
7313 template<class> struct Tmpl {};
7315 constexpr int S = 10;
7316 return Tmpl<int[S]>();
7321 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithPackArgDeclaredInside
) {
7324 template<class ...> struct Tmpl {};
7327 return Tmpl<int, X>();
7332 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithIntegerArgDeclaredInside
) {
7335 template<int> struct Tmpl {};
7337 constexpr int X = 1;
7343 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithPtrToStructDeclaredInside
) {
7346 template<class> struct Tmpl {};
7354 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithRefToStructDeclaredInside
) {
7357 template<class> struct Tmpl {};
7366 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithStructDeclaredInside1
) {
7369 template<class> struct Tmpl {};
7377 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithStructDeclaredInside2
) {
7380 template<class> struct Tmpl {};
7383 return Tmpl<Tmpl<X>>();
7388 TEST_P(ImportAutoFunctions
, ReturnWithTemplateWithTypedefDeclaredInside
) {
7391 template<class> struct Tmpl {};
7395 return Tmpl<x_type>();
7400 TEST_P(ImportAutoFunctions
, ReturnWithTypedefDeclaredInside
) {
7401 Decl
*FromTU
= getTuDecl(
7403 auto X = [](long l) {
7404 using int_type = long;
7406 return static_cast<int_type>(dur);
7409 Lang_CXX14
, "input0.cc");
7410 CXXMethodDecl
*From
=
7411 FirstDeclMatcher
<CXXMethodDecl
>().match(FromTU
, cxxMethodDecl());
7413 // Explicitly set the return type of the lambda's operator() to the TypeAlias.
7414 // Normally the return type would be the built-in 'long' type. However, there
7415 // are cases when Clang does not use the canonical type and the TypeAlias is
7416 // used. I could not create such an AST from regular source code, it requires
7417 // some special state in the preprocessor. I've found such an AST when Clang
7418 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce
7419 // that with creduce, because after preprocessing, the AST no longer
7420 // contained the TypeAlias as a return type of the lambda.
7421 ASTContext
&Ctx
= From
->getASTContext();
7422 TypeAliasDecl
*FromTA
=
7423 FirstDeclMatcher
<TypeAliasDecl
>().match(FromTU
, typeAliasDecl());
7424 QualType TT
= Ctx
.getTypedefType(FromTA
);
7425 const FunctionProtoType
*FPT
= cast
<FunctionProtoType
>(From
->getType());
7426 QualType NewFunType
=
7427 Ctx
.getFunctionType(TT
, FPT
->getParamTypes(), FPT
->getExtProtoInfo());
7428 From
->setType(NewFunType
);
7430 CXXMethodDecl
*To
= Import(From
, Lang_CXX14
);
7432 EXPECT_TRUE(isa
<TypedefType
>(To
->getReturnType()));
7435 TEST_P(ImportAutoFunctions
, ReturnWithStructDeclaredInside
) {
7445 TEST_P(ImportAutoFunctions
, ReturnWithStructDeclaredInside2
) {
7446 Decl
*FromTU
= getTuDecl(
7453 Lang_CXX14
, "input0.cc");
7454 FunctionDecl
*From
=
7455 FirstDeclMatcher
<FunctionDecl
>().match(FromTU
, functionDecl());
7457 // This time import the type directly.
7458 QualType ToT
= ImportType(From
->getType(), From
, Lang_CXX14
);
7459 const FunctionProtoType
*FPT
= cast
<FunctionProtoType
>(ToT
);
7460 EXPECT_TRUE(isa
<AutoType
>(FPT
->getReturnType()));
7463 TEST_P(ImportAutoFunctions
, ReturnWithStructDeclaredInside3
) {
7464 Decl
*FromTU
= getTuDecl(
7467 constexpr auto foo();
7469 constexpr auto S::foo() {
7474 Lang_CXX14
, "input0.cc");
7475 FunctionDecl
*From
= FirstDeclMatcher
<FunctionDecl
>().match(
7476 FromTU
, functionDecl(hasName("foo"), unless(hasBody(stmt()))));
7477 ASSERT_FALSE(From
->isThisDeclarationADefinition());
7479 FunctionDecl
*To
= Import(From
, Lang_CXX17
);
7481 EXPECT_TRUE(isa
<AutoType
>(To
->getReturnType()));
7482 EXPECT_FALSE(To
->isThisDeclarationADefinition());
7485 TEST_P(ImportAutoFunctions
, ReturnWithTypedefToStructDeclaredInside
) {
7496 TEST_P(ImportAutoFunctions
, ReturnWithStructDeclaredNestedInside
) {
7500 struct X { struct Y{}; };
7506 TEST_P(ImportAutoFunctions
, ReturnWithInternalLambdaType
) {
7520 TEST_P(ImportAutoFunctions
, ReturnWithTypeInIf
) {
7524 if (struct X {} x; true)
7533 TEST_P(ImportAutoFunctions
, ReturnWithTypeInFor
) {
7537 for (struct X {} x;;)
7544 TEST_P(ImportAutoFunctions
, ReturnWithTypeInSwitch
) {
7548 switch (struct X {} x; 10) {
7557 TEST_P(ImportAutoFunctions
, ReturnWithAutoTemplateType
) {
7566 auto a = foo<int>();
7568 Lang_CXX14
, /*FindLast=*/true);
7571 TEST_P(ImportAutoFunctions
, ReturnWithSubstNonTypeTemplateParmExpr
) {
7578 auto foo() { return array<N>(); }
7580 void bar() { foo<0>(); }
7582 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX17
);
7584 auto *FromBar
= FirstDeclMatcher
<FunctionDecl
>().match(
7585 FromTU
, functionDecl(hasName("bar")));
7587 auto *ToBar
= Import(FromBar
, Lang_CXX17
);
7591 TEST_P(ImportAutoFunctions
, ReturnWithUnaryTransformType
) {
7596 template<typename T>
7597 auto foo(T v) { return static_cast<__underlying_type(T)>(v); }
7599 bool bar() { return foo(E1); }
7601 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX17
);
7603 auto *FromBar
= FirstDeclMatcher
<FunctionDecl
>().match(
7604 FromTU
, functionDecl(hasName("bar")));
7606 auto *ToBar
= Import(FromBar
, Lang_CXX17
);
7610 struct ImportSourceLocations
: ASTImporterOptionSpecificTestBase
{};
7612 TEST_P(ImportSourceLocations
, PreserveFileIDTreeStructure
) {
7613 // Tests that the FileID tree structure (with the links being the include
7614 // chains) is preserved while importing other files (which need to be
7615 // added to this structure with fake include locations.
7617 SourceLocation Location1
;
7619 auto Pattern
= varDecl(hasName("X"));
7620 Decl
*FromTU
= getTuDecl("int X;", Lang_C99
, "input0.c");
7621 auto *FromD
= FirstDeclMatcher
<VarDecl
>().match(FromTU
, Pattern
);
7623 Location1
= Import(FromD
, Lang_C99
)->getLocation();
7625 SourceLocation Location2
;
7627 auto Pattern
= varDecl(hasName("Y"));
7628 Decl
*FromTU
= getTuDecl("int Y;", Lang_C99
, "input1.c");
7629 auto *FromD
= FirstDeclMatcher
<VarDecl
>().match(FromTU
, Pattern
);
7631 Location2
= Import(FromD
, Lang_C99
)->getLocation();
7634 SourceManager
&ToSM
= ToAST
->getSourceManager();
7635 FileID FileID1
= ToSM
.getFileID(Location1
);
7636 FileID FileID2
= ToSM
.getFileID(Location2
);
7638 // Check that the imported files look like as if they were included from the
7639 // start of the main file.
7640 SourceLocation FileStart
= ToSM
.getLocForStartOfFile(ToSM
.getMainFileID());
7641 EXPECT_NE(FileID1
, ToSM
.getMainFileID());
7642 EXPECT_NE(FileID2
, ToSM
.getMainFileID());
7643 EXPECT_EQ(ToSM
.getIncludeLoc(FileID1
), FileStart
);
7644 EXPECT_EQ(ToSM
.getIncludeLoc(FileID2
), FileStart
);
7646 // Let the SourceManager check the order of the locations. The order should
7647 // be the order in which the declarations are imported.
7648 EXPECT_TRUE(ToSM
.isBeforeInTranslationUnit(Location1
, Location2
));
7649 EXPECT_FALSE(ToSM
.isBeforeInTranslationUnit(Location2
, Location1
));
7652 TEST_P(ImportSourceLocations
, NormalFileBuffer
) {
7653 // Test importing normal file buffers.
7655 std::string Path
= "input0.c";
7656 std::string Source
= "int X;";
7657 TranslationUnitDecl
*FromTU
= getTuDecl(Source
, Lang_C99
, Path
);
7659 SourceLocation ImportedLoc
;
7661 // Import the VarDecl to trigger the importing of the FileID.
7662 auto Pattern
= varDecl(hasName("X"));
7663 VarDecl
*FromD
= FirstDeclMatcher
<VarDecl
>().match(FromTU
, Pattern
);
7664 ImportedLoc
= Import(FromD
, Lang_C99
)->getLocation();
7667 // Make sure the imported buffer has the original contents.
7668 SourceManager
&ToSM
= ToAST
->getSourceManager();
7669 FileID ImportedID
= ToSM
.getFileID(ImportedLoc
);
7671 ToSM
.getBufferOrFake(ImportedID
, SourceLocation()).getBuffer());
7674 TEST_P(ImportSourceLocations
, OverwrittenFileBuffer
) {
7675 // Test importing overwritten file buffers.
7677 std::string Path
= "input0.c";
7678 TranslationUnitDecl
*FromTU
= getTuDecl("int X;", Lang_C99
, Path
);
7680 // Overwrite the file buffer for our input file with new content.
7681 const std::string Contents
= "overwritten contents";
7682 SourceLocation ImportedLoc
;
7684 SourceManager
&FromSM
= FromTU
->getASTContext().getSourceManager();
7685 clang::FileManager
&FM
= FromSM
.getFileManager();
7686 clang::FileEntryRef FE
=
7687 FM
.getVirtualFileRef(Path
, static_cast<off_t
>(Contents
.size()), 0);
7689 llvm::SmallVector
<char, 64> Buffer
;
7690 Buffer
.append(Contents
.begin(), Contents
.end());
7691 auto FileContents
= std::make_unique
<llvm::SmallVectorMemoryBuffer
>(
7692 std::move(Buffer
), Path
, /*RequiresNullTerminator=*/false);
7693 FromSM
.overrideFileContents(FE
, std::move(FileContents
));
7695 // Import the VarDecl to trigger the importing of the FileID.
7696 auto Pattern
= varDecl(hasName("X"));
7697 VarDecl
*FromD
= FirstDeclMatcher
<VarDecl
>().match(FromTU
, Pattern
);
7698 ImportedLoc
= Import(FromD
, Lang_C99
)->getLocation();
7701 // Make sure the imported buffer has the overwritten contents.
7702 SourceManager
&ToSM
= ToAST
->getSourceManager();
7703 FileID ImportedID
= ToSM
.getFileID(ImportedLoc
);
7705 ToSM
.getBufferOrFake(ImportedID
, SourceLocation()).getBuffer());
7708 struct ImportAttributes
: public ASTImporterOptionSpecificTestBase
{
7709 void checkAttrImportCommon(const Attr
*From
, const Attr
*To
,
7712 // Verify that dump does not crash because invalid data.
7713 ToD
->dump(llvm::nulls());
7715 EXPECT_EQ(From
->getParsedKind(), To
->getParsedKind());
7716 EXPECT_EQ(From
->getSyntax(), To
->getSyntax());
7717 if (From
->getAttrName()) {
7718 EXPECT_TRUE(To
->getAttrName());
7719 EXPECT_STREQ(From
->getAttrName()->getNameStart(),
7720 To
->getAttrName()->getNameStart());
7722 EXPECT_FALSE(To
->getAttrName());
7724 if (From
->getScopeName()) {
7725 EXPECT_TRUE(To
->getScopeName());
7726 EXPECT_STREQ(From
->getScopeName()->getNameStart(),
7727 To
->getScopeName()->getNameStart());
7729 EXPECT_FALSE(To
->getScopeName());
7731 EXPECT_EQ(From
->getSpellingListIndex(), To
->getSpellingListIndex());
7732 EXPECT_STREQ(From
->getSpelling(), To
->getSpelling());
7733 EXPECT_EQ(From
->isInherited(), To
->isInherited());
7734 EXPECT_EQ(From
->isImplicit(), To
->isImplicit());
7735 EXPECT_EQ(From
->isPackExpansion(), To
->isPackExpansion());
7736 EXPECT_EQ(From
->isLateParsed(), To
->isLateParsed());
7739 template <class DT
, class AT
>
7740 void importAttr(const char *Code
, AT
*&FromAttr
, AT
*&ToAttr
,
7741 TestLanguage Lang
= Lang_CXX11
) {
7742 static_assert(std::is_base_of
<Attr
, AT
>::value
, "AT should be an Attr");
7743 static_assert(std::is_base_of
<Decl
, DT
>::value
, "DT should be a Decl");
7745 Decl
*FromTU
= getTuDecl(Code
, Lang
, "input.cc");
7747 FirstDeclMatcher
<DT
>().match(FromTU
, namedDecl(hasName("test")));
7750 DT
*ToD
= Import(FromD
, Lang_CXX11
);
7753 FromAttr
= FromD
->template getAttr
<AT
>();
7754 ToAttr
= ToD
->template getAttr
<AT
>();
7755 ASSERT_TRUE(FromAttr
);
7756 EXPECT_TRUE(ToAttr
);
7758 checkAttrImportCommon(FromAttr
, ToAttr
, ToD
);
7761 template <class T
> void checkImported(const T
*From
, const T
*To
) {
7763 EXPECT_NE(From
, To
);
7767 void checkImportVariadicArg(const llvm::iterator_range
<T
**> &From
,
7768 const llvm::iterator_range
<T
**> &To
) {
7769 for (auto FromI
= From
.begin(), ToI
= To
.begin(); FromI
!= From
.end();
7771 ASSERT_NE(ToI
, To
.end());
7772 checkImported(*FromI
, *ToI
);
7778 void ImportAttributes::checkImported
<Decl
>(const Decl
*From
, const Decl
*To
) {
7780 EXPECT_NE(From
, To
);
7781 EXPECT_EQ(To
->getTranslationUnitDecl(),
7782 ToAST
->getASTContext().getTranslationUnitDecl());
7785 TEST_P(ImportAttributes
, ImportAligned
) {
7786 AlignedAttr
*FromAttr
, *ToAttr
;
7787 importAttr
<RecordDecl
>(
7789 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; };
7790 struct alignas(alignof(A)) test {};
7793 checkImported(FromAttr
->getAlignmentExpr(), ToAttr
->getAlignmentExpr());
7795 auto *ToA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
7796 ToAST
->getASTContext().getTranslationUnitDecl(),
7797 cxxRecordDecl(hasName("A"), unless(isImplicit())));
7798 // Ensure that 'struct A' was imported (through reference from attribute of
7803 TEST_P(ImportAttributes
, ImportAlignValue
) {
7804 AlignValueAttr
*FromAttr
, *ToAttr
;
7805 importAttr
<VarDecl
>(
7807 void *test __attribute__((align_value(64)));
7810 checkImported(FromAttr
->getAlignment(), ToAttr
->getAlignment());
7813 TEST_P(ImportAttributes
, ImportFormat
) {
7814 FormatAttr
*FromAttr
, *ToAttr
;
7815 importAttr
<FunctionDecl
>(
7817 int test(const char * fmt, ...)
7818 __attribute__ ((__format__ (__scanf__, 1, 2)));
7822 EXPECT_EQ(FromAttr
->getType()->getName(), ToAttr
->getType()->getName());
7823 EXPECT_EQ(FromAttr
->getFirstArg(), ToAttr
->getFirstArg());
7824 EXPECT_EQ(FromAttr
->getFormatIdx(), ToAttr
->getFormatIdx());
7827 TEST_P(ImportAttributes
, ImportEnableIf
) {
7828 EnableIfAttr
*FromAttr
, *ToAttr
;
7829 importAttr
<FunctionDecl
>(
7830 "void test(int A) __attribute__((enable_if(A == 1, \"message\")));",
7832 checkImported(FromAttr
->getCond(), ToAttr
->getCond());
7833 EXPECT_EQ(FromAttr
->getMessage(), ToAttr
->getMessage());
7836 TEST_P(ImportAttributes
, ImportGuardedVar
) {
7837 GuardedVarAttr
*FromAttr
, *ToAttr
;
7838 importAttr
<VarDecl
>("int test __attribute__((guarded_var));", FromAttr
,
7842 TEST_P(ImportAttributes
, ImportPtGuardedVar
) {
7843 PtGuardedVarAttr
*FromAttr
, *ToAttr
;
7844 importAttr
<VarDecl
>("int *test __attribute__((pt_guarded_var));", FromAttr
,
7848 TEST_P(ImportAttributes
, ImportScopedLockable
) {
7849 ScopedLockableAttr
*FromAttr
, *ToAttr
;
7850 importAttr
<CXXRecordDecl
>("struct __attribute__((scoped_lockable)) test {};",
7854 TEST_P(ImportAttributes
, ImportCapability
) {
7855 CapabilityAttr
*FromAttr
, *ToAttr
;
7856 importAttr
<CXXRecordDecl
>(
7857 "struct __attribute__((capability(\"cap\"))) test {};", FromAttr
, ToAttr
);
7858 EXPECT_EQ(FromAttr
->getName(), ToAttr
->getName());
7861 TEST_P(ImportAttributes
, ImportAssertCapability
) {
7862 AssertCapabilityAttr
*FromAttr
, *ToAttr
;
7863 importAttr
<FunctionDecl
>(
7864 "void test(int A1, int A2) __attribute__((assert_capability(A1, A2)));",
7866 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7869 TEST_P(ImportAttributes
, ImportAcquireCapability
) {
7870 AcquireCapabilityAttr
*FromAttr
, *ToAttr
;
7871 importAttr
<FunctionDecl
>(
7872 "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));",
7874 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7877 TEST_P(ImportAttributes
, ImportTryAcquireCapability
) {
7878 TryAcquireCapabilityAttr
*FromAttr
, *ToAttr
;
7879 importAttr
<FunctionDecl
>(
7880 "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, "
7883 checkImported(FromAttr
->getSuccessValue(), ToAttr
->getSuccessValue());
7884 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7887 TEST_P(ImportAttributes
, ImportReleaseCapability
) {
7888 ReleaseCapabilityAttr
*FromAttr
, *ToAttr
;
7889 importAttr
<FunctionDecl
>(
7890 "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));",
7892 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7895 TEST_P(ImportAttributes
, ImportRequiresCapability
) {
7896 RequiresCapabilityAttr
*FromAttr
, *ToAttr
;
7897 importAttr
<FunctionDecl
>(
7898 "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));",
7900 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7903 TEST_P(ImportAttributes
, ImportNoThreadSafetyAnalysis
) {
7904 NoThreadSafetyAnalysisAttr
*FromAttr
, *ToAttr
;
7905 importAttr
<FunctionDecl
>(
7906 "void test() __attribute__((no_thread_safety_analysis));", FromAttr
,
7910 TEST_P(ImportAttributes
, ImportGuardedBy
) {
7911 GuardedByAttr
*FromAttr
, *ToAttr
;
7912 importAttr
<VarDecl
>(
7915 int test __attribute__((guarded_by(G)));
7918 checkImported(FromAttr
->getArg(), ToAttr
->getArg());
7921 TEST_P(ImportAttributes
, ImportPtGuardedBy
) {
7922 PtGuardedByAttr
*FromAttr
, *ToAttr
;
7923 importAttr
<VarDecl
>(
7926 int *test __attribute__((pt_guarded_by(G)));
7929 checkImported(FromAttr
->getArg(), ToAttr
->getArg());
7932 TEST_P(ImportAttributes
, ImportAcquiredAfter
) {
7933 AcquiredAfterAttr
*FromAttr
, *ToAttr
;
7934 importAttr
<VarDecl
>(
7936 struct __attribute__((lockable)) L {};
7939 L test __attribute__((acquired_after(A1, A2)));
7942 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7945 TEST_P(ImportAttributes
, ImportAcquiredBefore
) {
7946 AcquiredBeforeAttr
*FromAttr
, *ToAttr
;
7947 importAttr
<VarDecl
>(
7949 struct __attribute__((lockable)) L {};
7952 L test __attribute__((acquired_before(A1, A2)));
7955 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7958 TEST_P(ImportAttributes
, ImportAssertExclusiveLock
) {
7959 AssertExclusiveLockAttr
*FromAttr
, *ToAttr
;
7960 importAttr
<FunctionDecl
>("void test(int A1, int A2) "
7961 "__attribute__((assert_exclusive_lock(A1, A2)));",
7963 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7966 TEST_P(ImportAttributes
, ImportAssertSharedLock
) {
7967 AssertSharedLockAttr
*FromAttr
, *ToAttr
;
7968 importAttr
<FunctionDecl
>(
7969 "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));",
7971 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7974 TEST_P(ImportAttributes
, ImportExclusiveTrylockFunction
) {
7975 ExclusiveTrylockFunctionAttr
*FromAttr
, *ToAttr
;
7976 importAttr
<FunctionDecl
>(
7977 "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, "
7980 checkImported(FromAttr
->getSuccessValue(), ToAttr
->getSuccessValue());
7981 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7984 TEST_P(ImportAttributes
, ImportSharedTrylockFunction
) {
7985 SharedTrylockFunctionAttr
*FromAttr
, *ToAttr
;
7986 importAttr
<FunctionDecl
>(
7987 "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, "
7990 checkImported(FromAttr
->getSuccessValue(), ToAttr
->getSuccessValue());
7991 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
7994 TEST_P(ImportAttributes
, ImportLockReturned
) {
7995 LockReturnedAttr
*FromAttr
, *ToAttr
;
7996 importAttr
<FunctionDecl
>(
7997 "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr
,
7999 checkImported(FromAttr
->getArg(), ToAttr
->getArg());
8002 TEST_P(ImportAttributes
, ImportLocksExcluded
) {
8003 LocksExcludedAttr
*FromAttr
, *ToAttr
;
8004 importAttr
<FunctionDecl
>(
8005 "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));",
8007 checkImportVariadicArg(FromAttr
->args(), ToAttr
->args());
8010 TEST_P(ImportAttributes
, ImportC99NoThrowAttr
) {
8011 NoThrowAttr
*FromAttr
, *ToAttr
;
8012 importAttr
<FunctionDecl
>("void test () __attribute__ ((__nothrow__));",
8013 FromAttr
, ToAttr
, Lang_C99
);
8014 checkImported(FromAttr
->getAttrName(), ToAttr
->getAttrName());
8017 template <typename T
>
8018 auto ExtendWithOptions(const T
&Values
, const std::vector
<std::string
> &Args
) {
8020 for (std::vector
<std::string
> &ArgV
: Copy
) {
8021 for (const std::string
&Arg
: Args
) {
8022 ArgV
.push_back(Arg
);
8025 return ::testing::ValuesIn(Copy
);
8028 struct ImportWithExternalSource
: ASTImporterOptionSpecificTestBase
{
8029 ImportWithExternalSource() {
8030 Creator
= [](ASTContext
&ToContext
, FileManager
&ToFileManager
,
8031 ASTContext
&FromContext
, FileManager
&FromFileManager
,
8033 const std::shared_ptr
<ASTImporterSharedState
> &SharedState
) {
8034 return new ASTImporter(ToContext
, ToFileManager
, FromContext
,
8035 // Use minimal import for these tests.
8036 FromFileManager
, /*MinimalImport=*/true,
8037 // We use the regular lookup.
8038 /*SharedState=*/nullptr);
8043 /// An ExternalASTSource that keeps track of the tags is completed.
8044 struct SourceWithCompletedTagList
: clang::ExternalASTSource
{
8045 std::vector
<clang::TagDecl
*> &CompletedTags
;
8046 SourceWithCompletedTagList(std::vector
<clang::TagDecl
*> &CompletedTags
)
8047 : CompletedTags(CompletedTags
) {}
8048 void CompleteType(TagDecl
*Tag
) override
{
8049 auto *Record
= cast
<CXXRecordDecl
>(Tag
);
8050 Record
->startDefinition();
8051 Record
->completeDefinition();
8052 CompletedTags
.push_back(Tag
);
8054 using clang::ExternalASTSource::CompleteType
;
8057 TEST_P(ImportWithExternalSource
, CompleteRecordBeforeImporting
) {
8058 // Create an empty TU.
8059 TranslationUnitDecl
*FromTU
= getTuDecl("", Lang_CXX03
, "input.cpp");
8061 // Create and add the test ExternalASTSource.
8062 std::vector
<clang::TagDecl
*> CompletedTags
;
8063 IntrusiveRefCntPtr
<ExternalASTSource
> source
=
8064 new SourceWithCompletedTagList(CompletedTags
);
8065 clang::ASTContext
&Context
= FromTU
->getASTContext();
8066 Context
.setExternalSource(std::move(source
));
8068 // Create a dummy class by hand with external lexical storage.
8069 IdentifierInfo
&Ident
= Context
.Idents
.get("test_class");
8071 CXXRecordDecl::Create(Context
, TagTypeKind::Class
, FromTU
,
8072 SourceLocation(), SourceLocation(), &Ident
);
8073 Record
->setHasExternalLexicalStorage();
8074 FromTU
->addDecl(Record
);
8076 // Do a minimal import of the created class.
8077 EXPECT_EQ(0U, CompletedTags
.size());
8078 Import(Record
, Lang_CXX03
);
8079 EXPECT_EQ(0U, CompletedTags
.size());
8081 // Import the definition of the created class.
8082 llvm::Error Err
= findFromTU(Record
)->Importer
->ImportDefinition(Record
);
8083 EXPECT_FALSE((bool)Err
);
8084 consumeError(std::move(Err
));
8086 // Make sure the class was completed once.
8087 EXPECT_EQ(1U, CompletedTags
.size());
8088 EXPECT_EQ(Record
, CompletedTags
.front());
8091 TEST_P(ImportFunctions
, CTADImplicit
) {
8092 Decl
*FromTU
= getTuDecl(
8094 template <typename T> struct A {
8099 Lang_CXX17
, "input.cc");
8100 auto *FromD
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8102 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>")))));
8103 auto *ToD
= Import(FromD
, Lang_CXX17
);
8105 EXPECT_EQ(ToD
->getDeductionCandidateKind(), DeductionCandidate::Copy
);
8106 // Check that the deduced class template is also imported.
8107 EXPECT_TRUE(findFromTU(FromD
)->Importer
->GetAlreadyImportedOrNull(
8108 FromD
->getDeducedTemplate()));
8111 TEST_P(ImportFunctions
, CTADUserDefinedExplicit
) {
8112 Decl
*FromTU
= getTuDecl(
8114 template <typename T> struct A {
8117 template <typename T> explicit A(T) -> A<float>;
8118 A a{(int)0}; // calls A<float>::A(float)
8120 Lang_CXX17
, "input.cc");
8121 auto *FromD
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8122 FromTU
, cxxDeductionGuideDecl(unless(isImplicit())));
8123 // Not-implicit: i.e. not compiler-generated, user defined.
8124 ASSERT_FALSE(FromD
->isImplicit());
8125 ASSERT_TRUE(FromD
->isExplicit()); // Has the explicit keyword.
8126 auto *ToD
= Import(FromD
, Lang_CXX17
);
8128 EXPECT_FALSE(FromD
->isImplicit());
8129 EXPECT_TRUE(ToD
->isExplicit());
8132 TEST_P(ImportFunctions
, CTADWithLocalTypedef
) {
8133 Decl
*TU
= getTuDecl(
8135 template <typename T> struct A {
8141 Lang_CXX17
, "input.cc");
8142 auto *FromD
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8143 TU
, cxxDeductionGuideDecl());
8144 auto *ToD
= Import(FromD
, Lang_CXX17
);
8148 TEST_P(ImportFunctions
, ParmVarDeclDeclContext
) {
8149 constexpr auto FromTUCode
= R
"(
8152 Decl
*FromTU
= getTuDecl(FromTUCode
, Lang_CXX11
);
8153 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
8154 FromTU
, functionDecl(hasName("f")));
8157 auto *ImportedF
= Import(FromF
, Lang_CXX11
);
8158 EXPECT_TRUE(ImportedF
);
8159 EXPECT_TRUE(SharedStatePtr
->getLookupTable()->contains(
8160 ImportedF
, ImportedF
->getParamDecl(0)));
8163 // FIXME Move these tests out of ASTImporterTest. For that we need to factor
8164 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase
8165 // into a new test Fixture. Then we should lift up this Fixture to its own
8166 // implementation file and only then could we reuse the Fixture in other AST
8168 struct CTAD
: ASTImporterOptionSpecificTestBase
{};
8170 TEST_P(CTAD
, DeductionGuideShouldReferToANonLocalTypedef
) {
8171 Decl
*TU
= getTuDecl(
8174 template <typename T> struct A {
8177 A a{(int)0, (int)0};
8179 Lang_CXX17
, "input.cc");
8180 auto *Guide
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8181 TU
, cxxDeductionGuideDecl());
8182 auto *Typedef
= FirstDeclMatcher
<TypedefNameDecl
>().match(
8183 TU
, typedefNameDecl(hasName("U")));
8184 ParmVarDecl
*Param
= Guide
->getParamDecl(0);
8185 // The type of the first param (which is a typedef) should match the typedef
8186 // in the global scope.
8187 EXPECT_EQ(Param
->getType()->getAs
<TypedefType
>()->getDecl(), Typedef
);
8190 TEST_P(CTAD
, DeductionGuideShouldReferToANonLocalTypedefInParamPtr
) {
8191 Decl
*TU
= getTuDecl(
8194 template <typename T> struct A {
8197 A a{(int*)0, (int)0};
8199 Lang_CXX17
, "input.cc");
8200 auto *Guide
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8201 TU
, cxxDeductionGuideDecl());
8202 auto *Typedef
= FirstDeclMatcher
<TypedefNameDecl
>().match(
8203 TU
, typedefNameDecl(hasName("U")));
8204 ParmVarDecl
*Param
= Guide
->getParamDecl(0);
8205 EXPECT_EQ(Param
->getType()
8206 ->getAs
<PointerType
>()
8208 ->getAs
<TypedefType
>()
8213 TEST_P(CTAD
, DeductionGuideShouldCopyALocalTypedef
) {
8214 Decl
*TU
= getTuDecl(
8216 template <typename T> struct A {
8220 A a{(int)0, (int)0};
8222 Lang_CXX17
, "input.cc");
8223 auto *Guide
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8224 TU
, cxxDeductionGuideDecl());
8225 auto *Typedef
= FirstDeclMatcher
<TypedefNameDecl
>().match(
8226 TU
, typedefNameDecl(hasName("U")));
8227 ParmVarDecl
*Param
= Guide
->getParamDecl(0);
8228 EXPECT_NE(Param
->getType()->getAs
<TypedefType
>()->getDecl(), Typedef
);
8231 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, CTAD
,
8232 DefaultTestValuesForRunOptions
);
8234 TEST_P(ASTImporterOptionSpecificTestBase
, TypedefWithAttribute
) {
8235 Decl
*TU
= getTuDecl(
8238 typedef int X __attribute__((annotate("A
")));
8241 Lang_CXX17
, "input.cc");
8243 FirstDeclMatcher
<TypedefDecl
>().match(TU
, typedefDecl(hasName("X")));
8244 auto *ToD
= Import(FromD
, Lang_CXX17
);
8246 ASSERT_EQ(ToD
->getAttrs().size(), 1U);
8247 auto *ToAttr
= dyn_cast
<AnnotateAttr
>(ToD
->getAttrs()[0]);
8248 ASSERT_TRUE(ToAttr
);
8249 EXPECT_EQ(ToAttr
->getAnnotation(), "A");
8252 TEST_P(ASTImporterOptionSpecificTestBase
,
8253 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet
) {
8254 Decl
*FromTU
= getTuDecl(
8258 template<typename T>
8259 class basic_stringbuf;
8263 template<typename T = char_traits>
8264 class basic_stringbuf;
8267 template<typename T>
8268 class basic_stringbuf {};
8274 auto *From1
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
8276 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
8277 auto *To1
= cast_or_null
<ClassTemplateDecl
>(Import(From1
, Lang_CXX11
));
8280 auto *From2
= LastDeclMatcher
<ClassTemplateDecl
>().match(
8282 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
8283 auto *To2
= cast_or_null
<ClassTemplateDecl
>(Import(From2
, Lang_CXX11
));
8287 TEST_P(ASTImporterOptionSpecificTestBase
, ImportOfCapturedVLAType
) {
8288 Decl
*FromTU
= getTuDecl(
8290 void declToImport(int N) {
8292 [&VLA] {}; // FieldDecl inside the lambda.
8296 auto *FromFD
= FirstDeclMatcher
<FieldDecl
>().match(FromTU
, fieldDecl());
8297 ASSERT_TRUE(FromFD
);
8298 ASSERT_TRUE(FromFD
->hasCapturedVLAType());
8300 auto *ToFD
= Import(FromFD
, Lang_CXX14
);
8302 EXPECT_TRUE(ToFD
->hasCapturedVLAType());
8303 EXPECT_NE(FromFD
->getCapturedVLAType(), ToFD
->getCapturedVLAType());
8306 TEST_P(ASTImporterOptionSpecificTestBase
, ImportEnumMemberSpecialization
) {
8307 Decl
*FromTU
= getTuDecl(
8309 template <class T> struct A {
8310 enum tagname { enumerator };
8312 template struct A<int>;
8315 auto *FromD
= FirstDeclMatcher
<EnumDecl
>().match(
8316 FromTU
, enumDecl(hasName("tagname"),
8317 hasParent(classTemplateSpecializationDecl())));
8319 ASSERT_TRUE(FromD
->getMemberSpecializationInfo());
8321 auto *ToD
= Import(FromD
, Lang_CXX03
);
8323 EXPECT_TRUE(ToD
->getMemberSpecializationInfo());
8324 EXPECT_EQ(FromD
->getTemplateSpecializationKind(),
8325 ToD
->getTemplateSpecializationKind());
8328 TEST_P(ASTImporterOptionSpecificTestBase
, ImportIsInheritingConstructorBit
) {
8329 Decl
*FromTU
= getTuDecl(
8335 using A::A; // Inherited ctor.
8342 auto *FromD
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8343 FromTU
, cxxConstructorDecl(isInheritingConstructor()));
8345 ASSERT_TRUE(FromD
->isInheritingConstructor());
8347 auto *ToD
= Import(FromD
, Lang_CXX11
);
8349 EXPECT_TRUE(ToD
->isInheritingConstructor());
8352 TEST_P(ASTImporterOptionSpecificTestBase
, ImportConstructorUsingShadow
) {
8353 TranslationUnitDecl
*FromTU
= getTuDecl(
8367 auto CheckAST
= [](TranslationUnitDecl
*TU
, CXXRecordDecl
*RecordC
) {
8368 auto *RecordA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8369 TU
, cxxRecordDecl(hasName("A")));
8370 auto *RecordB
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8371 TU
, cxxRecordDecl(hasName("B")));
8372 auto *ConstrA
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8373 TU
, cxxConstructorDecl(hasParent(equalsNode(RecordA
)),
8374 parameterCountIs(2)));
8375 auto *ShadowBA
= cast
<ConstructorUsingShadowDecl
>(
8376 FirstDeclMatcher
<UsingShadowDecl
>().match(
8377 TU
, usingShadowDecl(hasParent(equalsNode(RecordB
)),
8378 hasTargetDecl(equalsNode(ConstrA
)))));
8379 auto *ShadowCA
= cast
<ConstructorUsingShadowDecl
>(
8380 FirstDeclMatcher
<UsingShadowDecl
>().match(
8381 TU
, usingShadowDecl(hasParent(equalsNode(RecordC
)),
8382 hasTargetDecl(equalsNode(ConstrA
)))));
8383 EXPECT_EQ(ShadowBA
->getTargetDecl(), ConstrA
);
8384 EXPECT_EQ(ShadowBA
->getNominatedBaseClass(), RecordA
);
8385 EXPECT_EQ(ShadowBA
->getConstructedBaseClass(), RecordA
);
8386 EXPECT_EQ(ShadowBA
->getNominatedBaseClassShadowDecl(), nullptr);
8387 EXPECT_EQ(ShadowBA
->getConstructedBaseClassShadowDecl(), nullptr);
8388 EXPECT_FALSE(ShadowBA
->constructsVirtualBase());
8389 EXPECT_EQ(ShadowCA
->getTargetDecl(), ConstrA
);
8390 EXPECT_EQ(ShadowCA
->getNominatedBaseClass(), RecordB
);
8391 EXPECT_EQ(ShadowCA
->getConstructedBaseClass(), RecordB
);
8392 EXPECT_EQ(ShadowCA
->getNominatedBaseClassShadowDecl(), ShadowBA
);
8393 EXPECT_EQ(ShadowCA
->getConstructedBaseClassShadowDecl(), ShadowBA
);
8394 EXPECT_FALSE(ShadowCA
->constructsVirtualBase());
8397 auto *FromC
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8398 FromTU
, cxxRecordDecl(hasName("C")));
8400 auto *ToC
= Import(FromC
, Lang_CXX11
);
8401 TranslationUnitDecl
*ToTU
= ToC
->getTranslationUnitDecl();
8403 CheckAST(FromTU
, FromC
);
8404 CheckAST(ToTU
, ToC
);
8407 TEST_P(ASTImporterOptionSpecificTestBase
,
8408 ImportFunctionDeclBitShouldNotOverwriteCtorDeclBits
) {
8410 std::tie(From
, To
) = getImportedDecl(
8417 A foo() { A a; return a; }
8418 A bar() { return {}; }
8426 A baz() { return {}; }
8431 hasAnyConstructorInitializer(cxxCtorInitializer(isMemberInitializer()));
8433 cxxConstructorDecl(isMoveConstructor(), isImplicit(), HasCtorInit
);
8435 auto *FromImpMoveCtor
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8437 auto *ToImpMoveCtor
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8440 EXPECT_TRUE(FromImpMoveCtor
->getNumCtorInitializers() == 1);
8441 EXPECT_FALSE(FromImpMoveCtor
->FriendConstraintRefersToEnclosingTemplate());
8443 EXPECT_TRUE(ToImpMoveCtor
->getNumCtorInitializers() == 1);
8444 EXPECT_FALSE(ToImpMoveCtor
->FriendConstraintRefersToEnclosingTemplate());
8445 EXPECT_TRUE(*ToImpMoveCtor
->init_begin());
8448 AST_MATCHER_P(UsingShadowDecl
, hasIntroducerDecl
, internal::Matcher
<NamedDecl
>,
8450 return InnerMatcher
.matches(*Node
.getIntroducer(), Finder
, Builder
);
8453 TEST_P(ASTImporterOptionSpecificTestBase
,
8454 ImportConstructorUsingShadowVirtualBase
) {
8455 TranslationUnitDecl
*FromTU
= getTuDecl(
8457 struct A { A(int, int); };
8458 struct B : A { using A::A; };
8460 struct V1 : virtual B { using B::B; };
8461 struct V2 : virtual B { using B::B; };
8463 struct D2 : V1, V2 {
8470 auto CheckAST
= [](TranslationUnitDecl
*TU
, CXXRecordDecl
*RecordD2
) {
8471 auto *RecordA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8472 TU
, cxxRecordDecl(hasName("A")));
8473 auto *RecordB
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8474 TU
, cxxRecordDecl(hasName("B")));
8475 auto *RecordV1
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8476 TU
, cxxRecordDecl(hasName("V1")));
8477 auto *RecordV2
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8478 TU
, cxxRecordDecl(hasName("V2")));
8479 auto *ConstrA
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8480 TU
, cxxConstructorDecl(hasParent(equalsNode(RecordA
)),
8481 parameterCountIs(2)));
8482 auto *ConstrB
= FirstDeclMatcher
<CXXConstructorDecl
>().match(
8483 TU
, cxxConstructorDecl(hasParent(equalsNode(RecordB
)),
8484 isCopyConstructor()));
8485 auto *UsingD2V1
= FirstDeclMatcher
<UsingDecl
>().match(
8486 TU
, usingDecl(hasParent(equalsNode(RecordD2
))));
8487 auto *UsingD2V2
= LastDeclMatcher
<UsingDecl
>().match(
8488 TU
, usingDecl(hasParent(equalsNode(RecordD2
))));
8489 auto *ShadowBA
= cast
<ConstructorUsingShadowDecl
>(
8490 FirstDeclMatcher
<UsingShadowDecl
>().match(
8491 TU
, usingShadowDecl(hasParent(equalsNode(RecordB
)),
8492 hasTargetDecl(equalsNode(ConstrA
)))));
8493 auto *ShadowV1A
= cast
<ConstructorUsingShadowDecl
>(
8494 FirstDeclMatcher
<UsingShadowDecl
>().match(
8495 TU
, usingShadowDecl(hasParent(equalsNode(RecordV1
)),
8496 hasTargetDecl(equalsNode(ConstrA
)))));
8497 auto *ShadowV1B
= cast
<ConstructorUsingShadowDecl
>(
8498 FirstDeclMatcher
<UsingShadowDecl
>().match(
8499 TU
, usingShadowDecl(hasParent(equalsNode(RecordV1
)),
8500 hasTargetDecl(equalsNode(ConstrB
)))));
8501 auto *ShadowV2A
= cast
<ConstructorUsingShadowDecl
>(
8502 FirstDeclMatcher
<UsingShadowDecl
>().match(
8503 TU
, usingShadowDecl(hasParent(equalsNode(RecordV2
)),
8504 hasTargetDecl(equalsNode(ConstrA
)))));
8505 auto *ShadowV2B
= cast
<ConstructorUsingShadowDecl
>(
8506 FirstDeclMatcher
<UsingShadowDecl
>().match(
8507 TU
, usingShadowDecl(hasParent(equalsNode(RecordV2
)),
8508 hasTargetDecl(equalsNode(ConstrB
)))));
8509 auto *ShadowD2V1A
= cast
<ConstructorUsingShadowDecl
>(
8510 FirstDeclMatcher
<UsingShadowDecl
>().match(
8511 TU
, usingShadowDecl(hasParent(equalsNode(RecordD2
)),
8512 hasIntroducerDecl(equalsNode(UsingD2V1
)),
8513 hasTargetDecl(equalsNode(ConstrA
)))));
8514 auto *ShadowD2V1B
= cast
<ConstructorUsingShadowDecl
>(
8515 FirstDeclMatcher
<UsingShadowDecl
>().match(
8516 TU
, usingShadowDecl(hasParent(equalsNode(RecordD2
)),
8517 hasIntroducerDecl(equalsNode(UsingD2V1
)),
8518 hasTargetDecl(equalsNode(ConstrB
)))));
8519 auto *ShadowD2V2A
= cast
<ConstructorUsingShadowDecl
>(
8520 FirstDeclMatcher
<UsingShadowDecl
>().match(
8521 TU
, usingShadowDecl(hasParent(equalsNode(RecordD2
)),
8522 hasIntroducerDecl(equalsNode(UsingD2V2
)),
8523 hasTargetDecl(equalsNode(ConstrA
)))));
8524 auto *ShadowD2V2B
= cast
<ConstructorUsingShadowDecl
>(
8525 FirstDeclMatcher
<UsingShadowDecl
>().match(
8526 TU
, usingShadowDecl(hasParent(equalsNode(RecordD2
)),
8527 hasIntroducerDecl(equalsNode(UsingD2V2
)),
8528 hasTargetDecl(equalsNode(ConstrB
)))));
8530 EXPECT_EQ(ShadowD2V1A
->getTargetDecl(), ConstrA
);
8531 EXPECT_EQ(ShadowD2V1A
->getNominatedBaseClassShadowDecl(), ShadowV1A
);
8532 EXPECT_EQ(ShadowD2V1A
->getNominatedBaseClass(), RecordV1
);
8533 EXPECT_EQ(ShadowD2V1A
->getConstructedBaseClassShadowDecl(), ShadowBA
);
8534 EXPECT_EQ(ShadowD2V1A
->getConstructedBaseClass(), RecordB
);
8535 EXPECT_TRUE(ShadowD2V1A
->constructsVirtualBase());
8536 EXPECT_EQ(ShadowD2V1B
->getTargetDecl(), ConstrB
);
8537 EXPECT_EQ(ShadowD2V1B
->getNominatedBaseClassShadowDecl(), ShadowV1B
);
8538 EXPECT_EQ(ShadowD2V1B
->getNominatedBaseClass(), RecordV1
);
8539 EXPECT_EQ(ShadowD2V1B
->getConstructedBaseClassShadowDecl(), nullptr);
8540 EXPECT_EQ(ShadowD2V1B
->getConstructedBaseClass(), RecordB
);
8541 EXPECT_TRUE(ShadowD2V1B
->constructsVirtualBase());
8542 EXPECT_EQ(ShadowD2V2A
->getTargetDecl(), ConstrA
);
8543 EXPECT_EQ(ShadowD2V2A
->getNominatedBaseClassShadowDecl(), ShadowV2A
);
8544 EXPECT_EQ(ShadowD2V2A
->getNominatedBaseClass(), RecordV2
);
8545 EXPECT_EQ(ShadowD2V2A
->getConstructedBaseClassShadowDecl(), ShadowBA
);
8546 EXPECT_EQ(ShadowD2V2A
->getConstructedBaseClass(), RecordB
);
8547 EXPECT_TRUE(ShadowD2V2A
->constructsVirtualBase());
8548 EXPECT_EQ(ShadowD2V2B
->getTargetDecl(), ConstrB
);
8549 EXPECT_EQ(ShadowD2V2B
->getNominatedBaseClassShadowDecl(), ShadowV2B
);
8550 EXPECT_EQ(ShadowD2V2B
->getNominatedBaseClass(), RecordV2
);
8551 EXPECT_EQ(ShadowD2V2B
->getConstructedBaseClassShadowDecl(), nullptr);
8552 EXPECT_EQ(ShadowD2V2B
->getConstructedBaseClass(), RecordB
);
8553 EXPECT_TRUE(ShadowD2V2B
->constructsVirtualBase());
8555 EXPECT_TRUE(ShadowV1A
->constructsVirtualBase());
8556 EXPECT_TRUE(ShadowV1B
->constructsVirtualBase());
8557 EXPECT_TRUE(ShadowV2A
->constructsVirtualBase());
8558 EXPECT_TRUE(ShadowV2B
->constructsVirtualBase());
8559 EXPECT_FALSE(ShadowBA
->constructsVirtualBase());
8562 auto *FromD2
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8563 FromTU
, cxxRecordDecl(hasName("D2")));
8565 auto *ToD2
= Import(FromD2
, Lang_CXX11
);
8566 TranslationUnitDecl
*ToTU
= ToD2
->getTranslationUnitDecl();
8568 CheckAST(FromTU
, FromD2
);
8569 CheckAST(ToTU
, ToD2
);
8572 TEST_P(ASTImporterOptionSpecificTestBase
, ImportUsingShadowList
) {
8573 TranslationUnitDecl
*FromTU
= getTuDecl(
8585 auto *FromB
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8586 FromTU
, cxxRecordDecl(hasName("B")));
8588 auto *ToB
= Import(FromB
, Lang_CXX11
);
8589 TranslationUnitDecl
*ToTU
= ToB
->getTranslationUnitDecl();
8591 auto *ToUsing
= FirstDeclMatcher
<UsingDecl
>().match(
8592 ToTU
, usingDecl(hasParent(equalsNode(ToB
))));
8593 auto *ToUsingShadowF1
= FirstDeclMatcher
<UsingShadowDecl
>().match(
8594 ToTU
, usingShadowDecl(hasTargetDecl(
8595 functionDecl(hasName("f"), parameterCountIs(0)))));
8596 auto *ToUsingShadowF2
= FirstDeclMatcher
<UsingShadowDecl
>().match(
8597 ToTU
, usingShadowDecl(hasTargetDecl(
8598 functionDecl(hasName("f"), parameterCountIs(1)))));
8600 EXPECT_EQ(ToUsing
->shadow_size(), 2u);
8601 auto ShadowI
= ToUsing
->shadow_begin();
8602 EXPECT_EQ(*ShadowI
, ToUsingShadowF1
);
8604 EXPECT_EQ(*ShadowI
, ToUsingShadowF2
);
8607 AST_MATCHER_P(FunctionTemplateDecl
, templateParameterCountIs
, unsigned, Cnt
) {
8608 return Node
.getTemplateParameters()->size() == Cnt
;
8611 TEST_P(ASTImporterOptionSpecificTestBase
, ImportDeductionGuide
) {
8612 TranslationUnitDecl
*FromTU
= getTuDecl(
8614 template<class> class A { };
8615 template<class T> class B {
8616 template<class T1, typename = A<T>> B(T1);
8623 // Get the implicit deduction guide for (non-default) constructor of 'B'.
8624 auto *FromDGCtor
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
8625 FromTU
, functionTemplateDecl(templateParameterCountIs(3)));
8626 // Implicit deduction guide for copy constructor of 'B'.
8627 auto *FromDGCopyCtor
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
8628 FromTU
, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
8629 // User defined deduction guide.
8630 auto *FromDGOther
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8631 FromTU
, cxxDeductionGuideDecl(unless(isImplicit())));
8633 TemplateParameterList
*FromDGCtorTP
= FromDGCtor
->getTemplateParameters();
8634 // Don't know why exactly but this is the DeclContext here.
8635 EXPECT_EQ(FromDGCtorTP
->getParam(0)->getDeclContext(),
8636 FromDGCopyCtor
->getTemplatedDecl());
8637 EXPECT_EQ(FromDGCtorTP
->getParam(1)->getDeclContext(),
8638 FromDGCtor
->getTemplatedDecl());
8639 EXPECT_EQ(FromDGCtorTP
->getParam(2)->getDeclContext(),
8640 FromDGCtor
->getTemplatedDecl());
8642 FromDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8643 FromDGCopyCtor
->getTemplatedDecl());
8644 EXPECT_EQ(FromDGOther
->getDescribedTemplate()
8645 ->getTemplateParameters()
8650 auto *ToDGCtor
= Import(FromDGCtor
, Lang_CXX17
);
8651 auto *ToDGCopyCtor
= Import(FromDGCopyCtor
, Lang_CXX17
);
8652 auto *ToDGOther
= Import(FromDGOther
, Lang_CXX17
);
8653 ASSERT_TRUE(ToDGCtor
);
8654 ASSERT_TRUE(ToDGCopyCtor
);
8655 ASSERT_TRUE(ToDGOther
);
8657 TemplateParameterList
*ToDGCtorTP
= ToDGCtor
->getTemplateParameters();
8658 EXPECT_EQ(ToDGCtorTP
->getParam(0)->getDeclContext(),
8659 ToDGCopyCtor
->getTemplatedDecl());
8660 EXPECT_EQ(ToDGCtorTP
->getParam(1)->getDeclContext(),
8661 ToDGCtor
->getTemplatedDecl());
8662 EXPECT_EQ(ToDGCtorTP
->getParam(2)->getDeclContext(),
8663 ToDGCtor
->getTemplatedDecl());
8665 ToDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8666 ToDGCopyCtor
->getTemplatedDecl());
8667 EXPECT_EQ(ToDGOther
->getDescribedTemplate()
8668 ->getTemplateParameters()
8674 TEST_P(ASTImporterOptionSpecificTestBase
, ImportDeductionGuideDifferentOrder
) {
8675 // This test demonstrates that the DeclContext of the imported object is
8676 // dependent on the order of import. The test is an exact copy of the previous
8677 // one except at the indicated locations.
8678 TranslationUnitDecl
*FromTU
= getTuDecl(
8680 template<class> class A { };
8681 template<class T> class B {
8682 template<class T1, typename = A<T>> B(T1);
8689 // Get the implicit deduction guide for (non-default) constructor of 'B'.
8690 auto *FromDGCtor
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
8691 FromTU
, functionTemplateDecl(templateParameterCountIs(3)));
8692 // Implicit deduction guide for copy constructor of 'B'.
8693 auto *FromDGCopyCtor
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
8694 FromTU
, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
8695 // User defined deduction guide.
8696 auto *FromDGOther
= FirstDeclMatcher
<CXXDeductionGuideDecl
>().match(
8697 FromTU
, cxxDeductionGuideDecl(unless(isImplicit())));
8699 TemplateParameterList
*FromDGCtorTP
= FromDGCtor
->getTemplateParameters();
8700 // Don't know why exactly but this is the DeclContext here.
8701 EXPECT_EQ(FromDGCtorTP
->getParam(0)->getDeclContext(),
8702 FromDGCopyCtor
->getTemplatedDecl());
8703 EXPECT_EQ(FromDGCtorTP
->getParam(1)->getDeclContext(),
8704 FromDGCtor
->getTemplatedDecl());
8705 EXPECT_EQ(FromDGCtorTP
->getParam(2)->getDeclContext(),
8706 FromDGCtor
->getTemplatedDecl());
8708 FromDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8709 FromDGCopyCtor
->getTemplatedDecl());
8710 EXPECT_EQ(FromDGOther
->getDescribedTemplate()
8711 ->getTemplateParameters()
8716 // Here the import of 'ToDGCopyCtor' and 'ToDGCtor' is reversed relative to
8717 // the previous test.
8718 auto *ToDGCopyCtor
= Import(FromDGCopyCtor
, Lang_CXX17
);
8719 auto *ToDGCtor
= Import(FromDGCtor
, Lang_CXX17
);
8720 auto *ToDGOther
= Import(FromDGOther
, Lang_CXX17
);
8721 ASSERT_TRUE(ToDGCtor
);
8722 ASSERT_TRUE(ToDGCopyCtor
);
8723 ASSERT_TRUE(ToDGOther
);
8725 TemplateParameterList
*ToDGCtorTP
= ToDGCtor
->getTemplateParameters();
8726 // Next line: DeclContext is different relative to the previous test.
8727 EXPECT_EQ(ToDGCtorTP
->getParam(0)->getDeclContext(),
8728 ToDGCtor
->getTemplatedDecl());
8729 EXPECT_EQ(ToDGCtorTP
->getParam(1)->getDeclContext(),
8730 ToDGCtor
->getTemplatedDecl());
8731 EXPECT_EQ(ToDGCtorTP
->getParam(2)->getDeclContext(),
8732 ToDGCtor
->getTemplatedDecl());
8733 // Next line: DeclContext is different relative to the previous test.
8735 ToDGCopyCtor
->getTemplateParameters()->getParam(0)->getDeclContext(),
8736 ToDGCtor
->getTemplatedDecl());
8737 EXPECT_EQ(ToDGOther
->getDescribedTemplate()
8738 ->getTemplateParameters()
8744 TEST_P(ASTImporterOptionSpecificTestBase
,
8745 ImportFieldsFirstForCorrectRecordLayout
) {
8746 // UnaryOperator(&) triggers RecordLayout computation, which relies on
8747 // correctly imported fields.
8752 return &((A *)0)->f1 - &((A *)0)->f2;
8758 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
8760 auto *FromF
= FirstDeclMatcher
<CXXMethodDecl
>().match(
8761 FromTU
, cxxMethodDecl(hasName("A::m")));
8762 Import(FromF
, Lang_CXX11
);
8765 TEST_P(ASTImporterOptionSpecificTestBase
,
8766 ImportCirularRefFieldsWithoutCorruptedRecordLayoutCache
) {
8767 // Import sequence: A => A.b => B => B.f() => ... => UnaryOperator(&) => ...
8769 // UnaryOperator(&) should not introduce invalid RecordLayout since 'A' is
8770 // still not completely imported.
8779 A *f() { return &((B *)0)->a; }
8784 auto *FromR
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8785 getTuDecl(Code
, Lang_CXX11
), cxxRecordDecl(hasName("A")));
8786 FromR
= FromR
->getDefinition();
8787 auto &FromAST
= FromR
->getASTContext();
8788 auto *ToR
= Import(FromR
, Lang_CXX11
);
8789 auto &ToAST
= ToR
->getASTContext();
8791 uint64_t SecondFieldOffset
= FromAST
.getTypeSize(FromAST
.VoidPtrTy
);
8793 EXPECT_TRUE(FromR
->isCompleteDefinition());
8794 const auto &FromLayout
= FromAST
.getASTRecordLayout(FromR
);
8795 EXPECT_TRUE(FromLayout
.getFieldOffset(0) == 0);
8796 EXPECT_TRUE(FromLayout
.getFieldOffset(1) == SecondFieldOffset
);
8798 EXPECT_TRUE(ToR
->isCompleteDefinition());
8799 const auto &ToLayout
= ToAST
.getASTRecordLayout(ToR
);
8800 EXPECT_TRUE(ToLayout
.getFieldOffset(0) == 0);
8801 EXPECT_TRUE(ToLayout
.getFieldOffset(1) == SecondFieldOffset
);
8804 TEST_P(ASTImporterOptionSpecificTestBase
,
8805 ImportRecordWithLayoutRequestingExpr
) {
8806 TranslationUnitDecl
*FromTU
= getTuDecl(
8810 static void foo(A x) {
8811 (void)&"text
"[x.idx];
8817 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8818 FromTU
, cxxRecordDecl(hasName("A")));
8820 // Test that during import of 'foo' the record layout can be obtained without
8822 auto *ToA
= Import(FromA
, Lang_CXX11
);
8824 EXPECT_TRUE(ToA
->isCompleteDefinition());
8827 TEST_P(ASTImporterOptionSpecificTestBase
,
8828 ImportRecordWithLayoutRequestingExprDifferentRecord
) {
8829 TranslationUnitDecl
*FromTU
= getTuDecl(
8837 static void foo(A x) {
8838 (void)&"text
"[x.idx];
8844 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8845 FromTU
, cxxRecordDecl(hasName("A")));
8847 // Test that during import of 'foo' the record layout (of 'A') can be obtained
8848 // without crash. It is not possible to have all of the fields of 'A' imported
8849 // at that time (without big code changes).
8850 auto *ToA
= Import(FromA
, Lang_CXX11
);
8852 EXPECT_TRUE(ToA
->isCompleteDefinition());
8855 TEST_P(ASTImporterOptionSpecificTestBase
, ImportInClassInitializerFromField
) {
8856 // Encounter import of a field when the field already exists but has the
8857 // in-class initializer expression not yet set. Such case can occur in the AST
8858 // of generated template specializations.
8859 // The first code forces to create a template specialization of
8860 // `A<int>` but without implicit constructors.
8861 // The second ("From") code contains a variable of type `A<int>`, this
8862 // results in a template specialization that has constructors and
8863 // CXXDefaultInitExpr nodes.
8864 Decl
*ToTU
= getToTuDecl(
8867 template<typename> struct A { int X = 1; };
8868 struct B { A<int> Y; };
8871 auto *ToX
= FirstDeclMatcher
<FieldDecl
>().match(
8873 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8874 ASSERT_TRUE(ToX
->hasInClassInitializer());
8875 ASSERT_FALSE(ToX
->getInClassInitializer());
8877 Decl
*FromTU
= getTuDecl(
8880 template<typename> struct A { int X = 1; };
8881 struct B { A<int> Y; };
8885 Lang_CXX11
, "input1.cc");
8886 auto *FromX
= FirstDeclMatcher
<FieldDecl
>().match(
8888 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8890 auto *ToXImported
= Import(FromX
, Lang_CXX11
);
8891 EXPECT_EQ(ToXImported
, ToX
);
8892 EXPECT_TRUE(ToX
->getInClassInitializer());
8895 TEST_P(ASTImporterOptionSpecificTestBase
,
8896 ImportInClassInitializerFromCXXDefaultInitExpr
) {
8897 // Encounter AST import of a CXXDefaultInitExpr where the "to-field"
8898 // of it exists but has the in-class initializer not set yet.
8899 Decl
*ToTU
= getToTuDecl(
8902 template<typename> int b;
8905 template<typename> struct A { N::X *X = nullptr; };
8906 struct B { A<int> Y; };
8909 auto *ToX
= FirstDeclMatcher
<FieldDecl
>().match(
8911 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
8912 ASSERT_TRUE(ToX
->hasInClassInitializer());
8913 ASSERT_FALSE(ToX
->getInClassInitializer());
8915 Decl
*FromTU
= getTuDecl(
8918 template<typename> int b;
8921 template<typename> struct A { N::X *X = nullptr; };
8922 struct B { A<int> Y; };
8928 C(): attr(new A<int>{}){}
8930 const int value = N::b<C>;
8933 Lang_CXX14
, "input1.cc");
8934 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
8935 FromTU
, functionDecl(hasName("f"), isDefinition()));
8936 auto *ToF
= Import(FromF
, Lang_CXX11
);
8938 EXPECT_TRUE(ToX
->getInClassInitializer());
8941 TEST_P(ASTImporterOptionSpecificTestBase
, ImportRecursiveFieldInitializer
) {
8947 AP_TECS *TECS_controller;
8955 AP_TECS TECS_controller{landing};
8956 AP_Landing landing{&TECS_controller};
8959 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
8961 auto *FromR
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8962 FromTU
, cxxRecordDecl(hasName("Plane")));
8963 for (FieldDecl
*F
: FromR
->fields())
8964 EXPECT_TRUE(F
->getInClassInitializer());
8965 auto *ToR
= Import(FromR
, Lang_CXX11
);
8966 for (FieldDecl
*F
: ToR
->fields())
8967 EXPECT_TRUE(F
->getInClassInitializer());
8970 TEST_P(ASTImporterOptionSpecificTestBase
, ImportFieldInitializerWithItself
) {
8977 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
8978 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
8979 FromTU
, cxxRecordDecl(hasName("A")));
8980 EXPECT_TRUE(FromA
->field_begin()->getInClassInitializer());
8981 auto *ToA
= Import(FromA
, Lang_CXX11
);
8982 EXPECT_TRUE(ToA
->field_begin()->getInClassInitializer());
8985 TEST_P(ASTImporterOptionSpecificTestBase
, ImportRecursiveFieldInitializer1
) {
8986 // FIXME: This is a example of recursive field initialization that is not
8988 // The following import chain occurs (not complete):
8989 // import of A => A.a => in-class initializer of A.a => ref_B() => B => B.b
8990 // => in-class initializer of B.b => ref_A() => CXXConstructExpr for A =>
8991 // CXXDefaultInitExpr for A.a => in-class initializer of A.a
8992 // in-class initializer of A.a is created in two different instances in this
8993 // case (import of FieldDecl and CXXDefaultInitExpr). Probably not a big
8994 // problem because it is an Expr (the second construction can be ignored
8995 // instead of assert). But such recursive init code should not occur in
9007 int ref_B() { B b; return b.b; }
9008 int ref_A() { A a; return a.a; }
9010 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
9011 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9012 FromTU
, cxxRecordDecl(hasName("A")));
9013 EXPECT_TRUE(FromA
->field_begin()->getInClassInitializer());
9014 // auto *ToA = Import(FromA, Lang_CXX11);
9015 // EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
9018 TEST_P(ASTImporterOptionSpecificTestBase
, isNewDecl
) {
9019 Decl
*FromTU
= getTuDecl(
9029 Decl
*ToTU
= getToTuDecl(
9036 auto *FromOther
= FirstDeclMatcher
<FunctionDecl
>().match(
9037 FromTU
, functionDecl(hasName("other")));
9038 ASSERT_TRUE(FromOther
);
9040 auto *ToOther
= Import(FromOther
, Lang_CXX11
);
9041 ASSERT_TRUE(ToOther
);
9043 auto *ToBar
= FirstDeclMatcher
<FunctionDecl
>().match(
9044 ToTU
, functionDecl(hasName("bar")));
9046 EXPECT_TRUE(SharedStatePtr
->isNewDecl(ToOther
));
9047 EXPECT_FALSE(SharedStatePtr
->isNewDecl(ToBar
));
9050 struct ImportInjectedClassNameType
: public ASTImporterOptionSpecificTestBase
{
9052 const CXXRecordDecl
*findInjected(const CXXRecordDecl
*Parent
) {
9053 for (Decl
*Found
: Parent
->decls()) {
9054 const auto *Record
= dyn_cast
<CXXRecordDecl
>(Found
);
9055 if (Record
&& Record
->isInjectedClassName())
9061 void checkInjType(const CXXRecordDecl
*D
) {
9062 // The whole redecl chain should have the same InjectedClassNameType
9063 // instance. The injected record declaration is a separate chain, this
9064 // should contain the same type too.
9065 const Type
*Ty
= nullptr;
9066 for (const Decl
*ReD
: D
->redecls()) {
9067 const auto *ReRD
= cast
<CXXRecordDecl
>(ReD
);
9068 EXPECT_TRUE(ReRD
->getTypeForDecl());
9069 EXPECT_TRUE(!Ty
|| Ty
== ReRD
->getTypeForDecl());
9070 Ty
= ReRD
->getTypeForDecl();
9073 const auto *InjTy
= Ty
->castAs
<InjectedClassNameType
>();
9075 if (CXXRecordDecl
*Def
= D
->getDefinition()) {
9076 const CXXRecordDecl
*InjRD
= findInjected(Def
);
9078 EXPECT_EQ(InjRD
->getTypeForDecl(), InjTy
);
9082 void testImport(Decl
*ToTU
, Decl
*FromTU
, Decl
*FromD
) {
9083 checkInjType(cast
<CXXRecordDecl
>(FromD
));
9084 Decl
*ToD
= Import(FromD
, Lang_CXX11
);
9085 if (auto *ToRD
= dyn_cast
<CXXRecordDecl
>(ToD
))
9089 const char *ToCodeA
=
9094 const char *ToCodeADef
=
9101 const char *ToCodeC
=
9106 const char *ToCodeCDef
=
9113 template <class T1, class T2>
9118 typedef typename A<T>::T1 T1;
9119 typedef B<T1, T> T2;
9120 typedef B<T1, C> T3;
9123 const char *FromCode
=
9134 template <class T1, class T2>
9141 typedef typename A<T>::T1 T1;
9142 typedef B<T1, T> T2;
9143 typedef B<T1, C> T3;
9150 void f(typename C<T>::T3 *);
9155 TEST_P(ImportInjectedClassNameType
, ImportADef
) {
9156 Decl
*ToTU
= getToTuDecl(ToCodeA
, Lang_CXX11
);
9157 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9158 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9159 FromTU
, cxxRecordDecl(hasName("A"), isDefinition()));
9160 testImport(ToTU
, FromTU
, FromA
);
9163 TEST_P(ImportInjectedClassNameType
, ImportAFirst
) {
9164 Decl
*ToTU
= getToTuDecl(ToCodeA
, Lang_CXX11
);
9165 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9166 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9167 FromTU
, cxxRecordDecl(hasName("A")));
9168 testImport(ToTU
, FromTU
, FromA
);
9171 TEST_P(ImportInjectedClassNameType
, ImportALast
) {
9172 Decl
*ToTU
= getToTuDecl(ToCodeA
, Lang_CXX11
);
9173 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9174 auto *FromA
= LastDeclMatcher
<CXXRecordDecl
>().match(
9175 FromTU
, cxxRecordDecl(hasName("A")));
9176 testImport(ToTU
, FromTU
, FromA
);
9179 TEST_P(ImportInjectedClassNameType
, ImportADefToDef
) {
9180 Decl
*ToTU
= getToTuDecl(ToCodeADef
, Lang_CXX11
);
9181 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9182 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9183 FromTU
, cxxRecordDecl(hasName("A"), isDefinition()));
9184 testImport(ToTU
, FromTU
, FromA
);
9187 TEST_P(ImportInjectedClassNameType
, ImportAFirstToDef
) {
9188 Decl
*ToTU
= getToTuDecl(ToCodeADef
, Lang_CXX11
);
9189 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9190 auto *FromA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9191 FromTU
, cxxRecordDecl(hasName("A")));
9192 testImport(ToTU
, FromTU
, FromA
);
9195 TEST_P(ImportInjectedClassNameType
, ImportALastToDef
) {
9196 Decl
*ToTU
= getToTuDecl(ToCodeADef
, Lang_CXX11
);
9197 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9198 auto *FromA
= LastDeclMatcher
<CXXRecordDecl
>().match(
9199 FromTU
, cxxRecordDecl(hasName("A")));
9200 testImport(ToTU
, FromTU
, FromA
);
9203 TEST_P(ImportInjectedClassNameType
, ImportCDef
) {
9204 Decl
*ToTU
= getToTuDecl(ToCodeC
, Lang_CXX11
);
9205 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9206 auto *FromC
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9207 FromTU
, cxxRecordDecl(hasName("C"), isDefinition()));
9208 testImport(ToTU
, FromTU
, FromC
);
9211 TEST_P(ImportInjectedClassNameType
, ImportCLast
) {
9212 Decl
*ToTU
= getToTuDecl(ToCodeC
, Lang_CXX11
);
9213 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9214 auto *FromC
= LastDeclMatcher
<CXXRecordDecl
>().match(
9215 FromTU
, cxxRecordDecl(hasName("C")));
9216 testImport(ToTU
, FromTU
, FromC
);
9219 TEST_P(ImportInjectedClassNameType
, ImportCDefToDef
) {
9220 Decl
*ToTU
= getToTuDecl(ToCodeCDef
, Lang_CXX11
);
9221 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9222 auto *FromC
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9223 FromTU
, cxxRecordDecl(hasName("C"), isDefinition()));
9224 testImport(ToTU
, FromTU
, FromC
);
9227 TEST_P(ImportInjectedClassNameType
, ImportCLastToDef
) {
9228 Decl
*ToTU
= getToTuDecl(ToCodeCDef
, Lang_CXX11
);
9229 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9230 auto *FromC
= LastDeclMatcher
<CXXRecordDecl
>().match(
9231 FromTU
, cxxRecordDecl(hasName("C")));
9232 testImport(ToTU
, FromTU
, FromC
);
9235 TEST_P(ImportInjectedClassNameType
, ImportD
) {
9236 Decl
*ToTU
= getToTuDecl("", Lang_CXX11
);
9237 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9238 auto *FromD
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9239 FromTU
, cxxRecordDecl(hasName("D"), isDefinition()));
9240 testImport(ToTU
, FromTU
, FromD
);
9243 TEST_P(ImportInjectedClassNameType
, ImportDToDef
) {
9244 Decl
*ToTU
= getToTuDecl(ToCodeCDef
, Lang_CXX11
);
9245 Decl
*FromTU
= getTuDecl(FromCode
, Lang_CXX11
);
9246 auto *FromD
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9247 FromTU
, cxxRecordDecl(hasName("D"), isDefinition()));
9248 testImport(ToTU
, FromTU
, FromD
);
9251 TEST_P(ImportInjectedClassNameType
, ImportTypedefType
) {
9252 Decl
*ToTU
= getToTuDecl(
9261 Decl
*FromTU
= getTuDecl(
9269 void A<T>::f(A::A1 *) {}
9273 auto *FromF
= FirstDeclMatcher
<FunctionDecl
>().match(
9274 FromTU
, functionDecl(hasName("f"), isDefinition()));
9275 auto *ToF
= Import(FromF
, Lang_CXX11
);
9277 ASTContext
&ToCtx
= ToF
->getDeclContext()->getParentASTContext();
9280 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("A1")));
9281 QualType ToInjTypedef
= ToA1
->getUnderlyingType().getCanonicalType();
9282 QualType ToInjParmVar
=
9283 ToF
->parameters()[0]->getType().getDesugaredType(ToCtx
);
9285 ToInjParmVar
->getAs
<PointerType
>()->getPointeeType().getCanonicalType();
9286 EXPECT_TRUE(isa
<InjectedClassNameType
>(ToInjTypedef
));
9287 EXPECT_TRUE(isa
<InjectedClassNameType
>(ToInjParmVar
));
9288 EXPECT_TRUE(ToCtx
.hasSameType(ToInjTypedef
, ToInjParmVar
));
9291 TEST_P(ASTImporterOptionSpecificTestBase
, ImportMacroQualifiedType
) {
9293 std::tie(From
, To
) = getImportedDecl(
9295 #define CDECL __attribute__((cdecl))
9296 typedef void (CDECL *X)();
9298 Lang_CXX03
, "", Lang_CXX03
, "X");
9301 FirstDeclMatcher
<MacroQualifiedType
>().match(From
, macroQualifiedType());
9303 FirstDeclMatcher
<MacroQualifiedType
>().match(To
, macroQualifiedType());
9305 EXPECT_TRUE(isa
<AttributedType
>(FromTy
->getUnderlyingType()));
9306 EXPECT_TRUE(isa
<AttributedType
>(ToTy
->getUnderlyingType()));
9309 TEST_P(ASTImporterOptionSpecificTestBase
, ImportCorrectTemplateName
) {
9310 constexpr auto TestCode
= R
"(
9315 template <template<class> class T = A>
9319 Decl
*ToTU
= getToTuDecl(TestCode
, Lang_CXX11
);
9320 Decl
*FromTU
= getTuDecl(TestCode
, Lang_CXX11
);
9322 auto *ToUsingFirst
= FirstDeclMatcher
<TypeAliasDecl
>().match(
9323 ToTU
, typeAliasDecl(hasName("C")));
9325 auto *FromUsing
= FirstDeclMatcher
<TypeAliasDecl
>().match(
9326 FromTU
, typeAliasDecl(hasName("C")));
9327 auto *ToUsing
= Import(FromUsing
, Lang_CXX11
);
9328 EXPECT_TRUE(ToUsing
);
9330 auto *ToB
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
9331 ToTU
, classTemplateDecl(hasName("B")));
9332 auto *ToB1
= LastDeclMatcher
<ClassTemplateDecl
>().match(
9333 ToTU
, classTemplateDecl(hasName("B")));
9334 // One template definition of 'B' should exist.
9335 EXPECT_EQ(ToB
, ToB1
);
9337 // These declarations are imported separately.
9338 EXPECT_NE(ToUsingFirst
, ToUsing
);
9340 auto SpB
= ToB
->spec_begin();
9341 auto SpE
= ToB
->spec_end();
9342 EXPECT_TRUE(SpB
!= SpE
);
9343 ClassTemplateSpecializationDecl
*Spec1
= *SpB
;
9345 // The template 'B' should have one specialization (with default argument).
9346 EXPECT_TRUE(SpB
== SpE
);
9348 // Even if 'B' has one specialization with the default arguments, the AST
9349 // contains after the import two specializations that are linked in the
9350 // declaration chain. The 'spec_begin' iteration does not find these because
9351 // the template arguments are the same. But the imported type alias has the
9352 // link to the second specialization. The template name object in these
9353 // specializations must point to the same (and one) instance of definition of
9355 auto *Spec2
= cast
<ClassTemplateSpecializationDecl
>(
9356 ToUsing
->getUnderlyingType()
9357 ->getAs
<TemplateSpecializationType
>()
9358 ->getAsRecordDecl());
9359 EXPECT_NE(Spec1
, Spec2
);
9360 EXPECT_TRUE(Spec1
->getPreviousDecl() == Spec2
||
9361 Spec2
->getPreviousDecl() == Spec1
);
9362 TemplateDecl
*Templ1
=
9363 Spec1
->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl();
9364 TemplateDecl
*Templ2
=
9365 Spec2
->getTemplateArgs()[0].getAsTemplate().getAsTemplateDecl();
9366 EXPECT_EQ(Templ1
, Templ2
);
9369 TEST_P(ASTImporterOptionSpecificTestBase
, VaListC
) {
9370 Decl
*FromTU
= getTuDecl(R
"(typedef __builtin_va_list va_list;)", Lang_C99
);
9372 auto *FromVaList
= FirstDeclMatcher
<TypedefDecl
>().match(
9373 FromTU
, typedefDecl(hasName("va_list")));
9374 ASSERT_TRUE(FromVaList
);
9376 auto *ToVaList
= Import(FromVaList
, Lang_C99
);
9377 ASSERT_TRUE(ToVaList
);
9379 auto *ToBuiltinVaList
= FirstDeclMatcher
<TypedefDecl
>().match(
9380 ToAST
->getASTContext().getTranslationUnitDecl(),
9381 typedefDecl(hasName("__builtin_va_list")));
9383 ASSERT_TRUE(ToAST
->getASTContext().hasSameType(
9384 ToVaList
->getUnderlyingType(), ToBuiltinVaList
->getUnderlyingType()));
9387 TEST_P(ASTImporterOptionSpecificTestBase
, VaListCpp
) {
9388 Decl
*FromTU
= getTuDecl(R
"(typedef __builtin_va_list va_list;)", Lang_CXX03
);
9390 auto *FromVaList
= FirstDeclMatcher
<TypedefDecl
>().match(
9391 FromTU
, typedefDecl(hasName("va_list")));
9392 ASSERT_TRUE(FromVaList
);
9394 auto *ToVaList
= Import(FromVaList
, Lang_CXX03
);
9395 ASSERT_TRUE(ToVaList
);
9397 auto *ToBuiltinVaList
= FirstDeclMatcher
<TypedefDecl
>().match(
9398 ToAST
->getASTContext().getTranslationUnitDecl(),
9399 typedefDecl(hasName("__builtin_va_list")));
9401 ASSERT_TRUE(ToAST
->getASTContext().hasSameType(
9402 ToVaList
->getUnderlyingType(), ToBuiltinVaList
->getUnderlyingType()));
9405 TEST_P(ASTImporterOptionSpecificTestBase
, ImportExistingTypedefToRecord
) {
9408 struct S { int i; };
9412 Decl
*ToTU
= getToTuDecl(Code
, Lang_C99
);
9413 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9416 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x")));
9417 auto *ToX
= Import(FromX
, Lang_C99
);
9421 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9423 LastDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9424 EXPECT_EQ(Typedef1
, Typedef2
);
9427 TEST_P(ASTImporterOptionSpecificTestBase
,
9428 ImportExistingTypedefToUnnamedRecord
) {
9431 typedef const struct { int f; } T;
9434 Decl
*ToTU
= getToTuDecl(Code
, Lang_C99
);
9435 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9438 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x")));
9439 auto *ToX
= Import(FromX
, Lang_C99
);
9443 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9445 LastDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9446 EXPECT_NE(Typedef1
, Typedef2
);
9447 EXPECT_NE(Typedef1
->getUnderlyingType().getTypePtr(),
9448 Typedef2
->getUnderlyingType().getTypePtr());
9449 EXPECT_EQ(ToX
->getType()->getAs
<TypedefType
>()->getDecl(), Typedef2
);
9452 TEST_P(ASTImporterOptionSpecificTestBase
, ImportTwoTypedefsToUnnamedRecord
) {
9455 typedef struct { int f; } T1;
9456 typedef struct { int f; } T2;
9460 Decl
*ToTU
= getToTuDecl("", Lang_C99
);
9461 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9464 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x1")));
9466 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x2")));
9467 auto *ToX1
= Import(FromX1
, Lang_C99
);
9469 auto *ToX2
= Import(FromX2
, Lang_C99
);
9473 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T1")));
9475 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T2")));
9476 EXPECT_NE(Typedef1
->getUnderlyingType().getTypePtr(),
9477 Typedef2
->getUnderlyingType().getTypePtr());
9480 TEST_P(ASTImporterOptionSpecificTestBase
,
9481 ImportExistingTypedefToUnnamedRecordPtr
) {
9484 typedef const struct { int fff; } * const T;
9487 Decl
*ToTU
= getToTuDecl(Code
, Lang_C99
);
9488 Decl
*FromTU
= getTuDecl(Code
, Lang_C99
);
9491 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("x")));
9492 auto *ToX
= Import(FromX
, Lang_C99
);
9496 FirstDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9498 LastDeclMatcher
<TypedefDecl
>().match(ToTU
, typedefDecl(hasName("T")));
9499 // FIXME: These should be imported separately, like in the test above.
9500 // Or: In the test above these should be merged too.
9501 EXPECT_EQ(Typedef1
, Typedef2
);
9503 auto *FromR
= FirstDeclMatcher
<RecordDecl
>().match(
9504 FromTU
, recordDecl(hasDescendant(fieldDecl(hasName("fff")))));
9505 auto *ToRExisting
= FirstDeclMatcher
<RecordDecl
>().match(
9506 ToTU
, recordDecl(hasDescendant(fieldDecl(hasName("fff")))));
9508 auto *ToRImported
= Import(FromR
, Lang_C99
);
9509 // FIXME: If typedefs are not imported separately, do not import ToRImported
9511 EXPECT_NE(ToRExisting
, ToRImported
);
9514 TEST_P(ASTImporterOptionSpecificTestBase
,
9515 ImportTypedefWithDifferentUnderlyingType
) {
9523 using RPB1 = Y1*; // redeclared
9526 auto X = 0 ? (RPX1){} : (RPY1){};
9528 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
9531 FirstDeclMatcher
<VarDecl
>().match(FromTU
, varDecl(hasName("X")));
9533 auto *FromXType
= FromX
->getType()->getAs
<TypedefType
>();
9534 EXPECT_FALSE(FromXType
->typeMatchesDecl());
9536 auto *ToX
= Import(FromX
, Lang_CXX11
);
9537 auto *ToXType
= ToX
->getType()->getAs
<TypedefType
>();
9538 // FIXME: This should be false.
9539 EXPECT_TRUE(ToXType
->typeMatchesDecl());
9542 TEST_P(ASTImporterOptionSpecificTestBase
,
9543 ImportTemplateArgumentWithPointerToDifferentInstantiation
) {
9544 const char *CodeTo
=
9550 template<class A, A (B)()>
9555 const char *CodeFrom
=
9559 template<class A, A (B)()>
9564 Decl
*ToTU
= getToTuDecl(CodeTo
, Lang_CXX11
);
9565 Decl
*FromTU
= getTuDecl(CodeFrom
, Lang_CXX11
);
9567 auto *ToF1
= FirstDeclMatcher
<FunctionDecl
>().match(
9568 ToTU
, functionDecl(hasName("f1"), isInstantiated()));
9569 auto *FromF1
= FirstDeclMatcher
<FunctionDecl
>().match(
9570 FromTU
, functionDecl(hasName("f1"), isInstantiated()));
9571 EXPECT_TRUE(ToF1
->isThisDeclarationADefinition());
9572 EXPECT_FALSE(FromF1
->isThisDeclarationADefinition());
9574 auto *ToX
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
9575 ToTU
, classTemplateSpecializationDecl(hasName("X")));
9576 auto *FromX
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
9577 FromTU
, classTemplateSpecializationDecl(hasName("X")));
9579 Decl
*ToTArgF
= ToX
->getTemplateArgs().get(1).getAsDecl();
9580 Decl
*FromTArgF
= FromX
->getTemplateArgs().get(1).getAsDecl();
9581 EXPECT_EQ(ToTArgF
, ToF1
);
9582 EXPECT_EQ(FromTArgF
, FromF1
);
9584 auto *ToXImported
= Import(FromX
, Lang_CXX11
);
9585 // The template argument 1 of 'X' in the "From" code points to a function
9586 // that has no definition. The import must ensure that this template argument
9587 // is imported in a way that it will point to the existing 'f1' function, not
9588 // to the 'f1' that is imported. In this way when specialization of 'X' is
9589 // imported it will have the same template arguments as the existing one.
9590 EXPECT_EQ(ToXImported
, ToX
);
9591 // FIXME: This matcher causes a crash "Tried to match orphan node".
9592 // The code is removed until the problem is fixed.
9593 // auto *ToF1Imported =
9594 // LastDeclMatcher<FunctionDecl>().match(ToTU,
9595 // functionDecl(hasName("f1"),isInstantiated()));
9596 // EXPECT_NE(ToF1Imported, ToF1);
9597 // EXPECT_EQ(ToF1Imported->getPreviousDecl(), ToF1);
9600 TEST_P(ASTImporterOptionSpecificTestBase
,
9601 ImportTypeAliasTemplateAfterSimilarCalledTemplateTypeParm
) {
9607 template <typename Callable>
9608 int bindingFunctionVTable;
9610 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX17
);
9612 auto *FromCallable
= FirstDeclMatcher
<TypeAliasTemplateDecl
>().match(
9613 FromTU
, typeAliasTemplateDecl(hasName("Callable")));
9615 auto *FromCallableParm
= FirstDeclMatcher
<TemplateTypeParmDecl
>().match(
9616 FromTU
, templateTypeParmDecl(hasName("Callable")));
9618 auto *ToFromCallableParm
= Import(FromCallableParm
, Lang_CXX17
);
9619 auto *ToCallable
= Import(FromCallable
, Lang_CXX17
);
9620 EXPECT_TRUE(ToFromCallableParm
);
9621 EXPECT_TRUE(ToCallable
);
9624 TEST_P(ASTImporterOptionSpecificTestBase
, ImportConflictTypeAliasTemplate
) {
9625 const char *ToCode
=
9628 template <typename, typename>
9637 (void)getToTuDecl(ToCode
, Lang_CXX17
);
9638 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX17
);
9640 auto *FromCallable
= FirstDeclMatcher
<TypeAliasTemplateDecl
>().match(
9641 FromTU
, typeAliasTemplateDecl(hasName("Callable")));
9643 auto *ImportedCallable
= Import(FromCallable
, Lang_CXX17
);
9644 EXPECT_FALSE(ImportedCallable
);
9647 AST_MATCHER(ClassTemplateSpecializationDecl
, hasInstantiatedFromMember
) {
9648 if (auto Instantiate
= Node
.getInstantiatedFrom()) {
9649 if (auto *FromPartialSpecialization
=
9650 cast
<ClassTemplatePartialSpecializationDecl
*>(Instantiate
)) {
9651 return nullptr != FromPartialSpecialization
->getInstantiatedFromMember();
9657 TEST_P(ASTImporterOptionSpecificTestBase
, ImportInstantiatedFromMember
) {
9660 template <typename> struct B {
9661 template <typename, bool = false> union D;
9662 template <typename T> union D<T> {};
9667 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
9668 auto *FromD
= FirstDeclMatcher
<ClassTemplateSpecializationDecl
>().match(
9669 FromTU
, classTemplateSpecializationDecl(hasName("D"),
9670 hasInstantiatedFromMember()));
9671 auto *FromPartialSpecialization
=
9672 cast
<ClassTemplatePartialSpecializationDecl
*>(
9673 FromD
->getInstantiatedFrom());
9674 ASSERT_TRUE(FromPartialSpecialization
->getInstantiatedFromMember());
9675 auto *ImportedPartialSpecialization
=
9676 Import(FromPartialSpecialization
, Lang_CXX11
);
9677 EXPECT_TRUE(ImportedPartialSpecialization
->getInstantiatedFromMember());
9680 AST_MATCHER_P(EnumDecl
, hasEnumConstName
, StringRef
, ConstName
) {
9681 for (EnumConstantDecl
*D
: Node
.enumerators())
9682 if (D
->getName() == ConstName
)
9687 TEST_P(ASTImporterOptionSpecificTestBase
, ImportAnonymousEnums
) {
9695 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
9696 auto *FromEnumE1
= FirstDeclMatcher
<EnumDecl
>().match(
9697 FromTU
, enumDecl(hasEnumConstName("E1")));
9698 auto *ImportedEnumE1
= Import(FromEnumE1
, Lang_CXX11
);
9699 EXPECT_TRUE(ImportedEnumE1
);
9700 auto *FromEnumE3
= FirstDeclMatcher
<EnumDecl
>().match(
9701 FromTU
, enumDecl(hasEnumConstName("E3")));
9702 auto *ImportedEnumE3
= Import(FromEnumE3
, Lang_CXX11
);
9703 EXPECT_TRUE(ImportedEnumE3
);
9704 EXPECT_NE(ImportedEnumE1
, ImportedEnumE3
);
9707 TEST_P(ASTImporterOptionSpecificTestBase
, ImportFreeStandingAnonymousEnums
) {
9715 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
9716 auto *FromEnumE1
= FirstDeclMatcher
<EnumDecl
>().match(
9717 FromTU
, enumDecl(hasEnumConstName("E1")));
9718 auto *ImportedEnumE1
= Import(FromEnumE1
, Lang_CXX11
);
9719 EXPECT_TRUE(ImportedEnumE1
);
9720 auto *FromEnumE3
= FirstDeclMatcher
<EnumDecl
>().match(
9721 FromTU
, enumDecl(hasEnumConstName("E3")));
9722 auto *ImportedEnumE3
= Import(FromEnumE3
, Lang_CXX11
);
9723 EXPECT_TRUE(ImportedEnumE3
);
9724 EXPECT_NE(ImportedEnumE1
, ImportedEnumE3
);
9727 TEST_P(ASTImporterOptionSpecificTestBase
, ImportExistingAnonymousEnums
) {
9728 const char *ToCode
=
9735 Decl
*ToTU
= getToTuDecl(ToCode
, Lang_CXX11
);
9736 auto *ToEnumE1
= FirstDeclMatcher
<EnumDecl
>().match(
9737 ToTU
, enumDecl(hasEnumConstName("E1")));
9738 auto *ToEnumE3
= FirstDeclMatcher
<EnumDecl
>().match(
9739 ToTU
, enumDecl(hasEnumConstName("E3")));
9747 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
9748 auto *FromEnumE1
= FirstDeclMatcher
<EnumDecl
>().match(
9749 FromTU
, enumDecl(hasEnumConstName("E1")));
9750 auto *ImportedEnumE1
= Import(FromEnumE1
, Lang_CXX11
);
9751 ASSERT_TRUE(ImportedEnumE1
);
9752 EXPECT_EQ(ImportedEnumE1
, ToEnumE1
);
9753 auto *FromEnumE3
= FirstDeclMatcher
<EnumDecl
>().match(
9754 FromTU
, enumDecl(hasEnumConstName("E3")));
9755 auto *ImportedEnumE3
= Import(FromEnumE3
, Lang_CXX11
);
9756 ASSERT_TRUE(ImportedEnumE3
);
9757 EXPECT_EQ(ImportedEnumE3
, ToEnumE3
);
9760 TEST_P(ASTImporterOptionSpecificTestBase
, ImportExistingEmptyAnonymousEnums
) {
9761 const char *ToCode
=
9767 Decl
*ToTU
= getToTuDecl(ToCode
, Lang_CXX11
);
9768 auto *ToE1
= FirstDeclMatcher
<EnumDecl
>().match(ToTU
, enumDecl());
9776 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX11
);
9777 auto *FromE1
= FirstDeclMatcher
<EnumDecl
>().match(FromTU
, enumDecl());
9778 auto *ImportedE1
= Import(FromE1
, Lang_CXX11
);
9779 ASSERT_TRUE(ImportedE1
);
9780 EXPECT_EQ(ImportedE1
, ToE1
);
9781 auto *FromE2
= LastDeclMatcher
<EnumDecl
>().match(FromTU
, enumDecl());
9782 ASSERT_NE(FromE1
, FromE2
);
9783 auto *ImportedE2
= Import(FromE2
, Lang_CXX11
);
9784 ASSERT_TRUE(ImportedE2
);
9785 // FIXME: These should not be equal, or the import should fail.
9786 EXPECT_EQ(ImportedE2
, ToE1
);
9789 TEST_P(ASTImporterOptionSpecificTestBase
, ImportMultipleAnonymousEnumDecls
) {
9790 Decl
*ToTU
= getToTuDecl("", Lang_CXX03
);
9791 Decl
*FromTU
= getTuDecl(
9800 auto EnumConstA
= enumConstantDecl(hasName("A"));
9801 auto EnumConstB
= enumConstantDecl(hasName("B"));
9803 auto *FromA
= FirstDeclMatcher
<EnumConstantDecl
>().match(FromTU
, EnumConstA
);
9804 auto *FromB
= FirstDeclMatcher
<EnumConstantDecl
>().match(FromTU
, EnumConstB
);
9806 auto *ToA
= Import(FromA
, Lang_CXX03
);
9807 auto *ToB
= Import(FromB
, Lang_CXX03
);
9812 auto *ToFooA
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9813 ToTU
, tagDecl(has(enumDecl(has(EnumConstA
)))));
9814 auto *ToFooB
= FirstDeclMatcher
<CXXRecordDecl
>().match(
9815 ToTU
, tagDecl(has(enumDecl(has(EnumConstB
)))));
9816 ASSERT_EQ(ToFooA
, ToFooB
);
9818 // different EnumDecl
9820 FirstDeclMatcher
<EnumDecl
>().match(ToTU
, enumDecl(has(EnumConstA
)));
9822 FirstDeclMatcher
<EnumDecl
>().match(ToTU
, enumDecl(has(EnumConstB
)));
9823 ASSERT_NE(ToEnumDeclA
, ToEnumDeclB
);
9826 struct ImportTemplateParmDeclDefaultValue
9827 : public ASTImporterOptionSpecificTestBase
{
9829 void checkTemplateParams(RedeclarableTemplateDecl
*D
,
9830 RedeclarableTemplateDecl
*InheritedFromD
) {
9832 cast
<NonTypeTemplateParmDecl
>(D
->getTemplateParameters()->getParam(0));
9834 cast
<TemplateTypeParmDecl
>(D
->getTemplateParameters()->getParam(1));
9836 cast
<TemplateTemplateParmDecl
>(D
->getTemplateParameters()->getParam(2));
9837 if (InheritedFromD
) {
9838 EXPECT_TRUE(NonTypeP
->getDefaultArgStorage().isInherited());
9839 EXPECT_TRUE(TypeP
->getDefaultArgStorage().isInherited());
9840 EXPECT_TRUE(TemplateP
->getDefaultArgStorage().isInherited());
9841 EXPECT_EQ(NonTypeP
->getDefaultArgStorage().getInheritedFrom(),
9842 InheritedFromD
->getTemplateParameters()->getParam(0));
9843 EXPECT_EQ(TypeP
->getDefaultArgStorage().getInheritedFrom(),
9844 InheritedFromD
->getTemplateParameters()->getParam(1));
9845 EXPECT_EQ(TemplateP
->getDefaultArgStorage().getInheritedFrom(),
9846 InheritedFromD
->getTemplateParameters()->getParam(2));
9848 EXPECT_FALSE(NonTypeP
->getDefaultArgStorage().isInherited());
9849 EXPECT_FALSE(TypeP
->getDefaultArgStorage().isInherited());
9850 EXPECT_FALSE(TemplateP
->getDefaultArgStorage().isInherited());
9854 void testImport(RedeclarableTemplateDecl
*FromD1
,
9855 RedeclarableTemplateDecl
*FromD2
,
9856 RedeclarableTemplateDecl
*FromD3
,
9857 RedeclarableTemplateDecl
*ToExistingD1
) {
9858 auto *ToD1
= Import(FromD1
, Lang_CXX14
);
9859 auto *ToD2
= Import(FromD2
, Lang_CXX14
);
9860 auto *ToD3
= Import(FromD3
, Lang_CXX14
);
9861 checkTemplateParams(ToD1
, nullptr);
9862 checkTemplateParams(ToD2
, ToD1
);
9863 checkTemplateParams(ToD3
, ToExistingD1
? ToExistingD1
: ToD1
);
9866 // In these tests a circular dependency is created between the template
9867 // parameter default value and the template declaration (with the same
9868 // template parameter).
9869 template <class TemplateParmDeclT
>
9871 testTemplateParmDeclCircularDependency(ClassTemplateDecl
*FromD
,
9872 ClassTemplateDecl
*FromDInherited
) {
9873 auto GetTemplateParm
=
9874 [](ClassTemplateDecl
*D
) -> const TemplateParmDeclT
* {
9875 return dyn_cast
<TemplateParmDeclT
>(
9876 D
->getTemplateParameters()->getParam(0));
9879 ASSERT_FALSE(GetTemplateParm(FromD
)->getDefaultArgStorage().isInherited());
9881 GetTemplateParm(FromDInherited
)->getDefaultArgStorage().isInherited());
9883 auto *ToD
= Import(FromD
, Lang_CXX14
);
9886 auto *ToDInherited
= Import(FromDInherited
, Lang_CXX14
);
9887 EXPECT_TRUE(ToDInherited
);
9889 EXPECT_FALSE(GetTemplateParm(ToD
)->getDefaultArgStorage().isInherited());
9891 GetTemplateParm(ToDInherited
)->getDefaultArgStorage().isInherited());
9892 EXPECT_EQ(GetTemplateParm(ToDInherited
)
9893 ->getDefaultArgStorage()
9894 .getInheritedFrom(),
9895 GetTemplateParm(ToD
));
9897 EXPECT_EQ(ToD
->getPreviousDecl(), ToDInherited
);
9900 const char *CodeFunction
=
9902 template <class> struct X;
9904 template <int A = 2, typename B = int, template<class> class C = X>
9906 template <int A, typename B, template<class> class C>
9908 template <int A, typename B, template<class> class C>
9912 const char *CodeClass
=
9915 template <class> struct X;
9917 template <int A = 2, typename B = int, template<class> class C = X>
9919 template <int A, typename B, template<class> class C>
9921 template <int A, typename B, template<class> class C>
9926 const char *CodeVar
=
9929 template <class> struct X;
9931 template <int A = 2, typename B = int, template<class> class C = X>
9933 template <int A, typename B, template<class> class C>
9935 template <int A, typename B, template<class> class C>
9941 TEST_P(ImportTemplateParmDeclDefaultValue
, InvisibleInheritedFrom
) {
9942 const char *ToCode
=
9944 template <int P = 1>
9947 TranslationUnitDecl
*ToTU
= getToTuDecl(ToCode
, Lang_CXX14
);
9948 auto *ToFDef
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
9949 ToTU
, functionTemplateDecl(hasName("f")));
9951 const char *FromCode
=
9953 template <int P = 1>
9958 TranslationUnitDecl
*FromTU
= getTuDecl(FromCode
, Lang_CXX14
);
9959 auto *FromFDef
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
9960 FromTU
, functionTemplateDecl(hasName("f")));
9961 auto *FromF
= LastDeclMatcher
<FunctionTemplateDecl
>().match(
9962 FromTU
, functionTemplateDecl(hasName("f")));
9964 auto *ToFDefImported
= Import(FromFDef
, Lang_CXX14
);
9965 EXPECT_EQ(ToFDefImported
, ToFDef
);
9966 auto *ToF
= Import(FromF
, Lang_CXX14
);
9967 EXPECT_NE(ToF
, ToFDef
);
9968 const auto *Parm
= dyn_cast
<NonTypeTemplateParmDecl
>(
9969 ToF
->getTemplateParameters()->getParam(0));
9970 EXPECT_TRUE(Parm
->defaultArgumentWasInherited());
9971 // FIXME: This behavior may be confusing:
9972 // Default value is not inherited from the existing declaration, instead a new
9973 // is created at import that is similar to the existing but not reachable from
9975 EXPECT_NE(Parm
->getDefaultArgStorage().getInheritedFrom(),
9976 ToFDef
->getTemplateParameters()->getParam(0));
9979 TEST_P(ImportTemplateParmDeclDefaultValue
, DefValImportError
) {
9980 const char *ToCode
=
9986 getToTuDecl(ToCode
, Lang_CXX14
);
9988 const char *FromCode
=
9992 template <typename P = X>
9999 TranslationUnitDecl
*FromTU
= getTuDecl(FromCode
, Lang_CXX14
);
10000 auto *FromF
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
10001 FromTU
, functionTemplateDecl(hasName("f")));
10003 auto *ToFImported
= Import(FromF
, Lang_CXX14
);
10004 EXPECT_FALSE(ToFImported
);
10007 TEST_P(ImportTemplateParmDeclDefaultValue
, ImportFunctionTemplate
) {
10008 TranslationUnitDecl
*FromTU
= getTuDecl(CodeFunction
, Lang_CXX14
);
10009 auto *D3
= LastDeclMatcher
<FunctionTemplateDecl
>().match(
10010 FromTU
, functionTemplateDecl(hasName("test") /*, hasBody(stmt())*/));
10011 auto *D2
= dyn_cast
<FunctionTemplateDecl
>(D3
->getPreviousDecl());
10012 auto *D1
= dyn_cast
<FunctionTemplateDecl
>(D2
->getPreviousDecl());
10013 testImport(D1
, D2
, D3
, nullptr);
10016 TEST_P(ImportTemplateParmDeclDefaultValue
, ImportExistingFunctionTemplate
) {
10017 TranslationUnitDecl
*ToTU
= getToTuDecl(CodeFunction
, Lang_CXX14
);
10018 auto *ToD1
= FirstDeclMatcher
<FunctionTemplateDecl
>().match(
10019 ToTU
, functionTemplateDecl(hasName("test")));
10020 TranslationUnitDecl
*FromTU
= getTuDecl(CodeFunction
, Lang_CXX14
);
10021 auto *D3
= LastDeclMatcher
<FunctionTemplateDecl
>().match(
10022 FromTU
, functionTemplateDecl(hasName("test")));
10023 auto *D2
= dyn_cast
<FunctionTemplateDecl
>(D3
->getPreviousDecl());
10024 auto *D1
= dyn_cast
<FunctionTemplateDecl
>(D2
->getPreviousDecl());
10025 testImport(D1
, D2
, D3
, ToD1
);
10028 TEST_P(ImportTemplateParmDeclDefaultValue
, ImportClassTemplate
) {
10029 TranslationUnitDecl
*FromTU
= getTuDecl(CodeClass
, Lang_CXX14
);
10030 auto *D3
= LastDeclMatcher
<ClassTemplateDecl
>().match(
10031 FromTU
, classTemplateDecl(hasName("test")));
10032 auto *D2
= dyn_cast
<ClassTemplateDecl
>(D3
->getPreviousDecl());
10033 auto *D1
= dyn_cast
<ClassTemplateDecl
>(D2
->getPreviousDecl());
10034 testImport(D1
, D2
, D3
, nullptr);
10037 TEST_P(ImportTemplateParmDeclDefaultValue
, ImportExistingClassTemplate
) {
10038 TranslationUnitDecl
*ToTU
= getToTuDecl(CodeClass
, Lang_CXX14
);
10039 auto *ToD1
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
10040 ToTU
, classTemplateDecl(hasName("test")));
10041 TranslationUnitDecl
*FromTU
= getTuDecl(CodeClass
, Lang_CXX14
);
10042 auto *D3
= LastDeclMatcher
<ClassTemplateDecl
>().match(
10043 FromTU
, classTemplateDecl(hasName("test")));
10044 auto *D2
= dyn_cast
<ClassTemplateDecl
>(D3
->getPreviousDecl());
10045 auto *D1
= dyn_cast
<ClassTemplateDecl
>(D2
->getPreviousDecl());
10046 testImport(D1
, D2
, D3
, ToD1
);
10049 TEST_P(ImportTemplateParmDeclDefaultValue
, ImportVarTemplate
) {
10050 TranslationUnitDecl
*FromTU
= getTuDecl(CodeVar
, Lang_CXX14
);
10051 auto *D3
= LastDeclMatcher
<VarTemplateDecl
>().match(
10052 FromTU
, varTemplateDecl(hasName("test")));
10053 auto *D2
= dyn_cast
<VarTemplateDecl
>(D3
->getPreviousDecl());
10054 auto *D1
= dyn_cast
<VarTemplateDecl
>(D2
->getPreviousDecl());
10055 testImport(D1
, D2
, D3
, nullptr);
10058 TEST_P(ImportTemplateParmDeclDefaultValue
, ImportExistingVarTemplate
) {
10059 TranslationUnitDecl
*ToTU
= getToTuDecl(CodeVar
, Lang_CXX14
);
10060 auto *ToD1
= FirstDeclMatcher
<VarTemplateDecl
>().match(
10061 ToTU
, varTemplateDecl(hasName("test")));
10062 TranslationUnitDecl
*FromTU
= getTuDecl(CodeVar
, Lang_CXX14
);
10063 auto *D3
= LastDeclMatcher
<VarTemplateDecl
>().match(
10064 FromTU
, varTemplateDecl(hasName("test")));
10065 auto *D2
= dyn_cast
<VarTemplateDecl
>(D3
->getPreviousDecl());
10066 auto *D1
= dyn_cast
<VarTemplateDecl
>(D2
->getPreviousDecl());
10067 testImport(D1
, D2
, D3
, ToD1
);
10070 TEST_P(ImportTemplateParmDeclDefaultValue
,
10071 NonTypeTemplateParmDeclCircularDependency
) {
10078 static const int x = 1;
10081 template <int P1 = Y::x>
10086 static const int A = 1;
10091 void f(int A = X<P>::A);
10095 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX14
);
10096 auto *FromD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
10097 FromTU
, classTemplateDecl(hasName("X")));
10098 auto *FromDInherited
= LastDeclMatcher
<ClassTemplateDecl
>().match(
10099 FromTU
, classTemplateDecl(hasName("X")));
10101 testTemplateParmDeclCircularDependency
<NonTypeTemplateParmDecl
>(
10102 FromD
, FromDInherited
);
10105 TEST_P(ImportTemplateParmDeclDefaultValue
,
10106 TemplateTypeParmDeclCircularDependency
) {
10115 template <typename T1 = Y>
10118 template <typename T2>
10120 static const int A = 1;
10124 template<typename T>
10125 void f(int A = X<T>::A);
10129 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX14
);
10130 auto *FromD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
10131 FromTU
, classTemplateDecl(hasName("X")));
10132 auto *FromDInherited
= LastDeclMatcher
<ClassTemplateDecl
>().match(
10133 FromTU
, classTemplateDecl(hasName("X")));
10135 testTemplateParmDeclCircularDependency
<TemplateTypeParmDecl
>(FromD
,
10139 TEST_P(ImportTemplateParmDeclDefaultValue
,
10140 TemplateTemplateParmDeclCircularDependency
) {
10150 template <template <int> class T1 = Y>
10153 template <template <int> class T2>
10155 static const int A = 1;
10159 template <template <int> class T>
10160 void f(int A = X<T>::A);
10164 Decl
*FromTU
= getTuDecl(Code
, Lang_CXX14
);
10165 auto *FromD
= FirstDeclMatcher
<ClassTemplateDecl
>().match(
10166 FromTU
, classTemplateDecl(hasName("X")));
10167 auto *FromDInherited
= LastDeclMatcher
<ClassTemplateDecl
>().match(
10168 FromTU
, classTemplateDecl(hasName("X")));
10170 testTemplateParmDeclCircularDependency
<TemplateTemplateParmDecl
>(
10171 FromD
, FromDInherited
);
10174 TEST_P(ASTImporterOptionSpecificTestBase
,
10175 ExistingUndeclaredImportDeclaredFriend
) {
10176 Decl
*ToTU
= getToTuDecl(
10178 template <class A, A>
10183 template <class A1, A1>
10188 Decl
*FromTU
= getTuDecl(
10190 template <class A, A>
10195 template <class A1, A1>
10203 auto *ToFr1
= FirstDeclMatcher
<FriendDecl
>().match(ToTU
, friendDecl());
10204 auto *ToFrD1
= ToFr1
->getFriendDecl();
10206 auto *FromFr1
= FirstDeclMatcher
<FriendDecl
>().match(FromTU
, friendDecl());
10207 auto *FromFr2
= LastDeclMatcher
<FriendDecl
>().match(FromTU
, friendDecl());
10209 auto *FromFrD1
= FromFr1
->getFriendDecl();
10210 auto *FromFrD2
= FromFr2
->getFriendDecl();
10212 auto *Ctx1
= cast
<Decl
>(FromFrD1
->getDeclContext());
10213 auto *Ctx2
= cast
<Decl
>(FromFrD2
->getDeclContext());
10215 ASSERT_EQ(Ctx1
, Ctx2
);
10216 ASSERT_EQ(ToFrD1
->getTemplateDepth(), 1u);
10217 ASSERT_EQ(FromFrD2
->getTemplateDepth(), 0u);
10218 ASSERT_EQ(ToFrD1
->getFriendObjectKind(), Decl::FOK_Undeclared
);
10219 ASSERT_EQ(FromFrD2
->getFriendObjectKind(), Decl::FOK_Declared
);
10221 auto *ToFr2Imp
= Import(FromFr2
, Lang_CXX11
);
10223 EXPECT_TRUE(ToFr2Imp
);
10226 TEST_P(ASTImporterOptionSpecificTestBase
,
10227 ExistingDeclaredImportUndeclaredFriend
) {
10228 Decl
*ToTU
= getToTuDecl(
10230 template <class A, A>
10235 template <class A1, A1>
10242 Decl
*FromTU
= getTuDecl(
10244 template <class A, A>
10249 template <class A1, A1>
10255 auto *ToFr1
= FirstDeclMatcher
<FriendDecl
>().match(ToTU
, friendDecl());
10256 auto *ToFr2
= LastDeclMatcher
<FriendDecl
>().match(ToTU
, friendDecl());
10258 auto *ToFrD1
= ToFr1
->getFriendDecl();
10259 auto *ToFrD2
= ToFr2
->getFriendDecl();
10261 auto *FromFr1
= FirstDeclMatcher
<FriendDecl
>().match(FromTU
, friendDecl());
10262 auto *FromFrD1
= FromFr1
->getFriendDecl();
10264 auto *Ctx1
= cast
<Decl
>(ToFrD1
->getDeclContext());
10265 auto *Ctx2
= cast
<Decl
>(ToFrD2
->getDeclContext());
10267 ASSERT_EQ(Ctx1
, Ctx2
);
10268 ASSERT_EQ(FromFrD1
->getTemplateDepth(), 1u);
10269 ASSERT_EQ(ToFrD2
->getTemplateDepth(), 0u);
10270 ASSERT_EQ(FromFrD1
->getFriendObjectKind(), Decl::FOK_Undeclared
);
10271 ASSERT_EQ(ToFrD2
->getFriendObjectKind(), Decl::FOK_Declared
);
10273 auto *ToFr1Imp
= Import(FromFr1
, Lang_CXX11
);
10275 EXPECT_TRUE(ToFr1Imp
);
10276 EXPECT_EQ(ToFr1Imp
, ToFr1
);
10279 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ASTImporterLookupTableTest
,
10280 DefaultTestValuesForRunOptions
);
10282 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportPath
,
10283 ::testing::Values(std::vector
<std::string
>()));
10285 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportExpr
,
10286 DefaultTestValuesForRunOptions
);
10288 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportFixedPointExpr
,
10289 ExtendWithOptions(DefaultTestArrayForRunOptions
,
10290 std::vector
<std::string
>{
10291 "-ffixed-point"}));
10293 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportBlock
,
10294 ExtendWithOptions(DefaultTestArrayForRunOptions
,
10295 std::vector
<std::string
>{
10298 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportType
,
10299 DefaultTestValuesForRunOptions
);
10301 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportDecl
,
10302 DefaultTestValuesForRunOptions
);
10304 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ASTImporterOptionSpecificTestBase
,
10305 DefaultTestValuesForRunOptions
);
10307 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ErrorHandlingTest
,
10308 DefaultTestValuesForRunOptions
);
10310 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, RedirectingImporterTest
,
10311 DefaultTestValuesForRunOptions
);
10313 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportFunctions
,
10314 DefaultTestValuesForRunOptions
);
10316 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportAutoFunctions
,
10317 DefaultTestValuesForRunOptions
);
10319 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportFunctionTemplates
,
10320 DefaultTestValuesForRunOptions
);
10322 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportFriendFunctionTemplates
,
10323 DefaultTestValuesForRunOptions
);
10325 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportClasses
,
10326 DefaultTestValuesForRunOptions
);
10328 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportFriendFunctions
,
10329 DefaultTestValuesForRunOptions
);
10331 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportFriendClasses
,
10332 DefaultTestValuesForRunOptions
);
10334 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
,
10335 ImportFunctionTemplateSpecializations
,
10336 DefaultTestValuesForRunOptions
);
10338 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportImplicitMethods
,
10339 DefaultTestValuesForRunOptions
);
10341 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportVariables
,
10342 DefaultTestValuesForRunOptions
);
10344 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, LLDBLookupTest
,
10345 DefaultTestValuesForRunOptions
);
10347 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportSourceLocations
,
10348 DefaultTestValuesForRunOptions
);
10350 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportWithExternalSource
,
10351 DefaultTestValuesForRunOptions
);
10353 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportAttributes
,
10354 DefaultTestValuesForRunOptions
);
10356 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportInjectedClassNameType
,
10357 DefaultTestValuesForRunOptions
);
10359 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportMatrixType
,
10360 DefaultTestValuesForRunOptions
);
10362 INSTANTIATE_TEST_SUITE_P(ParameterizedTests
, ImportTemplateParmDeclDefaultValue
,
10363 DefaultTestValuesForRunOptions
);
10365 // FIXME: Make ImportOpenCLPipe test work.
10366 // INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportOpenCLPipe,
10367 // DefaultTestValuesForRunOptions);
10368 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImportOpenCLPipe
);
10370 } // end namespace ast_matchers
10371 } // end namespace clang