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