1 //===- unittest/AST/ASTImporterTest.cpp - AST node import test ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Tests for the correct import of AST nodes from one AST context to another.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/ASTMatchers/ASTMatchers.h"
14 #include "llvm/ADT/StringMap.h"
15 #include "llvm/Support/SmallVectorMemoryBuffer.h"
16
17 #include "clang/AST/DeclContextInternals.h"
18 #include "gtest/gtest.h"
19
20 #include "ASTImporterFixtures.h"
21
22 namespace clang {
23 namespace ast_matchers {
24
25 using internal::Matcher;
26 using internal::BindableMatcher;
27 using llvm::StringMap;
28
getRecordDeclOfFriend(FriendDecl * FD)29 static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) {
30 QualType Ty = FD->getFriendType()->getType().getCanonicalType();
31 return cast<RecordType>(Ty)->getDecl();
32 }
33
34 struct ImportExpr : TestImportBase {};
35 struct ImportType : TestImportBase {};
36 struct ImportDecl : TestImportBase {};
37 struct ImportFixedPointExpr : ImportExpr {};
38
39 struct CanonicalRedeclChain : ASTImporterOptionSpecificTestBase {};
40
TEST_P(CanonicalRedeclChain,ShouldBeConsequentWithMatchers)41 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers) {
42 Decl *FromTU = getTuDecl("void f();", Lang_CXX03);
43 auto Pattern = functionDecl(hasName("f"));
44 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
45
46 auto Redecls = getCanonicalForwardRedeclChain(D0);
47 ASSERT_EQ(Redecls.size(), 1u);
48 EXPECT_EQ(D0, Redecls[0]);
49 }
50
TEST_P(CanonicalRedeclChain,ShouldBeConsequentWithMatchers2)51 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers2) {
52 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
53 auto Pattern = functionDecl(hasName("f"));
54 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
55 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
56 FunctionDecl *D1 = D2->getPreviousDecl();
57
58 auto Redecls = getCanonicalForwardRedeclChain(D0);
59 ASSERT_EQ(Redecls.size(), 3u);
60 EXPECT_EQ(D0, Redecls[0]);
61 EXPECT_EQ(D1, Redecls[1]);
62 EXPECT_EQ(D2, Redecls[2]);
63 }
64
TEST_P(CanonicalRedeclChain,ShouldBeSameForAllDeclInTheChain)65 TEST_P(CanonicalRedeclChain, ShouldBeSameForAllDeclInTheChain) {
66 Decl *FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
67 auto Pattern = functionDecl(hasName("f"));
68 auto *D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
69 auto *D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
70 FunctionDecl *D1 = D2->getPreviousDecl();
71
72 auto RedeclsD0 = getCanonicalForwardRedeclChain(D0);
73 auto RedeclsD1 = getCanonicalForwardRedeclChain(D1);
74 auto RedeclsD2 = getCanonicalForwardRedeclChain(D2);
75
76 EXPECT_THAT(RedeclsD0, ::testing::ContainerEq(RedeclsD1));
77 EXPECT_THAT(RedeclsD1, ::testing::ContainerEq(RedeclsD2));
78 }
79
80 namespace {
81 struct RedirectingImporter : public ASTImporter {
82 using ASTImporter::ASTImporter;
83
84 protected:
ImportImplclang::ast_matchers::__anon0ba290970111::RedirectingImporter85 llvm::Expected<Decl *> ImportImpl(Decl *FromD) override {
86 auto *ND = dyn_cast<NamedDecl>(FromD);
87 if (!ND || ND->getName() != "shouldNotBeImported")
88 return ASTImporter::ImportImpl(FromD);
89 for (Decl *D : getToContext().getTranslationUnitDecl()->decls()) {
90 if (auto *ND = dyn_cast<NamedDecl>(D))
91 if (ND->getName() == "realDecl") {
92 RegisterImportedDecl(FromD, ND);
93 return ND;
94 }
95 }
96 return ASTImporter::ImportImpl(FromD);
97 }
98 };
99
100 } // namespace
101
102 struct RedirectingImporterTest : ASTImporterOptionSpecificTestBase {
RedirectingImporterTestclang::ast_matchers::RedirectingImporterTest103 RedirectingImporterTest() {
104 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
105 ASTContext &FromContext, FileManager &FromFileManager,
106 bool MinimalImport,
107 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
108 return new RedirectingImporter(ToContext, ToFileManager, FromContext,
109 FromFileManager, MinimalImport,
110 SharedState);
111 };
112 }
113 };
114
115 // Test that an ASTImporter subclass can intercept an import call.
TEST_P(RedirectingImporterTest,InterceptImport)116 TEST_P(RedirectingImporterTest, InterceptImport) {
117 Decl *From, *To;
118 std::tie(From, To) =
119 getImportedDecl("class shouldNotBeImported {};", Lang_CXX03,
120 "class realDecl {};", Lang_CXX03, "shouldNotBeImported");
121 auto *Imported = cast<CXXRecordDecl>(To);
122 EXPECT_EQ(Imported->getQualifiedNameAsString(), "realDecl");
123
124 // Make sure our importer prevented the importing of the decl.
125 auto *ToTU = Imported->getTranslationUnitDecl();
126 auto Pattern = functionDecl(hasName("shouldNotBeImported"));
127 unsigned count =
128 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
129 EXPECT_EQ(0U, count);
130 }
131
132 // Test that when we indirectly import a declaration the custom ASTImporter
133 // is still intercepting the import.
TEST_P(RedirectingImporterTest,InterceptIndirectImport)134 TEST_P(RedirectingImporterTest, InterceptIndirectImport) {
135 Decl *From, *To;
136 std::tie(From, To) =
137 getImportedDecl("class shouldNotBeImported {};"
138 "class F { shouldNotBeImported f; };",
139 Lang_CXX03, "class realDecl {};", Lang_CXX03, "F");
140
141 // Make sure our ASTImporter prevented the importing of the decl.
142 auto *ToTU = To->getTranslationUnitDecl();
143 auto Pattern = functionDecl(hasName("shouldNotBeImported"));
144 unsigned count =
145 DeclCounterWithPredicate<CXXRecordDecl>().match(ToTU, Pattern);
146 EXPECT_EQ(0U, count);
147 }
148
149 struct ImportPath : ASTImporterOptionSpecificTestBase {
150 Decl *FromTU;
151 FunctionDecl *D0, *D1, *D2;
ImportPathclang::ast_matchers::ImportPath152 ImportPath() {
153 FromTU = getTuDecl("void f(); void f(); void f();", Lang_CXX03);
154 auto Pattern = functionDecl(hasName("f"));
155 D0 = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
156 D2 = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
157 D1 = D2->getPreviousDecl();
158 }
159 };
160
TEST_P(ImportPath,Push)161 TEST_P(ImportPath, Push) {
162 ASTImporter::ImportPathTy path;
163 path.push(D0);
164 EXPECT_FALSE(path.hasCycleAtBack());
165 }
166
TEST_P(ImportPath,SmallCycle)167 TEST_P(ImportPath, SmallCycle) {
168 ASTImporter::ImportPathTy path;
169 path.push(D0);
170 path.push(D0);
171 EXPECT_TRUE(path.hasCycleAtBack());
172 path.pop();
173 EXPECT_FALSE(path.hasCycleAtBack());
174 path.push(D0);
175 EXPECT_TRUE(path.hasCycleAtBack());
176 }
177
TEST_P(ImportPath,GetSmallCycle)178 TEST_P(ImportPath, GetSmallCycle) {
179 ASTImporter::ImportPathTy path;
180 path.push(D0);
181 path.push(D0);
182 EXPECT_TRUE(path.hasCycleAtBack());
183 std::array<Decl* ,2> Res;
184 int i = 0;
185 for (Decl *Di : path.getCycleAtBack()) {
186 Res[i++] = Di;
187 }
188 ASSERT_EQ(i, 2);
189 EXPECT_EQ(Res[0], D0);
190 EXPECT_EQ(Res[1], D0);
191 }
192
TEST_P(ImportPath,GetCycle)193 TEST_P(ImportPath, GetCycle) {
194 ASTImporter::ImportPathTy path;
195 path.push(D0);
196 path.push(D1);
197 path.push(D2);
198 path.push(D0);
199 EXPECT_TRUE(path.hasCycleAtBack());
200 std::array<Decl* ,4> Res;
201 int i = 0;
202 for (Decl *Di : path.getCycleAtBack()) {
203 Res[i++] = Di;
204 }
205 ASSERT_EQ(i, 4);
206 EXPECT_EQ(Res[0], D0);
207 EXPECT_EQ(Res[1], D2);
208 EXPECT_EQ(Res[2], D1);
209 EXPECT_EQ(Res[3], D0);
210 }
211
TEST_P(ImportPath,CycleAfterCycle)212 TEST_P(ImportPath, CycleAfterCycle) {
213 ASTImporter::ImportPathTy path;
214 path.push(D0);
215 path.push(D1);
216 path.push(D0);
217 path.push(D1);
218 path.push(D2);
219 path.push(D0);
220 EXPECT_TRUE(path.hasCycleAtBack());
221 std::array<Decl* ,4> Res;
222 int i = 0;
223 for (Decl *Di : path.getCycleAtBack()) {
224 Res[i++] = Di;
225 }
226 ASSERT_EQ(i, 4);
227 EXPECT_EQ(Res[0], D0);
228 EXPECT_EQ(Res[1], D2);
229 EXPECT_EQ(Res[2], D1);
230 EXPECT_EQ(Res[3], D0);
231
232 path.pop();
233 path.pop();
234 path.pop();
235 EXPECT_TRUE(path.hasCycleAtBack());
236 i = 0;
237 for (Decl *Di : path.getCycleAtBack()) {
238 Res[i++] = Di;
239 }
240 ASSERT_EQ(i, 3);
241 EXPECT_EQ(Res[0], D0);
242 EXPECT_EQ(Res[1], D1);
243 EXPECT_EQ(Res[2], D0);
244
245 path.pop();
246 EXPECT_FALSE(path.hasCycleAtBack());
247 }
248
249 const internal::VariadicDynCastAllOfMatcher<Stmt, SourceLocExpr> sourceLocExpr;
250
AST_MATCHER_P(SourceLocExpr,hasBuiltinStr,StringRef,Str)251 AST_MATCHER_P(SourceLocExpr, hasBuiltinStr, StringRef, Str) {
252 return Node.getBuiltinStr() == Str;
253 }
254
TEST_P(ImportExpr,ImportSourceLocExpr)255 TEST_P(ImportExpr, ImportSourceLocExpr) {
256 MatchVerifier<Decl> Verifier;
257 testImport("void declToImport() { (void)__builtin_FILE(); }", Lang_CXX03, "",
258 Lang_CXX03, Verifier,
259 functionDecl(hasDescendant(
260 sourceLocExpr(hasBuiltinStr("__builtin_FILE")))));
261 testImport("void declToImport() { (void)__builtin_COLUMN(); }", Lang_CXX03,
262 "", Lang_CXX03, Verifier,
263 functionDecl(hasDescendant(
264 sourceLocExpr(hasBuiltinStr("__builtin_COLUMN")))));
265 }
266
TEST_P(ImportExpr,ImportStringLiteral)267 TEST_P(ImportExpr, ImportStringLiteral) {
268 MatchVerifier<Decl> Verifier;
269 testImport("void declToImport() { (void)\"foo\"; }", Lang_CXX03, "",
270 Lang_CXX03, Verifier,
271 functionDecl(hasDescendant(
272 stringLiteral(hasType(asString("const char[4]"))))));
273 testImport("void declToImport() { (void)L\"foo\"; }", Lang_CXX03, "",
274 Lang_CXX03, Verifier,
275 functionDecl(hasDescendant(
276 stringLiteral(hasType(asString("const wchar_t[4]"))))));
277 testImport("void declToImport() { (void) \"foo\" \"bar\"; }", Lang_CXX03, "",
278 Lang_CXX03, Verifier,
279 functionDecl(hasDescendant(
280 stringLiteral(hasType(asString("const char[7]"))))));
281 }
282
TEST_P(ImportExpr,ImportChooseExpr)283 TEST_P(ImportExpr, ImportChooseExpr) {
284 MatchVerifier<Decl> Verifier;
285
286 // This case tests C code that is not condition-dependent and has a true
287 // condition.
288 testImport("void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }",
289 Lang_C99, "", Lang_C99, Verifier,
290 functionDecl(hasDescendant(chooseExpr())));
291 }
292
293 const internal::VariadicDynCastAllOfMatcher<Stmt, ShuffleVectorExpr>
294 shuffleVectorExpr;
295
TEST_P(ImportExpr,ImportShuffleVectorExpr)296 TEST_P(ImportExpr, ImportShuffleVectorExpr) {
297 MatchVerifier<Decl> Verifier;
298 constexpr auto Code = R"code(
299 typedef double vector4double __attribute__((__vector_size__(32)));
300 vector4double declToImport(vector4double a, vector4double b) {
301 return __builtin_shufflevector(a, b, 0, 1, 2, 3);
302 }
303 )code";
304 const auto Pattern = functionDecl(hasDescendant(shuffleVectorExpr(
305 allOf(has(declRefExpr(to(parmVarDecl(hasName("a"))))),
306 has(declRefExpr(to(parmVarDecl(hasName("b"))))),
307 has(integerLiteral(equals(0))), has(integerLiteral(equals(1))),
308 has(integerLiteral(equals(2))), has(integerLiteral(equals(3)))))));
309 testImport(Code, Lang_C99, "", Lang_C99, Verifier, Pattern);
310 }
311
TEST_P(ImportExpr,ImportGNUNullExpr)312 TEST_P(ImportExpr, ImportGNUNullExpr) {
313 MatchVerifier<Decl> Verifier;
314 testImport("void declToImport() { (void)__null; }", Lang_CXX03, "",
315 Lang_CXX03, Verifier,
316 functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger())))));
317 }
318
TEST_P(ImportExpr,ImportGenericSelectionExpr)319 TEST_P(ImportExpr, ImportGenericSelectionExpr) {
320 MatchVerifier<Decl> Verifier;
321
322 testImport(
323 "void declToImport() { int x; (void)_Generic(x, int: 0, float: 1); }",
324 Lang_C99, "", Lang_C99, Verifier,
325 functionDecl(hasDescendant(genericSelectionExpr())));
326 }
327
TEST_P(ImportExpr,ImportCXXNullPtrLiteralExpr)328 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) {
329 MatchVerifier<Decl> Verifier;
330 testImport(
331 "void declToImport() { (void)nullptr; }",
332 Lang_CXX11, "", Lang_CXX11, Verifier,
333 functionDecl(hasDescendant(cxxNullPtrLiteralExpr())));
334 }
335
336
TEST_P(ImportExpr,ImportFloatinglLiteralExpr)337 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) {
338 MatchVerifier<Decl> Verifier;
339 testImport("void declToImport() { (void)1.0; }", Lang_C99, "", Lang_C99,
340 Verifier,
341 functionDecl(hasDescendant(
342 floatLiteral(equals(1.0), hasType(asString("double"))))));
343 testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99, "", Lang_C99,
344 Verifier,
345 functionDecl(hasDescendant(
346 floatLiteral(equals(1.0e-5f), hasType(asString("float"))))));
347 }
348
TEST_P(ImportFixedPointExpr,ImportFixedPointerLiteralExpr)349 TEST_P(ImportFixedPointExpr, ImportFixedPointerLiteralExpr) {
350 MatchVerifier<Decl> Verifier;
351 testImport("void declToImport() { (void)1.0k; }", Lang_C99, "", Lang_C99,
352 Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
353 testImport("void declToImport() { (void)0.75r; }", Lang_C99, "", Lang_C99,
354 Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
355 }
356
TEST_P(ImportExpr,ImportImaginaryLiteralExpr)357 TEST_P(ImportExpr, ImportImaginaryLiteralExpr) {
358 MatchVerifier<Decl> Verifier;
359 testImport(
360 "void declToImport() { (void)1.0i; }",
361 Lang_CXX14, "", Lang_CXX14, Verifier,
362 functionDecl(hasDescendant(imaginaryLiteral())));
363 }
364
TEST_P(ImportExpr,ImportCompoundLiteralExpr)365 TEST_P(ImportExpr, ImportCompoundLiteralExpr) {
366 MatchVerifier<Decl> Verifier;
367 testImport("void declToImport() {"
368 " struct s { int x; long y; unsigned z; }; "
369 " (void)(struct s){ 42, 0L, 1U }; }",
370 Lang_CXX03, "", Lang_CXX03, Verifier,
371 functionDecl(hasDescendant(compoundLiteralExpr(
372 hasType(asString("struct s")),
373 has(initListExpr(
374 hasType(asString("struct s")),
375 has(integerLiteral(equals(42), hasType(asString("int")))),
376 has(integerLiteral(equals(0), hasType(asString("long")))),
377 has(integerLiteral(
378 equals(1), hasType(asString("unsigned int"))))))))));
379 }
380
TEST_P(ImportExpr,ImportCXXThisExpr)381 TEST_P(ImportExpr, ImportCXXThisExpr) {
382 MatchVerifier<Decl> Verifier;
383 testImport("class declToImport { void f() { (void)this; } };", Lang_CXX03, "",
384 Lang_CXX03, Verifier,
385 cxxRecordDecl(hasMethod(hasDescendant(
386 cxxThisExpr(hasType(asString("class declToImport *")))))));
387 }
388
TEST_P(ImportExpr,ImportAtomicExpr)389 TEST_P(ImportExpr, ImportAtomicExpr) {
390 MatchVerifier<Decl> Verifier;
391 testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }",
392 Lang_C99, "", Lang_C99, Verifier,
393 functionDecl(hasDescendant(atomicExpr(
394 has(ignoringParenImpCasts(
395 declRefExpr(hasDeclaration(varDecl(hasName("ptr"))),
396 hasType(asString("int *"))))),
397 has(integerLiteral(equals(1), hasType(asString("int"))))))));
398 }
399
TEST_P(ImportExpr,ImportLabelDeclAndAddrLabelExpr)400 TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) {
401 MatchVerifier<Decl> Verifier;
402 testImport("void declToImport() { loop: goto loop; (void)&&loop; }", Lang_C99,
403 "", Lang_C99, Verifier,
404 functionDecl(hasDescendant(labelStmt(
405 hasDeclaration(labelDecl(hasName("loop"))))),
406 hasDescendant(addrLabelExpr(
407 hasDeclaration(labelDecl(hasName("loop")))))));
408 }
409
AST_MATCHER_P(TemplateDecl,hasTemplateDecl,internal::Matcher<NamedDecl>,InnerMatcher)410 AST_MATCHER_P(TemplateDecl, hasTemplateDecl,
411 internal::Matcher<NamedDecl>, InnerMatcher) {
412 const NamedDecl *Template = Node.getTemplatedDecl();
413 return Template && InnerMatcher.matches(*Template, Finder, Builder);
414 }
415
TEST_P(ImportExpr,ImportParenListExpr)416 TEST_P(ImportExpr, ImportParenListExpr) {
417 MatchVerifier<Decl> Verifier;
418 testImport(
419 "template<typename T> class dummy { void f() { dummy X(*this); } };"
420 "typedef dummy<int> declToImport;"
421 "template class dummy<int>;",
422 Lang_CXX03, "", Lang_CXX03, Verifier,
423 typedefDecl(hasType(templateSpecializationType(
424 hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate(
425 classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(allOf(
426 hasName("f"),
427 hasBody(compoundStmt(has(declStmt(hasSingleDecl(
428 varDecl(hasInitializer(parenListExpr(has(unaryOperator(
429 hasOperatorName("*"),
430 hasUnaryOperand(cxxThisExpr())))))))))))))))))))))));
431 }
432
TEST_P(ImportExpr,ImportSwitch)433 TEST_P(ImportExpr, ImportSwitch) {
434 MatchVerifier<Decl> Verifier;
435 testImport("void declToImport() { int b; switch (b) { case 1: break; } }",
436 Lang_C99, "", Lang_C99, Verifier,
437 functionDecl(hasDescendant(
438 switchStmt(has(compoundStmt(has(caseStmt())))))));
439 }
440
TEST_P(ImportExpr,ImportStmtExpr)441 TEST_P(ImportExpr, ImportStmtExpr) {
442 MatchVerifier<Decl> Verifier;
443 testImport(
444 "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
445 Lang_C99, "", Lang_C99, Verifier,
446 traverse(TK_AsIs,
447 functionDecl(hasDescendant(varDecl(
448 hasName("C"), hasType(asString("int")),
449 hasInitializer(stmtExpr(
450 hasAnySubstatement(declStmt(hasSingleDecl(varDecl(
451 hasName("X"), hasType(asString("int")),
452 hasInitializer(integerLiteral(equals(4))))))),
453 hasDescendant(implicitCastExpr()))))))));
454 }
455
TEST_P(ImportExpr,ImportConditionalOperator)456 TEST_P(ImportExpr, ImportConditionalOperator) {
457 MatchVerifier<Decl> Verifier;
458 testImport("void declToImport() { (void)(true ? 1 : -5); }", Lang_CXX03, "",
459 Lang_CXX03, Verifier,
460 functionDecl(hasDescendant(conditionalOperator(
461 hasCondition(cxxBoolLiteral(equals(true))),
462 hasTrueExpression(integerLiteral(equals(1))),
463 hasFalseExpression(unaryOperator(
464 hasUnaryOperand(integerLiteral(equals(5)))))))));
465 }
466
TEST_P(ImportExpr,ImportBinaryConditionalOperator)467 TEST_P(ImportExpr, ImportBinaryConditionalOperator) {
468 MatchVerifier<Decl> Verifier;
469 testImport(
470 "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03, "", Lang_CXX03,
471 Verifier,
472 traverse(TK_AsIs,
473 functionDecl(hasDescendant(binaryConditionalOperator(
474 hasCondition(implicitCastExpr(
475 hasSourceExpression(opaqueValueExpr(
476 hasSourceExpression(integerLiteral(equals(1))))),
477 hasType(booleanType()))),
478 hasTrueExpression(opaqueValueExpr(
479 hasSourceExpression(integerLiteral(equals(1))))),
480 hasFalseExpression(unaryOperator(
481 hasOperatorName("-"),
482 hasUnaryOperand(integerLiteral(equals(5))))))))));
483 }
484
TEST_P(ImportExpr,ImportDesignatedInitExpr)485 TEST_P(ImportExpr, ImportDesignatedInitExpr) {
486 MatchVerifier<Decl> Verifier;
487 testImport(
488 "void declToImport() {"
489 " struct point { double x; double y; };"
490 " struct point ptarray[10] = "
491 "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }",
492 Lang_C99, "", Lang_C99, Verifier,
493 functionDecl(hasDescendant(initListExpr(
494 has(designatedInitExpr(designatorCountIs(2),
495 hasDescendant(floatLiteral(equals(1.0))),
496 hasDescendant(integerLiteral(equals(2))))),
497 has(designatedInitExpr(designatorCountIs(2),
498 hasDescendant(floatLiteral(equals(2.0))),
499 hasDescendant(integerLiteral(equals(2))))),
500 has(designatedInitExpr(designatorCountIs(2),
501 hasDescendant(floatLiteral(equals(1.0))),
502 hasDescendant(integerLiteral(equals(0)))))))));
503 }
504
TEST_P(ImportExpr,ImportPredefinedExpr)505 TEST_P(ImportExpr, ImportPredefinedExpr) {
506 MatchVerifier<Decl> Verifier;
507 // __func__ expands as StringLiteral("declToImport")
508 testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "",
509 Lang_CXX03, Verifier,
510 functionDecl(hasDescendant(predefinedExpr(
511 hasType(asString("const char[13]")),
512 has(stringLiteral(hasType(asString("const char[13]"))))))));
513 }
514
TEST_P(ImportExpr,ImportInitListExpr)515 TEST_P(ImportExpr, ImportInitListExpr) {
516 MatchVerifier<Decl> Verifier;
517 testImport(
518 "void declToImport() {"
519 " struct point { double x; double y; };"
520 " point ptarray[10] = { [2].y = 1.0, [2].x = 2.0,"
521 " [0].x = 1.0 }; }",
522 Lang_CXX03, "", Lang_CXX03, Verifier,
523 functionDecl(hasDescendant(initListExpr(
524 has(cxxConstructExpr(requiresZeroInitialization())),
525 has(initListExpr(
526 hasType(asString("struct point")), has(floatLiteral(equals(1.0))),
527 has(implicitValueInitExpr(hasType(asString("double")))))),
528 has(initListExpr(hasType(asString("struct point")),
529 has(floatLiteral(equals(2.0))),
530 has(floatLiteral(equals(1.0)))))))));
531 }
532
533 const internal::VariadicDynCastAllOfMatcher<Expr, CXXDefaultInitExpr>
534 cxxDefaultInitExpr;
535
TEST_P(ImportExpr,ImportCXXDefaultInitExpr)536 TEST_P(ImportExpr, ImportCXXDefaultInitExpr) {
537 MatchVerifier<Decl> Verifier;
538 testImport("class declToImport { int DefInit = 5; }; declToImport X;",
539 Lang_CXX11, "", Lang_CXX11, Verifier,
540 cxxRecordDecl(hasDescendant(cxxConstructorDecl(
541 hasAnyConstructorInitializer(cxxCtorInitializer(
542 withInitializer(cxxDefaultInitExpr())))))));
543 testImport(
544 "struct X { int A = 5; }; X declToImport{};", Lang_CXX17, "", Lang_CXX17,
545 Verifier,
546 varDecl(hasInitializer(initListExpr(hasInit(0, cxxDefaultInitExpr())))));
547 }
548
549 const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr;
550
TEST_P(ImportExpr,ImportVAArgExpr)551 TEST_P(ImportExpr, ImportVAArgExpr) {
552 MatchVerifier<Decl> Verifier;
553 testImport("void declToImport(__builtin_va_list list, ...) {"
554 " (void)__builtin_va_arg(list, int); }",
555 Lang_CXX03, "", Lang_CXX03, Verifier,
556 functionDecl(hasDescendant(
557 cStyleCastExpr(hasSourceExpression(vaArgExpr())))));
558 }
559
TEST_P(ImportExpr,CXXTemporaryObjectExpr)560 TEST_P(ImportExpr, CXXTemporaryObjectExpr) {
561 MatchVerifier<Decl> Verifier;
562 testImport(
563 "struct C {};"
564 "void declToImport() { C c = C(); }",
565 Lang_CXX03, "", Lang_CXX03, Verifier,
566 traverse(TK_AsIs,
567 functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr(
568 has(materializeTemporaryExpr(has(implicitCastExpr(
569 has(cxxTemporaryObjectExpr()))))))))))));
570 }
571
TEST_P(ImportType,ImportAtomicType)572 TEST_P(ImportType, ImportAtomicType) {
573 MatchVerifier<Decl> Verifier;
574 testImport(
575 "void declToImport() { typedef _Atomic(int) a_int; }",
576 Lang_CXX11, "", Lang_CXX11, Verifier,
577 functionDecl(hasDescendant(typedefDecl(has(atomicType())))));
578 }
579
TEST_P(ImportType,ImportUsingType)580 TEST_P(ImportType, ImportUsingType) {
581 MatchVerifier<Decl> Verifier;
582 testImport("struct C {};"
583 "void declToImport() { using ::C; new C{}; }",
584 Lang_CXX11, "", Lang_CXX11, Verifier,
585 functionDecl(hasDescendant(
586 cxxNewExpr(hasType(pointerType(pointee(usingType())))))));
587 }
588
TEST_P(ImportDecl,ImportFunctionTemplateDecl)589 TEST_P(ImportDecl, ImportFunctionTemplateDecl) {
590 MatchVerifier<Decl> Verifier;
591 testImport("template <typename T> void declToImport() { };", Lang_CXX03, "",
592 Lang_CXX03, Verifier, functionTemplateDecl());
593 }
594
TEST_P(ImportExpr,ImportCXXDependentScopeMemberExpr)595 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) {
596 MatchVerifier<Decl> Verifier;
597 testImport("template <typename T> struct C { T t; };"
598 "template <typename T> void declToImport() {"
599 " C<T> d;"
600 " (void)d.t;"
601 "}"
602 "void instantiate() { declToImport<int>(); }",
603 Lang_CXX03, "", Lang_CXX03, Verifier,
604 functionTemplateDecl(hasDescendant(
605 cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
606 testImport("template <typename T> struct C { T t; };"
607 "template <typename T> void declToImport() {"
608 " C<T> d;"
609 " (void)(&d)->t;"
610 "}"
611 "void instantiate() { declToImport<int>(); }",
612 Lang_CXX03, "", Lang_CXX03, Verifier,
613 functionTemplateDecl(hasDescendant(
614 cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
615 }
616
TEST_P(ImportType,ImportTypeAliasTemplate)617 TEST_P(ImportType, ImportTypeAliasTemplate) {
618 MatchVerifier<Decl> Verifier;
619 testImport(
620 "template <int K>"
621 "struct dummy { static const int i = K; };"
622 "template <int K> using dummy2 = dummy<K>;"
623 "int declToImport() { return dummy2<3>::i; }",
624 Lang_CXX11, "", Lang_CXX11, Verifier,
625 traverse(TK_AsIs,
626 functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))),
627 unless(hasAncestor(
628 translationUnitDecl(has(typeAliasDecl())))))));
629 }
630
631 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl>
632 varTemplateSpecializationDecl;
633
TEST_P(ImportDecl,ImportVarTemplate)634 TEST_P(ImportDecl, ImportVarTemplate) {
635 MatchVerifier<Decl> Verifier;
636 testImport(
637 "template <typename T>"
638 "T pi = T(3.1415926535897932385L);"
639 "void declToImport() { (void)pi<int>; }",
640 Lang_CXX14, "", Lang_CXX14, Verifier,
641 functionDecl(
642 hasDescendant(declRefExpr(to(varTemplateSpecializationDecl()))),
643 unless(hasAncestor(translationUnitDecl(has(varDecl(
644 hasName("pi"), unless(varTemplateSpecializationDecl()))))))));
645 }
646
TEST_P(ImportType,ImportPackExpansion)647 TEST_P(ImportType, ImportPackExpansion) {
648 MatchVerifier<Decl> Verifier;
649 testImport("template <typename... Args>"
650 "struct dummy {"
651 " dummy(Args... args) {}"
652 " static const int i = 4;"
653 "};"
654 "int declToImport() { return dummy<int>::i; }",
655 Lang_CXX11, "", Lang_CXX11, Verifier,
656 traverse(TK_AsIs, functionDecl(hasDescendant(returnStmt(has(
657 implicitCastExpr(has(declRefExpr()))))))));
658 }
659
660 const internal::VariadicDynCastAllOfMatcher<Type,
661 DependentTemplateSpecializationType>
662 dependentTemplateSpecializationType;
663
TEST_P(ImportType,ImportDependentTemplateSpecialization)664 TEST_P(ImportType, ImportDependentTemplateSpecialization) {
665 MatchVerifier<Decl> Verifier;
666 testImport("template<typename T>"
667 "struct A;"
668 "template<typename T>"
669 "struct declToImport {"
670 " typename A<T>::template B<T> a;"
671 "};",
672 Lang_CXX03, "", Lang_CXX03, Verifier,
673 classTemplateDecl(has(cxxRecordDecl(has(
674 fieldDecl(hasType(dependentTemplateSpecializationType())))))));
675 }
676
TEST_P(ImportType,ImportDeducedTemplateSpecialization)677 TEST_P(ImportType, ImportDeducedTemplateSpecialization) {
678 MatchVerifier<Decl> Verifier;
679 testImport("template <typename T>"
680 "class C { public: C(T); };"
681 "C declToImport(123);",
682 Lang_CXX17, "", Lang_CXX17, Verifier,
683 varDecl(hasType(deducedTemplateSpecializationType())));
684 }
685
686 const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr>
687 sizeOfPackExpr;
688
TEST_P(ImportExpr,ImportSizeOfPackExpr)689 TEST_P(ImportExpr, ImportSizeOfPackExpr) {
690 MatchVerifier<Decl> Verifier;
691 testImport(
692 "template <typename... Ts>"
693 "void declToImport() {"
694 " const int i = sizeof...(Ts);"
695 "};"
696 "void g() { declToImport<int>(); }",
697 Lang_CXX11, "", Lang_CXX11, Verifier,
698 functionTemplateDecl(hasDescendant(sizeOfPackExpr())));
699 testImport(
700 "template <typename... Ts>"
701 "using X = int[sizeof...(Ts)];"
702 "template <typename... Us>"
703 "struct Y {"
704 " X<Us..., int, double, int, Us...> f;"
705 "};"
706 "Y<float, int> declToImport;",
707 Lang_CXX11, "", Lang_CXX11, Verifier,
708 varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType(
709 hasUnqualifiedDesugaredType(constantArrayType(hasSize(7))))))))));
710 }
711
712 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFoldExpr> cxxFoldExpr;
713
AST_MATCHER_P(CXXFoldExpr,hasOperator,BinaryOperatorKind,Op)714 AST_MATCHER_P(CXXFoldExpr, hasOperator, BinaryOperatorKind, Op) {
715 return Node.getOperator() == Op;
716 }
AST_MATCHER(CXXFoldExpr,hasInit)717 AST_MATCHER(CXXFoldExpr, hasInit) { return Node.getInit(); }
AST_MATCHER(CXXFoldExpr,isRightFold)718 AST_MATCHER(CXXFoldExpr, isRightFold) { return Node.isRightFold(); }
AST_MATCHER(CXXFoldExpr,isLeftFold)719 AST_MATCHER(CXXFoldExpr, isLeftFold) { return Node.isLeftFold(); }
720
TEST_P(ImportExpr,ImportCXXFoldExpr)721 TEST_P(ImportExpr, ImportCXXFoldExpr) {
722 auto Match1 =
723 cxxFoldExpr(hasOperator(BO_Add), isLeftFold(), unless(hasInit()));
724 auto Match2 = cxxFoldExpr(hasOperator(BO_Sub), isLeftFold(), hasInit());
725 auto Match3 =
726 cxxFoldExpr(hasOperator(BO_Mul), isRightFold(), unless(hasInit()));
727 auto Match4 = cxxFoldExpr(hasOperator(BO_Div), isRightFold(), hasInit());
728
729 MatchVerifier<Decl> Verifier;
730 testImport("template <typename... Ts>"
731 "void declToImport(Ts... args) {"
732 " const int i1 = (... + args);"
733 " const int i2 = (1 - ... - args);"
734 " const int i3 = (args * ...);"
735 " const int i4 = (args / ... / 1);"
736 "};"
737 "void g() { declToImport(1, 2, 3, 4, 5); }",
738 Lang_CXX17, "", Lang_CXX17, Verifier,
739 functionTemplateDecl(hasDescendant(Match1), hasDescendant(Match2),
740 hasDescendant(Match3),
741 hasDescendant(Match4)));
742 }
743
744 /// \brief Matches __builtin_types_compatible_p:
745 /// GNU extension to check equivalent types
746 /// Given
747 /// \code
748 /// __builtin_types_compatible_p(int, int)
749 /// \endcode
750 // will generate TypeTraitExpr <...> 'int'
751 const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr;
752
TEST_P(ImportExpr,ImportTypeTraitExpr)753 TEST_P(ImportExpr, ImportTypeTraitExpr) {
754 MatchVerifier<Decl> Verifier;
755 testImport(
756 "void declToImport() { "
757 " (void)__builtin_types_compatible_p(int, int);"
758 "}",
759 Lang_C99, "", Lang_C99, Verifier,
760 functionDecl(hasDescendant(typeTraitExpr(hasType(asString("int"))))));
761 }
762
763 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr;
764
TEST_P(ImportExpr,ImportCXXTypeidExpr)765 TEST_P(ImportExpr, ImportCXXTypeidExpr) {
766 MatchVerifier<Decl> Verifier;
767 testImport(
768 "namespace std { class type_info {}; }"
769 "void declToImport() {"
770 " int x;"
771 " auto a = typeid(int); auto b = typeid(x);"
772 "}",
773 Lang_CXX11, "", Lang_CXX11, Verifier,
774 traverse(
775 TK_AsIs,
776 functionDecl(
777 hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant(
778 cxxTypeidExpr())))),
779 hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant(
780 cxxTypeidExpr())))))));
781 }
782
TEST_P(ImportExpr,ImportTypeTraitExprValDep)783 TEST_P(ImportExpr, ImportTypeTraitExprValDep) {
784 MatchVerifier<Decl> Verifier;
785 testImport(
786 "template<typename T> struct declToImport {"
787 " void m() { (void)__is_pod(T); }"
788 "};"
789 "void f() { declToImport<int>().m(); }",
790 Lang_CXX11, "", Lang_CXX11, Verifier,
791 classTemplateDecl(has(cxxRecordDecl(has(
792 functionDecl(hasDescendant(
793 typeTraitExpr(hasType(booleanType())))))))));
794 }
795
TEST_P(ImportDecl,ImportRecordDeclInFunc)796 TEST_P(ImportDecl, ImportRecordDeclInFunc) {
797 MatchVerifier<Decl> Verifier;
798 testImport("int declToImport() { "
799 " struct data_t {int a;int b;};"
800 " struct data_t d;"
801 " return 0;"
802 "}",
803 Lang_C99, "", Lang_C99, Verifier,
804 functionDecl(hasBody(compoundStmt(
805 has(declStmt(hasSingleDecl(varDecl(hasName("d")))))))));
806 }
807
TEST_P(ImportDecl,ImportedVarDeclPreservesThreadLocalStorage)808 TEST_P(ImportDecl, ImportedVarDeclPreservesThreadLocalStorage) {
809 MatchVerifier<Decl> Verifier;
810 testImport("thread_local int declToImport;", Lang_CXX11, "", Lang_CXX11,
811 Verifier, varDecl(hasThreadStorageDuration()));
812 }
813
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordTypeInFunc)814 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) {
815 Decl *FromTU = getTuDecl("int declToImport() { "
816 " struct data_t {int a;int b;};"
817 " struct data_t d;"
818 " return 0;"
819 "}",
820 Lang_C99, "input.c");
821 auto *FromVar =
822 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d")));
823 ASSERT_TRUE(FromVar);
824 auto ToType =
825 ImportType(FromVar->getType().getCanonicalType(), FromVar, Lang_C99);
826 EXPECT_FALSE(ToType.isNull());
827 }
828
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordDeclInFuncParams)829 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) {
830 // This construct is not supported by ASTImporter.
831 Decl *FromTU = getTuDecl(
832 "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }",
833 Lang_C99, "input.c");
834 auto *From = FirstDeclMatcher<FunctionDecl>().match(
835 FromTU, functionDecl(hasName("declToImport")));
836 ASSERT_TRUE(From);
837 auto *To = Import(From, Lang_C99);
838 EXPECT_EQ(To, nullptr);
839 }
840
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordDeclInFuncFromMacro)841 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) {
842 Decl *FromTU =
843 getTuDecl("#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n"
844 "int declToImport(){ return NONAME_SIZEOF(int); }",
845 Lang_C99, "input.c");
846 auto *From = FirstDeclMatcher<FunctionDecl>().match(
847 FromTU, functionDecl(hasName("declToImport")));
848 ASSERT_TRUE(From);
849 auto *To = Import(From, Lang_C99);
850 ASSERT_TRUE(To);
851 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
852 To, functionDecl(hasName("declToImport"),
853 hasDescendant(unaryExprOrTypeTraitExpr()))));
854 }
855
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordDeclInFuncParamsFromMacro)856 TEST_P(ASTImporterOptionSpecificTestBase,
857 ImportRecordDeclInFuncParamsFromMacro) {
858 // This construct is not supported by ASTImporter.
859 Decl *FromTU =
860 getTuDecl("#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n"
861 "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }",
862 Lang_C99, "input.c");
863 auto *From = FirstDeclMatcher<FunctionDecl>().match(
864 FromTU, functionDecl(hasName("declToImport")));
865 ASSERT_TRUE(From);
866 auto *To = Import(From, Lang_C99);
867 EXPECT_EQ(To, nullptr);
868 }
869
870 const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr>
871 cxxPseudoDestructorExpr;
872
TEST_P(ImportExpr,ImportCXXPseudoDestructorExpr)873 TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) {
874 MatchVerifier<Decl> Verifier;
875 testImport(
876 "typedef int T;"
877 "void declToImport(int *p) {"
878 " T t;"
879 " p->T::~T();"
880 "}",
881 Lang_CXX03, "", Lang_CXX03, Verifier,
882 functionDecl(hasDescendant(callExpr(has(cxxPseudoDestructorExpr())))));
883 }
884
TEST_P(ImportDecl,ImportUsingDecl)885 TEST_P(ImportDecl, ImportUsingDecl) {
886 MatchVerifier<Decl> Verifier;
887 testImport("namespace foo { int bar; }"
888 "void declToImport() { using foo::bar; }",
889 Lang_CXX03, "", Lang_CXX03, Verifier,
890 functionDecl(hasDescendant(usingDecl(hasName("bar")))));
891 }
892
TEST_P(ImportDecl,ImportUsingTemplate)893 TEST_P(ImportDecl, ImportUsingTemplate) {
894 MatchVerifier<Decl> Verifier;
895 testImport("namespace ns { template <typename T> struct S {}; }"
896 "template <template <typename> class T> class X {};"
897 "void declToImport() {"
898 "using ns::S; X<S> xi; }",
899 Lang_CXX11, "", Lang_CXX11, Verifier,
900 functionDecl(
901 hasDescendant(varDecl(hasTypeLoc(templateSpecializationTypeLoc(
902 hasAnyTemplateArgumentLoc(templateArgumentLoc())))))));
903 }
904
TEST_P(ImportDecl,ImportUsingEnumDecl)905 TEST_P(ImportDecl, ImportUsingEnumDecl) {
906 MatchVerifier<Decl> Verifier;
907 testImport("namespace foo { enum bar { baz, toto, quux }; }"
908 "void declToImport() { using enum foo::bar; }",
909 Lang_CXX20, "", Lang_CXX20, Verifier,
910 functionDecl(hasDescendant(usingEnumDecl(hasName("bar")))));
911 }
912
913 const internal::VariadicDynCastAllOfMatcher<Decl, UsingPackDecl> usingPackDecl;
914
TEST_P(ImportDecl,ImportUsingPackDecl)915 TEST_P(ImportDecl, ImportUsingPackDecl) {
916 MatchVerifier<Decl> Verifier;
917 testImport(
918 "struct A { int operator()() { return 1; } };"
919 "struct B { int operator()() { return 2; } };"
920 "template<typename ...T> struct C : T... { using T::operator()...; };"
921 "C<A, B> declToImport;",
922 Lang_CXX20, "", Lang_CXX20, Verifier,
923 varDecl(hasType(templateSpecializationType(hasDeclaration(
924 classTemplateSpecializationDecl(hasDescendant(usingPackDecl())))))));
925 }
926
927 /// \brief Matches shadow declarations introduced into a scope by a
928 /// (resolved) using declaration.
929 ///
930 /// Given
931 /// \code
932 /// namespace n { int f; }
933 /// namespace declToImport { using n::f; }
934 /// \endcode
935 /// usingShadowDecl()
936 /// matches \code f \endcode
937 const internal::VariadicDynCastAllOfMatcher<Decl,
938 UsingShadowDecl> usingShadowDecl;
939
TEST_P(ImportDecl,ImportUsingShadowDecl)940 TEST_P(ImportDecl, ImportUsingShadowDecl) {
941 MatchVerifier<Decl> Verifier;
942 // from using-decl
943 testImport("namespace foo { int bar; }"
944 "namespace declToImport { using foo::bar; }",
945 Lang_CXX03, "", Lang_CXX03, Verifier,
946 namespaceDecl(has(usingShadowDecl(hasName("bar")))));
947 // from using-enum-decl
948 testImport("namespace foo { enum bar {baz, toto, quux }; }"
949 "namespace declToImport { using enum foo::bar; }",
950 Lang_CXX20, "", Lang_CXX20, Verifier,
951 namespaceDecl(has(usingShadowDecl(hasName("baz")))));
952 }
953
TEST_P(ImportExpr,ImportUnresolvedLookupExpr)954 TEST_P(ImportExpr, ImportUnresolvedLookupExpr) {
955 MatchVerifier<Decl> Verifier;
956 testImport("template<typename T> int foo();"
957 "template <typename T> void declToImport() {"
958 " (void)::foo<T>;"
959 " (void)::template foo<T>;"
960 "}"
961 "void instantiate() { declToImport<int>(); }",
962 Lang_CXX03, "", Lang_CXX03, Verifier,
963 functionTemplateDecl(hasDescendant(unresolvedLookupExpr())));
964 }
965
TEST_P(ImportExpr,ImportCXXUnresolvedConstructExpr)966 TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) {
967 MatchVerifier<Decl> Verifier;
968 testImport("template <typename T> struct C { T t; };"
969 "template <typename T> void declToImport() {"
970 " C<T> d;"
971 " d.t = T();"
972 "}"
973 "void instantiate() { declToImport<int>(); }",
974 Lang_CXX03, "", Lang_CXX03, Verifier,
975 functionTemplateDecl(hasDescendant(
976 binaryOperator(has(cxxUnresolvedConstructExpr())))));
977 testImport("template <typename T> struct C { T t; };"
978 "template <typename T> void declToImport() {"
979 " C<T> d;"
980 " (&d)->t = T();"
981 "}"
982 "void instantiate() { declToImport<int>(); }",
983 Lang_CXX03, "", Lang_CXX03, Verifier,
984 functionTemplateDecl(hasDescendant(
985 binaryOperator(has(cxxUnresolvedConstructExpr())))));
986 }
987
988 /// Check that function "declToImport()" (which is the templated function
989 /// for corresponding FunctionTemplateDecl) is not added into DeclContext.
990 /// Same for class template declarations.
TEST_P(ImportDecl,ImportTemplatedDeclForTemplate)991 TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) {
992 MatchVerifier<Decl> Verifier;
993 testImport("template <typename T> void declToImport() { T a = 1; }"
994 "void instantiate() { declToImport<int>(); }",
995 Lang_CXX03, "", Lang_CXX03, Verifier,
996 functionTemplateDecl(hasAncestor(translationUnitDecl(
997 unless(has(functionDecl(hasName("declToImport"))))))));
998 testImport("template <typename T> struct declToImport { T t; };"
999 "void instantiate() { declToImport<int>(); }",
1000 Lang_CXX03, "", Lang_CXX03, Verifier,
1001 classTemplateDecl(hasAncestor(translationUnitDecl(
1002 unless(has(cxxRecordDecl(hasName("declToImport"))))))));
1003 }
1004
TEST_P(ImportDecl,ImportClassTemplatePartialSpecialization)1005 TEST_P(ImportDecl, ImportClassTemplatePartialSpecialization) {
1006 MatchVerifier<Decl> Verifier;
1007 auto Code =
1008 R"s(
1009 struct declToImport {
1010 template <typename T0> struct X;
1011 template <typename T0> struct X<T0 *> {};
1012 };
1013 )s";
1014 testImport(Code, Lang_CXX03, "", Lang_CXX03, Verifier,
1015 recordDecl(has(classTemplateDecl()),
1016 has(classTemplateSpecializationDecl())));
1017 }
1018
TEST_P(ImportExpr,CXXOperatorCallExpr)1019 TEST_P(ImportExpr, CXXOperatorCallExpr) {
1020 MatchVerifier<Decl> Verifier;
1021 testImport(
1022 "class declToImport {"
1023 " void f() { *this = declToImport(); }"
1024 "};",
1025 Lang_CXX03, "", Lang_CXX03, Verifier,
1026 cxxRecordDecl(has(cxxMethodDecl(hasDescendant(cxxOperatorCallExpr())))));
1027 }
1028
TEST_P(ImportExpr,DependentSizedArrayType)1029 TEST_P(ImportExpr, DependentSizedArrayType) {
1030 MatchVerifier<Decl> Verifier;
1031 testImport("template<typename T, int Size> class declToImport {"
1032 " T data[Size];"
1033 "};",
1034 Lang_CXX03, "", Lang_CXX03, Verifier,
1035 classTemplateDecl(has(cxxRecordDecl(
1036 has(fieldDecl(hasType(dependentSizedArrayType())))))));
1037 }
1038
TEST_P(ASTImporterOptionSpecificTestBase,ImportUsingPackDecl)1039 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingPackDecl) {
1040 Decl *FromTU = getTuDecl(
1041 "struct A { int operator()() { return 1; } };"
1042 "struct B { int operator()() { return 2; } };"
1043 "template<typename ...T> struct C : T... { using T::operator()...; };"
1044 "C<A, B> Var;",
1045 Lang_CXX20);
1046
1047 auto From = FirstDeclMatcher<UsingPackDecl>().match(FromTU, usingPackDecl());
1048 ASSERT_TRUE(From);
1049 auto To = cast<UsingPackDecl>(Import(From, Lang_CXX20));
1050 ASSERT_TRUE(To);
1051
1052 ArrayRef<NamedDecl *> FromExpansions = From->expansions();
1053 ArrayRef<NamedDecl *> ToExpansions = To->expansions();
1054 ASSERT_EQ(FromExpansions.size(), ToExpansions.size());
1055 for (unsigned int I = 0; I < FromExpansions.size(); ++I) {
1056 auto ImportedExpansion = Import(FromExpansions[I], Lang_CXX20);
1057 EXPECT_EQ(ImportedExpansion, ToExpansions[I]);
1058 }
1059
1060 auto ImportedDC = cast<Decl>(Import(From->getDeclContext(), Lang_CXX20));
1061 EXPECT_EQ(ImportedDC, cast<Decl>(To->getDeclContext()));
1062 }
1063
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTypeParmDeclNoDefaultArg)1064 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) {
1065 Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03);
1066 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
1067 FromTU, templateTypeParmDecl(hasName("T")));
1068 TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
1069 ASSERT_FALSE(To->hasDefaultArgument());
1070 }
1071
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTypeParmDeclDefaultArg)1072 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) {
1073 Decl *FromTU =
1074 getTuDecl("template<typename T = int> struct X {};", Lang_CXX03);
1075 auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
1076 FromTU, templateTypeParmDecl(hasName("T")));
1077 TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
1078 ASSERT_TRUE(To->hasDefaultArgument());
1079 QualType ToArg = To->getDefaultArgument();
1080 ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy));
1081 }
1082
TEST_P(ASTImporterOptionSpecificTestBase,ImportBeginLocOfDeclRefExpr)1083 TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) {
1084 Decl *FromTU =
1085 getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }",
1086 Lang_CXX03);
1087 auto From = FirstDeclMatcher<FunctionDecl>().match(
1088 FromTU, functionDecl(hasName("f")));
1089 ASSERT_TRUE(From);
1090 ASSERT_TRUE(
1091 cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front())
1092 ->getSubExpr()
1093 ->getBeginLoc()
1094 .isValid());
1095 FunctionDecl *To = Import(From, Lang_CXX03);
1096 ASSERT_TRUE(To);
1097 ASSERT_TRUE(
1098 cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front())
1099 ->getSubExpr()
1100 ->getBeginLoc()
1101 .isValid());
1102 }
1103
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTemplateParmDeclNoDefaultArg)1104 TEST_P(ASTImporterOptionSpecificTestBase,
1105 TemplateTemplateParmDeclNoDefaultArg) {
1106 Decl *FromTU = getTuDecl(R"(
1107 template<template<typename> typename TT> struct Y {};
1108 )",
1109 Lang_CXX17);
1110 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
1111 FromTU, templateTemplateParmDecl(hasName("TT")));
1112 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
1113 ASSERT_FALSE(To->hasDefaultArgument());
1114 }
1115
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTemplateParmDeclDefaultArg)1116 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) {
1117 Decl *FromTU = getTuDecl(R"(
1118 template<typename T> struct X {};
1119 template<template<typename> typename TT = X> struct Y {};
1120 )",
1121 Lang_CXX17);
1122 auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
1123 FromTU, templateTemplateParmDecl(hasName("TT")));
1124 TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
1125 ASSERT_TRUE(To->hasDefaultArgument());
1126 const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument();
1127 ASSERT_TRUE(To->isTemplateDecl());
1128 TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl();
1129
1130 // Find the default argument template 'X' in the AST and compare it against
1131 // the default argument we got.
1132 auto ToExpectedDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
1133 To->getTranslationUnitDecl(), classTemplateDecl(hasName("X")));
1134 ASSERT_EQ(ToTemplate, ToExpectedDecl);
1135 }
1136
TEST_P(ASTImporterOptionSpecificTestBase,NonTypeTemplateParmDeclNoDefaultArg)1137 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclNoDefaultArg) {
1138 Decl *FromTU = getTuDecl("template<int N> struct X {};", Lang_CXX03);
1139 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
1140 FromTU, nonTypeTemplateParmDecl(hasName("N")));
1141 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
1142 ASSERT_FALSE(To->hasDefaultArgument());
1143 }
1144
TEST_P(ASTImporterOptionSpecificTestBase,NonTypeTemplateParmDeclDefaultArg)1145 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclDefaultArg) {
1146 Decl *FromTU = getTuDecl("template<int S = 1> struct X {};", Lang_CXX03);
1147 auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
1148 FromTU, nonTypeTemplateParmDecl(hasName("S")));
1149 NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
1150 ASSERT_TRUE(To->hasDefaultArgument());
1151 Stmt *ToArg = To->getDefaultArgument();
1152 ASSERT_TRUE(isa<ConstantExpr>(ToArg));
1153 ToArg = *ToArg->child_begin();
1154 ASSERT_TRUE(isa<IntegerLiteral>(ToArg));
1155 ASSERT_EQ(cast<IntegerLiteral>(ToArg)->getValue().getLimitedValue(), 1U);
1156 }
1157
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclOfClassTemplateDecl)1158 TEST_P(ASTImporterOptionSpecificTestBase,
1159 ImportOfTemplatedDeclOfClassTemplateDecl) {
1160 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
1161 auto From =
1162 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
1163 ASSERT_TRUE(From);
1164 auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX03));
1165 ASSERT_TRUE(To);
1166 Decl *ToTemplated = To->getTemplatedDecl();
1167 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
1168 EXPECT_TRUE(ToTemplated1);
1169 EXPECT_EQ(ToTemplated1, ToTemplated);
1170 }
1171
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclOfFunctionTemplateDecl)1172 TEST_P(ASTImporterOptionSpecificTestBase,
1173 ImportOfTemplatedDeclOfFunctionTemplateDecl) {
1174 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
1175 auto From = FirstDeclMatcher<FunctionTemplateDecl>().match(
1176 FromTU, functionTemplateDecl());
1177 ASSERT_TRUE(From);
1178 auto To = cast<FunctionTemplateDecl>(Import(From, Lang_CXX03));
1179 ASSERT_TRUE(To);
1180 Decl *ToTemplated = To->getTemplatedDecl();
1181 Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
1182 EXPECT_TRUE(ToTemplated1);
1183 EXPECT_EQ(ToTemplated1, ToTemplated);
1184 }
1185
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclShouldImportTheClassTemplateDecl)1186 TEST_P(ASTImporterOptionSpecificTestBase,
1187 ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) {
1188 Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
1189 auto FromFT =
1190 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
1191 ASSERT_TRUE(FromFT);
1192
1193 auto ToTemplated =
1194 cast<CXXRecordDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1195 EXPECT_TRUE(ToTemplated);
1196 auto ToTU = ToTemplated->getTranslationUnitDecl();
1197 auto ToFT =
1198 FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, classTemplateDecl());
1199 EXPECT_TRUE(ToFT);
1200 }
1201
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl)1202 TEST_P(ASTImporterOptionSpecificTestBase,
1203 ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
1204 Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
1205 auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1206 FromTU, functionTemplateDecl());
1207 ASSERT_TRUE(FromFT);
1208
1209 auto ToTemplated =
1210 cast<FunctionDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1211 EXPECT_TRUE(ToTemplated);
1212 auto ToTU = ToTemplated->getTranslationUnitDecl();
1213 auto ToFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1214 ToTU, functionTemplateDecl());
1215 EXPECT_TRUE(ToFT);
1216 }
1217
TEST_P(ASTImporterOptionSpecificTestBase,ImportCorrectTemplatedDecl)1218 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) {
1219 auto Code =
1220 R"(
1221 namespace x {
1222 template<class X> struct S1{};
1223 template<class X> struct S2{};
1224 template<class X> struct S3{};
1225 }
1226 )";
1227 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
1228 auto FromNs =
1229 FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl());
1230 auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX03));
1231 ASSERT_TRUE(ToNs);
1232 auto From =
1233 FirstDeclMatcher<ClassTemplateDecl>().match(FromTU,
1234 classTemplateDecl(
1235 hasName("S2")));
1236 auto To =
1237 FirstDeclMatcher<ClassTemplateDecl>().match(ToNs,
1238 classTemplateDecl(
1239 hasName("S2")));
1240 ASSERT_TRUE(From);
1241 ASSERT_TRUE(To);
1242 auto ToTemplated = To->getTemplatedDecl();
1243 auto ToTemplated1 =
1244 cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX03));
1245 EXPECT_TRUE(ToTemplated1);
1246 ASSERT_EQ(ToTemplated1, ToTemplated);
1247 }
1248
TEST_P(ASTImporterOptionSpecificTestBase,ImportChooseExpr)1249 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) {
1250 // This tests the import of isConditionTrue directly to make sure the importer
1251 // gets it right.
1252 Decl *From, *To;
1253 std::tie(From, To) = getImportedDecl(
1254 "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", Lang_C99,
1255 "", Lang_C99);
1256
1257 auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext());
1258 auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext());
1259
1260 const ChooseExpr *FromChooseExpr =
1261 selectFirst<ChooseExpr>("choose", FromResults);
1262 ASSERT_TRUE(FromChooseExpr);
1263
1264 const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults);
1265 ASSERT_TRUE(ToChooseExpr);
1266
1267 EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue());
1268 EXPECT_EQ(FromChooseExpr->isConditionDependent(),
1269 ToChooseExpr->isConditionDependent());
1270 }
1271
TEST_P(ASTImporterOptionSpecificTestBase,ImportGenericSelectionExpr)1272 TEST_P(ASTImporterOptionSpecificTestBase, ImportGenericSelectionExpr) {
1273 Decl *From, *To;
1274 std::tie(From, To) = getImportedDecl(
1275 R"(
1276 int declToImport() {
1277 int x;
1278 return _Generic(x, int: 0, default: 1);
1279 }
1280 )",
1281 Lang_C99, "", Lang_C99);
1282
1283 auto ToResults =
1284 match(genericSelectionExpr().bind("expr"), To->getASTContext());
1285 auto FromResults =
1286 match(genericSelectionExpr().bind("expr"), From->getASTContext());
1287
1288 const GenericSelectionExpr *FromGenericSelectionExpr =
1289 selectFirst<GenericSelectionExpr>("expr", FromResults);
1290 ASSERT_TRUE(FromGenericSelectionExpr);
1291
1292 const GenericSelectionExpr *ToGenericSelectionExpr =
1293 selectFirst<GenericSelectionExpr>("expr", ToResults);
1294 ASSERT_TRUE(ToGenericSelectionExpr);
1295
1296 EXPECT_EQ(FromGenericSelectionExpr->isResultDependent(),
1297 ToGenericSelectionExpr->isResultDependent());
1298 EXPECT_EQ(FromGenericSelectionExpr->getResultIndex(),
1299 ToGenericSelectionExpr->getResultIndex());
1300 }
1301
TEST_P(ASTImporterOptionSpecificTestBase,ImportFunctionWithBackReferringParameter)1302 TEST_P(ASTImporterOptionSpecificTestBase,
1303 ImportFunctionWithBackReferringParameter) {
1304 Decl *From, *To;
1305 std::tie(From, To) = getImportedDecl(
1306 R"(
1307 template <typename T> struct X {};
1308
1309 void declToImport(int y, X<int> &x) {}
1310
1311 template <> struct X<int> {
1312 void g() {
1313 X<int> x;
1314 declToImport(0, x);
1315 }
1316 };
1317 )",
1318 Lang_CXX03, "", Lang_CXX03);
1319
1320 MatchVerifier<Decl> Verifier;
1321 auto Matcher = functionDecl(hasName("declToImport"),
1322 parameterCountIs(2),
1323 hasParameter(0, hasName("y")),
1324 hasParameter(1, hasName("x")),
1325 hasParameter(1, hasType(asString("X<int> &"))));
1326 ASSERT_TRUE(Verifier.match(From, Matcher));
1327 EXPECT_TRUE(Verifier.match(To, Matcher));
1328 }
1329
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainTemplatedDeclOfFunctionTemplates)1330 TEST_P(ASTImporterOptionSpecificTestBase,
1331 TUshouldNotContainTemplatedDeclOfFunctionTemplates) {
1332 Decl *From, *To;
1333 std::tie(From, To) =
1334 getImportedDecl("template <typename T> void declToImport() { T a = 1; }"
1335 "void instantiate() { declToImport<int>(); }",
1336 Lang_CXX03, "", Lang_CXX03);
1337
1338 auto Check = [](Decl *D) -> bool {
1339 auto TU = D->getTranslationUnitDecl();
1340 for (auto Child : TU->decls()) {
1341 if (auto *FD = dyn_cast<FunctionDecl>(Child)) {
1342 if (FD->getNameAsString() == "declToImport") {
1343 GTEST_NONFATAL_FAILURE_(
1344 "TU should not contain any FunctionDecl with name declToImport");
1345 return false;
1346 }
1347 }
1348 }
1349 return true;
1350 };
1351
1352 ASSERT_TRUE(Check(From));
1353 EXPECT_TRUE(Check(To));
1354 }
1355
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainTemplatedDeclOfClassTemplates)1356 TEST_P(ASTImporterOptionSpecificTestBase,
1357 TUshouldNotContainTemplatedDeclOfClassTemplates) {
1358 Decl *From, *To;
1359 std::tie(From, To) =
1360 getImportedDecl("template <typename T> struct declToImport { T t; };"
1361 "void instantiate() { declToImport<int>(); }",
1362 Lang_CXX03, "", Lang_CXX03);
1363
1364 auto Check = [](Decl *D) -> bool {
1365 auto TU = D->getTranslationUnitDecl();
1366 for (auto Child : TU->decls()) {
1367 if (auto *RD = dyn_cast<CXXRecordDecl>(Child)) {
1368 if (RD->getNameAsString() == "declToImport") {
1369 GTEST_NONFATAL_FAILURE_(
1370 "TU should not contain any CXXRecordDecl with name declToImport");
1371 return false;
1372 }
1373 }
1374 }
1375 return true;
1376 };
1377
1378 ASSERT_TRUE(Check(From));
1379 EXPECT_TRUE(Check(To));
1380 }
1381
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainTemplatedDeclOfTypeAlias)1382 TEST_P(ASTImporterOptionSpecificTestBase,
1383 TUshouldNotContainTemplatedDeclOfTypeAlias) {
1384 Decl *From, *To;
1385 std::tie(From, To) =
1386 getImportedDecl(
1387 "template <typename T> struct X {};"
1388 "template <typename T> using declToImport = X<T>;"
1389 "void instantiate() { declToImport<int> a; }",
1390 Lang_CXX11, "", Lang_CXX11);
1391
1392 auto Check = [](Decl *D) -> bool {
1393 auto TU = D->getTranslationUnitDecl();
1394 for (auto Child : TU->decls()) {
1395 if (auto *AD = dyn_cast<TypeAliasDecl>(Child)) {
1396 if (AD->getNameAsString() == "declToImport") {
1397 GTEST_NONFATAL_FAILURE_(
1398 "TU should not contain any TypeAliasDecl with name declToImport");
1399 return false;
1400 }
1401 }
1402 }
1403 return true;
1404 };
1405
1406 ASSERT_TRUE(Check(From));
1407 EXPECT_TRUE(Check(To));
1408 }
1409
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation)1410 TEST_P(ASTImporterOptionSpecificTestBase,
1411 TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
1412
1413 Decl *From, *To;
1414 std::tie(From, To) = getImportedDecl(
1415 R"(
1416 template<class T>
1417 class Base {};
1418 class declToImport : public Base<declToImport> {};
1419 )",
1420 Lang_CXX03, "", Lang_CXX03);
1421
1422 // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU.
1423 auto Pattern =
1424 translationUnitDecl(unless(has(classTemplateSpecializationDecl())));
1425 ASSERT_TRUE(
1426 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1427 EXPECT_TRUE(
1428 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1429
1430 // Check that the ClassTemplateSpecializationDecl is the child of the
1431 // ClassTemplateDecl.
1432 Pattern = translationUnitDecl(has(classTemplateDecl(
1433 hasName("Base"), has(classTemplateSpecializationDecl()))));
1434 ASSERT_TRUE(
1435 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1436 EXPECT_TRUE(
1437 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1438 }
1439
AST_MATCHER_P(RecordDecl,hasFieldOrder,std::vector<StringRef>,Order)1440 AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
1441 size_t Index = 0;
1442 for (Decl *D : Node.decls()) {
1443 if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
1444 auto *ND = cast<NamedDecl>(D);
1445 if (Index == Order.size())
1446 return false;
1447 if (ND->getName() != Order[Index])
1448 return false;
1449 ++Index;
1450 }
1451 }
1452 return Index == Order.size();
1453 }
1454
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldContainClassTemplateSpecializationOfExplicitInstantiation)1455 TEST_P(ASTImporterOptionSpecificTestBase,
1456 TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) {
1457 Decl *From, *To;
1458 std::tie(From, To) = getImportedDecl(
1459 R"(
1460 namespace NS {
1461 template<class T>
1462 class X {};
1463 template class X<int>;
1464 }
1465 )",
1466 Lang_CXX03, "", Lang_CXX03, "NS");
1467
1468 // Check that the ClassTemplateSpecializationDecl is NOT the child of the
1469 // ClassTemplateDecl.
1470 auto Pattern = namespaceDecl(has(classTemplateDecl(
1471 hasName("X"), unless(has(classTemplateSpecializationDecl())))));
1472 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1473 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1474
1475 // Check that the ClassTemplateSpecializationDecl is the child of the
1476 // NamespaceDecl.
1477 Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X"))));
1478 ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1479 EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1480 }
1481
TEST_P(ASTImporterOptionSpecificTestBase,CXXRecordDeclFieldsShouldBeInCorrectOrder)1482 TEST_P(ASTImporterOptionSpecificTestBase,
1483 CXXRecordDeclFieldsShouldBeInCorrectOrder) {
1484 Decl *From, *To;
1485 std::tie(From, To) =
1486 getImportedDecl(
1487 "struct declToImport { int a; int b; };",
1488 Lang_CXX11, "", Lang_CXX11);
1489
1490 MatchVerifier<Decl> Verifier;
1491 ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1492 EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1493 }
1494
TEST_P(ASTImporterOptionSpecificTestBase,CXXRecordDeclFieldOrderShouldNotDependOnImportOrder)1495 TEST_P(ASTImporterOptionSpecificTestBase,
1496 CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) {
1497 Decl *From, *To;
1498 std::tie(From, To) = getImportedDecl(
1499 // The original recursive algorithm of ASTImporter first imports 'c' then
1500 // 'b' and lastly 'a'. Therefore we must restore the order somehow.
1501 R"s(
1502 struct declToImport {
1503 int a = c + b;
1504 int b = 1;
1505 int c = 2;
1506 };
1507 )s",
1508 Lang_CXX11, "", Lang_CXX11);
1509
1510 MatchVerifier<Decl> Verifier;
1511 ASSERT_TRUE(
1512 Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1513 EXPECT_TRUE(
1514 Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1515 }
1516
TEST_P(ASTImporterOptionSpecificTestBase,CXXRecordDeclFieldAndIndirectFieldOrder)1517 TEST_P(ASTImporterOptionSpecificTestBase,
1518 CXXRecordDeclFieldAndIndirectFieldOrder) {
1519 Decl *From, *To;
1520 std::tie(From, To) = getImportedDecl(
1521 // First field is "a", then the field for unnamed union, then "b" and "c"
1522 // from it (indirect fields), then "d".
1523 R"s(
1524 struct declToImport {
1525 int a = d;
1526 union {
1527 int b;
1528 int c;
1529 };
1530 int d;
1531 };
1532 )s",
1533 Lang_CXX11, "", Lang_CXX11);
1534
1535 MatchVerifier<Decl> Verifier;
1536 ASSERT_TRUE(Verifier.match(
1537 From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1538 EXPECT_TRUE(Verifier.match(
1539 To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1540 }
1541
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportImplicitCXXRecordDecl)1542 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) {
1543 Decl *From, *To;
1544 std::tie(From, To) = getImportedDecl(
1545 R"(
1546 struct declToImport {
1547 };
1548 )",
1549 Lang_CXX03, "", Lang_CXX03);
1550
1551 MatchVerifier<Decl> Verifier;
1552 // Match the implicit Decl.
1553 auto Matcher = cxxRecordDecl(has(cxxRecordDecl()));
1554 ASSERT_TRUE(Verifier.match(From, Matcher));
1555 EXPECT_TRUE(Verifier.match(To, Matcher));
1556 }
1557
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportImplicitCXXRecordDeclOfClassTemplate)1558 TEST_P(ASTImporterOptionSpecificTestBase,
1559 ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
1560 Decl *From, *To;
1561 std::tie(From, To) = getImportedDecl(
1562 R"(
1563 template <typename U>
1564 struct declToImport {
1565 };
1566 )",
1567 Lang_CXX03, "", Lang_CXX03);
1568
1569 MatchVerifier<Decl> Verifier;
1570 // Match the implicit Decl.
1571 auto Matcher = classTemplateDecl(has(cxxRecordDecl(has(cxxRecordDecl()))));
1572 ASSERT_TRUE(Verifier.match(From, Matcher));
1573 EXPECT_TRUE(Verifier.match(To, Matcher));
1574 }
1575
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl)1576 TEST_P(ASTImporterOptionSpecificTestBase,
1577 ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
1578 Decl *From, *To;
1579 std::tie(From, To) = getImportedDecl(
1580 R"(
1581 template<class T>
1582 class Base {};
1583 class declToImport : public Base<declToImport> {};
1584 )",
1585 Lang_CXX03, "", Lang_CXX03);
1586
1587 auto hasImplicitClass = has(cxxRecordDecl());
1588 auto Pattern = translationUnitDecl(has(classTemplateDecl(
1589 hasName("Base"),
1590 has(classTemplateSpecializationDecl(hasImplicitClass)))));
1591 ASSERT_TRUE(
1592 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1593 EXPECT_TRUE(
1594 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1595 }
1596
TEST_P(ASTImporterOptionSpecificTestBase,IDNSOrdinary)1597 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) {
1598 Decl *From, *To;
1599 std::tie(From, To) =
1600 getImportedDecl("void declToImport() {}", Lang_CXX03, "", Lang_CXX03);
1601
1602 MatchVerifier<Decl> Verifier;
1603 auto Matcher = functionDecl();
1604 ASSERT_TRUE(Verifier.match(From, Matcher));
1605 EXPECT_TRUE(Verifier.match(To, Matcher));
1606 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1607 }
1608
TEST_P(ASTImporterOptionSpecificTestBase,IDNSOfNonmemberOperator)1609 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) {
1610 Decl *FromTU = getTuDecl(
1611 R"(
1612 struct X {};
1613 void operator<<(int, X);
1614 )",
1615 Lang_CXX03);
1616 Decl *From = LastDeclMatcher<Decl>{}.match(FromTU, functionDecl());
1617 const Decl *To = Import(From, Lang_CXX03);
1618 EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1619 }
1620
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportMembersOfClassTemplateSpecializationDecl)1621 TEST_P(ASTImporterOptionSpecificTestBase,
1622 ShouldImportMembersOfClassTemplateSpecializationDecl) {
1623 Decl *From, *To;
1624 std::tie(From, To) = getImportedDecl(
1625 R"(
1626 template<class T>
1627 class Base { int a; };
1628 class declToImport : Base<declToImport> {};
1629 )",
1630 Lang_CXX03, "", Lang_CXX03);
1631
1632 auto Pattern = translationUnitDecl(has(classTemplateDecl(
1633 hasName("Base"),
1634 has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a"))))))));
1635 ASSERT_TRUE(
1636 MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1637 EXPECT_TRUE(
1638 MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1639 }
1640
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassTemplateAfterFwdDecl)1641 TEST_P(ASTImporterOptionSpecificTestBase,
1642 ImportDefinitionOfClassTemplateAfterFwdDecl) {
1643 {
1644 Decl *FromTU = getTuDecl(
1645 R"(
1646 template <typename T>
1647 struct B;
1648 )",
1649 Lang_CXX03, "input0.cc");
1650 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1651 FromTU, classTemplateDecl(hasName("B")));
1652
1653 Import(FromD, Lang_CXX03);
1654 }
1655
1656 {
1657 Decl *FromTU = getTuDecl(
1658 R"(
1659 template <typename T>
1660 struct B {
1661 void f();
1662 };
1663 )",
1664 Lang_CXX03, "input1.cc");
1665 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
1666 FromTU, functionDecl(hasName("f")));
1667 Import(FromD, Lang_CXX03);
1668 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
1669 FromTU, classTemplateDecl(hasName("B")));
1670 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
1671 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
1672 }
1673 }
1674
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition)1675 TEST_P(ASTImporterOptionSpecificTestBase,
1676 ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) {
1677 Decl *ToTU = getToTuDecl(
1678 R"(
1679 template <typename T>
1680 struct B {
1681 void f();
1682 };
1683
1684 template <typename T>
1685 struct B;
1686 )",
1687 Lang_CXX03);
1688 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1689 [](const ClassTemplateDecl *T) {
1690 return T->isThisDeclarationADefinition();
1691 })
1692 .match(ToTU, classTemplateDecl()));
1693
1694 Decl *FromTU = getTuDecl(
1695 R"(
1696 template <typename T>
1697 struct B {
1698 void f();
1699 };
1700 )",
1701 Lang_CXX03, "input1.cc");
1702 ClassTemplateDecl *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1703 FromTU, classTemplateDecl(hasName("B")));
1704
1705 Import(FromD, Lang_CXX03);
1706
1707 // We should have only one definition.
1708 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1709 [](const ClassTemplateDecl *T) {
1710 return T->isThisDeclarationADefinition();
1711 })
1712 .match(ToTU, classTemplateDecl()));
1713 }
1714
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition)1715 TEST_P(ASTImporterOptionSpecificTestBase,
1716 ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) {
1717 Decl *ToTU = getToTuDecl(
1718 R"(
1719 struct B {
1720 void f();
1721 };
1722
1723 struct B;
1724 )",
1725 Lang_CXX03);
1726 ASSERT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1727 ToTU, cxxRecordDecl(unless(isImplicit()))));
1728
1729 Decl *FromTU = getTuDecl(
1730 R"(
1731 struct B {
1732 void f();
1733 };
1734 )",
1735 Lang_CXX03, "input1.cc");
1736 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
1737 FromTU, cxxRecordDecl(hasName("B")));
1738
1739 Import(FromD, Lang_CXX03);
1740
1741 EXPECT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1742 ToTU, cxxRecordDecl(unless(isImplicit()))));
1743 }
1744
CompareSourceLocs(FullSourceLoc Loc1,FullSourceLoc Loc2)1745 static void CompareSourceLocs(FullSourceLoc Loc1, FullSourceLoc Loc2) {
1746 EXPECT_EQ(Loc1.getExpansionLineNumber(), Loc2.getExpansionLineNumber());
1747 EXPECT_EQ(Loc1.getExpansionColumnNumber(), Loc2.getExpansionColumnNumber());
1748 EXPECT_EQ(Loc1.getSpellingLineNumber(), Loc2.getSpellingLineNumber());
1749 EXPECT_EQ(Loc1.getSpellingColumnNumber(), Loc2.getSpellingColumnNumber());
1750 }
CompareSourceRanges(SourceRange Range1,SourceRange Range2,SourceManager & SM1,SourceManager & SM2)1751 static void CompareSourceRanges(SourceRange Range1, SourceRange Range2,
1752 SourceManager &SM1, SourceManager &SM2) {
1753 CompareSourceLocs(FullSourceLoc{ Range1.getBegin(), SM1 },
1754 FullSourceLoc{ Range2.getBegin(), SM2 });
1755 CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 },
1756 FullSourceLoc{ Range2.getEnd(), SM2 });
1757 }
TEST_P(ASTImporterOptionSpecificTestBase,ImportSourceLocs)1758 TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) {
1759 Decl *FromTU = getTuDecl(
1760 R"(
1761 #define MFOO(arg) arg = arg + 1
1762
1763 void foo() {
1764 int a = 5;
1765 MFOO(a);
1766 }
1767 )",
1768 Lang_CXX03);
1769 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1770 auto ToD = Import(FromD, Lang_CXX03);
1771
1772 auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr());
1773 auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr());
1774 auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral());
1775 auto FromRHS =
1776 LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral());
1777
1778 SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1779 SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1780 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1781 FromSM);
1782 CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM,
1783 FromSM);
1784 CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM,
1785 FromSM);
1786 }
1787
TEST_P(ASTImporterOptionSpecificTestBase,ImportNestedMacro)1788 TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) {
1789 Decl *FromTU = getTuDecl(
1790 R"(
1791 #define FUNC_INT void declToImport
1792 #define FUNC FUNC_INT
1793 FUNC(int a);
1794 )",
1795 Lang_CXX03);
1796 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1797 auto ToD = Import(FromD, Lang_CXX03);
1798
1799 SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1800 SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1801 CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1802 FromSM);
1803 }
1804
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition)1805 TEST_P(
1806 ASTImporterOptionSpecificTestBase,
1807 ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) {
1808 Decl *ToTU = getToTuDecl(
1809 R"(
1810 template <typename T>
1811 struct B;
1812
1813 template <>
1814 struct B<int> {};
1815
1816 template <>
1817 struct B<int>;
1818 )",
1819 Lang_CXX03);
1820 // We should have only one definition.
1821 ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
1822 [](const ClassTemplateSpecializationDecl *T) {
1823 return T->isThisDeclarationADefinition();
1824 })
1825 .match(ToTU, classTemplateSpecializationDecl()));
1826
1827 Decl *FromTU = getTuDecl(
1828 R"(
1829 template <typename T>
1830 struct B;
1831
1832 template <>
1833 struct B<int> {};
1834 )",
1835 Lang_CXX03, "input1.cc");
1836 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
1837 FromTU, classTemplateSpecializationDecl(hasName("B")));
1838
1839 Import(FromD, Lang_CXX03);
1840
1841 // We should have only one definition.
1842 EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
1843 [](const ClassTemplateSpecializationDecl *T) {
1844 return T->isThisDeclarationADefinition();
1845 })
1846 .match(ToTU, classTemplateSpecializationDecl()));
1847 }
1848
TEST_P(ASTImporterOptionSpecificTestBase,ObjectsWithUnnamedStructType)1849 TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) {
1850 Decl *FromTU = getTuDecl(
1851 R"(
1852 struct { int a; int b; } object0 = { 2, 3 };
1853 struct { int x; int y; int z; } object1;
1854 )",
1855 Lang_CXX03, "input0.cc");
1856
1857 auto *Obj0 =
1858 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object0")));
1859 auto *From0 = getRecordDecl(Obj0);
1860 auto *Obj1 =
1861 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object1")));
1862 auto *From1 = getRecordDecl(Obj1);
1863
1864 auto *To0 = Import(From0, Lang_CXX03);
1865 auto *To1 = Import(From1, Lang_CXX03);
1866
1867 EXPECT_TRUE(To0);
1868 EXPECT_TRUE(To1);
1869 EXPECT_NE(To0, To1);
1870 EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl());
1871 }
1872
TEST_P(ASTImporterOptionSpecificTestBase,AnonymousRecords)1873 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) {
1874 auto *Code =
1875 R"(
1876 struct X {
1877 struct { int a; };
1878 struct { int b; };
1879 };
1880 )";
1881 Decl *FromTU0 = getTuDecl(Code, Lang_C99, "input0.c");
1882
1883 Decl *FromTU1 = getTuDecl(Code, Lang_C99, "input1.c");
1884
1885 auto *X0 =
1886 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
1887 auto *X1 =
1888 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
1889 Import(X0, Lang_C99);
1890 Import(X1, Lang_C99);
1891
1892 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
1893 // We expect no (ODR) warning during the import.
1894 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
1895 EXPECT_EQ(1u,
1896 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
1897 }
1898
TEST_P(ASTImporterOptionSpecificTestBase,AnonymousRecordsReversed)1899 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) {
1900 Decl *FromTU0 = getTuDecl(
1901 R"(
1902 struct X {
1903 struct { int a; };
1904 struct { int b; };
1905 };
1906 )",
1907 Lang_C99, "input0.c");
1908
1909 Decl *FromTU1 = getTuDecl(
1910 R"(
1911 struct X { // reversed order
1912 struct { int b; };
1913 struct { int a; };
1914 };
1915 )",
1916 Lang_C99, "input1.c");
1917
1918 auto *X0 =
1919 FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
1920 auto *X1 =
1921 FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
1922 Import(X0, Lang_C99);
1923 Import(X1, Lang_C99);
1924
1925 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
1926 // We expect one (ODR) warning during the import.
1927 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
1928 EXPECT_EQ(1u,
1929 DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
1930 }
1931
TEST_P(ASTImporterOptionSpecificTestBase,ImportDoesUpdateUsedFlag)1932 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) {
1933 auto Pattern = varDecl(hasName("x"));
1934 VarDecl *Imported1;
1935 {
1936 Decl *FromTU = getTuDecl("extern int x;", Lang_CXX03, "input0.cc");
1937 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
1938 Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
1939 }
1940 VarDecl *Imported2;
1941 {
1942 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input1.cc");
1943 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
1944 Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
1945 }
1946 EXPECT_EQ(Imported1->getCanonicalDecl(), Imported2->getCanonicalDecl());
1947 EXPECT_FALSE(Imported2->isUsed(false));
1948 {
1949 Decl *FromTU = getTuDecl("extern int x; int f() { return x; }", Lang_CXX03,
1950 "input2.cc");
1951 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
1952 FromTU, functionDecl(hasName("f")));
1953 Import(FromD, Lang_CXX03);
1954 }
1955 EXPECT_TRUE(Imported2->isUsed(false));
1956 }
1957
TEST_P(ASTImporterOptionSpecificTestBase,ImportDoesUpdateUsedFlag2)1958 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) {
1959 auto Pattern = varDecl(hasName("x"));
1960 VarDecl *ExistingD;
1961 {
1962 Decl *ToTU = getToTuDecl("int x = 1;", Lang_CXX03);
1963 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
1964 }
1965 EXPECT_FALSE(ExistingD->isUsed(false));
1966 {
1967 Decl *FromTU =
1968 getTuDecl("int x = 1; int f() { return x; }", Lang_CXX03, "input1.cc");
1969 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
1970 FromTU, functionDecl(hasName("f")));
1971 Import(FromD, Lang_CXX03);
1972 }
1973 EXPECT_TRUE(ExistingD->isUsed(false));
1974 }
1975
TEST_P(ASTImporterOptionSpecificTestBase,ImportDoesUpdateUsedFlag3)1976 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) {
1977 auto Pattern = varDecl(hasName("a"));
1978 VarDecl *ExistingD;
1979 {
1980 Decl *ToTU = getToTuDecl(
1981 R"(
1982 struct A {
1983 static const int a = 1;
1984 };
1985 )",
1986 Lang_CXX03);
1987 ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
1988 }
1989 EXPECT_FALSE(ExistingD->isUsed(false));
1990 {
1991 Decl *FromTU = getTuDecl(
1992 R"(
1993 struct A {
1994 static const int a = 1;
1995 };
1996 const int *f() { return &A::a; } // requires storage,
1997 // thus used flag will be set
1998 )",
1999 Lang_CXX03, "input1.cc");
2000 auto *FromFunD = FirstDeclMatcher<FunctionDecl>().match(
2001 FromTU, functionDecl(hasName("f")));
2002 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2003 ASSERT_TRUE(FromD->isUsed(false));
2004 Import(FromFunD, Lang_CXX03);
2005 }
2006 EXPECT_TRUE(ExistingD->isUsed(false));
2007 }
2008
TEST_P(ASTImporterOptionSpecificTestBase,ReimportWithUsedFlag)2009 TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) {
2010 auto Pattern = varDecl(hasName("x"));
2011
2012 Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input0.cc");
2013 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
2014
2015 auto *Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2016
2017 ASSERT_FALSE(Imported1->isUsed(false));
2018
2019 FromD->setIsUsed();
2020 auto *Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
2021
2022 EXPECT_EQ(Imported1, Imported2);
2023 EXPECT_TRUE(Imported2->isUsed(false));
2024 }
2025
2026 struct ImportFunctions : ASTImporterOptionSpecificTestBase {};
2027
TEST_P(ImportFunctions,ImportPrototypeOfRecursiveFunction)2028 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
2029 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
2030 auto Pattern = functionDecl(hasName("f"));
2031 auto *From =
2032 FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto
2033
2034 Decl *ImportedD = Import(From, Lang_CXX03);
2035 Decl *ToTU = ImportedD->getTranslationUnitDecl();
2036
2037 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2038 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2039 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2040 EXPECT_TRUE(ImportedD == To0);
2041 EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
2042 EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
2043 EXPECT_EQ(To1->getPreviousDecl(), To0);
2044 }
2045
TEST_P(ImportFunctions,ImportDefinitionOfRecursiveFunction)2046 TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) {
2047 Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
2048 auto Pattern = functionDecl(hasName("f"));
2049 auto *From =
2050 LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def
2051
2052 Decl *ImportedD = Import(From, Lang_CXX03);
2053 Decl *ToTU = ImportedD->getTranslationUnitDecl();
2054
2055 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2056 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2057 auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2058 EXPECT_TRUE(ImportedD == To1);
2059 EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
2060 EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
2061 EXPECT_EQ(To1->getPreviousDecl(), To0);
2062 }
2063
TEST_P(ImportFunctions,OverriddenMethodsShouldBeImported)2064 TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) {
2065 auto Code =
2066 R"(
2067 struct B { virtual void f(); };
2068 void B::f() {}
2069 struct D : B { void f(); };
2070 )";
2071 auto Pattern =
2072 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2073 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2074 CXXMethodDecl *Proto =
2075 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2076
2077 ASSERT_EQ(Proto->size_overridden_methods(), 1u);
2078 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
2079 EXPECT_EQ(To->size_overridden_methods(), 1u);
2080 }
2081
TEST_P(ImportFunctions,VirtualFlagShouldBePreservedWhenImportingPrototype)2082 TEST_P(ImportFunctions, VirtualFlagShouldBePreservedWhenImportingPrototype) {
2083 auto Code =
2084 R"(
2085 struct B { virtual void f(); };
2086 void B::f() {}
2087 )";
2088 auto Pattern =
2089 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2090 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2091 CXXMethodDecl *Proto =
2092 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2093 CXXMethodDecl *Def = LastDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
2094
2095 ASSERT_TRUE(Proto->isVirtual());
2096 ASSERT_TRUE(Def->isVirtual());
2097 CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
2098 EXPECT_TRUE(To->isVirtual());
2099 }
2100
TEST_P(ImportFunctions,ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl)2101 TEST_P(ImportFunctions,
2102 ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) {
2103 Decl *ToTU = getToTuDecl(
2104 R"(
2105 void f() {}
2106 void f();
2107 )",
2108 Lang_CXX03);
2109 ASSERT_EQ(1u,
2110 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
2111 return FD->doesThisDeclarationHaveABody();
2112 }).match(ToTU, functionDecl()));
2113
2114 Decl *FromTU = getTuDecl("void f() {}", Lang_CXX03, "input0.cc");
2115 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
2116
2117 Import(FromD, Lang_CXX03);
2118
2119 EXPECT_EQ(1u,
2120 DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
2121 return FD->doesThisDeclarationHaveABody();
2122 }).match(ToTU, functionDecl()));
2123 }
2124
TEST_P(ImportFunctions,ImportOverriddenMethodTwice)2125 TEST_P(ImportFunctions, ImportOverriddenMethodTwice) {
2126 auto Code =
2127 R"(
2128 struct B { virtual void f(); };
2129 struct D:B { void f(); };
2130 )";
2131 auto BFP =
2132 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2133 auto DFP =
2134 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2135
2136 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
2137 auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2138 Import(DF, Lang_CXX03);
2139
2140 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2141 auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
2142 Import(BF, Lang_CXX03);
2143
2144 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2145
2146 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2147 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2148 }
2149
TEST_P(ImportFunctions,ImportOverriddenMethodTwiceDefinitionFirst)2150 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) {
2151 auto CodeWithoutDef =
2152 R"(
2153 struct B { virtual void f(); };
2154 struct D:B { void f(); };
2155 )";
2156 auto CodeWithDef =
2157 R"(
2158 struct B { virtual void f(){}; };
2159 struct D:B { void f(){}; };
2160 )";
2161 auto BFP =
2162 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2163 auto DFP =
2164 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2165 auto BFDefP = cxxMethodDecl(
2166 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2167 auto DFDefP = cxxMethodDecl(
2168 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
2169 auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition());
2170
2171 {
2172 Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX03, "input0.cc");
2173 auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP);
2174 Import(FromD, Lang_CXX03);
2175 }
2176 {
2177 Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX03, "input1.cc");
2178 auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP);
2179 Import(FromB, Lang_CXX03);
2180 }
2181
2182 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2183
2184 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2185 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2186 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u);
2187 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u);
2188 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u);
2189 }
2190
TEST_P(ImportFunctions,ImportOverriddenMethodTwiceOutOfClassDef)2191 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) {
2192 auto Code =
2193 R"(
2194 struct B { virtual void f(); };
2195 struct D:B { void f(); };
2196 void B::f(){};
2197 )";
2198
2199 auto BFP =
2200 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2201 auto BFDefP = cxxMethodDecl(
2202 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2203 auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))),
2204 unless(isDefinition()));
2205
2206 Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
2207 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2208 Import(D, Lang_CXX03);
2209
2210 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2211 auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
2212 Import(B, Lang_CXX03);
2213
2214 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2215
2216 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2217 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2218
2219 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2220 ToTU, cxxRecordDecl(hasName("B")));
2221 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2222 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2223 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2224
2225 // The definition should be out-of-class.
2226 EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2227 EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2228 ToBFOutOfClass->getLexicalDeclContext());
2229 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2230 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2231
2232 // Check that the redecl chain is intact.
2233 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2234 }
2235
TEST_P(ImportFunctions,ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode)2236 TEST_P(ImportFunctions,
2237 ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) {
2238 auto CodeTU0 =
2239 R"(
2240 struct B { virtual void f(); };
2241 struct D:B { void f(); };
2242 )";
2243 auto CodeTU1 =
2244 R"(
2245 struct B { virtual void f(); };
2246 struct D:B { void f(); };
2247 void B::f(){}
2248 void D::f(){}
2249 void foo(B &b, D &d) { b.f(); d.f(); }
2250 )";
2251
2252 auto BFP =
2253 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2254 auto BFDefP = cxxMethodDecl(
2255 hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2256 auto DFP =
2257 cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2258 auto DFDefP = cxxMethodDecl(
2259 hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
2260 auto FooDef = functionDecl(hasName("foo"));
2261
2262 {
2263 Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX03, "input0.cc");
2264 auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2265 Import(D, Lang_CXX03);
2266 }
2267
2268 {
2269 Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX03, "input1.cc");
2270 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef);
2271 Import(Foo, Lang_CXX03);
2272 }
2273
2274 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2275
2276 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2277 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2278 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2279 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u);
2280
2281 auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2282 ToTU, cxxRecordDecl(hasName("B")));
2283 auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match(
2284 ToTU, cxxRecordDecl(hasName("D")));
2285 auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2286 auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2287 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2288 auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP);
2289 auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match(
2290 ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2291
2292 // The definition should be out-of-class.
2293 EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2294 EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2295 ToBFOutOfClass->getLexicalDeclContext());
2296 EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2297 EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2298
2299 EXPECT_NE(ToDFInClass, ToDFOutOfClass);
2300 EXPECT_NE(ToDFInClass->getLexicalDeclContext(),
2301 ToDFOutOfClass->getLexicalDeclContext());
2302 EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD);
2303 EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU);
2304
2305 // Check that the redecl chain is intact.
2306 EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2307 EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass);
2308 }
2309
TEST_P(ASTImporterOptionSpecificTestBase,ImportVariableChainInC)2310 TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) {
2311 std::string Code = "static int v; static int v = 0;";
2312 auto Pattern = varDecl(hasName("v"));
2313
2314 TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C99, "input0.c");
2315
2316 auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern);
2317 auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern);
2318
2319 auto *To0 = Import(From0, Lang_C99);
2320 auto *To1 = Import(From1, Lang_C99);
2321
2322 EXPECT_TRUE(To0);
2323 ASSERT_TRUE(To1);
2324 EXPECT_NE(To0, To1);
2325 EXPECT_EQ(To1->getPreviousDecl(), To0);
2326 }
2327
TEST_P(ImportFunctions,ImportFromDifferentScopedAnonNamespace)2328 TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) {
2329 TranslationUnitDecl *FromTu =
2330 getTuDecl("namespace NS0 { namespace { void f(); } }"
2331 "namespace NS1 { namespace { void f(); } }",
2332 Lang_CXX03, "input0.cc");
2333 auto Pattern = functionDecl(hasName("f"));
2334
2335 auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2336 auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2337
2338 auto *ToF0 = Import(FromF0, Lang_CXX03);
2339 auto *ToF1 = Import(FromF1, Lang_CXX03);
2340
2341 EXPECT_TRUE(ToF0);
2342 ASSERT_TRUE(ToF1);
2343 EXPECT_NE(ToF0, ToF1);
2344 EXPECT_FALSE(ToF1->getPreviousDecl());
2345 }
2346
TEST_P(ImportFunctions,ImportFunctionFromUnnamedNamespace)2347 TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) {
2348 {
2349 Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }",
2350 Lang_CXX03, "input0.cc");
2351 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2352 FromTU, functionDecl(hasName("g0")));
2353
2354 Import(FromD, Lang_CXX03);
2355 }
2356 {
2357 Decl *FromTU =
2358 getTuDecl("namespace { void f() { int a; } } void g1() { f(); }",
2359 Lang_CXX03, "input1.cc");
2360 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2361 FromTU, functionDecl(hasName("g1")));
2362 Import(FromD, Lang_CXX03);
2363 }
2364
2365 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2366 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
2367 2u);
2368 }
2369
TEST_P(ImportFunctions,ImportImplicitFunctionsInLambda)2370 TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) {
2371 Decl *FromTU = getTuDecl(
2372 R"(
2373 void foo() {
2374 (void)[]() { ; };
2375 }
2376 )",
2377 Lang_CXX11);
2378 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2379 FromTU, functionDecl(hasName("foo")));
2380 auto *ToD = Import(FromD, Lang_CXX03);
2381 EXPECT_TRUE(ToD);
2382 CXXRecordDecl *LambdaRec =
2383 cast<LambdaExpr>(cast<CStyleCastExpr>(
2384 *cast<CompoundStmt>(ToD->getBody())->body_begin())
2385 ->getSubExpr())
2386 ->getLambdaClass();
2387 EXPECT_TRUE(LambdaRec->getDestructor());
2388 }
2389
TEST_P(ImportFunctions,CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs)2390 TEST_P(ImportFunctions,
2391 CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2392 Decl *FromTU = getTuDecl(
2393 R"(
2394 struct X {
2395 template <typename T>
2396 void foo(){}
2397 };
2398 void f() {
2399 X x;
2400 x.foo<int>();
2401 }
2402 )",
2403 Lang_CXX03);
2404 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2405 FromTU, functionDecl(hasName("f")));
2406 auto *ToD = Import(FromD, Lang_CXX03);
2407 EXPECT_TRUE(ToD);
2408 EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
2409 ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr()))));
2410 }
2411
TEST_P(ImportFunctions,DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs)2412 TEST_P(ImportFunctions,
2413 DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2414 Decl *FromTU = getTuDecl(
2415 R"(
2416 struct X {
2417 template <typename T>
2418 void foo(){}
2419 };
2420 template <typename T>
2421 void f() {
2422 X x;
2423 x.foo<T>();
2424 }
2425 void g() {
2426 f<int>();
2427 }
2428 )",
2429 Lang_CXX03);
2430 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2431 FromTU, functionDecl(hasName("g")));
2432 auto *ToD = Import(FromD, Lang_CXX03);
2433 EXPECT_TRUE(ToD);
2434 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2435 EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match(
2436 ToTU, translationUnitDecl(hasDescendant(
2437 functionDecl(hasName("f"), hasDescendant(declRefExpr()))))));
2438 }
2439
2440 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {};
2441
TEST_P(ImportFunctionTemplates,ImportFunctionTemplateInRecordDeclTwice)2442 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) {
2443 auto Code =
2444 R"(
2445 class X {
2446 template <class T>
2447 void f(T t);
2448 };
2449 )";
2450 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2451 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2452 FromTU1, functionTemplateDecl(hasName("f")));
2453 auto *ToD1 = Import(FromD1, Lang_CXX03);
2454 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2455 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2456 FromTU2, functionTemplateDecl(hasName("f")));
2457 auto *ToD2 = Import(FromD2, Lang_CXX03);
2458 EXPECT_EQ(ToD1, ToD2);
2459 }
2460
TEST_P(ImportFunctionTemplates,ImportFunctionTemplateWithDefInRecordDeclTwice)2461 TEST_P(ImportFunctionTemplates,
2462 ImportFunctionTemplateWithDefInRecordDeclTwice) {
2463 auto Code =
2464 R"(
2465 class X {
2466 template <class T>
2467 void f(T t);
2468 };
2469 template <class T>
2470 void X::f(T t) {};
2471 )";
2472 Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2473 auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2474 FromTU1, functionTemplateDecl(hasName("f")));
2475 auto *ToD1 = Import(FromD1, Lang_CXX03);
2476 Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2477 auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2478 FromTU2, functionTemplateDecl(hasName("f")));
2479 auto *ToD2 = Import(FromD2, Lang_CXX03);
2480 EXPECT_EQ(ToD1, ToD2);
2481 }
2482
TEST_P(ImportFunctionTemplates,ImportFunctionWhenThereIsAFunTemplateWithSameName)2483 TEST_P(ImportFunctionTemplates,
2484 ImportFunctionWhenThereIsAFunTemplateWithSameName) {
2485 getToTuDecl(
2486 R"(
2487 template <typename T>
2488 void foo(T) {}
2489 void foo();
2490 )",
2491 Lang_CXX03);
2492 Decl *FromTU = getTuDecl("void foo();", Lang_CXX03);
2493 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2494 FromTU, functionDecl(hasName("foo")));
2495 auto *ImportedD = Import(FromD, Lang_CXX03);
2496 EXPECT_TRUE(ImportedD);
2497 }
2498
TEST_P(ImportFunctionTemplates,ImportConstructorWhenThereIsAFunTemplateWithSameName)2499 TEST_P(ImportFunctionTemplates,
2500 ImportConstructorWhenThereIsAFunTemplateWithSameName) {
2501 auto Code =
2502 R"(
2503 struct Foo {
2504 template <typename T>
2505 Foo(T) {}
2506 Foo();
2507 };
2508 )";
2509 getToTuDecl(Code, Lang_CXX03);
2510 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2511 auto *FromD =
2512 LastDeclMatcher<CXXConstructorDecl>().match(FromTU, cxxConstructorDecl());
2513 auto *ImportedD = Import(FromD, Lang_CXX03);
2514 EXPECT_TRUE(ImportedD);
2515 }
2516
TEST_P(ImportFunctionTemplates,ImportOperatorWhenThereIsAFunTemplateWithSameName)2517 TEST_P(ImportFunctionTemplates,
2518 ImportOperatorWhenThereIsAFunTemplateWithSameName) {
2519 getToTuDecl(
2520 R"(
2521 template <typename T>
2522 void operator<(T,T) {}
2523 struct X{};
2524 void operator<(X, X);
2525 )",
2526 Lang_CXX03);
2527 Decl *FromTU = getTuDecl(
2528 R"(
2529 struct X{};
2530 void operator<(X, X);
2531 )",
2532 Lang_CXX03);
2533 auto *FromD = LastDeclMatcher<FunctionDecl>().match(
2534 FromTU, functionDecl(hasOverloadedOperatorName("<")));
2535 auto *ImportedD = Import(FromD, Lang_CXX03);
2536 EXPECT_TRUE(ImportedD);
2537 }
2538
2539 struct ImportFriendFunctions : ImportFunctions {};
2540
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainProto)2541 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {
2542 auto Pattern = functionDecl(hasName("f"));
2543
2544 Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2545 "void f();",
2546 Lang_CXX03, "input0.cc");
2547 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2548
2549 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2550 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2551 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2552 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2553 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2554 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2555 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2556 }
2557
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst)2558 TEST_P(ImportFriendFunctions,
2559 ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) {
2560 auto Pattern = functionDecl(hasName("f"));
2561
2562 Decl *FromTU = getTuDecl("void f();"
2563 "struct X { friend void f(); };",
2564 Lang_CXX03, "input0.cc");
2565 auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2566
2567 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2568 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2569 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2570 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2571 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2572 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2573 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2574 }
2575
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDef)2576 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) {
2577 auto Pattern = functionDecl(hasName("f"));
2578
2579 Decl *FromTU = getTuDecl("struct X { friend void f(){} };"
2580 "void f();",
2581 Lang_CXX03, "input0.cc");
2582 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2583
2584 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2585 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2586 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2587 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2588 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2589 EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2590 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2591 }
2592
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDef_OutOfClassDef)2593 TEST_P(ImportFriendFunctions,
2594 ImportFriendFunctionRedeclChainDef_OutOfClassDef) {
2595 auto Pattern = functionDecl(hasName("f"));
2596
2597 Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2598 "void f(){}",
2599 Lang_CXX03, "input0.cc");
2600 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2601
2602 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2603 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2604 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2605 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2606 auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2607 EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody());
2608 EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2609 }
2610
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDefWithClass)2611 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) {
2612 auto Pattern = functionDecl(hasName("f"));
2613
2614 Decl *FromTU = getTuDecl(
2615 R"(
2616 class X;
2617 void f(X *x){}
2618 class X{
2619 friend void f(X *x);
2620 };
2621 )",
2622 Lang_CXX03, "input0.cc");
2623 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2624
2625 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2626 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2627 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2628 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2629 auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>()
2630 .match(ToTU, friendDecl())
2631 ->getFriendDecl());
2632 EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody());
2633 EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD);
2634 // The parameters must refer the same type
2635 EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(),
2636 (*ImportedD->param_begin())->getOriginalType());
2637 }
2638
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto)2639 TEST_P(ImportFriendFunctions,
2640 ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) {
2641 auto Pattern = functionDecl(hasName("f"));
2642
2643 Decl *FromTU = getTuDecl(
2644 R"(
2645 class X;
2646 void f(X *x){}
2647 class X{
2648 friend void f(X *x);
2649 };
2650 )",
2651 Lang_CXX03, "input0.cc");
2652 auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2653
2654 auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2655 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2656 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2657 EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2658 auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match(
2659 ToTU, functionDecl(unless(hasParent(friendDecl()))));
2660
2661 EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody());
2662 EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD);
2663 // The parameters must refer the same type
2664 EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(),
2665 (*ImportedD->param_begin())->getOriginalType());
2666 }
2667
TEST_P(ImportFriendFunctions,ImportFriendFunctionFromMultipleTU)2668 TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) {
2669 auto Pattern = functionDecl(hasName("f"));
2670
2671 FunctionDecl *ImportedD;
2672 {
2673 Decl *FromTU =
2674 getTuDecl("struct X { friend void f(){} };", Lang_CXX03, "input0.cc");
2675 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2676 ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2677 }
2678 FunctionDecl *ImportedD1;
2679 {
2680 Decl *FromTU = getTuDecl("void f();", Lang_CXX03, "input1.cc");
2681 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2682 ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2683 }
2684
2685 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2686 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2687 EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2688 EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody());
2689 EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD);
2690 }
2691
TEST_P(ImportFriendFunctions,Lookup)2692 TEST_P(ImportFriendFunctions, Lookup) {
2693 auto FunctionPattern = functionDecl(hasName("f"));
2694 auto ClassPattern = cxxRecordDecl(hasName("X"));
2695
2696 TranslationUnitDecl *FromTU =
2697 getTuDecl("struct X { friend void f(); };", Lang_CXX03, "input0.cc");
2698 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2699 ASSERT_TRUE(FromD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2700 ASSERT_FALSE(FromD->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2701 {
2702 auto FromName = FromD->getDeclName();
2703 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2704 auto LookupRes = Class->noload_lookup(FromName);
2705 ASSERT_TRUE(LookupRes.empty());
2706 LookupRes = FromTU->noload_lookup(FromName);
2707 ASSERT_TRUE(LookupRes.isSingleResult());
2708 }
2709
2710 auto *ToD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2711 auto ToName = ToD->getDeclName();
2712
2713 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2714 auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2715 auto LookupRes = Class->noload_lookup(ToName);
2716 EXPECT_TRUE(LookupRes.empty());
2717 LookupRes = ToTU->noload_lookup(ToName);
2718 EXPECT_TRUE(LookupRes.isSingleResult());
2719
2720 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 1u);
2721 auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2722 EXPECT_TRUE(To0->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2723 EXPECT_FALSE(To0->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2724 }
2725
TEST_P(ImportFriendFunctions,LookupWithProtoAfter)2726 TEST_P(ImportFriendFunctions, LookupWithProtoAfter) {
2727 auto FunctionPattern = functionDecl(hasName("f"));
2728 auto ClassPattern = cxxRecordDecl(hasName("X"));
2729
2730 TranslationUnitDecl *FromTU =
2731 getTuDecl("struct X { friend void f(); };"
2732 // This proto decl makes f available to normal
2733 // lookup, otherwise it is hidden.
2734 // Normal C++ lookup (implemented in
2735 // `clang::Sema::CppLookupName()` and in `LookupDirect()`)
2736 // returns the found `NamedDecl` only if the set IDNS is matched
2737 "void f();",
2738 Lang_CXX03, "input0.cc");
2739 auto *FromFriend =
2740 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2741 auto *FromNormal =
2742 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2743 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2744 ASSERT_FALSE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2745 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2746 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2747
2748 auto FromName = FromFriend->getDeclName();
2749 auto *FromClass =
2750 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2751 auto LookupRes = FromClass->noload_lookup(FromName);
2752 ASSERT_TRUE(LookupRes.empty());
2753 LookupRes = FromTU->noload_lookup(FromName);
2754 ASSERT_TRUE(LookupRes.isSingleResult());
2755
2756 auto *ToFriend = cast<FunctionDecl>(Import(FromFriend, Lang_CXX03));
2757 auto ToName = ToFriend->getDeclName();
2758
2759 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2760 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2761 LookupRes = ToClass->noload_lookup(ToName);
2762 EXPECT_TRUE(LookupRes.empty());
2763 LookupRes = ToTU->noload_lookup(ToName);
2764 // Test is disabled because this result is 2.
2765 EXPECT_TRUE(LookupRes.isSingleResult());
2766
2767 ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
2768 ToFriend = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2769 auto *ToNormal = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2770 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2771 EXPECT_FALSE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2772 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2773 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2774 }
2775
TEST_P(ImportFriendFunctions,LookupWithProtoBefore)2776 TEST_P(ImportFriendFunctions, LookupWithProtoBefore) {
2777 auto FunctionPattern = functionDecl(hasName("f"));
2778 auto ClassPattern = cxxRecordDecl(hasName("X"));
2779
2780 TranslationUnitDecl *FromTU = getTuDecl("void f();"
2781 "struct X { friend void f(); };",
2782 Lang_CXX03, "input0.cc");
2783 auto *FromNormal =
2784 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2785 auto *FromFriend =
2786 LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2787 ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2788 ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2789 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2790 ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2791
2792 auto FromName = FromNormal->getDeclName();
2793 auto *FromClass =
2794 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2795 auto LookupRes = FromClass->noload_lookup(FromName);
2796 ASSERT_TRUE(LookupRes.empty());
2797 LookupRes = FromTU->noload_lookup(FromName);
2798 ASSERT_TRUE(LookupRes.isSingleResult());
2799
2800 auto *ToNormal = cast<FunctionDecl>(Import(FromNormal, Lang_CXX03));
2801 auto ToName = ToNormal->getDeclName();
2802 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2803
2804 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2805 LookupRes = ToClass->noload_lookup(ToName);
2806 EXPECT_TRUE(LookupRes.empty());
2807 LookupRes = ToTU->noload_lookup(ToName);
2808 EXPECT_TRUE(LookupRes.isSingleResult());
2809
2810 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
2811 ToNormal = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2812 auto *ToFriend = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2813 EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2814 EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2815 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2816 EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2817 }
2818
TEST_P(ImportFriendFunctions,ImportFriendChangesLookup)2819 TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) {
2820 auto Pattern = functionDecl(hasName("f"));
2821
2822 TranslationUnitDecl *FromNormalTU =
2823 getTuDecl("void f();", Lang_CXX03, "input0.cc");
2824 auto *FromNormalF =
2825 FirstDeclMatcher<FunctionDecl>().match(FromNormalTU, Pattern);
2826 TranslationUnitDecl *FromFriendTU =
2827 getTuDecl("class X { friend void f(); };", Lang_CXX03, "input1.cc");
2828 auto *FromFriendF =
2829 FirstDeclMatcher<FunctionDecl>().match(FromFriendTU, Pattern);
2830 auto FromNormalName = FromNormalF->getDeclName();
2831 auto FromFriendName = FromFriendF->getDeclName();
2832
2833 ASSERT_TRUE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2834 ASSERT_FALSE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2835 ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2836 ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2837 auto LookupRes = FromNormalTU->noload_lookup(FromNormalName);
2838 ASSERT_TRUE(LookupRes.isSingleResult());
2839 LookupRes = FromFriendTU->noload_lookup(FromFriendName);
2840 ASSERT_TRUE(LookupRes.isSingleResult());
2841
2842 auto *ToNormalF = cast<FunctionDecl>(Import(FromNormalF, Lang_CXX03));
2843 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2844 auto ToName = ToNormalF->getDeclName();
2845 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2846 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2847 LookupRes = ToTU->noload_lookup(ToName);
2848 EXPECT_TRUE(LookupRes.isSingleResult());
2849 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
2850
2851 auto *ToFriendF = cast<FunctionDecl>(Import(FromFriendF, Lang_CXX03));
2852 LookupRes = ToTU->noload_lookup(ToName);
2853 EXPECT_TRUE(LookupRes.isSingleResult());
2854 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2855
2856 EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2857 EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2858
2859 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2860 EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2861 }
2862
TEST_P(ImportFriendFunctions,ImportFriendList)2863 TEST_P(ImportFriendFunctions, ImportFriendList) {
2864 TranslationUnitDecl *FromTU = getTuDecl("struct X { friend void f(); };"
2865 "void f();",
2866 Lang_CXX03, "input0.cc");
2867 auto *FromFriendF = FirstDeclMatcher<FunctionDecl>().match(
2868 FromTU, functionDecl(hasName("f")));
2869
2870 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
2871 FromTU, cxxRecordDecl(hasName("X")));
2872 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl());
2873 auto FromFriends = FromClass->friends();
2874 unsigned int FrN = 0;
2875 for (auto Fr : FromFriends) {
2876 ASSERT_EQ(Fr, FromFriend);
2877 ++FrN;
2878 }
2879 ASSERT_EQ(FrN, 1u);
2880
2881 Import(FromFriendF, Lang_CXX03);
2882 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2883 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
2884 ToTU, cxxRecordDecl(hasName("X")));
2885 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
2886 auto ToFriends = ToClass->friends();
2887 FrN = 0;
2888 for (auto Fr : ToFriends) {
2889 EXPECT_EQ(Fr, ToFriend);
2890 ++FrN;
2891 }
2892 EXPECT_EQ(FrN, 1u);
2893 }
2894
AST_MATCHER_P(TagDecl,hasTypedefForAnonDecl,Matcher<TypedefNameDecl>,InnerMatcher)2895 AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>,
2896 InnerMatcher) {
2897 if (auto *Typedef = Node.getTypedefNameForAnonDecl())
2898 return InnerMatcher.matches(*Typedef, Finder, Builder);
2899 return false;
2900 }
2901
TEST_P(ImportDecl,ImportEnumSequential)2902 TEST_P(ImportDecl, ImportEnumSequential) {
2903 CodeFiles Samples{{"main.c",
2904 {"void foo();"
2905 "void moo();"
2906 "int main() { foo(); moo(); }",
2907 Lang_C99}},
2908
2909 {"foo.c",
2910 {"typedef enum { THING_VALUE } thing_t;"
2911 "void conflict(thing_t type);"
2912 "void foo() { (void)THING_VALUE; }"
2913 "void conflict(thing_t type) {}",
2914 Lang_C99}},
2915
2916 {"moo.c",
2917 {"typedef enum { THING_VALUE } thing_t;"
2918 "void conflict(thing_t type);"
2919 "void moo() { conflict(THING_VALUE); }",
2920 Lang_C99}}};
2921
2922 auto VerificationMatcher =
2923 enumDecl(has(enumConstantDecl(hasName("THING_VALUE"))),
2924 hasTypedefForAnonDecl(hasName("thing_t")));
2925
2926 ImportAction ImportFoo{"foo.c", "main.c", functionDecl(hasName("foo"))},
2927 ImportMoo{"moo.c", "main.c", functionDecl(hasName("moo"))};
2928
2929 testImportSequence(
2930 Samples, {ImportFoo, ImportMoo}, // "foo", them "moo".
2931 // Just check that there is only one enum decl in the result AST.
2932 "main.c", enumDecl(), VerificationMatcher);
2933
2934 // For different import order, result should be the same.
2935 testImportSequence(
2936 Samples, {ImportMoo, ImportFoo}, // "moo", them "foo".
2937 // Check that there is only one enum decl in the result AST.
2938 "main.c", enumDecl(), VerificationMatcher);
2939 }
2940
TEST_P(ImportDecl,ImportFieldOrder)2941 TEST_P(ImportDecl, ImportFieldOrder) {
2942 MatchVerifier<Decl> Verifier;
2943 testImport("struct declToImport {"
2944 " int b = a + 2;"
2945 " int a = 5;"
2946 "};",
2947 Lang_CXX11, "", Lang_CXX11, Verifier,
2948 recordDecl(hasFieldOrder({"b", "a"})));
2949 }
2950
2951 const internal::VariadicDynCastAllOfMatcher<Expr, DependentScopeDeclRefExpr>
2952 dependentScopeDeclRefExpr;
2953
TEST_P(ImportExpr,DependentScopeDeclRefExpr)2954 TEST_P(ImportExpr, DependentScopeDeclRefExpr) {
2955 MatchVerifier<Decl> Verifier;
2956 testImport("template <typename T> struct S { static T foo; };"
2957 "template <typename T> void declToImport() {"
2958 " (void) S<T>::foo;"
2959 "}"
2960 "void instantiate() { declToImport<int>(); }"
2961 "template <typename T> T S<T>::foo;",
2962 Lang_CXX11, "", Lang_CXX11, Verifier,
2963 functionTemplateDecl(has(functionDecl(has(compoundStmt(
2964 has(cStyleCastExpr(has(dependentScopeDeclRefExpr())))))))));
2965
2966 testImport("template <typename T> struct S {"
2967 "template<typename S> static void foo(){};"
2968 "};"
2969 "template <typename T> void declToImport() {"
2970 " S<T>::template foo<T>();"
2971 "}"
2972 "void instantiate() { declToImport<int>(); }",
2973 Lang_CXX11, "", Lang_CXX11, Verifier,
2974 functionTemplateDecl(has(functionDecl(has(compoundStmt(
2975 has(callExpr(has(dependentScopeDeclRefExpr())))))))));
2976 }
2977
2978 const internal::VariadicDynCastAllOfMatcher<Type, DependentNameType>
2979 dependentNameType;
2980
TEST_P(ImportExpr,DependentNameType)2981 TEST_P(ImportExpr, DependentNameType) {
2982 MatchVerifier<Decl> Verifier;
2983 testImport("template <typename T> struct declToImport {"
2984 " typedef typename T::type dependent_name;"
2985 "};",
2986 Lang_CXX11, "", Lang_CXX11, Verifier,
2987 classTemplateDecl(has(
2988 cxxRecordDecl(has(typedefDecl(has(dependentNameType())))))));
2989 }
2990
TEST_P(ImportExpr,UnresolvedMemberExpr)2991 TEST_P(ImportExpr, UnresolvedMemberExpr) {
2992 MatchVerifier<Decl> Verifier;
2993 testImport("struct S { template <typename T> void mem(); };"
2994 "template <typename U> void declToImport() {"
2995 " S s;"
2996 " s.mem<U>();"
2997 "}"
2998 "void instantiate() { declToImport<int>(); }",
2999 Lang_CXX11, "", Lang_CXX11, Verifier,
3000 functionTemplateDecl(has(functionDecl(has(
3001 compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
3002 }
3003
3004 class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
3005 public:
3006 static constexpr auto DefaultCode = R"(
3007 struct A { int x; };
3008 void f() {
3009 A a;
3010 A a1(a);
3011 A a2(A{});
3012 a = a1;
3013 a = A{};
3014 a.~A();
3015 })";
3016
3017 template <typename MatcherType>
testImportOf(const MatcherType & MethodMatcher,const char * Code=DefaultCode)3018 void testImportOf(
3019 const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
3020 test(MethodMatcher, Code, /*ExpectedCount=*/1u);
3021 }
3022
3023 template <typename MatcherType>
testNoImportOf(const MatcherType & MethodMatcher,const char * Code=DefaultCode)3024 void testNoImportOf(
3025 const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
3026 test(MethodMatcher, Code, /*ExpectedCount=*/0u);
3027 }
3028
3029 private:
3030 template <typename MatcherType>
test(const MatcherType & MethodMatcher,const char * Code,unsigned int ExpectedCount)3031 void test(const MatcherType &MethodMatcher,
3032 const char *Code, unsigned int ExpectedCount) {
3033 auto ClassMatcher = cxxRecordDecl(unless(isImplicit()));
3034
3035 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3036 auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
3037 ToTU, ClassMatcher);
3038
3039 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1u);
3040
3041 {
3042 CXXMethodDecl *Method =
3043 FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher);
3044 ToClass->removeDecl(Method);
3045 SharedStatePtr->getLookupTable()->remove(Method);
3046 }
3047
3048 ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0u);
3049
3050 Decl *ImportedClass = nullptr;
3051 {
3052 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc");
3053 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
3054 FromTU, ClassMatcher);
3055 ImportedClass = Import(FromClass, Lang_CXX11);
3056 }
3057
3058 EXPECT_EQ(ToClass, ImportedClass);
3059 EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher),
3060 ExpectedCount);
3061 }
3062 };
3063
TEST_P(ImportImplicitMethods,DefaultConstructor)3064 TEST_P(ImportImplicitMethods, DefaultConstructor) {
3065 testImportOf(cxxConstructorDecl(isDefaultConstructor()));
3066 }
3067
TEST_P(ImportImplicitMethods,CopyConstructor)3068 TEST_P(ImportImplicitMethods, CopyConstructor) {
3069 testImportOf(cxxConstructorDecl(isCopyConstructor()));
3070 }
3071
TEST_P(ImportImplicitMethods,MoveConstructor)3072 TEST_P(ImportImplicitMethods, MoveConstructor) {
3073 testImportOf(cxxConstructorDecl(isMoveConstructor()));
3074 }
3075
TEST_P(ImportImplicitMethods,Destructor)3076 TEST_P(ImportImplicitMethods, Destructor) {
3077 testImportOf(cxxDestructorDecl());
3078 }
3079
TEST_P(ImportImplicitMethods,CopyAssignment)3080 TEST_P(ImportImplicitMethods, CopyAssignment) {
3081 testImportOf(cxxMethodDecl(isCopyAssignmentOperator()));
3082 }
3083
TEST_P(ImportImplicitMethods,MoveAssignment)3084 TEST_P(ImportImplicitMethods, MoveAssignment) {
3085 testImportOf(cxxMethodDecl(isMoveAssignmentOperator()));
3086 }
3087
TEST_P(ImportImplicitMethods,DoNotImportUserProvided)3088 TEST_P(ImportImplicitMethods, DoNotImportUserProvided) {
3089 auto Code = R"(
3090 struct A { A() { int x; } };
3091 )";
3092 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3093 }
3094
TEST_P(ImportImplicitMethods,DoNotImportDefault)3095 TEST_P(ImportImplicitMethods, DoNotImportDefault) {
3096 auto Code = R"(
3097 struct A { A() = default; };
3098 )";
3099 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3100 }
3101
TEST_P(ImportImplicitMethods,DoNotImportDeleted)3102 TEST_P(ImportImplicitMethods, DoNotImportDeleted) {
3103 auto Code = R"(
3104 struct A { A() = delete; };
3105 )";
3106 testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
3107 }
3108
TEST_P(ImportImplicitMethods,DoNotImportOtherMethod)3109 TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) {
3110 auto Code = R"(
3111 struct A { void f() { } };
3112 )";
3113 testNoImportOf(cxxMethodDecl(hasName("f")), Code);
3114 }
3115
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfEquivalentRecord)3116 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) {
3117 Decl *ToR1;
3118 {
3119 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input0.cc");
3120 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3121 FromTU, cxxRecordDecl(hasName("A")));
3122
3123 ToR1 = Import(FromR, Lang_CXX03);
3124 }
3125
3126 Decl *ToR2;
3127 {
3128 Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input1.cc");
3129 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3130 FromTU, cxxRecordDecl(hasName("A")));
3131
3132 ToR2 = Import(FromR, Lang_CXX03);
3133 }
3134
3135 EXPECT_EQ(ToR1, ToR2);
3136 }
3137
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfNonEquivalentRecord)3138 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) {
3139 Decl *ToR1;
3140 {
3141 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3142 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3143 FromTU, cxxRecordDecl(hasName("A")));
3144 ToR1 = Import(FromR, Lang_CXX03);
3145 }
3146 Decl *ToR2;
3147 {
3148 Decl *FromTU =
3149 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
3150 auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
3151 FromTU, cxxRecordDecl(hasName("A")));
3152 ToR2 = Import(FromR, Lang_CXX03);
3153 }
3154 EXPECT_NE(ToR1, ToR2);
3155 }
3156
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfEquivalentField)3157 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) {
3158 Decl *ToF1;
3159 {
3160 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3161 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3162 FromTU, fieldDecl(hasName("x")));
3163 ToF1 = Import(FromF, Lang_CXX03);
3164 }
3165 Decl *ToF2;
3166 {
3167 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input1.cc");
3168 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3169 FromTU, fieldDecl(hasName("x")));
3170 ToF2 = Import(FromF, Lang_CXX03);
3171 }
3172 EXPECT_EQ(ToF1, ToF2);
3173 }
3174
TEST_P(ASTImporterOptionSpecificTestBase,ImportBitfields)3175 TEST_P(ASTImporterOptionSpecificTestBase, ImportBitfields) {
3176 Decl *FromTU = getTuDecl("struct A { unsigned x : 3; };", Lang_CXX03);
3177 auto *FromF =
3178 FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl(hasName("x")));
3179
3180 ASSERT_TRUE(FromF->isBitField());
3181 ASSERT_EQ(3u, FromF->getBitWidthValue(FromTU->getASTContext()));
3182 auto *ToField = Import(FromF, Lang_CXX03);
3183 auto *ToTU = ToField->getTranslationUnitDecl();
3184
3185 EXPECT_TRUE(ToField->isBitField());
3186 EXPECT_EQ(3u, ToField->getBitWidthValue(ToTU->getASTContext()));
3187
3188 const auto *FromBT = FromF->getBitWidth()->getType()->getAs<BuiltinType>();
3189 const auto *ToBT = ToField->getBitWidth()->getType()->getAs<BuiltinType>();
3190 ASSERT_TRUE(FromBT);
3191 ASSERT_EQ(BuiltinType::Int, FromBT->getKind());
3192 EXPECT_TRUE(ToBT);
3193 EXPECT_EQ(BuiltinType::Int, ToBT->getKind());
3194 }
3195
3196 struct ImportBlock : ASTImporterOptionSpecificTestBase {};
TEST_P(ImportBlock,ImportBlocksAreUnsupported)3197 TEST_P(ImportBlock, ImportBlocksAreUnsupported) {
3198 const auto *Code = R"(
3199 void test_block__capture_null() {
3200 int *p = 0;
3201 ^(){
3202 *p = 1;
3203 }();
3204 })";
3205 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
3206 auto *FromBlock = FirstDeclMatcher<BlockDecl>().match(FromTU, blockDecl());
3207 ASSERT_TRUE(FromBlock);
3208
3209 auto ToBlockOrError = importOrError(FromBlock, Lang_CXX03);
3210
3211 const auto ExpectUnsupportedConstructError = [](const ASTImportError &Error) {
3212 EXPECT_EQ(ASTImportError::UnsupportedConstruct, Error.Error);
3213 };
3214 llvm::handleAllErrors(ToBlockOrError.takeError(),
3215 ExpectUnsupportedConstructError);
3216 }
3217
TEST_P(ASTImporterOptionSpecificTestBase,ImportParmVarDecl)3218 TEST_P(ASTImporterOptionSpecificTestBase, ImportParmVarDecl) {
3219 const auto *Code = R"(
3220 template <typename T> struct Wrapper {
3221 Wrapper(T Value = {}) {}
3222 };
3223 template class Wrapper<int>;
3224 )";
3225 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3226 auto *FromVar = FirstDeclMatcher<ParmVarDecl>().match(
3227 FromTU, parmVarDecl(hasType(asString("int"))));
3228 ASSERT_TRUE(FromVar);
3229 ASSERT_TRUE(FromVar->hasUninstantiatedDefaultArg());
3230 ASSERT_TRUE(FromVar->getUninstantiatedDefaultArg());
3231
3232 const auto *ToVar = Import(FromVar, Lang_CXX11);
3233 EXPECT_TRUE(ToVar);
3234 EXPECT_TRUE(ToVar->hasUninstantiatedDefaultArg());
3235 EXPECT_TRUE(ToVar->getUninstantiatedDefaultArg());
3236 EXPECT_NE(FromVar->getUninstantiatedDefaultArg(),
3237 ToVar->getUninstantiatedDefaultArg());
3238 }
3239
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfNonEquivalentField)3240 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) {
3241 Decl *ToF1;
3242 {
3243 Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
3244 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3245 FromTU, fieldDecl(hasName("x")));
3246 ToF1 = Import(FromF, Lang_CXX03);
3247 }
3248 Decl *ToF2;
3249 {
3250 Decl *FromTU =
3251 getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
3252 auto *FromF = FirstDeclMatcher<FieldDecl>().match(
3253 FromTU, fieldDecl(hasName("x")));
3254 ToF2 = Import(FromF, Lang_CXX03);
3255 }
3256 EXPECT_NE(ToF1, ToF2);
3257 }
3258
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfEquivalentMethod)3259 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) {
3260 Decl *ToM1;
3261 {
3262 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3263 Lang_CXX03, "input0.cc");
3264 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3265 FromTU, functionDecl(hasName("x"), isDefinition()));
3266 ToM1 = Import(FromM, Lang_CXX03);
3267 }
3268 Decl *ToM2;
3269 {
3270 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3271 Lang_CXX03, "input1.cc");
3272 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3273 FromTU, functionDecl(hasName("x"), isDefinition()));
3274 ToM2 = Import(FromM, Lang_CXX03);
3275 }
3276 EXPECT_EQ(ToM1, ToM2);
3277 }
3278
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfNonEquivalentMethod)3279 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) {
3280 Decl *ToM1;
3281 {
3282 Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3283 Lang_CXX03, "input0.cc");
3284 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3285 FromTU, functionDecl(hasName("x"), isDefinition()));
3286 ToM1 = Import(FromM, Lang_CXX03);
3287 }
3288 Decl *ToM2;
3289 {
3290 Decl *FromTU =
3291 getTuDecl("struct A { void x() const; }; void A::x() const { }",
3292 Lang_CXX03, "input1.cc");
3293 auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3294 FromTU, functionDecl(hasName("x"), isDefinition()));
3295 ToM2 = Import(FromM, Lang_CXX03);
3296 }
3297 EXPECT_NE(ToM1, ToM2);
3298 }
3299
TEST_P(ASTImporterOptionSpecificTestBase,ImportUnnamedStructsWithRecursingField)3300 TEST_P(ASTImporterOptionSpecificTestBase,
3301 ImportUnnamedStructsWithRecursingField) {
3302 Decl *FromTU = getTuDecl(
3303 R"(
3304 struct A {
3305 struct {
3306 struct A *next;
3307 } entry0;
3308 struct {
3309 struct A *next;
3310 } entry1;
3311 };
3312 )",
3313 Lang_C99, "input0.cc");
3314 auto *From =
3315 FirstDeclMatcher<RecordDecl>().match(FromTU, recordDecl(hasName("A")));
3316
3317 Import(From, Lang_C99);
3318
3319 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3320 auto *Entry0 =
3321 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
3322 auto *Entry1 =
3323 FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry1")));
3324 auto *R0 = getRecordDecl(Entry0);
3325 auto *R1 = getRecordDecl(Entry1);
3326 EXPECT_NE(R0, R1);
3327 EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3328 R0, recordDecl(has(fieldDecl(hasName("next"))))));
3329 EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3330 R1, recordDecl(has(fieldDecl(hasName("next"))))));
3331 }
3332
TEST_P(ASTImporterOptionSpecificTestBase,ImportUnnamedFieldsInCorrectOrder)3333 TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) {
3334 Decl *FromTU = getTuDecl(
3335 R"(
3336 void f(int X, int Y, bool Z) {
3337 (void)[X, Y, Z] { (void)Z; };
3338 }
3339 )",
3340 Lang_CXX11, "input0.cc");
3341 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
3342 FromTU, functionDecl(hasName("f")));
3343 auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11));
3344 EXPECT_TRUE(ToF);
3345
3346 CXXRecordDecl *FromLambda =
3347 cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>(
3348 FromF->getBody())->body_front())->getSubExpr())->getLambdaClass();
3349
3350 auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11));
3351 EXPECT_TRUE(ToLambda);
3352
3353 // Check if the fields of the lambda class are imported in correct order.
3354 unsigned FromIndex = 0u;
3355 for (auto *FromField : FromLambda->fields()) {
3356 ASSERT_FALSE(FromField->getDeclName());
3357 auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11));
3358 EXPECT_TRUE(ToField);
3359 Optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField);
3360 EXPECT_TRUE(ToIndex);
3361 EXPECT_EQ(*ToIndex, FromIndex);
3362 ++FromIndex;
3363 }
3364
3365 EXPECT_EQ(FromIndex, 3u);
3366 }
3367
TEST_P(ASTImporterOptionSpecificTestBase,MergeFieldDeclsOfClassTemplateSpecialization)3368 TEST_P(ASTImporterOptionSpecificTestBase,
3369 MergeFieldDeclsOfClassTemplateSpecialization) {
3370 std::string ClassTemplate =
3371 R"(
3372 template <typename T>
3373 struct X {
3374 int a{0}; // FieldDecl with InitListExpr
3375 X(char) : a(3) {} // (1)
3376 X(int) {} // (2)
3377 };
3378 )";
3379 Decl *ToTU = getToTuDecl(ClassTemplate +
3380 R"(
3381 void foo() {
3382 // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr
3383 X<char> xc('c');
3384 }
3385 )", Lang_CXX11);
3386 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3387 ToTU, classTemplateSpecializationDecl(hasName("X")));
3388 // FieldDecl without InitlistExpr:
3389 auto *ToField = *ToSpec->field_begin();
3390 ASSERT_TRUE(ToField);
3391 ASSERT_FALSE(ToField->getInClassInitializer());
3392 Decl *FromTU = getTuDecl(ClassTemplate +
3393 R"(
3394 void bar() {
3395 // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr
3396 X<char> xc(1);
3397 }
3398 )", Lang_CXX11);
3399 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3400 FromTU, classTemplateSpecializationDecl(hasName("X")));
3401 // FieldDecl with InitlistExpr:
3402 auto *FromField = *FromSpec->field_begin();
3403 ASSERT_TRUE(FromField);
3404 ASSERT_TRUE(FromField->getInClassInitializer());
3405
3406 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3407 ASSERT_TRUE(ImportedSpec);
3408 EXPECT_EQ(ImportedSpec, ToSpec);
3409 // After the import, the FieldDecl has to be merged, thus it should have the
3410 // InitListExpr.
3411 EXPECT_TRUE(ToField->getInClassInitializer());
3412 }
3413
TEST_P(ASTImporterOptionSpecificTestBase,MergeFunctionOfClassTemplateSpecialization)3414 TEST_P(ASTImporterOptionSpecificTestBase,
3415 MergeFunctionOfClassTemplateSpecialization) {
3416 std::string ClassTemplate =
3417 R"(
3418 template <typename T>
3419 struct X {
3420 void f() {}
3421 void g() {}
3422 };
3423 )";
3424 Decl *ToTU = getToTuDecl(ClassTemplate +
3425 R"(
3426 void foo() {
3427 X<char> x;
3428 x.f();
3429 }
3430 )", Lang_CXX11);
3431 Decl *FromTU = getTuDecl(ClassTemplate +
3432 R"(
3433 void bar() {
3434 X<char> x;
3435 x.g();
3436 }
3437 )", Lang_CXX11);
3438 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3439 FromTU, classTemplateSpecializationDecl(hasName("X")));
3440 auto FunPattern = functionDecl(hasName("g"),
3441 hasParent(classTemplateSpecializationDecl()));
3442 auto *FromFun =
3443 FirstDeclMatcher<FunctionDecl>().match(FromTU, FunPattern);
3444 auto *ToFun =
3445 FirstDeclMatcher<FunctionDecl>().match(ToTU, FunPattern);
3446 ASSERT_TRUE(FromFun->hasBody());
3447 ASSERT_FALSE(ToFun->hasBody());
3448 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3449 ASSERT_TRUE(ImportedSpec);
3450 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3451 ToTU, classTemplateSpecializationDecl(hasName("X")));
3452 EXPECT_EQ(ImportedSpec, ToSpec);
3453 EXPECT_TRUE(ToFun->hasBody());
3454 }
3455
TEST_P(ASTImporterOptionSpecificTestBase,MergeTemplateSpecWithForwardDecl)3456 TEST_P(ASTImporterOptionSpecificTestBase, MergeTemplateSpecWithForwardDecl) {
3457 std::string ClassTemplate =
3458 R"(
3459 template<typename T>
3460 struct X { int m; };
3461 template<>
3462 struct X<int> { int m; };
3463 )";
3464 // Append a forward decl for our template specialization.
3465 getToTuDecl(ClassTemplate + "template<> struct X<int>;", Lang_CXX11);
3466 Decl *FromTU = getTuDecl(ClassTemplate, Lang_CXX11);
3467 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3468 FromTU, classTemplateSpecializationDecl(hasName("X"), isDefinition()));
3469 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3470 // Check that our definition got merged with the existing definition.
3471 EXPECT_TRUE(FromSpec->isThisDeclarationADefinition());
3472 EXPECT_TRUE(ImportedSpec->isThisDeclarationADefinition());
3473 }
3474
TEST_P(ASTImporterOptionSpecificTestBase,ODRViolationOfClassTemplateSpecializationsShouldBeReported)3475 TEST_P(ASTImporterOptionSpecificTestBase,
3476 ODRViolationOfClassTemplateSpecializationsShouldBeReported) {
3477 std::string ClassTemplate =
3478 R"(
3479 template <typename T>
3480 struct X {};
3481 )";
3482 Decl *ToTU = getToTuDecl(ClassTemplate +
3483 R"(
3484 template <>
3485 struct X<char> {
3486 int a;
3487 };
3488 void foo() {
3489 X<char> x;
3490 }
3491 )",
3492 Lang_CXX11);
3493 Decl *FromTU = getTuDecl(ClassTemplate +
3494 R"(
3495 template <>
3496 struct X<char> {
3497 int b;
3498 };
3499 void foo() {
3500 X<char> x;
3501 }
3502 )",
3503 Lang_CXX11);
3504 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3505 FromTU, classTemplateSpecializationDecl(hasName("X")));
3506 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3507
3508 // We expect one (ODR) warning during the import.
3509 EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
3510
3511 // The second specialization is different from the first, thus it violates
3512 // ODR, consequently we expect to keep the first specialization only, which is
3513 // already in the "To" context.
3514 EXPECT_FALSE(ImportedSpec);
3515 EXPECT_EQ(1u,
3516 DeclCounter<ClassTemplateSpecializationDecl>().match(
3517 ToTU, classTemplateSpecializationDecl(hasName("X"))));
3518 }
3519
TEST_P(ASTImporterOptionSpecificTestBase,MergeCtorOfClassTemplateSpecialization)3520 TEST_P(ASTImporterOptionSpecificTestBase,
3521 MergeCtorOfClassTemplateSpecialization) {
3522 std::string ClassTemplate =
3523 R"(
3524 template <typename T>
3525 struct X {
3526 X(char) {}
3527 X(int) {}
3528 };
3529 )";
3530 Decl *ToTU = getToTuDecl(ClassTemplate +
3531 R"(
3532 void foo() {
3533 X<char> x('c');
3534 }
3535 )", Lang_CXX11);
3536 Decl *FromTU = getTuDecl(ClassTemplate +
3537 R"(
3538 void bar() {
3539 X<char> x(1);
3540 }
3541 )", Lang_CXX11);
3542 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3543 FromTU, classTemplateSpecializationDecl(hasName("X")));
3544 // Match the void(int) ctor.
3545 auto CtorPattern =
3546 cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))),
3547 hasParent(classTemplateSpecializationDecl()));
3548 auto *FromCtor =
3549 FirstDeclMatcher<CXXConstructorDecl>().match(FromTU, CtorPattern);
3550 auto *ToCtor =
3551 FirstDeclMatcher<CXXConstructorDecl>().match(ToTU, CtorPattern);
3552 ASSERT_TRUE(FromCtor->hasBody());
3553 ASSERT_FALSE(ToCtor->hasBody());
3554 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3555 ASSERT_TRUE(ImportedSpec);
3556 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3557 ToTU, classTemplateSpecializationDecl(hasName("X")));
3558 EXPECT_EQ(ImportedSpec, ToSpec);
3559 EXPECT_TRUE(ToCtor->hasBody());
3560 }
3561
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplateFriendDecl)3562 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) {
3563 const auto *Code =
3564 R"(
3565 template <class T> class X { friend T; };
3566 struct Y {};
3567 template class X<Y>;
3568 )";
3569 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3570 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3571 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3572 FromTU, classTemplateSpecializationDecl());
3573 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3574 ToTU, classTemplateSpecializationDecl());
3575
3576 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3577 EXPECT_EQ(ImportedSpec, ToSpec);
3578 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3579 ToTU, classTemplateSpecializationDecl()));
3580 }
3581
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplatePartialSpecializationsShouldNotBeDuplicated)3582 TEST_P(ASTImporterOptionSpecificTestBase,
3583 ClassTemplatePartialSpecializationsShouldNotBeDuplicated) {
3584 auto Code =
3585 R"(
3586 // primary template
3587 template<class T1, class T2, int I>
3588 class A {};
3589
3590 // partial specialization
3591 template<class T, int I>
3592 class A<T, T*, I> {};
3593 )";
3594 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3595 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3596 auto *FromSpec =
3597 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3598 FromTU, classTemplatePartialSpecializationDecl());
3599 auto *ToSpec =
3600 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3601 ToTU, classTemplatePartialSpecializationDecl());
3602
3603 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3604 EXPECT_EQ(ImportedSpec, ToSpec);
3605 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3606 ToTU, classTemplatePartialSpecializationDecl()));
3607 }
3608
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplateSpecializationsShouldNotBeDuplicated)3609 TEST_P(ASTImporterOptionSpecificTestBase,
3610 ClassTemplateSpecializationsShouldNotBeDuplicated) {
3611 auto Code =
3612 R"(
3613 // primary template
3614 template<class T1, class T2, int I>
3615 class A {};
3616
3617 // full specialization
3618 template<>
3619 class A<int, int, 1> {};
3620 )";
3621 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3622 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3623 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3624 FromTU, classTemplateSpecializationDecl());
3625 auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3626 ToTU, classTemplateSpecializationDecl());
3627
3628 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3629 EXPECT_EQ(ImportedSpec, ToSpec);
3630 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3631 ToTU, classTemplateSpecializationDecl()));
3632 }
3633
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplateFullAndPartialSpecsShouldNotBeMixed)3634 TEST_P(ASTImporterOptionSpecificTestBase,
3635 ClassTemplateFullAndPartialSpecsShouldNotBeMixed) {
3636 std::string PrimaryTemplate =
3637 R"(
3638 template<class T1, class T2, int I>
3639 class A {};
3640 )";
3641 auto PartialSpec =
3642 R"(
3643 template<class T, int I>
3644 class A<T, T*, I> {};
3645 )";
3646 auto FullSpec =
3647 R"(
3648 template<>
3649 class A<int, int, 1> {};
3650 )";
3651 Decl *ToTU = getToTuDecl(PrimaryTemplate + FullSpec, Lang_CXX11);
3652 Decl *FromTU = getTuDecl(PrimaryTemplate + PartialSpec, Lang_CXX11);
3653 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3654 FromTU, classTemplateSpecializationDecl());
3655
3656 auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3657 EXPECT_TRUE(ImportedSpec);
3658 // Check the number of partial specializations.
3659 EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3660 ToTU, classTemplatePartialSpecializationDecl()));
3661 // Check the number of full specializations.
3662 EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3663 ToTU, classTemplateSpecializationDecl(
3664 unless(classTemplatePartialSpecializationDecl()))));
3665 }
3666
TEST_P(ASTImporterOptionSpecificTestBase,InitListExprValueKindShouldBeImported)3667 TEST_P(ASTImporterOptionSpecificTestBase,
3668 InitListExprValueKindShouldBeImported) {
3669 Decl *TU = getTuDecl(
3670 R"(
3671 const int &init();
3672 void foo() { const int &a{init()}; }
3673 )", Lang_CXX11, "input0.cc");
3674 auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a")));
3675 ASSERT_TRUE(FromD->getAnyInitializer());
3676 auto *InitExpr = FromD->getAnyInitializer();
3677 ASSERT_TRUE(InitExpr);
3678 ASSERT_TRUE(InitExpr->isGLValue());
3679
3680 auto *ToD = Import(FromD, Lang_CXX11);
3681 EXPECT_TRUE(ToD);
3682 auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer();
3683 EXPECT_TRUE(ToInitExpr);
3684 EXPECT_TRUE(ToInitExpr->isGLValue());
3685 }
3686
3687 struct ImportVariables : ASTImporterOptionSpecificTestBase {};
3688
TEST_P(ImportVariables,ImportOfOneDeclBringsInTheWholeChain)3689 TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) {
3690 Decl *FromTU = getTuDecl(
3691 R"(
3692 struct A {
3693 static const int a = 1 + 2;
3694 };
3695 const int A::a;
3696 )",
3697 Lang_CXX03, "input1.cc");
3698
3699 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3700 FromTU, varDecl(hasName("a"))); // Decl with init
3701 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3702 FromTU, varDecl(hasName("a"))); // Decl with definition
3703 ASSERT_NE(FromDWithInit, FromDWithDef);
3704 ASSERT_EQ(FromDWithDef->getPreviousDecl(), FromDWithInit);
3705
3706 auto *ToD0 = cast<VarDecl>(Import(FromDWithInit, Lang_CXX11));
3707 auto *ToD1 = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3708 ASSERT_TRUE(ToD0);
3709 ASSERT_TRUE(ToD1);
3710 EXPECT_NE(ToD0, ToD1);
3711 EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
3712 }
3713
TEST_P(ImportVariables,InitAndDefinitionAreInDifferentTUs)3714 TEST_P(ImportVariables, InitAndDefinitionAreInDifferentTUs) {
3715 auto StructA =
3716 R"(
3717 struct A {
3718 static const int a = 1 + 2;
3719 };
3720 )";
3721 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3722 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a;", Lang_CXX03,
3723 "input1.cc");
3724
3725 auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3726 FromTU, varDecl(hasName("a"))); // Decl with init
3727 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3728 FromTU, varDecl(hasName("a"))); // Decl with definition
3729 ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl());
3730 ASSERT_TRUE(FromDWithInit->getInit());
3731 ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition());
3732 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3733 ASSERT_FALSE(FromDWithDef->getInit());
3734
3735 auto *ToD = FirstDeclMatcher<VarDecl>().match(
3736 ToTU, varDecl(hasName("a"))); // Decl with init
3737 ASSERT_TRUE(ToD->getInit());
3738 ASSERT_FALSE(ToD->getDefinition());
3739
3740 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3741 EXPECT_TRUE(ImportedD->getAnyInitializer());
3742 EXPECT_TRUE(ImportedD->getDefinition());
3743 }
3744
TEST_P(ImportVariables,InitAndDefinitionAreInTheFromContext)3745 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) {
3746 auto StructA =
3747 R"(
3748 struct A {
3749 static const int a;
3750 };
3751 )";
3752 Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3753 Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a = 1 + 2;",
3754 Lang_CXX03, "input1.cc");
3755
3756 auto *FromDDeclarationOnly = FirstDeclMatcher<VarDecl>().match(
3757 FromTU, varDecl(hasName("a")));
3758 auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3759 FromTU, varDecl(hasName("a"))); // Decl with definition and with init.
3760 ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl());
3761 ASSERT_FALSE(FromDDeclarationOnly->getInit());
3762 ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition());
3763 ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3764 ASSERT_TRUE(FromDWithDef->getInit());
3765
3766 auto *ToD = FirstDeclMatcher<VarDecl>().match(
3767 ToTU, varDecl(hasName("a")));
3768 ASSERT_FALSE(ToD->getInit());
3769 ASSERT_FALSE(ToD->getDefinition());
3770
3771 auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3772 EXPECT_TRUE(ImportedD->getAnyInitializer());
3773 EXPECT_TRUE(ImportedD->getDefinition());
3774 }
3775
TEST_P(ImportVariables,ImportBindingDecl)3776 TEST_P(ImportVariables, ImportBindingDecl) {
3777 Decl *From, *To;
3778 std::tie(From, To) = getImportedDecl(
3779 R"(
3780 void declToImport() {
3781 int a[2] = {1,2};
3782 auto [x1,y1] = a;
3783 auto& [x2,y2] = a;
3784
3785 struct S {
3786 mutable int x1 : 2;
3787 volatile double y1;
3788 };
3789 S b;
3790 const auto [x3, y3] = b;
3791 };
3792 )",
3793 Lang_CXX17, "", Lang_CXX17);
3794
3795 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl();
3796 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
3797 FromTU, functionDecl(hasName("declToImport")));
3798 auto *ToF = Import(FromF, Lang_CXX17);
3799 EXPECT_TRUE(ToF);
3800
3801 auto VerifyImport = [&](llvm::StringRef BindName) {
3802 auto *FromB = FirstDeclMatcher<BindingDecl>().match(
3803 FromF, bindingDecl(hasName(BindName)));
3804 ASSERT_TRUE(FromB);
3805 auto *ToB = Import(FromB, Lang_CXX17);
3806 EXPECT_TRUE(ToB);
3807 EXPECT_EQ(FromB->getBinding() != nullptr, ToB->getBinding() != nullptr);
3808 EXPECT_EQ(FromB->getDecomposedDecl() != nullptr,
3809 ToB->getDecomposedDecl() != nullptr);
3810 EXPECT_EQ(FromB->getHoldingVar() != nullptr,
3811 ToB->getHoldingVar() != nullptr);
3812 };
3813
3814 VerifyImport("x1");
3815 VerifyImport("y1");
3816 VerifyImport("x2");
3817 VerifyImport("y2");
3818 VerifyImport("x3");
3819 VerifyImport("y3");
3820 }
3821
TEST_P(ImportVariables,ImportDecompositionDeclArray)3822 TEST_P(ImportVariables, ImportDecompositionDeclArray) {
3823 Decl *From, *To;
3824 std::tie(From, To) = getImportedDecl(
3825 R"(
3826 void declToImport() {
3827 int a[2] = {1,2};
3828 auto [x1,y1] = a;
3829 };
3830 )",
3831 Lang_CXX17, "", Lang_CXX17);
3832
3833 TranslationUnitDecl *FromTU = From->getTranslationUnitDecl();
3834 auto *FromDecomp =
3835 FirstDeclMatcher<DecompositionDecl>().match(FromTU, decompositionDecl());
3836 auto *ToDecomp = Import(FromDecomp, Lang_CXX17);
3837 EXPECT_TRUE(ToDecomp);
3838
3839 ArrayRef<BindingDecl *> FromB = FromDecomp->bindings();
3840 ArrayRef<BindingDecl *> ToB = ToDecomp->bindings();
3841 EXPECT_EQ(FromB.size(), ToB.size());
3842 for (unsigned int I = 0; I < FromB.size(); ++I) {
3843 auto *ToBI = Import(FromB[I], Lang_CXX17);
3844 EXPECT_EQ(ToBI, ToB[I]);
3845 }
3846 }
3847
3848 struct ImportClasses : ASTImporterOptionSpecificTestBase {};
3849
TEST_P(ImportClasses,ImportDefinitionWhenProtoIsInNestedToContext)3850 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {
3851 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C99);
3852 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
3853 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
3854 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3855 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
3856
3857 Decl *ImportedDef = Import(FromDef, Lang_C99);
3858
3859 EXPECT_NE(ImportedDef, ToProto);
3860 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
3861 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3862 EXPECT_TRUE(ImportedDef == ToDef);
3863 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
3864 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
3865 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
3866 }
3867
TEST_P(ImportClasses,ImportDefinitionWhenProtoIsInNestedToContextCXX)3868 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) {
3869 Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03);
3870 Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX03, "input1.cc");
3871 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
3872 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3873 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
3874
3875 Decl *ImportedDef = Import(FromDef, Lang_CXX03);
3876
3877 EXPECT_NE(ImportedDef, ToProto);
3878 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
3879 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3880 EXPECT_TRUE(ImportedDef == ToDef);
3881 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
3882 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
3883 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
3884 }
3885
TEST_P(ImportClasses,ImportNestedPrototypeThenDefinition)3886 TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) {
3887 Decl *FromTU0 =
3888 getTuDecl("struct A { struct X *Xp; };", Lang_C99, "input0.cc");
3889 Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
3890 auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
3891 auto FromProto = FirstDeclMatcher<RecordDecl>().match(FromTU0, Pattern);
3892 auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
3893
3894 Decl *ImportedProto = Import(FromProto, Lang_C99);
3895 Decl *ImportedDef = Import(FromDef, Lang_C99);
3896 Decl *ToTU = ImportedDef->getTranslationUnitDecl();
3897
3898 EXPECT_NE(ImportedDef, ImportedProto);
3899 EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
3900 auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3901 auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3902 EXPECT_TRUE(ImportedDef == ToDef);
3903 EXPECT_TRUE(ImportedProto == ToProto);
3904 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
3905 EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
3906 EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
3907 }
3908
3909
3910 struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {};
3911
TEST_P(ImportFriendClasses,ImportOfFriendRecordDoesNotMergeDefinition)3912 TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) {
3913 Decl *FromTU = getTuDecl(
3914 R"(
3915 class A {
3916 template <int I> class F {};
3917 class X {
3918 template <int I> friend class F;
3919 };
3920 };
3921 )",
3922 Lang_CXX03, "input0.cc");
3923
3924 auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
3925 FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
3926 auto *FromFriendClass = LastDeclMatcher<CXXRecordDecl>().match(
3927 FromTU, cxxRecordDecl(hasName("F")));
3928
3929 ASSERT_TRUE(FromClass);
3930 ASSERT_TRUE(FromFriendClass);
3931 ASSERT_NE(FromClass, FromFriendClass);
3932 ASSERT_EQ(FromFriendClass->getDefinition(), FromClass);
3933 ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass);
3934 ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
3935 FromClass->getDescribedClassTemplate());
3936
3937 auto *ToClass = cast<CXXRecordDecl>(Import(FromClass, Lang_CXX03));
3938 auto *ToFriendClass =
3939 cast<CXXRecordDecl>(Import(FromFriendClass, Lang_CXX03));
3940
3941 EXPECT_TRUE(ToClass);
3942 EXPECT_TRUE(ToFriendClass);
3943 EXPECT_NE(ToClass, ToFriendClass);
3944 EXPECT_EQ(ToFriendClass->getDefinition(), ToClass);
3945 EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass);
3946 EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
3947 ToClass->getDescribedClassTemplate());
3948 }
3949
TEST_P(ImportFriendClasses,ImportOfRecursiveFriendClass)3950 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) {
3951 Decl *FromTu = getTuDecl(
3952 R"(
3953 class declToImport {
3954 friend class declToImport;
3955 };
3956 )",
3957 Lang_CXX03, "input.cc");
3958
3959 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
3960 FromTu, cxxRecordDecl(hasName("declToImport")));
3961 auto *ToD = Import(FromD, Lang_CXX03);
3962 auto Pattern = cxxRecordDecl(has(friendDecl()));
3963 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
3964 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
3965 }
3966
TEST_P(ImportFriendClasses,UndeclaredFriendClassShouldNotBeVisible)3967 TEST_P(ImportFriendClasses, UndeclaredFriendClassShouldNotBeVisible) {
3968 Decl *FromTu =
3969 getTuDecl("class X { friend class Y; };", Lang_CXX03, "from.cc");
3970 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
3971 FromTu, cxxRecordDecl(hasName("X")));
3972 auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
3973 RecordDecl *FromRecordOfFriend =
3974 const_cast<RecordDecl *>(getRecordDeclOfFriend(FromFriend));
3975
3976 ASSERT_EQ(FromRecordOfFriend->getDeclContext(), cast<DeclContext>(FromTu));
3977 ASSERT_EQ(FromRecordOfFriend->getLexicalDeclContext(),
3978 cast<DeclContext>(FromX));
3979 ASSERT_FALSE(
3980 FromRecordOfFriend->getDeclContext()->containsDecl(FromRecordOfFriend));
3981 ASSERT_FALSE(FromRecordOfFriend->getLexicalDeclContext()->containsDecl(
3982 FromRecordOfFriend));
3983 ASSERT_FALSE(FromRecordOfFriend->getLookupParent()
3984 ->lookup(FromRecordOfFriend->getDeclName())
3985 .empty());
3986
3987 auto *ToX = Import(FromX, Lang_CXX03);
3988 ASSERT_TRUE(ToX);
3989
3990 Decl *ToTu = ToX->getTranslationUnitDecl();
3991 auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
3992 RecordDecl *ToRecordOfFriend =
3993 const_cast<RecordDecl *>(getRecordDeclOfFriend(ToFriend));
3994
3995 ASSERT_EQ(ToRecordOfFriend->getDeclContext(), cast<DeclContext>(ToTu));
3996 ASSERT_EQ(ToRecordOfFriend->getLexicalDeclContext(), cast<DeclContext>(ToX));
3997 EXPECT_FALSE(
3998 ToRecordOfFriend->getDeclContext()->containsDecl(ToRecordOfFriend));
3999 EXPECT_FALSE(ToRecordOfFriend->getLexicalDeclContext()->containsDecl(
4000 ToRecordOfFriend));
4001 EXPECT_FALSE(ToRecordOfFriend->getLookupParent()
4002 ->lookup(ToRecordOfFriend->getDeclName())
4003 .empty());
4004 }
4005
TEST_P(ImportFriendClasses,ImportOfRecursiveFriendClassTemplate)4006 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) {
4007 Decl *FromTu = getTuDecl(
4008 R"(
4009 template<class A> class declToImport {
4010 template<class A1> friend class declToImport;
4011 };
4012 )",
4013 Lang_CXX03, "input.cc");
4014
4015 auto *FromD =
4016 FirstDeclMatcher<ClassTemplateDecl>().match(FromTu, classTemplateDecl());
4017 auto *ToD = Import(FromD, Lang_CXX03);
4018
4019 auto Pattern = classTemplateDecl(
4020 has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
4021 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
4022 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
4023
4024 auto *Class =
4025 FirstDeclMatcher<ClassTemplateDecl>().match(ToD, classTemplateDecl());
4026 auto *Friend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl());
4027 EXPECT_NE(Friend->getFriendDecl(), Class);
4028 EXPECT_EQ(Friend->getFriendDecl()->getPreviousDecl(), Class);
4029 }
4030
TEST_P(ImportFriendClasses,ProperPrevDeclForClassTemplateDecls)4031 TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) {
4032 auto Pattern = classTemplateSpecializationDecl(hasName("X"));
4033
4034 ClassTemplateSpecializationDecl *Imported1;
4035 {
4036 Decl *FromTU = getTuDecl("template<class T> class X;"
4037 "struct Y { friend class X<int>; };",
4038 Lang_CXX03, "input0.cc");
4039 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4040 FromTU, Pattern);
4041
4042 Imported1 =
4043 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
4044 }
4045 ClassTemplateSpecializationDecl *Imported2;
4046 {
4047 Decl *FromTU = getTuDecl("template<class T> class X;"
4048 "template<> class X<int>{};"
4049 "struct Z { friend class X<int>; };",
4050 Lang_CXX03, "input1.cc");
4051 auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4052 FromTU, Pattern);
4053
4054 Imported2 =
4055 cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
4056 }
4057
4058 Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4059 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(ToTU, Pattern),
4060 2u);
4061 ASSERT_TRUE(Imported2->getPreviousDecl());
4062 EXPECT_EQ(Imported2->getPreviousDecl(), Imported1);
4063 }
4064
TEST_P(ImportFriendClasses,TypeForDeclShouldBeSetInTemplated)4065 TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) {
4066 Decl *FromTU0 = getTuDecl(
4067 R"(
4068 class X {
4069 class Y;
4070 };
4071 class X::Y {
4072 template <typename T>
4073 friend class F; // The decl context of F is the global namespace.
4074 };
4075 )",
4076 Lang_CXX03, "input0.cc");
4077 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4078 FromTU0, classTemplateDecl(hasName("F")));
4079 auto *Imported0 = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
4080 Decl *FromTU1 = getTuDecl(
4081 R"(
4082 template <typename T>
4083 class F {};
4084 )",
4085 Lang_CXX03, "input1.cc");
4086 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4087 FromTU1, classTemplateDecl(hasName("F")));
4088 auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4089 EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(),
4090 Imported1->getTemplatedDecl()->getTypeForDecl());
4091 }
4092
TEST_P(ImportFriendClasses,DeclsFromFriendsShouldBeInRedeclChains)4093 TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) {
4094 Decl *From, *To;
4095 std::tie(From, To) =
4096 getImportedDecl("class declToImport {};", Lang_CXX03,
4097 "class Y { friend class declToImport; };", Lang_CXX03);
4098 auto *Imported = cast<CXXRecordDecl>(To);
4099
4100 EXPECT_TRUE(Imported->getPreviousDecl());
4101 }
4102
TEST_P(ImportFriendClasses,ImportOfClassTemplateDefinitionShouldConnectToFwdFriend)4103 TEST_P(ImportFriendClasses,
4104 ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
4105 Decl *ToTU = getToTuDecl(
4106 R"(
4107 class X {
4108 class Y;
4109 };
4110 class X::Y {
4111 template <typename T>
4112 friend class F; // The decl context of F is the global namespace.
4113 };
4114 )",
4115 Lang_CXX03);
4116 auto *ToDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
4117 ToTU, classTemplateDecl(hasName("F")));
4118 Decl *FromTU = getTuDecl(
4119 R"(
4120 template <typename T>
4121 class F {};
4122 )",
4123 Lang_CXX03, "input0.cc");
4124 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4125 FromTU, classTemplateDecl(hasName("F")));
4126 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4127 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4128 EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl());
4129 EXPECT_EQ(ToDecl->getTemplatedDecl(),
4130 ImportedDef->getTemplatedDecl()->getPreviousDecl());
4131 }
4132
TEST_P(ImportFriendClasses,ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked)4133 TEST_P(ImportFriendClasses,
4134 ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) {
4135 Decl *FromTU0 = getTuDecl(
4136 R"(
4137 class X {
4138 class Y;
4139 };
4140 class X::Y {
4141 template <typename T>
4142 friend class F; // The decl context of F is the global namespace.
4143 };
4144 )",
4145 Lang_CXX03, "input0.cc");
4146 auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
4147 FromTU0, classTemplateDecl(hasName("F")));
4148 auto *ImportedFwd = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
4149 Decl *FromTU1 = getTuDecl(
4150 R"(
4151 template <typename T>
4152 class F {};
4153 )",
4154 Lang_CXX03, "input1.cc");
4155 auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
4156 FromTU1, classTemplateDecl(hasName("F")));
4157 auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
4158 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4159 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
4160 EXPECT_EQ(ImportedFwd->getTemplatedDecl(),
4161 ImportedDef->getTemplatedDecl()->getPreviousDecl());
4162 }
4163
TEST_P(ImportFriendClasses,ImportOfClassDefinitionAndFwdFriendShouldBeLinked)4164 TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
4165 Decl *FromTU0 = getTuDecl(
4166 R"(
4167 class X {
4168 class Y;
4169 };
4170 class X::Y {
4171 friend class F; // The decl context of F is the global namespace.
4172 };
4173 )",
4174 Lang_CXX03, "input0.cc");
4175 auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl());
4176 QualType FT = Friend->getFriendType()->getType();
4177 FT = FromTU0->getASTContext().getCanonicalType(FT);
4178 auto *Fwd = cast<TagType>(FT)->getDecl();
4179 auto *ImportedFwd = Import(Fwd, Lang_CXX03);
4180 Decl *FromTU1 = getTuDecl(
4181 R"(
4182 class F {};
4183 )",
4184 Lang_CXX03, "input1.cc");
4185 auto *Definition = FirstDeclMatcher<CXXRecordDecl>().match(
4186 FromTU1, cxxRecordDecl(hasName("F")));
4187 auto *ImportedDef = Import(Definition, Lang_CXX03);
4188 EXPECT_TRUE(ImportedDef->getPreviousDecl());
4189 EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
4190 }
4191
TEST_P(ImportFriendClasses,ImportOfRepeatedFriendType)4192 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) {
4193 const char *Code =
4194 R"(
4195 class Container {
4196 friend class X;
4197 friend class X;
4198 };
4199 )";
4200 Decl *ToTu = getToTuDecl(Code, Lang_CXX03);
4201 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc");
4202
4203 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4204 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4205 auto *FromFriend1 =
4206 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4207 auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4208
4209 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03);
4210 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03);
4211
4212 EXPECT_NE(ToImportedFriend1, ToImportedFriend2);
4213 EXPECT_EQ(ToFriend1, ToImportedFriend1);
4214 EXPECT_EQ(ToFriend2, ToImportedFriend2);
4215 }
4216
TEST_P(ImportFriendClasses,ImportOfRepeatedFriendDecl)4217 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) {
4218 const char *Code =
4219 R"(
4220 class Container {
4221 friend void f();
4222 friend void f();
4223 };
4224 )";
4225 Decl *ToTu = getToTuDecl(Code, Lang_CXX03);
4226 Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc");
4227
4228 auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4229 auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
4230 auto *FromFriend1 =
4231 FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4232 auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
4233
4234 FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03);
4235 FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03);
4236
4237 EXPECT_NE(ToImportedFriend1, ToImportedFriend2);
4238 EXPECT_EQ(ToFriend1, ToImportedFriend1);
4239 EXPECT_EQ(ToFriend2, ToImportedFriend2);
4240 }
4241
TEST_P(ASTImporterOptionSpecificTestBase,FriendFunInClassTemplate)4242 TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) {
4243 auto *Code = R"(
4244 template <class T>
4245 struct X {
4246 friend void foo(){}
4247 };
4248 )";
4249 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
4250 auto *ToFoo = FirstDeclMatcher<FunctionDecl>().match(
4251 ToTU, functionDecl(hasName("foo")));
4252
4253 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
4254 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
4255 FromTU, functionDecl(hasName("foo")));
4256 auto *ImportedFoo = Import(FromFoo, Lang_CXX03);
4257 EXPECT_EQ(ImportedFoo, ToFoo);
4258 }
4259
4260 struct DeclContextTest : ASTImporterOptionSpecificTestBase {};
4261
TEST_P(DeclContextTest,removeDeclOfClassTemplateSpecialization)4262 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
4263 Decl *TU = getTuDecl(
4264 R"(
4265 namespace NS {
4266
4267 template <typename T>
4268 struct S {};
4269 template struct S<int>;
4270
4271 inline namespace INS {
4272 template <typename T>
4273 struct S {};
4274 template struct S<int>;
4275 }
4276
4277 }
4278 )", Lang_CXX11, "input0.cc");
4279 auto *NS = FirstDeclMatcher<NamespaceDecl>().match(
4280 TU, namespaceDecl());
4281 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4282 TU, classTemplateSpecializationDecl());
4283 ASSERT_TRUE(NS->containsDecl(Spec));
4284
4285 NS->removeDecl(Spec);
4286 EXPECT_FALSE(NS->containsDecl(Spec));
4287 }
4288
TEST_P(DeclContextTest,removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage)4289 TEST_P(DeclContextTest,
4290 removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) {
4291 Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX03);
4292 auto *A0 = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
4293 auto *A1 = LastDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
4294
4295 // Investigate the list.
4296 auto *DC = A0->getDeclContext();
4297 ASSERT_TRUE(DC->containsDecl(A0));
4298 ASSERT_TRUE(DC->containsDecl(A1));
4299
4300 // Investigate the lookup table.
4301 auto *Map = DC->getLookupPtr();
4302 ASSERT_TRUE(Map);
4303 auto I = Map->find(A0->getDeclName());
4304 ASSERT_NE(I, Map->end());
4305 StoredDeclsList &L = I->second;
4306 // The lookup table contains the most recent decl of A.
4307 ASSERT_NE(L.getAsDecl(), A0);
4308 ASSERT_EQ(L.getAsDecl(), A1);
4309
4310 ASSERT_TRUE(L.getAsDecl());
4311 // Simulate the private function DeclContext::reconcileExternalVisibleStorage.
4312 // We do not have a list with one element.
4313 L.setHasExternalDecls();
4314 ASSERT_FALSE(L.getAsList());
4315 auto Results = L.getLookupResult();
4316 ASSERT_EQ(1u, std::distance(Results.begin(), Results.end()));
4317
4318 // This asserts in the old implementation.
4319 DC->removeDecl(A0);
4320 EXPECT_FALSE(DC->containsDecl(A0));
4321
4322 // Make sure we do not leave a StoredDeclsList with no entries.
4323 DC->removeDecl(A1);
4324 ASSERT_EQ(Map->find(A1->getDeclName()), Map->end());
4325 }
4326
4327 struct ImportFunctionTemplateSpecializations
4328 : ASTImporterOptionSpecificTestBase {};
4329
TEST_P(ImportFunctionTemplateSpecializations,TUshouldNotContainFunctionTemplateImplicitInstantiation)4330 TEST_P(ImportFunctionTemplateSpecializations,
4331 TUshouldNotContainFunctionTemplateImplicitInstantiation) {
4332
4333 Decl *FromTU = getTuDecl(
4334 R"(
4335 template<class T>
4336 int f() { return 0; }
4337 void foo() { f<int>(); }
4338 )",
4339 Lang_CXX03, "input0.cc");
4340
4341 // Check that the function template instantiation is NOT the child of the TU.
4342 auto Pattern = translationUnitDecl(
4343 unless(has(functionDecl(hasName("f"), isTemplateInstantiation()))));
4344 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4345
4346 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
4347 FromTU, functionDecl(hasName("foo")));
4348 ASSERT_TRUE(Import(Foo, Lang_CXX03));
4349
4350 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4351 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4352 }
4353
TEST_P(ImportFunctionTemplateSpecializations,TUshouldNotContainFunctionTemplateExplicitInstantiation)4354 TEST_P(ImportFunctionTemplateSpecializations,
4355 TUshouldNotContainFunctionTemplateExplicitInstantiation) {
4356
4357 Decl *FromTU = getTuDecl(
4358 R"(
4359 template<class T>
4360 int f() { return 0; }
4361 template int f<int>();
4362 )",
4363 Lang_CXX03, "input0.cc");
4364
4365 // Check that the function template instantiation is NOT the child of the TU.
4366 auto Instantiation = functionDecl(hasName("f"), isTemplateInstantiation());
4367 auto Pattern = translationUnitDecl(unless(has(Instantiation)));
4368 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4369
4370 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation),
4371 Lang_CXX03));
4372
4373 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4374 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4375 }
4376
TEST_P(ImportFunctionTemplateSpecializations,TUshouldContainFunctionTemplateSpecialization)4377 TEST_P(ImportFunctionTemplateSpecializations,
4378 TUshouldContainFunctionTemplateSpecialization) {
4379
4380 Decl *FromTU = getTuDecl(
4381 R"(
4382 template<class T>
4383 int f() { return 0; }
4384 template <> int f<int>() { return 4; }
4385 )",
4386 Lang_CXX03, "input0.cc");
4387
4388 // Check that the function template specialization is the child of the TU.
4389 auto Specialization =
4390 functionDecl(hasName("f"), isExplicitTemplateSpecialization());
4391 auto Pattern = translationUnitDecl(has(Specialization));
4392 ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4393
4394 ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization),
4395 Lang_CXX03));
4396
4397 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4398 EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4399 }
4400
TEST_P(ImportFunctionTemplateSpecializations,FunctionTemplateSpecializationRedeclChain)4401 TEST_P(ImportFunctionTemplateSpecializations,
4402 FunctionTemplateSpecializationRedeclChain) {
4403
4404 Decl *FromTU = getTuDecl(
4405 R"(
4406 template<class T>
4407 int f() { return 0; }
4408 template <> int f<int>() { return 4; }
4409 )",
4410 Lang_CXX03, "input0.cc");
4411
4412 auto Spec = functionDecl(hasName("f"), isExplicitTemplateSpecialization(),
4413 hasParent(translationUnitDecl()));
4414 auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec);
4415 {
4416 auto *TU = FromTU;
4417 auto *SpecD = FromSpecD;
4418 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4419 TU, functionTemplateDecl());
4420 auto *FirstSpecD = *(TemplateD->spec_begin());
4421 ASSERT_EQ(SpecD, FirstSpecD);
4422 ASSERT_TRUE(SpecD->getPreviousDecl());
4423 ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4424 ->doesThisDeclarationHaveABody());
4425 }
4426
4427 ASSERT_TRUE(Import(FromSpecD, Lang_CXX03));
4428
4429 {
4430 auto *TU = ToAST->getASTContext().getTranslationUnitDecl();
4431 auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec);
4432 auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4433 TU, functionTemplateDecl());
4434 auto *FirstSpecD = *(TemplateD->spec_begin());
4435 EXPECT_EQ(SpecD, FirstSpecD);
4436 ASSERT_TRUE(SpecD->getPreviousDecl());
4437 EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4438 ->doesThisDeclarationHaveABody());
4439 }
4440 }
4441
TEST_P(ImportFunctionTemplateSpecializations,MatchNumberOfFunctionTemplateSpecializations)4442 TEST_P(ImportFunctionTemplateSpecializations,
4443 MatchNumberOfFunctionTemplateSpecializations) {
4444
4445 Decl *FromTU = getTuDecl(
4446 R"(
4447 template <typename T> constexpr int f() { return 0; }
4448 template <> constexpr int f<int>() { return 4; }
4449 void foo() {
4450 static_assert(f<char>() == 0, "");
4451 static_assert(f<int>() == 4, "");
4452 }
4453 )",
4454 Lang_CXX11, "input0.cc");
4455 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
4456 FromTU, functionDecl(hasName("foo")));
4457
4458 Import(FromD, Lang_CXX11);
4459 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4460 EXPECT_EQ(
4461 DeclCounter<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))),
4462 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))));
4463 }
4464
TEST_P(ASTImporterOptionSpecificTestBase,ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined)4465 TEST_P(ASTImporterOptionSpecificTestBase,
4466 ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
4467 {
4468 Decl *FromTU = getTuDecl(
4469 R"(
4470 template <typename T>
4471 struct B;
4472 )",
4473 Lang_CXX03, "input0.cc");
4474 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4475 FromTU, classTemplateDecl(hasName("B")));
4476
4477 Import(FromD, Lang_CXX03);
4478 }
4479
4480 {
4481 Decl *FromTU = getTuDecl(
4482 R"(
4483 template <typename T>
4484 struct B {
4485 void f();
4486 B* b;
4487 };
4488 )",
4489 Lang_CXX03, "input1.cc");
4490 FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
4491 FromTU, functionDecl(hasName("f")));
4492 Import(FromD, Lang_CXX03);
4493 auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
4494 FromTU, classTemplateDecl(hasName("B")));
4495 auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
4496 EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
4497
4498 // We expect no (ODR) warning during the import.
4499 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4500 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
4501 }
4502 }
4503
TEST_P(ASTImporterOptionSpecificTestBase,ImportingTypedefShouldImportTheCompleteType)4504 TEST_P(ASTImporterOptionSpecificTestBase,
4505 ImportingTypedefShouldImportTheCompleteType) {
4506 // We already have an incomplete underlying type in the "To" context.
4507 auto Code =
4508 R"(
4509 template <typename T>
4510 struct S {
4511 void foo();
4512 };
4513 using U = S<int>;
4514 )";
4515 Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
4516 auto *ToD = FirstDeclMatcher<TypedefNameDecl>().match(ToTU,
4517 typedefNameDecl(hasName("U")));
4518 ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType());
4519
4520 // The "From" context has the same typedef, but the underlying type is
4521 // complete this time.
4522 Decl *FromTU = getTuDecl(std::string(Code) +
4523 R"(
4524 void foo(U* u) {
4525 u->foo();
4526 }
4527 )", Lang_CXX11);
4528 auto *FromD = FirstDeclMatcher<TypedefNameDecl>().match(FromTU,
4529 typedefNameDecl(hasName("U")));
4530 ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType());
4531
4532 // The imported type should be complete.
4533 auto *ImportedD = cast<TypedefNameDecl>(Import(FromD, Lang_CXX11));
4534 EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType());
4535 }
4536
TEST_P(ASTImporterOptionSpecificTestBase,ImportTemplateParameterLists)4537 TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) {
4538 auto Code =
4539 R"(
4540 template<class T>
4541 int f() { return 0; }
4542 template <> int f<int>() { return 4; }
4543 )";
4544
4545 Decl *FromTU = getTuDecl(Code, Lang_CXX03);
4546 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU,
4547 functionDecl(hasName("f"), isExplicitTemplateSpecialization()));
4548 ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1u);
4549
4550 auto *ToD = Import(FromD, Lang_CXX03);
4551 // The template parameter list should exist.
4552 EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1u);
4553 }
4554
4555 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl>
4556 varTemplateDecl;
4557
4558 const internal::VariadicDynCastAllOfMatcher<
4559 Decl, VarTemplatePartialSpecializationDecl>
4560 varTemplatePartialSpecializationDecl;
4561
TEST_P(ASTImporterOptionSpecificTestBase,FunctionTemplateParameterDeclContext)4562 TEST_P(ASTImporterOptionSpecificTestBase,
4563 FunctionTemplateParameterDeclContext) {
4564 constexpr auto Code =
4565 R"(
4566 template<class T>
4567 void f() {};
4568 )";
4569
4570 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
4571
4572 auto *FromD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4573 FromTU, functionTemplateDecl(hasName("f")));
4574
4575 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(),
4576 FromD->getTemplatedDecl());
4577
4578 auto *ToD = Import(FromD, Lang_CXX11);
4579 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(),
4580 ToD->getTemplatedDecl());
4581 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4582 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0)));
4583 }
4584
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplateParameterDeclContext)4585 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateParameterDeclContext) {
4586 constexpr auto Code =
4587 R"(
4588 template<class T1, class T2>
4589 struct S {};
4590 template<class T2>
4591 struct S<int, T2> {};
4592 )";
4593
4594 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
4595
4596 auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4597 FromTU, classTemplateDecl(hasName("S")));
4598 auto *FromDPart =
4599 FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
4600 FromTU, classTemplatePartialSpecializationDecl(hasName("S")));
4601
4602 ASSERT_EQ(FromD->getTemplateParameters()->getParam(0)->getDeclContext(),
4603 FromD->getTemplatedDecl());
4604 ASSERT_EQ(FromDPart->getTemplateParameters()->getParam(0)->getDeclContext(),
4605 FromDPart);
4606
4607 auto *ToD = Import(FromD, Lang_CXX11);
4608 auto *ToDPart = Import(FromDPart, Lang_CXX11);
4609
4610 EXPECT_EQ(ToD->getTemplateParameters()->getParam(0)->getDeclContext(),
4611 ToD->getTemplatedDecl());
4612 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4613 ToD->getTemplatedDecl(), ToD->getTemplateParameters()->getParam(0)));
4614
4615 EXPECT_EQ(ToDPart->getTemplateParameters()->getParam(0)->getDeclContext(),
4616 ToDPart);
4617 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4618 ToDPart, ToDPart->getTemplateParameters()->getParam(0)));
4619 }
4620
TEST_P(ASTImporterOptionSpecificTestBase,CXXDeductionGuideTemplateParameterDeclContext)4621 TEST_P(ASTImporterOptionSpecificTestBase,
4622 CXXDeductionGuideTemplateParameterDeclContext) {
4623 Decl *FromTU = getTuDecl(
4624 R"(
4625 template <typename T> struct A {
4626 A(T);
4627 };
4628 A a{(int)0};
4629 )",
4630 Lang_CXX17, "input.cc");
4631 // clang-format off
4632 /*
4633 |-ClassTemplateDecl 0x1fe5000 <input.cc:2:7, line:4:7> line:2:36 A
4634 | |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
4635 | |-CXXRecordDecl 0x1fe4f70 <col:29, line:4:7> line:2:36 struct A definition
4636
4637 |-FunctionTemplateDecl 0x1fe5860 <line:2:7, line:3:12> col:9 implicit <deduction guide for A>
4638 | |-TemplateTypeParmDecl 0x1fe4eb0 <line:2:17, col:26> col:26 referenced typename depth 0 index 0 T
4639 | |-CXXDeductionGuideDecl 0x1fe57a8 <line:3:9, col:12> col:9 implicit <deduction guide for A> 'auto (T) -> A<T>'
4640 | | `-ParmVarDecl 0x1fe56b0 <col:11> col:12 'T'
4641 | `-CXXDeductionGuideDecl 0x20515d8 <col:9, col:12> col:9 implicit used <deduction guide for A> 'auto (int) -> A<int>'
4642 | |-TemplateArgument type 'int'
4643 | | `-BuiltinType 0x20587e0 'int'
4644 | `-ParmVarDecl 0x2051388 <col:11> col:12 'int':'int'
4645 `-FunctionTemplateDecl 0x1fe5a78 <line:2:7, col:36> col:36 implicit <deduction guide for A>
4646 |-TemplateTypeParmDecl 0x1fe4eb0 <col:17, col:26> col:26 referenced typename depth 0 index 0 T
4647 `-CXXDeductionGuideDecl 0x1fe59c0 <col:36> col:36 implicit <deduction guide for A> 'auto (A<T>) -> A<T>'
4648 `-ParmVarDecl 0x1fe5958 <col:36> col:36 'A<T>'
4649 */
4650 // clang-format on
4651 auto *FromD1 = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
4652 FromTU, cxxDeductionGuideDecl());
4653 auto *FromD2 = LastDeclMatcher<CXXDeductionGuideDecl>().match(
4654 FromTU, cxxDeductionGuideDecl());
4655
4656 NamedDecl *P1 =
4657 FromD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
4658 0);
4659 NamedDecl *P2 =
4660 FromD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
4661 0);
4662 DeclContext *DC = P1->getDeclContext();
4663
4664 ASSERT_EQ(P1, P2);
4665 ASSERT_TRUE(DC == FromD1 || DC == FromD2);
4666
4667 auto *ToD1 = Import(FromD1, Lang_CXX17);
4668 auto *ToD2 = Import(FromD2, Lang_CXX17);
4669 ASSERT_TRUE(ToD1 && ToD2);
4670
4671 P1 = ToD1->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
4672 0);
4673 P2 = ToD2->getDescribedFunctionTemplate()->getTemplateParameters()->getParam(
4674 0);
4675 DC = P1->getDeclContext();
4676
4677 EXPECT_EQ(P1, P2);
4678 EXPECT_TRUE(DC == ToD1 || DC == ToD2);
4679
4680 ASTImporterLookupTable *Tbl = SharedStatePtr->getLookupTable();
4681 if (Tbl->contains(ToD1, P1)) {
4682 EXPECT_FALSE(Tbl->contains(ToD2, P1));
4683 } else {
4684 EXPECT_TRUE(Tbl->contains(ToD2, P1));
4685 }
4686 }
4687
TEST_P(ASTImporterOptionSpecificTestBase,VarTemplateParameterDeclContext)4688 TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) {
4689 constexpr auto Code =
4690 R"(
4691 template<class T1, class T2>
4692 int X1;
4693 template<class T2>
4694 int X1<int, T2>;
4695
4696 namespace Ns {
4697 template<class T1, class T2>
4698 int X2;
4699 template<class T2>
4700 int X2<int, T2>;
4701 }
4702 )";
4703
4704 Decl *FromTU = getTuDecl(Code, Lang_CXX14);
4705
4706 auto *FromD1 = FirstDeclMatcher<VarTemplateDecl>().match(
4707 FromTU, varTemplateDecl(hasName("X1")));
4708 auto *FromD1Part =
4709 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match(
4710 FromTU, varTemplatePartialSpecializationDecl(hasName("X1")));
4711 auto *FromD2 = FirstDeclMatcher<VarTemplateDecl>().match(
4712 FromTU, varTemplateDecl(hasName("X2")));
4713 auto *FromD2Part =
4714 FirstDeclMatcher<VarTemplatePartialSpecializationDecl>().match(
4715 FromTU, varTemplatePartialSpecializationDecl(hasName("X2")));
4716
4717 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(),
4718 FromD1->getDeclContext());
4719 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(),
4720 FromD2->getDeclContext());
4721
4722 ASSERT_EQ(FromD1Part->getTemplateParameters()->getParam(0)->getDeclContext(),
4723 FromD1Part->getDeclContext());
4724 // FIXME: VarTemplatePartialSpecializationDecl does not update ("adopt")
4725 // template parameter decl context
4726 // ASSERT_EQ(FromD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
4727 // FromD2Part->getDeclContext());
4728
4729 auto *ToD1 = Import(FromD1, Lang_CXX14);
4730 auto *ToD2 = Import(FromD2, Lang_CXX14);
4731
4732 auto *ToD1Part = Import(FromD1Part, Lang_CXX14);
4733 auto *ToD2Part = Import(FromD2Part, Lang_CXX14);
4734
4735 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(),
4736 ToD1->getDeclContext());
4737 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4738 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0)));
4739 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(),
4740 ToD2->getDeclContext());
4741 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4742 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0)));
4743
4744 EXPECT_EQ(ToD1Part->getTemplateParameters()->getParam(0)->getDeclContext(),
4745 ToD1Part->getDeclContext());
4746 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4747 ToD1Part->getDeclContext(),
4748 ToD1Part->getTemplateParameters()->getParam(0)));
4749 // EXPECT_EQ(ToD2Part->getTemplateParameters()->getParam(0)->getDeclContext(),
4750 // ToD2Part->getDeclContext());
4751 // EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4752 // ToD2Part->getDeclContext(),
4753 // ToD2Part->getTemplateParameters()->getParam(0)));
4754 (void)ToD2Part;
4755 }
4756
TEST_P(ASTImporterOptionSpecificTestBase,TypeAliasTemplateParameterDeclContext)4757 TEST_P(ASTImporterOptionSpecificTestBase,
4758 TypeAliasTemplateParameterDeclContext) {
4759 constexpr auto Code =
4760 R"(
4761 template<class T1, class T2>
4762 struct S {};
4763 template<class T> using S1 = S<T, int>;
4764 namespace Ns {
4765 template<class T> using S2 = S<T, int>;
4766 }
4767 )";
4768
4769 Decl *FromTU = getTuDecl(Code, Lang_CXX11);
4770
4771 auto *FromD1 = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
4772 FromTU, typeAliasTemplateDecl(hasName("S1")));
4773 auto *FromD2 = FirstDeclMatcher<TypeAliasTemplateDecl>().match(
4774 FromTU, typeAliasTemplateDecl(hasName("S2")));
4775
4776 ASSERT_EQ(FromD1->getTemplateParameters()->getParam(0)->getDeclContext(),
4777 FromD1->getDeclContext());
4778 ASSERT_EQ(FromD2->getTemplateParameters()->getParam(0)->getDeclContext(),
4779 FromD2->getDeclContext());
4780
4781 auto *ToD1 = Import(FromD1, Lang_CXX11);
4782 auto *ToD2 = Import(FromD2, Lang_CXX11);
4783
4784 EXPECT_EQ(ToD1->getTemplateParameters()->getParam(0)->getDeclContext(),
4785 ToD1->getDeclContext());
4786 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4787 ToD1->getDeclContext(), ToD1->getTemplateParameters()->getParam(0)));
4788 EXPECT_EQ(ToD2->getTemplateParameters()->getParam(0)->getDeclContext(),
4789 ToD2->getDeclContext());
4790 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
4791 ToD2->getDeclContext(), ToD2->getTemplateParameters()->getParam(0)));
4792 }
4793
4794 const AstTypeMatcher<SubstTemplateTypeParmPackType>
4795 substTemplateTypeParmPackType;
4796
TEST_P(ASTImporterOptionSpecificTestBase,ImportSubstTemplateTypeParmPackType)4797 TEST_P(ASTImporterOptionSpecificTestBase, ImportSubstTemplateTypeParmPackType) {
4798 constexpr auto Code = R"(
4799 template<typename ...T> struct D {
4800 template<typename... U> using B = int(int (*...p)(T, U));
4801 template<typename U1, typename U2> D(B<U1, U2>*);
4802 };
4803 int f(int(int, int), int(int, int));
4804
4805 using asd = D<float, double, float>::B<int, long, int>;
4806 )";
4807 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cpp");
4808 auto *FromClass = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4809 FromTU, classTemplateSpecializationDecl());
4810
4811 {
4812 ASTContext &FromCtx = FromTU->getASTContext();
4813 const auto *FromSubstPack = selectFirst<SubstTemplateTypeParmPackType>(
4814 "pack", match(substTemplateTypeParmPackType().bind("pack"), FromCtx));
4815
4816 ASSERT_TRUE(FromSubstPack);
4817 ASSERT_EQ(FromSubstPack->getIdentifier()->getName(), "T");
4818 ArrayRef<TemplateArgument> FromArgPack =
4819 FromSubstPack->getArgumentPack().pack_elements();
4820 ASSERT_EQ(FromArgPack.size(), 3u);
4821 ASSERT_EQ(FromArgPack[0].getAsType(), FromCtx.FloatTy);
4822 ASSERT_EQ(FromArgPack[1].getAsType(), FromCtx.DoubleTy);
4823 ASSERT_EQ(FromArgPack[2].getAsType(), FromCtx.FloatTy);
4824 }
4825 {
4826 // Let's do the import.
4827 ClassTemplateSpecializationDecl *ToClass = Import(FromClass, Lang_CXX11);
4828 ASTContext &ToCtx = ToClass->getASTContext();
4829
4830 const auto *ToSubstPack = selectFirst<SubstTemplateTypeParmPackType>(
4831 "pack", match(substTemplateTypeParmPackType().bind("pack"), ToCtx));
4832
4833 // Check if it meets the requirements.
4834 ASSERT_TRUE(ToSubstPack);
4835 ASSERT_EQ(ToSubstPack->getIdentifier()->getName(), "T");
4836 ArrayRef<TemplateArgument> ToArgPack =
4837 ToSubstPack->getArgumentPack().pack_elements();
4838 ASSERT_EQ(ToArgPack.size(), 3u);
4839 ASSERT_EQ(ToArgPack[0].getAsType(), ToCtx.FloatTy);
4840 ASSERT_EQ(ToArgPack[1].getAsType(), ToCtx.DoubleTy);
4841 ASSERT_EQ(ToArgPack[2].getAsType(), ToCtx.FloatTy);
4842 }
4843 }
4844
4845 struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {};
4846
TEST_P(ASTImporterLookupTableTest,OneDecl)4847 TEST_P(ASTImporterLookupTableTest, OneDecl) {
4848 auto *ToTU = getToTuDecl("int a;", Lang_CXX03);
4849 auto *D = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("a")));
4850 ASTImporterLookupTable LT(*ToTU);
4851 auto Res = LT.lookup(ToTU, D->getDeclName());
4852 ASSERT_EQ(Res.size(), 1u);
4853 EXPECT_EQ(*Res.begin(), D);
4854 }
4855
findInDeclListOfDC(DeclContext * DC,DeclarationName Name)4856 static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) {
4857 for (Decl *D : DC->decls()) {
4858 if (auto *ND = dyn_cast<NamedDecl>(D))
4859 if (ND->getDeclName() == Name)
4860 return ND;
4861 }
4862 return nullptr;
4863 }
4864
TEST_P(ASTImporterLookupTableTest,FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup)4865 TEST_P(ASTImporterLookupTableTest,
4866 FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) {
4867 auto *Code = R"(
4868 template <class T>
4869 struct X {
4870 friend void foo(){}
4871 };
4872 )";
4873 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
4874 auto *X = FirstDeclMatcher<ClassTemplateDecl>().match(
4875 ToTU, classTemplateDecl(hasName("X")));
4876 auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
4877 ToTU, functionDecl(hasName("foo")));
4878 DeclContext *FooDC = Foo->getDeclContext();
4879 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
4880 ASSERT_EQ(cast<Decl>(FooLexicalDC), X->getTemplatedDecl());
4881 ASSERT_EQ(cast<Decl>(FooDC), ToTU);
4882 DeclarationName FooName = Foo->getDeclName();
4883
4884 // Cannot find in the LookupTable of its DC (TUDecl)
4885 SmallVector<NamedDecl *, 2> FoundDecls;
4886 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4887 EXPECT_EQ(FoundDecls.size(), 0u);
4888
4889 // Cannot find in the LookupTable of its LexicalDC (X)
4890 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4891 EXPECT_EQ(FoundDecls.size(), 0u);
4892
4893 // Can't find in the list of Decls of the DC.
4894 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
4895
4896 // Can't find in the list of Decls of the LexicalDC
4897 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr);
4898
4899 // ASTImporter specific lookup finds it.
4900 ASTImporterLookupTable LT(*ToTU);
4901 auto Res = LT.lookup(FooDC, Foo->getDeclName());
4902 ASSERT_EQ(Res.size(), 1u);
4903 EXPECT_EQ(*Res.begin(), Foo);
4904 }
4905
TEST_P(ASTImporterLookupTableTest,FwdDeclStructShouldBeFoundByImporterSpecificLookup)4906 TEST_P(ASTImporterLookupTableTest,
4907 FwdDeclStructShouldBeFoundByImporterSpecificLookup) {
4908 TranslationUnitDecl *ToTU =
4909 getToTuDecl("struct A { struct Foo *p; };", Lang_C99);
4910 auto *Foo =
4911 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("Foo")));
4912 auto *A =
4913 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
4914 DeclContext *FooDC = Foo->getDeclContext();
4915 DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
4916 ASSERT_EQ(cast<Decl>(FooLexicalDC), A);
4917 ASSERT_EQ(cast<Decl>(FooDC), ToTU);
4918 DeclarationName FooName = Foo->getDeclName();
4919
4920 // Cannot find in the LookupTable of its DC (TUDecl).
4921 SmallVector<NamedDecl *, 2> FoundDecls;
4922 FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4923 EXPECT_EQ(FoundDecls.size(), 0u);
4924
4925 // Cannot find in the LookupTable of its LexicalDC (A).
4926 FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4927 EXPECT_EQ(FoundDecls.size(), 0u);
4928
4929 // Can't find in the list of Decls of the DC.
4930 EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
4931
4932 // Can find in the list of Decls of the LexicalDC.
4933 EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo);
4934
4935 // ASTImporter specific lookup finds it.
4936 ASTImporterLookupTable LT(*ToTU);
4937 auto Res = LT.lookup(FooDC, Foo->getDeclName());
4938 ASSERT_EQ(Res.size(), 1u);
4939 EXPECT_EQ(*Res.begin(), Foo);
4940 }
4941
TEST_P(ASTImporterLookupTableTest,LookupFindsNamesInDifferentDC)4942 TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) {
4943 TranslationUnitDecl *ToTU =
4944 getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99);
4945 DeclarationName VName = FirstDeclMatcher<VarDecl>()
4946 .match(ToTU, varDecl(hasName("V")))
4947 ->getDeclName();
4948 auto *A =
4949 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
4950 auto *B =
4951 FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("B")));
4952
4953 ASTImporterLookupTable LT(*ToTU);
4954
4955 auto Res = LT.lookup(cast<DeclContext>(A), VName);
4956 ASSERT_EQ(Res.size(), 1u);
4957 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
4958 ToTU, fieldDecl(hasName("V"),
4959 hasParent(recordDecl(hasName("A"))))));
4960 Res = LT.lookup(cast<DeclContext>(B), VName);
4961 ASSERT_EQ(Res.size(), 1u);
4962 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
4963 ToTU, fieldDecl(hasName("V"),
4964 hasParent(recordDecl(hasName("B"))))));
4965 Res = LT.lookup(ToTU, VName);
4966 ASSERT_EQ(Res.size(), 1u);
4967 EXPECT_EQ(*Res.begin(), FirstDeclMatcher<VarDecl>().match(
4968 ToTU, varDecl(hasName("V"),
4969 hasParent(translationUnitDecl()))));
4970 }
4971
TEST_P(ASTImporterLookupTableTest,LookupFindsOverloadedNames)4972 TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) {
4973 TranslationUnitDecl *ToTU = getToTuDecl(
4974 R"(
4975 void foo();
4976 void foo(int);
4977 void foo(int, int);
4978 )",
4979 Lang_CXX03);
4980
4981 ASTImporterLookupTable LT(*ToTU);
4982 auto *F0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
4983 auto *F2 = LastDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
4984 DeclarationName Name = F0->getDeclName();
4985 auto Res = LT.lookup(ToTU, Name);
4986 EXPECT_EQ(Res.size(), 3u);
4987 EXPECT_EQ(Res.count(F0), 1u);
4988 EXPECT_EQ(Res.count(F2), 1u);
4989 }
4990
TEST_P(ASTImporterLookupTableTest,DifferentOperatorsShouldHaveDifferentResultSet)4991 TEST_P(ASTImporterLookupTableTest,
4992 DifferentOperatorsShouldHaveDifferentResultSet) {
4993 TranslationUnitDecl *ToTU = getToTuDecl(
4994 R"(
4995 struct X{};
4996 void operator+(X, X);
4997 void operator-(X, X);
4998 )",
4999 Lang_CXX03);
5000
5001 ASTImporterLookupTable LT(*ToTU);
5002 auto *FPlus = FirstDeclMatcher<FunctionDecl>().match(
5003 ToTU, functionDecl(hasOverloadedOperatorName("+")));
5004 auto *FMinus = FirstDeclMatcher<FunctionDecl>().match(
5005 ToTU, functionDecl(hasOverloadedOperatorName("-")));
5006 DeclarationName NamePlus = FPlus->getDeclName();
5007 auto ResPlus = LT.lookup(ToTU, NamePlus);
5008 EXPECT_EQ(ResPlus.size(), 1u);
5009 EXPECT_EQ(ResPlus.count(FPlus), 1u);
5010 EXPECT_EQ(ResPlus.count(FMinus), 0u);
5011 DeclarationName NameMinus = FMinus->getDeclName();
5012 auto ResMinus = LT.lookup(ToTU, NameMinus);
5013 EXPECT_EQ(ResMinus.size(), 1u);
5014 EXPECT_EQ(ResMinus.count(FMinus), 1u);
5015 EXPECT_EQ(ResMinus.count(FPlus), 0u);
5016 EXPECT_NE(*ResMinus.begin(), *ResPlus.begin());
5017 }
5018
TEST_P(ASTImporterLookupTableTest,LookupDeclNamesFromDifferentTUs)5019 TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) {
5020 TranslationUnitDecl *ToTU = getToTuDecl(
5021 R"(
5022 struct X {};
5023 void operator+(X, X);
5024 )",
5025 Lang_CXX03);
5026 auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match(
5027 ToTU, functionDecl(hasOverloadedOperatorName("+")));
5028
5029 Decl *FromTU = getTuDecl(
5030 R"(
5031 struct X {};
5032 void operator+(X, X);
5033 )",
5034 Lang_CXX03);
5035 auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match(
5036 FromTU, functionDecl(hasOverloadedOperatorName("+")));
5037
5038 // FromPlus have a different TU, thus its DeclarationName is different too.
5039 ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName());
5040
5041 ASTImporterLookupTable LT(*ToTU);
5042 auto Res = LT.lookup(ToTU, ToPlus->getDeclName());
5043 ASSERT_EQ(Res.size(), 1u);
5044 EXPECT_EQ(*Res.begin(), ToPlus);
5045
5046 // FromPlus have a different TU, thus its DeclarationName is different too.
5047 Res = LT.lookup(ToTU, FromPlus->getDeclName());
5048 ASSERT_EQ(Res.size(), 0u);
5049 }
5050
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendClassDeclWithElaboratedType)5051 TEST_P(ASTImporterLookupTableTest,
5052 LookupFindsFwdFriendClassDeclWithElaboratedType) {
5053 TranslationUnitDecl *ToTU = getToTuDecl(
5054 R"(
5055 class Y { friend class F; };
5056 )",
5057 Lang_CXX03);
5058
5059 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5060 // So we must dig up the underlying CXXRecordDecl.
5061 ASTImporterLookupTable LT(*ToTU);
5062 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5063 const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
5064 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(
5065 ToTU, cxxRecordDecl(hasName("Y")));
5066
5067 DeclarationName Name = RD->getDeclName();
5068 auto Res = LT.lookup(ToTU, Name);
5069 EXPECT_EQ(Res.size(), 1u);
5070 EXPECT_EQ(*Res.begin(), RD);
5071
5072 Res = LT.lookup(Y, Name);
5073 EXPECT_EQ(Res.size(), 0u);
5074 }
5075
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendClassDeclWithUnelaboratedType)5076 TEST_P(ASTImporterLookupTableTest,
5077 LookupFindsFwdFriendClassDeclWithUnelaboratedType) {
5078 TranslationUnitDecl *ToTU = getToTuDecl(
5079 R"(
5080 class F;
5081 class Y { friend F; };
5082 )",
5083 Lang_CXX11);
5084
5085 // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
5086 // So we must dig up the underlying CXXRecordDecl.
5087 ASTImporterLookupTable LT(*ToTU);
5088 auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5089 const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
5090 auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, cxxRecordDecl(hasName("Y")));
5091
5092 DeclarationName Name = RD->getDeclName();
5093 auto Res = LT.lookup(ToTU, Name);
5094 EXPECT_EQ(Res.size(), 1u);
5095 EXPECT_EQ(*Res.begin(), RD);
5096
5097 Res = LT.lookup(Y, Name);
5098 EXPECT_EQ(Res.size(), 0u);
5099 }
5100
TEST_P(ASTImporterLookupTableTest,LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert)5101 TEST_P(ASTImporterLookupTableTest,
5102 LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert) {
5103 TranslationUnitDecl *ToTU = getToTuDecl(
5104 R"(
5105 class F;
5106 using alias_of_f = F;
5107 class Y { friend alias_of_f; };
5108 )",
5109 Lang_CXX11);
5110
5111 // ASTImporterLookupTable constructor handles using declarations correctly,
5112 // no assert is expected.
5113 ASTImporterLookupTable LT(*ToTU);
5114
5115 auto *Alias = FirstDeclMatcher<TypeAliasDecl>().match(
5116 ToTU, typeAliasDecl(hasName("alias_of_f")));
5117 DeclarationName Name = Alias->getDeclName();
5118 auto Res = LT.lookup(ToTU, Name);
5119 EXPECT_EQ(Res.count(Alias), 1u);
5120 }
5121
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendClassTemplateDecl)5122 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) {
5123 TranslationUnitDecl *ToTU = getToTuDecl(
5124 R"(
5125 class Y { template <class T> friend class F; };
5126 )",
5127 Lang_CXX03);
5128
5129 ASTImporterLookupTable LT(*ToTU);
5130 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5131 ToTU, classTemplateDecl(hasName("F")));
5132 DeclarationName Name = F->getDeclName();
5133 auto Res = LT.lookup(ToTU, Name);
5134 EXPECT_EQ(Res.size(), 2u);
5135 EXPECT_EQ(Res.count(F), 1u);
5136 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5137 }
5138
TEST_P(ASTImporterLookupTableTest,DependentFriendClass)5139 TEST_P(ASTImporterLookupTableTest, DependentFriendClass) {
5140 TranslationUnitDecl *ToTU = getToTuDecl(
5141 R"(
5142 template <typename T>
5143 class F;
5144
5145 template <typename T>
5146 class Y {
5147 friend class F<T>;
5148 };
5149 )",
5150 Lang_CXX03);
5151
5152 ASTImporterLookupTable LT(*ToTU);
5153 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5154 ToTU, classTemplateDecl(hasName("F")));
5155 DeclarationName Name = F->getDeclName();
5156 auto Res = LT.lookup(ToTU, Name);
5157 EXPECT_EQ(Res.size(), 2u);
5158 EXPECT_EQ(Res.count(F), 1u);
5159 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5160 }
5161
TEST_P(ASTImporterLookupTableTest,FriendClassTemplateSpecialization)5162 TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) {
5163 TranslationUnitDecl *ToTU = getToTuDecl(
5164 R"(
5165 template <typename T>
5166 class F;
5167
5168 class Y {
5169 friend class F<int>;
5170 };
5171 )",
5172 Lang_CXX03);
5173
5174 ASTImporterLookupTable LT(*ToTU);
5175 auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
5176 ToTU, classTemplateDecl(hasName("F")));
5177 DeclarationName Name = F->getDeclName();
5178 auto Res = LT.lookup(ToTU, Name);
5179 ASSERT_EQ(Res.size(), 3u);
5180 EXPECT_EQ(Res.count(F), 1u);
5181 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5182 EXPECT_EQ(Res.count(*F->spec_begin()), 1u);
5183 }
5184
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendFunctionDecl)5185 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) {
5186 TranslationUnitDecl *ToTU = getToTuDecl(
5187 R"(
5188 class Y { friend void F(); };
5189 )",
5190 Lang_CXX03);
5191
5192 ASTImporterLookupTable LT(*ToTU);
5193 auto *F =
5194 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("F")));
5195 DeclarationName Name = F->getDeclName();
5196 auto Res = LT.lookup(ToTU, Name);
5197 EXPECT_EQ(Res.size(), 1u);
5198 EXPECT_EQ(*Res.begin(), F);
5199 }
5200
TEST_P(ASTImporterLookupTableTest,LookupFindsDeclsInClassTemplateSpecialization)5201 TEST_P(ASTImporterLookupTableTest,
5202 LookupFindsDeclsInClassTemplateSpecialization) {
5203 TranslationUnitDecl *ToTU = getToTuDecl(
5204 R"(
5205 template <typename T>
5206 struct X {
5207 int F;
5208 };
5209 void foo() {
5210 X<char> xc;
5211 }
5212 )",
5213 Lang_CXX03);
5214
5215 ASTImporterLookupTable LT(*ToTU);
5216
5217 auto *Template = FirstDeclMatcher<ClassTemplateDecl>().match(
5218 ToTU, classTemplateDecl(hasName("X")));
5219 auto *FieldInTemplate = FirstDeclMatcher<FieldDecl>().match(
5220 ToTU,
5221 fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl())))));
5222
5223 auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5224 ToTU, classTemplateSpecializationDecl(hasName("X")));
5225 FieldDecl *FieldInSpec = *Spec->field_begin();
5226 ASSERT_TRUE(FieldInSpec);
5227
5228 DeclarationName Name = FieldInSpec->getDeclName();
5229 auto TemplateDC = cast<DeclContext>(Template->getTemplatedDecl());
5230
5231 SmallVector<NamedDecl *, 2> FoundDecls;
5232 TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
5233 EXPECT_EQ(FoundDecls.size(), 1u);
5234 EXPECT_EQ(FoundDecls[0], FieldInTemplate);
5235
5236 auto Res = LT.lookup(TemplateDC, Name);
5237 ASSERT_EQ(Res.size(), 1u);
5238 EXPECT_EQ(*Res.begin(), FieldInTemplate);
5239
5240 cast<DeclContext>(Spec)->getRedeclContext()->localUncachedLookup(Name,
5241 FoundDecls);
5242 EXPECT_EQ(FoundDecls.size(), 1u);
5243 EXPECT_EQ(FoundDecls[0], FieldInSpec);
5244
5245 Res = LT.lookup(cast<DeclContext>(Spec), Name);
5246 ASSERT_EQ(Res.size(), 1u);
5247 EXPECT_EQ(*Res.begin(), FieldInSpec);
5248 }
5249
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendFunctionTemplateDecl)5250 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) {
5251 TranslationUnitDecl *ToTU = getToTuDecl(
5252 R"(
5253 class Y { template <class T> friend void F(); };
5254 )",
5255 Lang_CXX03);
5256
5257 ASTImporterLookupTable LT(*ToTU);
5258 auto *F = FirstDeclMatcher<FunctionTemplateDecl>().match(
5259 ToTU, functionTemplateDecl(hasName("F")));
5260 DeclarationName Name = F->getDeclName();
5261 auto Res = LT.lookup(ToTU, Name);
5262 EXPECT_EQ(Res.size(), 2u);
5263 EXPECT_EQ(Res.count(F), 1u);
5264 EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
5265 }
5266
TEST_P(ASTImporterLookupTableTest,MultipleBefriendingClasses)5267 TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) {
5268 TranslationUnitDecl *ToTU = getToTuDecl(
5269 R"(
5270 struct X;
5271 struct A {
5272 friend struct X;
5273 };
5274 struct B {
5275 friend struct X;
5276 };
5277 )",
5278 Lang_CXX03);
5279
5280 ASTImporterLookupTable LT(*ToTU);
5281 auto *X = FirstDeclMatcher<CXXRecordDecl>().match(
5282 ToTU, cxxRecordDecl(hasName("X")));
5283 auto *FriendD0 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5284 auto *FriendD1 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
5285 const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0);
5286 const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1);
5287 ASSERT_EQ(RD0, RD1);
5288 ASSERT_EQ(RD1, X);
5289
5290 DeclarationName Name = X->getDeclName();
5291 auto Res = LT.lookup(ToTU, Name);
5292 EXPECT_EQ(Res.size(), 1u);
5293 EXPECT_EQ(*Res.begin(), X);
5294 }
5295
TEST_P(ASTImporterLookupTableTest,EnumConstantDecl)5296 TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) {
5297 TranslationUnitDecl *ToTU = getToTuDecl(
5298 R"(
5299 enum E {
5300 A,
5301 B
5302 };
5303 )",
5304 Lang_C99);
5305
5306 ASTImporterLookupTable LT(*ToTU);
5307 auto *E = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(hasName("E")));
5308 auto *A = FirstDeclMatcher<EnumConstantDecl>().match(
5309 ToTU, enumConstantDecl(hasName("A")));
5310
5311 DeclarationName Name = A->getDeclName();
5312 // Redecl context is the TU.
5313 ASSERT_EQ(E->getRedeclContext(), ToTU);
5314
5315 SmallVector<NamedDecl *, 2> FoundDecls;
5316 // Normal lookup finds in the DC.
5317 E->localUncachedLookup(Name, FoundDecls);
5318 EXPECT_EQ(FoundDecls.size(), 1u);
5319
5320 // Normal lookup finds in the Redecl context.
5321 ToTU->localUncachedLookup(Name, FoundDecls);
5322 EXPECT_EQ(FoundDecls.size(), 1u);
5323
5324 // Import specific lookup finds in the DC.
5325 auto Res = LT.lookup(E, Name);
5326 ASSERT_EQ(Res.size(), 1u);
5327 EXPECT_EQ(*Res.begin(), A);
5328
5329 // Import specific lookup finds in the Redecl context.
5330 Res = LT.lookup(ToTU, Name);
5331 ASSERT_EQ(Res.size(), 1u);
5332 EXPECT_EQ(*Res.begin(), A);
5333 }
5334
TEST_P(ASTImporterLookupTableTest,LookupSearchesInTheWholeRedeclChain)5335 TEST_P(ASTImporterLookupTableTest, LookupSearchesInTheWholeRedeclChain) {
5336 TranslationUnitDecl *ToTU = getToTuDecl(
5337 R"(
5338 namespace N {
5339 int A;
5340 }
5341 namespace N {
5342 }
5343 )",
5344 Lang_CXX03);
5345 auto *N1 =
5346 LastDeclMatcher<NamespaceDecl>().match(ToTU, namespaceDecl(hasName("N")));
5347 auto *A = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("A")));
5348 DeclarationName Name = A->getDeclName();
5349
5350 ASTImporterLookupTable LT(*ToTU);
5351 auto Res = LT.lookup(N1, Name);
5352 ASSERT_EQ(Res.size(), 1u);
5353 EXPECT_EQ(*Res.begin(), A);
5354 }
5355
TEST_P(ASTImporterOptionSpecificTestBase,RedeclChainShouldBeCorrectAmongstNamespaces)5356 TEST_P(ASTImporterOptionSpecificTestBase,
5357 RedeclChainShouldBeCorrectAmongstNamespaces) {
5358 Decl *FromTU = getTuDecl(
5359 R"(
5360 namespace NS {
5361 struct X;
5362 struct Y {
5363 static const int I = 3;
5364 };
5365 }
5366 namespace NS {
5367 struct X { // <--- To be imported
5368 void method(int i = Y::I) {}
5369 int f;
5370 };
5371 }
5372 )",
5373 Lang_CXX03);
5374 auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match(
5375 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
5376 auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match(
5377 FromTU,
5378 cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit())));
5379 ASSERT_NE(FromFwd, FromDef);
5380 ASSERT_FALSE(FromFwd->isThisDeclarationADefinition());
5381 ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
5382 ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl());
5383
5384 auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX03));
5385 auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX03));
5386 EXPECT_NE(ToFwd, ToDef);
5387 EXPECT_FALSE(ToFwd->isThisDeclarationADefinition());
5388 EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
5389 EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl());
5390 auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5391 // We expect no (ODR) warning during the import.
5392 EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
5393 }
5394
5395 struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {};
5396
TEST_P(ImportFriendFunctionTemplates,LookupShouldFindPreviousFriend)5397 TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
5398 Decl *ToTU = getToTuDecl(
5399 R"(
5400 class X {
5401 template <typename T> friend void foo();
5402 };
5403 )",
5404 Lang_CXX03);
5405 auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match(
5406 ToTU, functionTemplateDecl(hasName("foo")));
5407
5408 Decl *FromTU = getTuDecl(
5409 R"(
5410 template <typename T> void foo();
5411 )",
5412 Lang_CXX03);
5413 auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match(
5414 FromTU, functionTemplateDecl(hasName("foo")));
5415 auto *Imported = Import(FromFoo, Lang_CXX03);
5416
5417 EXPECT_EQ(Imported->getPreviousDecl(), Friend);
5418 }
5419
5420 struct ASTImporterWithFakeErrors : ASTImporter {
5421 using ASTImporter::ASTImporter;
returnWithErrorInTestclang::ast_matchers::ASTImporterWithFakeErrors5422 bool returnWithErrorInTest() override { return true; }
5423 };
5424
5425 struct ErrorHandlingTest : ASTImporterOptionSpecificTestBase {
ErrorHandlingTestclang::ast_matchers::ErrorHandlingTest5426 ErrorHandlingTest() {
5427 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
5428 ASTContext &FromContext, FileManager &FromFileManager,
5429 bool MinimalImport,
5430 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
5431 return new ASTImporterWithFakeErrors(ToContext, ToFileManager,
5432 FromContext, FromFileManager,
5433 MinimalImport, SharedState);
5434 };
5435 }
5436 // In this test we purposely report an error (UnsupportedConstruct) when
5437 // importing the below stmt.
5438 static constexpr auto* ErroneousStmt = R"( asm(""); )";
5439 };
5440
5441 // Check a case when no new AST node is created in the AST before encountering
5442 // the error.
TEST_P(ErrorHandlingTest,ErrorHappensBeforeCreatingANewNode)5443 TEST_P(ErrorHandlingTest, ErrorHappensBeforeCreatingANewNode) {
5444 TranslationUnitDecl *ToTU = getToTuDecl(
5445 R"(
5446 template <typename T>
5447 class X {};
5448 template <>
5449 class X<int> { int a; };
5450 )",
5451 Lang_CXX03);
5452 TranslationUnitDecl *FromTU = getTuDecl(
5453 R"(
5454 template <typename T>
5455 class X {};
5456 template <>
5457 class X<int> { double b; };
5458 )",
5459 Lang_CXX03);
5460 auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
5461 FromTU, classTemplateSpecializationDecl(hasName("X")));
5462 ClassTemplateSpecializationDecl *ImportedSpec = Import(FromSpec, Lang_CXX03);
5463 EXPECT_FALSE(ImportedSpec);
5464
5465 // The original Decl is kept, no new decl is created.
5466 EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(
5467 ToTU, classTemplateSpecializationDecl(hasName("X"))),
5468 1u);
5469
5470 // But an error is set to the counterpart in the "from" context.
5471 ASTImporter *Importer = findFromTU(FromSpec)->Importer.get();
5472 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromSpec);
5473 ASSERT_TRUE(OptErr);
5474 EXPECT_EQ(OptErr->Error, ASTImportError::NameConflict);
5475 }
5476
5477 // Check a case when a new AST node is created but not linked to the AST before
5478 // encountering the error.
TEST_P(ErrorHandlingTest,ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST)5479 TEST_P(ErrorHandlingTest,
5480 ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST) {
5481 TranslationUnitDecl *FromTU = getTuDecl(
5482 std::string("void foo() { ") + ErroneousStmt + " }", Lang_CXX03);
5483 auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
5484 FromTU, functionDecl(hasName("foo")));
5485
5486 FunctionDecl *ImportedFoo = Import(FromFoo, Lang_CXX03);
5487 EXPECT_FALSE(ImportedFoo);
5488
5489 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5490 // Created, but not linked.
5491 EXPECT_EQ(
5492 DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("foo"))),
5493 0u);
5494
5495 ASTImporter *Importer = findFromTU(FromFoo)->Importer.get();
5496 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFoo);
5497 ASSERT_TRUE(OptErr);
5498 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5499 }
5500
5501 // Check a case when a new AST node is created and linked to the AST before
5502 // encountering the error. The error is set for the counterpart of the nodes in
5503 // the "from" context.
TEST_P(ErrorHandlingTest,ErrorHappensAfterNodeIsCreatedAndLinked)5504 TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) {
5505 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5506 void f();
5507 void f() { )") + ErroneousStmt + R"( }
5508 )",
5509 Lang_CXX03);
5510 auto *FromProto = FirstDeclMatcher<FunctionDecl>().match(
5511 FromTU, functionDecl(hasName("f")));
5512 auto *FromDef =
5513 LastDeclMatcher<FunctionDecl>().match(FromTU, functionDecl(hasName("f")));
5514 FunctionDecl *ImportedProto = Import(FromProto, Lang_CXX03);
5515 EXPECT_FALSE(ImportedProto); // Could not import.
5516 // However, we created two nodes in the AST. 1) the fwd decl 2) the
5517 // definition. The definition is not added to its DC, but the fwd decl is
5518 // there.
5519 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5520 EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
5521 1u);
5522 // Match the fwd decl.
5523 auto *ToProto =
5524 FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("f")));
5525 EXPECT_TRUE(ToProto);
5526 // An error is set to the counterpart in the "from" context both for the fwd
5527 // decl and the definition.
5528 ASTImporter *Importer = findFromTU(FromProto)->Importer.get();
5529 Optional<ASTImportError> OptErr =
5530 Importer->getImportDeclErrorIfAny(FromProto);
5531 ASSERT_TRUE(OptErr);
5532 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5533 OptErr = Importer->getImportDeclErrorIfAny(FromDef);
5534 ASSERT_TRUE(OptErr);
5535 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5536 }
5537
5538 // An error should be set for a class if we cannot import one member.
TEST_P(ErrorHandlingTest,ErrorIsPropagatedFromMemberToClass)5539 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) {
5540 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5541 class X {
5542 void f() { )") + ErroneousStmt + R"( } // This member has the error
5543 // during import.
5544 void ok(); // The error should not prevent importing this.
5545 }; // An error will be set for X too.
5546 )",
5547 Lang_CXX03);
5548 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
5549 FromTU, cxxRecordDecl(hasName("X")));
5550 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
5551
5552 // An error is set for X.
5553 EXPECT_FALSE(ImportedX);
5554 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
5555 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
5556 ASSERT_TRUE(OptErr);
5557 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5558
5559 // An error is set for f().
5560 auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
5561 FromTU, cxxMethodDecl(hasName("f")));
5562 OptErr = Importer->getImportDeclErrorIfAny(FromF);
5563 ASSERT_TRUE(OptErr);
5564 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5565 // And any subsequent import should fail.
5566 CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03);
5567 EXPECT_FALSE(ImportedF);
5568
5569 // There is an error set for the other member too.
5570 auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match(
5571 FromTU, cxxMethodDecl(hasName("ok")));
5572 OptErr = Importer->getImportDeclErrorIfAny(FromOK);
5573 EXPECT_TRUE(OptErr);
5574 // Cannot import the other member.
5575 CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03);
5576 EXPECT_FALSE(ImportedOK);
5577 }
5578
5579 // Check that an error propagates to the dependent AST nodes.
5580 // In the below code it means that an error in X should propagate to A.
5581 // And even to F since the containing A is erroneous.
5582 // And to all AST nodes which we visit during the import process which finally
5583 // ends up in a failure (in the error() function).
TEST_P(ErrorHandlingTest,ErrorPropagatesThroughImportCycles)5584 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) {
5585 Decl *FromTU = getTuDecl(std::string(R"(
5586 namespace NS {
5587 class A {
5588 template <int I> class F {};
5589 class X {
5590 template <int I> friend class F;
5591 void error() { )") +
5592 ErroneousStmt + R"( }
5593 };
5594 };
5595
5596 class B {};
5597 } // NS
5598 )",
5599 Lang_CXX03, "input0.cc");
5600
5601 auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match(
5602 FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
5603 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
5604 FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
5605 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match(
5606 FromTU, cxxRecordDecl(hasName("B"), isDefinition()));
5607 auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match(
5608 FromTU, namespaceDecl(hasName("NS")));
5609
5610 // Start by importing the templated CXXRecordDecl of F.
5611 // Import fails for that.
5612 EXPECT_FALSE(Import(FromFRD, Lang_CXX03));
5613 // Import fails for A.
5614 EXPECT_FALSE(Import(FromA, Lang_CXX03));
5615 // But we should be able to import the independent B.
5616 EXPECT_TRUE(Import(FromB, Lang_CXX03));
5617 // And the namespace.
5618 EXPECT_TRUE(Import(FromNS, Lang_CXX03));
5619
5620 // An error is set to the templated CXXRecordDecl of F.
5621 ASTImporter *Importer = findFromTU(FromFRD)->Importer.get();
5622 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFRD);
5623 EXPECT_TRUE(OptErr);
5624
5625 // An error is set to A.
5626 OptErr = Importer->getImportDeclErrorIfAny(FromA);
5627 EXPECT_TRUE(OptErr);
5628
5629 // There is no error set to B.
5630 OptErr = Importer->getImportDeclErrorIfAny(FromB);
5631 EXPECT_FALSE(OptErr);
5632
5633 // There is no error set to NS.
5634 OptErr = Importer->getImportDeclErrorIfAny(FromNS);
5635 EXPECT_FALSE(OptErr);
5636
5637 // Check some of those decls whose ancestor is X, they all should have an
5638 // error set if we visited them during an import process which finally failed.
5639 // These decls are part of a cycle in an ImportPath.
5640 // There would not be any error set for these decls if we hadn't follow the
5641 // ImportPaths and the cycles.
5642 OptErr = Importer->getImportDeclErrorIfAny(
5643 FirstDeclMatcher<ClassTemplateDecl>().match(
5644 FromTU, classTemplateDecl(hasName("F"))));
5645 // An error is set to the 'F' ClassTemplateDecl.
5646 EXPECT_TRUE(OptErr);
5647 // An error is set to the FriendDecl.
5648 OptErr = Importer->getImportDeclErrorIfAny(
5649 FirstDeclMatcher<FriendDecl>().match(
5650 FromTU, friendDecl()));
5651 EXPECT_TRUE(OptErr);
5652 // An error is set to the implicit class of A.
5653 OptErr =
5654 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
5655 FromTU, cxxRecordDecl(hasName("A"), isImplicit())));
5656 EXPECT_TRUE(OptErr);
5657 // An error is set to the implicit class of X.
5658 OptErr =
5659 Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
5660 FromTU, cxxRecordDecl(hasName("X"), isImplicit())));
5661 EXPECT_TRUE(OptErr);
5662 }
5663
TEST_P(ErrorHandlingTest,ErrorIsNotPropagatedFromMemberToNamespace)5664 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) {
5665 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5666 namespace X {
5667 void f() { )") + ErroneousStmt + R"( } // This member has the error
5668 // during import.
5669 void ok(); // The error should not prevent importing this.
5670 }; // An error will be set for X too.
5671 )",
5672 Lang_CXX03);
5673 auto *FromX = FirstDeclMatcher<NamespaceDecl>().match(
5674 FromTU, namespaceDecl(hasName("X")));
5675 NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03);
5676
5677 // There is no error set for X.
5678 EXPECT_TRUE(ImportedX);
5679 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
5680 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
5681 ASSERT_FALSE(OptErr);
5682
5683 // An error is set for f().
5684 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
5685 FromTU, functionDecl(hasName("f")));
5686 OptErr = Importer->getImportDeclErrorIfAny(FromF);
5687 ASSERT_TRUE(OptErr);
5688 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5689 // And any subsequent import should fail.
5690 FunctionDecl *ImportedF = Import(FromF, Lang_CXX03);
5691 EXPECT_FALSE(ImportedF);
5692
5693 // There is no error set for ok().
5694 auto *FromOK = FirstDeclMatcher<FunctionDecl>().match(
5695 FromTU, functionDecl(hasName("ok")));
5696 OptErr = Importer->getImportDeclErrorIfAny(FromOK);
5697 EXPECT_FALSE(OptErr);
5698 // And we should be able to import.
5699 FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03);
5700 EXPECT_TRUE(ImportedOK);
5701 }
5702
TEST_P(ErrorHandlingTest,ODRViolationWithinTypedefDecls)5703 TEST_P(ErrorHandlingTest, ODRViolationWithinTypedefDecls) {
5704 // Importing `z` should fail - instead of crashing - due to an ODR violation.
5705 // The `bar::e` typedef sets it's DeclContext after the import is done.
5706 // However, if the importation fails, it will be left as a nullptr.
5707 // During the cleanup of the failed import, we should check whether the
5708 // DeclContext is null or not - instead of dereferencing that unconditionally.
5709 constexpr auto ToTUCode = R"(
5710 namespace X {
5711 struct bar {
5712 int odr_violation;
5713 };
5714 })";
5715 constexpr auto FromTUCode = R"(
5716 namespace X {
5717 enum b {};
5718 struct bar {
5719 typedef b e;
5720 static e d;
5721 };
5722 }
5723 int z = X::bar::d;
5724 )";
5725 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
5726 static_cast<void>(ToTU);
5727 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
5728 auto *FromZ =
5729 FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("z")));
5730 ASSERT_TRUE(FromZ);
5731 ASSERT_TRUE(FromZ->hasInit());
5732
5733 auto *ImportedZ = Import(FromZ, Lang_CXX11);
5734 EXPECT_FALSE(ImportedZ);
5735 }
5736
5737 // An error should be set for a class if it had a previous import with an error
5738 // from another TU.
TEST_P(ErrorHandlingTest,ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt)5739 TEST_P(ErrorHandlingTest,
5740 ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) {
5741 // We already have a fwd decl.
5742 TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03);
5743 // Then we import a definition.
5744 {
5745 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5746 class X {
5747 void f() { )") + ErroneousStmt + R"( }
5748 void ok();
5749 };
5750 )",
5751 Lang_CXX03);
5752 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
5753 FromTU, cxxRecordDecl(hasName("X")));
5754 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
5755
5756 // An error is set for X ...
5757 EXPECT_FALSE(ImportedX);
5758 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
5759 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
5760 ASSERT_TRUE(OptErr);
5761 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5762 }
5763 // ... but the node had been created.
5764 auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match(
5765 ToTU, cxxRecordDecl(hasName("X"), isDefinition()));
5766 // An error is set for "ToXDef" in the shared state.
5767 Optional<ASTImportError> OptErr =
5768 SharedStatePtr->getImportDeclErrorIfAny(ToXDef);
5769 ASSERT_TRUE(OptErr);
5770 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5771
5772 auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match(
5773 ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition())));
5774 // An error is NOT set for the fwd Decl of X in the shared state.
5775 OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd);
5776 ASSERT_FALSE(OptErr);
5777
5778 // Try to import X again but from another TU.
5779 {
5780 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5781 class X {
5782 void f() { )") + ErroneousStmt + R"( }
5783 void ok();
5784 };
5785 )",
5786 Lang_CXX03, "input1.cc");
5787
5788 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
5789 FromTU, cxxRecordDecl(hasName("X")));
5790 CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
5791
5792 // If we did not save the errors for the "to" context then the below checks
5793 // would fail, because the lookup finds the fwd Decl of the existing
5794 // definition in the "to" context. We can reach the existing definition via
5795 // the found fwd Decl. That existing definition is structurally equivalent
5796 // (we check only the fields) with this one we want to import, so we return
5797 // with the existing definition, which is erroneous (one method is missing).
5798
5799 // The import should fail.
5800 EXPECT_FALSE(ImportedX);
5801 ASTImporter *Importer = findFromTU(FromX)->Importer.get();
5802 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
5803 // And an error is set for this new X in the "from" ctx.
5804 ASSERT_TRUE(OptErr);
5805 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5806 }
5807 }
5808
TEST_P(ErrorHandlingTest,ImportOfOverriddenMethods)5809 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) {
5810 auto MatchFooA =
5811 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A"))));
5812 auto MatchFooB =
5813 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B"))));
5814 auto MatchFooC =
5815 functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C"))));
5816
5817 // Provoke import of a method that has overridden methods with import error.
5818 TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5819 struct C;
5820 struct A {
5821 virtual void foo();
5822 void f1(C *);
5823 };
5824 void A::foo() {
5825 )") + ErroneousStmt + R"(
5826 }
5827 struct B : public A {
5828 void foo() override;
5829 };
5830 struct C : public B {
5831 void foo() override;
5832 };
5833 )",
5834 Lang_CXX11);
5835 auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA);
5836 auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB);
5837 auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC);
5838
5839 EXPECT_FALSE(Import(FromFooA, Lang_CXX11));
5840 ASTImporter *Importer = findFromTU(FromFooA)->Importer.get();
5841 auto CheckError = [&Importer](Decl *FromD) {
5842 Optional<ASTImportError> OptErr = Importer->getImportDeclErrorIfAny(FromD);
5843 ASSERT_TRUE(OptErr);
5844 EXPECT_EQ(OptErr->Error, ASTImportError::UnsupportedConstruct);
5845 };
5846 CheckError(FromFooA);
5847 EXPECT_FALSE(Import(FromFooB, Lang_CXX11));
5848 CheckError(FromFooB);
5849 EXPECT_FALSE(Import(FromFooC, Lang_CXX11));
5850 CheckError(FromFooC);
5851 }
5852
TEST_P(ErrorHandlingTest,ODRViolationWithinParmVarDecls)5853 TEST_P(ErrorHandlingTest, ODRViolationWithinParmVarDecls) {
5854 // Importing of 'f' and parameter 'P' should cause an ODR error.
5855 // The error happens after the ParmVarDecl for 'P' was already created.
5856 // This is a special case because the ParmVarDecl has a temporary DeclContext.
5857 // Expected is no crash at error handling of ASTImporter.
5858 constexpr auto ToTUCode = R"(
5859 struct X {
5860 char A;
5861 };
5862 )";
5863 constexpr auto FromTUCode = R"(
5864 struct X {
5865 enum Y { Z };
5866 };
5867 void f(int P = X::Z);
5868 )";
5869 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
5870 static_cast<void>(ToTU);
5871 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
5872 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
5873 FromTU, functionDecl(hasName("f")));
5874 ASSERT_TRUE(FromF);
5875
5876 auto *ImportedF = Import(FromF, Lang_CXX11);
5877 EXPECT_FALSE(ImportedF);
5878 }
5879
TEST_P(ErrorHandlingTest,DoNotInheritErrorFromNonDependentChild)5880 TEST_P(ErrorHandlingTest, DoNotInheritErrorFromNonDependentChild) {
5881 // Declarations should not inherit an import error from a child object
5882 // if the declaration has no direct dependence to such a child.
5883 // For example a namespace should not get import error if one of the
5884 // declarations inside it fails to import.
5885 // There was a special case in error handling (when "import path circles" are
5886 // encountered) when this property was not held. This case is provoked by the
5887 // following code.
5888 constexpr auto ToTUCode = R"(
5889 namespace ns {
5890 struct Err {
5891 char A;
5892 };
5893 }
5894 )";
5895 constexpr auto FromTUCode = R"(
5896 namespace ns {
5897 struct A {
5898 using U = struct Err;
5899 };
5900 }
5901 namespace ns {
5902 struct Err {}; // ODR violation
5903 void f(A) {}
5904 }
5905 )";
5906
5907 Decl *ToTU = getToTuDecl(ToTUCode, Lang_CXX11);
5908 static_cast<void>(ToTU);
5909 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
5910 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
5911 FromTU, cxxRecordDecl(hasName("A"), hasDefinition()));
5912 ASSERT_TRUE(FromA);
5913 auto *ImportedA = Import(FromA, Lang_CXX11);
5914 // 'A' can not be imported: ODR error at 'Err'
5915 EXPECT_FALSE(ImportedA);
5916 // When import of 'A' failed there was a "saved import path circle" that
5917 // contained namespace 'ns' (A - U - Err - ns - f - A). This should not mean
5918 // that every object in this path fails to import.
5919
5920 Decl *FromNS = FirstDeclMatcher<NamespaceDecl>().match(
5921 FromTU, namespaceDecl(hasName("ns")));
5922 EXPECT_TRUE(FromNS);
5923 auto *ImportedNS = Import(FromNS, Lang_CXX11);
5924 EXPECT_TRUE(ImportedNS);
5925 }
5926
TEST_P(ASTImporterOptionSpecificTestBase,LambdaInFunctionBody)5927 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) {
5928 Decl *FromTU = getTuDecl(
5929 R"(
5930 void f() {
5931 auto L = [](){};
5932 }
5933 )",
5934 Lang_CXX11, "input0.cc");
5935 auto Pattern = lambdaExpr();
5936 CXXRecordDecl *FromL =
5937 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
5938
5939 auto ToL = Import(FromL, Lang_CXX11);
5940 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
5941 unsigned FromLSize =
5942 std::distance(FromL->decls().begin(), FromL->decls().end());
5943 EXPECT_NE(ToLSize, 0u);
5944 EXPECT_EQ(ToLSize, FromLSize);
5945 EXPECT_FALSE(FromL->isDependentLambda());
5946 }
5947
TEST_P(ASTImporterOptionSpecificTestBase,LambdaInFunctionParam)5948 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
5949 Decl *FromTU = getTuDecl(
5950 R"(
5951 template <typename F>
5952 void f(F L = [](){}) {}
5953 )",
5954 Lang_CXX11, "input0.cc");
5955 auto Pattern = lambdaExpr();
5956 CXXRecordDecl *FromL =
5957 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
5958
5959 auto ToL = Import(FromL, Lang_CXX11);
5960 unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
5961 unsigned FromLSize =
5962 std::distance(FromL->decls().begin(), FromL->decls().end());
5963 EXPECT_NE(ToLSize, 0u);
5964 EXPECT_EQ(ToLSize, FromLSize);
5965 EXPECT_TRUE(FromL->isDependentLambda());
5966 }
5967
TEST_P(ASTImporterOptionSpecificTestBase,LambdaInGlobalScope)5968 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) {
5969 Decl *FromTU = getTuDecl(
5970 R"(
5971 auto l1 = [](unsigned lp) { return 1; };
5972 auto l2 = [](int lp) { return 2; };
5973 int f(int p) {
5974 return l1(p) + l2(p);
5975 }
5976 )",
5977 Lang_CXX11, "input0.cc");
5978 FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match(
5979 FromTU, functionDecl(hasName("f")));
5980 FunctionDecl *ToF = Import(FromF, Lang_CXX11);
5981 EXPECT_TRUE(ToF);
5982 }
5983
TEST_P(ASTImporterOptionSpecificTestBase,ImportExistingFriendClassTemplateDef)5984 TEST_P(ASTImporterOptionSpecificTestBase,
5985 ImportExistingFriendClassTemplateDef) {
5986 auto Code =
5987 R"(
5988 template <class T1, class T2>
5989 struct Base {
5990 template <class U1, class U2>
5991 friend struct Class;
5992 };
5993 template <class T1, class T2>
5994 struct Class { };
5995 )";
5996
5997 TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
5998 TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
5999
6000 auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
6001 ToTU, classTemplateDecl(hasName("Class")));
6002 auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
6003 ToTU, classTemplateDecl(hasName("Class")));
6004 ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition());
6005 ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition());
6006 // Previous friend decl is not linked to it!
6007 ASSERT_FALSE(ToClassDef->getPreviousDecl());
6008 ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef);
6009 ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto);
6010
6011 auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
6012 FromTU, classTemplateDecl(hasName("Class")));
6013 auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
6014 FromTU, classTemplateDecl(hasName("Class")));
6015 ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition());
6016 ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition());
6017 ASSERT_FALSE(FromClassDef->getPreviousDecl());
6018 ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef);
6019 ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto);
6020
6021 auto *ImportedDef = Import(FromClassDef, Lang_CXX03);
6022 // At import we should find the definition for 'Class' even if the
6023 // prototype (inside 'friend') for it comes first in the AST and is not
6024 // linked to the definition.
6025 EXPECT_EQ(ImportedDef, ToClassDef);
6026 }
6027
6028 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase {
LLDBLookupTestclang::ast_matchers::LLDBLookupTest6029 LLDBLookupTest() {
6030 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
6031 ASTContext &FromContext, FileManager &FromFileManager,
6032 bool MinimalImport,
6033 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
6034 return new ASTImporter(ToContext, ToFileManager, FromContext,
6035 FromFileManager, MinimalImport,
6036 // We use the regular lookup.
6037 /*SharedState=*/nullptr);
6038 };
6039 }
6040 };
6041
TEST_P(LLDBLookupTest,ImporterShouldFindInTransparentContext)6042 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) {
6043 TranslationUnitDecl *ToTU = getToTuDecl(
6044 R"(
6045 extern "C" {
6046 class X{};
6047 };
6048 )",
6049 Lang_CXX03);
6050 auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match(
6051 ToTU, cxxRecordDecl(hasName("X")));
6052
6053 // Set up a stub external storage.
6054 ToTU->setHasExternalLexicalStorage(true);
6055 // Set up DeclContextBits.HasLazyExternalLexicalLookups to true.
6056 ToTU->setMustBuildLookupTable();
6057 struct TestExternalASTSource : ExternalASTSource {};
6058 ToTU->getASTContext().setExternalSource(new TestExternalASTSource());
6059
6060 Decl *FromTU = getTuDecl(
6061 R"(
6062 class X;
6063 )",
6064 Lang_CXX03);
6065 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6066 FromTU, cxxRecordDecl(hasName("X")));
6067 auto *ImportedX = Import(FromX, Lang_CXX03);
6068 // The lookup must find the existing class definition in the LinkageSpecDecl.
6069 // Then the importer renders the existing and the new decl into one chain.
6070 EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl());
6071 }
6072
6073 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {};
6074
TEST_P(SVEBuiltins,ImportTypes)6075 TEST_P(SVEBuiltins, ImportTypes) {
6076 static const char *const TypeNames[] = {
6077 "__SVInt8_t",
6078 "__SVInt16_t",
6079 "__SVInt32_t",
6080 "__SVInt64_t",
6081 "__SVUint8_t",
6082 "__SVUint16_t",
6083 "__SVUint32_t",
6084 "__SVUint64_t",
6085 "__SVFloat16_t",
6086 "__SVBFloat16_t",
6087 "__SVFloat32_t",
6088 "__SVFloat64_t",
6089 "__SVBool_t"
6090 };
6091
6092 TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03);
6093 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc");
6094 for (auto *TypeName : TypeNames) {
6095 auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match(
6096 ToTU, typedefDecl(hasName(TypeName)));
6097 QualType ToType = ToTypedef->getUnderlyingType();
6098
6099 auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match(
6100 FromTU, typedefDecl(hasName(TypeName)));
6101 QualType FromType = FromTypedef->getUnderlyingType();
6102
6103 QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03);
6104 EXPECT_EQ(ImportedType, ToType);
6105 }
6106 }
6107
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfDefaultImplicitFunctions)6108 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) {
6109 // Test that import of implicit functions works and the functions
6110 // are merged into one chain.
6111 auto GetDeclToImport = [this](StringRef File) {
6112 Decl *FromTU = getTuDecl(
6113 R"(
6114 struct X { };
6115 // Force generating some implicit operator definitions for X.
6116 void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; }
6117 )",
6118 Lang_CXX11, File);
6119 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
6120 FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
6121 // Destructor is picked as one example of implicit function.
6122 return FromD->getDestructor();
6123 };
6124
6125 auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11);
6126 ASSERT_TRUE(ToD1);
6127
6128 auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11);
6129 ASSERT_TRUE(ToD2);
6130
6131 EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl());
6132 }
6133
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfExplicitlyDefaultedOrDeleted)6134 TEST_P(ASTImporterOptionSpecificTestBase,
6135 ImportOfExplicitlyDefaultedOrDeleted) {
6136 Decl *FromTU = getTuDecl(
6137 R"(
6138 struct X { X() = default; X(const X&) = delete; };
6139 )",
6140 Lang_CXX11);
6141 auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
6142 FromTU, cxxRecordDecl(hasName("X")));
6143 auto *ImportedX = Import(FromX, Lang_CXX11);
6144 auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match(
6145 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6146 auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match(
6147 ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
6148
6149 ASSERT_TRUE(ImportedX);
6150 EXPECT_TRUE(Constr1->isDefaulted());
6151 EXPECT_TRUE(Constr1->isExplicitlyDefaulted());
6152 EXPECT_TRUE(Constr2->isDeletedAsWritten());
6153 EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate());
6154 }
6155
6156 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, SVEBuiltins,
6157 ::testing::Values(std::vector<std::string>{
6158 "-target", "aarch64-linux-gnu"}));
6159
6160 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, DeclContextTest,
6161 ::testing::Values(std::vector<std::string>()));
6162
6163 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CanonicalRedeclChain,
6164 ::testing::Values(std::vector<std::string>()));
6165
TEST_P(ASTImporterOptionSpecificTestBase,LambdasAreDifferentiated)6166 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) {
6167 Decl *FromTU = getTuDecl(
6168 R"(
6169 void f() {
6170 auto L0 = [](){};
6171 auto L1 = [](){};
6172 }
6173 )",
6174 Lang_CXX11, "input0.cc");
6175 auto Pattern = lambdaExpr();
6176 CXXRecordDecl *FromL0 =
6177 FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6178 CXXRecordDecl *FromL1 =
6179 LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
6180 ASSERT_NE(FromL0, FromL1);
6181
6182 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
6183 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
6184 EXPECT_NE(ToL0, ToL1);
6185 }
6186
TEST_P(ASTImporterOptionSpecificTestBase,LambdasInFunctionParamsAreDifferentiated)6187 TEST_P(ASTImporterOptionSpecificTestBase,
6188 LambdasInFunctionParamsAreDifferentiated) {
6189 Decl *FromTU = getTuDecl(
6190 R"(
6191 template <typename F0, typename F1>
6192 void f(F0 L0 = [](){}, F1 L1 = [](){}) {}
6193 )",
6194 Lang_CXX11, "input0.cc");
6195 auto Pattern = cxxRecordDecl(isLambda());
6196 CXXRecordDecl *FromL0 =
6197 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6198 CXXRecordDecl *FromL1 =
6199 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6200 ASSERT_NE(FromL0, FromL1);
6201
6202 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
6203 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
6204 ASSERT_NE(ToL0, ToL1);
6205 }
6206
TEST_P(ASTImporterOptionSpecificTestBase,LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed)6207 TEST_P(ASTImporterOptionSpecificTestBase,
6208 LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) {
6209 Decl *FromTU = getTuDecl(
6210 R"(
6211 #define LAMBDA [](){}
6212 template <typename F0, typename F1>
6213 void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {}
6214 )",
6215 Lang_CXX11, "input0.cc");
6216 auto Pattern = cxxRecordDecl(isLambda());
6217 CXXRecordDecl *FromL0 =
6218 FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6219 CXXRecordDecl *FromL1 =
6220 LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
6221 ASSERT_NE(FromL0, FromL1);
6222
6223 Import(FromL0, Lang_CXX11);
6224 Import(FromL1, Lang_CXX11);
6225 CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
6226 CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
6227 ASSERT_NE(ToL0, ToL1);
6228 }
6229
TEST_P(ASTImporterOptionSpecificTestBase,ImportAssignedLambda)6230 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) {
6231 Decl *FromTU = getTuDecl(
6232 R"(
6233 void f() {
6234 auto x = []{} = {}; auto x2 = x;
6235 }
6236 )",
6237 Lang_CXX20, "input0.cc");
6238 auto FromF = FirstDeclMatcher<FunctionDecl>().match(
6239 FromTU, functionDecl(hasName("f")));
6240 // We have only one lambda class.
6241 ASSERT_EQ(
6242 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
6243 1u);
6244
6245 FunctionDecl *ToF = Import(FromF, Lang_CXX20);
6246 EXPECT_TRUE(ToF);
6247 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
6248 // We have only one lambda class after the import.
6249 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
6250 1u);
6251 }
6252
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefaultConstructibleLambdas)6253 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) {
6254 Decl *FromTU = getTuDecl(
6255 R"(
6256 void f() {
6257 auto x = []{} = {};
6258 auto xb = []{} = {};
6259 }
6260 )",
6261 Lang_CXX20, "input0.cc");
6262 auto FromF = FirstDeclMatcher<FunctionDecl>().match(
6263 FromTU, functionDecl(hasName("f")));
6264 // We have two lambda classes.
6265 ASSERT_EQ(
6266 DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
6267 2u);
6268
6269 FunctionDecl *ToF = Import(FromF, Lang_CXX20);
6270 EXPECT_TRUE(ToF);
6271 TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
6272 // We have two lambda classes after the import.
6273 EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
6274 2u);
6275 }
6276
TEST_P(ASTImporterOptionSpecificTestBase,ImportFunctionDeclWithTypeSourceInfoWithSourceDecl)6277 TEST_P(ASTImporterOptionSpecificTestBase,
6278 ImportFunctionDeclWithTypeSourceInfoWithSourceDecl) {
6279 // This code results in a lambda with implicit constructor.
6280 // The constructor's TypeSourceInfo points out the function prototype.
6281 // This prototype has an EST_Unevaluated in its exception information and a
6282 // SourceDecl that is the function declaration itself.
6283 // The test verifies that AST import of such AST does not crash.
6284 // (Here the function's TypeSourceInfo references the function itself.)
6285 Decl *FromTU = getTuDecl(
6286 R"(
6287 template<typename T> void f(T) { auto X = [](){}; }
6288 void g() { f(10); }
6289 )",
6290 Lang_CXX11, "input0.cc");
6291
6292 // Use LastDeclMatcher to find the LambdaExpr in the template specialization.
6293 CXXRecordDecl *FromL = LastDeclMatcher<LambdaExpr>()
6294 .match(FromTU, lambdaExpr())
6295 ->getLambdaClass();
6296
6297 CXXConstructorDecl *FromCtor = *FromL->ctor_begin();
6298 ASSERT_TRUE(FromCtor->isCopyConstructor());
6299 ASSERT_TRUE(FromCtor->getTypeSourceInfo());
6300 const auto *FromFPT = FromCtor->getType()->getAs<FunctionProtoType>();
6301 ASSERT_TRUE(FromFPT);
6302 EXPECT_EQ(FromCtor->getTypeSourceInfo()->getType().getTypePtr(), FromFPT);
6303 FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
6304 // If type is EST_Unevaluated, SourceDecl should be set to the parent Decl.
6305 EXPECT_EQ(FromEPI.ExceptionSpec.Type, EST_Unevaluated);
6306 EXPECT_EQ(FromEPI.ExceptionSpec.SourceDecl, FromCtor);
6307
6308 auto ToL = Import(FromL, Lang_CXX11);
6309
6310 // Check if the import was correct.
6311 CXXConstructorDecl *ToCtor = *ToL->ctor_begin();
6312 EXPECT_TRUE(ToCtor->getTypeSourceInfo());
6313 const auto *ToFPT = ToCtor->getType()->getAs<FunctionProtoType>();
6314 ASSERT_TRUE(ToFPT);
6315 EXPECT_EQ(ToCtor->getTypeSourceInfo()->getType().getTypePtr(), ToFPT);
6316 FunctionProtoType::ExtProtoInfo ToEPI = ToFPT->getExtProtoInfo();
6317 EXPECT_EQ(ToEPI.ExceptionSpec.Type, EST_Unevaluated);
6318 EXPECT_EQ(ToEPI.ExceptionSpec.SourceDecl, ToCtor);
6319 }
6320
6321 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {};
6322
TEST_P(ImportAutoFunctions,ReturnWithTemplateWithIntegerArgDeclaredInside)6323 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithIntegerArgDeclaredInside) {
6324 Decl *FromTU = getTuDecl(
6325 R"(
6326 template<int> struct Tmpl {};
6327 auto foo() {
6328 constexpr int X = 1;
6329 return Tmpl<X>();
6330 }
6331 )",
6332 Lang_CXX14, "input0.cc");
6333 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6334 FromTU, functionDecl(hasName("foo")));
6335
6336 FunctionDecl *To = Import(From, Lang_CXX14);
6337 EXPECT_TRUE(To);
6338 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6339 }
6340
TEST_P(ImportAutoFunctions,ReturnWithTemplateWithStructDeclaredInside1)6341 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside1) {
6342 Decl *FromTU = getTuDecl(
6343 R"(
6344 template<class> struct Tmpl {};
6345 auto foo() {
6346 struct X {};
6347 return Tmpl<X>();
6348 }
6349 )",
6350 Lang_CXX14, "input0.cc");
6351 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6352 FromTU, functionDecl(hasName("foo")));
6353
6354 FunctionDecl *To = Import(From, Lang_CXX14);
6355 EXPECT_TRUE(To);
6356 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6357 }
6358
TEST_P(ImportAutoFunctions,ReturnWithTemplateWithStructDeclaredInside2)6359 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithStructDeclaredInside2) {
6360 Decl *FromTU = getTuDecl(
6361 R"(
6362 template<class> struct Tmpl {};
6363 auto foo() {
6364 struct X {};
6365 return Tmpl<Tmpl<X>>();
6366 }
6367 )",
6368 Lang_CXX14, "input0.cc");
6369 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6370 FromTU, functionDecl(hasName("foo")));
6371
6372 FunctionDecl *To = Import(From, Lang_CXX14);
6373 EXPECT_TRUE(To);
6374 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6375 }
6376
TEST_P(ImportAutoFunctions,ReturnWithTemplateWithTypedefDeclaredInside)6377 TEST_P(ImportAutoFunctions, ReturnWithTemplateWithTypedefDeclaredInside) {
6378 Decl *FromTU = getTuDecl(
6379 R"(
6380 template<class> struct Tmpl {};
6381 auto foo() {
6382 struct X {};
6383 using x_type = X;
6384 return Tmpl<x_type>();
6385 }
6386 )",
6387 Lang_CXX14, "input0.cc");
6388 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6389 FromTU, functionDecl(hasName("foo")));
6390
6391 FunctionDecl *To = Import(From, Lang_CXX14);
6392 EXPECT_TRUE(To);
6393 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6394 }
6395
TEST_P(ImportAutoFunctions,ReturnWithTypedefDeclaredInside)6396 TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) {
6397 Decl *FromTU = getTuDecl(
6398 R"(
6399 auto X = [](long l) {
6400 using int_type = long;
6401 auto dur = 13;
6402 return static_cast<int_type>(dur);
6403 };
6404 )",
6405 Lang_CXX14, "input0.cc");
6406 CXXMethodDecl *From =
6407 FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl());
6408
6409 // Explicitly set the return type of the lambda's operator() to the TypeAlias.
6410 // Normally the return type would be the built-in 'long' type. However, there
6411 // are cases when Clang does not use the canonical type and the TypeAlias is
6412 // used. I could not create such an AST from regular source code, it requires
6413 // some special state in the preprocessor. I've found such an AST when Clang
6414 // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce
6415 // that with creduce, because after preprocessing, the AST no longer
6416 // contained the TypeAlias as a return type of the lambda.
6417 ASTContext &Ctx = From->getASTContext();
6418 TypeAliasDecl *FromTA =
6419 FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl());
6420 QualType TT = Ctx.getTypedefType(FromTA);
6421 const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType());
6422 QualType NewFunType =
6423 Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo());
6424 From->setType(NewFunType);
6425
6426 CXXMethodDecl *To = Import(From, Lang_CXX14);
6427 EXPECT_TRUE(To);
6428 EXPECT_TRUE(isa<TypedefType>(To->getReturnType()));
6429 }
6430
TEST_P(ImportAutoFunctions,ReturnWithStructDeclaredInside)6431 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) {
6432 Decl *FromTU = getTuDecl(
6433 R"(
6434 auto foo() {
6435 struct X {};
6436 return X();
6437 }
6438 )",
6439 Lang_CXX14, "input0.cc");
6440 FunctionDecl *From =
6441 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
6442
6443 FunctionDecl *To = Import(From, Lang_CXX14);
6444 EXPECT_TRUE(To);
6445 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6446 }
6447
TEST_P(ImportAutoFunctions,ReturnWithStructDeclaredInside2)6448 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) {
6449 Decl *FromTU = getTuDecl(
6450 R"(
6451 auto foo() {
6452 struct X {};
6453 return X();
6454 }
6455 )",
6456 Lang_CXX14, "input0.cc");
6457 FunctionDecl *From =
6458 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
6459
6460 // This time import the type directly.
6461 QualType ToT = ImportType(From->getType(), From, Lang_CXX14);
6462 const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT);
6463 EXPECT_TRUE(isa<AutoType>(FPT->getReturnType()));
6464 }
6465
TEST_P(ImportAutoFunctions,ReturnWithTypedefToStructDeclaredInside)6466 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) {
6467 Decl *FromTU = getTuDecl(
6468 R"(
6469 auto foo() {
6470 struct X {};
6471 using Y = X;
6472 return Y();
6473 }
6474 )",
6475 Lang_CXX14, "input0.cc");
6476 FunctionDecl *From =
6477 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
6478
6479 FunctionDecl *To = Import(From, Lang_CXX14);
6480 EXPECT_TRUE(To);
6481 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6482 }
6483
TEST_P(ImportAutoFunctions,ReturnWithStructDeclaredNestedInside)6484 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) {
6485 Decl *FromTU = getTuDecl(
6486 R"(
6487 auto foo() {
6488 struct X { struct Y{}; };
6489 return X::Y();
6490 }
6491 )",
6492 Lang_CXX14, "input0.cc");
6493 FunctionDecl *From =
6494 FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
6495
6496 FunctionDecl *To = Import(From, Lang_CXX14);
6497 EXPECT_TRUE(To);
6498 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6499 }
6500
TEST_P(ImportAutoFunctions,ReturnWithInternalLambdaType)6501 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) {
6502 Decl *FromTU = getTuDecl(
6503 R"(
6504 auto f() {
6505 auto l = []() {
6506 struct X {};
6507 return X();
6508 };
6509 return l();
6510 }
6511 )",
6512 Lang_CXX17, "input0.cc");
6513 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6514 FromTU, functionDecl(hasName("f")));
6515
6516 FunctionDecl *To = Import(From, Lang_CXX17);
6517 EXPECT_TRUE(To);
6518 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6519 }
6520
TEST_P(ImportAutoFunctions,ReturnWithTypeInIf)6521 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) {
6522 Decl *FromTU = getTuDecl(
6523 R"(
6524 auto f() {
6525 if (struct X {} x; true)
6526 return X();
6527 else
6528 return X();
6529 }
6530 )",
6531 Lang_CXX17, "input0.cc");
6532 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6533 FromTU, functionDecl(hasName("f")));
6534
6535 FunctionDecl *To = Import(From, Lang_CXX17);
6536 EXPECT_TRUE(To);
6537 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6538 }
6539
TEST_P(ImportAutoFunctions,ReturnWithTypeInFor)6540 TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) {
6541 Decl *FromTU = getTuDecl(
6542 R"(
6543 auto f() {
6544 for (struct X {} x;;)
6545 return X();
6546 }
6547 )",
6548 Lang_CXX17, "input0.cc");
6549 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6550 FromTU, functionDecl(hasName("f")));
6551
6552 FunctionDecl *To = Import(From, Lang_CXX17);
6553 EXPECT_TRUE(To);
6554 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6555 }
6556
TEST_P(ImportAutoFunctions,ReturnWithTypeInSwitch)6557 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) {
6558 Decl *FromTU = getTuDecl(
6559 R"(
6560 auto f() {
6561 switch (struct X {} x; 10) {
6562 case 10:
6563 return X();
6564 }
6565 }
6566 )",
6567 Lang_CXX17, "input0.cc");
6568 FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
6569 FromTU, functionDecl(hasName("f")));
6570
6571 FunctionDecl *To = Import(From, Lang_CXX17);
6572 EXPECT_TRUE(To);
6573 EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
6574 }
6575
6576 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {};
6577
TEST_P(ImportSourceLocations,PreserveFileIDTreeStructure)6578 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) {
6579 // Tests that the FileID tree structure (with the links being the include
6580 // chains) is preserved while importing other files (which need to be
6581 // added to this structure with fake include locations.
6582
6583 SourceLocation Location1;
6584 {
6585 auto Pattern = varDecl(hasName("X"));
6586 Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c");
6587 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
6588
6589 Location1 = Import(FromD, Lang_C99)->getLocation();
6590 }
6591 SourceLocation Location2;
6592 {
6593 auto Pattern = varDecl(hasName("Y"));
6594 Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c");
6595 auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
6596
6597 Location2 = Import(FromD, Lang_C99)->getLocation();
6598 }
6599
6600 SourceManager &ToSM = ToAST->getSourceManager();
6601 FileID FileID1 = ToSM.getFileID(Location1);
6602 FileID FileID2 = ToSM.getFileID(Location2);
6603
6604 // Check that the imported files look like as if they were included from the
6605 // start of the main file.
6606 SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID());
6607 EXPECT_NE(FileID1, ToSM.getMainFileID());
6608 EXPECT_NE(FileID2, ToSM.getMainFileID());
6609 EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart);
6610 EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart);
6611
6612 // Let the SourceManager check the order of the locations. The order should
6613 // be the order in which the declarations are imported.
6614 EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2));
6615 EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1));
6616 }
6617
TEST_P(ImportSourceLocations,NormalFileBuffer)6618 TEST_P(ImportSourceLocations, NormalFileBuffer) {
6619 // Test importing normal file buffers.
6620
6621 std::string Path = "input0.c";
6622 std::string Source = "int X;";
6623 TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path);
6624
6625 SourceLocation ImportedLoc;
6626 {
6627 // Import the VarDecl to trigger the importing of the FileID.
6628 auto Pattern = varDecl(hasName("X"));
6629 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
6630 ImportedLoc = Import(FromD, Lang_C99)->getLocation();
6631 }
6632
6633 // Make sure the imported buffer has the original contents.
6634 SourceManager &ToSM = ToAST->getSourceManager();
6635 FileID ImportedID = ToSM.getFileID(ImportedLoc);
6636 EXPECT_EQ(Source,
6637 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
6638 }
6639
TEST_P(ImportSourceLocations,OverwrittenFileBuffer)6640 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) {
6641 // Test importing overwritten file buffers.
6642
6643 std::string Path = "input0.c";
6644 TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path);
6645
6646 // Overwrite the file buffer for our input file with new content.
6647 const std::string Contents = "overwritten contents";
6648 SourceLocation ImportedLoc;
6649 {
6650 SourceManager &FromSM = FromTU->getASTContext().getSourceManager();
6651 clang::FileManager &FM = FromSM.getFileManager();
6652 const clang::FileEntry &FE =
6653 *FM.getVirtualFile(Path, static_cast<off_t>(Contents.size()), 0);
6654
6655 llvm::SmallVector<char, 64> Buffer;
6656 Buffer.append(Contents.begin(), Contents.end());
6657 auto FileContents = std::make_unique<llvm::SmallVectorMemoryBuffer>(
6658 std::move(Buffer), Path, /*RequiresNullTerminator=*/false);
6659 FromSM.overrideFileContents(&FE, std::move(FileContents));
6660
6661 // Import the VarDecl to trigger the importing of the FileID.
6662 auto Pattern = varDecl(hasName("X"));
6663 VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
6664 ImportedLoc = Import(FromD, Lang_C99)->getLocation();
6665 }
6666
6667 // Make sure the imported buffer has the overwritten contents.
6668 SourceManager &ToSM = ToAST->getSourceManager();
6669 FileID ImportedID = ToSM.getFileID(ImportedLoc);
6670 EXPECT_EQ(Contents,
6671 ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
6672 }
6673
6674 struct ImportAttributes : public ASTImporterOptionSpecificTestBase {
checkAttrImportCommonclang::ast_matchers::ImportAttributes6675 void checkAttrImportCommon(const Attr *From, const Attr *To,
6676 const Decl *ToD) {
6677
6678 // Verify that dump does not crash because invalid data.
6679 ToD->dump(llvm::nulls());
6680
6681 EXPECT_EQ(From->getParsedKind(), To->getParsedKind());
6682 EXPECT_EQ(From->getSyntax(), To->getSyntax());
6683 if (From->getAttrName()) {
6684 EXPECT_TRUE(To->getAttrName());
6685 EXPECT_STREQ(From->getAttrName()->getNameStart(),
6686 To->getAttrName()->getNameStart());
6687 } else {
6688 EXPECT_FALSE(To->getAttrName());
6689 }
6690 if (From->getScopeName()) {
6691 EXPECT_TRUE(To->getScopeName());
6692 EXPECT_STREQ(From->getScopeName()->getNameStart(),
6693 To->getScopeName()->getNameStart());
6694 } else {
6695 EXPECT_FALSE(To->getScopeName());
6696 }
6697 EXPECT_EQ(From->getSpellingListIndex(), To->getSpellingListIndex());
6698 EXPECT_STREQ(From->getSpelling(), To->getSpelling());
6699 EXPECT_EQ(From->isInherited(), To->isInherited());
6700 EXPECT_EQ(From->isImplicit(), To->isImplicit());
6701 EXPECT_EQ(From->isPackExpansion(), To->isPackExpansion());
6702 EXPECT_EQ(From->isLateParsed(), To->isLateParsed());
6703 }
6704
6705 template <class DT, class AT>
importAttrclang::ast_matchers::ImportAttributes6706 void importAttr(const char *Code, AT *&FromAttr, AT *&ToAttr) {
6707 static_assert(std::is_base_of<Attr, AT>::value, "AT should be an Attr");
6708 static_assert(std::is_base_of<Decl, DT>::value, "DT should be a Decl");
6709
6710 Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input.cc");
6711 DT *FromD =
6712 FirstDeclMatcher<DT>().match(FromTU, namedDecl(hasName("test")));
6713 ASSERT_TRUE(FromD);
6714
6715 DT *ToD = Import(FromD, Lang_CXX11);
6716 ASSERT_TRUE(ToD);
6717
6718 FromAttr = FromD->template getAttr<AT>();
6719 ToAttr = ToD->template getAttr<AT>();
6720 ASSERT_TRUE(FromAttr);
6721 EXPECT_TRUE(ToAttr);
6722
6723 checkAttrImportCommon(FromAttr, ToAttr, ToD);
6724 }
6725
checkImportedclang::ast_matchers::ImportAttributes6726 template <class T> void checkImported(const T *From, const T *To) {
6727 EXPECT_TRUE(To);
6728 EXPECT_NE(From, To);
6729 }
6730
6731 template <class T>
checkImportVariadicArgclang::ast_matchers::ImportAttributes6732 void checkImportVariadicArg(const llvm::iterator_range<T **> &From,
6733 const llvm::iterator_range<T **> &To) {
6734 for (auto FromI = From.begin(), ToI = To.begin(); FromI != From.end();
6735 ++FromI, ++ToI) {
6736 ASSERT_NE(ToI, To.end());
6737 checkImported(*FromI, *ToI);
6738 }
6739 }
6740 };
6741
6742 template <>
checkImported(const Decl * From,const Decl * To)6743 void ImportAttributes::checkImported<Decl>(const Decl *From, const Decl *To) {
6744 EXPECT_TRUE(To);
6745 EXPECT_NE(From, To);
6746 EXPECT_EQ(To->getTranslationUnitDecl(),
6747 ToAST->getASTContext().getTranslationUnitDecl());
6748 }
6749
6750 // FIXME: Use ImportAttributes for this test.
TEST_P(ASTImporterOptionSpecificTestBase,ImportExprOfAlignmentAttr)6751 TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) {
6752 // Test if import of these packed and aligned attributes does not trigger an
6753 // error situation where source location from 'From' context is referenced in
6754 // 'To' context through evaluation of the alignof attribute.
6755 // This happens if the 'alignof(A)' expression is not imported correctly.
6756 Decl *FromTU = getTuDecl(
6757 R"(
6758 struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; };
6759 struct alignas(alignof(A)) S {};
6760 )",
6761 Lang_CXX11, "input.cc");
6762 auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
6763 FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit())));
6764 ASSERT_TRUE(FromD);
6765
6766 auto *ToD = Import(FromD, Lang_CXX11);
6767 ASSERT_TRUE(ToD);
6768
6769 auto *FromAttr = FromD->getAttr<AlignedAttr>();
6770 auto *ToAttr = ToD->getAttr<AlignedAttr>();
6771 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited());
6772 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion());
6773 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit());
6774 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax());
6775 EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling());
6776 EXPECT_TRUE(ToAttr->getAlignmentExpr());
6777
6778 auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match(
6779 ToD->getTranslationUnitDecl(),
6780 cxxRecordDecl(hasName("A"), unless(isImplicit())));
6781 // Ensure that 'struct A' was imported (through reference from attribute of
6782 // 'S').
6783 EXPECT_TRUE(ToA);
6784 }
6785
6786 // FIXME: Use ImportAttributes for this test.
TEST_P(ASTImporterOptionSpecificTestBase,ImportFormatAttr)6787 TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) {
6788 Decl *FromTU = getTuDecl(
6789 R"(
6790 int foo(const char * fmt, ...)
6791 __attribute__ ((__format__ (__scanf__, 1, 2)));
6792 )",
6793 Lang_CXX03, "input.cc");
6794 auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
6795 FromTU, functionDecl(hasName("foo")));
6796 ASSERT_TRUE(FromD);
6797
6798 auto *ToD = Import(FromD, Lang_CXX03);
6799 ASSERT_TRUE(ToD);
6800 ToD->dump(); // Should not crash!
6801
6802 auto *FromAttr = FromD->getAttr<FormatAttr>();
6803 auto *ToAttr = ToD->getAttr<FormatAttr>();
6804 EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited());
6805 EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion());
6806 EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit());
6807 EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax());
6808 EXPECT_EQ(FromAttr->getAttributeSpellingListIndex(),
6809 ToAttr->getAttributeSpellingListIndex());
6810 EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName());
6811 }
6812
TEST_P(ImportAttributes,ImportEnableIf)6813 TEST_P(ImportAttributes, ImportEnableIf) {
6814 EnableIfAttr *FromAttr, *ToAttr;
6815 importAttr<FunctionDecl>(
6816 "void test(int A) __attribute__((enable_if(A == 1, \"message\")));",
6817 FromAttr, ToAttr);
6818 checkImported(FromAttr->getCond(), ToAttr->getCond());
6819 EXPECT_EQ(FromAttr->getMessage(), ToAttr->getMessage());
6820 }
6821
TEST_P(ImportAttributes,ImportGuardedVar)6822 TEST_P(ImportAttributes, ImportGuardedVar) {
6823 GuardedVarAttr *FromAttr, *ToAttr;
6824 importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr,
6825 ToAttr);
6826 }
6827
TEST_P(ImportAttributes,ImportPtGuardedVar)6828 TEST_P(ImportAttributes, ImportPtGuardedVar) {
6829 PtGuardedVarAttr *FromAttr, *ToAttr;
6830 importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr,
6831 ToAttr);
6832 }
6833
TEST_P(ImportAttributes,ImportScopedLockable)6834 TEST_P(ImportAttributes, ImportScopedLockable) {
6835 ScopedLockableAttr *FromAttr, *ToAttr;
6836 importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};",
6837 FromAttr, ToAttr);
6838 }
6839
TEST_P(ImportAttributes,ImportCapability)6840 TEST_P(ImportAttributes, ImportCapability) {
6841 CapabilityAttr *FromAttr, *ToAttr;
6842 importAttr<CXXRecordDecl>(
6843 "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr);
6844 EXPECT_EQ(FromAttr->getName(), ToAttr->getName());
6845 }
6846
TEST_P(ImportAttributes,ImportAssertCapability)6847 TEST_P(ImportAttributes, ImportAssertCapability) {
6848 AssertCapabilityAttr *FromAttr, *ToAttr;
6849 importAttr<FunctionDecl>(
6850 "void test(int A1, int A2) __attribute__((assert_capability(A1, A2)));",
6851 FromAttr, ToAttr);
6852 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6853 }
6854
TEST_P(ImportAttributes,ImportAcquireCapability)6855 TEST_P(ImportAttributes, ImportAcquireCapability) {
6856 AcquireCapabilityAttr *FromAttr, *ToAttr;
6857 importAttr<FunctionDecl>(
6858 "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));",
6859 FromAttr, ToAttr);
6860 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6861 }
6862
TEST_P(ImportAttributes,ImportTryAcquireCapability)6863 TEST_P(ImportAttributes, ImportTryAcquireCapability) {
6864 TryAcquireCapabilityAttr *FromAttr, *ToAttr;
6865 importAttr<FunctionDecl>(
6866 "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, "
6867 "A2)));",
6868 FromAttr, ToAttr);
6869 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
6870 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6871 }
6872
TEST_P(ImportAttributes,ImportReleaseCapability)6873 TEST_P(ImportAttributes, ImportReleaseCapability) {
6874 ReleaseCapabilityAttr *FromAttr, *ToAttr;
6875 importAttr<FunctionDecl>(
6876 "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));",
6877 FromAttr, ToAttr);
6878 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6879 }
6880
TEST_P(ImportAttributes,ImportRequiresCapability)6881 TEST_P(ImportAttributes, ImportRequiresCapability) {
6882 RequiresCapabilityAttr *FromAttr, *ToAttr;
6883 importAttr<FunctionDecl>(
6884 "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));",
6885 FromAttr, ToAttr);
6886 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6887 }
6888
TEST_P(ImportAttributes,ImportNoThreadSafetyAnalysis)6889 TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) {
6890 NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr;
6891 importAttr<FunctionDecl>(
6892 "void test() __attribute__((no_thread_safety_analysis));", FromAttr,
6893 ToAttr);
6894 }
6895
TEST_P(ImportAttributes,ImportGuardedBy)6896 TEST_P(ImportAttributes, ImportGuardedBy) {
6897 GuardedByAttr *FromAttr, *ToAttr;
6898 importAttr<VarDecl>(
6899 R"(
6900 int G;
6901 int test __attribute__((guarded_by(G)));
6902 )",
6903 FromAttr, ToAttr);
6904 checkImported(FromAttr->getArg(), ToAttr->getArg());
6905 }
6906
TEST_P(ImportAttributes,ImportPtGuardedBy)6907 TEST_P(ImportAttributes, ImportPtGuardedBy) {
6908 PtGuardedByAttr *FromAttr, *ToAttr;
6909 importAttr<VarDecl>(
6910 R"(
6911 int G;
6912 int *test __attribute__((pt_guarded_by(G)));
6913 )",
6914 FromAttr, ToAttr);
6915 checkImported(FromAttr->getArg(), ToAttr->getArg());
6916 }
6917
TEST_P(ImportAttributes,ImportAcquiredAfter)6918 TEST_P(ImportAttributes, ImportAcquiredAfter) {
6919 AcquiredAfterAttr *FromAttr, *ToAttr;
6920 importAttr<VarDecl>(
6921 R"(
6922 struct __attribute__((lockable)) L {};
6923 L A1;
6924 L A2;
6925 L test __attribute__((acquired_after(A1, A2)));
6926 )",
6927 FromAttr, ToAttr);
6928 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6929 }
6930
TEST_P(ImportAttributes,ImportAcquiredBefore)6931 TEST_P(ImportAttributes, ImportAcquiredBefore) {
6932 AcquiredBeforeAttr *FromAttr, *ToAttr;
6933 importAttr<VarDecl>(
6934 R"(
6935 struct __attribute__((lockable)) L {};
6936 L A1;
6937 L A2;
6938 L test __attribute__((acquired_before(A1, A2)));
6939 )",
6940 FromAttr, ToAttr);
6941 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6942 }
6943
TEST_P(ImportAttributes,ImportAssertExclusiveLock)6944 TEST_P(ImportAttributes, ImportAssertExclusiveLock) {
6945 AssertExclusiveLockAttr *FromAttr, *ToAttr;
6946 importAttr<FunctionDecl>("void test(int A1, int A2) "
6947 "__attribute__((assert_exclusive_lock(A1, A2)));",
6948 FromAttr, ToAttr);
6949 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6950 }
6951
TEST_P(ImportAttributes,ImportAssertSharedLock)6952 TEST_P(ImportAttributes, ImportAssertSharedLock) {
6953 AssertSharedLockAttr *FromAttr, *ToAttr;
6954 importAttr<FunctionDecl>(
6955 "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));",
6956 FromAttr, ToAttr);
6957 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6958 }
6959
TEST_P(ImportAttributes,ImportExclusiveTrylockFunction)6960 TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) {
6961 ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr;
6962 importAttr<FunctionDecl>(
6963 "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, "
6964 "A1, A2)));",
6965 FromAttr, ToAttr);
6966 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
6967 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6968 }
6969
TEST_P(ImportAttributes,ImportSharedTrylockFunction)6970 TEST_P(ImportAttributes, ImportSharedTrylockFunction) {
6971 SharedTrylockFunctionAttr *FromAttr, *ToAttr;
6972 importAttr<FunctionDecl>(
6973 "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, "
6974 "A2)));",
6975 FromAttr, ToAttr);
6976 checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
6977 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6978 }
6979
TEST_P(ImportAttributes,ImportLockReturned)6980 TEST_P(ImportAttributes, ImportLockReturned) {
6981 LockReturnedAttr *FromAttr, *ToAttr;
6982 importAttr<FunctionDecl>(
6983 "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr,
6984 ToAttr);
6985 checkImported(FromAttr->getArg(), ToAttr->getArg());
6986 }
6987
TEST_P(ImportAttributes,ImportLocksExcluded)6988 TEST_P(ImportAttributes, ImportLocksExcluded) {
6989 LocksExcludedAttr *FromAttr, *ToAttr;
6990 importAttr<FunctionDecl>(
6991 "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));",
6992 FromAttr, ToAttr);
6993 checkImportVariadicArg(FromAttr->args(), ToAttr->args());
6994 }
6995
6996 template <typename T>
ExtendWithOptions(const T & Values,const std::vector<std::string> & Args)6997 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) {
6998 auto Copy = Values;
6999 for (std::vector<std::string> &ArgV : Copy) {
7000 for (const std::string &Arg : Args) {
7001 ArgV.push_back(Arg);
7002 }
7003 }
7004 return ::testing::ValuesIn(Copy);
7005 }
7006
7007 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase {
ImportWithExternalSourceclang::ast_matchers::ImportWithExternalSource7008 ImportWithExternalSource() {
7009 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
7010 ASTContext &FromContext, FileManager &FromFileManager,
7011 bool MinimalImport,
7012 const std::shared_ptr<ASTImporterSharedState> &SharedState) {
7013 return new ASTImporter(ToContext, ToFileManager, FromContext,
7014 // Use minimal import for these tests.
7015 FromFileManager, /*MinimalImport=*/true,
7016 // We use the regular lookup.
7017 /*SharedState=*/nullptr);
7018 };
7019 }
7020 };
7021
7022 /// An ExternalASTSource that keeps track of the tags is completed.
7023 struct SourceWithCompletedTagList : clang::ExternalASTSource {
7024 std::vector<clang::TagDecl *> &CompletedTags;
SourceWithCompletedTagListclang::ast_matchers::SourceWithCompletedTagList7025 SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags)
7026 : CompletedTags(CompletedTags) {}
CompleteTypeclang::ast_matchers::SourceWithCompletedTagList7027 void CompleteType(TagDecl *Tag) override {
7028 auto *Record = cast<CXXRecordDecl>(Tag);
7029 Record->startDefinition();
7030 Record->completeDefinition();
7031 CompletedTags.push_back(Tag);
7032 }
7033 using clang::ExternalASTSource::CompleteType;
7034 };
7035
TEST_P(ImportWithExternalSource,CompleteRecordBeforeImporting)7036 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) {
7037 // Create an empty TU.
7038 TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp");
7039
7040 // Create and add the test ExternalASTSource.
7041 std::vector<clang::TagDecl *> CompletedTags;
7042 IntrusiveRefCntPtr<ExternalASTSource> source =
7043 new SourceWithCompletedTagList(CompletedTags);
7044 clang::ASTContext &Context = FromTU->getASTContext();
7045 Context.setExternalSource(std::move(source));
7046
7047 // Create a dummy class by hand with external lexical storage.
7048 IdentifierInfo &Ident = Context.Idents.get("test_class");
7049 auto *Record = CXXRecordDecl::Create(
7050 Context, TTK_Class, FromTU, SourceLocation(), SourceLocation(), &Ident);
7051 Record->setHasExternalLexicalStorage();
7052 FromTU->addDecl(Record);
7053
7054 // Do a minimal import of the created class.
7055 EXPECT_EQ(0U, CompletedTags.size());
7056 Import(Record, Lang_CXX03);
7057 EXPECT_EQ(0U, CompletedTags.size());
7058
7059 // Import the definition of the created class.
7060 llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record);
7061 EXPECT_FALSE((bool)Err);
7062 consumeError(std::move(Err));
7063
7064 // Make sure the class was completed once.
7065 EXPECT_EQ(1U, CompletedTags.size());
7066 EXPECT_EQ(Record, CompletedTags.front());
7067 }
7068
TEST_P(ImportFunctions,CTADImplicit)7069 TEST_P(ImportFunctions, CTADImplicit) {
7070 Decl *FromTU = getTuDecl(
7071 R"(
7072 template <typename T> struct A {
7073 A(T);
7074 };
7075 A a{(int)0};
7076 )",
7077 Lang_CXX17, "input.cc");
7078 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7079 FromTU,
7080 cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>")))));
7081 auto *ToD = Import(FromD, Lang_CXX17);
7082 ASSERT_TRUE(ToD);
7083 EXPECT_TRUE(ToD->isCopyDeductionCandidate());
7084 // Check that the deduced class template is also imported.
7085 EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull(
7086 FromD->getDeducedTemplate()));
7087 }
7088
TEST_P(ImportFunctions,CTADUserDefinedExplicit)7089 TEST_P(ImportFunctions, CTADUserDefinedExplicit) {
7090 Decl *FromTU = getTuDecl(
7091 R"(
7092 template <typename T> struct A {
7093 A(T);
7094 };
7095 template <typename T> explicit A(T) -> A<float>;
7096 A a{(int)0}; // calls A<float>::A(float)
7097 )",
7098 Lang_CXX17, "input.cc");
7099 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7100 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
7101 // Not-implicit: i.e. not compiler-generated, user defined.
7102 ASSERT_FALSE(FromD->isImplicit());
7103 ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword.
7104 auto *ToD = Import(FromD, Lang_CXX17);
7105 ASSERT_TRUE(ToD);
7106 EXPECT_FALSE(FromD->isImplicit());
7107 EXPECT_TRUE(ToD->isExplicit());
7108 }
7109
TEST_P(ImportFunctions,CTADWithLocalTypedef)7110 TEST_P(ImportFunctions, CTADWithLocalTypedef) {
7111 Decl *TU = getTuDecl(
7112 R"(
7113 template <typename T> struct A {
7114 typedef T U;
7115 A(U);
7116 };
7117 A a{(int)0};
7118 )",
7119 Lang_CXX17, "input.cc");
7120 auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7121 TU, cxxDeductionGuideDecl());
7122 auto *ToD = Import(FromD, Lang_CXX17);
7123 ASSERT_TRUE(ToD);
7124 }
7125
TEST_P(ImportFunctions,ParmVarDeclDeclContext)7126 TEST_P(ImportFunctions, ParmVarDeclDeclContext) {
7127 constexpr auto FromTUCode = R"(
7128 void f(int P);
7129 )";
7130 Decl *FromTU = getTuDecl(FromTUCode, Lang_CXX11);
7131 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
7132 FromTU, functionDecl(hasName("f")));
7133 ASSERT_TRUE(FromF);
7134
7135 auto *ImportedF = Import(FromF, Lang_CXX11);
7136 EXPECT_TRUE(ImportedF);
7137 EXPECT_TRUE(SharedStatePtr->getLookupTable()->contains(
7138 ImportedF, ImportedF->getParamDecl(0)));
7139 }
7140
7141 // FIXME Move these tests out of ASTImporterTest. For that we need to factor
7142 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase
7143 // into a new test Fixture. Then we should lift up this Fixture to its own
7144 // implementation file and only then could we reuse the Fixture in other AST
7145 // unitttests.
7146 struct CTAD : ASTImporterOptionSpecificTestBase {};
7147
TEST_P(CTAD,DeductionGuideShouldReferToANonLocalTypedef)7148 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) {
7149 Decl *TU = getTuDecl(
7150 R"(
7151 typedef int U;
7152 template <typename T> struct A {
7153 A(U, T);
7154 };
7155 A a{(int)0, (int)0};
7156 )",
7157 Lang_CXX17, "input.cc");
7158 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7159 TU, cxxDeductionGuideDecl());
7160 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
7161 TU, typedefNameDecl(hasName("U")));
7162 ParmVarDecl *Param = Guide->getParamDecl(0);
7163 // The type of the first param (which is a typedef) should match the typedef
7164 // in the global scope.
7165 EXPECT_EQ(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef);
7166 }
7167
TEST_P(CTAD,DeductionGuideShouldReferToANonLocalTypedefInParamPtr)7168 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) {
7169 Decl *TU = getTuDecl(
7170 R"(
7171 typedef int U;
7172 template <typename T> struct A {
7173 A(U*, T);
7174 };
7175 A a{(int*)0, (int)0};
7176 )",
7177 Lang_CXX17, "input.cc");
7178 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7179 TU, cxxDeductionGuideDecl());
7180 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
7181 TU, typedefNameDecl(hasName("U")));
7182 ParmVarDecl *Param = Guide->getParamDecl(0);
7183 EXPECT_EQ(Param->getType()
7184 ->getAs<PointerType>()
7185 ->getPointeeType()
7186 ->getAs<TypedefType>()
7187 ->getDecl(),
7188 Typedef);
7189 }
7190
TEST_P(CTAD,DeductionGuideShouldCopyALocalTypedef)7191 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) {
7192 Decl *TU = getTuDecl(
7193 R"(
7194 template <typename T> struct A {
7195 typedef T U;
7196 A(U, T);
7197 };
7198 A a{(int)0, (int)0};
7199 )",
7200 Lang_CXX17, "input.cc");
7201 auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7202 TU, cxxDeductionGuideDecl());
7203 auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
7204 TU, typedefNameDecl(hasName("U")));
7205 ParmVarDecl *Param = Guide->getParamDecl(0);
7206 EXPECT_NE(Param->getType()->castAs<TypedefType>()->getDecl(), Typedef);
7207 }
7208
7209 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, CTAD,
7210 DefaultTestValuesForRunOptions);
7211
TEST_P(ASTImporterOptionSpecificTestBase,TypedefWithAttribute)7212 TEST_P(ASTImporterOptionSpecificTestBase, TypedefWithAttribute) {
7213 Decl *TU = getTuDecl(
7214 R"(
7215 namespace N {
7216 typedef int X __attribute__((annotate("A")));
7217 }
7218 )",
7219 Lang_CXX17, "input.cc");
7220 auto *FromD =
7221 FirstDeclMatcher<TypedefDecl>().match(TU, typedefDecl(hasName("X")));
7222 auto *ToD = Import(FromD, Lang_CXX17);
7223 ASSERT_TRUE(ToD);
7224 ASSERT_EQ(ToD->getAttrs().size(), 1U);
7225 auto *ToAttr = dyn_cast<AnnotateAttr>(ToD->getAttrs()[0]);
7226 ASSERT_TRUE(ToAttr);
7227 EXPECT_EQ(ToAttr->getAnnotation(), "A");
7228 }
7229
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet)7230 TEST_P(ASTImporterOptionSpecificTestBase,
7231 ImportOfTemplatedDeclWhenPreviousDeclHasNoDescribedTemplateSet) {
7232 Decl *FromTU = getTuDecl(
7233 R"(
7234
7235 namespace std {
7236 template<typename T>
7237 class basic_stringbuf;
7238 }
7239 namespace std {
7240 class char_traits;
7241 template<typename T = char_traits>
7242 class basic_stringbuf;
7243 }
7244 namespace std {
7245 template<typename T>
7246 class basic_stringbuf {};
7247 }
7248
7249 )",
7250 Lang_CXX11);
7251
7252 auto *From1 = FirstDeclMatcher<ClassTemplateDecl>().match(
7253 FromTU,
7254 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
7255 auto *To1 = cast_or_null<ClassTemplateDecl>(Import(From1, Lang_CXX11));
7256 EXPECT_TRUE(To1);
7257
7258 auto *From2 = LastDeclMatcher<ClassTemplateDecl>().match(
7259 FromTU,
7260 classTemplateDecl(hasName("basic_stringbuf"), unless(isImplicit())));
7261 auto *To2 = cast_or_null<ClassTemplateDecl>(Import(From2, Lang_CXX11));
7262 EXPECT_TRUE(To2);
7263 }
7264
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfCapturedVLAType)7265 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfCapturedVLAType) {
7266 Decl *FromTU = getTuDecl(
7267 R"(
7268 void declToImport(int N) {
7269 int VLA[N];
7270 [&VLA] {}; // FieldDecl inside the lambda.
7271 }
7272 )",
7273 Lang_CXX14);
7274 auto *FromFD = FirstDeclMatcher<FieldDecl>().match(FromTU, fieldDecl());
7275 ASSERT_TRUE(FromFD);
7276 ASSERT_TRUE(FromFD->hasCapturedVLAType());
7277
7278 auto *ToFD = Import(FromFD, Lang_CXX14);
7279 EXPECT_TRUE(ToFD);
7280 EXPECT_TRUE(ToFD->hasCapturedVLAType());
7281 EXPECT_NE(FromFD->getCapturedVLAType(), ToFD->getCapturedVLAType());
7282 }
7283
TEST_P(ASTImporterOptionSpecificTestBase,ImportEnumMemberSpecialization)7284 TEST_P(ASTImporterOptionSpecificTestBase, ImportEnumMemberSpecialization) {
7285 Decl *FromTU = getTuDecl(
7286 R"(
7287 template <class T> struct A {
7288 enum tagname { enumerator };
7289 };
7290 template struct A<int>;
7291 )",
7292 Lang_CXX03);
7293 auto *FromD = FirstDeclMatcher<EnumDecl>().match(
7294 FromTU, enumDecl(hasName("tagname"),
7295 hasParent(classTemplateSpecializationDecl())));
7296 ASSERT_TRUE(FromD);
7297 ASSERT_TRUE(FromD->getMemberSpecializationInfo());
7298
7299 auto *ToD = Import(FromD, Lang_CXX03);
7300 EXPECT_TRUE(ToD);
7301 EXPECT_TRUE(ToD->getMemberSpecializationInfo());
7302 EXPECT_EQ(FromD->getTemplateSpecializationKind(),
7303 ToD->getTemplateSpecializationKind());
7304 }
7305
TEST_P(ASTImporterOptionSpecificTestBase,ImportIsInheritingConstructorBit)7306 TEST_P(ASTImporterOptionSpecificTestBase, ImportIsInheritingConstructorBit) {
7307 Decl *FromTU = getTuDecl(
7308 R"(
7309 struct A {
7310 A(int);
7311 };
7312 struct B : A {
7313 using A::A; // Inherited ctor.
7314 };
7315 void f() {
7316 (B(0));
7317 }
7318 )",
7319 Lang_CXX11);
7320 auto *FromD = FirstDeclMatcher<CXXConstructorDecl>().match(
7321 FromTU, cxxConstructorDecl(isInheritingConstructor()));
7322 ASSERT_TRUE(FromD);
7323 ASSERT_TRUE(FromD->isInheritingConstructor());
7324
7325 auto *ToD = Import(FromD, Lang_CXX11);
7326 ASSERT_TRUE(ToD);
7327 EXPECT_TRUE(ToD->isInheritingConstructor());
7328 }
7329
TEST_P(ASTImporterOptionSpecificTestBase,ImportConstructorUsingShadow)7330 TEST_P(ASTImporterOptionSpecificTestBase, ImportConstructorUsingShadow) {
7331 TranslationUnitDecl *FromTU = getTuDecl(
7332 R"(
7333 struct A {
7334 A(int, int);
7335 };
7336 struct B : A {
7337 using A::A;
7338 };
7339 struct C : B {
7340 using B::B;
7341 };
7342 )",
7343 Lang_CXX11);
7344
7345 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordC) {
7346 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match(
7347 TU, cxxRecordDecl(hasName("A")));
7348 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
7349 TU, cxxRecordDecl(hasName("B")));
7350 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match(
7351 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)),
7352 parameterCountIs(2)));
7353 auto *ShadowBA = cast<ConstructorUsingShadowDecl>(
7354 FirstDeclMatcher<UsingShadowDecl>().match(
7355 TU, usingShadowDecl(hasParent(equalsNode(RecordB)),
7356 hasTargetDecl(equalsNode(ConstrA)))));
7357 auto *ShadowCA = cast<ConstructorUsingShadowDecl>(
7358 FirstDeclMatcher<UsingShadowDecl>().match(
7359 TU, usingShadowDecl(hasParent(equalsNode(RecordC)),
7360 hasTargetDecl(equalsNode(ConstrA)))));
7361 EXPECT_EQ(ShadowBA->getTargetDecl(), ConstrA);
7362 EXPECT_EQ(ShadowBA->getNominatedBaseClass(), RecordA);
7363 EXPECT_EQ(ShadowBA->getConstructedBaseClass(), RecordA);
7364 EXPECT_EQ(ShadowBA->getNominatedBaseClassShadowDecl(), nullptr);
7365 EXPECT_EQ(ShadowBA->getConstructedBaseClassShadowDecl(), nullptr);
7366 EXPECT_FALSE(ShadowBA->constructsVirtualBase());
7367 EXPECT_EQ(ShadowCA->getTargetDecl(), ConstrA);
7368 EXPECT_EQ(ShadowCA->getNominatedBaseClass(), RecordB);
7369 EXPECT_EQ(ShadowCA->getConstructedBaseClass(), RecordB);
7370 EXPECT_EQ(ShadowCA->getNominatedBaseClassShadowDecl(), ShadowBA);
7371 EXPECT_EQ(ShadowCA->getConstructedBaseClassShadowDecl(), ShadowBA);
7372 EXPECT_FALSE(ShadowCA->constructsVirtualBase());
7373 };
7374
7375 auto *FromC = FirstDeclMatcher<CXXRecordDecl>().match(
7376 FromTU, cxxRecordDecl(hasName("C")));
7377
7378 auto *ToC = Import(FromC, Lang_CXX11);
7379 TranslationUnitDecl *ToTU = ToC->getTranslationUnitDecl();
7380
7381 CheckAST(FromTU, FromC);
7382 CheckAST(ToTU, ToC);
7383 }
7384
AST_MATCHER_P(UsingShadowDecl,hasIntroducerDecl,internal::Matcher<NamedDecl>,InnerMatcher)7385 AST_MATCHER_P(UsingShadowDecl, hasIntroducerDecl, internal::Matcher<NamedDecl>,
7386 InnerMatcher) {
7387 return InnerMatcher.matches(*Node.getIntroducer(), Finder, Builder);
7388 }
7389
TEST_P(ASTImporterOptionSpecificTestBase,ImportConstructorUsingShadowVirtualBase)7390 TEST_P(ASTImporterOptionSpecificTestBase,
7391 ImportConstructorUsingShadowVirtualBase) {
7392 TranslationUnitDecl *FromTU = getTuDecl(
7393 R"(
7394 struct A { A(int, int); };
7395 struct B : A { using A::A; };
7396
7397 struct V1 : virtual B { using B::B; };
7398 struct V2 : virtual B { using B::B; };
7399
7400 struct D2 : V1, V2 {
7401 using V1::V1;
7402 using V2::V2;
7403 };
7404 )",
7405 Lang_CXX11);
7406
7407 auto CheckAST = [](TranslationUnitDecl *TU, CXXRecordDecl *RecordD2) {
7408 auto *RecordA = FirstDeclMatcher<CXXRecordDecl>().match(
7409 TU, cxxRecordDecl(hasName("A")));
7410 auto *RecordB = FirstDeclMatcher<CXXRecordDecl>().match(
7411 TU, cxxRecordDecl(hasName("B")));
7412 auto *RecordV1 = FirstDeclMatcher<CXXRecordDecl>().match(
7413 TU, cxxRecordDecl(hasName("V1")));
7414 auto *RecordV2 = FirstDeclMatcher<CXXRecordDecl>().match(
7415 TU, cxxRecordDecl(hasName("V2")));
7416 auto *ConstrA = FirstDeclMatcher<CXXConstructorDecl>().match(
7417 TU, cxxConstructorDecl(hasParent(equalsNode(RecordA)),
7418 parameterCountIs(2)));
7419 auto *ConstrB = FirstDeclMatcher<CXXConstructorDecl>().match(
7420 TU, cxxConstructorDecl(hasParent(equalsNode(RecordB)),
7421 isCopyConstructor()));
7422 auto *UsingD2V1 = FirstDeclMatcher<UsingDecl>().match(
7423 TU, usingDecl(hasParent(equalsNode(RecordD2))));
7424 auto *UsingD2V2 = LastDeclMatcher<UsingDecl>().match(
7425 TU, usingDecl(hasParent(equalsNode(RecordD2))));
7426 auto *ShadowBA = cast<ConstructorUsingShadowDecl>(
7427 FirstDeclMatcher<UsingShadowDecl>().match(
7428 TU, usingShadowDecl(hasParent(equalsNode(RecordB)),
7429 hasTargetDecl(equalsNode(ConstrA)))));
7430 auto *ShadowV1A = cast<ConstructorUsingShadowDecl>(
7431 FirstDeclMatcher<UsingShadowDecl>().match(
7432 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)),
7433 hasTargetDecl(equalsNode(ConstrA)))));
7434 auto *ShadowV1B = cast<ConstructorUsingShadowDecl>(
7435 FirstDeclMatcher<UsingShadowDecl>().match(
7436 TU, usingShadowDecl(hasParent(equalsNode(RecordV1)),
7437 hasTargetDecl(equalsNode(ConstrB)))));
7438 auto *ShadowV2A = cast<ConstructorUsingShadowDecl>(
7439 FirstDeclMatcher<UsingShadowDecl>().match(
7440 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)),
7441 hasTargetDecl(equalsNode(ConstrA)))));
7442 auto *ShadowV2B = cast<ConstructorUsingShadowDecl>(
7443 FirstDeclMatcher<UsingShadowDecl>().match(
7444 TU, usingShadowDecl(hasParent(equalsNode(RecordV2)),
7445 hasTargetDecl(equalsNode(ConstrB)))));
7446 auto *ShadowD2V1A = cast<ConstructorUsingShadowDecl>(
7447 FirstDeclMatcher<UsingShadowDecl>().match(
7448 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
7449 hasIntroducerDecl(equalsNode(UsingD2V1)),
7450 hasTargetDecl(equalsNode(ConstrA)))));
7451 auto *ShadowD2V1B = cast<ConstructorUsingShadowDecl>(
7452 FirstDeclMatcher<UsingShadowDecl>().match(
7453 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
7454 hasIntroducerDecl(equalsNode(UsingD2V1)),
7455 hasTargetDecl(equalsNode(ConstrB)))));
7456 auto *ShadowD2V2A = cast<ConstructorUsingShadowDecl>(
7457 FirstDeclMatcher<UsingShadowDecl>().match(
7458 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
7459 hasIntroducerDecl(equalsNode(UsingD2V2)),
7460 hasTargetDecl(equalsNode(ConstrA)))));
7461 auto *ShadowD2V2B = cast<ConstructorUsingShadowDecl>(
7462 FirstDeclMatcher<UsingShadowDecl>().match(
7463 TU, usingShadowDecl(hasParent(equalsNode(RecordD2)),
7464 hasIntroducerDecl(equalsNode(UsingD2V2)),
7465 hasTargetDecl(equalsNode(ConstrB)))));
7466
7467 EXPECT_EQ(ShadowD2V1A->getTargetDecl(), ConstrA);
7468 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClassShadowDecl(), ShadowV1A);
7469 EXPECT_EQ(ShadowD2V1A->getNominatedBaseClass(), RecordV1);
7470 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClassShadowDecl(), ShadowBA);
7471 EXPECT_EQ(ShadowD2V1A->getConstructedBaseClass(), RecordB);
7472 EXPECT_TRUE(ShadowD2V1A->constructsVirtualBase());
7473 EXPECT_EQ(ShadowD2V1B->getTargetDecl(), ConstrB);
7474 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClassShadowDecl(), ShadowV1B);
7475 EXPECT_EQ(ShadowD2V1B->getNominatedBaseClass(), RecordV1);
7476 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClassShadowDecl(), nullptr);
7477 EXPECT_EQ(ShadowD2V1B->getConstructedBaseClass(), RecordB);
7478 EXPECT_TRUE(ShadowD2V1B->constructsVirtualBase());
7479 EXPECT_EQ(ShadowD2V2A->getTargetDecl(), ConstrA);
7480 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClassShadowDecl(), ShadowV2A);
7481 EXPECT_EQ(ShadowD2V2A->getNominatedBaseClass(), RecordV2);
7482 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClassShadowDecl(), ShadowBA);
7483 EXPECT_EQ(ShadowD2V2A->getConstructedBaseClass(), RecordB);
7484 EXPECT_TRUE(ShadowD2V2A->constructsVirtualBase());
7485 EXPECT_EQ(ShadowD2V2B->getTargetDecl(), ConstrB);
7486 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClassShadowDecl(), ShadowV2B);
7487 EXPECT_EQ(ShadowD2V2B->getNominatedBaseClass(), RecordV2);
7488 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClassShadowDecl(), nullptr);
7489 EXPECT_EQ(ShadowD2V2B->getConstructedBaseClass(), RecordB);
7490 EXPECT_TRUE(ShadowD2V2B->constructsVirtualBase());
7491
7492 EXPECT_TRUE(ShadowV1A->constructsVirtualBase());
7493 EXPECT_TRUE(ShadowV1B->constructsVirtualBase());
7494 EXPECT_TRUE(ShadowV2A->constructsVirtualBase());
7495 EXPECT_TRUE(ShadowV2B->constructsVirtualBase());
7496 EXPECT_FALSE(ShadowBA->constructsVirtualBase());
7497 };
7498
7499 auto *FromD2 = FirstDeclMatcher<CXXRecordDecl>().match(
7500 FromTU, cxxRecordDecl(hasName("D2")));
7501
7502 auto *ToD2 = Import(FromD2, Lang_CXX11);
7503 TranslationUnitDecl *ToTU = ToD2->getTranslationUnitDecl();
7504
7505 CheckAST(FromTU, FromD2);
7506 CheckAST(ToTU, ToD2);
7507 }
7508
TEST_P(ASTImporterOptionSpecificTestBase,ImportUsingShadowList)7509 TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingShadowList) {
7510 TranslationUnitDecl *FromTU = getTuDecl(
7511 R"(
7512 struct A {
7513 void f();
7514 void f(int);
7515 };
7516 struct B : A {
7517 using A::f;
7518 };
7519 )",
7520 Lang_CXX11);
7521
7522 auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match(
7523 FromTU, cxxRecordDecl(hasName("B")));
7524
7525 auto *ToB = Import(FromB, Lang_CXX11);
7526 TranslationUnitDecl *ToTU = ToB->getTranslationUnitDecl();
7527
7528 auto *ToUsing = FirstDeclMatcher<UsingDecl>().match(
7529 ToTU, usingDecl(hasParent(equalsNode(ToB))));
7530 auto *ToUsingShadowF1 = FirstDeclMatcher<UsingShadowDecl>().match(
7531 ToTU, usingShadowDecl(hasTargetDecl(
7532 functionDecl(hasName("f"), parameterCountIs(0)))));
7533 auto *ToUsingShadowF2 = FirstDeclMatcher<UsingShadowDecl>().match(
7534 ToTU, usingShadowDecl(hasTargetDecl(
7535 functionDecl(hasName("f"), parameterCountIs(1)))));
7536
7537 EXPECT_EQ(ToUsing->shadow_size(), 2u);
7538 auto ShadowI = ToUsing->shadow_begin();
7539 EXPECT_EQ(*ShadowI, ToUsingShadowF1);
7540 ++ShadowI;
7541 EXPECT_EQ(*ShadowI, ToUsingShadowF2);
7542 }
7543
AST_MATCHER_P(FunctionTemplateDecl,templateParameterCountIs,unsigned,Cnt)7544 AST_MATCHER_P(FunctionTemplateDecl, templateParameterCountIs, unsigned, Cnt) {
7545 return Node.getTemplateParameters()->size() == Cnt;
7546 }
7547
TEST_P(ASTImporterOptionSpecificTestBase,ImportDeductionGuide)7548 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuide) {
7549 TranslationUnitDecl *FromTU = getTuDecl(
7550 R"(
7551 template<class> class A { };
7552 template<class T> class B {
7553 template<class T1, typename = A<T>> B(T1);
7554 };
7555 template<class T>
7556 B(T, T) -> B<int>;
7557 )",
7558 Lang_CXX17);
7559
7560 // Get the implicit deduction guide for (non-default) constructor of 'B'.
7561 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
7562 FromTU, functionTemplateDecl(templateParameterCountIs(3)));
7563 // Implicit deduction guide for copy constructor of 'B'.
7564 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
7565 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
7566 // User defined deduction guide.
7567 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7568 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
7569
7570 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters();
7571 // Don't know why exactly but this is the DeclContext here.
7572 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(),
7573 FromDGCopyCtor->getTemplatedDecl());
7574 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(),
7575 FromDGCtor->getTemplatedDecl());
7576 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(),
7577 FromDGCtor->getTemplatedDecl());
7578 EXPECT_EQ(
7579 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
7580 FromDGCopyCtor->getTemplatedDecl());
7581 EXPECT_EQ(FromDGOther->getDescribedTemplate()
7582 ->getTemplateParameters()
7583 ->getParam(0)
7584 ->getDeclContext(),
7585 FromDGOther);
7586
7587 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17);
7588 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17);
7589 auto *ToDGOther = Import(FromDGOther, Lang_CXX17);
7590 ASSERT_TRUE(ToDGCtor);
7591 ASSERT_TRUE(ToDGCopyCtor);
7592 ASSERT_TRUE(ToDGOther);
7593
7594 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters();
7595 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(),
7596 ToDGCopyCtor->getTemplatedDecl());
7597 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(),
7598 ToDGCtor->getTemplatedDecl());
7599 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(),
7600 ToDGCtor->getTemplatedDecl());
7601 EXPECT_EQ(
7602 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
7603 ToDGCopyCtor->getTemplatedDecl());
7604 EXPECT_EQ(ToDGOther->getDescribedTemplate()
7605 ->getTemplateParameters()
7606 ->getParam(0)
7607 ->getDeclContext(),
7608 ToDGOther);
7609 }
7610
TEST_P(ASTImporterOptionSpecificTestBase,ImportDeductionGuideDifferentOrder)7611 TEST_P(ASTImporterOptionSpecificTestBase, ImportDeductionGuideDifferentOrder) {
7612 // This test demonstrates that the DeclContext of the imported object is
7613 // dependent on the order of import. The test is an exact copy of the previous
7614 // one except at the indicated locations.
7615 TranslationUnitDecl *FromTU = getTuDecl(
7616 R"(
7617 template<class> class A { };
7618 template<class T> class B {
7619 template<class T1, typename = A<T>> B(T1);
7620 };
7621 template<class T>
7622 B(T, T) -> B<int>;
7623 )",
7624 Lang_CXX17);
7625
7626 // Get the implicit deduction guide for (non-default) constructor of 'B'.
7627 auto *FromDGCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
7628 FromTU, functionTemplateDecl(templateParameterCountIs(3)));
7629 // Implicit deduction guide for copy constructor of 'B'.
7630 auto *FromDGCopyCtor = FirstDeclMatcher<FunctionTemplateDecl>().match(
7631 FromTU, functionTemplateDecl(templateParameterCountIs(1), isImplicit()));
7632 // User defined deduction guide.
7633 auto *FromDGOther = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
7634 FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
7635
7636 TemplateParameterList *FromDGCtorTP = FromDGCtor->getTemplateParameters();
7637 // Don't know why exactly but this is the DeclContext here.
7638 EXPECT_EQ(FromDGCtorTP->getParam(0)->getDeclContext(),
7639 FromDGCopyCtor->getTemplatedDecl());
7640 EXPECT_EQ(FromDGCtorTP->getParam(1)->getDeclContext(),
7641 FromDGCtor->getTemplatedDecl());
7642 EXPECT_EQ(FromDGCtorTP->getParam(2)->getDeclContext(),
7643 FromDGCtor->getTemplatedDecl());
7644 EXPECT_EQ(
7645 FromDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
7646 FromDGCopyCtor->getTemplatedDecl());
7647 EXPECT_EQ(FromDGOther->getDescribedTemplate()
7648 ->getTemplateParameters()
7649 ->getParam(0)
7650 ->getDeclContext(),
7651 FromDGOther);
7652
7653 // Here the import of 'ToDGCopyCtor' and 'ToDGCtor' is reversed relative to
7654 // the previous test.
7655 auto *ToDGCopyCtor = Import(FromDGCopyCtor, Lang_CXX17);
7656 auto *ToDGCtor = Import(FromDGCtor, Lang_CXX17);
7657 auto *ToDGOther = Import(FromDGOther, Lang_CXX17);
7658 ASSERT_TRUE(ToDGCtor);
7659 ASSERT_TRUE(ToDGCopyCtor);
7660 ASSERT_TRUE(ToDGOther);
7661
7662 TemplateParameterList *ToDGCtorTP = ToDGCtor->getTemplateParameters();
7663 // Next line: DeclContext is different relative to the previous test.
7664 EXPECT_EQ(ToDGCtorTP->getParam(0)->getDeclContext(),
7665 ToDGCtor->getTemplatedDecl());
7666 EXPECT_EQ(ToDGCtorTP->getParam(1)->getDeclContext(),
7667 ToDGCtor->getTemplatedDecl());
7668 EXPECT_EQ(ToDGCtorTP->getParam(2)->getDeclContext(),
7669 ToDGCtor->getTemplatedDecl());
7670 // Next line: DeclContext is different relative to the previous test.
7671 EXPECT_EQ(
7672 ToDGCopyCtor->getTemplateParameters()->getParam(0)->getDeclContext(),
7673 ToDGCtor->getTemplatedDecl());
7674 EXPECT_EQ(ToDGOther->getDescribedTemplate()
7675 ->getTemplateParameters()
7676 ->getParam(0)
7677 ->getDeclContext(),
7678 ToDGOther);
7679 }
7680
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordWithLayoutRequestingExpr)7681 TEST_P(ASTImporterOptionSpecificTestBase,
7682 ImportRecordWithLayoutRequestingExpr) {
7683 TranslationUnitDecl *FromTU = getTuDecl(
7684 R"(
7685 struct A {
7686 int idx;
7687 static void foo(A x) {
7688 (void)&"text"[x.idx];
7689 }
7690 };
7691 )",
7692 Lang_CXX11);
7693
7694 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
7695 FromTU, cxxRecordDecl(hasName("A")));
7696
7697 // Test that during import of 'foo' the record layout can be obtained without
7698 // crash.
7699 auto *ToA = Import(FromA, Lang_CXX11);
7700 EXPECT_TRUE(ToA);
7701 EXPECT_TRUE(ToA->isCompleteDefinition());
7702 }
7703
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordWithLayoutRequestingExprDifferentRecord)7704 TEST_P(ASTImporterOptionSpecificTestBase,
7705 ImportRecordWithLayoutRequestingExprDifferentRecord) {
7706 TranslationUnitDecl *FromTU = getTuDecl(
7707 R"(
7708 struct B;
7709 struct A {
7710 int idx;
7711 B *b;
7712 };
7713 struct B {
7714 static void foo(A x) {
7715 (void)&"text"[x.idx];
7716 }
7717 };
7718 )",
7719 Lang_CXX11);
7720
7721 auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
7722 FromTU, cxxRecordDecl(hasName("A")));
7723
7724 // Test that during import of 'foo' the record layout (of 'A') can be obtained
7725 // without crash. It is not possible to have all of the fields of 'A' imported
7726 // at that time (without big code changes).
7727 auto *ToA = Import(FromA, Lang_CXX11);
7728 EXPECT_TRUE(ToA);
7729 EXPECT_TRUE(ToA->isCompleteDefinition());
7730 }
7731
TEST_P(ASTImporterOptionSpecificTestBase,ImportInClassInitializerFromField)7732 TEST_P(ASTImporterOptionSpecificTestBase, ImportInClassInitializerFromField) {
7733 // Encounter import of a field when the field already exists but has the
7734 // in-class initializer expression not yet set. Such case can occur in the AST
7735 // of generated template specializations.
7736 // The first code forces to create a template specialization of
7737 // `A<int>` but without implicit constructors.
7738 // The second ("From") code contains a variable of type `A<int>`, this
7739 // results in a template specialization that has constructors and
7740 // CXXDefaultInitExpr nodes.
7741 Decl *ToTU = getToTuDecl(
7742 R"(
7743 void f();
7744 template<typename> struct A { int X = 1; };
7745 struct B { A<int> Y; };
7746 )",
7747 Lang_CXX11);
7748 auto *ToX = FirstDeclMatcher<FieldDecl>().match(
7749 ToTU,
7750 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
7751 ASSERT_TRUE(ToX->hasInClassInitializer());
7752 ASSERT_FALSE(ToX->getInClassInitializer());
7753
7754 Decl *FromTU = getTuDecl(
7755 R"(
7756 void f();
7757 template<typename> struct A { int X = 1; };
7758 struct B { A<int> Y; };
7759 //
7760 A<int> Z;
7761 )",
7762 Lang_CXX11, "input1.cc");
7763 auto *FromX = FirstDeclMatcher<FieldDecl>().match(
7764 FromTU,
7765 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
7766
7767 auto *ToXImported = Import(FromX, Lang_CXX11);
7768 EXPECT_EQ(ToXImported, ToX);
7769 EXPECT_TRUE(ToX->getInClassInitializer());
7770 }
7771
TEST_P(ASTImporterOptionSpecificTestBase,ImportInClassInitializerFromCXXDefaultInitExpr)7772 TEST_P(ASTImporterOptionSpecificTestBase,
7773 ImportInClassInitializerFromCXXDefaultInitExpr) {
7774 // Encounter AST import of a CXXDefaultInitExpr where the "to-field"
7775 // of it exists but has the in-class initializer not set yet.
7776 Decl *ToTU = getToTuDecl(
7777 R"(
7778 namespace N {
7779 template<typename> int b;
7780 struct X;
7781 }
7782 template<typename> struct A { N::X *X = nullptr; };
7783 struct B { A<int> Y; };
7784 )",
7785 Lang_CXX14);
7786 auto *ToX = FirstDeclMatcher<FieldDecl>().match(
7787 ToTU,
7788 fieldDecl(hasName("X"), hasParent(classTemplateSpecializationDecl())));
7789 ASSERT_TRUE(ToX->hasInClassInitializer());
7790 ASSERT_FALSE(ToX->getInClassInitializer());
7791
7792 Decl *FromTU = getTuDecl(
7793 R"(
7794 namespace N {
7795 template<typename> int b;
7796 struct X;
7797 }
7798 template<typename> struct A { N::X *X = nullptr; };
7799 struct B { A<int> Y; };
7800 //
7801 void f() {
7802 (void)A<int>{};
7803 }
7804 struct C {
7805 C(): attr(new A<int>{}){}
7806 A<int> *attr;
7807 const int value = N::b<C>;
7808 };
7809 )",
7810 Lang_CXX14, "input1.cc");
7811 auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
7812 FromTU, functionDecl(hasName("f"), isDefinition()));
7813 auto *ToF = Import(FromF, Lang_CXX11);
7814 EXPECT_TRUE(ToF);
7815 EXPECT_TRUE(ToX->getInClassInitializer());
7816 }
7817
TEST_P(ASTImporterOptionSpecificTestBase,isNewDecl)7818 TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
7819 Decl *FromTU = getTuDecl(
7820 R"(
7821 int bar() {
7822 return 0;
7823 }
7824 void other() {
7825 bar();
7826 }
7827 )",
7828 Lang_CXX11);
7829 Decl *ToTU = getToTuDecl(
7830 R"(
7831 int bar() {
7832 return 0;
7833 }
7834 )",
7835 Lang_CXX11);
7836 auto *FromOther = FirstDeclMatcher<FunctionDecl>().match(
7837 FromTU, functionDecl(hasName("other")));
7838 ASSERT_TRUE(FromOther);
7839
7840 auto *ToOther = Import(FromOther, Lang_CXX11);
7841 ASSERT_TRUE(ToOther);
7842
7843 auto *ToBar = FirstDeclMatcher<FunctionDecl>().match(
7844 ToTU, functionDecl(hasName("bar")));
7845
7846 EXPECT_TRUE(SharedStatePtr->isNewDecl(ToOther));
7847 EXPECT_FALSE(SharedStatePtr->isNewDecl(ToBar));
7848 }
7849
7850 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterLookupTableTest,
7851 DefaultTestValuesForRunOptions);
7852
7853 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportPath,
7854 ::testing::Values(std::vector<std::string>()));
7855
7856 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportExpr,
7857 DefaultTestValuesForRunOptions);
7858
7859 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFixedPointExpr,
7860 ExtendWithOptions(DefaultTestArrayForRunOptions,
7861 std::vector<std::string>{
7862 "-ffixed-point"}));
7863
7864 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportBlock,
7865 ExtendWithOptions(DefaultTestArrayForRunOptions,
7866 std::vector<std::string>{
7867 "-fblocks"}));
7868
7869 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportType,
7870 DefaultTestValuesForRunOptions);
7871
7872 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportDecl,
7873 DefaultTestValuesForRunOptions);
7874
7875 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase,
7876 DefaultTestValuesForRunOptions);
7877
7878 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ErrorHandlingTest,
7879 DefaultTestValuesForRunOptions);
7880
7881 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, RedirectingImporterTest,
7882 DefaultTestValuesForRunOptions);
7883
7884 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctions,
7885 DefaultTestValuesForRunOptions);
7886
7887 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAutoFunctions,
7888 DefaultTestValuesForRunOptions);
7889
7890 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFunctionTemplates,
7891 DefaultTestValuesForRunOptions);
7892
7893 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctionTemplates,
7894 DefaultTestValuesForRunOptions);
7895
7896 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportClasses,
7897 DefaultTestValuesForRunOptions);
7898
7899 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendFunctions,
7900 DefaultTestValuesForRunOptions);
7901
7902 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportFriendClasses,
7903 DefaultTestValuesForRunOptions);
7904
7905 INSTANTIATE_TEST_SUITE_P(ParameterizedTests,
7906 ImportFunctionTemplateSpecializations,
7907 DefaultTestValuesForRunOptions);
7908
7909 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportImplicitMethods,
7910 DefaultTestValuesForRunOptions);
7911
7912 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportVariables,
7913 DefaultTestValuesForRunOptions);
7914
7915 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, LLDBLookupTest,
7916 DefaultTestValuesForRunOptions);
7917
7918 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportSourceLocations,
7919 DefaultTestValuesForRunOptions);
7920
7921 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportWithExternalSource,
7922 DefaultTestValuesForRunOptions);
7923
7924 INSTANTIATE_TEST_SUITE_P(ParameterizedTests, ImportAttributes,
7925 DefaultTestValuesForRunOptions);
7926
7927 } // end namespace ast_matchers
7928 } // end namespace clang
7929