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