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