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::__anone9d694570111::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 
TEST_P(ImportExpr,ImportStringLiteral)249 TEST_P(ImportExpr, ImportStringLiteral) {
250   MatchVerifier<Decl> Verifier;
251   testImport("void declToImport() { (void)\"foo\"; }", Lang_CXX03, "",
252              Lang_CXX03, Verifier,
253              functionDecl(hasDescendant(
254                  stringLiteral(hasType(asString("const char [4]"))))));
255   testImport("void declToImport() { (void)L\"foo\"; }", Lang_CXX03, "",
256              Lang_CXX03, Verifier,
257              functionDecl(hasDescendant(
258                  stringLiteral(hasType(asString("const wchar_t [4]"))))));
259   testImport("void declToImport() { (void) \"foo\" \"bar\"; }", Lang_CXX03, "",
260              Lang_CXX03, Verifier,
261              functionDecl(hasDescendant(
262                  stringLiteral(hasType(asString("const char [7]"))))));
263 }
264 
TEST_P(ImportExpr,ImportChooseExpr)265 TEST_P(ImportExpr, ImportChooseExpr) {
266   MatchVerifier<Decl> Verifier;
267 
268   // This case tests C code that is not condition-dependent and has a true
269   // condition.
270   testImport("void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }",
271              Lang_C99, "", Lang_C99, Verifier,
272              functionDecl(hasDescendant(chooseExpr())));
273 }
274 
TEST_P(ImportExpr,ImportGNUNullExpr)275 TEST_P(ImportExpr, ImportGNUNullExpr) {
276   MatchVerifier<Decl> Verifier;
277   testImport("void declToImport() { (void)__null; }", Lang_CXX03, "",
278              Lang_CXX03, Verifier,
279              functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger())))));
280 }
281 
TEST_P(ImportExpr,ImportCXXNullPtrLiteralExpr)282 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) {
283   MatchVerifier<Decl> Verifier;
284   testImport(
285       "void declToImport() { (void)nullptr; }",
286       Lang_CXX11, "", Lang_CXX11, Verifier,
287       functionDecl(hasDescendant(cxxNullPtrLiteralExpr())));
288 }
289 
290 
TEST_P(ImportExpr,ImportFloatinglLiteralExpr)291 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) {
292   MatchVerifier<Decl> Verifier;
293   testImport("void declToImport() { (void)1.0; }", Lang_C99, "", Lang_C99,
294              Verifier,
295              functionDecl(hasDescendant(
296                  floatLiteral(equals(1.0), hasType(asString("double"))))));
297   testImport("void declToImport() { (void)1.0e-5f; }", Lang_C99, "", Lang_C99,
298              Verifier,
299              functionDecl(hasDescendant(
300                  floatLiteral(equals(1.0e-5f), hasType(asString("float"))))));
301 }
302 
TEST_P(ImportFixedPointExpr,ImportFixedPointerLiteralExpr)303 TEST_P(ImportFixedPointExpr, ImportFixedPointerLiteralExpr) {
304   MatchVerifier<Decl> Verifier;
305   testImport("void declToImport() { (void)1.0k; }", Lang_C99, "", Lang_C99,
306              Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
307   testImport("void declToImport() { (void)0.75r; }", Lang_C99, "", Lang_C99,
308              Verifier, functionDecl(hasDescendant(fixedPointLiteral())));
309 }
310 
TEST_P(ImportExpr,ImportImaginaryLiteralExpr)311 TEST_P(ImportExpr, ImportImaginaryLiteralExpr) {
312   MatchVerifier<Decl> Verifier;
313   testImport(
314       "void declToImport() { (void)1.0i; }",
315       Lang_CXX14, "", Lang_CXX14, Verifier,
316       functionDecl(hasDescendant(imaginaryLiteral())));
317 }
318 
TEST_P(ImportExpr,ImportCompoundLiteralExpr)319 TEST_P(ImportExpr, ImportCompoundLiteralExpr) {
320   MatchVerifier<Decl> Verifier;
321   testImport("void declToImport() {"
322              "  struct s { int x; long y; unsigned z; }; "
323              "  (void)(struct s){ 42, 0L, 1U }; }",
324              Lang_CXX03, "", Lang_CXX03, Verifier,
325              functionDecl(hasDescendant(compoundLiteralExpr(
326                  hasType(asString("struct s")),
327                  has(initListExpr(
328                      hasType(asString("struct s")),
329                      has(integerLiteral(equals(42), hasType(asString("int")))),
330                      has(integerLiteral(equals(0), hasType(asString("long")))),
331                      has(integerLiteral(
332                          equals(1), hasType(asString("unsigned int"))))))))));
333 }
334 
TEST_P(ImportExpr,ImportCXXThisExpr)335 TEST_P(ImportExpr, ImportCXXThisExpr) {
336   MatchVerifier<Decl> Verifier;
337   testImport("class declToImport { void f() { (void)this; } };", Lang_CXX03, "",
338              Lang_CXX03, Verifier,
339              cxxRecordDecl(hasMethod(hasDescendant(
340                  cxxThisExpr(hasType(asString("class declToImport *")))))));
341 }
342 
TEST_P(ImportExpr,ImportAtomicExpr)343 TEST_P(ImportExpr, ImportAtomicExpr) {
344   MatchVerifier<Decl> Verifier;
345   testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }",
346              Lang_C99, "", Lang_C99, Verifier,
347              functionDecl(hasDescendant(atomicExpr(
348                  has(ignoringParenImpCasts(
349                      declRefExpr(hasDeclaration(varDecl(hasName("ptr"))),
350                                  hasType(asString("int *"))))),
351                  has(integerLiteral(equals(1), hasType(asString("int"))))))));
352 }
353 
TEST_P(ImportExpr,ImportLabelDeclAndAddrLabelExpr)354 TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) {
355   MatchVerifier<Decl> Verifier;
356   testImport("void declToImport() { loop: goto loop; (void)&&loop; }", Lang_C99,
357              "", Lang_C99, Verifier,
358              functionDecl(hasDescendant(labelStmt(
359                               hasDeclaration(labelDecl(hasName("loop"))))),
360                           hasDescendant(addrLabelExpr(
361                               hasDeclaration(labelDecl(hasName("loop")))))));
362 }
363 
AST_MATCHER_P(TemplateDecl,hasTemplateDecl,internal::Matcher<NamedDecl>,InnerMatcher)364 AST_MATCHER_P(TemplateDecl, hasTemplateDecl,
365               internal::Matcher<NamedDecl>, InnerMatcher) {
366   const NamedDecl *Template = Node.getTemplatedDecl();
367   return Template && InnerMatcher.matches(*Template, Finder, Builder);
368 }
369 
TEST_P(ImportExpr,ImportParenListExpr)370 TEST_P(ImportExpr, ImportParenListExpr) {
371   MatchVerifier<Decl> Verifier;
372   testImport(
373       "template<typename T> class dummy { void f() { dummy X(*this); } };"
374       "typedef dummy<int> declToImport;"
375       "template class dummy<int>;",
376       Lang_CXX03, "", Lang_CXX03, Verifier,
377       typedefDecl(hasType(templateSpecializationType(
378           hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate(
379               classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(allOf(
380                   hasName("f"),
381                   hasBody(compoundStmt(has(declStmt(hasSingleDecl(
382                       varDecl(hasInitializer(parenListExpr(has(unaryOperator(
383                           hasOperatorName("*"),
384                           hasUnaryOperand(cxxThisExpr())))))))))))))))))))))));
385 }
386 
TEST_P(ImportExpr,ImportSwitch)387 TEST_P(ImportExpr, ImportSwitch) {
388   MatchVerifier<Decl> Verifier;
389   testImport("void declToImport() { int b; switch (b) { case 1: break; } }",
390              Lang_C99, "", Lang_C99, Verifier,
391              functionDecl(hasDescendant(
392                  switchStmt(has(compoundStmt(has(caseStmt())))))));
393 }
394 
TEST_P(ImportExpr,ImportStmtExpr)395 TEST_P(ImportExpr, ImportStmtExpr) {
396   MatchVerifier<Decl> Verifier;
397   testImport(
398       "void declToImport() { int b; int a = b ?: 1; int C = ({int X=4; X;}); }",
399       Lang_C99, "", Lang_C99, Verifier,
400       traverse(ast_type_traits::TK_AsIs,
401                functionDecl(hasDescendant(varDecl(
402                    hasName("C"), hasType(asString("int")),
403                    hasInitializer(stmtExpr(
404                        hasAnySubstatement(declStmt(hasSingleDecl(varDecl(
405                            hasName("X"), hasType(asString("int")),
406                            hasInitializer(integerLiteral(equals(4))))))),
407                        hasDescendant(implicitCastExpr()))))))));
408 }
409 
TEST_P(ImportExpr,ImportConditionalOperator)410 TEST_P(ImportExpr, ImportConditionalOperator) {
411   MatchVerifier<Decl> Verifier;
412   testImport("void declToImport() { (void)(true ? 1 : -5); }", Lang_CXX03, "",
413              Lang_CXX03, Verifier,
414              functionDecl(hasDescendant(conditionalOperator(
415                  hasCondition(cxxBoolLiteral(equals(true))),
416                  hasTrueExpression(integerLiteral(equals(1))),
417                  hasFalseExpression(unaryOperator(
418                      hasUnaryOperand(integerLiteral(equals(5)))))))));
419 }
420 
TEST_P(ImportExpr,ImportBinaryConditionalOperator)421 TEST_P(ImportExpr, ImportBinaryConditionalOperator) {
422   MatchVerifier<Decl> Verifier;
423   testImport(
424       "void declToImport() { (void)(1 ?: -5); }", Lang_CXX03, "", Lang_CXX03,
425       Verifier,
426       traverse(ast_type_traits::TK_AsIs,
427                functionDecl(hasDescendant(binaryConditionalOperator(
428                    hasCondition(implicitCastExpr(
429                        hasSourceExpression(opaqueValueExpr(
430                            hasSourceExpression(integerLiteral(equals(1))))),
431                        hasType(booleanType()))),
432                    hasTrueExpression(opaqueValueExpr(
433                        hasSourceExpression(integerLiteral(equals(1))))),
434                    hasFalseExpression(unaryOperator(
435                        hasOperatorName("-"),
436                        hasUnaryOperand(integerLiteral(equals(5))))))))));
437 }
438 
TEST_P(ImportExpr,ImportDesignatedInitExpr)439 TEST_P(ImportExpr, ImportDesignatedInitExpr) {
440   MatchVerifier<Decl> Verifier;
441   testImport(
442       "void declToImport() {"
443       "  struct point { double x; double y; };"
444       "  struct point ptarray[10] = "
445       "{ [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }",
446       Lang_C99, "", Lang_C99, Verifier,
447       functionDecl(hasDescendant(initListExpr(
448           has(designatedInitExpr(designatorCountIs(2),
449                                  hasDescendant(floatLiteral(equals(1.0))),
450                                  hasDescendant(integerLiteral(equals(2))))),
451           has(designatedInitExpr(designatorCountIs(2),
452                                  hasDescendant(floatLiteral(equals(2.0))),
453                                  hasDescendant(integerLiteral(equals(2))))),
454           has(designatedInitExpr(designatorCountIs(2),
455                                  hasDescendant(floatLiteral(equals(1.0))),
456                                  hasDescendant(integerLiteral(equals(0)))))))));
457 }
458 
TEST_P(ImportExpr,ImportPredefinedExpr)459 TEST_P(ImportExpr, ImportPredefinedExpr) {
460   MatchVerifier<Decl> Verifier;
461   // __func__ expands as StringLiteral("declToImport")
462   testImport("void declToImport() { (void)__func__; }", Lang_CXX03, "",
463              Lang_CXX03, Verifier,
464              functionDecl(hasDescendant(predefinedExpr(
465                  hasType(asString("const char [13]")),
466                  has(stringLiteral(hasType(asString("const char [13]"))))))));
467 }
468 
TEST_P(ImportExpr,ImportInitListExpr)469 TEST_P(ImportExpr, ImportInitListExpr) {
470   MatchVerifier<Decl> Verifier;
471   testImport(
472       "void declToImport() {"
473       "  struct point { double x; double y; };"
474       "  point ptarray[10] = { [2].y = 1.0, [2].x = 2.0,"
475       "                        [0].x = 1.0 }; }",
476       Lang_CXX03, "", Lang_CXX03, Verifier,
477       functionDecl(hasDescendant(initListExpr(
478           has(cxxConstructExpr(requiresZeroInitialization())),
479           has(initListExpr(
480               hasType(asString("struct point")), has(floatLiteral(equals(1.0))),
481               has(implicitValueInitExpr(hasType(asString("double")))))),
482           has(initListExpr(hasType(asString("struct point")),
483                            has(floatLiteral(equals(2.0))),
484                            has(floatLiteral(equals(1.0)))))))));
485 }
486 
487 
488 const internal::VariadicDynCastAllOfMatcher<Expr, VAArgExpr> vaArgExpr;
489 
TEST_P(ImportExpr,ImportVAArgExpr)490 TEST_P(ImportExpr, ImportVAArgExpr) {
491   MatchVerifier<Decl> Verifier;
492   testImport("void declToImport(__builtin_va_list list, ...) {"
493              "  (void)__builtin_va_arg(list, int); }",
494              Lang_CXX03, "", Lang_CXX03, Verifier,
495              functionDecl(hasDescendant(
496                  cStyleCastExpr(hasSourceExpression(vaArgExpr())))));
497 }
498 
TEST_P(ImportExpr,CXXTemporaryObjectExpr)499 TEST_P(ImportExpr, CXXTemporaryObjectExpr) {
500   MatchVerifier<Decl> Verifier;
501   testImport(
502       "struct C {};"
503       "void declToImport() { C c = C(); }",
504       Lang_CXX03, "", Lang_CXX03, Verifier,
505       traverse(ast_type_traits::TK_AsIs,
506                functionDecl(hasDescendant(exprWithCleanups(has(cxxConstructExpr(
507                    has(materializeTemporaryExpr(has(implicitCastExpr(
508                        has(cxxTemporaryObjectExpr()))))))))))));
509 }
510 
TEST_P(ImportType,ImportAtomicType)511 TEST_P(ImportType, ImportAtomicType) {
512   MatchVerifier<Decl> Verifier;
513   testImport(
514       "void declToImport() { typedef _Atomic(int) a_int; }",
515       Lang_CXX11, "", Lang_CXX11, Verifier,
516       functionDecl(hasDescendant(typedefDecl(has(atomicType())))));
517 }
518 
TEST_P(ImportDecl,ImportFunctionTemplateDecl)519 TEST_P(ImportDecl, ImportFunctionTemplateDecl) {
520   MatchVerifier<Decl> Verifier;
521   testImport("template <typename T> void declToImport() { };", Lang_CXX03, "",
522              Lang_CXX03, Verifier, functionTemplateDecl());
523 }
524 
TEST_P(ImportExpr,ImportCXXDependentScopeMemberExpr)525 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) {
526   MatchVerifier<Decl> Verifier;
527   testImport("template <typename T> struct C { T t; };"
528              "template <typename T> void declToImport() {"
529              "  C<T> d;"
530              "  (void)d.t;"
531              "}"
532              "void instantiate() { declToImport<int>(); }",
533              Lang_CXX03, "", Lang_CXX03, Verifier,
534              functionTemplateDecl(hasDescendant(
535                  cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
536   testImport("template <typename T> struct C { T t; };"
537              "template <typename T> void declToImport() {"
538              "  C<T> d;"
539              "  (void)(&d)->t;"
540              "}"
541              "void instantiate() { declToImport<int>(); }",
542              Lang_CXX03, "", Lang_CXX03, Verifier,
543              functionTemplateDecl(hasDescendant(
544                  cStyleCastExpr(has(cxxDependentScopeMemberExpr())))));
545 }
546 
TEST_P(ImportType,ImportTypeAliasTemplate)547 TEST_P(ImportType, ImportTypeAliasTemplate) {
548   MatchVerifier<Decl> Verifier;
549   testImport(
550       "template <int K>"
551       "struct dummy { static const int i = K; };"
552       "template <int K> using dummy2 = dummy<K>;"
553       "int declToImport() { return dummy2<3>::i; }",
554       Lang_CXX11, "", Lang_CXX11, Verifier,
555       traverse(ast_type_traits::TK_AsIs,
556                functionDecl(hasDescendant(implicitCastExpr(has(declRefExpr()))),
557                             unless(hasAncestor(
558                                 translationUnitDecl(has(typeAliasDecl())))))));
559 }
560 
561 const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateSpecializationDecl>
562     varTemplateSpecializationDecl;
563 
TEST_P(ImportDecl,ImportVarTemplate)564 TEST_P(ImportDecl, ImportVarTemplate) {
565   MatchVerifier<Decl> Verifier;
566   testImport(
567       "template <typename T>"
568       "T pi = T(3.1415926535897932385L);"
569       "void declToImport() { (void)pi<int>; }",
570       Lang_CXX14, "", Lang_CXX14, Verifier,
571       functionDecl(
572           hasDescendant(declRefExpr(to(varTemplateSpecializationDecl()))),
573           unless(hasAncestor(translationUnitDecl(has(varDecl(
574               hasName("pi"), unless(varTemplateSpecializationDecl()))))))));
575 }
576 
TEST_P(ImportType,ImportPackExpansion)577 TEST_P(ImportType, ImportPackExpansion) {
578   MatchVerifier<Decl> Verifier;
579   testImport("template <typename... Args>"
580              "struct dummy {"
581              "  dummy(Args... args) {}"
582              "  static const int i = 4;"
583              "};"
584              "int declToImport() { return dummy<int>::i; }",
585              Lang_CXX11, "", Lang_CXX11, Verifier,
586              traverse(ast_type_traits::TK_AsIs,
587                       functionDecl(hasDescendant(returnStmt(
588                           has(implicitCastExpr(has(declRefExpr()))))))));
589 }
590 
591 const internal::VariadicDynCastAllOfMatcher<Type,
592                                             DependentTemplateSpecializationType>
593     dependentTemplateSpecializationType;
594 
TEST_P(ImportType,ImportDependentTemplateSpecialization)595 TEST_P(ImportType, ImportDependentTemplateSpecialization) {
596   MatchVerifier<Decl> Verifier;
597   testImport("template<typename T>"
598              "struct A;"
599              "template<typename T>"
600              "struct declToImport {"
601              "  typename A<T>::template B<T> a;"
602              "};",
603              Lang_CXX03, "", Lang_CXX03, Verifier,
604              classTemplateDecl(has(cxxRecordDecl(has(
605                  fieldDecl(hasType(dependentTemplateSpecializationType())))))));
606 }
607 
608 const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr>
609     sizeOfPackExpr;
610 
TEST_P(ImportExpr,ImportSizeOfPackExpr)611 TEST_P(ImportExpr, ImportSizeOfPackExpr) {
612   MatchVerifier<Decl> Verifier;
613   testImport(
614       "template <typename... Ts>"
615       "void declToImport() {"
616       "  const int i = sizeof...(Ts);"
617       "};"
618       "void g() { declToImport<int>(); }",
619       Lang_CXX11, "", Lang_CXX11, Verifier,
620           functionTemplateDecl(hasDescendant(sizeOfPackExpr())));
621   testImport(
622       "template <typename... Ts>"
623       "using X = int[sizeof...(Ts)];"
624       "template <typename... Us>"
625       "struct Y {"
626       "  X<Us..., int, double, int, Us...> f;"
627       "};"
628       "Y<float, int> declToImport;",
629       Lang_CXX11, "", Lang_CXX11, Verifier,
630       varDecl(hasType(classTemplateSpecializationDecl(has(fieldDecl(hasType(
631           hasUnqualifiedDesugaredType(constantArrayType(hasSize(7))))))))));
632 }
633 
634 /// \brief Matches __builtin_types_compatible_p:
635 /// GNU extension to check equivalent types
636 /// Given
637 /// \code
638 ///   __builtin_types_compatible_p(int, int)
639 /// \endcode
640 //  will generate TypeTraitExpr <...> 'int'
641 const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr;
642 
TEST_P(ImportExpr,ImportTypeTraitExpr)643 TEST_P(ImportExpr, ImportTypeTraitExpr) {
644   MatchVerifier<Decl> Verifier;
645   testImport(
646       "void declToImport() { "
647       "  (void)__builtin_types_compatible_p(int, int);"
648       "}",
649       Lang_C99, "", Lang_C99, Verifier,
650       functionDecl(hasDescendant(typeTraitExpr(hasType(asString("int"))))));
651 }
652 
653 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr> cxxTypeidExpr;
654 
TEST_P(ImportExpr,ImportCXXTypeidExpr)655 TEST_P(ImportExpr, ImportCXXTypeidExpr) {
656   MatchVerifier<Decl> Verifier;
657   testImport(
658       "namespace std { class type_info {}; }"
659       "void declToImport() {"
660       "  int x;"
661       "  auto a = typeid(int); auto b = typeid(x);"
662       "}",
663       Lang_CXX11, "", Lang_CXX11, Verifier,
664       traverse(
665           ast_type_traits::TK_AsIs,
666           functionDecl(
667               hasDescendant(varDecl(hasName("a"), hasInitializer(hasDescendant(
668                                                       cxxTypeidExpr())))),
669               hasDescendant(varDecl(hasName("b"), hasInitializer(hasDescendant(
670                                                       cxxTypeidExpr())))))));
671 }
672 
TEST_P(ImportExpr,ImportTypeTraitExprValDep)673 TEST_P(ImportExpr, ImportTypeTraitExprValDep) {
674   MatchVerifier<Decl> Verifier;
675   testImport(
676       "template<typename T> struct declToImport {"
677       "  void m() { (void)__is_pod(T); }"
678       "};"
679       "void f() { declToImport<int>().m(); }",
680       Lang_CXX11, "", Lang_CXX11, Verifier,
681       classTemplateDecl(has(cxxRecordDecl(has(
682           functionDecl(hasDescendant(
683               typeTraitExpr(hasType(booleanType())))))))));
684 }
685 
TEST_P(ImportDecl,ImportRecordDeclInFunc)686 TEST_P(ImportDecl, ImportRecordDeclInFunc) {
687   MatchVerifier<Decl> Verifier;
688   testImport("int declToImport() { "
689              "  struct data_t {int a;int b;};"
690              "  struct data_t d;"
691              "  return 0;"
692              "}",
693              Lang_C99, "", Lang_C99, Verifier,
694              functionDecl(hasBody(compoundStmt(
695                  has(declStmt(hasSingleDecl(varDecl(hasName("d")))))))));
696 }
697 
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordTypeInFunc)698 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) {
699   Decl *FromTU = getTuDecl("int declToImport() { "
700                            "  struct data_t {int a;int b;};"
701                            "  struct data_t d;"
702                            "  return 0;"
703                            "}",
704                            Lang_C99, "input.c");
705   auto *FromVar =
706       FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("d")));
707   ASSERT_TRUE(FromVar);
708   auto ToType =
709       ImportType(FromVar->getType().getCanonicalType(), FromVar, Lang_C99);
710   EXPECT_FALSE(ToType.isNull());
711 }
712 
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordDeclInFuncParams)713 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) {
714   // This construct is not supported by ASTImporter.
715   Decl *FromTU = getTuDecl(
716       "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }",
717       Lang_C99, "input.c");
718   auto *From = FirstDeclMatcher<FunctionDecl>().match(
719       FromTU, functionDecl(hasName("declToImport")));
720   ASSERT_TRUE(From);
721   auto *To = Import(From, Lang_C99);
722   EXPECT_EQ(To, nullptr);
723 }
724 
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordDeclInFuncFromMacro)725 TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncFromMacro) {
726   Decl *FromTU =
727       getTuDecl("#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n"
728                 "int declToImport(){ return NONAME_SIZEOF(int); }",
729                 Lang_C99, "input.c");
730   auto *From = FirstDeclMatcher<FunctionDecl>().match(
731       FromTU, functionDecl(hasName("declToImport")));
732   ASSERT_TRUE(From);
733   auto *To = Import(From, Lang_C99);
734   ASSERT_TRUE(To);
735   EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
736       To, functionDecl(hasName("declToImport"),
737                        hasDescendant(unaryExprOrTypeTraitExpr()))));
738 }
739 
TEST_P(ASTImporterOptionSpecificTestBase,ImportRecordDeclInFuncParamsFromMacro)740 TEST_P(ASTImporterOptionSpecificTestBase,
741        ImportRecordDeclInFuncParamsFromMacro) {
742   // This construct is not supported by ASTImporter.
743   Decl *FromTU =
744       getTuDecl("#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n"
745                 "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }",
746                 Lang_C99, "input.c");
747   auto *From = FirstDeclMatcher<FunctionDecl>().match(
748       FromTU, functionDecl(hasName("declToImport")));
749   ASSERT_TRUE(From);
750   auto *To = Import(From, Lang_C99);
751   EXPECT_EQ(To, nullptr);
752 }
753 
754 const internal::VariadicDynCastAllOfMatcher<Expr, CXXPseudoDestructorExpr>
755     cxxPseudoDestructorExpr;
756 
TEST_P(ImportExpr,ImportCXXPseudoDestructorExpr)757 TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) {
758   MatchVerifier<Decl> Verifier;
759   testImport(
760       "typedef int T;"
761       "void declToImport(int *p) {"
762       "  T t;"
763       "  p->T::~T();"
764       "}",
765       Lang_CXX03, "", Lang_CXX03, Verifier,
766       functionDecl(hasDescendant(callExpr(has(cxxPseudoDestructorExpr())))));
767 }
768 
TEST_P(ImportDecl,ImportUsingDecl)769 TEST_P(ImportDecl, ImportUsingDecl) {
770   MatchVerifier<Decl> Verifier;
771   testImport("namespace foo { int bar; }"
772              "void declToImport() { using foo::bar; }",
773              Lang_CXX03, "", Lang_CXX03, Verifier,
774              functionDecl(hasDescendant(usingDecl())));
775 }
776 
777 /// \brief Matches shadow declarations introduced into a scope by a
778 ///        (resolved) using declaration.
779 ///
780 /// Given
781 /// \code
782 ///   namespace n { int f; }
783 ///   namespace declToImport { using n::f; }
784 /// \endcode
785 /// usingShadowDecl()
786 ///   matches \code f \endcode
787 const internal::VariadicDynCastAllOfMatcher<Decl,
788                                             UsingShadowDecl> usingShadowDecl;
789 
TEST_P(ImportDecl,ImportUsingShadowDecl)790 TEST_P(ImportDecl, ImportUsingShadowDecl) {
791   MatchVerifier<Decl> Verifier;
792   testImport("namespace foo { int bar; }"
793              "namespace declToImport { using foo::bar; }",
794              Lang_CXX03, "", Lang_CXX03, Verifier,
795              namespaceDecl(has(usingShadowDecl())));
796 }
797 
TEST_P(ImportExpr,ImportUnresolvedLookupExpr)798 TEST_P(ImportExpr, ImportUnresolvedLookupExpr) {
799   MatchVerifier<Decl> Verifier;
800   testImport("template<typename T> int foo();"
801              "template <typename T> void declToImport() {"
802              "  (void)::foo<T>;"
803              "  (void)::template foo<T>;"
804              "}"
805              "void instantiate() { declToImport<int>(); }",
806              Lang_CXX03, "", Lang_CXX03, Verifier,
807              functionTemplateDecl(hasDescendant(unresolvedLookupExpr())));
808 }
809 
TEST_P(ImportExpr,ImportCXXUnresolvedConstructExpr)810 TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) {
811   MatchVerifier<Decl> Verifier;
812   testImport("template <typename T> struct C { T t; };"
813              "template <typename T> void declToImport() {"
814              "  C<T> d;"
815              "  d.t = T();"
816              "}"
817              "void instantiate() { declToImport<int>(); }",
818              Lang_CXX03, "", Lang_CXX03, Verifier,
819              functionTemplateDecl(hasDescendant(
820                  binaryOperator(has(cxxUnresolvedConstructExpr())))));
821   testImport("template <typename T> struct C { T t; };"
822              "template <typename T> void declToImport() {"
823              "  C<T> d;"
824              "  (&d)->t = T();"
825              "}"
826              "void instantiate() { declToImport<int>(); }",
827              Lang_CXX03, "", Lang_CXX03, Verifier,
828              functionTemplateDecl(hasDescendant(
829                  binaryOperator(has(cxxUnresolvedConstructExpr())))));
830 }
831 
832 /// Check that function "declToImport()" (which is the templated function
833 /// for corresponding FunctionTemplateDecl) is not added into DeclContext.
834 /// Same for class template declarations.
TEST_P(ImportDecl,ImportTemplatedDeclForTemplate)835 TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) {
836   MatchVerifier<Decl> Verifier;
837   testImport("template <typename T> void declToImport() { T a = 1; }"
838              "void instantiate() { declToImport<int>(); }",
839              Lang_CXX03, "", Lang_CXX03, Verifier,
840              functionTemplateDecl(hasAncestor(translationUnitDecl(
841                  unless(has(functionDecl(hasName("declToImport"))))))));
842   testImport("template <typename T> struct declToImport { T t; };"
843              "void instantiate() { declToImport<int>(); }",
844              Lang_CXX03, "", Lang_CXX03, Verifier,
845              classTemplateDecl(hasAncestor(translationUnitDecl(
846                  unless(has(cxxRecordDecl(hasName("declToImport"))))))));
847 }
848 
TEST_P(ImportDecl,ImportClassTemplatePartialSpecialization)849 TEST_P(ImportDecl, ImportClassTemplatePartialSpecialization) {
850   MatchVerifier<Decl> Verifier;
851   auto Code =
852       R"s(
853       struct declToImport {
854         template <typename T0> struct X;
855         template <typename T0> struct X<T0 *> {};
856       };
857       )s";
858   testImport(Code, Lang_CXX03, "", Lang_CXX03, Verifier,
859              recordDecl(has(classTemplateDecl()),
860                         has(classTemplateSpecializationDecl())));
861 }
862 
TEST_P(ImportExpr,CXXOperatorCallExpr)863 TEST_P(ImportExpr, CXXOperatorCallExpr) {
864   MatchVerifier<Decl> Verifier;
865   testImport(
866       "class declToImport {"
867       "  void f() { *this = declToImport(); }"
868       "};",
869       Lang_CXX03, "", Lang_CXX03, Verifier,
870       cxxRecordDecl(has(cxxMethodDecl(hasDescendant(cxxOperatorCallExpr())))));
871 }
872 
TEST_P(ImportExpr,DependentSizedArrayType)873 TEST_P(ImportExpr, DependentSizedArrayType) {
874   MatchVerifier<Decl> Verifier;
875   testImport("template<typename T, int Size> class declToImport {"
876              "  T data[Size];"
877              "};",
878              Lang_CXX03, "", Lang_CXX03, Verifier,
879              classTemplateDecl(has(cxxRecordDecl(
880                  has(fieldDecl(hasType(dependentSizedArrayType())))))));
881 }
882 
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTypeParmDeclNoDefaultArg)883 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclNoDefaultArg) {
884   Decl *FromTU = getTuDecl("template<typename T> struct X {};", Lang_CXX03);
885   auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
886       FromTU, templateTypeParmDecl(hasName("T")));
887   TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
888   ASSERT_FALSE(To->hasDefaultArgument());
889 }
890 
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTypeParmDeclDefaultArg)891 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTypeParmDeclDefaultArg) {
892   Decl *FromTU =
893       getTuDecl("template<typename T = int> struct X {};", Lang_CXX03);
894   auto From = FirstDeclMatcher<TemplateTypeParmDecl>().match(
895       FromTU, templateTypeParmDecl(hasName("T")));
896   TemplateTypeParmDecl *To = Import(From, Lang_CXX03);
897   ASSERT_TRUE(To->hasDefaultArgument());
898   QualType ToArg = To->getDefaultArgument();
899   ASSERT_EQ(ToArg, QualType(To->getASTContext().IntTy));
900 }
901 
TEST_P(ASTImporterOptionSpecificTestBase,ImportBeginLocOfDeclRefExpr)902 TEST_P(ASTImporterOptionSpecificTestBase, ImportBeginLocOfDeclRefExpr) {
903   Decl *FromTU =
904       getTuDecl("class A { public: static int X; }; void f() { (void)A::X; }",
905                 Lang_CXX03);
906   auto From = FirstDeclMatcher<FunctionDecl>().match(
907       FromTU, functionDecl(hasName("f")));
908   ASSERT_TRUE(From);
909   ASSERT_TRUE(
910       cast<CStyleCastExpr>(cast<CompoundStmt>(From->getBody())->body_front())
911           ->getSubExpr()
912           ->getBeginLoc()
913           .isValid());
914   FunctionDecl *To = Import(From, Lang_CXX03);
915   ASSERT_TRUE(To);
916   ASSERT_TRUE(
917       cast<CStyleCastExpr>(cast<CompoundStmt>(To->getBody())->body_front())
918           ->getSubExpr()
919           ->getBeginLoc()
920           .isValid());
921 }
922 
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTemplateParmDeclNoDefaultArg)923 TEST_P(ASTImporterOptionSpecificTestBase,
924        TemplateTemplateParmDeclNoDefaultArg) {
925   Decl *FromTU = getTuDecl(R"(
926                            template<template<typename> typename TT> struct Y {};
927                            )",
928                            Lang_CXX17);
929   auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
930       FromTU, templateTemplateParmDecl(hasName("TT")));
931   TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
932   ASSERT_FALSE(To->hasDefaultArgument());
933 }
934 
TEST_P(ASTImporterOptionSpecificTestBase,TemplateTemplateParmDeclDefaultArg)935 TEST_P(ASTImporterOptionSpecificTestBase, TemplateTemplateParmDeclDefaultArg) {
936   Decl *FromTU = getTuDecl(R"(
937                            template<typename T> struct X {};
938                            template<template<typename> typename TT = X> struct Y {};
939                            )",
940                            Lang_CXX17);
941   auto From = FirstDeclMatcher<TemplateTemplateParmDecl>().match(
942       FromTU, templateTemplateParmDecl(hasName("TT")));
943   TemplateTemplateParmDecl *To = Import(From, Lang_CXX17);
944   ASSERT_TRUE(To->hasDefaultArgument());
945   const TemplateArgument &ToDefaultArg = To->getDefaultArgument().getArgument();
946   ASSERT_TRUE(To->isTemplateDecl());
947   TemplateDecl *ToTemplate = ToDefaultArg.getAsTemplate().getAsTemplateDecl();
948 
949   // Find the default argument template 'X' in the AST and compare it against
950   // the default argument we got.
951   auto ToExpectedDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
952       To->getTranslationUnitDecl(), classTemplateDecl(hasName("X")));
953   ASSERT_EQ(ToTemplate, ToExpectedDecl);
954 }
955 
TEST_P(ASTImporterOptionSpecificTestBase,NonTypeTemplateParmDeclNoDefaultArg)956 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclNoDefaultArg) {
957   Decl *FromTU = getTuDecl("template<int N> struct X {};", Lang_CXX03);
958   auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
959       FromTU, nonTypeTemplateParmDecl(hasName("N")));
960   NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
961   ASSERT_FALSE(To->hasDefaultArgument());
962 }
963 
TEST_P(ASTImporterOptionSpecificTestBase,NonTypeTemplateParmDeclDefaultArg)964 TEST_P(ASTImporterOptionSpecificTestBase, NonTypeTemplateParmDeclDefaultArg) {
965   Decl *FromTU = getTuDecl("template<int S = 1> struct X {};", Lang_CXX03);
966   auto From = FirstDeclMatcher<NonTypeTemplateParmDecl>().match(
967       FromTU, nonTypeTemplateParmDecl(hasName("S")));
968   NonTypeTemplateParmDecl *To = Import(From, Lang_CXX03);
969   ASSERT_TRUE(To->hasDefaultArgument());
970   Stmt *ToArg = To->getDefaultArgument();
971   ASSERT_TRUE(isa<ConstantExpr>(ToArg));
972   ToArg = *ToArg->child_begin();
973   ASSERT_TRUE(isa<IntegerLiteral>(ToArg));
974   ASSERT_EQ(cast<IntegerLiteral>(ToArg)->getValue().getLimitedValue(), 1U);
975 }
976 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclOfClassTemplateDecl)977 TEST_P(ASTImporterOptionSpecificTestBase,
978        ImportOfTemplatedDeclOfClassTemplateDecl) {
979   Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
980   auto From =
981       FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
982   ASSERT_TRUE(From);
983   auto To = cast<ClassTemplateDecl>(Import(From, Lang_CXX03));
984   ASSERT_TRUE(To);
985   Decl *ToTemplated = To->getTemplatedDecl();
986   Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
987   EXPECT_TRUE(ToTemplated1);
988   EXPECT_EQ(ToTemplated1, ToTemplated);
989 }
990 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclOfFunctionTemplateDecl)991 TEST_P(ASTImporterOptionSpecificTestBase,
992        ImportOfTemplatedDeclOfFunctionTemplateDecl) {
993   Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
994   auto From = FirstDeclMatcher<FunctionTemplateDecl>().match(
995       FromTU, functionTemplateDecl());
996   ASSERT_TRUE(From);
997   auto To = cast<FunctionTemplateDecl>(Import(From, Lang_CXX03));
998   ASSERT_TRUE(To);
999   Decl *ToTemplated = To->getTemplatedDecl();
1000   Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX03);
1001   EXPECT_TRUE(ToTemplated1);
1002   EXPECT_EQ(ToTemplated1, ToTemplated);
1003 }
1004 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclShouldImportTheClassTemplateDecl)1005 TEST_P(ASTImporterOptionSpecificTestBase,
1006        ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) {
1007   Decl *FromTU = getTuDecl("template<class X> struct S{};", Lang_CXX03);
1008   auto FromFT =
1009       FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());
1010   ASSERT_TRUE(FromFT);
1011 
1012   auto ToTemplated =
1013       cast<CXXRecordDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1014   EXPECT_TRUE(ToTemplated);
1015   auto ToTU = ToTemplated->getTranslationUnitDecl();
1016   auto ToFT =
1017       FirstDeclMatcher<ClassTemplateDecl>().match(ToTU, classTemplateDecl());
1018   EXPECT_TRUE(ToFT);
1019 }
1020 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl)1021 TEST_P(ASTImporterOptionSpecificTestBase,
1022        ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
1023   Decl *FromTU = getTuDecl("template<class X> void f(){}", Lang_CXX03);
1024   auto FromFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1025       FromTU, functionTemplateDecl());
1026   ASSERT_TRUE(FromFT);
1027 
1028   auto ToTemplated =
1029       cast<FunctionDecl>(Import(FromFT->getTemplatedDecl(), Lang_CXX03));
1030   EXPECT_TRUE(ToTemplated);
1031   auto ToTU = ToTemplated->getTranslationUnitDecl();
1032   auto ToFT = FirstDeclMatcher<FunctionTemplateDecl>().match(
1033       ToTU, functionTemplateDecl());
1034   EXPECT_TRUE(ToFT);
1035 }
1036 
TEST_P(ASTImporterOptionSpecificTestBase,ImportCorrectTemplatedDecl)1037 TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) {
1038   auto Code =
1039         R"(
1040         namespace x {
1041           template<class X> struct S1{};
1042           template<class X> struct S2{};
1043           template<class X> struct S3{};
1044         }
1045         )";
1046   Decl *FromTU = getTuDecl(Code, Lang_CXX03);
1047   auto FromNs =
1048       FirstDeclMatcher<NamespaceDecl>().match(FromTU, namespaceDecl());
1049   auto ToNs = cast<NamespaceDecl>(Import(FromNs, Lang_CXX03));
1050   ASSERT_TRUE(ToNs);
1051   auto From =
1052       FirstDeclMatcher<ClassTemplateDecl>().match(FromTU,
1053                                                   classTemplateDecl(
1054                                                       hasName("S2")));
1055   auto To =
1056       FirstDeclMatcher<ClassTemplateDecl>().match(ToNs,
1057                                                   classTemplateDecl(
1058                                                       hasName("S2")));
1059   ASSERT_TRUE(From);
1060   ASSERT_TRUE(To);
1061   auto ToTemplated = To->getTemplatedDecl();
1062   auto ToTemplated1 =
1063       cast<CXXRecordDecl>(Import(From->getTemplatedDecl(), Lang_CXX03));
1064   EXPECT_TRUE(ToTemplated1);
1065   ASSERT_EQ(ToTemplated1, ToTemplated);
1066 }
1067 
TEST_P(ASTImporterOptionSpecificTestBase,ImportChooseExpr)1068 TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) {
1069   // This tests the import of isConditionTrue directly to make sure the importer
1070   // gets it right.
1071   Decl *From, *To;
1072   std::tie(From, To) = getImportedDecl(
1073       "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", Lang_C99,
1074       "", Lang_C99);
1075 
1076   auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext());
1077   auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext());
1078 
1079   const ChooseExpr *FromChooseExpr =
1080       selectFirst<ChooseExpr>("choose", FromResults);
1081   ASSERT_TRUE(FromChooseExpr);
1082 
1083   const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults);
1084   ASSERT_TRUE(ToChooseExpr);
1085 
1086   EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue());
1087   EXPECT_EQ(FromChooseExpr->isConditionDependent(),
1088             ToChooseExpr->isConditionDependent());
1089 }
1090 
TEST_P(ASTImporterOptionSpecificTestBase,ImportFunctionWithBackReferringParameter)1091 TEST_P(ASTImporterOptionSpecificTestBase,
1092        ImportFunctionWithBackReferringParameter) {
1093   Decl *From, *To;
1094   std::tie(From, To) = getImportedDecl(
1095       R"(
1096       template <typename T> struct X {};
1097 
1098       void declToImport(int y, X<int> &x) {}
1099 
1100       template <> struct X<int> {
1101         void g() {
1102           X<int> x;
1103           declToImport(0, x);
1104         }
1105       };
1106       )",
1107       Lang_CXX03, "", Lang_CXX03);
1108 
1109   MatchVerifier<Decl> Verifier;
1110   auto Matcher = functionDecl(hasName("declToImport"),
1111                               parameterCountIs(2),
1112                               hasParameter(0, hasName("y")),
1113                               hasParameter(1, hasName("x")),
1114                               hasParameter(1, hasType(asString("X<int> &"))));
1115   ASSERT_TRUE(Verifier.match(From, Matcher));
1116   EXPECT_TRUE(Verifier.match(To, Matcher));
1117 }
1118 
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainTemplatedDeclOfFunctionTemplates)1119 TEST_P(ASTImporterOptionSpecificTestBase,
1120        TUshouldNotContainTemplatedDeclOfFunctionTemplates) {
1121   Decl *From, *To;
1122   std::tie(From, To) =
1123       getImportedDecl("template <typename T> void declToImport() { T a = 1; }"
1124                       "void instantiate() { declToImport<int>(); }",
1125                       Lang_CXX03, "", Lang_CXX03);
1126 
1127   auto Check = [](Decl *D) -> bool {
1128     auto TU = D->getTranslationUnitDecl();
1129     for (auto Child : TU->decls()) {
1130       if (auto *FD = dyn_cast<FunctionDecl>(Child)) {
1131         if (FD->getNameAsString() == "declToImport") {
1132           GTEST_NONFATAL_FAILURE_(
1133               "TU should not contain any FunctionDecl with name declToImport");
1134           return false;
1135         }
1136       }
1137     }
1138     return true;
1139   };
1140 
1141   ASSERT_TRUE(Check(From));
1142   EXPECT_TRUE(Check(To));
1143 }
1144 
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainTemplatedDeclOfClassTemplates)1145 TEST_P(ASTImporterOptionSpecificTestBase,
1146        TUshouldNotContainTemplatedDeclOfClassTemplates) {
1147   Decl *From, *To;
1148   std::tie(From, To) =
1149       getImportedDecl("template <typename T> struct declToImport { T t; };"
1150                       "void instantiate() { declToImport<int>(); }",
1151                       Lang_CXX03, "", Lang_CXX03);
1152 
1153   auto Check = [](Decl *D) -> bool {
1154     auto TU = D->getTranslationUnitDecl();
1155     for (auto Child : TU->decls()) {
1156       if (auto *RD = dyn_cast<CXXRecordDecl>(Child)) {
1157         if (RD->getNameAsString() == "declToImport") {
1158           GTEST_NONFATAL_FAILURE_(
1159               "TU should not contain any CXXRecordDecl with name declToImport");
1160           return false;
1161         }
1162       }
1163     }
1164     return true;
1165   };
1166 
1167   ASSERT_TRUE(Check(From));
1168   EXPECT_TRUE(Check(To));
1169 }
1170 
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainTemplatedDeclOfTypeAlias)1171 TEST_P(ASTImporterOptionSpecificTestBase,
1172        TUshouldNotContainTemplatedDeclOfTypeAlias) {
1173   Decl *From, *To;
1174   std::tie(From, To) =
1175       getImportedDecl(
1176           "template <typename T> struct X {};"
1177           "template <typename T> using declToImport = X<T>;"
1178           "void instantiate() { declToImport<int> a; }",
1179                       Lang_CXX11, "", Lang_CXX11);
1180 
1181   auto Check = [](Decl *D) -> bool {
1182     auto TU = D->getTranslationUnitDecl();
1183     for (auto Child : TU->decls()) {
1184       if (auto *AD = dyn_cast<TypeAliasDecl>(Child)) {
1185         if (AD->getNameAsString() == "declToImport") {
1186           GTEST_NONFATAL_FAILURE_(
1187               "TU should not contain any TypeAliasDecl with name declToImport");
1188           return false;
1189         }
1190       }
1191     }
1192     return true;
1193   };
1194 
1195   ASSERT_TRUE(Check(From));
1196   EXPECT_TRUE(Check(To));
1197 }
1198 
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation)1199 TEST_P(ASTImporterOptionSpecificTestBase,
1200        TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
1201 
1202   Decl *From, *To;
1203   std::tie(From, To) = getImportedDecl(
1204       R"(
1205       template<class T>
1206       class Base {};
1207       class declToImport : public Base<declToImport> {};
1208       )",
1209       Lang_CXX03, "", Lang_CXX03);
1210 
1211   // Check that the ClassTemplateSpecializationDecl is NOT the child of the TU.
1212   auto Pattern =
1213       translationUnitDecl(unless(has(classTemplateSpecializationDecl())));
1214   ASSERT_TRUE(
1215       MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1216   EXPECT_TRUE(
1217       MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1218 
1219   // Check that the ClassTemplateSpecializationDecl is the child of the
1220   // ClassTemplateDecl.
1221   Pattern = translationUnitDecl(has(classTemplateDecl(
1222       hasName("Base"), has(classTemplateSpecializationDecl()))));
1223   ASSERT_TRUE(
1224       MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1225   EXPECT_TRUE(
1226       MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1227 }
1228 
AST_MATCHER_P(RecordDecl,hasFieldOrder,std::vector<StringRef>,Order)1229 AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
1230   size_t Index = 0;
1231   for (Decl *D : Node.decls()) {
1232     if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
1233       auto *ND = cast<NamedDecl>(D);
1234       if (Index == Order.size())
1235         return false;
1236       if (ND->getName() != Order[Index])
1237         return false;
1238       ++Index;
1239     }
1240   }
1241   return Index == Order.size();
1242 }
1243 
TEST_P(ASTImporterOptionSpecificTestBase,TUshouldContainClassTemplateSpecializationOfExplicitInstantiation)1244 TEST_P(ASTImporterOptionSpecificTestBase,
1245        TUshouldContainClassTemplateSpecializationOfExplicitInstantiation) {
1246   Decl *From, *To;
1247   std::tie(From, To) = getImportedDecl(
1248       R"(
1249       namespace NS {
1250         template<class T>
1251         class X {};
1252         template class X<int>;
1253       }
1254       )",
1255       Lang_CXX03, "", Lang_CXX03, "NS");
1256 
1257   // Check that the ClassTemplateSpecializationDecl is NOT the child of the
1258   // ClassTemplateDecl.
1259   auto Pattern = namespaceDecl(has(classTemplateDecl(
1260       hasName("X"), unless(has(classTemplateSpecializationDecl())))));
1261   ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1262   EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1263 
1264   // Check that the ClassTemplateSpecializationDecl is the child of the
1265   // NamespaceDecl.
1266   Pattern = namespaceDecl(has(classTemplateSpecializationDecl(hasName("X"))));
1267   ASSERT_TRUE(MatchVerifier<Decl>{}.match(From, Pattern));
1268   EXPECT_TRUE(MatchVerifier<Decl>{}.match(To, Pattern));
1269 }
1270 
TEST_P(ASTImporterOptionSpecificTestBase,CXXRecordDeclFieldsShouldBeInCorrectOrder)1271 TEST_P(ASTImporterOptionSpecificTestBase,
1272        CXXRecordDeclFieldsShouldBeInCorrectOrder) {
1273   Decl *From, *To;
1274   std::tie(From, To) =
1275       getImportedDecl(
1276           "struct declToImport { int a; int b; };",
1277                       Lang_CXX11, "", Lang_CXX11);
1278 
1279   MatchVerifier<Decl> Verifier;
1280   ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1281   EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
1282 }
1283 
TEST_P(ASTImporterOptionSpecificTestBase,CXXRecordDeclFieldOrderShouldNotDependOnImportOrder)1284 TEST_P(ASTImporterOptionSpecificTestBase,
1285        CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) {
1286   Decl *From, *To;
1287   std::tie(From, To) = getImportedDecl(
1288       // The original recursive algorithm of ASTImporter first imports 'c' then
1289       // 'b' and lastly 'a'.  Therefore we must restore the order somehow.
1290       R"s(
1291       struct declToImport {
1292           int a = c + b;
1293           int b = 1;
1294           int c = 2;
1295       };
1296       )s",
1297       Lang_CXX11, "", Lang_CXX11);
1298 
1299   MatchVerifier<Decl> Verifier;
1300   ASSERT_TRUE(
1301       Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1302   EXPECT_TRUE(
1303       Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
1304 }
1305 
TEST_P(ASTImporterOptionSpecificTestBase,CXXRecordDeclFieldAndIndirectFieldOrder)1306 TEST_P(ASTImporterOptionSpecificTestBase,
1307        CXXRecordDeclFieldAndIndirectFieldOrder) {
1308   Decl *From, *To;
1309   std::tie(From, To) = getImportedDecl(
1310       // First field is "a", then the field for unnamed union, then "b" and "c"
1311       // from it (indirect fields), then "d".
1312       R"s(
1313       struct declToImport {
1314         int a = d;
1315         union {
1316           int b;
1317           int c;
1318         };
1319         int d;
1320       };
1321       )s",
1322       Lang_CXX11, "", Lang_CXX11);
1323 
1324   MatchVerifier<Decl> Verifier;
1325   ASSERT_TRUE(Verifier.match(
1326       From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1327   EXPECT_TRUE(Verifier.match(
1328       To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
1329 }
1330 
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportImplicitCXXRecordDecl)1331 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) {
1332   Decl *From, *To;
1333   std::tie(From, To) = getImportedDecl(
1334       R"(
1335       struct declToImport {
1336       };
1337       )",
1338       Lang_CXX03, "", Lang_CXX03);
1339 
1340   MatchVerifier<Decl> Verifier;
1341   // Match the implicit Decl.
1342   auto Matcher = cxxRecordDecl(has(cxxRecordDecl()));
1343   ASSERT_TRUE(Verifier.match(From, Matcher));
1344   EXPECT_TRUE(Verifier.match(To, Matcher));
1345 }
1346 
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportImplicitCXXRecordDeclOfClassTemplate)1347 TEST_P(ASTImporterOptionSpecificTestBase,
1348        ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
1349   Decl *From, *To;
1350   std::tie(From, To) = getImportedDecl(
1351       R"(
1352       template <typename U>
1353       struct declToImport {
1354       };
1355       )",
1356       Lang_CXX03, "", Lang_CXX03);
1357 
1358   MatchVerifier<Decl> Verifier;
1359   // Match the implicit Decl.
1360   auto Matcher = classTemplateDecl(has(cxxRecordDecl(has(cxxRecordDecl()))));
1361   ASSERT_TRUE(Verifier.match(From, Matcher));
1362   EXPECT_TRUE(Verifier.match(To, Matcher));
1363 }
1364 
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl)1365 TEST_P(ASTImporterOptionSpecificTestBase,
1366        ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
1367   Decl *From, *To;
1368   std::tie(From, To) = getImportedDecl(
1369       R"(
1370       template<class T>
1371       class Base {};
1372       class declToImport : public Base<declToImport> {};
1373       )",
1374       Lang_CXX03, "", Lang_CXX03);
1375 
1376   auto hasImplicitClass = has(cxxRecordDecl());
1377   auto Pattern = translationUnitDecl(has(classTemplateDecl(
1378       hasName("Base"),
1379       has(classTemplateSpecializationDecl(hasImplicitClass)))));
1380   ASSERT_TRUE(
1381       MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1382   EXPECT_TRUE(
1383       MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1384 }
1385 
TEST_P(ASTImporterOptionSpecificTestBase,IDNSOrdinary)1386 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOrdinary) {
1387   Decl *From, *To;
1388   std::tie(From, To) =
1389       getImportedDecl("void declToImport() {}", Lang_CXX03, "", Lang_CXX03);
1390 
1391   MatchVerifier<Decl> Verifier;
1392   auto Matcher = functionDecl();
1393   ASSERT_TRUE(Verifier.match(From, Matcher));
1394   EXPECT_TRUE(Verifier.match(To, Matcher));
1395   EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1396 }
1397 
TEST_P(ASTImporterOptionSpecificTestBase,IDNSOfNonmemberOperator)1398 TEST_P(ASTImporterOptionSpecificTestBase, IDNSOfNonmemberOperator) {
1399   Decl *FromTU = getTuDecl(
1400       R"(
1401       struct X {};
1402       void operator<<(int, X);
1403       )",
1404       Lang_CXX03);
1405   Decl *From = LastDeclMatcher<Decl>{}.match(FromTU, functionDecl());
1406   const Decl *To = Import(From, Lang_CXX03);
1407   EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
1408 }
1409 
TEST_P(ASTImporterOptionSpecificTestBase,ShouldImportMembersOfClassTemplateSpecializationDecl)1410 TEST_P(ASTImporterOptionSpecificTestBase,
1411        ShouldImportMembersOfClassTemplateSpecializationDecl) {
1412   Decl *From, *To;
1413   std::tie(From, To) = getImportedDecl(
1414       R"(
1415       template<class T>
1416       class Base { int a; };
1417       class declToImport : Base<declToImport> {};
1418       )",
1419       Lang_CXX03, "", Lang_CXX03);
1420 
1421   auto Pattern = translationUnitDecl(has(classTemplateDecl(
1422       hasName("Base"),
1423       has(classTemplateSpecializationDecl(has(fieldDecl(hasName("a"))))))));
1424   ASSERT_TRUE(
1425       MatchVerifier<Decl>{}.match(From->getTranslationUnitDecl(), Pattern));
1426   EXPECT_TRUE(
1427       MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
1428 }
1429 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassTemplateAfterFwdDecl)1430 TEST_P(ASTImporterOptionSpecificTestBase,
1431        ImportDefinitionOfClassTemplateAfterFwdDecl) {
1432   {
1433     Decl *FromTU = getTuDecl(
1434         R"(
1435             template <typename T>
1436             struct B;
1437             )",
1438         Lang_CXX03, "input0.cc");
1439     auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1440         FromTU, classTemplateDecl(hasName("B")));
1441 
1442     Import(FromD, Lang_CXX03);
1443   }
1444 
1445   {
1446     Decl *FromTU = getTuDecl(
1447         R"(
1448             template <typename T>
1449             struct B {
1450               void f();
1451             };
1452             )",
1453         Lang_CXX03, "input1.cc");
1454     FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
1455         FromTU, functionDecl(hasName("f")));
1456     Import(FromD, Lang_CXX03);
1457     auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
1458         FromTU, classTemplateDecl(hasName("B")));
1459     auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
1460     EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
1461   }
1462 }
1463 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition)1464 TEST_P(ASTImporterOptionSpecificTestBase,
1465        ImportDefinitionOfClassTemplateIfThereIsAnExistingFwdDeclAndDefinition) {
1466   Decl *ToTU = getToTuDecl(
1467       R"(
1468       template <typename T>
1469       struct B {
1470         void f();
1471       };
1472 
1473       template <typename T>
1474       struct B;
1475       )",
1476       Lang_CXX03);
1477   ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1478                     [](const ClassTemplateDecl *T) {
1479                       return T->isThisDeclarationADefinition();
1480                     })
1481                     .match(ToTU, classTemplateDecl()));
1482 
1483   Decl *FromTU = getTuDecl(
1484       R"(
1485       template <typename T>
1486       struct B {
1487         void f();
1488       };
1489       )",
1490       Lang_CXX03, "input1.cc");
1491   ClassTemplateDecl *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
1492       FromTU, classTemplateDecl(hasName("B")));
1493 
1494   Import(FromD, Lang_CXX03);
1495 
1496   // We should have only one definition.
1497   EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateDecl>(
1498                     [](const ClassTemplateDecl *T) {
1499                       return T->isThisDeclarationADefinition();
1500                     })
1501                     .match(ToTU, classTemplateDecl()));
1502 }
1503 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition)1504 TEST_P(ASTImporterOptionSpecificTestBase,
1505        ImportDefinitionOfClassIfThereIsAnExistingFwdDeclAndDefinition) {
1506   Decl *ToTU = getToTuDecl(
1507       R"(
1508       struct B {
1509         void f();
1510       };
1511 
1512       struct B;
1513       )",
1514       Lang_CXX03);
1515   ASSERT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1516                     ToTU, cxxRecordDecl(unless(isImplicit()))));
1517 
1518   Decl *FromTU = getTuDecl(
1519       R"(
1520       struct B {
1521         void f();
1522       };
1523       )",
1524       Lang_CXX03, "input1.cc");
1525   auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
1526       FromTU, cxxRecordDecl(hasName("B")));
1527 
1528   Import(FromD, Lang_CXX03);
1529 
1530   EXPECT_EQ(2u, DeclCounter<CXXRecordDecl>().match(
1531                     ToTU, cxxRecordDecl(unless(isImplicit()))));
1532 }
1533 
CompareSourceLocs(FullSourceLoc Loc1,FullSourceLoc Loc2)1534 static void CompareSourceLocs(FullSourceLoc Loc1, FullSourceLoc Loc2) {
1535   EXPECT_EQ(Loc1.getExpansionLineNumber(), Loc2.getExpansionLineNumber());
1536   EXPECT_EQ(Loc1.getExpansionColumnNumber(), Loc2.getExpansionColumnNumber());
1537   EXPECT_EQ(Loc1.getSpellingLineNumber(), Loc2.getSpellingLineNumber());
1538   EXPECT_EQ(Loc1.getSpellingColumnNumber(), Loc2.getSpellingColumnNumber());
1539 }
CompareSourceRanges(SourceRange Range1,SourceRange Range2,SourceManager & SM1,SourceManager & SM2)1540 static void CompareSourceRanges(SourceRange Range1, SourceRange Range2,
1541                                 SourceManager &SM1, SourceManager &SM2) {
1542   CompareSourceLocs(FullSourceLoc{ Range1.getBegin(), SM1 },
1543                     FullSourceLoc{ Range2.getBegin(), SM2 });
1544   CompareSourceLocs(FullSourceLoc{ Range1.getEnd(), SM1 },
1545                     FullSourceLoc{ Range2.getEnd(), SM2 });
1546 }
TEST_P(ASTImporterOptionSpecificTestBase,ImportSourceLocs)1547 TEST_P(ASTImporterOptionSpecificTestBase, ImportSourceLocs) {
1548   Decl *FromTU = getTuDecl(
1549       R"(
1550       #define MFOO(arg) arg = arg + 1
1551 
1552       void foo() {
1553         int a = 5;
1554         MFOO(a);
1555       }
1556       )",
1557       Lang_CXX03);
1558   auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1559   auto ToD = Import(FromD, Lang_CXX03);
1560 
1561   auto ToLHS = LastDeclMatcher<DeclRefExpr>().match(ToD, declRefExpr());
1562   auto FromLHS = LastDeclMatcher<DeclRefExpr>().match(FromTU, declRefExpr());
1563   auto ToRHS = LastDeclMatcher<IntegerLiteral>().match(ToD, integerLiteral());
1564   auto FromRHS =
1565       LastDeclMatcher<IntegerLiteral>().match(FromTU, integerLiteral());
1566 
1567   SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1568   SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1569   CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1570                       FromSM);
1571   CompareSourceRanges(ToLHS->getSourceRange(), FromLHS->getSourceRange(), ToSM,
1572                       FromSM);
1573   CompareSourceRanges(ToRHS->getSourceRange(), FromRHS->getSourceRange(), ToSM,
1574                       FromSM);
1575 }
1576 
TEST_P(ASTImporterOptionSpecificTestBase,ImportNestedMacro)1577 TEST_P(ASTImporterOptionSpecificTestBase, ImportNestedMacro) {
1578   Decl *FromTU = getTuDecl(
1579       R"(
1580       #define FUNC_INT void declToImport
1581       #define FUNC FUNC_INT
1582       FUNC(int a);
1583       )",
1584       Lang_CXX03);
1585   auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1586   auto ToD = Import(FromD, Lang_CXX03);
1587 
1588   SourceManager &ToSM = ToAST->getASTContext().getSourceManager();
1589   SourceManager &FromSM = FromD->getASTContext().getSourceManager();
1590   CompareSourceRanges(ToD->getSourceRange(), FromD->getSourceRange(), ToSM,
1591                       FromSM);
1592 }
1593 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition)1594 TEST_P(
1595     ASTImporterOptionSpecificTestBase,
1596     ImportDefinitionOfClassTemplateSpecIfThereIsAnExistingFwdDeclAndDefinition) {
1597   Decl *ToTU = getToTuDecl(
1598       R"(
1599       template <typename T>
1600       struct B;
1601 
1602       template <>
1603       struct B<int> {};
1604 
1605       template <>
1606       struct B<int>;
1607       )",
1608       Lang_CXX03);
1609   // We should have only one definition.
1610   ASSERT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
1611                     [](const ClassTemplateSpecializationDecl *T) {
1612                       return T->isThisDeclarationADefinition();
1613                     })
1614                     .match(ToTU, classTemplateSpecializationDecl()));
1615 
1616   Decl *FromTU = getTuDecl(
1617       R"(
1618       template <typename T>
1619       struct B;
1620 
1621       template <>
1622       struct B<int> {};
1623       )",
1624       Lang_CXX03, "input1.cc");
1625   auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
1626       FromTU, classTemplateSpecializationDecl(hasName("B")));
1627 
1628   Import(FromD, Lang_CXX03);
1629 
1630   // We should have only one definition.
1631   EXPECT_EQ(1u, DeclCounterWithPredicate<ClassTemplateSpecializationDecl>(
1632                     [](const ClassTemplateSpecializationDecl *T) {
1633                       return T->isThisDeclarationADefinition();
1634                     })
1635                     .match(ToTU, classTemplateSpecializationDecl()));
1636 }
1637 
TEST_P(ASTImporterOptionSpecificTestBase,ObjectsWithUnnamedStructType)1638 TEST_P(ASTImporterOptionSpecificTestBase, ObjectsWithUnnamedStructType) {
1639   Decl *FromTU = getTuDecl(
1640       R"(
1641       struct { int a; int b; } object0 = { 2, 3 };
1642       struct { int x; int y; int z; } object1;
1643       )",
1644       Lang_CXX03, "input0.cc");
1645 
1646   auto *Obj0 =
1647       FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object0")));
1648   auto *From0 = getRecordDecl(Obj0);
1649   auto *Obj1 =
1650       FirstDeclMatcher<VarDecl>().match(FromTU, varDecl(hasName("object1")));
1651   auto *From1 = getRecordDecl(Obj1);
1652 
1653   auto *To0 = Import(From0, Lang_CXX03);
1654   auto *To1 = Import(From1, Lang_CXX03);
1655 
1656   EXPECT_TRUE(To0);
1657   EXPECT_TRUE(To1);
1658   EXPECT_NE(To0, To1);
1659   EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl());
1660 }
1661 
TEST_P(ASTImporterOptionSpecificTestBase,AnonymousRecords)1662 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecords) {
1663   auto *Code =
1664       R"(
1665       struct X {
1666         struct { int a; };
1667         struct { int b; };
1668       };
1669       )";
1670   Decl *FromTU0 = getTuDecl(Code, Lang_C99, "input0.c");
1671 
1672   Decl *FromTU1 = getTuDecl(Code, Lang_C99, "input1.c");
1673 
1674   auto *X0 =
1675       FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
1676   auto *X1 =
1677       FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
1678   Import(X0, Lang_C99);
1679   Import(X1, Lang_C99);
1680 
1681   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
1682   // We expect no (ODR) warning during the import.
1683   EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
1684   EXPECT_EQ(1u,
1685             DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
1686 }
1687 
TEST_P(ASTImporterOptionSpecificTestBase,AnonymousRecordsReversed)1688 TEST_P(ASTImporterOptionSpecificTestBase, AnonymousRecordsReversed) {
1689   Decl *FromTU0 = getTuDecl(
1690       R"(
1691       struct X {
1692         struct { int a; };
1693         struct { int b; };
1694       };
1695       )",
1696       Lang_C99, "input0.c");
1697 
1698   Decl *FromTU1 = getTuDecl(
1699       R"(
1700       struct X { // reversed order
1701         struct { int b; };
1702         struct { int a; };
1703       };
1704       )",
1705       Lang_C99, "input1.c");
1706 
1707   auto *X0 =
1708       FirstDeclMatcher<RecordDecl>().match(FromTU0, recordDecl(hasName("X")));
1709   auto *X1 =
1710       FirstDeclMatcher<RecordDecl>().match(FromTU1, recordDecl(hasName("X")));
1711   Import(X0, Lang_C99);
1712   Import(X1, Lang_C99);
1713 
1714   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
1715   // We expect one (ODR) warning during the import.
1716   EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
1717   EXPECT_EQ(1u,
1718             DeclCounter<RecordDecl>().match(ToTU, recordDecl(hasName("X"))));
1719 }
1720 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDoesUpdateUsedFlag)1721 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag) {
1722   auto Pattern = varDecl(hasName("x"));
1723   VarDecl *Imported1;
1724   {
1725     Decl *FromTU = getTuDecl("extern int x;", Lang_CXX03, "input0.cc");
1726     auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
1727     Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
1728   }
1729   VarDecl *Imported2;
1730   {
1731     Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input1.cc");
1732     auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
1733     Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
1734   }
1735   EXPECT_EQ(Imported1->getCanonicalDecl(), Imported2->getCanonicalDecl());
1736   EXPECT_FALSE(Imported2->isUsed(false));
1737   {
1738     Decl *FromTU = getTuDecl("extern int x; int f() { return x; }", Lang_CXX03,
1739                              "input2.cc");
1740     auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
1741         FromTU, functionDecl(hasName("f")));
1742     Import(FromD, Lang_CXX03);
1743   }
1744   EXPECT_TRUE(Imported2->isUsed(false));
1745 }
1746 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDoesUpdateUsedFlag2)1747 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag2) {
1748   auto Pattern = varDecl(hasName("x"));
1749   VarDecl *ExistingD;
1750   {
1751     Decl *ToTU = getToTuDecl("int x = 1;", Lang_CXX03);
1752     ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
1753   }
1754   EXPECT_FALSE(ExistingD->isUsed(false));
1755   {
1756     Decl *FromTU =
1757         getTuDecl("int x = 1; int f() { return x; }", Lang_CXX03, "input1.cc");
1758     auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
1759         FromTU, functionDecl(hasName("f")));
1760     Import(FromD, Lang_CXX03);
1761   }
1762   EXPECT_TRUE(ExistingD->isUsed(false));
1763 }
1764 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDoesUpdateUsedFlag3)1765 TEST_P(ASTImporterOptionSpecificTestBase, ImportDoesUpdateUsedFlag3) {
1766   auto Pattern = varDecl(hasName("a"));
1767   VarDecl *ExistingD;
1768   {
1769     Decl *ToTU = getToTuDecl(
1770         R"(
1771         struct A {
1772           static const int a = 1;
1773         };
1774         )",
1775         Lang_CXX03);
1776     ExistingD = FirstDeclMatcher<VarDecl>().match(ToTU, Pattern);
1777   }
1778   EXPECT_FALSE(ExistingD->isUsed(false));
1779   {
1780     Decl *FromTU = getTuDecl(
1781         R"(
1782         struct A {
1783           static const int a = 1;
1784         };
1785         const int *f() { return &A::a; } // requires storage,
1786                                          // thus used flag will be set
1787         )",
1788         Lang_CXX03, "input1.cc");
1789     auto *FromFunD = FirstDeclMatcher<FunctionDecl>().match(
1790         FromTU, functionDecl(hasName("f")));
1791     auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
1792     ASSERT_TRUE(FromD->isUsed(false));
1793     Import(FromFunD, Lang_CXX03);
1794   }
1795   EXPECT_TRUE(ExistingD->isUsed(false));
1796 }
1797 
TEST_P(ASTImporterOptionSpecificTestBase,ReimportWithUsedFlag)1798 TEST_P(ASTImporterOptionSpecificTestBase, ReimportWithUsedFlag) {
1799   auto Pattern = varDecl(hasName("x"));
1800 
1801   Decl *FromTU = getTuDecl("int x;", Lang_CXX03, "input0.cc");
1802   auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
1803 
1804   auto *Imported1 = cast<VarDecl>(Import(FromD, Lang_CXX03));
1805 
1806   ASSERT_FALSE(Imported1->isUsed(false));
1807 
1808   FromD->setIsUsed();
1809   auto *Imported2 = cast<VarDecl>(Import(FromD, Lang_CXX03));
1810 
1811   EXPECT_EQ(Imported1, Imported2);
1812   EXPECT_TRUE(Imported2->isUsed(false));
1813 }
1814 
1815 struct ImportFunctions : ASTImporterOptionSpecificTestBase {};
1816 
TEST_P(ImportFunctions,ImportPrototypeOfRecursiveFunction)1817 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
1818   Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
1819   auto Pattern = functionDecl(hasName("f"));
1820   auto *From =
1821       FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Proto
1822 
1823   Decl *ImportedD = Import(From, Lang_CXX03);
1824   Decl *ToTU = ImportedD->getTranslationUnitDecl();
1825 
1826   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
1827   auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
1828   auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
1829   EXPECT_TRUE(ImportedD == To0);
1830   EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
1831   EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
1832   EXPECT_EQ(To1->getPreviousDecl(), To0);
1833 }
1834 
TEST_P(ImportFunctions,ImportDefinitionOfRecursiveFunction)1835 TEST_P(ImportFunctions, ImportDefinitionOfRecursiveFunction) {
1836   Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX03);
1837   auto Pattern = functionDecl(hasName("f"));
1838   auto *From =
1839       LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern); // Def
1840 
1841   Decl *ImportedD = Import(From, Lang_CXX03);
1842   Decl *ToTU = ImportedD->getTranslationUnitDecl();
1843 
1844   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
1845   auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
1846   auto *To1 = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
1847   EXPECT_TRUE(ImportedD == To1);
1848   EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
1849   EXPECT_TRUE(To1->doesThisDeclarationHaveABody());
1850   EXPECT_EQ(To1->getPreviousDecl(), To0);
1851 }
1852 
TEST_P(ImportFunctions,OverriddenMethodsShouldBeImported)1853 TEST_P(ImportFunctions, OverriddenMethodsShouldBeImported) {
1854   auto Code =
1855       R"(
1856       struct B { virtual void f(); };
1857       void B::f() {}
1858       struct D : B { void f(); };
1859       )";
1860   auto Pattern =
1861       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
1862   Decl *FromTU = getTuDecl(Code, Lang_CXX03);
1863   CXXMethodDecl *Proto =
1864       FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
1865 
1866   ASSERT_EQ(Proto->size_overridden_methods(), 1u);
1867   CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
1868   EXPECT_EQ(To->size_overridden_methods(), 1u);
1869 }
1870 
TEST_P(ImportFunctions,VirtualFlagShouldBePreservedWhenImportingPrototype)1871 TEST_P(ImportFunctions, VirtualFlagShouldBePreservedWhenImportingPrototype) {
1872   auto Code =
1873       R"(
1874       struct B { virtual void f(); };
1875       void B::f() {}
1876       )";
1877   auto Pattern =
1878       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
1879   Decl *FromTU = getTuDecl(Code, Lang_CXX03);
1880   CXXMethodDecl *Proto =
1881       FirstDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
1882   CXXMethodDecl *Def = LastDeclMatcher<CXXMethodDecl>().match(FromTU, Pattern);
1883 
1884   ASSERT_TRUE(Proto->isVirtual());
1885   ASSERT_TRUE(Def->isVirtual());
1886   CXXMethodDecl *To = cast<CXXMethodDecl>(Import(Proto, Lang_CXX03));
1887   EXPECT_TRUE(To->isVirtual());
1888 }
1889 
TEST_P(ImportFunctions,ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl)1890 TEST_P(ImportFunctions,
1891        ImportDefinitionIfThereIsAnExistingDefinitionAndFwdDecl) {
1892   Decl *ToTU = getToTuDecl(
1893       R"(
1894       void f() {}
1895       void f();
1896       )",
1897       Lang_CXX03);
1898   ASSERT_EQ(1u,
1899             DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
1900               return FD->doesThisDeclarationHaveABody();
1901             }).match(ToTU, functionDecl()));
1902 
1903   Decl *FromTU = getTuDecl("void f() {}", Lang_CXX03, "input0.cc");
1904   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
1905 
1906   Import(FromD, Lang_CXX03);
1907 
1908   EXPECT_EQ(1u,
1909             DeclCounterWithPredicate<FunctionDecl>([](const FunctionDecl *FD) {
1910               return FD->doesThisDeclarationHaveABody();
1911             }).match(ToTU, functionDecl()));
1912 }
1913 
TEST_P(ImportFunctions,ImportOverriddenMethodTwice)1914 TEST_P(ImportFunctions, ImportOverriddenMethodTwice) {
1915   auto Code =
1916       R"(
1917       struct B { virtual void f(); };
1918       struct D:B { void f(); };
1919       )";
1920   auto BFP =
1921       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
1922   auto DFP =
1923       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
1924 
1925   Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
1926   auto *DF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
1927   Import(DF, Lang_CXX03);
1928 
1929   Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
1930   auto *BF = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
1931   Import(BF, Lang_CXX03);
1932 
1933   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
1934 
1935   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
1936   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
1937 }
1938 
TEST_P(ImportFunctions,ImportOverriddenMethodTwiceDefinitionFirst)1939 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceDefinitionFirst) {
1940   auto CodeWithoutDef =
1941       R"(
1942       struct B { virtual void f(); };
1943       struct D:B { void f(); };
1944       )";
1945   auto CodeWithDef =
1946       R"(
1947     struct B { virtual void f(){}; };
1948     struct D:B { void f(){}; };
1949   )";
1950   auto BFP =
1951       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
1952   auto DFP =
1953       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
1954   auto BFDefP = cxxMethodDecl(
1955       hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
1956   auto DFDefP = cxxMethodDecl(
1957       hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
1958   auto FDefAllP = cxxMethodDecl(hasName("f"), isDefinition());
1959 
1960   {
1961     Decl *FromTU = getTuDecl(CodeWithDef, Lang_CXX03, "input0.cc");
1962     auto *FromD = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, DFP);
1963     Import(FromD, Lang_CXX03);
1964   }
1965   {
1966     Decl *FromTU = getTuDecl(CodeWithoutDef, Lang_CXX03, "input1.cc");
1967     auto *FromB = FirstDeclMatcher<CXXMethodDecl>().match(FromTU, BFP);
1968     Import(FromB, Lang_CXX03);
1969   }
1970 
1971   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
1972 
1973   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
1974   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
1975   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 1u);
1976   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 1u);
1977   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FDefAllP), 2u);
1978 }
1979 
TEST_P(ImportFunctions,ImportOverriddenMethodTwiceOutOfClassDef)1980 TEST_P(ImportFunctions, ImportOverriddenMethodTwiceOutOfClassDef) {
1981   auto Code =
1982       R"(
1983       struct B { virtual void f(); };
1984       struct D:B { void f(); };
1985       void B::f(){};
1986       )";
1987 
1988   auto BFP =
1989       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
1990   auto BFDefP = cxxMethodDecl(
1991       hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
1992   auto DFP = cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))),
1993                            unless(isDefinition()));
1994 
1995   Decl *FromTU0 = getTuDecl(Code, Lang_CXX03);
1996   auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
1997   Import(D, Lang_CXX03);
1998 
1999   Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2000   auto *B = FirstDeclMatcher<CXXMethodDecl>().match(FromTU1, BFP);
2001   Import(B, Lang_CXX03);
2002 
2003   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2004 
2005   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2006   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2007 
2008   auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2009       ToTU, cxxRecordDecl(hasName("B")));
2010   auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2011   auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2012       ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2013 
2014   // The definition should be out-of-class.
2015   EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2016   EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2017             ToBFOutOfClass->getLexicalDeclContext());
2018   EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2019   EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2020 
2021   // Check that the redecl chain is intact.
2022   EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2023 }
2024 
TEST_P(ImportFunctions,ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode)2025 TEST_P(ImportFunctions,
2026        ImportOverriddenMethodTwiceOutOfClassDefInSeparateCode) {
2027   auto CodeTU0 =
2028       R"(
2029       struct B { virtual void f(); };
2030       struct D:B { void f(); };
2031       )";
2032   auto CodeTU1 =
2033       R"(
2034       struct B { virtual void f(); };
2035       struct D:B { void f(); };
2036       void B::f(){}
2037       void D::f(){}
2038       void foo(B &b, D &d) { b.f(); d.f(); }
2039       )";
2040 
2041   auto BFP =
2042       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("B"))));
2043   auto BFDefP = cxxMethodDecl(
2044       hasName("f"), hasParent(cxxRecordDecl(hasName("B"))), isDefinition());
2045   auto DFP =
2046       cxxMethodDecl(hasName("f"), hasParent(cxxRecordDecl(hasName("D"))));
2047   auto DFDefP = cxxMethodDecl(
2048       hasName("f"), hasParent(cxxRecordDecl(hasName("D"))), isDefinition());
2049   auto FooDef = functionDecl(hasName("foo"));
2050 
2051   {
2052     Decl *FromTU0 = getTuDecl(CodeTU0, Lang_CXX03, "input0.cc");
2053     auto *D = FirstDeclMatcher<CXXMethodDecl>().match(FromTU0, DFP);
2054     Import(D, Lang_CXX03);
2055   }
2056 
2057   {
2058     Decl *FromTU1 = getTuDecl(CodeTU1, Lang_CXX03, "input1.cc");
2059     auto *Foo = FirstDeclMatcher<FunctionDecl>().match(FromTU1, FooDef);
2060     Import(Foo, Lang_CXX03);
2061   }
2062 
2063   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2064 
2065   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFP), 1u);
2066   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFP), 1u);
2067   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, BFDefP), 0u);
2068   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, DFDefP), 0u);
2069 
2070   auto *ToB = FirstDeclMatcher<CXXRecordDecl>().match(
2071       ToTU, cxxRecordDecl(hasName("B")));
2072   auto *ToD = FirstDeclMatcher<CXXRecordDecl>().match(
2073       ToTU, cxxRecordDecl(hasName("D")));
2074   auto *ToBFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, BFP);
2075   auto *ToBFOutOfClass = FirstDeclMatcher<CXXMethodDecl>().match(
2076       ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2077   auto *ToDFInClass = FirstDeclMatcher<CXXMethodDecl>().match(ToTU, DFP);
2078   auto *ToDFOutOfClass = LastDeclMatcher<CXXMethodDecl>().match(
2079       ToTU, cxxMethodDecl(hasName("f"), isDefinition()));
2080 
2081   // The definition should be out-of-class.
2082   EXPECT_NE(ToBFInClass, ToBFOutOfClass);
2083   EXPECT_NE(ToBFInClass->getLexicalDeclContext(),
2084             ToBFOutOfClass->getLexicalDeclContext());
2085   EXPECT_EQ(ToBFOutOfClass->getDeclContext(), ToB);
2086   EXPECT_EQ(ToBFOutOfClass->getLexicalDeclContext(), ToTU);
2087 
2088   EXPECT_NE(ToDFInClass, ToDFOutOfClass);
2089   EXPECT_NE(ToDFInClass->getLexicalDeclContext(),
2090             ToDFOutOfClass->getLexicalDeclContext());
2091   EXPECT_EQ(ToDFOutOfClass->getDeclContext(), ToD);
2092   EXPECT_EQ(ToDFOutOfClass->getLexicalDeclContext(), ToTU);
2093 
2094   // Check that the redecl chain is intact.
2095   EXPECT_EQ(ToBFOutOfClass->getPreviousDecl(), ToBFInClass);
2096   EXPECT_EQ(ToDFOutOfClass->getPreviousDecl(), ToDFInClass);
2097 }
2098 
TEST_P(ASTImporterOptionSpecificTestBase,ImportVariableChainInC)2099 TEST_P(ASTImporterOptionSpecificTestBase, ImportVariableChainInC) {
2100     std::string Code = "static int v; static int v = 0;";
2101     auto Pattern = varDecl(hasName("v"));
2102 
2103     TranslationUnitDecl *FromTu = getTuDecl(Code, Lang_C99, "input0.c");
2104 
2105     auto *From0 = FirstDeclMatcher<VarDecl>().match(FromTu, Pattern);
2106     auto *From1 = LastDeclMatcher<VarDecl>().match(FromTu, Pattern);
2107 
2108     auto *To0 = Import(From0, Lang_C99);
2109     auto *To1 = Import(From1, Lang_C99);
2110 
2111     EXPECT_TRUE(To0);
2112     ASSERT_TRUE(To1);
2113     EXPECT_NE(To0, To1);
2114     EXPECT_EQ(To1->getPreviousDecl(), To0);
2115 }
2116 
TEST_P(ImportFunctions,ImportFromDifferentScopedAnonNamespace)2117 TEST_P(ImportFunctions, ImportFromDifferentScopedAnonNamespace) {
2118   TranslationUnitDecl *FromTu =
2119       getTuDecl("namespace NS0 { namespace { void f(); } }"
2120                 "namespace NS1 { namespace { void f(); } }",
2121                 Lang_CXX03, "input0.cc");
2122   auto Pattern = functionDecl(hasName("f"));
2123 
2124   auto *FromF0 = FirstDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2125   auto *FromF1 = LastDeclMatcher<FunctionDecl>().match(FromTu, Pattern);
2126 
2127   auto *ToF0 = Import(FromF0, Lang_CXX03);
2128   auto *ToF1 = Import(FromF1, Lang_CXX03);
2129 
2130   EXPECT_TRUE(ToF0);
2131   ASSERT_TRUE(ToF1);
2132   EXPECT_NE(ToF0, ToF1);
2133   EXPECT_FALSE(ToF1->getPreviousDecl());
2134 }
2135 
TEST_P(ImportFunctions,ImportFunctionFromUnnamedNamespace)2136 TEST_P(ImportFunctions, ImportFunctionFromUnnamedNamespace) {
2137   {
2138     Decl *FromTU = getTuDecl("namespace { void f() {} } void g0() { f(); }",
2139                              Lang_CXX03, "input0.cc");
2140     auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2141         FromTU, functionDecl(hasName("g0")));
2142 
2143     Import(FromD, Lang_CXX03);
2144   }
2145   {
2146     Decl *FromTU =
2147         getTuDecl("namespace { void f() { int a; } } void g1() { f(); }",
2148                   Lang_CXX03, "input1.cc");
2149     auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2150         FromTU, functionDecl(hasName("g1")));
2151     Import(FromD, Lang_CXX03);
2152   }
2153 
2154   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2155   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
2156             2u);
2157 }
2158 
TEST_P(ImportFunctions,ImportImplicitFunctionsInLambda)2159 TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) {
2160   Decl *FromTU = getTuDecl(
2161       R"(
2162       void foo() {
2163         (void)[]() { ; };
2164       }
2165       )",
2166       Lang_CXX11);
2167   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2168       FromTU, functionDecl(hasName("foo")));
2169   auto *ToD = Import(FromD, Lang_CXX03);
2170   EXPECT_TRUE(ToD);
2171   CXXRecordDecl *LambdaRec =
2172       cast<LambdaExpr>(cast<CStyleCastExpr>(
2173                            *cast<CompoundStmt>(ToD->getBody())->body_begin())
2174                            ->getSubExpr())
2175           ->getLambdaClass();
2176   EXPECT_TRUE(LambdaRec->getDestructor());
2177 }
2178 
TEST_P(ImportFunctions,CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs)2179 TEST_P(ImportFunctions,
2180        CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2181   Decl *FromTU = getTuDecl(
2182       R"(
2183       struct X {
2184         template <typename T>
2185         void foo(){}
2186       };
2187       void f() {
2188         X x;
2189         x.foo<int>();
2190       }
2191       )",
2192       Lang_CXX03);
2193   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2194       FromTU, functionDecl(hasName("f")));
2195   auto *ToD = Import(FromD, Lang_CXX03);
2196   EXPECT_TRUE(ToD);
2197   EXPECT_TRUE(MatchVerifier<FunctionDecl>().match(
2198       ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr()))));
2199 }
2200 
TEST_P(ImportFunctions,DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs)2201 TEST_P(ImportFunctions,
2202        DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
2203   Decl *FromTU = getTuDecl(
2204       R"(
2205       struct X {
2206         template <typename T>
2207         void foo(){}
2208       };
2209       template <typename T>
2210       void f() {
2211         X x;
2212         x.foo<T>();
2213       }
2214       void g() {
2215         f<int>();
2216       }
2217       )",
2218       Lang_CXX03);
2219   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2220       FromTU, functionDecl(hasName("g")));
2221   auto *ToD = Import(FromD, Lang_CXX03);
2222   EXPECT_TRUE(ToD);
2223   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2224   EXPECT_TRUE(MatchVerifier<TranslationUnitDecl>().match(
2225       ToTU, translationUnitDecl(hasDescendant(
2226                 functionDecl(hasName("f"), hasDescendant(declRefExpr()))))));
2227 }
2228 
2229 struct ImportFunctionTemplates : ASTImporterOptionSpecificTestBase {};
2230 
TEST_P(ImportFunctionTemplates,ImportFunctionTemplateInRecordDeclTwice)2231 TEST_P(ImportFunctionTemplates, ImportFunctionTemplateInRecordDeclTwice) {
2232   auto Code =
2233       R"(
2234       class X {
2235         template <class T>
2236         void f(T t);
2237       };
2238       )";
2239   Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2240   auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2241       FromTU1, functionTemplateDecl(hasName("f")));
2242   auto *ToD1 = Import(FromD1, Lang_CXX03);
2243   Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2244   auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2245       FromTU2, functionTemplateDecl(hasName("f")));
2246   auto *ToD2 = Import(FromD2, Lang_CXX03);
2247   EXPECT_EQ(ToD1, ToD2);
2248 }
2249 
TEST_P(ImportFunctionTemplates,ImportFunctionTemplateWithDefInRecordDeclTwice)2250 TEST_P(ImportFunctionTemplates,
2251        ImportFunctionTemplateWithDefInRecordDeclTwice) {
2252   auto Code =
2253       R"(
2254       class X {
2255         template <class T>
2256         void f(T t);
2257       };
2258       template <class T>
2259       void X::f(T t) {};
2260       )";
2261   Decl *FromTU1 = getTuDecl(Code, Lang_CXX03, "input1.cc");
2262   auto *FromD1 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2263       FromTU1, functionTemplateDecl(hasName("f")));
2264   auto *ToD1 = Import(FromD1, Lang_CXX03);
2265   Decl *FromTU2 = getTuDecl(Code, Lang_CXX03, "input2.cc");
2266   auto *FromD2 = FirstDeclMatcher<FunctionTemplateDecl>().match(
2267       FromTU2, functionTemplateDecl(hasName("f")));
2268   auto *ToD2 = Import(FromD2, Lang_CXX03);
2269   EXPECT_EQ(ToD1, ToD2);
2270 }
2271 
TEST_P(ImportFunctionTemplates,ImportFunctionWhenThereIsAFunTemplateWithSameName)2272 TEST_P(ImportFunctionTemplates,
2273        ImportFunctionWhenThereIsAFunTemplateWithSameName) {
2274   getToTuDecl(
2275       R"(
2276       template <typename T>
2277       void foo(T) {}
2278       void foo();
2279       )",
2280       Lang_CXX03);
2281   Decl *FromTU = getTuDecl("void foo();", Lang_CXX03);
2282   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
2283       FromTU, functionDecl(hasName("foo")));
2284   auto *ImportedD = Import(FromD, Lang_CXX03);
2285   EXPECT_TRUE(ImportedD);
2286 }
2287 
TEST_P(ImportFunctionTemplates,ImportConstructorWhenThereIsAFunTemplateWithSameName)2288 TEST_P(ImportFunctionTemplates,
2289        ImportConstructorWhenThereIsAFunTemplateWithSameName) {
2290   auto Code =
2291       R"(
2292       struct Foo {
2293         template <typename T>
2294         Foo(T) {}
2295         Foo();
2296       };
2297       )";
2298   getToTuDecl(Code, Lang_CXX03);
2299   Decl *FromTU = getTuDecl(Code, Lang_CXX03);
2300   auto *FromD =
2301       LastDeclMatcher<CXXConstructorDecl>().match(FromTU, cxxConstructorDecl());
2302   auto *ImportedD = Import(FromD, Lang_CXX03);
2303   EXPECT_TRUE(ImportedD);
2304 }
2305 
TEST_P(ImportFunctionTemplates,ImportOperatorWhenThereIsAFunTemplateWithSameName)2306 TEST_P(ImportFunctionTemplates,
2307        ImportOperatorWhenThereIsAFunTemplateWithSameName) {
2308   getToTuDecl(
2309       R"(
2310       template <typename T>
2311       void operator<(T,T) {}
2312       struct X{};
2313       void operator<(X, X);
2314       )",
2315       Lang_CXX03);
2316   Decl *FromTU = getTuDecl(
2317       R"(
2318       struct X{};
2319       void operator<(X, X);
2320       )",
2321       Lang_CXX03);
2322   auto *FromD = LastDeclMatcher<FunctionDecl>().match(
2323       FromTU, functionDecl(hasOverloadedOperatorName("<")));
2324   auto *ImportedD = Import(FromD, Lang_CXX03);
2325   EXPECT_TRUE(ImportedD);
2326 }
2327 
2328 struct ImportFriendFunctions : ImportFunctions {};
2329 
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainProto)2330 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {
2331   auto Pattern = functionDecl(hasName("f"));
2332 
2333   Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2334                            "void f();",
2335                            Lang_CXX03, "input0.cc");
2336   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2337 
2338   auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2339   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2340   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2341   EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2342   auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2343   EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2344   EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2345 }
2346 
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst)2347 TEST_P(ImportFriendFunctions,
2348        ImportFriendFunctionRedeclChainProto_OutOfClassProtoFirst) {
2349   auto Pattern = functionDecl(hasName("f"));
2350 
2351   Decl *FromTU = getTuDecl("void f();"
2352                            "struct X { friend void f(); };",
2353                            Lang_CXX03, "input0.cc");
2354   auto FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2355 
2356   auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2357   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2358   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2359   EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2360   auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2361   EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2362   EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2363 }
2364 
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDef)2365 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDef) {
2366   auto Pattern = functionDecl(hasName("f"));
2367 
2368   Decl *FromTU = getTuDecl("struct X { friend void f(){} };"
2369                            "void f();",
2370                            Lang_CXX03, "input0.cc");
2371   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2372 
2373   auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2374   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2375   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2376   EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2377   auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2378   EXPECT_FALSE(ToFD->doesThisDeclarationHaveABody());
2379   EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2380 }
2381 
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDef_OutOfClassDef)2382 TEST_P(ImportFriendFunctions,
2383        ImportFriendFunctionRedeclChainDef_OutOfClassDef) {
2384   auto Pattern = functionDecl(hasName("f"));
2385 
2386   Decl *FromTU = getTuDecl("struct X { friend void f(); };"
2387                            "void f(){}",
2388                            Lang_CXX03, "input0.cc");
2389   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2390 
2391   auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2392   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2393   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2394   EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2395   auto *ToFD = LastDeclMatcher<FunctionDecl>().match(ToTU, Pattern);
2396   EXPECT_TRUE(ToFD->doesThisDeclarationHaveABody());
2397   EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
2398 }
2399 
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDefWithClass)2400 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) {
2401   auto Pattern = functionDecl(hasName("f"));
2402 
2403   Decl *FromTU = getTuDecl(
2404       R"(
2405         class X;
2406         void f(X *x){}
2407         class X{
2408         friend void f(X *x);
2409         };
2410       )",
2411       Lang_CXX03, "input0.cc");
2412   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2413 
2414   auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2415   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2416   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2417   EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2418   auto *InClassFD = cast<FunctionDecl>(FirstDeclMatcher<FriendDecl>()
2419                                               .match(ToTU, friendDecl())
2420                                               ->getFriendDecl());
2421   EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody());
2422   EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD);
2423   // The parameters must refer the same type
2424   EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(),
2425             (*ImportedD->param_begin())->getOriginalType());
2426 }
2427 
TEST_P(ImportFriendFunctions,ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto)2428 TEST_P(ImportFriendFunctions,
2429        ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) {
2430   auto Pattern = functionDecl(hasName("f"));
2431 
2432   Decl *FromTU = getTuDecl(
2433       R"(
2434         class X;
2435         void f(X *x){}
2436         class X{
2437         friend void f(X *x);
2438         };
2439       )",
2440       Lang_CXX03, "input0.cc");
2441   auto *FromD = LastDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2442 
2443   auto *ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2444   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2445   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2446   EXPECT_FALSE(ImportedD->doesThisDeclarationHaveABody());
2447   auto *OutOfClassFD = FirstDeclMatcher<FunctionDecl>().match(
2448       ToTU, functionDecl(unless(hasParent(friendDecl()))));
2449 
2450   EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody());
2451   EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD);
2452   // The parameters must refer the same type
2453   EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(),
2454             (*ImportedD->param_begin())->getOriginalType());
2455 }
2456 
TEST_P(ImportFriendFunctions,ImportFriendFunctionFromMultipleTU)2457 TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) {
2458   auto Pattern = functionDecl(hasName("f"));
2459 
2460   FunctionDecl *ImportedD;
2461   {
2462     Decl *FromTU =
2463         getTuDecl("struct X { friend void f(){} };", Lang_CXX03, "input0.cc");
2464     auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2465     ImportedD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2466   }
2467   FunctionDecl *ImportedD1;
2468   {
2469     Decl *FromTU = getTuDecl("void f();", Lang_CXX03, "input1.cc");
2470     auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, Pattern);
2471     ImportedD1 = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2472   }
2473 
2474   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2475   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2476   EXPECT_TRUE(ImportedD->doesThisDeclarationHaveABody());
2477   EXPECT_FALSE(ImportedD1->doesThisDeclarationHaveABody());
2478   EXPECT_EQ(ImportedD1->getPreviousDecl(), ImportedD);
2479 }
2480 
TEST_P(ImportFriendFunctions,Lookup)2481 TEST_P(ImportFriendFunctions, Lookup) {
2482   auto FunctionPattern = functionDecl(hasName("f"));
2483   auto ClassPattern = cxxRecordDecl(hasName("X"));
2484 
2485   TranslationUnitDecl *FromTU =
2486       getTuDecl("struct X { friend void f(); };", Lang_CXX03, "input0.cc");
2487   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2488   ASSERT_TRUE(FromD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2489   ASSERT_FALSE(FromD->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2490   {
2491     auto FromName = FromD->getDeclName();
2492     auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2493     auto LookupRes = Class->noload_lookup(FromName);
2494     ASSERT_EQ(LookupRes.size(), 0u);
2495     LookupRes = FromTU->noload_lookup(FromName);
2496     ASSERT_EQ(LookupRes.size(), 1u);
2497   }
2498 
2499   auto *ToD = cast<FunctionDecl>(Import(FromD, Lang_CXX03));
2500   auto ToName = ToD->getDeclName();
2501 
2502   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2503   auto *Class = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2504   auto LookupRes = Class->noload_lookup(ToName);
2505   EXPECT_EQ(LookupRes.size(), 0u);
2506   LookupRes = ToTU->noload_lookup(ToName);
2507   EXPECT_EQ(LookupRes.size(), 1u);
2508 
2509   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 1u);
2510   auto *To0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2511   EXPECT_TRUE(To0->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2512   EXPECT_FALSE(To0->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2513 }
2514 
TEST_P(ImportFriendFunctions,LookupWithProtoAfter)2515 TEST_P(ImportFriendFunctions, LookupWithProtoAfter) {
2516   auto FunctionPattern = functionDecl(hasName("f"));
2517   auto ClassPattern = cxxRecordDecl(hasName("X"));
2518 
2519   TranslationUnitDecl *FromTU =
2520       getTuDecl("struct X { friend void f(); };"
2521                 // This proto decl makes f available to normal
2522                 // lookup, otherwise it is hidden.
2523                 // Normal C++ lookup (implemented in
2524                 // `clang::Sema::CppLookupName()` and in `LookupDirect()`)
2525                 // returns the found `NamedDecl` only if the set IDNS is matched
2526                 "void f();",
2527                 Lang_CXX03, "input0.cc");
2528   auto *FromFriend =
2529       FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2530   auto *FromNormal =
2531       LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2532   ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2533   ASSERT_FALSE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2534   ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2535   ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2536 
2537   auto FromName = FromFriend->getDeclName();
2538   auto *FromClass =
2539       FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2540   auto LookupRes = FromClass->noload_lookup(FromName);
2541   ASSERT_EQ(LookupRes.size(), 0u);
2542   LookupRes = FromTU->noload_lookup(FromName);
2543   ASSERT_EQ(LookupRes.size(), 1u);
2544 
2545   auto *ToFriend = cast<FunctionDecl>(Import(FromFriend, Lang_CXX03));
2546   auto ToName = ToFriend->getDeclName();
2547 
2548   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2549   auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2550   LookupRes = ToClass->noload_lookup(ToName);
2551   EXPECT_EQ(LookupRes.size(), 0u);
2552   LookupRes = ToTU->noload_lookup(ToName);
2553   // Test is disabled because this result is 2.
2554   EXPECT_EQ(LookupRes.size(), 1u);
2555 
2556   ASSERT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
2557   ToFriend = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2558   auto *ToNormal = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2559   EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2560   EXPECT_FALSE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2561   EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2562   EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2563 }
2564 
TEST_P(ImportFriendFunctions,LookupWithProtoBefore)2565 TEST_P(ImportFriendFunctions, LookupWithProtoBefore) {
2566   auto FunctionPattern = functionDecl(hasName("f"));
2567   auto ClassPattern = cxxRecordDecl(hasName("X"));
2568 
2569   TranslationUnitDecl *FromTU = getTuDecl("void f();"
2570                                           "struct X { friend void f(); };",
2571                                           Lang_CXX03, "input0.cc");
2572   auto *FromNormal =
2573       FirstDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2574   auto *FromFriend =
2575       LastDeclMatcher<FunctionDecl>().match(FromTU, FunctionPattern);
2576   ASSERT_FALSE(FromNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2577   ASSERT_TRUE(FromNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2578   ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2579   ASSERT_TRUE(FromFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2580 
2581   auto FromName = FromNormal->getDeclName();
2582   auto *FromClass =
2583       FirstDeclMatcher<CXXRecordDecl>().match(FromTU, ClassPattern);
2584   auto LookupRes = FromClass->noload_lookup(FromName);
2585   ASSERT_EQ(LookupRes.size(), 0u);
2586   LookupRes = FromTU->noload_lookup(FromName);
2587   ASSERT_EQ(LookupRes.size(), 1u);
2588 
2589   auto *ToNormal = cast<FunctionDecl>(Import(FromNormal, Lang_CXX03));
2590   auto ToName = ToNormal->getDeclName();
2591   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2592 
2593   auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, ClassPattern);
2594   LookupRes = ToClass->noload_lookup(ToName);
2595   EXPECT_EQ(LookupRes.size(), 0u);
2596   LookupRes = ToTU->noload_lookup(ToName);
2597   EXPECT_EQ(LookupRes.size(), 1u);
2598 
2599   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, FunctionPattern), 2u);
2600   ToNormal = FirstDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2601   auto *ToFriend = LastDeclMatcher<FunctionDecl>().match(ToTU, FunctionPattern);
2602   EXPECT_FALSE(ToNormal->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2603   EXPECT_TRUE(ToNormal->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2604   EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2605   EXPECT_TRUE(ToFriend->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2606 }
2607 
TEST_P(ImportFriendFunctions,ImportFriendChangesLookup)2608 TEST_P(ImportFriendFunctions, ImportFriendChangesLookup) {
2609   auto Pattern = functionDecl(hasName("f"));
2610 
2611   TranslationUnitDecl *FromNormalTU =
2612       getTuDecl("void f();", Lang_CXX03, "input0.cc");
2613   auto *FromNormalF =
2614       FirstDeclMatcher<FunctionDecl>().match(FromNormalTU, Pattern);
2615   TranslationUnitDecl *FromFriendTU =
2616       getTuDecl("class X { friend void f(); };", Lang_CXX03, "input1.cc");
2617   auto *FromFriendF =
2618       FirstDeclMatcher<FunctionDecl>().match(FromFriendTU, Pattern);
2619   auto FromNormalName = FromNormalF->getDeclName();
2620   auto FromFriendName = FromFriendF->getDeclName();
2621 
2622   ASSERT_TRUE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2623   ASSERT_FALSE(FromNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2624   ASSERT_FALSE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2625   ASSERT_TRUE(FromFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2626   auto LookupRes = FromNormalTU->noload_lookup(FromNormalName);
2627   ASSERT_EQ(LookupRes.size(), 1u);
2628   LookupRes = FromFriendTU->noload_lookup(FromFriendName);
2629   ASSERT_EQ(LookupRes.size(), 1u);
2630 
2631   auto *ToNormalF = cast<FunctionDecl>(Import(FromNormalF, Lang_CXX03));
2632   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2633   auto ToName = ToNormalF->getDeclName();
2634   EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2635   EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2636   LookupRes = ToTU->noload_lookup(ToName);
2637   EXPECT_EQ(LookupRes.size(), 1u);
2638   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 1u);
2639 
2640   auto *ToFriendF = cast<FunctionDecl>(Import(FromFriendF, Lang_CXX03));
2641   LookupRes = ToTU->noload_lookup(ToName);
2642   EXPECT_EQ(LookupRes.size(), 1u);
2643   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, Pattern), 2u);
2644 
2645   EXPECT_TRUE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2646   EXPECT_FALSE(ToNormalF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2647 
2648   EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_Ordinary));
2649   EXPECT_TRUE(ToFriendF->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend));
2650 }
2651 
TEST_P(ImportFriendFunctions,ImportFriendList)2652 TEST_P(ImportFriendFunctions, ImportFriendList) {
2653   TranslationUnitDecl *FromTU = getTuDecl("struct X { friend void f(); };"
2654                                           "void f();",
2655                                           Lang_CXX03, "input0.cc");
2656   auto *FromFriendF = FirstDeclMatcher<FunctionDecl>().match(
2657       FromTU, functionDecl(hasName("f")));
2658 
2659   auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
2660       FromTU, cxxRecordDecl(hasName("X")));
2661   auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTU, friendDecl());
2662   auto FromFriends = FromClass->friends();
2663   unsigned int FrN = 0;
2664   for (auto Fr : FromFriends) {
2665     ASSERT_EQ(Fr, FromFriend);
2666     ++FrN;
2667   }
2668   ASSERT_EQ(FrN, 1u);
2669 
2670   Import(FromFriendF, Lang_CXX03);
2671   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
2672   auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
2673       ToTU, cxxRecordDecl(hasName("X")));
2674   auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
2675   auto ToFriends = ToClass->friends();
2676   FrN = 0;
2677   for (auto Fr : ToFriends) {
2678     EXPECT_EQ(Fr, ToFriend);
2679     ++FrN;
2680   }
2681   EXPECT_EQ(FrN, 1u);
2682 }
2683 
AST_MATCHER_P(TagDecl,hasTypedefForAnonDecl,Matcher<TypedefNameDecl>,InnerMatcher)2684 AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher<TypedefNameDecl>,
2685               InnerMatcher) {
2686   if (auto *Typedef = Node.getTypedefNameForAnonDecl())
2687     return InnerMatcher.matches(*Typedef, Finder, Builder);
2688   return false;
2689 }
2690 
TEST_P(ImportDecl,ImportEnumSequential)2691 TEST_P(ImportDecl, ImportEnumSequential) {
2692   CodeFiles Samples{{"main.c",
2693                      {"void foo();"
2694                       "void moo();"
2695                       "int main() { foo(); moo(); }",
2696                       Lang_C99}},
2697 
2698                     {"foo.c",
2699                      {"typedef enum { THING_VALUE } thing_t;"
2700                       "void conflict(thing_t type);"
2701                       "void foo() { (void)THING_VALUE; }"
2702                       "void conflict(thing_t type) {}",
2703                       Lang_C99}},
2704 
2705                     {"moo.c",
2706                      {"typedef enum { THING_VALUE } thing_t;"
2707                       "void conflict(thing_t type);"
2708                       "void moo() { conflict(THING_VALUE); }",
2709                       Lang_C99}}};
2710 
2711   auto VerificationMatcher =
2712       enumDecl(has(enumConstantDecl(hasName("THING_VALUE"))),
2713                hasTypedefForAnonDecl(hasName("thing_t")));
2714 
2715   ImportAction ImportFoo{"foo.c", "main.c", functionDecl(hasName("foo"))},
2716       ImportMoo{"moo.c", "main.c", functionDecl(hasName("moo"))};
2717 
2718   testImportSequence(
2719       Samples, {ImportFoo, ImportMoo}, // "foo", them "moo".
2720       // Just check that there is only one enum decl in the result AST.
2721       "main.c", enumDecl(), VerificationMatcher);
2722 
2723   // For different import order, result should be the same.
2724   testImportSequence(
2725       Samples, {ImportMoo, ImportFoo}, // "moo", them "foo".
2726       // Check that there is only one enum decl in the result AST.
2727       "main.c", enumDecl(), VerificationMatcher);
2728 }
2729 
TEST_P(ImportDecl,ImportFieldOrder)2730 TEST_P(ImportDecl, ImportFieldOrder) {
2731   MatchVerifier<Decl> Verifier;
2732   testImport("struct declToImport {"
2733              "  int b = a + 2;"
2734              "  int a = 5;"
2735              "};",
2736              Lang_CXX11, "", Lang_CXX11, Verifier,
2737              recordDecl(hasFieldOrder({"b", "a"})));
2738 }
2739 
2740 const internal::VariadicDynCastAllOfMatcher<Expr, DependentScopeDeclRefExpr>
2741     dependentScopeDeclRefExpr;
2742 
TEST_P(ImportExpr,DependentScopeDeclRefExpr)2743 TEST_P(ImportExpr, DependentScopeDeclRefExpr) {
2744   MatchVerifier<Decl> Verifier;
2745   testImport("template <typename T> struct S { static T foo; };"
2746              "template <typename T> void declToImport() {"
2747              "  (void) S<T>::foo;"
2748              "}"
2749              "void instantiate() { declToImport<int>(); }"
2750              "template <typename T> T S<T>::foo;",
2751              Lang_CXX11, "", Lang_CXX11, Verifier,
2752              functionTemplateDecl(has(functionDecl(has(compoundStmt(
2753                  has(cStyleCastExpr(has(dependentScopeDeclRefExpr())))))))));
2754 
2755   testImport("template <typename T> struct S {"
2756              "template<typename S> static void foo(){};"
2757              "};"
2758              "template <typename T> void declToImport() {"
2759              "  S<T>::template foo<T>();"
2760              "}"
2761              "void instantiate() { declToImport<int>(); }",
2762              Lang_CXX11, "", Lang_CXX11, Verifier,
2763              functionTemplateDecl(has(functionDecl(has(compoundStmt(
2764                  has(callExpr(has(dependentScopeDeclRefExpr())))))))));
2765 }
2766 
2767 const internal::VariadicDynCastAllOfMatcher<Type, DependentNameType>
2768     dependentNameType;
2769 
TEST_P(ImportExpr,DependentNameType)2770 TEST_P(ImportExpr, DependentNameType) {
2771   MatchVerifier<Decl> Verifier;
2772   testImport("template <typename T> struct declToImport {"
2773              "  typedef typename T::type dependent_name;"
2774              "};",
2775              Lang_CXX11, "", Lang_CXX11, Verifier,
2776              classTemplateDecl(has(
2777                  cxxRecordDecl(has(typedefDecl(has(dependentNameType())))))));
2778 }
2779 
TEST_P(ImportExpr,UnresolvedMemberExpr)2780 TEST_P(ImportExpr, UnresolvedMemberExpr) {
2781   MatchVerifier<Decl> Verifier;
2782   testImport("struct S { template <typename T> void mem(); };"
2783              "template <typename U> void declToImport() {"
2784              "  S s;"
2785              "  s.mem<U>();"
2786              "}"
2787              "void instantiate() { declToImport<int>(); }",
2788              Lang_CXX11, "", Lang_CXX11, Verifier,
2789              functionTemplateDecl(has(functionDecl(has(
2790                  compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
2791 }
2792 
2793 class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
2794 public:
2795   static constexpr auto DefaultCode = R"(
2796       struct A { int x; };
2797       void f() {
2798         A a;
2799         A a1(a);
2800         A a2(A{});
2801         a = a1;
2802         a = A{};
2803         a.~A();
2804       })";
2805 
2806   template <typename MatcherType>
testImportOf(const MatcherType & MethodMatcher,const char * Code=DefaultCode)2807   void testImportOf(
2808       const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
2809     test(MethodMatcher, Code, /*ExpectedCount=*/1u);
2810   }
2811 
2812   template <typename MatcherType>
testNoImportOf(const MatcherType & MethodMatcher,const char * Code=DefaultCode)2813   void testNoImportOf(
2814       const MatcherType &MethodMatcher, const char *Code = DefaultCode) {
2815     test(MethodMatcher, Code, /*ExpectedCount=*/0u);
2816   }
2817 
2818 private:
2819   template <typename MatcherType>
test(const MatcherType & MethodMatcher,const char * Code,unsigned int ExpectedCount)2820   void test(const MatcherType &MethodMatcher,
2821       const char *Code, unsigned int ExpectedCount) {
2822     auto ClassMatcher = cxxRecordDecl(unless(isImplicit()));
2823 
2824     Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
2825     auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match(
2826         ToTU, ClassMatcher);
2827 
2828     ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1u);
2829 
2830     {
2831       CXXMethodDecl *Method =
2832           FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher);
2833       ToClass->removeDecl(Method);
2834       SharedStatePtr->getLookupTable()->remove(Method);
2835     }
2836 
2837     ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0u);
2838 
2839     Decl *ImportedClass = nullptr;
2840     {
2841       Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc");
2842       auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
2843           FromTU, ClassMatcher);
2844       ImportedClass = Import(FromClass, Lang_CXX11);
2845     }
2846 
2847     EXPECT_EQ(ToClass, ImportedClass);
2848     EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher),
2849         ExpectedCount);
2850   }
2851 };
2852 
TEST_P(ImportImplicitMethods,DefaultConstructor)2853 TEST_P(ImportImplicitMethods, DefaultConstructor) {
2854   testImportOf(cxxConstructorDecl(isDefaultConstructor()));
2855 }
2856 
TEST_P(ImportImplicitMethods,CopyConstructor)2857 TEST_P(ImportImplicitMethods, CopyConstructor) {
2858   testImportOf(cxxConstructorDecl(isCopyConstructor()));
2859 }
2860 
TEST_P(ImportImplicitMethods,MoveConstructor)2861 TEST_P(ImportImplicitMethods, MoveConstructor) {
2862   testImportOf(cxxConstructorDecl(isMoveConstructor()));
2863 }
2864 
TEST_P(ImportImplicitMethods,Destructor)2865 TEST_P(ImportImplicitMethods, Destructor) {
2866   testImportOf(cxxDestructorDecl());
2867 }
2868 
TEST_P(ImportImplicitMethods,CopyAssignment)2869 TEST_P(ImportImplicitMethods, CopyAssignment) {
2870   testImportOf(cxxMethodDecl(isCopyAssignmentOperator()));
2871 }
2872 
TEST_P(ImportImplicitMethods,MoveAssignment)2873 TEST_P(ImportImplicitMethods, MoveAssignment) {
2874   testImportOf(cxxMethodDecl(isMoveAssignmentOperator()));
2875 }
2876 
TEST_P(ImportImplicitMethods,DoNotImportUserProvided)2877 TEST_P(ImportImplicitMethods, DoNotImportUserProvided) {
2878   auto Code = R"(
2879       struct A { A() { int x; } };
2880       )";
2881   testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
2882 }
2883 
TEST_P(ImportImplicitMethods,DoNotImportDefault)2884 TEST_P(ImportImplicitMethods, DoNotImportDefault) {
2885   auto Code = R"(
2886       struct A { A() = default; };
2887       )";
2888   testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
2889 }
2890 
TEST_P(ImportImplicitMethods,DoNotImportDeleted)2891 TEST_P(ImportImplicitMethods, DoNotImportDeleted) {
2892   auto Code = R"(
2893       struct A { A() = delete; };
2894       )";
2895   testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code);
2896 }
2897 
TEST_P(ImportImplicitMethods,DoNotImportOtherMethod)2898 TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) {
2899   auto Code = R"(
2900       struct A { void f() { } };
2901       )";
2902   testNoImportOf(cxxMethodDecl(hasName("f")), Code);
2903 }
2904 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfEquivalentRecord)2905 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentRecord) {
2906   Decl *ToR1;
2907   {
2908     Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input0.cc");
2909     auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
2910         FromTU, cxxRecordDecl(hasName("A")));
2911 
2912     ToR1 = Import(FromR, Lang_CXX03);
2913   }
2914 
2915   Decl *ToR2;
2916   {
2917     Decl *FromTU = getTuDecl("struct A { };", Lang_CXX03, "input1.cc");
2918     auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
2919         FromTU, cxxRecordDecl(hasName("A")));
2920 
2921     ToR2 = Import(FromR, Lang_CXX03);
2922   }
2923 
2924   EXPECT_EQ(ToR1, ToR2);
2925 }
2926 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfNonEquivalentRecord)2927 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentRecord) {
2928   Decl *ToR1;
2929   {
2930     Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
2931     auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
2932         FromTU, cxxRecordDecl(hasName("A")));
2933     ToR1 = Import(FromR, Lang_CXX03);
2934   }
2935   Decl *ToR2;
2936   {
2937     Decl *FromTU =
2938         getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
2939     auto *FromR = FirstDeclMatcher<CXXRecordDecl>().match(
2940         FromTU, cxxRecordDecl(hasName("A")));
2941     ToR2 = Import(FromR, Lang_CXX03);
2942   }
2943   EXPECT_NE(ToR1, ToR2);
2944 }
2945 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfEquivalentField)2946 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentField) {
2947   Decl *ToF1;
2948   {
2949     Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
2950     auto *FromF = FirstDeclMatcher<FieldDecl>().match(
2951         FromTU, fieldDecl(hasName("x")));
2952     ToF1 = Import(FromF, Lang_CXX03);
2953   }
2954   Decl *ToF2;
2955   {
2956     Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input1.cc");
2957     auto *FromF = FirstDeclMatcher<FieldDecl>().match(
2958         FromTU, fieldDecl(hasName("x")));
2959     ToF2 = Import(FromF, Lang_CXX03);
2960   }
2961   EXPECT_EQ(ToF1, ToF2);
2962 }
2963 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfNonEquivalentField)2964 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentField) {
2965   Decl *ToF1;
2966   {
2967     Decl *FromTU = getTuDecl("struct A { int x; };", Lang_CXX03, "input0.cc");
2968     auto *FromF = FirstDeclMatcher<FieldDecl>().match(
2969         FromTU, fieldDecl(hasName("x")));
2970     ToF1 = Import(FromF, Lang_CXX03);
2971   }
2972   Decl *ToF2;
2973   {
2974     Decl *FromTU =
2975         getTuDecl("struct A { unsigned x; };", Lang_CXX03, "input1.cc");
2976     auto *FromF = FirstDeclMatcher<FieldDecl>().match(
2977         FromTU, fieldDecl(hasName("x")));
2978     ToF2 = Import(FromF, Lang_CXX03);
2979   }
2980   EXPECT_NE(ToF1, ToF2);
2981 }
2982 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfEquivalentMethod)2983 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfEquivalentMethod) {
2984   Decl *ToM1;
2985   {
2986     Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
2987                              Lang_CXX03, "input0.cc");
2988     auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
2989         FromTU, functionDecl(hasName("x"), isDefinition()));
2990     ToM1 = Import(FromM, Lang_CXX03);
2991   }
2992   Decl *ToM2;
2993   {
2994     Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
2995                              Lang_CXX03, "input1.cc");
2996     auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
2997         FromTU, functionDecl(hasName("x"), isDefinition()));
2998     ToM2 = Import(FromM, Lang_CXX03);
2999   }
3000   EXPECT_EQ(ToM1, ToM2);
3001 }
3002 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfNonEquivalentMethod)3003 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfNonEquivalentMethod) {
3004   Decl *ToM1;
3005   {
3006     Decl *FromTU = getTuDecl("struct A { void x(); }; void A::x() { }",
3007                              Lang_CXX03, "input0.cc");
3008     auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3009         FromTU, functionDecl(hasName("x"), isDefinition()));
3010     ToM1 = Import(FromM, Lang_CXX03);
3011   }
3012   Decl *ToM2;
3013   {
3014     Decl *FromTU =
3015         getTuDecl("struct A { void x() const; }; void A::x() const { }",
3016                   Lang_CXX03, "input1.cc");
3017     auto *FromM = FirstDeclMatcher<FunctionDecl>().match(
3018         FromTU, functionDecl(hasName("x"), isDefinition()));
3019     ToM2 = Import(FromM, Lang_CXX03);
3020   }
3021   EXPECT_NE(ToM1, ToM2);
3022 }
3023 
TEST_P(ASTImporterOptionSpecificTestBase,ImportUnnamedStructsWithRecursingField)3024 TEST_P(ASTImporterOptionSpecificTestBase,
3025        ImportUnnamedStructsWithRecursingField) {
3026   Decl *FromTU = getTuDecl(
3027       R"(
3028       struct A {
3029         struct {
3030           struct A *next;
3031         } entry0;
3032         struct {
3033           struct A *next;
3034         } entry1;
3035       };
3036       )",
3037       Lang_C99, "input0.cc");
3038   auto *From =
3039       FirstDeclMatcher<RecordDecl>().match(FromTU, recordDecl(hasName("A")));
3040 
3041   Import(From, Lang_C99);
3042 
3043   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3044   auto *Entry0 =
3045       FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry0")));
3046   auto *Entry1 =
3047       FirstDeclMatcher<FieldDecl>().match(ToTU, fieldDecl(hasName("entry1")));
3048   auto *R0 = getRecordDecl(Entry0);
3049   auto *R1 = getRecordDecl(Entry1);
3050   EXPECT_NE(R0, R1);
3051   EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3052       R0, recordDecl(has(fieldDecl(hasName("next"))))));
3053   EXPECT_TRUE(MatchVerifier<RecordDecl>().match(
3054       R1, recordDecl(has(fieldDecl(hasName("next"))))));
3055 }
3056 
TEST_P(ASTImporterOptionSpecificTestBase,ImportUnnamedFieldsInCorrectOrder)3057 TEST_P(ASTImporterOptionSpecificTestBase, ImportUnnamedFieldsInCorrectOrder) {
3058   Decl *FromTU = getTuDecl(
3059       R"(
3060       void f(int X, int Y, bool Z) {
3061         (void)[X, Y, Z] { (void)Z; };
3062       }
3063       )",
3064       Lang_CXX11, "input0.cc");
3065   auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
3066       FromTU, functionDecl(hasName("f")));
3067   auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11));
3068   EXPECT_TRUE(ToF);
3069 
3070   CXXRecordDecl *FromLambda =
3071       cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>(
3072           FromF->getBody())->body_front())->getSubExpr())->getLambdaClass();
3073 
3074   auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11));
3075   EXPECT_TRUE(ToLambda);
3076 
3077   // Check if the fields of the lambda class are imported in correct order.
3078   unsigned FromIndex = 0u;
3079   for (auto *FromField : FromLambda->fields()) {
3080     ASSERT_FALSE(FromField->getDeclName());
3081     auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11));
3082     EXPECT_TRUE(ToField);
3083     Optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField);
3084     EXPECT_TRUE(ToIndex);
3085     EXPECT_EQ(*ToIndex, FromIndex);
3086     ++FromIndex;
3087   }
3088 
3089   EXPECT_EQ(FromIndex, 3u);
3090 }
3091 
TEST_P(ASTImporterOptionSpecificTestBase,MergeFieldDeclsOfClassTemplateSpecialization)3092 TEST_P(ASTImporterOptionSpecificTestBase,
3093        MergeFieldDeclsOfClassTemplateSpecialization) {
3094   std::string ClassTemplate =
3095       R"(
3096       template <typename T>
3097       struct X {
3098           int a{0}; // FieldDecl with InitListExpr
3099           X(char) : a(3) {}     // (1)
3100           X(int) {}             // (2)
3101       };
3102       )";
3103   Decl *ToTU = getToTuDecl(ClassTemplate +
3104       R"(
3105       void foo() {
3106           // ClassTemplateSpec with ctor (1): FieldDecl without InitlistExpr
3107           X<char> xc('c');
3108       }
3109       )", Lang_CXX11);
3110   auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3111       ToTU, classTemplateSpecializationDecl(hasName("X")));
3112   // FieldDecl without InitlistExpr:
3113   auto *ToField = *ToSpec->field_begin();
3114   ASSERT_TRUE(ToField);
3115   ASSERT_FALSE(ToField->getInClassInitializer());
3116   Decl *FromTU = getTuDecl(ClassTemplate +
3117       R"(
3118       void bar() {
3119           // ClassTemplateSpec with ctor (2): FieldDecl WITH InitlistExpr
3120           X<char> xc(1);
3121       }
3122       )", Lang_CXX11);
3123   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3124       FromTU, classTemplateSpecializationDecl(hasName("X")));
3125   // FieldDecl with InitlistExpr:
3126   auto *FromField = *FromSpec->field_begin();
3127   ASSERT_TRUE(FromField);
3128   ASSERT_TRUE(FromField->getInClassInitializer());
3129 
3130   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3131   ASSERT_TRUE(ImportedSpec);
3132   EXPECT_EQ(ImportedSpec, ToSpec);
3133   // After the import, the FieldDecl has to be merged, thus it should have the
3134   // InitListExpr.
3135   EXPECT_TRUE(ToField->getInClassInitializer());
3136 }
3137 
TEST_P(ASTImporterOptionSpecificTestBase,MergeFunctionOfClassTemplateSpecialization)3138 TEST_P(ASTImporterOptionSpecificTestBase,
3139        MergeFunctionOfClassTemplateSpecialization) {
3140   std::string ClassTemplate =
3141       R"(
3142       template <typename T>
3143       struct X {
3144         void f() {}
3145         void g() {}
3146       };
3147       )";
3148   Decl *ToTU = getToTuDecl(ClassTemplate +
3149       R"(
3150       void foo() {
3151           X<char> x;
3152           x.f();
3153       }
3154       )", Lang_CXX11);
3155   Decl *FromTU = getTuDecl(ClassTemplate +
3156       R"(
3157       void bar() {
3158           X<char> x;
3159           x.g();
3160       }
3161       )", Lang_CXX11);
3162   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3163       FromTU, classTemplateSpecializationDecl(hasName("X")));
3164   auto FunPattern = functionDecl(hasName("g"),
3165                          hasParent(classTemplateSpecializationDecl()));
3166   auto *FromFun =
3167       FirstDeclMatcher<FunctionDecl>().match(FromTU, FunPattern);
3168   auto *ToFun =
3169       FirstDeclMatcher<FunctionDecl>().match(ToTU, FunPattern);
3170   ASSERT_TRUE(FromFun->hasBody());
3171   ASSERT_FALSE(ToFun->hasBody());
3172   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3173   ASSERT_TRUE(ImportedSpec);
3174   auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3175       ToTU, classTemplateSpecializationDecl(hasName("X")));
3176   EXPECT_EQ(ImportedSpec, ToSpec);
3177   EXPECT_TRUE(ToFun->hasBody());
3178 }
3179 
TEST_P(ASTImporterOptionSpecificTestBase,MergeTemplateSpecWithForwardDecl)3180 TEST_P(ASTImporterOptionSpecificTestBase, MergeTemplateSpecWithForwardDecl) {
3181   std::string ClassTemplate =
3182       R"(
3183       template<typename T>
3184       struct X { int m; };
3185       template<>
3186       struct X<int> { int m; };
3187       )";
3188   // Append a forward decl for our template specialization.
3189   getToTuDecl(ClassTemplate + "template<> struct X<int>;", Lang_CXX11);
3190   Decl *FromTU = getTuDecl(ClassTemplate, Lang_CXX11);
3191   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3192       FromTU, classTemplateSpecializationDecl(hasName("X"), isDefinition()));
3193   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3194   // Check that our definition got merged with the existing definition.
3195   EXPECT_TRUE(FromSpec->isThisDeclarationADefinition());
3196   EXPECT_TRUE(ImportedSpec->isThisDeclarationADefinition());
3197 }
3198 
TEST_P(ASTImporterOptionSpecificTestBase,ODRViolationOfClassTemplateSpecializationsShouldBeReported)3199 TEST_P(ASTImporterOptionSpecificTestBase,
3200        ODRViolationOfClassTemplateSpecializationsShouldBeReported) {
3201   std::string ClassTemplate =
3202       R"(
3203       template <typename T>
3204       struct X {};
3205       )";
3206   Decl *ToTU = getToTuDecl(ClassTemplate +
3207                                R"(
3208       template <>
3209       struct X<char> {
3210           int a;
3211       };
3212       void foo() {
3213           X<char> x;
3214       }
3215       )",
3216                            Lang_CXX11);
3217   Decl *FromTU = getTuDecl(ClassTemplate +
3218                                R"(
3219       template <>
3220       struct X<char> {
3221           int b;
3222       };
3223       void foo() {
3224           X<char> x;
3225       }
3226       )",
3227                            Lang_CXX11);
3228   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3229       FromTU, classTemplateSpecializationDecl(hasName("X")));
3230   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3231 
3232   // We expect one (ODR) warning during the import.
3233   EXPECT_EQ(1u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
3234 
3235   // The second specialization is different from the first, thus it violates
3236   // ODR, consequently we expect to keep the first specialization only, which is
3237   // already in the "To" context.
3238   EXPECT_FALSE(ImportedSpec);
3239   EXPECT_EQ(1u,
3240             DeclCounter<ClassTemplateSpecializationDecl>().match(
3241                 ToTU, classTemplateSpecializationDecl(hasName("X"))));
3242 }
3243 
TEST_P(ASTImporterOptionSpecificTestBase,MergeCtorOfClassTemplateSpecialization)3244 TEST_P(ASTImporterOptionSpecificTestBase,
3245        MergeCtorOfClassTemplateSpecialization) {
3246   std::string ClassTemplate =
3247       R"(
3248       template <typename T>
3249       struct X {
3250           X(char) {}
3251           X(int) {}
3252       };
3253       )";
3254   Decl *ToTU = getToTuDecl(ClassTemplate +
3255       R"(
3256       void foo() {
3257           X<char> x('c');
3258       }
3259       )", Lang_CXX11);
3260   Decl *FromTU = getTuDecl(ClassTemplate +
3261       R"(
3262       void bar() {
3263           X<char> x(1);
3264       }
3265       )", Lang_CXX11);
3266   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3267       FromTU, classTemplateSpecializationDecl(hasName("X")));
3268   // Match the void(int) ctor.
3269   auto CtorPattern =
3270       cxxConstructorDecl(hasParameter(0, varDecl(hasType(asString("int")))),
3271                          hasParent(classTemplateSpecializationDecl()));
3272   auto *FromCtor =
3273       FirstDeclMatcher<CXXConstructorDecl>().match(FromTU, CtorPattern);
3274   auto *ToCtor =
3275       FirstDeclMatcher<CXXConstructorDecl>().match(ToTU, CtorPattern);
3276   ASSERT_TRUE(FromCtor->hasBody());
3277   ASSERT_FALSE(ToCtor->hasBody());
3278   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3279   ASSERT_TRUE(ImportedSpec);
3280   auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3281       ToTU, classTemplateSpecializationDecl(hasName("X")));
3282   EXPECT_EQ(ImportedSpec, ToSpec);
3283   EXPECT_TRUE(ToCtor->hasBody());
3284 }
3285 
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplateFriendDecl)3286 TEST_P(ASTImporterOptionSpecificTestBase, ClassTemplateFriendDecl) {
3287   const auto *Code =
3288       R"(
3289       template <class T> class X {  friend T; };
3290       struct Y {};
3291       template class X<Y>;
3292     )";
3293   Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3294   Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3295   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3296       FromTU, classTemplateSpecializationDecl());
3297   auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3298       ToTU, classTemplateSpecializationDecl());
3299 
3300   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3301   EXPECT_EQ(ImportedSpec, ToSpec);
3302   EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3303                     ToTU, classTemplateSpecializationDecl()));
3304 }
3305 
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplatePartialSpecializationsShouldNotBeDuplicated)3306 TEST_P(ASTImporterOptionSpecificTestBase,
3307        ClassTemplatePartialSpecializationsShouldNotBeDuplicated) {
3308   auto Code =
3309       R"(
3310     // primary template
3311     template<class T1, class T2, int I>
3312     class A {};
3313 
3314     // partial specialization
3315     template<class T, int I>
3316     class A<T, T*, I> {};
3317     )";
3318   Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3319   Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3320   auto *FromSpec =
3321       FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3322           FromTU, classTemplatePartialSpecializationDecl());
3323   auto *ToSpec =
3324       FirstDeclMatcher<ClassTemplatePartialSpecializationDecl>().match(
3325           ToTU, classTemplatePartialSpecializationDecl());
3326 
3327   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3328   EXPECT_EQ(ImportedSpec, ToSpec);
3329   EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3330                     ToTU, classTemplatePartialSpecializationDecl()));
3331 }
3332 
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplateSpecializationsShouldNotBeDuplicated)3333 TEST_P(ASTImporterOptionSpecificTestBase,
3334        ClassTemplateSpecializationsShouldNotBeDuplicated) {
3335   auto Code =
3336       R"(
3337     // primary template
3338     template<class T1, class T2, int I>
3339     class A {};
3340 
3341     // full specialization
3342     template<>
3343     class A<int, int, 1> {};
3344     )";
3345   Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
3346   Decl *FromTU = getTuDecl(Code, Lang_CXX11);
3347   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3348       FromTU, classTemplateSpecializationDecl());
3349   auto *ToSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3350       ToTU, classTemplateSpecializationDecl());
3351 
3352   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3353   EXPECT_EQ(ImportedSpec, ToSpec);
3354   EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3355                    ToTU, classTemplateSpecializationDecl()));
3356 }
3357 
TEST_P(ASTImporterOptionSpecificTestBase,ClassTemplateFullAndPartialSpecsShouldNotBeMixed)3358 TEST_P(ASTImporterOptionSpecificTestBase,
3359        ClassTemplateFullAndPartialSpecsShouldNotBeMixed) {
3360   std::string PrimaryTemplate =
3361       R"(
3362     template<class T1, class T2, int I>
3363     class A {};
3364     )";
3365   auto PartialSpec =
3366       R"(
3367     template<class T, int I>
3368     class A<T, T*, I> {};
3369     )";
3370   auto FullSpec =
3371       R"(
3372     template<>
3373     class A<int, int, 1> {};
3374     )";
3375   Decl *ToTU = getToTuDecl(PrimaryTemplate + FullSpec, Lang_CXX11);
3376   Decl *FromTU = getTuDecl(PrimaryTemplate + PartialSpec, Lang_CXX11);
3377   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3378       FromTU, classTemplateSpecializationDecl());
3379 
3380   auto *ImportedSpec = Import(FromSpec, Lang_CXX11);
3381   EXPECT_TRUE(ImportedSpec);
3382   // Check the number of partial specializations.
3383   EXPECT_EQ(1u, DeclCounter<ClassTemplatePartialSpecializationDecl>().match(
3384                     ToTU, classTemplatePartialSpecializationDecl()));
3385   // Check the number of full specializations.
3386   EXPECT_EQ(1u, DeclCounter<ClassTemplateSpecializationDecl>().match(
3387                     ToTU, classTemplateSpecializationDecl(
3388                               unless(classTemplatePartialSpecializationDecl()))));
3389 }
3390 
TEST_P(ASTImporterOptionSpecificTestBase,InitListExprValueKindShouldBeImported)3391 TEST_P(ASTImporterOptionSpecificTestBase,
3392        InitListExprValueKindShouldBeImported) {
3393   Decl *TU = getTuDecl(
3394       R"(
3395       const int &init();
3396       void foo() { const int &a{init()}; }
3397       )", Lang_CXX11, "input0.cc");
3398   auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a")));
3399   ASSERT_TRUE(FromD->getAnyInitializer());
3400   auto *InitExpr = FromD->getAnyInitializer();
3401   ASSERT_TRUE(InitExpr);
3402   ASSERT_TRUE(InitExpr->isGLValue());
3403 
3404   auto *ToD = Import(FromD, Lang_CXX11);
3405   EXPECT_TRUE(ToD);
3406   auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer();
3407   EXPECT_TRUE(ToInitExpr);
3408   EXPECT_TRUE(ToInitExpr->isGLValue());
3409 }
3410 
3411 struct ImportVariables : ASTImporterOptionSpecificTestBase {};
3412 
TEST_P(ImportVariables,ImportOfOneDeclBringsInTheWholeChain)3413 TEST_P(ImportVariables, ImportOfOneDeclBringsInTheWholeChain) {
3414   Decl *FromTU = getTuDecl(
3415       R"(
3416       struct A {
3417         static const int a = 1 + 2;
3418       };
3419       const int A::a;
3420       )",
3421       Lang_CXX03, "input1.cc");
3422 
3423   auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3424       FromTU, varDecl(hasName("a"))); // Decl with init
3425   auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3426       FromTU, varDecl(hasName("a"))); // Decl with definition
3427   ASSERT_NE(FromDWithInit, FromDWithDef);
3428   ASSERT_EQ(FromDWithDef->getPreviousDecl(), FromDWithInit);
3429 
3430   auto *ToD0 = cast<VarDecl>(Import(FromDWithInit, Lang_CXX11));
3431   auto *ToD1 = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3432   ASSERT_TRUE(ToD0);
3433   ASSERT_TRUE(ToD1);
3434   EXPECT_NE(ToD0, ToD1);
3435   EXPECT_EQ(ToD1->getPreviousDecl(), ToD0);
3436 }
3437 
TEST_P(ImportVariables,InitAndDefinitionAreInDifferentTUs)3438 TEST_P(ImportVariables, InitAndDefinitionAreInDifferentTUs) {
3439   auto StructA =
3440       R"(
3441       struct A {
3442         static const int a = 1 + 2;
3443       };
3444       )";
3445   Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3446   Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a;", Lang_CXX03,
3447                            "input1.cc");
3448 
3449   auto *FromDWithInit = FirstDeclMatcher<VarDecl>().match(
3450       FromTU, varDecl(hasName("a"))); // Decl with init
3451   auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3452       FromTU, varDecl(hasName("a"))); // Decl with definition
3453   ASSERT_EQ(FromDWithInit, FromDWithDef->getPreviousDecl());
3454   ASSERT_TRUE(FromDWithInit->getInit());
3455   ASSERT_FALSE(FromDWithInit->isThisDeclarationADefinition());
3456   ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3457   ASSERT_FALSE(FromDWithDef->getInit());
3458 
3459   auto *ToD = FirstDeclMatcher<VarDecl>().match(
3460       ToTU, varDecl(hasName("a"))); // Decl with init
3461   ASSERT_TRUE(ToD->getInit());
3462   ASSERT_FALSE(ToD->getDefinition());
3463 
3464   auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3465   EXPECT_TRUE(ImportedD->getAnyInitializer());
3466   EXPECT_TRUE(ImportedD->getDefinition());
3467 }
3468 
TEST_P(ImportVariables,InitAndDefinitionAreInTheFromContext)3469 TEST_P(ImportVariables, InitAndDefinitionAreInTheFromContext) {
3470   auto StructA =
3471       R"(
3472       struct A {
3473         static const int a;
3474       };
3475       )";
3476   Decl *ToTU = getToTuDecl(StructA, Lang_CXX03);
3477   Decl *FromTU = getTuDecl(std::string(StructA) + "const int A::a = 1 + 2;",
3478                            Lang_CXX03, "input1.cc");
3479 
3480   auto *FromDDeclarationOnly = FirstDeclMatcher<VarDecl>().match(
3481       FromTU, varDecl(hasName("a")));
3482   auto *FromDWithDef = LastDeclMatcher<VarDecl>().match(
3483       FromTU, varDecl(hasName("a"))); // Decl with definition and with init.
3484   ASSERT_EQ(FromDDeclarationOnly, FromDWithDef->getPreviousDecl());
3485   ASSERT_FALSE(FromDDeclarationOnly->getInit());
3486   ASSERT_FALSE(FromDDeclarationOnly->isThisDeclarationADefinition());
3487   ASSERT_TRUE(FromDWithDef->isThisDeclarationADefinition());
3488   ASSERT_TRUE(FromDWithDef->getInit());
3489 
3490   auto *ToD = FirstDeclMatcher<VarDecl>().match(
3491       ToTU, varDecl(hasName("a")));
3492   ASSERT_FALSE(ToD->getInit());
3493   ASSERT_FALSE(ToD->getDefinition());
3494 
3495   auto *ImportedD = cast<VarDecl>(Import(FromDWithDef, Lang_CXX11));
3496   EXPECT_TRUE(ImportedD->getAnyInitializer());
3497   EXPECT_TRUE(ImportedD->getDefinition());
3498 }
3499 
3500 struct ImportClasses : ASTImporterOptionSpecificTestBase {};
3501 
TEST_P(ImportClasses,ImportDefinitionWhenProtoIsInNestedToContext)3502 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContext) {
3503   Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_C99);
3504   Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
3505   auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
3506   auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3507   auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
3508 
3509   Decl *ImportedDef = Import(FromDef, Lang_C99);
3510 
3511   EXPECT_NE(ImportedDef, ToProto);
3512   EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
3513   auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3514   EXPECT_TRUE(ImportedDef == ToDef);
3515   EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
3516   EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
3517   EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
3518 }
3519 
TEST_P(ImportClasses,ImportDefinitionWhenProtoIsInNestedToContextCXX)3520 TEST_P(ImportClasses, ImportDefinitionWhenProtoIsInNestedToContextCXX) {
3521   Decl *ToTU = getToTuDecl("struct A { struct X *Xp; };", Lang_CXX03);
3522   Decl *FromTU1 = getTuDecl("struct X {};", Lang_CXX03, "input1.cc");
3523   auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
3524   auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3525   auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
3526 
3527   Decl *ImportedDef = Import(FromDef, Lang_CXX03);
3528 
3529   EXPECT_NE(ImportedDef, ToProto);
3530   EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
3531   auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3532   EXPECT_TRUE(ImportedDef == ToDef);
3533   EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
3534   EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
3535   EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
3536 }
3537 
TEST_P(ImportClasses,ImportNestedPrototypeThenDefinition)3538 TEST_P(ImportClasses, ImportNestedPrototypeThenDefinition) {
3539   Decl *FromTU0 =
3540       getTuDecl("struct A { struct X *Xp; };", Lang_C99, "input0.cc");
3541   Decl *FromTU1 = getTuDecl("struct X {};", Lang_C99, "input1.cc");
3542   auto Pattern = recordDecl(hasName("X"), unless(isImplicit()));
3543   auto FromProto = FirstDeclMatcher<RecordDecl>().match(FromTU0, Pattern);
3544   auto FromDef = FirstDeclMatcher<RecordDecl>().match(FromTU1, Pattern);
3545 
3546   Decl *ImportedProto = Import(FromProto, Lang_C99);
3547   Decl *ImportedDef = Import(FromDef, Lang_C99);
3548   Decl *ToTU = ImportedDef->getTranslationUnitDecl();
3549 
3550   EXPECT_NE(ImportedDef, ImportedProto);
3551   EXPECT_EQ(DeclCounter<RecordDecl>().match(ToTU, Pattern), 2u);
3552   auto ToProto = FirstDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3553   auto ToDef = LastDeclMatcher<RecordDecl>().match(ToTU, Pattern);
3554   EXPECT_TRUE(ImportedDef == ToDef);
3555   EXPECT_TRUE(ImportedProto == ToProto);
3556   EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
3557   EXPECT_FALSE(ToProto->isThisDeclarationADefinition());
3558   EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
3559 }
3560 
3561 
3562 struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {};
3563 
TEST_P(ImportFriendClasses,ImportOfFriendRecordDoesNotMergeDefinition)3564 TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) {
3565   Decl *FromTU = getTuDecl(
3566       R"(
3567       class A {
3568         template <int I> class F {};
3569         class X {
3570           template <int I> friend class F;
3571         };
3572       };
3573       )",
3574       Lang_CXX03, "input0.cc");
3575 
3576   auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match(
3577       FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
3578   auto *FromFriendClass = LastDeclMatcher<CXXRecordDecl>().match(
3579       FromTU, cxxRecordDecl(hasName("F")));
3580 
3581   ASSERT_TRUE(FromClass);
3582   ASSERT_TRUE(FromFriendClass);
3583   ASSERT_NE(FromClass, FromFriendClass);
3584   ASSERT_EQ(FromFriendClass->getDefinition(), FromClass);
3585   ASSERT_EQ(FromFriendClass->getPreviousDecl(), FromClass);
3586   ASSERT_EQ(FromFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
3587             FromClass->getDescribedClassTemplate());
3588 
3589   auto *ToClass = cast<CXXRecordDecl>(Import(FromClass, Lang_CXX03));
3590   auto *ToFriendClass =
3591       cast<CXXRecordDecl>(Import(FromFriendClass, Lang_CXX03));
3592 
3593   EXPECT_TRUE(ToClass);
3594   EXPECT_TRUE(ToFriendClass);
3595   EXPECT_NE(ToClass, ToFriendClass);
3596   EXPECT_EQ(ToFriendClass->getDefinition(), ToClass);
3597   EXPECT_EQ(ToFriendClass->getPreviousDecl(), ToClass);
3598   EXPECT_EQ(ToFriendClass->getDescribedClassTemplate()->getPreviousDecl(),
3599             ToClass->getDescribedClassTemplate());
3600 }
3601 
TEST_P(ImportFriendClasses,ImportOfRecursiveFriendClass)3602 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClass) {
3603   Decl *FromTu = getTuDecl(
3604       R"(
3605       class declToImport {
3606         friend class declToImport;
3607       };
3608       )",
3609       Lang_CXX03, "input.cc");
3610 
3611   auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
3612       FromTu, cxxRecordDecl(hasName("declToImport")));
3613   auto *ToD = Import(FromD, Lang_CXX03);
3614   auto Pattern = cxxRecordDecl(has(friendDecl()));
3615   ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
3616   EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
3617 }
3618 
TEST_P(ImportFriendClasses,UndeclaredFriendClassShouldNotBeVisible)3619 TEST_P(ImportFriendClasses, UndeclaredFriendClassShouldNotBeVisible) {
3620   Decl *FromTu =
3621       getTuDecl("class X { friend class Y; };", Lang_CXX03, "from.cc");
3622   auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
3623       FromTu, cxxRecordDecl(hasName("X")));
3624   auto *FromFriend = FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
3625   RecordDecl *FromRecordOfFriend =
3626       const_cast<RecordDecl *>(getRecordDeclOfFriend(FromFriend));
3627 
3628   ASSERT_EQ(FromRecordOfFriend->getDeclContext(), cast<DeclContext>(FromTu));
3629   ASSERT_EQ(FromRecordOfFriend->getLexicalDeclContext(),
3630             cast<DeclContext>(FromX));
3631   ASSERT_FALSE(
3632       FromRecordOfFriend->getDeclContext()->containsDecl(FromRecordOfFriend));
3633   ASSERT_FALSE(FromRecordOfFriend->getLexicalDeclContext()->containsDecl(
3634       FromRecordOfFriend));
3635   ASSERT_FALSE(FromRecordOfFriend->getLookupParent()
3636                    ->lookup(FromRecordOfFriend->getDeclName())
3637                    .empty());
3638 
3639   auto *ToX = Import(FromX, Lang_CXX03);
3640   ASSERT_TRUE(ToX);
3641 
3642   Decl *ToTu = ToX->getTranslationUnitDecl();
3643   auto *ToFriend = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
3644   RecordDecl *ToRecordOfFriend =
3645       const_cast<RecordDecl *>(getRecordDeclOfFriend(ToFriend));
3646 
3647   ASSERT_EQ(ToRecordOfFriend->getDeclContext(), cast<DeclContext>(ToTu));
3648   ASSERT_EQ(ToRecordOfFriend->getLexicalDeclContext(), cast<DeclContext>(ToX));
3649   EXPECT_FALSE(
3650       ToRecordOfFriend->getDeclContext()->containsDecl(ToRecordOfFriend));
3651   EXPECT_FALSE(ToRecordOfFriend->getLexicalDeclContext()->containsDecl(
3652       ToRecordOfFriend));
3653   EXPECT_FALSE(ToRecordOfFriend->getLookupParent()
3654                    ->lookup(ToRecordOfFriend->getDeclName())
3655                    .empty());
3656 }
3657 
TEST_P(ImportFriendClasses,ImportOfRecursiveFriendClassTemplate)3658 TEST_P(ImportFriendClasses, ImportOfRecursiveFriendClassTemplate) {
3659   Decl *FromTu = getTuDecl(
3660       R"(
3661       template<class A> class declToImport {
3662         template<class A1> friend class declToImport;
3663       };
3664       )",
3665       Lang_CXX03, "input.cc");
3666 
3667   auto *FromD =
3668       FirstDeclMatcher<ClassTemplateDecl>().match(FromTu, classTemplateDecl());
3669   auto *ToD = Import(FromD, Lang_CXX03);
3670 
3671   auto Pattern = classTemplateDecl(
3672       has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
3673   ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
3674   EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
3675 
3676   auto *Class =
3677       FirstDeclMatcher<ClassTemplateDecl>().match(ToD, classTemplateDecl());
3678   auto *Friend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl());
3679   EXPECT_NE(Friend->getFriendDecl(), Class);
3680   EXPECT_EQ(Friend->getFriendDecl()->getPreviousDecl(), Class);
3681 }
3682 
TEST_P(ImportFriendClasses,ProperPrevDeclForClassTemplateDecls)3683 TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) {
3684   auto Pattern = classTemplateSpecializationDecl(hasName("X"));
3685 
3686   ClassTemplateSpecializationDecl *Imported1;
3687   {
3688     Decl *FromTU = getTuDecl("template<class T> class X;"
3689                              "struct Y { friend class X<int>; };",
3690                              Lang_CXX03, "input0.cc");
3691     auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3692         FromTU, Pattern);
3693 
3694     Imported1 =
3695         cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
3696   }
3697   ClassTemplateSpecializationDecl *Imported2;
3698   {
3699     Decl *FromTU = getTuDecl("template<class T> class X;"
3700                              "template<> class X<int>{};"
3701                              "struct Z { friend class X<int>; };",
3702                              Lang_CXX03, "input1.cc");
3703     auto *FromD = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3704         FromTU, Pattern);
3705 
3706     Imported2 =
3707         cast<ClassTemplateSpecializationDecl>(Import(FromD, Lang_CXX03));
3708   }
3709 
3710   Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3711   EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(ToTU, Pattern),
3712             2u);
3713   ASSERT_TRUE(Imported2->getPreviousDecl());
3714   EXPECT_EQ(Imported2->getPreviousDecl(), Imported1);
3715 }
3716 
TEST_P(ImportFriendClasses,TypeForDeclShouldBeSetInTemplated)3717 TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) {
3718   Decl *FromTU0 = getTuDecl(
3719       R"(
3720       class X {
3721         class Y;
3722       };
3723       class X::Y {
3724         template <typename T>
3725         friend class F; // The decl context of F is the global namespace.
3726       };
3727       )",
3728       Lang_CXX03, "input0.cc");
3729   auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
3730       FromTU0, classTemplateDecl(hasName("F")));
3731   auto *Imported0 = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
3732   Decl *FromTU1 = getTuDecl(
3733       R"(
3734       template <typename T>
3735       class F {};
3736       )",
3737       Lang_CXX03, "input1.cc");
3738   auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
3739       FromTU1, classTemplateDecl(hasName("F")));
3740   auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
3741   EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(),
3742             Imported1->getTemplatedDecl()->getTypeForDecl());
3743 }
3744 
TEST_P(ImportFriendClasses,DeclsFromFriendsShouldBeInRedeclChains)3745 TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) {
3746   Decl *From, *To;
3747   std::tie(From, To) =
3748       getImportedDecl("class declToImport {};", Lang_CXX03,
3749                       "class Y { friend class declToImport; };", Lang_CXX03);
3750   auto *Imported = cast<CXXRecordDecl>(To);
3751 
3752   EXPECT_TRUE(Imported->getPreviousDecl());
3753 }
3754 
TEST_P(ImportFriendClasses,ImportOfClassTemplateDefinitionShouldConnectToFwdFriend)3755 TEST_P(ImportFriendClasses,
3756        ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
3757   Decl *ToTU = getToTuDecl(
3758       R"(
3759       class X {
3760         class Y;
3761       };
3762       class X::Y {
3763         template <typename T>
3764         friend class F; // The decl context of F is the global namespace.
3765       };
3766       )",
3767       Lang_CXX03);
3768   auto *ToDecl = FirstDeclMatcher<ClassTemplateDecl>().match(
3769       ToTU, classTemplateDecl(hasName("F")));
3770   Decl *FromTU = getTuDecl(
3771       R"(
3772       template <typename T>
3773       class F {};
3774       )",
3775       Lang_CXX03, "input0.cc");
3776   auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
3777       FromTU, classTemplateDecl(hasName("F")));
3778   auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
3779   EXPECT_TRUE(ImportedDef->getPreviousDecl());
3780   EXPECT_EQ(ToDecl, ImportedDef->getPreviousDecl());
3781   EXPECT_EQ(ToDecl->getTemplatedDecl(),
3782             ImportedDef->getTemplatedDecl()->getPreviousDecl());
3783 }
3784 
TEST_P(ImportFriendClasses,ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked)3785 TEST_P(ImportFriendClasses,
3786        ImportOfClassTemplateDefinitionAndFwdFriendShouldBeLinked) {
3787   Decl *FromTU0 = getTuDecl(
3788       R"(
3789       class X {
3790         class Y;
3791       };
3792       class X::Y {
3793         template <typename T>
3794         friend class F; // The decl context of F is the global namespace.
3795       };
3796       )",
3797       Lang_CXX03, "input0.cc");
3798   auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
3799       FromTU0, classTemplateDecl(hasName("F")));
3800   auto *ImportedFwd = cast<ClassTemplateDecl>(Import(Fwd, Lang_CXX03));
3801   Decl *FromTU1 = getTuDecl(
3802       R"(
3803       template <typename T>
3804       class F {};
3805       )",
3806       Lang_CXX03, "input1.cc");
3807   auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
3808       FromTU1, classTemplateDecl(hasName("F")));
3809   auto *ImportedDef = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
3810   EXPECT_TRUE(ImportedDef->getPreviousDecl());
3811   EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
3812   EXPECT_EQ(ImportedFwd->getTemplatedDecl(),
3813             ImportedDef->getTemplatedDecl()->getPreviousDecl());
3814 }
3815 
TEST_P(ImportFriendClasses,ImportOfClassDefinitionAndFwdFriendShouldBeLinked)3816 TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
3817   Decl *FromTU0 = getTuDecl(
3818       R"(
3819       class X {
3820         class Y;
3821       };
3822       class X::Y {
3823         friend class F; // The decl context of F is the global namespace.
3824       };
3825       )",
3826       Lang_CXX03, "input0.cc");
3827   auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl());
3828   QualType FT = Friend->getFriendType()->getType();
3829   FT = FromTU0->getASTContext().getCanonicalType(FT);
3830   auto *Fwd = cast<TagType>(FT)->getDecl();
3831   auto *ImportedFwd = Import(Fwd, Lang_CXX03);
3832   Decl *FromTU1 = getTuDecl(
3833       R"(
3834       class F {};
3835       )",
3836       Lang_CXX03, "input1.cc");
3837   auto *Definition = FirstDeclMatcher<CXXRecordDecl>().match(
3838       FromTU1, cxxRecordDecl(hasName("F")));
3839   auto *ImportedDef = Import(Definition, Lang_CXX03);
3840   EXPECT_TRUE(ImportedDef->getPreviousDecl());
3841   EXPECT_EQ(ImportedFwd, ImportedDef->getPreviousDecl());
3842 }
3843 
TEST_P(ImportFriendClasses,ImportOfRepeatedFriendType)3844 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendType) {
3845   const char *Code =
3846       R"(
3847       class Container {
3848         friend class X;
3849         friend class X;
3850       };
3851       )";
3852   Decl *ToTu = getToTuDecl(Code, Lang_CXX03);
3853   Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc");
3854 
3855   auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
3856   auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
3857   auto *FromFriend1 =
3858       FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
3859   auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
3860 
3861   FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03);
3862   FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03);
3863 
3864   EXPECT_NE(ToImportedFriend1, ToImportedFriend2);
3865   EXPECT_EQ(ToFriend1, ToImportedFriend1);
3866   EXPECT_EQ(ToFriend2, ToImportedFriend2);
3867 }
3868 
TEST_P(ImportFriendClasses,ImportOfRepeatedFriendDecl)3869 TEST_P(ImportFriendClasses, ImportOfRepeatedFriendDecl) {
3870   const char *Code =
3871       R"(
3872       class Container {
3873         friend void f();
3874         friend void f();
3875       };
3876       )";
3877   Decl *ToTu = getToTuDecl(Code, Lang_CXX03);
3878   Decl *FromTu = getTuDecl(Code, Lang_CXX03, "from.cc");
3879 
3880   auto *ToFriend1 = FirstDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
3881   auto *ToFriend2 = LastDeclMatcher<FriendDecl>().match(ToTu, friendDecl());
3882   auto *FromFriend1 =
3883       FirstDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
3884   auto *FromFriend2 = LastDeclMatcher<FriendDecl>().match(FromTu, friendDecl());
3885 
3886   FriendDecl *ToImportedFriend1 = Import(FromFriend1, Lang_CXX03);
3887   FriendDecl *ToImportedFriend2 = Import(FromFriend2, Lang_CXX03);
3888 
3889   EXPECT_NE(ToImportedFriend1, ToImportedFriend2);
3890   EXPECT_EQ(ToFriend1, ToImportedFriend1);
3891   EXPECT_EQ(ToFriend2, ToImportedFriend2);
3892 }
3893 
TEST_P(ASTImporterOptionSpecificTestBase,FriendFunInClassTemplate)3894 TEST_P(ASTImporterOptionSpecificTestBase, FriendFunInClassTemplate) {
3895   auto *Code = R"(
3896   template <class T>
3897   struct X {
3898     friend void foo(){}
3899   };
3900       )";
3901   TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
3902   auto *ToFoo = FirstDeclMatcher<FunctionDecl>().match(
3903       ToTU, functionDecl(hasName("foo")));
3904 
3905   TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
3906   auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
3907       FromTU, functionDecl(hasName("foo")));
3908   auto *ImportedFoo = Import(FromFoo, Lang_CXX03);
3909   EXPECT_EQ(ImportedFoo, ToFoo);
3910 }
3911 
3912 struct DeclContextTest : ASTImporterOptionSpecificTestBase {};
3913 
TEST_P(DeclContextTest,removeDeclOfClassTemplateSpecialization)3914 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
3915   Decl *TU = getTuDecl(
3916       R"(
3917       namespace NS {
3918 
3919       template <typename T>
3920       struct S {};
3921       template struct S<int>;
3922 
3923       inline namespace INS {
3924         template <typename T>
3925         struct S {};
3926         template struct S<int>;
3927       }
3928 
3929       }
3930       )", Lang_CXX11, "input0.cc");
3931   auto *NS = FirstDeclMatcher<NamespaceDecl>().match(
3932       TU, namespaceDecl());
3933   auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
3934       TU, classTemplateSpecializationDecl());
3935   ASSERT_TRUE(NS->containsDecl(Spec));
3936 
3937   NS->removeDecl(Spec);
3938   EXPECT_FALSE(NS->containsDecl(Spec));
3939 }
3940 
TEST_P(DeclContextTest,removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage)3941 TEST_P(DeclContextTest,
3942        removeDeclShouldNotFailEvenIfWeHaveExternalVisibleStorage) {
3943   Decl *TU = getTuDecl("extern int A; int A;", Lang_CXX03);
3944   auto *A0 = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
3945   auto *A1 = LastDeclMatcher<VarDecl>().match(TU, varDecl(hasName("A")));
3946 
3947   // Investigate the list.
3948   auto *DC = A0->getDeclContext();
3949   ASSERT_TRUE(DC->containsDecl(A0));
3950   ASSERT_TRUE(DC->containsDecl(A1));
3951 
3952   // Investigate the lookup table.
3953   auto *Map = DC->getLookupPtr();
3954   ASSERT_TRUE(Map);
3955   auto I = Map->find(A0->getDeclName());
3956   ASSERT_NE(I, Map->end());
3957   StoredDeclsList &L = I->second;
3958   // The lookup table contains the most recent decl of A.
3959   ASSERT_NE(L.getAsDecl(), A0);
3960   ASSERT_EQ(L.getAsDecl(), A1);
3961 
3962   ASSERT_TRUE(L.getAsDecl());
3963   // Simulate the private function DeclContext::reconcileExternalVisibleStorage.
3964   // The point here is to have a Vec with only one element, which is not the
3965   // one we are going to delete from the DC later.
3966   L.setHasExternalDecls();
3967   ASSERT_TRUE(L.getAsVector());
3968   ASSERT_EQ(1u, L.getAsVector()->size());
3969 
3970   // This asserts in the old implementation.
3971   DC->removeDecl(A0);
3972   EXPECT_FALSE(DC->containsDecl(A0));
3973 }
3974 
3975 struct ImportFunctionTemplateSpecializations
3976     : ASTImporterOptionSpecificTestBase {};
3977 
TEST_P(ImportFunctionTemplateSpecializations,TUshouldNotContainFunctionTemplateImplicitInstantiation)3978 TEST_P(ImportFunctionTemplateSpecializations,
3979        TUshouldNotContainFunctionTemplateImplicitInstantiation) {
3980 
3981   Decl *FromTU = getTuDecl(
3982       R"(
3983       template<class T>
3984       int f() { return 0; }
3985       void foo() { f<int>(); }
3986       )",
3987       Lang_CXX03, "input0.cc");
3988 
3989   // Check that the function template instantiation is NOT the child of the TU.
3990   auto Pattern = translationUnitDecl(
3991       unless(has(functionDecl(hasName("f"), isTemplateInstantiation()))));
3992   ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
3993 
3994   auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
3995       FromTU, functionDecl(hasName("foo")));
3996   ASSERT_TRUE(Import(Foo, Lang_CXX03));
3997 
3998   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
3999   EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4000 }
4001 
TEST_P(ImportFunctionTemplateSpecializations,TUshouldNotContainFunctionTemplateExplicitInstantiation)4002 TEST_P(ImportFunctionTemplateSpecializations,
4003        TUshouldNotContainFunctionTemplateExplicitInstantiation) {
4004 
4005   Decl *FromTU = getTuDecl(
4006       R"(
4007       template<class T>
4008       int f() { return 0; }
4009       template int f<int>();
4010       )",
4011       Lang_CXX03, "input0.cc");
4012 
4013   // Check that the function template instantiation is NOT the child of the TU.
4014   auto Instantiation = functionDecl(hasName("f"), isTemplateInstantiation());
4015   auto Pattern = translationUnitDecl(unless(has(Instantiation)));
4016   ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4017 
4018   ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Instantiation),
4019                      Lang_CXX03));
4020 
4021   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4022   EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4023 }
4024 
TEST_P(ImportFunctionTemplateSpecializations,TUshouldContainFunctionTemplateSpecialization)4025 TEST_P(ImportFunctionTemplateSpecializations,
4026        TUshouldContainFunctionTemplateSpecialization) {
4027 
4028   Decl *FromTU = getTuDecl(
4029       R"(
4030       template<class T>
4031       int f() { return 0; }
4032       template <> int f<int>() { return 4; }
4033       )",
4034       Lang_CXX03, "input0.cc");
4035 
4036   // Check that the function template specialization is the child of the TU.
4037   auto Specialization =
4038       functionDecl(hasName("f"), isExplicitTemplateSpecialization());
4039   auto Pattern = translationUnitDecl(has(Specialization));
4040   ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromTU, Pattern));
4041 
4042   ASSERT_TRUE(Import(FirstDeclMatcher<Decl>().match(FromTU, Specialization),
4043                      Lang_CXX03));
4044 
4045   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4046   EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToTU, Pattern));
4047 }
4048 
TEST_P(ImportFunctionTemplateSpecializations,FunctionTemplateSpecializationRedeclChain)4049 TEST_P(ImportFunctionTemplateSpecializations,
4050        FunctionTemplateSpecializationRedeclChain) {
4051 
4052   Decl *FromTU = getTuDecl(
4053       R"(
4054       template<class T>
4055       int f() { return 0; }
4056       template <> int f<int>() { return 4; }
4057       )",
4058       Lang_CXX03, "input0.cc");
4059 
4060   auto Spec = functionDecl(hasName("f"), isExplicitTemplateSpecialization(),
4061                            hasParent(translationUnitDecl()));
4062   auto *FromSpecD = FirstDeclMatcher<Decl>().match(FromTU, Spec);
4063   {
4064     auto *TU = FromTU;
4065     auto *SpecD = FromSpecD;
4066     auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4067         TU, functionTemplateDecl());
4068     auto *FirstSpecD = *(TemplateD->spec_begin());
4069     ASSERT_EQ(SpecD, FirstSpecD);
4070     ASSERT_TRUE(SpecD->getPreviousDecl());
4071     ASSERT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4072                      ->doesThisDeclarationHaveABody());
4073   }
4074 
4075   ASSERT_TRUE(Import(FromSpecD, Lang_CXX03));
4076 
4077   {
4078     auto *TU = ToAST->getASTContext().getTranslationUnitDecl();
4079     auto *SpecD = FirstDeclMatcher<Decl>().match(TU, Spec);
4080     auto *TemplateD = FirstDeclMatcher<FunctionTemplateDecl>().match(
4081         TU, functionTemplateDecl());
4082     auto *FirstSpecD = *(TemplateD->spec_begin());
4083     EXPECT_EQ(SpecD, FirstSpecD);
4084     ASSERT_TRUE(SpecD->getPreviousDecl());
4085     EXPECT_FALSE(cast<FunctionDecl>(SpecD->getPreviousDecl())
4086                      ->doesThisDeclarationHaveABody());
4087   }
4088 }
4089 
TEST_P(ImportFunctionTemplateSpecializations,MatchNumberOfFunctionTemplateSpecializations)4090 TEST_P(ImportFunctionTemplateSpecializations,
4091        MatchNumberOfFunctionTemplateSpecializations) {
4092 
4093   Decl *FromTU = getTuDecl(
4094       R"(
4095       template <typename T> constexpr int f() { return 0; }
4096       template <> constexpr int f<int>() { return 4; }
4097       void foo() {
4098         static_assert(f<char>() == 0, "");
4099         static_assert(f<int>() == 4, "");
4100       }
4101       )",
4102       Lang_CXX11, "input0.cc");
4103   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
4104       FromTU, functionDecl(hasName("foo")));
4105 
4106   Import(FromD, Lang_CXX11);
4107   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4108   EXPECT_EQ(
4109       DeclCounter<FunctionDecl>().match(FromTU, functionDecl(hasName("f"))),
4110       DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))));
4111 }
4112 
TEST_P(ASTImporterOptionSpecificTestBase,ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined)4113 TEST_P(ASTImporterOptionSpecificTestBase,
4114     ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
4115   {
4116     Decl *FromTU = getTuDecl(
4117         R"(
4118             template <typename T>
4119             struct B;
4120             )",
4121         Lang_CXX03, "input0.cc");
4122     auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
4123         FromTU, classTemplateDecl(hasName("B")));
4124 
4125     Import(FromD, Lang_CXX03);
4126   }
4127 
4128   {
4129     Decl *FromTU = getTuDecl(
4130         R"(
4131             template <typename T>
4132             struct B {
4133               void f();
4134               B* b;
4135             };
4136             )",
4137         Lang_CXX03, "input1.cc");
4138     FunctionDecl *FromD = FirstDeclMatcher<FunctionDecl>().match(
4139         FromTU, functionDecl(hasName("f")));
4140     Import(FromD, Lang_CXX03);
4141     auto *FromCTD = FirstDeclMatcher<ClassTemplateDecl>().match(
4142         FromTU, classTemplateDecl(hasName("B")));
4143     auto *ToCTD = cast<ClassTemplateDecl>(Import(FromCTD, Lang_CXX03));
4144     EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
4145 
4146     // We expect no (ODR) warning during the import.
4147     auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4148     EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
4149   }
4150 }
4151 
TEST_P(ASTImporterOptionSpecificTestBase,ImportingTypedefShouldImportTheCompleteType)4152 TEST_P(ASTImporterOptionSpecificTestBase,
4153        ImportingTypedefShouldImportTheCompleteType) {
4154   // We already have an incomplete underlying type in the "To" context.
4155   auto Code =
4156       R"(
4157       template <typename T>
4158       struct S {
4159         void foo();
4160       };
4161       using U = S<int>;
4162       )";
4163   Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
4164   auto *ToD = FirstDeclMatcher<TypedefNameDecl>().match(ToTU,
4165       typedefNameDecl(hasName("U")));
4166   ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType());
4167 
4168   // The "From" context has the same typedef, but the underlying type is
4169   // complete this time.
4170   Decl *FromTU = getTuDecl(std::string(Code) +
4171       R"(
4172       void foo(U* u) {
4173         u->foo();
4174       }
4175       )", Lang_CXX11);
4176   auto *FromD = FirstDeclMatcher<TypedefNameDecl>().match(FromTU,
4177       typedefNameDecl(hasName("U")));
4178   ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType());
4179 
4180   // The imported type should be complete.
4181   auto *ImportedD = cast<TypedefNameDecl>(Import(FromD, Lang_CXX11));
4182   EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType());
4183 }
4184 
TEST_P(ASTImporterOptionSpecificTestBase,ImportTemplateParameterLists)4185 TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) {
4186   auto Code =
4187       R"(
4188       template<class T>
4189       int f() { return 0; }
4190       template <> int f<int>() { return 4; }
4191       )";
4192 
4193   Decl *FromTU = getTuDecl(Code, Lang_CXX03);
4194   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(FromTU,
4195       functionDecl(hasName("f"), isExplicitTemplateSpecialization()));
4196   ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1u);
4197 
4198   auto *ToD = Import(FromD, Lang_CXX03);
4199   // The template parameter list should exist.
4200   EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1u);
4201 }
4202 
4203 struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {};
4204 
TEST_P(ASTImporterLookupTableTest,OneDecl)4205 TEST_P(ASTImporterLookupTableTest, OneDecl) {
4206   auto *ToTU = getToTuDecl("int a;", Lang_CXX03);
4207   auto *D = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("a")));
4208   ASTImporterLookupTable LT(*ToTU);
4209   auto Res = LT.lookup(ToTU, D->getDeclName());
4210   ASSERT_EQ(Res.size(), 1u);
4211   EXPECT_EQ(*Res.begin(), D);
4212 }
4213 
findInDeclListOfDC(DeclContext * DC,DeclarationName Name)4214 static Decl *findInDeclListOfDC(DeclContext *DC, DeclarationName Name) {
4215   for (Decl *D : DC->decls()) {
4216     if (auto *ND = dyn_cast<NamedDecl>(D))
4217       if (ND->getDeclName() == Name)
4218         return ND;
4219   }
4220   return nullptr;
4221 }
4222 
TEST_P(ASTImporterLookupTableTest,FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup)4223 TEST_P(ASTImporterLookupTableTest,
4224     FriendWhichIsnotFoundByNormalLookupShouldBeFoundByImporterSpecificLookup) {
4225   auto *Code = R"(
4226   template <class T>
4227   struct X {
4228     friend void foo(){}
4229   };
4230       )";
4231   TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
4232   auto *X = FirstDeclMatcher<ClassTemplateDecl>().match(
4233       ToTU, classTemplateDecl(hasName("X")));
4234   auto *Foo = FirstDeclMatcher<FunctionDecl>().match(
4235       ToTU, functionDecl(hasName("foo")));
4236   DeclContext *FooDC = Foo->getDeclContext();
4237   DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
4238   ASSERT_EQ(cast<Decl>(FooLexicalDC), X->getTemplatedDecl());
4239   ASSERT_EQ(cast<Decl>(FooDC), ToTU);
4240   DeclarationName FooName = Foo->getDeclName();
4241 
4242   // Cannot find in the LookupTable of its DC (TUDecl)
4243   SmallVector<NamedDecl *, 2> FoundDecls;
4244   FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4245   EXPECT_EQ(FoundDecls.size(), 0u);
4246 
4247   // Cannot find in the LookupTable of its LexicalDC (X)
4248   FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4249   EXPECT_EQ(FoundDecls.size(), 0u);
4250 
4251   // Can't find in the list of Decls of the DC.
4252   EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
4253 
4254   // Can't find in the list of Decls of the LexicalDC
4255   EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), nullptr);
4256 
4257   // ASTImporter specific lookup finds it.
4258   ASTImporterLookupTable LT(*ToTU);
4259   auto Res = LT.lookup(FooDC, Foo->getDeclName());
4260   ASSERT_EQ(Res.size(), 1u);
4261   EXPECT_EQ(*Res.begin(), Foo);
4262 }
4263 
TEST_P(ASTImporterLookupTableTest,FwdDeclStructShouldBeFoundByImporterSpecificLookup)4264 TEST_P(ASTImporterLookupTableTest,
4265        FwdDeclStructShouldBeFoundByImporterSpecificLookup) {
4266   TranslationUnitDecl *ToTU =
4267       getToTuDecl("struct A { struct Foo *p; };", Lang_C99);
4268   auto *Foo =
4269       FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("Foo")));
4270   auto *A =
4271       FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
4272   DeclContext *FooDC = Foo->getDeclContext();
4273   DeclContext *FooLexicalDC = Foo->getLexicalDeclContext();
4274   ASSERT_EQ(cast<Decl>(FooLexicalDC), A);
4275   ASSERT_EQ(cast<Decl>(FooDC), ToTU);
4276   DeclarationName FooName = Foo->getDeclName();
4277 
4278   // Cannot find in the LookupTable of its DC (TUDecl).
4279   SmallVector<NamedDecl *, 2> FoundDecls;
4280   FooDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4281   EXPECT_EQ(FoundDecls.size(), 0u);
4282 
4283   // Cannot find in the LookupTable of its LexicalDC (A).
4284   FooLexicalDC->getRedeclContext()->localUncachedLookup(FooName, FoundDecls);
4285   EXPECT_EQ(FoundDecls.size(), 0u);
4286 
4287   // Can't find in the list of Decls of the DC.
4288   EXPECT_EQ(findInDeclListOfDC(FooDC, FooName), nullptr);
4289 
4290   // Can find in the list of Decls of the LexicalDC.
4291   EXPECT_EQ(findInDeclListOfDC(FooLexicalDC, FooName), Foo);
4292 
4293   // ASTImporter specific lookup finds it.
4294   ASTImporterLookupTable LT(*ToTU);
4295   auto Res = LT.lookup(FooDC, Foo->getDeclName());
4296   ASSERT_EQ(Res.size(), 1u);
4297   EXPECT_EQ(*Res.begin(), Foo);
4298 }
4299 
TEST_P(ASTImporterLookupTableTest,LookupFindsNamesInDifferentDC)4300 TEST_P(ASTImporterLookupTableTest, LookupFindsNamesInDifferentDC) {
4301   TranslationUnitDecl *ToTU =
4302       getToTuDecl("int V; struct A { int V; }; struct B { int V; };", Lang_C99);
4303   DeclarationName VName = FirstDeclMatcher<VarDecl>()
4304                               .match(ToTU, varDecl(hasName("V")))
4305                               ->getDeclName();
4306   auto *A =
4307       FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("A")));
4308   auto *B =
4309       FirstDeclMatcher<RecordDecl>().match(ToTU, recordDecl(hasName("B")));
4310 
4311   ASTImporterLookupTable LT(*ToTU);
4312 
4313   auto Res = LT.lookup(cast<DeclContext>(A), VName);
4314   ASSERT_EQ(Res.size(), 1u);
4315   EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
4316                         ToTU, fieldDecl(hasName("V"),
4317                                         hasParent(recordDecl(hasName("A"))))));
4318   Res = LT.lookup(cast<DeclContext>(B), VName);
4319   ASSERT_EQ(Res.size(), 1u);
4320   EXPECT_EQ(*Res.begin(), FirstDeclMatcher<FieldDecl>().match(
4321                         ToTU, fieldDecl(hasName("V"),
4322                                         hasParent(recordDecl(hasName("B"))))));
4323   Res = LT.lookup(ToTU, VName);
4324   ASSERT_EQ(Res.size(), 1u);
4325   EXPECT_EQ(*Res.begin(), FirstDeclMatcher<VarDecl>().match(
4326                         ToTU, varDecl(hasName("V"),
4327                                         hasParent(translationUnitDecl()))));
4328 }
4329 
TEST_P(ASTImporterLookupTableTest,LookupFindsOverloadedNames)4330 TEST_P(ASTImporterLookupTableTest, LookupFindsOverloadedNames) {
4331   TranslationUnitDecl *ToTU = getToTuDecl(
4332       R"(
4333       void foo();
4334       void foo(int);
4335       void foo(int, int);
4336       )",
4337       Lang_CXX03);
4338 
4339   ASTImporterLookupTable LT(*ToTU);
4340   auto *F0 = FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
4341   auto *F2 = LastDeclMatcher<FunctionDecl>().match(ToTU, functionDecl());
4342   DeclarationName Name = F0->getDeclName();
4343   auto Res = LT.lookup(ToTU, Name);
4344   EXPECT_EQ(Res.size(), 3u);
4345   EXPECT_EQ(Res.count(F0), 1u);
4346   EXPECT_EQ(Res.count(F2), 1u);
4347 }
4348 
TEST_P(ASTImporterLookupTableTest,DifferentOperatorsShouldHaveDifferentResultSet)4349 TEST_P(ASTImporterLookupTableTest,
4350        DifferentOperatorsShouldHaveDifferentResultSet) {
4351   TranslationUnitDecl *ToTU = getToTuDecl(
4352       R"(
4353       struct X{};
4354       void operator+(X, X);
4355       void operator-(X, X);
4356       )",
4357       Lang_CXX03);
4358 
4359   ASTImporterLookupTable LT(*ToTU);
4360   auto *FPlus = FirstDeclMatcher<FunctionDecl>().match(
4361       ToTU, functionDecl(hasOverloadedOperatorName("+")));
4362   auto *FMinus = FirstDeclMatcher<FunctionDecl>().match(
4363       ToTU, functionDecl(hasOverloadedOperatorName("-")));
4364   DeclarationName NamePlus = FPlus->getDeclName();
4365   auto ResPlus = LT.lookup(ToTU, NamePlus);
4366   EXPECT_EQ(ResPlus.size(), 1u);
4367   EXPECT_EQ(ResPlus.count(FPlus), 1u);
4368   EXPECT_EQ(ResPlus.count(FMinus), 0u);
4369   DeclarationName NameMinus = FMinus->getDeclName();
4370   auto ResMinus = LT.lookup(ToTU, NameMinus);
4371   EXPECT_EQ(ResMinus.size(), 1u);
4372   EXPECT_EQ(ResMinus.count(FMinus), 1u);
4373   EXPECT_EQ(ResMinus.count(FPlus), 0u);
4374   EXPECT_NE(*ResMinus.begin(), *ResPlus.begin());
4375 }
4376 
TEST_P(ASTImporterLookupTableTest,LookupDeclNamesFromDifferentTUs)4377 TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) {
4378   TranslationUnitDecl *ToTU = getToTuDecl(
4379       R"(
4380       struct X {};
4381       void operator+(X, X);
4382       )",
4383       Lang_CXX03);
4384   auto *ToPlus = FirstDeclMatcher<FunctionDecl>().match(
4385       ToTU, functionDecl(hasOverloadedOperatorName("+")));
4386 
4387   Decl *FromTU = getTuDecl(
4388       R"(
4389       struct X {};
4390       void operator+(X, X);
4391       )",
4392       Lang_CXX03);
4393   auto *FromPlus = FirstDeclMatcher<FunctionDecl>().match(
4394       FromTU, functionDecl(hasOverloadedOperatorName("+")));
4395 
4396   // FromPlus have a different TU, thus its DeclarationName is different too.
4397   ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName());
4398 
4399   ASTImporterLookupTable LT(*ToTU);
4400   auto Res = LT.lookup(ToTU, ToPlus->getDeclName());
4401   ASSERT_EQ(Res.size(), 1u);
4402   EXPECT_EQ(*Res.begin(), ToPlus);
4403 
4404   // FromPlus have a different TU, thus its DeclarationName is different too.
4405   Res = LT.lookup(ToTU, FromPlus->getDeclName());
4406   ASSERT_EQ(Res.size(), 0u);
4407 }
4408 
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendClassDeclWithElaboratedType)4409 TEST_P(ASTImporterLookupTableTest,
4410        LookupFindsFwdFriendClassDeclWithElaboratedType) {
4411   TranslationUnitDecl *ToTU = getToTuDecl(
4412       R"(
4413       class Y { friend class F; };
4414       )",
4415       Lang_CXX03);
4416 
4417   // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
4418   // So we must dig up the underlying CXXRecordDecl.
4419   ASTImporterLookupTable LT(*ToTU);
4420   auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
4421   const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
4422   auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(
4423       ToTU, cxxRecordDecl(hasName("Y")));
4424 
4425   DeclarationName Name = RD->getDeclName();
4426   auto Res = LT.lookup(ToTU, Name);
4427   EXPECT_EQ(Res.size(), 1u);
4428   EXPECT_EQ(*Res.begin(), RD);
4429 
4430   Res = LT.lookup(Y, Name);
4431   EXPECT_EQ(Res.size(), 0u);
4432 }
4433 
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendClassDeclWithUnelaboratedType)4434 TEST_P(ASTImporterLookupTableTest,
4435        LookupFindsFwdFriendClassDeclWithUnelaboratedType) {
4436   TranslationUnitDecl *ToTU = getToTuDecl(
4437       R"(
4438       class F;
4439       class Y { friend F; };
4440       )",
4441       Lang_CXX11);
4442 
4443   // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
4444   // So we must dig up the underlying CXXRecordDecl.
4445   ASTImporterLookupTable LT(*ToTU);
4446   auto *FriendD = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
4447   const RecordDecl *RD = getRecordDeclOfFriend(FriendD);
4448   auto *Y = FirstDeclMatcher<CXXRecordDecl>().match(ToTU, cxxRecordDecl(hasName("Y")));
4449 
4450   DeclarationName Name = RD->getDeclName();
4451   auto Res = LT.lookup(ToTU, Name);
4452   EXPECT_EQ(Res.size(), 1u);
4453   EXPECT_EQ(*Res.begin(), RD);
4454 
4455   Res = LT.lookup(Y, Name);
4456   EXPECT_EQ(Res.size(), 0u);
4457 }
4458 
TEST_P(ASTImporterLookupTableTest,LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert)4459 TEST_P(ASTImporterLookupTableTest,
4460        LookupFindsFriendClassDeclWithTypeAliasDoesNotAssert) {
4461   TranslationUnitDecl *ToTU = getToTuDecl(
4462       R"(
4463       class F;
4464       using alias_of_f = F;
4465       class Y { friend alias_of_f; };
4466       )",
4467       Lang_CXX11);
4468 
4469   // ASTImporterLookupTable constructor handles using declarations correctly,
4470   // no assert is expected.
4471   ASTImporterLookupTable LT(*ToTU);
4472 
4473   auto *Alias = FirstDeclMatcher<TypeAliasDecl>().match(
4474       ToTU, typeAliasDecl(hasName("alias_of_f")));
4475   DeclarationName Name = Alias->getDeclName();
4476   auto Res = LT.lookup(ToTU, Name);
4477   EXPECT_EQ(Res.count(Alias), 1u);
4478 }
4479 
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendClassTemplateDecl)4480 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassTemplateDecl) {
4481   TranslationUnitDecl *ToTU = getToTuDecl(
4482       R"(
4483       class Y { template <class T> friend class F; };
4484       )",
4485       Lang_CXX03);
4486 
4487   ASTImporterLookupTable LT(*ToTU);
4488   auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
4489       ToTU, classTemplateDecl(hasName("F")));
4490   DeclarationName Name = F->getDeclName();
4491   auto Res = LT.lookup(ToTU, Name);
4492   EXPECT_EQ(Res.size(), 2u);
4493   EXPECT_EQ(Res.count(F), 1u);
4494   EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
4495 }
4496 
TEST_P(ASTImporterLookupTableTest,DependentFriendClass)4497 TEST_P(ASTImporterLookupTableTest, DependentFriendClass) {
4498   TranslationUnitDecl *ToTU = getToTuDecl(
4499       R"(
4500       template <typename T>
4501       class F;
4502 
4503       template <typename T>
4504       class Y {
4505         friend class F<T>;
4506       };
4507       )",
4508       Lang_CXX03);
4509 
4510   ASTImporterLookupTable LT(*ToTU);
4511   auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
4512       ToTU, classTemplateDecl(hasName("F")));
4513   DeclarationName Name = F->getDeclName();
4514   auto Res = LT.lookup(ToTU, Name);
4515   EXPECT_EQ(Res.size(), 2u);
4516   EXPECT_EQ(Res.count(F), 1u);
4517   EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
4518 }
4519 
TEST_P(ASTImporterLookupTableTest,FriendClassTemplateSpecialization)4520 TEST_P(ASTImporterLookupTableTest, FriendClassTemplateSpecialization) {
4521   TranslationUnitDecl *ToTU = getToTuDecl(
4522       R"(
4523       template <typename T>
4524       class F;
4525 
4526       class Y {
4527         friend class F<int>;
4528       };
4529       )",
4530       Lang_CXX03);
4531 
4532   ASTImporterLookupTable LT(*ToTU);
4533   auto *F = FirstDeclMatcher<ClassTemplateDecl>().match(
4534       ToTU, classTemplateDecl(hasName("F")));
4535   DeclarationName Name = F->getDeclName();
4536   auto Res = LT.lookup(ToTU, Name);
4537   ASSERT_EQ(Res.size(), 3u);
4538   EXPECT_EQ(Res.count(F), 1u);
4539   EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
4540   EXPECT_EQ(Res.count(*F->spec_begin()), 1u);
4541 }
4542 
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendFunctionDecl)4543 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionDecl) {
4544   TranslationUnitDecl *ToTU = getToTuDecl(
4545       R"(
4546       class Y { friend void F(); };
4547       )",
4548       Lang_CXX03);
4549 
4550   ASTImporterLookupTable LT(*ToTU);
4551   auto *F =
4552       FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("F")));
4553   DeclarationName Name = F->getDeclName();
4554   auto Res = LT.lookup(ToTU, Name);
4555   EXPECT_EQ(Res.size(), 1u);
4556   EXPECT_EQ(*Res.begin(), F);
4557 }
4558 
TEST_P(ASTImporterLookupTableTest,LookupFindsDeclsInClassTemplateSpecialization)4559 TEST_P(ASTImporterLookupTableTest,
4560        LookupFindsDeclsInClassTemplateSpecialization) {
4561   TranslationUnitDecl *ToTU = getToTuDecl(
4562       R"(
4563       template <typename T>
4564       struct X {
4565         int F;
4566       };
4567       void foo() {
4568         X<char> xc;
4569       }
4570       )",
4571       Lang_CXX03);
4572 
4573   ASTImporterLookupTable LT(*ToTU);
4574 
4575   auto *Template = FirstDeclMatcher<ClassTemplateDecl>().match(
4576       ToTU, classTemplateDecl(hasName("X")));
4577   auto *FieldInTemplate = FirstDeclMatcher<FieldDecl>().match(
4578       ToTU,
4579       fieldDecl(hasParent(cxxRecordDecl(hasParent(classTemplateDecl())))));
4580 
4581   auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4582       ToTU, classTemplateSpecializationDecl(hasName("X")));
4583   FieldDecl *FieldInSpec = *Spec->field_begin();
4584   ASSERT_TRUE(FieldInSpec);
4585 
4586   DeclarationName Name = FieldInSpec->getDeclName();
4587   auto TemplateDC = cast<DeclContext>(Template->getTemplatedDecl());
4588 
4589   SmallVector<NamedDecl *, 2> FoundDecls;
4590   TemplateDC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
4591   EXPECT_EQ(FoundDecls.size(), 1u);
4592   EXPECT_EQ(FoundDecls[0], FieldInTemplate);
4593 
4594   auto Res = LT.lookup(TemplateDC, Name);
4595   ASSERT_EQ(Res.size(), 1u);
4596   EXPECT_EQ(*Res.begin(), FieldInTemplate);
4597 
4598   cast<DeclContext>(Spec)->getRedeclContext()->localUncachedLookup(Name,
4599                                                                    FoundDecls);
4600   EXPECT_EQ(FoundDecls.size(), 1u);
4601   EXPECT_EQ(FoundDecls[0], FieldInSpec);
4602 
4603   Res = LT.lookup(cast<DeclContext>(Spec), Name);
4604   ASSERT_EQ(Res.size(), 1u);
4605   EXPECT_EQ(*Res.begin(), FieldInSpec);
4606 }
4607 
TEST_P(ASTImporterLookupTableTest,LookupFindsFwdFriendFunctionTemplateDecl)4608 TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendFunctionTemplateDecl) {
4609   TranslationUnitDecl *ToTU = getToTuDecl(
4610       R"(
4611       class Y { template <class T> friend void F(); };
4612       )",
4613       Lang_CXX03);
4614 
4615   ASTImporterLookupTable LT(*ToTU);
4616   auto *F = FirstDeclMatcher<FunctionTemplateDecl>().match(
4617       ToTU, functionTemplateDecl(hasName("F")));
4618   DeclarationName Name = F->getDeclName();
4619   auto Res = LT.lookup(ToTU, Name);
4620   EXPECT_EQ(Res.size(), 2u);
4621   EXPECT_EQ(Res.count(F), 1u);
4622   EXPECT_EQ(Res.count(F->getTemplatedDecl()), 1u);
4623 }
4624 
TEST_P(ASTImporterLookupTableTest,MultipleBefriendingClasses)4625 TEST_P(ASTImporterLookupTableTest, MultipleBefriendingClasses) {
4626   TranslationUnitDecl *ToTU = getToTuDecl(
4627       R"(
4628       struct X;
4629       struct A {
4630         friend struct X;
4631       };
4632       struct B {
4633         friend struct X;
4634       };
4635       )",
4636       Lang_CXX03);
4637 
4638   ASTImporterLookupTable LT(*ToTU);
4639   auto *X = FirstDeclMatcher<CXXRecordDecl>().match(
4640       ToTU, cxxRecordDecl(hasName("X")));
4641   auto *FriendD0 = FirstDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
4642   auto *FriendD1 = LastDeclMatcher<FriendDecl>().match(ToTU, friendDecl());
4643   const RecordDecl *RD0 = getRecordDeclOfFriend(FriendD0);
4644   const RecordDecl *RD1 = getRecordDeclOfFriend(FriendD1);
4645   ASSERT_EQ(RD0, RD1);
4646   ASSERT_EQ(RD1, X);
4647 
4648   DeclarationName Name = X->getDeclName();
4649   auto Res = LT.lookup(ToTU, Name);
4650   EXPECT_EQ(Res.size(), 1u);
4651   EXPECT_EQ(*Res.begin(), X);
4652 }
4653 
TEST_P(ASTImporterLookupTableTest,EnumConstantDecl)4654 TEST_P(ASTImporterLookupTableTest, EnumConstantDecl) {
4655   TranslationUnitDecl *ToTU = getToTuDecl(
4656       R"(
4657       enum E {
4658         A,
4659         B
4660       };
4661       )",
4662       Lang_C99);
4663 
4664   ASTImporterLookupTable LT(*ToTU);
4665   auto *E = FirstDeclMatcher<EnumDecl>().match(ToTU, enumDecl(hasName("E")));
4666   auto *A = FirstDeclMatcher<EnumConstantDecl>().match(
4667       ToTU, enumConstantDecl(hasName("A")));
4668 
4669   DeclarationName Name = A->getDeclName();
4670   // Redecl context is the TU.
4671   ASSERT_EQ(E->getRedeclContext(), ToTU);
4672 
4673   SmallVector<NamedDecl *, 2> FoundDecls;
4674   // Normal lookup finds in the DC.
4675   E->localUncachedLookup(Name, FoundDecls);
4676   EXPECT_EQ(FoundDecls.size(), 1u);
4677 
4678   // Normal lookup finds in the Redecl context.
4679   ToTU->localUncachedLookup(Name, FoundDecls);
4680   EXPECT_EQ(FoundDecls.size(), 1u);
4681 
4682   // Import specific lookup finds in the DC.
4683   auto Res = LT.lookup(E, Name);
4684   ASSERT_EQ(Res.size(), 1u);
4685   EXPECT_EQ(*Res.begin(), A);
4686 
4687   // Import specific lookup finds in the Redecl context.
4688   Res = LT.lookup(ToTU, Name);
4689   ASSERT_EQ(Res.size(), 1u);
4690   EXPECT_EQ(*Res.begin(), A);
4691 }
4692 
TEST_P(ASTImporterLookupTableTest,LookupSearchesInTheWholeRedeclChain)4693 TEST_P(ASTImporterLookupTableTest, LookupSearchesInTheWholeRedeclChain) {
4694   TranslationUnitDecl *ToTU = getToTuDecl(
4695       R"(
4696       namespace N {
4697         int A;
4698       }
4699       namespace N {
4700       }
4701       )",
4702       Lang_CXX03);
4703   auto *N1 =
4704       LastDeclMatcher<NamespaceDecl>().match(ToTU, namespaceDecl(hasName("N")));
4705   auto *A = FirstDeclMatcher<VarDecl>().match(ToTU, varDecl(hasName("A")));
4706   DeclarationName Name = A->getDeclName();
4707 
4708   ASTImporterLookupTable LT(*ToTU);
4709   auto Res = LT.lookup(N1, Name);
4710   ASSERT_EQ(Res.size(), 1u);
4711   EXPECT_EQ(*Res.begin(), A);
4712 }
4713 
TEST_P(ASTImporterOptionSpecificTestBase,RedeclChainShouldBeCorrectAmongstNamespaces)4714 TEST_P(ASTImporterOptionSpecificTestBase,
4715        RedeclChainShouldBeCorrectAmongstNamespaces) {
4716   Decl *FromTU = getTuDecl(
4717       R"(
4718       namespace NS {
4719         struct X;
4720         struct Y {
4721           static const int I = 3;
4722         };
4723       }
4724       namespace NS {
4725         struct X {  // <--- To be imported
4726           void method(int i = Y::I) {}
4727           int f;
4728         };
4729       }
4730       )",
4731       Lang_CXX03);
4732   auto *FromFwd = FirstDeclMatcher<CXXRecordDecl>().match(
4733       FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
4734   auto *FromDef = LastDeclMatcher<CXXRecordDecl>().match(
4735       FromTU,
4736       cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit())));
4737   ASSERT_NE(FromFwd, FromDef);
4738   ASSERT_FALSE(FromFwd->isThisDeclarationADefinition());
4739   ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
4740   ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl());
4741 
4742   auto *ToDef = cast_or_null<CXXRecordDecl>(Import(FromDef, Lang_CXX03));
4743   auto *ToFwd = cast_or_null<CXXRecordDecl>(Import(FromFwd, Lang_CXX03));
4744   EXPECT_NE(ToFwd, ToDef);
4745   EXPECT_FALSE(ToFwd->isThisDeclarationADefinition());
4746   EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
4747   EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl());
4748   auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4749   // We expect no (ODR) warning during the import.
4750   EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
4751 }
4752 
4753 struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {};
4754 
TEST_P(ImportFriendFunctionTemplates,LookupShouldFindPreviousFriend)4755 TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
4756   Decl *ToTU = getToTuDecl(
4757       R"(
4758       class X {
4759         template <typename T> friend void foo();
4760       };
4761       )",
4762       Lang_CXX03);
4763   auto *Friend = FirstDeclMatcher<FunctionTemplateDecl>().match(
4764       ToTU, functionTemplateDecl(hasName("foo")));
4765 
4766   Decl *FromTU = getTuDecl(
4767       R"(
4768       template <typename T> void foo();
4769       )",
4770       Lang_CXX03);
4771   auto *FromFoo = FirstDeclMatcher<FunctionTemplateDecl>().match(
4772       FromTU, functionTemplateDecl(hasName("foo")));
4773   auto *Imported = Import(FromFoo, Lang_CXX03);
4774 
4775   EXPECT_EQ(Imported->getPreviousDecl(), Friend);
4776 }
4777 
4778 struct ASTImporterWithFakeErrors : ASTImporter {
4779   using ASTImporter::ASTImporter;
returnWithErrorInTestclang::ast_matchers::ASTImporterWithFakeErrors4780   bool returnWithErrorInTest() override { return true; }
4781 };
4782 
4783 struct ErrorHandlingTest : ASTImporterOptionSpecificTestBase {
ErrorHandlingTestclang::ast_matchers::ErrorHandlingTest4784   ErrorHandlingTest() {
4785     Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
4786                  ASTContext &FromContext, FileManager &FromFileManager,
4787                  bool MinimalImport,
4788                  const std::shared_ptr<ASTImporterSharedState> &SharedState) {
4789       return new ASTImporterWithFakeErrors(ToContext, ToFileManager,
4790                                            FromContext, FromFileManager,
4791                                            MinimalImport, SharedState);
4792     };
4793   }
4794   // In this test we purposely report an error (UnsupportedConstruct) when
4795   // importing the below stmt.
4796   static constexpr auto* ErroneousStmt = R"( asm(""); )";
4797 };
4798 
4799 // Check a case when no new AST node is created in the AST before encountering
4800 // the error.
TEST_P(ErrorHandlingTest,ErrorHappensBeforeCreatingANewNode)4801 TEST_P(ErrorHandlingTest, ErrorHappensBeforeCreatingANewNode) {
4802   TranslationUnitDecl *ToTU = getToTuDecl(
4803       R"(
4804       template <typename T>
4805       class X {};
4806       template <>
4807       class X<int> { int a; };
4808       )",
4809       Lang_CXX03);
4810   TranslationUnitDecl *FromTU = getTuDecl(
4811       R"(
4812       template <typename T>
4813       class X {};
4814       template <>
4815       class X<int> { double b; };
4816       )",
4817       Lang_CXX03);
4818   auto *FromSpec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().match(
4819       FromTU, classTemplateSpecializationDecl(hasName("X")));
4820   ClassTemplateSpecializationDecl *ImportedSpec = Import(FromSpec, Lang_CXX03);
4821   EXPECT_FALSE(ImportedSpec);
4822 
4823   // The original Decl is kept, no new decl is created.
4824   EXPECT_EQ(DeclCounter<ClassTemplateSpecializationDecl>().match(
4825                 ToTU, classTemplateSpecializationDecl(hasName("X"))),
4826             1u);
4827 
4828   // But an error is set to the counterpart in the "from" context.
4829   ASTImporter *Importer = findFromTU(FromSpec)->Importer.get();
4830   Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromSpec);
4831   ASSERT_TRUE(OptErr);
4832   EXPECT_EQ(OptErr->Error, ImportError::NameConflict);
4833 }
4834 
4835 // Check a case when a new AST node is created but not linked to the AST before
4836 // encountering the error.
TEST_P(ErrorHandlingTest,ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST)4837 TEST_P(ErrorHandlingTest,
4838        ErrorHappensAfterCreatingTheNodeButBeforeLinkingThatToTheAST) {
4839   TranslationUnitDecl *FromTU = getTuDecl(
4840       std::string("void foo() { ") + ErroneousStmt + " }", Lang_CXX03);
4841   auto *FromFoo = FirstDeclMatcher<FunctionDecl>().match(
4842       FromTU, functionDecl(hasName("foo")));
4843 
4844   FunctionDecl *ImportedFoo = Import(FromFoo, Lang_CXX03);
4845   EXPECT_FALSE(ImportedFoo);
4846 
4847   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4848   // Created, but not linked.
4849   EXPECT_EQ(
4850       DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("foo"))),
4851       0u);
4852 
4853   ASTImporter *Importer = findFromTU(FromFoo)->Importer.get();
4854   Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFoo);
4855   ASSERT_TRUE(OptErr);
4856   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
4857 }
4858 
4859 // Check a case when a new AST node is created and linked to the AST before
4860 // encountering the error. The error is set for the counterpart of the nodes in
4861 // the "from" context.
TEST_P(ErrorHandlingTest,ErrorHappensAfterNodeIsCreatedAndLinked)4862 TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) {
4863   TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
4864       void f();
4865       void f() { )") + ErroneousStmt + R"( }
4866       )",
4867                                           Lang_CXX03);
4868   auto *FromProto = FirstDeclMatcher<FunctionDecl>().match(
4869       FromTU, functionDecl(hasName("f")));
4870   auto *FromDef =
4871       LastDeclMatcher<FunctionDecl>().match(FromTU, functionDecl(hasName("f")));
4872   FunctionDecl *ImportedProto = Import(FromProto, Lang_CXX03);
4873   EXPECT_FALSE(ImportedProto); // Could not import.
4874   // However, we created two nodes in the AST. 1) the fwd decl 2) the
4875   // definition. The definition is not added to its DC, but the fwd decl is
4876   // there.
4877   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
4878   EXPECT_EQ(DeclCounter<FunctionDecl>().match(ToTU, functionDecl(hasName("f"))),
4879             1u);
4880   // Match the fwd decl.
4881   auto *ToProto =
4882       FirstDeclMatcher<FunctionDecl>().match(ToTU, functionDecl(hasName("f")));
4883   EXPECT_TRUE(ToProto);
4884   // An error is set to the counterpart in the "from" context both for the fwd
4885   // decl and the definition.
4886   ASTImporter *Importer = findFromTU(FromProto)->Importer.get();
4887   Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromProto);
4888   ASSERT_TRUE(OptErr);
4889   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
4890   OptErr = Importer->getImportDeclErrorIfAny(FromDef);
4891   ASSERT_TRUE(OptErr);
4892   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
4893 }
4894 
4895 // An error should be set for a class if we cannot import one member.
TEST_P(ErrorHandlingTest,ErrorIsPropagatedFromMemberToClass)4896 TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) {
4897   TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
4898       class X {
4899         void f() { )") + ErroneousStmt + R"( } // This member has the error
4900                                                // during import.
4901         void ok();        // The error should not prevent importing this.
4902       };                  // An error will be set for X too.
4903       )",
4904                                           Lang_CXX03);
4905   auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
4906       FromTU, cxxRecordDecl(hasName("X")));
4907   CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
4908 
4909   // An error is set for X.
4910   EXPECT_FALSE(ImportedX);
4911   ASTImporter *Importer = findFromTU(FromX)->Importer.get();
4912   Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
4913   ASSERT_TRUE(OptErr);
4914   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
4915 
4916   // An error is set for f().
4917   auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
4918       FromTU, cxxMethodDecl(hasName("f")));
4919   OptErr = Importer->getImportDeclErrorIfAny(FromF);
4920   ASSERT_TRUE(OptErr);
4921   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
4922   // And any subsequent import should fail.
4923   CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX03);
4924   EXPECT_FALSE(ImportedF);
4925 
4926   // There is an error set for the other member too.
4927   auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match(
4928       FromTU, cxxMethodDecl(hasName("ok")));
4929   OptErr = Importer->getImportDeclErrorIfAny(FromOK);
4930   EXPECT_TRUE(OptErr);
4931   // Cannot import the other member.
4932   CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX03);
4933   EXPECT_FALSE(ImportedOK);
4934 }
4935 
4936 // Check that an error propagates to the dependent AST nodes.
4937 // In the below code it means that an error in X should propagate to A.
4938 // And even to F since the containing A is erroneous.
4939 // And to all AST nodes which we visit during the import process which finally
4940 // ends up in a failure (in the error() function).
TEST_P(ErrorHandlingTest,ErrorPropagatesThroughImportCycles)4941 TEST_P(ErrorHandlingTest, ErrorPropagatesThroughImportCycles) {
4942   Decl *FromTU = getTuDecl(std::string(R"(
4943       namespace NS {
4944         class A {
4945           template <int I> class F {};
4946           class X {
4947             template <int I> friend class F;
4948             void error() { )") +
4949                                ErroneousStmt + R"( }
4950           };
4951         };
4952 
4953         class B {};
4954       } // NS
4955       )",
4956                            Lang_CXX03, "input0.cc");
4957 
4958   auto *FromFRD = FirstDeclMatcher<CXXRecordDecl>().match(
4959       FromTU, cxxRecordDecl(hasName("F"), isDefinition()));
4960   auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
4961       FromTU, cxxRecordDecl(hasName("A"), isDefinition()));
4962   auto *FromB = FirstDeclMatcher<CXXRecordDecl>().match(
4963       FromTU, cxxRecordDecl(hasName("B"), isDefinition()));
4964   auto *FromNS = FirstDeclMatcher<NamespaceDecl>().match(
4965       FromTU, namespaceDecl(hasName("NS")));
4966 
4967   // Start by importing the templated CXXRecordDecl of F.
4968   // Import fails for that.
4969   EXPECT_FALSE(Import(FromFRD, Lang_CXX03));
4970   // Import fails for A.
4971   EXPECT_FALSE(Import(FromA, Lang_CXX03));
4972   // But we should be able to import the independent B.
4973   EXPECT_TRUE(Import(FromB, Lang_CXX03));
4974   // And the namespace.
4975   EXPECT_TRUE(Import(FromNS, Lang_CXX03));
4976 
4977   // An error is set to the templated CXXRecordDecl of F.
4978   ASTImporter *Importer = findFromTU(FromFRD)->Importer.get();
4979   Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromFRD);
4980   EXPECT_TRUE(OptErr);
4981 
4982   // An error is set to A.
4983   OptErr = Importer->getImportDeclErrorIfAny(FromA);
4984   EXPECT_TRUE(OptErr);
4985 
4986   // There is no error set to B.
4987   OptErr = Importer->getImportDeclErrorIfAny(FromB);
4988   EXPECT_FALSE(OptErr);
4989 
4990   // There is no error set to NS.
4991   OptErr = Importer->getImportDeclErrorIfAny(FromNS);
4992   EXPECT_FALSE(OptErr);
4993 
4994   // Check some of those decls whose ancestor is X, they all should have an
4995   // error set if we visited them during an import process which finally failed.
4996   // These decls are part of a cycle in an ImportPath.
4997   // There would not be any error set for these decls if we hadn't follow the
4998   // ImportPaths and the cycles.
4999   OptErr = Importer->getImportDeclErrorIfAny(
5000       FirstDeclMatcher<ClassTemplateDecl>().match(
5001           FromTU, classTemplateDecl(hasName("F"))));
5002   // An error is set to the 'F' ClassTemplateDecl.
5003   EXPECT_TRUE(OptErr);
5004   // An error is set to the FriendDecl.
5005   OptErr = Importer->getImportDeclErrorIfAny(
5006       FirstDeclMatcher<FriendDecl>().match(
5007           FromTU, friendDecl()));
5008   EXPECT_TRUE(OptErr);
5009   // An error is set to the implicit class of A.
5010   OptErr =
5011       Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
5012           FromTU, cxxRecordDecl(hasName("A"), isImplicit())));
5013   EXPECT_TRUE(OptErr);
5014   // An error is set to the implicit class of X.
5015   OptErr =
5016       Importer->getImportDeclErrorIfAny(FirstDeclMatcher<CXXRecordDecl>().match(
5017           FromTU, cxxRecordDecl(hasName("X"), isImplicit())));
5018   EXPECT_TRUE(OptErr);
5019 }
5020 
TEST_P(ErrorHandlingTest,ErrorIsNotPropagatedFromMemberToNamespace)5021 TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) {
5022   TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5023       namespace X {
5024         void f() { )") + ErroneousStmt + R"( } // This member has the error
5025                                                // during import.
5026         void ok();        // The error should not prevent importing this.
5027       };                  // An error will be set for X too.
5028       )",
5029                                           Lang_CXX03);
5030   auto *FromX = FirstDeclMatcher<NamespaceDecl>().match(
5031       FromTU, namespaceDecl(hasName("X")));
5032   NamespaceDecl *ImportedX = Import(FromX, Lang_CXX03);
5033 
5034   // There is no error set for X.
5035   EXPECT_TRUE(ImportedX);
5036   ASTImporter *Importer = findFromTU(FromX)->Importer.get();
5037   Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
5038   ASSERT_FALSE(OptErr);
5039 
5040   // An error is set for f().
5041   auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
5042       FromTU, functionDecl(hasName("f")));
5043   OptErr = Importer->getImportDeclErrorIfAny(FromF);
5044   ASSERT_TRUE(OptErr);
5045   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
5046   // And any subsequent import should fail.
5047   FunctionDecl *ImportedF = Import(FromF, Lang_CXX03);
5048   EXPECT_FALSE(ImportedF);
5049 
5050   // There is no error set for ok().
5051   auto *FromOK = FirstDeclMatcher<FunctionDecl>().match(
5052       FromTU, functionDecl(hasName("ok")));
5053   OptErr = Importer->getImportDeclErrorIfAny(FromOK);
5054   EXPECT_FALSE(OptErr);
5055   // And we should be able to import.
5056   FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX03);
5057   EXPECT_TRUE(ImportedOK);
5058 }
5059 
5060 // An error should be set for a class if it had a previous import with an error
5061 // from another TU.
TEST_P(ErrorHandlingTest,ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt)5062 TEST_P(ErrorHandlingTest,
5063        ImportedDeclWithErrorShouldFailTheImportOfDeclWhichMapToIt) {
5064   // We already have a fwd decl.
5065   TranslationUnitDecl *ToTU = getToTuDecl("class X;", Lang_CXX03);
5066   // Then we import a definition.
5067   {
5068     TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5069         class X {
5070           void f() { )") + ErroneousStmt + R"( }
5071           void ok();
5072         };
5073         )",
5074                                             Lang_CXX03);
5075     auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
5076         FromTU, cxxRecordDecl(hasName("X")));
5077     CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
5078 
5079     // An error is set for X ...
5080     EXPECT_FALSE(ImportedX);
5081     ASTImporter *Importer = findFromTU(FromX)->Importer.get();
5082     Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
5083     ASSERT_TRUE(OptErr);
5084     EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
5085   }
5086   // ... but the node had been created.
5087   auto *ToXDef = FirstDeclMatcher<CXXRecordDecl>().match(
5088       ToTU, cxxRecordDecl(hasName("X"), isDefinition()));
5089   // An error is set for "ToXDef" in the shared state.
5090   Optional<ImportError> OptErr =
5091       SharedStatePtr->getImportDeclErrorIfAny(ToXDef);
5092   ASSERT_TRUE(OptErr);
5093   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
5094 
5095   auto *ToXFwd = FirstDeclMatcher<CXXRecordDecl>().match(
5096       ToTU, cxxRecordDecl(hasName("X"), unless(isDefinition())));
5097   // An error is NOT set for the fwd Decl of X in the shared state.
5098   OptErr = SharedStatePtr->getImportDeclErrorIfAny(ToXFwd);
5099   ASSERT_FALSE(OptErr);
5100 
5101   // Try to import  X again but from another TU.
5102   {
5103     TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5104         class X {
5105           void f() { )") + ErroneousStmt + R"( }
5106           void ok();
5107         };
5108         )",
5109                                             Lang_CXX03, "input1.cc");
5110 
5111     auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
5112         FromTU, cxxRecordDecl(hasName("X")));
5113     CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX03);
5114 
5115     // If we did not save the errors for the "to" context then the below checks
5116     // would fail, because the lookup finds the fwd Decl of the existing
5117     // definition in the "to" context. We can reach the existing definition via
5118     // the found fwd Decl. That existing definition is structurally equivalent
5119     // (we check only the fields) with this one we want to import, so we return
5120     // with the existing definition, which is erroneous (one method is missing).
5121 
5122     // The import should fail.
5123     EXPECT_FALSE(ImportedX);
5124     ASTImporter *Importer = findFromTU(FromX)->Importer.get();
5125     Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX);
5126     // And an error is set for this new X in the "from" ctx.
5127     ASSERT_TRUE(OptErr);
5128     EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
5129   }
5130 }
5131 
TEST_P(ErrorHandlingTest,ImportOfOverriddenMethods)5132 TEST_P(ErrorHandlingTest, ImportOfOverriddenMethods) {
5133   auto MatchFooA =
5134       functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("A"))));
5135   auto MatchFooB =
5136       functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("B"))));
5137   auto MatchFooC =
5138       functionDecl(hasName("foo"), hasAncestor(cxxRecordDecl(hasName("C"))));
5139 
5140   // Provoke import of a method that has overridden methods with import error.
5141   TranslationUnitDecl *FromTU = getTuDecl(std::string(R"(
5142         struct C;
5143         struct A {
5144           virtual void foo();
5145           void f1(C *);
5146         };
5147         void A::foo() {
5148           )") + ErroneousStmt + R"(
5149         }
5150         struct B : public A {
5151           void foo() override;
5152         };
5153         struct C : public B {
5154           void foo() override;
5155         };
5156         )",
5157                                           Lang_CXX11);
5158   auto *FromFooA = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooA);
5159   auto *FromFooB = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooB);
5160   auto *FromFooC = FirstDeclMatcher<FunctionDecl>().match(FromTU, MatchFooC);
5161 
5162   EXPECT_FALSE(Import(FromFooA, Lang_CXX11));
5163   ASTImporter *Importer = findFromTU(FromFooA)->Importer.get();
5164   auto CheckError = [&Importer](Decl *FromD) {
5165     Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromD);
5166     ASSERT_TRUE(OptErr);
5167     EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
5168   };
5169   CheckError(FromFooA);
5170   EXPECT_FALSE(Import(FromFooB, Lang_CXX11));
5171   CheckError(FromFooB);
5172   EXPECT_FALSE(Import(FromFooC, Lang_CXX11));
5173   CheckError(FromFooC);
5174 }
5175 
TEST_P(ASTImporterOptionSpecificTestBase,LambdaInFunctionBody)5176 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) {
5177   Decl *FromTU = getTuDecl(
5178       R"(
5179       void f() {
5180         auto L = [](){};
5181       }
5182       )",
5183       Lang_CXX11, "input0.cc");
5184   auto Pattern = lambdaExpr();
5185   CXXRecordDecl *FromL =
5186       FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
5187 
5188   auto ToL = Import(FromL, Lang_CXX11);
5189   unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
5190   unsigned FromLSize =
5191       std::distance(FromL->decls().begin(), FromL->decls().end());
5192   EXPECT_NE(ToLSize, 0u);
5193   EXPECT_EQ(ToLSize, FromLSize);
5194 }
5195 
TEST_P(ASTImporterOptionSpecificTestBase,LambdaInFunctionParam)5196 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
5197   Decl *FromTU = getTuDecl(
5198       R"(
5199       template <typename F>
5200       void f(F L = [](){}) {}
5201       )",
5202       Lang_CXX11, "input0.cc");
5203   auto Pattern = lambdaExpr();
5204   CXXRecordDecl *FromL =
5205       FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
5206 
5207   auto ToL = Import(FromL, Lang_CXX11);
5208   unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
5209   unsigned FromLSize =
5210       std::distance(FromL->decls().begin(), FromL->decls().end());
5211   EXPECT_NE(ToLSize, 0u);
5212   EXPECT_EQ(ToLSize, FromLSize);
5213 }
5214 
TEST_P(ASTImporterOptionSpecificTestBase,LambdaInGlobalScope)5215 TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) {
5216   Decl *FromTU = getTuDecl(
5217       R"(
5218       auto l1 = [](unsigned lp) { return 1; };
5219       auto l2 = [](int lp) { return 2; };
5220       int f(int p) {
5221         return l1(p) + l2(p);
5222       }
5223       )",
5224       Lang_CXX11, "input0.cc");
5225   FunctionDecl *FromF = FirstDeclMatcher<FunctionDecl>().match(
5226       FromTU, functionDecl(hasName("f")));
5227   FunctionDecl *ToF = Import(FromF, Lang_CXX11);
5228   EXPECT_TRUE(ToF);
5229 }
5230 
TEST_P(ASTImporterOptionSpecificTestBase,ImportExistingFriendClassTemplateDef)5231 TEST_P(ASTImporterOptionSpecificTestBase,
5232        ImportExistingFriendClassTemplateDef) {
5233   auto Code =
5234       R"(
5235         template <class T1, class T2>
5236         struct Base {
5237           template <class U1, class U2>
5238           friend struct Class;
5239         };
5240         template <class T1, class T2>
5241         struct Class { };
5242         )";
5243 
5244   TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX03);
5245   TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX03, "input.cc");
5246 
5247   auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
5248       ToTU, classTemplateDecl(hasName("Class")));
5249   auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
5250       ToTU, classTemplateDecl(hasName("Class")));
5251   ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition());
5252   ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition());
5253   // Previous friend decl is not linked to it!
5254   ASSERT_FALSE(ToClassDef->getPreviousDecl());
5255   ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef);
5256   ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto);
5257 
5258   auto *FromClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
5259       FromTU, classTemplateDecl(hasName("Class")));
5260   auto *FromClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
5261       FromTU, classTemplateDecl(hasName("Class")));
5262   ASSERT_FALSE(FromClassProto->isThisDeclarationADefinition());
5263   ASSERT_TRUE(FromClassDef->isThisDeclarationADefinition());
5264   ASSERT_FALSE(FromClassDef->getPreviousDecl());
5265   ASSERT_EQ(FromClassDef->getMostRecentDecl(), FromClassDef);
5266   ASSERT_EQ(FromClassProto->getMostRecentDecl(), FromClassProto);
5267 
5268   auto *ImportedDef = Import(FromClassDef, Lang_CXX03);
5269   // At import we should find the definition for 'Class' even if the
5270   // prototype (inside 'friend') for it comes first in the AST and is not
5271   // linked to the definition.
5272   EXPECT_EQ(ImportedDef, ToClassDef);
5273 }
5274 
5275 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase {
LLDBLookupTestclang::ast_matchers::LLDBLookupTest5276   LLDBLookupTest() {
5277     Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
5278                  ASTContext &FromContext, FileManager &FromFileManager,
5279                  bool MinimalImport,
5280                  const std::shared_ptr<ASTImporterSharedState> &SharedState) {
5281       return new ASTImporter(ToContext, ToFileManager, FromContext,
5282                              FromFileManager, MinimalImport,
5283                              // We use the regular lookup.
5284                              /*SharedState=*/nullptr);
5285     };
5286   }
5287 };
5288 
TEST_P(LLDBLookupTest,ImporterShouldFindInTransparentContext)5289 TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) {
5290   TranslationUnitDecl *ToTU = getToTuDecl(
5291       R"(
5292       extern "C" {
5293         class X{};
5294       };
5295       )",
5296       Lang_CXX03);
5297   auto *ToX = FirstDeclMatcher<CXXRecordDecl>().match(
5298       ToTU, cxxRecordDecl(hasName("X")));
5299 
5300   // Set up a stub external storage.
5301   ToTU->setHasExternalLexicalStorage(true);
5302   // Set up DeclContextBits.HasLazyExternalLexicalLookups to true.
5303   ToTU->setMustBuildLookupTable();
5304   struct TestExternalASTSource : ExternalASTSource {};
5305   ToTU->getASTContext().setExternalSource(new TestExternalASTSource());
5306 
5307   Decl *FromTU = getTuDecl(
5308       R"(
5309         class X;
5310       )",
5311       Lang_CXX03);
5312   auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
5313       FromTU, cxxRecordDecl(hasName("X")));
5314   auto *ImportedX = Import(FromX, Lang_CXX03);
5315   // The lookup must find the existing class definition in the LinkageSpecDecl.
5316   // Then the importer renders the existing and the new decl into one chain.
5317   EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl());
5318 }
5319 
5320 struct SVEBuiltins : ASTImporterOptionSpecificTestBase {};
5321 
TEST_P(SVEBuiltins,ImportTypes)5322 TEST_P(SVEBuiltins, ImportTypes) {
5323   static const char *const TypeNames[] = {
5324     "__SVInt8_t",
5325     "__SVInt16_t",
5326     "__SVInt32_t",
5327     "__SVInt64_t",
5328     "__SVUint8_t",
5329     "__SVUint16_t",
5330     "__SVUint32_t",
5331     "__SVUint64_t",
5332     "__SVFloat16_t",
5333     "__SVBFloat16_t",
5334     "__SVFloat32_t",
5335     "__SVFloat64_t",
5336     "__SVBool_t"
5337   };
5338 
5339   TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX03);
5340   TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cc");
5341   for (auto *TypeName : TypeNames) {
5342     auto *ToTypedef = FirstDeclMatcher<TypedefDecl>().match(
5343       ToTU, typedefDecl(hasName(TypeName)));
5344     QualType ToType = ToTypedef->getUnderlyingType();
5345 
5346     auto *FromTypedef = FirstDeclMatcher<TypedefDecl>().match(
5347       FromTU, typedefDecl(hasName(TypeName)));
5348     QualType FromType = FromTypedef->getUnderlyingType();
5349 
5350     QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX03);
5351     EXPECT_EQ(ImportedType, ToType);
5352   }
5353 }
5354 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfDefaultImplicitFunctions)5355 TEST_P(ASTImporterOptionSpecificTestBase, ImportOfDefaultImplicitFunctions) {
5356   // Test that import of implicit functions works and the functions
5357   // are merged into one chain.
5358   auto GetDeclToImport = [this](StringRef File) {
5359     Decl *FromTU = getTuDecl(
5360         R"(
5361         struct X { };
5362         // Force generating some implicit operator definitions for X.
5363         void f() { X x1, x2; x1 = x2; X *x3 = new X; delete x3; }
5364         )",
5365         Lang_CXX11, File);
5366     auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
5367         FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit())));
5368     // Destructor is picked as one example of implicit function.
5369     return FromD->getDestructor();
5370   };
5371 
5372   auto *ToD1 = Import(GetDeclToImport("input1.cc"), Lang_CXX11);
5373   ASSERT_TRUE(ToD1);
5374 
5375   auto *ToD2 = Import(GetDeclToImport("input2.cc"), Lang_CXX11);
5376   ASSERT_TRUE(ToD2);
5377 
5378   EXPECT_EQ(ToD1->getCanonicalDecl(), ToD2->getCanonicalDecl());
5379 }
5380 
TEST_P(ASTImporterOptionSpecificTestBase,ImportOfExplicitlyDefaultedOrDeleted)5381 TEST_P(ASTImporterOptionSpecificTestBase,
5382        ImportOfExplicitlyDefaultedOrDeleted) {
5383   Decl *FromTU = getTuDecl(
5384       R"(
5385         struct X { X() = default; X(const X&) = delete; };
5386       )",
5387       Lang_CXX11);
5388   auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match(
5389       FromTU, cxxRecordDecl(hasName("X")));
5390   auto *ImportedX = Import(FromX, Lang_CXX11);
5391   auto *Constr1 = FirstDeclMatcher<CXXConstructorDecl>().match(
5392       ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
5393   auto *Constr2 = LastDeclMatcher<CXXConstructorDecl>().match(
5394       ImportedX, cxxConstructorDecl(hasName("X"), unless(isImplicit())));
5395 
5396   ASSERT_TRUE(ImportedX);
5397   EXPECT_TRUE(Constr1->isDefaulted());
5398   EXPECT_TRUE(Constr1->isExplicitlyDefaulted());
5399   EXPECT_TRUE(Constr2->isDeletedAsWritten());
5400   EXPECT_EQ(ImportedX->isAggregate(), FromX->isAggregate());
5401 }
5402 
5403 INSTANTIATE_TEST_CASE_P(ParameterizedTests, SVEBuiltins,
5404                         ::testing::Values(std::vector<std::string>{
5405                             "-target", "aarch64-linux-gnu"}), );
5406 
5407 INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest,
5408                         ::testing::Values(std::vector<std::string>()), );
5409 
5410 INSTANTIATE_TEST_CASE_P(ParameterizedTests, CanonicalRedeclChain,
5411                         ::testing::Values(std::vector<std::string>()), );
5412 
TEST_P(ASTImporterOptionSpecificTestBase,LambdasAreDifferentiated)5413 TEST_P(ASTImporterOptionSpecificTestBase, LambdasAreDifferentiated) {
5414   Decl *FromTU = getTuDecl(
5415       R"(
5416       void f() {
5417         auto L0 = [](){};
5418         auto L1 = [](){};
5419       }
5420       )",
5421       Lang_CXX11, "input0.cc");
5422   auto Pattern = lambdaExpr();
5423   CXXRecordDecl *FromL0 =
5424       FirstDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
5425   CXXRecordDecl *FromL1 =
5426       LastDeclMatcher<LambdaExpr>().match(FromTU, Pattern)->getLambdaClass();
5427   ASSERT_NE(FromL0, FromL1);
5428 
5429   CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
5430   CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
5431   EXPECT_NE(ToL0, ToL1);
5432 }
5433 
TEST_P(ASTImporterOptionSpecificTestBase,LambdasInFunctionParamsAreDifferentiated)5434 TEST_P(ASTImporterOptionSpecificTestBase,
5435        LambdasInFunctionParamsAreDifferentiated) {
5436   Decl *FromTU = getTuDecl(
5437       R"(
5438       template <typename F0, typename F1>
5439       void f(F0 L0 = [](){}, F1 L1 = [](){}) {}
5440       )",
5441       Lang_CXX11, "input0.cc");
5442   auto Pattern = cxxRecordDecl(isLambda());
5443   CXXRecordDecl *FromL0 =
5444       FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
5445   CXXRecordDecl *FromL1 =
5446       LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
5447   ASSERT_NE(FromL0, FromL1);
5448 
5449   CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
5450   CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
5451   ASSERT_NE(ToL0, ToL1);
5452 }
5453 
TEST_P(ASTImporterOptionSpecificTestBase,LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed)5454 TEST_P(ASTImporterOptionSpecificTestBase,
5455        LambdasInFunctionParamsAreDifferentiatedWhenMacroIsUsed) {
5456   Decl *FromTU = getTuDecl(
5457       R"(
5458       #define LAMBDA [](){}
5459       template <typename F0, typename F1>
5460       void f(F0 L0 = LAMBDA, F1 L1 = LAMBDA) {}
5461       )",
5462       Lang_CXX11, "input0.cc");
5463   auto Pattern = cxxRecordDecl(isLambda());
5464   CXXRecordDecl *FromL0 =
5465       FirstDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
5466   CXXRecordDecl *FromL1 =
5467       LastDeclMatcher<CXXRecordDecl>().match(FromTU, Pattern);
5468   ASSERT_NE(FromL0, FromL1);
5469 
5470   Import(FromL0, Lang_CXX11);
5471   Import(FromL1, Lang_CXX11);
5472   CXXRecordDecl *ToL0 = Import(FromL0, Lang_CXX11);
5473   CXXRecordDecl *ToL1 = Import(FromL1, Lang_CXX11);
5474   ASSERT_NE(ToL0, ToL1);
5475 }
5476 
TEST_P(ASTImporterOptionSpecificTestBase,ImportAssignedLambda)5477 TEST_P(ASTImporterOptionSpecificTestBase, ImportAssignedLambda) {
5478   Decl *FromTU = getTuDecl(
5479       R"(
5480       void f() {
5481         auto x = []{} = {}; auto x2 = x;
5482       }
5483       )",
5484       Lang_CXX20, "input0.cc");
5485   auto FromF = FirstDeclMatcher<FunctionDecl>().match(
5486       FromTU, functionDecl(hasName("f")));
5487   // We have only one lambda class.
5488   ASSERT_EQ(
5489       DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
5490       1u);
5491 
5492   FunctionDecl *ToF = Import(FromF, Lang_CXX20);
5493   EXPECT_TRUE(ToF);
5494   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5495   // We have only one lambda class after the import.
5496   EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
5497             1u);
5498 }
5499 
TEST_P(ASTImporterOptionSpecificTestBase,ImportDefaultConstructibleLambdas)5500 TEST_P(ASTImporterOptionSpecificTestBase, ImportDefaultConstructibleLambdas) {
5501   Decl *FromTU = getTuDecl(
5502       R"(
5503       void f() {
5504         auto x = []{} = {};
5505         auto xb = []{} = {};
5506       }
5507       )",
5508       Lang_CXX20, "input0.cc");
5509   auto FromF = FirstDeclMatcher<FunctionDecl>().match(
5510       FromTU, functionDecl(hasName("f")));
5511   // We have two lambda classes.
5512   ASSERT_EQ(
5513       DeclCounter<CXXRecordDecl>().match(FromTU, cxxRecordDecl(isLambda())),
5514       2u);
5515 
5516   FunctionDecl *ToF = Import(FromF, Lang_CXX20);
5517   EXPECT_TRUE(ToF);
5518   TranslationUnitDecl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
5519   // We have two lambda classes after the import.
5520   EXPECT_EQ(DeclCounter<CXXRecordDecl>().match(ToTU, cxxRecordDecl(isLambda())),
5521             2u);
5522 }
5523 
TEST_P(ASTImporterOptionSpecificTestBase,ImplicitlyDeclareSelf)5524 TEST_P(ASTImporterOptionSpecificTestBase, ImplicitlyDeclareSelf) {
5525   Decl *FromTU = getTuDecl(R"(
5526                            __attribute__((objc_root_class))
5527                            @interface Root
5528                            @end
5529                            @interface C : Root
5530                              -(void)method;
5531                            @end
5532                            @implementation C
5533                              -(void)method {}
5534                            @end
5535                            )",
5536                            Lang_OBJCXX, "input.mm");
5537   auto *FromMethod = LastDeclMatcher<ObjCMethodDecl>().match(
5538       FromTU, namedDecl(hasName("method")));
5539   ASSERT_TRUE(FromMethod);
5540   auto ToMethod = Import(FromMethod, Lang_OBJCXX);
5541   ASSERT_TRUE(ToMethod);
5542 
5543   // Both methods should have their implicit parameters.
5544   EXPECT_TRUE(FromMethod->getSelfDecl() != nullptr);
5545   EXPECT_TRUE(ToMethod->getSelfDecl() != nullptr);
5546 }
5547 
5548 struct ImportAutoFunctions : ASTImporterOptionSpecificTestBase {};
5549 
TEST_P(ImportAutoFunctions,ReturnWithTypedefDeclaredInside)5550 TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) {
5551   Decl *FromTU = getTuDecl(
5552       R"(
5553       auto X = [](long l) {
5554         using int_type = long;
5555         auto dur = 13;
5556         return static_cast<int_type>(dur);
5557       };
5558       )",
5559       Lang_CXX14, "input0.cc");
5560   CXXMethodDecl *From =
5561       FirstDeclMatcher<CXXMethodDecl>().match(FromTU, cxxMethodDecl());
5562 
5563   // Explicitly set the return type of the lambda's operator() to the TypeAlias.
5564   // Normally the return type would be the built-in 'long' type. However, there
5565   // are cases when Clang does not use the canonical type and the TypeAlias is
5566   // used. I could not create such an AST from regular source code, it requires
5567   // some special state in the preprocessor. I've found such an AST when Clang
5568   // parsed libcxx/src/filesystem/directory_iterator.cpp, but could not reduce
5569   // that with creduce, because after preprocessing, the AST no longer
5570   // contained the TypeAlias as a return type of the lambda.
5571   ASTContext &Ctx = From->getASTContext();
5572   TypeAliasDecl *FromTA =
5573       FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl());
5574   QualType TT = Ctx.getTypedefType(FromTA);
5575   const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType());
5576   QualType NewFunType =
5577       Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo());
5578   From->setType(NewFunType);
5579 
5580   CXXMethodDecl *To = Import(From, Lang_CXX14);
5581   EXPECT_TRUE(To);
5582   EXPECT_TRUE(isa<TypedefType>(To->getReturnType()));
5583 }
5584 
TEST_P(ImportAutoFunctions,ReturnWithStructDeclaredInside)5585 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside) {
5586   Decl *FromTU = getTuDecl(
5587       R"(
5588       auto foo() {
5589         struct X {};
5590         return X();
5591       }
5592       )",
5593       Lang_CXX14, "input0.cc");
5594   FunctionDecl *From =
5595       FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
5596 
5597   FunctionDecl *To = Import(From, Lang_CXX14);
5598   EXPECT_TRUE(To);
5599   EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
5600 }
5601 
TEST_P(ImportAutoFunctions,ReturnWithStructDeclaredInside2)5602 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredInside2) {
5603   Decl *FromTU = getTuDecl(
5604       R"(
5605       auto foo() {
5606         struct X {};
5607         return X();
5608       }
5609       )",
5610       Lang_CXX14, "input0.cc");
5611   FunctionDecl *From =
5612       FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
5613 
5614   // This time import the type directly.
5615   QualType ToT = ImportType(From->getType(), From, Lang_CXX14);
5616   const FunctionProtoType *FPT = cast<FunctionProtoType>(ToT);
5617   EXPECT_TRUE(isa<AutoType>(FPT->getReturnType()));
5618 }
5619 
TEST_P(ImportAutoFunctions,ReturnWithTypedefToStructDeclaredInside)5620 TEST_P(ImportAutoFunctions, ReturnWithTypedefToStructDeclaredInside) {
5621   Decl *FromTU = getTuDecl(
5622       R"(
5623       auto foo() {
5624         struct X {};
5625         using Y = X;
5626         return Y();
5627       }
5628       )",
5629       Lang_CXX14, "input0.cc");
5630   FunctionDecl *From =
5631       FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
5632 
5633   FunctionDecl *To = Import(From, Lang_CXX14);
5634   EXPECT_TRUE(To);
5635   EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
5636 }
5637 
TEST_P(ImportAutoFunctions,ReturnWithStructDeclaredNestedInside)5638 TEST_P(ImportAutoFunctions, ReturnWithStructDeclaredNestedInside) {
5639   Decl *FromTU = getTuDecl(
5640       R"(
5641       auto foo() {
5642         struct X { struct Y{}; };
5643         return X::Y();
5644       }
5645       )",
5646       Lang_CXX14, "input0.cc");
5647   FunctionDecl *From =
5648       FirstDeclMatcher<FunctionDecl>().match(FromTU, functionDecl());
5649 
5650   FunctionDecl *To = Import(From, Lang_CXX14);
5651   EXPECT_TRUE(To);
5652   EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
5653 }
5654 
TEST_P(ImportAutoFunctions,ReturnWithInternalLambdaType)5655 TEST_P(ImportAutoFunctions, ReturnWithInternalLambdaType) {
5656   Decl *FromTU = getTuDecl(
5657       R"(
5658       auto f() {
5659         auto l = []() {
5660           struct X {};
5661           return X();
5662         };
5663         return l();
5664       }
5665       )",
5666       Lang_CXX17, "input0.cc");
5667   FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
5668       FromTU, functionDecl(hasName("f")));
5669 
5670   FunctionDecl *To = Import(From, Lang_CXX17);
5671   EXPECT_TRUE(To);
5672   EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
5673 }
5674 
TEST_P(ImportAutoFunctions,ReturnWithTypeInIf)5675 TEST_P(ImportAutoFunctions, ReturnWithTypeInIf) {
5676   Decl *FromTU = getTuDecl(
5677       R"(
5678       auto f() {
5679         if (struct X {} x; true)
5680           return X();
5681         else
5682           return X();
5683       }
5684       )",
5685       Lang_CXX17, "input0.cc");
5686   FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
5687       FromTU, functionDecl(hasName("f")));
5688 
5689   FunctionDecl *To = Import(From, Lang_CXX17);
5690   EXPECT_TRUE(To);
5691   EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
5692 }
5693 
TEST_P(ImportAutoFunctions,ReturnWithTypeInFor)5694 TEST_P(ImportAutoFunctions, ReturnWithTypeInFor) {
5695   Decl *FromTU = getTuDecl(
5696       R"(
5697       auto f() {
5698         for (struct X {} x;;)
5699           return X();
5700       }
5701       )",
5702       Lang_CXX17, "input0.cc");
5703   FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
5704       FromTU, functionDecl(hasName("f")));
5705 
5706   FunctionDecl *To = Import(From, Lang_CXX17);
5707   EXPECT_TRUE(To);
5708   EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
5709 }
5710 
TEST_P(ImportAutoFunctions,ReturnWithTypeInSwitch)5711 TEST_P(ImportAutoFunctions, ReturnWithTypeInSwitch) {
5712   Decl *FromTU = getTuDecl(
5713       R"(
5714       auto f() {
5715         switch (struct X {} x; 10) {
5716         case 10:
5717           return X();
5718         }
5719       }
5720       )",
5721       Lang_CXX17, "input0.cc");
5722   FunctionDecl *From = FirstDeclMatcher<FunctionDecl>().match(
5723       FromTU, functionDecl(hasName("f")));
5724 
5725   FunctionDecl *To = Import(From, Lang_CXX17);
5726   EXPECT_TRUE(To);
5727   EXPECT_TRUE(isa<AutoType>(To->getReturnType()));
5728 }
5729 
5730 struct ImportSourceLocations : ASTImporterOptionSpecificTestBase {};
5731 
TEST_P(ImportSourceLocations,PreserveFileIDTreeStructure)5732 TEST_P(ImportSourceLocations, PreserveFileIDTreeStructure) {
5733   // Tests that the FileID tree structure (with the links being the include
5734   // chains) is preserved while importing other files (which need to be
5735   // added to this structure with fake include locations.
5736 
5737   SourceLocation Location1;
5738   {
5739     auto Pattern = varDecl(hasName("X"));
5740     Decl *FromTU = getTuDecl("int X;", Lang_C99, "input0.c");
5741     auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
5742 
5743     Location1 = Import(FromD, Lang_C99)->getLocation();
5744   }
5745   SourceLocation Location2;
5746   {
5747     auto Pattern = varDecl(hasName("Y"));
5748     Decl *FromTU = getTuDecl("int Y;", Lang_C99, "input1.c");
5749     auto *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
5750 
5751     Location2 = Import(FromD, Lang_C99)->getLocation();
5752   }
5753 
5754   SourceManager &ToSM = ToAST->getSourceManager();
5755   FileID FileID1 = ToSM.getFileID(Location1);
5756   FileID FileID2 = ToSM.getFileID(Location2);
5757 
5758   // Check that the imported files look like as if they were included from the
5759   // start of the main file.
5760   SourceLocation FileStart = ToSM.getLocForStartOfFile(ToSM.getMainFileID());
5761   EXPECT_NE(FileID1, ToSM.getMainFileID());
5762   EXPECT_NE(FileID2, ToSM.getMainFileID());
5763   EXPECT_EQ(ToSM.getIncludeLoc(FileID1), FileStart);
5764   EXPECT_EQ(ToSM.getIncludeLoc(FileID2), FileStart);
5765 
5766   // Let the SourceManager check the order of the locations. The order should
5767   // be the order in which the declarations are imported.
5768   EXPECT_TRUE(ToSM.isBeforeInTranslationUnit(Location1, Location2));
5769   EXPECT_FALSE(ToSM.isBeforeInTranslationUnit(Location2, Location1));
5770 }
5771 
TEST_P(ImportSourceLocations,NormalFileBuffer)5772 TEST_P(ImportSourceLocations, NormalFileBuffer) {
5773   // Test importing normal file buffers.
5774 
5775   std::string Path = "input0.c";
5776   std::string Source = "int X;";
5777   TranslationUnitDecl *FromTU = getTuDecl(Source, Lang_C99, Path);
5778 
5779   SourceLocation ImportedLoc;
5780   {
5781     // Import the VarDecl to trigger the importing of the FileID.
5782     auto Pattern = varDecl(hasName("X"));
5783     VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
5784     ImportedLoc = Import(FromD, Lang_C99)->getLocation();
5785   }
5786 
5787   // Make sure the imported buffer has the original contents.
5788   SourceManager &ToSM = ToAST->getSourceManager();
5789   FileID ImportedID = ToSM.getFileID(ImportedLoc);
5790   EXPECT_EQ(Source,
5791             ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
5792 }
5793 
TEST_P(ImportSourceLocations,OverwrittenFileBuffer)5794 TEST_P(ImportSourceLocations, OverwrittenFileBuffer) {
5795   // Test importing overwritten file buffers.
5796 
5797   std::string Path = "input0.c";
5798   TranslationUnitDecl *FromTU = getTuDecl("int X;", Lang_C99, Path);
5799 
5800   // Overwrite the file buffer for our input file with new content.
5801   const std::string Contents = "overwritten contents";
5802   SourceLocation ImportedLoc;
5803   {
5804     SourceManager &FromSM = FromTU->getASTContext().getSourceManager();
5805     clang::FileManager &FM = FromSM.getFileManager();
5806     const clang::FileEntry &FE =
5807         *FM.getVirtualFile(Path, static_cast<off_t>(Contents.size()), 0);
5808 
5809     llvm::SmallVector<char, 64> Buffer;
5810     Buffer.append(Contents.begin(), Contents.end());
5811     auto FileContents =
5812         std::make_unique<llvm::SmallVectorMemoryBuffer>(std::move(Buffer), Path);
5813     FromSM.overrideFileContents(&FE, std::move(FileContents));
5814 
5815     // Import the VarDecl to trigger the importing of the FileID.
5816     auto Pattern = varDecl(hasName("X"));
5817     VarDecl *FromD = FirstDeclMatcher<VarDecl>().match(FromTU, Pattern);
5818     ImportedLoc = Import(FromD, Lang_C99)->getLocation();
5819   }
5820 
5821   // Make sure the imported buffer has the overwritten contents.
5822   SourceManager &ToSM = ToAST->getSourceManager();
5823   FileID ImportedID = ToSM.getFileID(ImportedLoc);
5824   EXPECT_EQ(Contents,
5825             ToSM.getBufferOrFake(ImportedID, SourceLocation()).getBuffer());
5826 }
5827 
TEST_P(ASTImporterOptionSpecificTestBase,ImportExprOfAlignmentAttr)5828 TEST_P(ASTImporterOptionSpecificTestBase, ImportExprOfAlignmentAttr) {
5829   // Test if import of these packed and aligned attributes does not trigger an
5830   // error situation where source location from 'From' context is referenced in
5831   // 'To' context through evaluation of the alignof attribute.
5832   // This happens if the 'alignof(A)' expression is not imported correctly.
5833   Decl *FromTU = getTuDecl(
5834       R"(
5835       struct __attribute__((packed)) A { int __attribute__((aligned(8))) X; };
5836       struct alignas(alignof(A)) S {};
5837       )",
5838       Lang_CXX11, "input.cc");
5839   auto *FromD = FirstDeclMatcher<CXXRecordDecl>().match(
5840       FromTU, cxxRecordDecl(hasName("S"), unless(isImplicit())));
5841   ASSERT_TRUE(FromD);
5842 
5843   auto *ToD = Import(FromD, Lang_CXX11);
5844   ASSERT_TRUE(ToD);
5845 
5846   auto *FromAttr = FromD->getAttr<AlignedAttr>();
5847   auto *ToAttr = ToD->getAttr<AlignedAttr>();
5848   EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited());
5849   EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion());
5850   EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit());
5851   EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax());
5852   EXPECT_EQ(FromAttr->getSemanticSpelling(), ToAttr->getSemanticSpelling());
5853   EXPECT_TRUE(ToAttr->getAlignmentExpr());
5854 
5855   auto *ToA = FirstDeclMatcher<CXXRecordDecl>().match(
5856       ToD->getTranslationUnitDecl(),
5857       cxxRecordDecl(hasName("A"), unless(isImplicit())));
5858   // Ensure that 'struct A' was imported (through reference from attribute of
5859   // 'S').
5860   EXPECT_TRUE(ToA);
5861 }
5862 
TEST_P(ASTImporterOptionSpecificTestBase,ImportFormatAttr)5863 TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) {
5864   Decl *FromTU = getTuDecl(
5865       R"(
5866       int foo(const char * fmt, ...)
5867       __attribute__ ((__format__ (__scanf__, 1, 2)));
5868       )",
5869       Lang_CXX03, "input.cc");
5870   auto *FromD = FirstDeclMatcher<FunctionDecl>().match(
5871       FromTU, functionDecl(hasName("foo")));
5872   ASSERT_TRUE(FromD);
5873 
5874   auto *ToD = Import(FromD, Lang_CXX03);
5875   ASSERT_TRUE(ToD);
5876   ToD->dump(); // Should not crash!
5877 
5878   auto *FromAttr = FromD->getAttr<FormatAttr>();
5879   auto *ToAttr = ToD->getAttr<FormatAttr>();
5880   EXPECT_EQ(FromAttr->isInherited(), ToAttr->isInherited());
5881   EXPECT_EQ(FromAttr->isPackExpansion(), ToAttr->isPackExpansion());
5882   EXPECT_EQ(FromAttr->isImplicit(), ToAttr->isImplicit());
5883   EXPECT_EQ(FromAttr->getSyntax(), ToAttr->getSyntax());
5884   EXPECT_EQ(FromAttr->getAttributeSpellingListIndex(),
5885             ToAttr->getAttributeSpellingListIndex());
5886   EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName());
5887 }
5888 template <typename T>
ExtendWithOptions(const T & Values,const std::vector<std::string> & Args)5889 auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) {
5890   auto Copy = Values;
5891   for (std::vector<std::string> &ArgV : Copy) {
5892     for (const std::string &Arg : Args) {
5893       ArgV.push_back(Arg);
5894     }
5895   }
5896   return ::testing::ValuesIn(Copy);
5897 }
5898 
5899 struct ImportWithExternalSource : ASTImporterOptionSpecificTestBase {
ImportWithExternalSourceclang::ast_matchers::ImportWithExternalSource5900   ImportWithExternalSource() {
5901     Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
5902                  ASTContext &FromContext, FileManager &FromFileManager,
5903                  bool MinimalImport,
5904                  const std::shared_ptr<ASTImporterSharedState> &SharedState) {
5905       return new ASTImporter(ToContext, ToFileManager, FromContext,
5906                              FromFileManager, MinimalImport,
5907                              // We use the regular lookup.
5908                              /*SharedState=*/nullptr);
5909     };
5910   }
5911 };
5912 
5913 /// An ExternalASTSource that keeps track of the tags is completed.
5914 struct SourceWithCompletedTagList : clang::ExternalASTSource {
5915   std::vector<clang::TagDecl *> &CompletedTags;
SourceWithCompletedTagListclang::ast_matchers::SourceWithCompletedTagList5916   SourceWithCompletedTagList(std::vector<clang::TagDecl *> &CompletedTags)
5917       : CompletedTags(CompletedTags) {}
CompleteTypeclang::ast_matchers::SourceWithCompletedTagList5918   void CompleteType(TagDecl *Tag) override {
5919     auto *Record = cast<CXXRecordDecl>(Tag);
5920     Record->startDefinition();
5921     Record->completeDefinition();
5922     CompletedTags.push_back(Tag);
5923   }
5924   using clang::ExternalASTSource::CompleteType;
5925 };
5926 
TEST_P(ImportWithExternalSource,CompleteRecordBeforeImporting)5927 TEST_P(ImportWithExternalSource, CompleteRecordBeforeImporting) {
5928   // Create an empty TU.
5929   TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX03, "input.cpp");
5930 
5931   // Create and add the test ExternalASTSource.
5932   std::vector<clang::TagDecl *> CompletedTags;
5933   IntrusiveRefCntPtr<ExternalASTSource> source =
5934       new SourceWithCompletedTagList(CompletedTags);
5935   clang::ASTContext &Context = FromTU->getASTContext();
5936   Context.setExternalSource(std::move(source));
5937 
5938   // Create a dummy class by hand with external lexical storage.
5939   IdentifierInfo &Ident = Context.Idents.get("test_class");
5940   auto *Record = CXXRecordDecl::Create(
5941       Context, TTK_Class, FromTU, SourceLocation(), SourceLocation(), &Ident);
5942   Record->setHasExternalLexicalStorage();
5943   FromTU->addDecl(Record);
5944 
5945   // Do a minimal import of the created class.
5946   EXPECT_EQ(0U, CompletedTags.size());
5947   Import(Record, Lang_CXX03);
5948   EXPECT_EQ(0U, CompletedTags.size());
5949 
5950   // Import the definition of the created class.
5951   llvm::Error Err = findFromTU(Record)->Importer->ImportDefinition(Record);
5952   EXPECT_FALSE((bool)Err);
5953   consumeError(std::move(Err));
5954 
5955   // Make sure the class was completed once.
5956   EXPECT_EQ(1U, CompletedTags.size());
5957   EXPECT_EQ(Record, CompletedTags.front());
5958 }
5959 
TEST_P(ImportFunctions,CTADImplicit)5960 TEST_P(ImportFunctions, CTADImplicit) {
5961   Decl *FromTU = getTuDecl(
5962       R"(
5963       template <typename T> struct A {
5964         A(T);
5965       };
5966       A a{(int)0};
5967       )",
5968       Lang_CXX17, "input.cc");
5969   auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
5970       FromTU,
5971       cxxDeductionGuideDecl(hasParameter(0, hasType(asString("A<T>")))));
5972   auto *ToD = Import(FromD, Lang_CXX17);
5973   ASSERT_TRUE(ToD);
5974   EXPECT_TRUE(ToD->isCopyDeductionCandidate());
5975   // Check that the deduced class template is also imported.
5976   EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull(
5977       FromD->getDeducedTemplate()));
5978 }
5979 
TEST_P(ImportFunctions,CTADUserDefinedExplicit)5980 TEST_P(ImportFunctions, CTADUserDefinedExplicit) {
5981   Decl *FromTU = getTuDecl(
5982       R"(
5983       template <typename T> struct A {
5984         A(T);
5985       };
5986       template <typename T> explicit A(T) -> A<float>;
5987       A a{(int)0}; // calls A<float>::A(float)
5988       )",
5989       Lang_CXX17, "input.cc");
5990   auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
5991       FromTU, cxxDeductionGuideDecl(unless(isImplicit())));
5992   // Not-implicit: i.e. not compiler-generated, user defined.
5993   ASSERT_FALSE(FromD->isImplicit());
5994   ASSERT_TRUE(FromD->isExplicit()); // Has the explicit keyword.
5995   auto *ToD = Import(FromD, Lang_CXX17);
5996   ASSERT_TRUE(ToD);
5997   EXPECT_FALSE(FromD->isImplicit());
5998   EXPECT_TRUE(ToD->isExplicit());
5999 }
6000 
6001 // FIXME Move these tests out of ASTImporterTest. For that we need to factor
6002 // out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase
6003 // into a new test Fixture. Then we should lift up this Fixture to its own
6004 // implementation file and only then could we reuse the Fixture in other AST
6005 // unitttests.
6006 struct CTAD : ASTImporterOptionSpecificTestBase {};
6007 
TEST_P(CTAD,DeductionGuideShouldReferToANonLocalTypedef)6008 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) {
6009   Decl *TU = getTuDecl(
6010       R"(
6011       typedef int U;
6012       template <typename T> struct A {
6013         A(U, T);
6014       };
6015       A a{(int)0, (int)0};
6016       )",
6017       Lang_CXX17, "input.cc");
6018   auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
6019       TU, cxxDeductionGuideDecl());
6020   auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
6021       TU, typedefNameDecl(hasName("U")));
6022   ParmVarDecl *Param = Guide->getParamDecl(0);
6023   // The type of the first param (which is a typedef) should match the typedef
6024   // in the global scope.
6025   EXPECT_EQ(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
6026 }
6027 
TEST_P(CTAD,DeductionGuideShouldReferToANonLocalTypedefInParamPtr)6028 TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) {
6029   Decl *TU = getTuDecl(
6030       R"(
6031       typedef int U;
6032       template <typename T> struct A {
6033         A(U*, T);
6034       };
6035       A a{(int*)0, (int)0};
6036       )",
6037       Lang_CXX17, "input.cc");
6038   auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
6039       TU, cxxDeductionGuideDecl());
6040   auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
6041       TU, typedefNameDecl(hasName("U")));
6042   ParmVarDecl *Param = Guide->getParamDecl(0);
6043   EXPECT_EQ(Param->getType()
6044                 ->getAs<PointerType>()
6045                 ->getPointeeType()
6046                 ->getAs<TypedefType>()
6047                 ->getDecl(),
6048             Typedef);
6049 }
6050 
TEST_P(CTAD,DeductionGuideShouldCopyALocalTypedef)6051 TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) {
6052   Decl *TU = getTuDecl(
6053       R"(
6054       template <typename T> struct A {
6055         typedef T U;
6056         A(U, T);
6057       };
6058       A a{(int)0, (int)0};
6059       )",
6060       Lang_CXX17, "input.cc");
6061   auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
6062       TU, cxxDeductionGuideDecl());
6063   auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
6064       TU, typedefNameDecl(hasName("U")));
6065   ParmVarDecl *Param = Guide->getParamDecl(0);
6066   EXPECT_NE(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
6067 }
6068 
6069 INSTANTIATE_TEST_CASE_P(ParameterizedTests, CTAD,
6070                         DefaultTestValuesForRunOptions, );
6071 
6072 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
6073                         DefaultTestValuesForRunOptions, );
6074 
6075 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportPath,
6076                         ::testing::Values(std::vector<std::string>()), );
6077 
6078 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportExpr,
6079                         DefaultTestValuesForRunOptions, );
6080 
6081 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFixedPointExpr,
6082                         ExtendWithOptions(DefaultTestArrayForRunOptions,
6083                                           std::vector<std::string>{
6084                                               "-ffixed-point"}), );
6085 
6086 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportType,
6087                         DefaultTestValuesForRunOptions, );
6088 
6089 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportDecl,
6090                         DefaultTestValuesForRunOptions, );
6091 
6092 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterOptionSpecificTestBase,
6093                         DefaultTestValuesForRunOptions, );
6094 
6095 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ErrorHandlingTest,
6096                         DefaultTestValuesForRunOptions, );
6097 
6098 INSTANTIATE_TEST_CASE_P(ParameterizedTests, RedirectingImporterTest,
6099                         DefaultTestValuesForRunOptions, );
6100 
6101 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions,
6102                         DefaultTestValuesForRunOptions, );
6103 
6104 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportAutoFunctions,
6105                         DefaultTestValuesForRunOptions, );
6106 
6107 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctionTemplates,
6108                         DefaultTestValuesForRunOptions, );
6109 
6110 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctionTemplates,
6111                         DefaultTestValuesForRunOptions, );
6112 
6113 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
6114                         DefaultTestValuesForRunOptions, );
6115 
6116 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctions,
6117                         DefaultTestValuesForRunOptions, );
6118 
6119 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendClasses,
6120                         DefaultTestValuesForRunOptions, );
6121 
6122 INSTANTIATE_TEST_CASE_P(ParameterizedTests,
6123                         ImportFunctionTemplateSpecializations,
6124                         DefaultTestValuesForRunOptions, );
6125 
6126 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportImplicitMethods,
6127                         DefaultTestValuesForRunOptions, );
6128 
6129 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportVariables,
6130                         DefaultTestValuesForRunOptions, );
6131 
6132 INSTANTIATE_TEST_CASE_P(ParameterizedTests, LLDBLookupTest,
6133                         DefaultTestValuesForRunOptions, );
6134 
6135 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportSourceLocations,
6136                         DefaultTestValuesForRunOptions, );
6137 
6138 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportWithExternalSource,
6139                         DefaultTestValuesForRunOptions, );
6140 
6141 } // end namespace ast_matchers
6142 } // end namespace clang
6143