Clang Project

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