16470706bSChuanqi Xu //===- unittests/Lex/ModuleDeclStateTest.cpp - PPCallbacks tests ------===//
26470706bSChuanqi Xu //
36470706bSChuanqi Xu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
46470706bSChuanqi Xu // See https://llvm.org/LICENSE.txt for license information.
56470706bSChuanqi Xu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66470706bSChuanqi Xu //
76470706bSChuanqi Xu //===--------------------------------------------------------------===//
86470706bSChuanqi Xu
96470706bSChuanqi Xu #include "clang/Basic/Diagnostic.h"
106470706bSChuanqi Xu #include "clang/Basic/DiagnosticOptions.h"
116470706bSChuanqi Xu #include "clang/Basic/FileManager.h"
126470706bSChuanqi Xu #include "clang/Basic/LangOptions.h"
136470706bSChuanqi Xu #include "clang/Basic/SourceManager.h"
146470706bSChuanqi Xu #include "clang/Basic/TargetInfo.h"
156470706bSChuanqi Xu #include "clang/Basic/TargetOptions.h"
166470706bSChuanqi Xu #include "clang/Lex/HeaderSearch.h"
176470706bSChuanqi Xu #include "clang/Lex/HeaderSearchOptions.h"
186470706bSChuanqi Xu #include "clang/Lex/ModuleLoader.h"
196470706bSChuanqi Xu #include "clang/Lex/Preprocessor.h"
206470706bSChuanqi Xu #include "clang/Lex/PreprocessorOptions.h"
216470706bSChuanqi Xu #include "gtest/gtest.h"
226470706bSChuanqi Xu #include <cstddef>
236470706bSChuanqi Xu #include <initializer_list>
246470706bSChuanqi Xu
256470706bSChuanqi Xu using namespace clang;
266470706bSChuanqi Xu
276470706bSChuanqi Xu namespace {
286470706bSChuanqi Xu
296470706bSChuanqi Xu class CheckNamedModuleImportingCB : public PPCallbacks {
306470706bSChuanqi Xu Preprocessor &PP;
316470706bSChuanqi Xu std::vector<bool> IsImportingNamedModulesAssertions;
326470706bSChuanqi Xu std::size_t NextCheckingIndex;
336470706bSChuanqi Xu
346470706bSChuanqi Xu public:
CheckNamedModuleImportingCB(Preprocessor & PP,std::initializer_list<bool> lists)356470706bSChuanqi Xu CheckNamedModuleImportingCB(Preprocessor &PP,
366470706bSChuanqi Xu std::initializer_list<bool> lists)
376470706bSChuanqi Xu : PP(PP), IsImportingNamedModulesAssertions(lists), NextCheckingIndex(0) {
386470706bSChuanqi Xu }
396470706bSChuanqi Xu
moduleImport(SourceLocation ImportLoc,ModuleIdPath Path,const Module * Imported)406470706bSChuanqi Xu void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
416470706bSChuanqi Xu const Module *Imported) override {
426470706bSChuanqi Xu ASSERT_TRUE(NextCheckingIndex < IsImportingNamedModulesAssertions.size());
436470706bSChuanqi Xu EXPECT_EQ(PP.isInImportingCXXNamedModules(),
446470706bSChuanqi Xu IsImportingNamedModulesAssertions[NextCheckingIndex]);
456470706bSChuanqi Xu NextCheckingIndex++;
466470706bSChuanqi Xu
476470706bSChuanqi Xu ASSERT_EQ(Imported, nullptr);
486470706bSChuanqi Xu }
496470706bSChuanqi Xu
506470706bSChuanqi Xu // Currently, only the named module will be handled by `moduleImport`
516470706bSChuanqi Xu // callback.
importNamedModuleNum()526470706bSChuanqi Xu std::size_t importNamedModuleNum() { return NextCheckingIndex; }
536470706bSChuanqi Xu };
546470706bSChuanqi Xu class ModuleDeclStateTest : public ::testing::Test {
556470706bSChuanqi Xu protected:
ModuleDeclStateTest()566470706bSChuanqi Xu ModuleDeclStateTest()
576470706bSChuanqi Xu : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
586470706bSChuanqi Xu Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
5954cf24dcSChuanqi Xu SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) {
606470706bSChuanqi Xu TargetOpts->Triple = "x86_64-unknown-linux-gnu";
616470706bSChuanqi Xu Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
626470706bSChuanqi Xu }
636470706bSChuanqi Xu
646470706bSChuanqi Xu std::unique_ptr<Preprocessor>
getPreprocessor(const char * source,Language Lang)6554cf24dcSChuanqi Xu getPreprocessor(const char *source, Language Lang) {
666470706bSChuanqi Xu std::unique_ptr<llvm::MemoryBuffer> Buf =
676470706bSChuanqi Xu llvm::MemoryBuffer::getMemBuffer(source);
686470706bSChuanqi Xu SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
696470706bSChuanqi Xu
7054cf24dcSChuanqi Xu std::vector<std::string> Includes;
7154cf24dcSChuanqi Xu LangOptions::setLangDefaults(LangOpts, Lang, Target->getTriple(), Includes, LangStandard::lang_cxx20);
7254cf24dcSChuanqi Xu LangOpts.CPlusPlusModules = true;
7354cf24dcSChuanqi Xu if (Lang != Language::CXX) {
7454cf24dcSChuanqi Xu LangOpts.Modules = true;
7554cf24dcSChuanqi Xu LangOpts.ImplicitModules = true;
7654cf24dcSChuanqi Xu }
7754cf24dcSChuanqi Xu
786470706bSChuanqi Xu HeaderInfo.emplace(std::make_shared<HeaderSearchOptions>(), SourceMgr,
796470706bSChuanqi Xu Diags, LangOpts, Target.get());
806470706bSChuanqi Xu
816470706bSChuanqi Xu return std::make_unique<Preprocessor>(
826470706bSChuanqi Xu std::make_shared<PreprocessorOptions>(), Diags, LangOpts, SourceMgr,
836470706bSChuanqi Xu *HeaderInfo, ModLoader,
846470706bSChuanqi Xu /*IILookup =*/nullptr,
856470706bSChuanqi Xu /*OwnsHeaderSearch =*/false);
866470706bSChuanqi Xu }
876470706bSChuanqi Xu
preprocess(Preprocessor & PP,std::unique_ptr<PPCallbacks> C)886470706bSChuanqi Xu void preprocess(Preprocessor &PP, std::unique_ptr<PPCallbacks> C) {
896470706bSChuanqi Xu PP.Initialize(*Target);
906470706bSChuanqi Xu PP.addPPCallbacks(std::move(C));
916470706bSChuanqi Xu PP.EnterMainSourceFile();
926470706bSChuanqi Xu
93*3116d604SJonas Hahnfeld PP.LexTokensUntilEOF();
946470706bSChuanqi Xu }
956470706bSChuanqi Xu
966470706bSChuanqi Xu FileSystemOptions FileMgrOpts;
976470706bSChuanqi Xu FileManager FileMgr;
986470706bSChuanqi Xu IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
996470706bSChuanqi Xu DiagnosticsEngine Diags;
1006470706bSChuanqi Xu SourceManager SourceMgr;
1016470706bSChuanqi Xu std::shared_ptr<TargetOptions> TargetOpts;
1026470706bSChuanqi Xu IntrusiveRefCntPtr<TargetInfo> Target;
10354cf24dcSChuanqi Xu LangOptions LangOpts;
1046470706bSChuanqi Xu TrivialModuleLoader ModLoader;
1056470706bSChuanqi Xu std::optional<HeaderSearch> HeaderInfo;
1066470706bSChuanqi Xu };
1076470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,NamedModuleInterface)1086470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, NamedModuleInterface) {
1096470706bSChuanqi Xu const char *source = R"(
1106470706bSChuanqi Xu export module foo;
1116470706bSChuanqi Xu )";
11254cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
1136470706bSChuanqi Xu
1146470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {};
1156470706bSChuanqi Xu preprocess(*PP,
1166470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
1176470706bSChuanqi Xu
1186470706bSChuanqi Xu auto *Callback =
1196470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
12035537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0);
1216470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedModule());
1226470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedInterfaceUnit());
1236470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
1246470706bSChuanqi Xu EXPECT_EQ(PP->getNamedModuleName(), "foo");
1256470706bSChuanqi Xu }
1266470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,NamedModuleImplementation)1276470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, NamedModuleImplementation) {
1286470706bSChuanqi Xu const char *source = R"(
1296470706bSChuanqi Xu module foo;
1306470706bSChuanqi Xu )";
13154cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
1326470706bSChuanqi Xu
1336470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {};
1346470706bSChuanqi Xu preprocess(*PP,
1356470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
1366470706bSChuanqi Xu
1376470706bSChuanqi Xu auto *Callback =
1386470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
13935537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0);
1406470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedModule());
1416470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedInterfaceUnit());
1426470706bSChuanqi Xu EXPECT_TRUE(PP->isInImplementationUnit());
1436470706bSChuanqi Xu EXPECT_EQ(PP->getNamedModuleName(), "foo");
1446470706bSChuanqi Xu }
1456470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ModuleImplementationPartition)1466470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ModuleImplementationPartition) {
1476470706bSChuanqi Xu const char *source = R"(
1486470706bSChuanqi Xu module foo:part;
1496470706bSChuanqi Xu )";
15054cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
1516470706bSChuanqi Xu
1526470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {};
1536470706bSChuanqi Xu preprocess(*PP,
1546470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
1556470706bSChuanqi Xu
1566470706bSChuanqi Xu auto *Callback =
1576470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
15835537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0);
1596470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedModule());
1606470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedInterfaceUnit());
1616470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
1626470706bSChuanqi Xu EXPECT_EQ(PP->getNamedModuleName(), "foo:part");
1636470706bSChuanqi Xu }
1646470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ModuleInterfacePartition)1656470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ModuleInterfacePartition) {
1666470706bSChuanqi Xu const char *source = R"(
1676470706bSChuanqi Xu export module foo:part;
1686470706bSChuanqi Xu )";
16954cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
1706470706bSChuanqi Xu
1716470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {};
1726470706bSChuanqi Xu preprocess(*PP,
1736470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
1746470706bSChuanqi Xu
1756470706bSChuanqi Xu auto *Callback =
1766470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
17735537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0);
1786470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedModule());
1796470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedInterfaceUnit());
1806470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
1816470706bSChuanqi Xu EXPECT_EQ(PP->getNamedModuleName(), "foo:part");
1826470706bSChuanqi Xu }
1836470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ModuleNameWithDot)1846470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ModuleNameWithDot) {
1856470706bSChuanqi Xu const char *source = R"(
1866470706bSChuanqi Xu export module foo.dot:part.dot;
1876470706bSChuanqi Xu )";
18854cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
1896470706bSChuanqi Xu
1906470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {};
1916470706bSChuanqi Xu preprocess(*PP,
1926470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
1936470706bSChuanqi Xu
1946470706bSChuanqi Xu auto *Callback =
1956470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
19635537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0);
1976470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedModule());
1986470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedInterfaceUnit());
1996470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
2006470706bSChuanqi Xu EXPECT_EQ(PP->getNamedModuleName(), "foo.dot:part.dot");
2016470706bSChuanqi Xu }
2026470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,NotModule)2036470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, NotModule) {
2046470706bSChuanqi Xu const char *source = R"(
2056470706bSChuanqi Xu // export module foo:part;
2066470706bSChuanqi Xu )";
20754cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
2086470706bSChuanqi Xu
2096470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {};
2106470706bSChuanqi Xu preprocess(*PP,
2116470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
2126470706bSChuanqi Xu
2136470706bSChuanqi Xu auto *Callback =
2146470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
21535537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0);
2166470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedModule());
2176470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedInterfaceUnit());
2186470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
2196470706bSChuanqi Xu }
2206470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ModuleWithGMF)2216470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ModuleWithGMF) {
2226470706bSChuanqi Xu const char *source = R"(
2236470706bSChuanqi Xu module;
2246470706bSChuanqi Xu #include "bar.h"
2256470706bSChuanqi Xu #include <zoo.h>
2266470706bSChuanqi Xu import "bar";
2276470706bSChuanqi Xu import <zoo>;
2286470706bSChuanqi Xu export module foo:part;
2296470706bSChuanqi Xu import "HU";
2306470706bSChuanqi Xu import M;
2316470706bSChuanqi Xu import :another;
2326470706bSChuanqi Xu )";
23354cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
2346470706bSChuanqi Xu
2356470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {true, true};
2366470706bSChuanqi Xu preprocess(*PP,
2376470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
2386470706bSChuanqi Xu
2396470706bSChuanqi Xu auto *Callback =
2406470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
24135537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)2);
2426470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedModule());
2436470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedInterfaceUnit());
2446470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
2456470706bSChuanqi Xu EXPECT_EQ(PP->getNamedModuleName(), "foo:part");
2466470706bSChuanqi Xu }
2476470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ModuleWithGMFWithClangNamedModule)2486470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ModuleWithGMFWithClangNamedModule) {
2496470706bSChuanqi Xu const char *source = R"(
2506470706bSChuanqi Xu module;
2516470706bSChuanqi Xu #include "bar.h"
2526470706bSChuanqi Xu #include <zoo.h>
2536470706bSChuanqi Xu import "bar";
2546470706bSChuanqi Xu import <zoo>;
2556470706bSChuanqi Xu export module foo:part;
2566470706bSChuanqi Xu import "HU";
2576470706bSChuanqi Xu import M;
2586470706bSChuanqi Xu import :another;
2596470706bSChuanqi Xu )";
26054cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
2616470706bSChuanqi Xu
2626470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {true, true};
2636470706bSChuanqi Xu preprocess(*PP,
2646470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
2656470706bSChuanqi Xu
2666470706bSChuanqi Xu auto *Callback =
2676470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
26835537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)2);
2696470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedModule());
2706470706bSChuanqi Xu EXPECT_TRUE(PP->isInNamedInterfaceUnit());
2716470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
2726470706bSChuanqi Xu EXPECT_EQ(PP->getNamedModuleName(), "foo:part");
2736470706bSChuanqi Xu }
2746470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ImportsInNormalTU)2756470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ImportsInNormalTU) {
2766470706bSChuanqi Xu const char *source = R"(
2776470706bSChuanqi Xu #include "bar.h"
2786470706bSChuanqi Xu #include <zoo.h>
2796470706bSChuanqi Xu import "bar";
2806470706bSChuanqi Xu import <zoo>;
2816470706bSChuanqi Xu import "HU";
2826470706bSChuanqi Xu import M;
2836470706bSChuanqi Xu // We can't import a partition in non-module TU.
2846470706bSChuanqi Xu import :another;
2856470706bSChuanqi Xu )";
28654cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX);
2876470706bSChuanqi Xu
2886470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {true};
2896470706bSChuanqi Xu preprocess(*PP,
2906470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
2916470706bSChuanqi Xu
2926470706bSChuanqi Xu auto *Callback =
2936470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
29435537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)1);
2956470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedModule());
2966470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedInterfaceUnit());
2976470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
2986470706bSChuanqi Xu }
2996470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ImportAClangNamedModule)3006470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ImportAClangNamedModule) {
3016470706bSChuanqi Xu const char *source = R"(
3026470706bSChuanqi Xu @import anything;
3036470706bSChuanqi Xu )";
30454cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::ObjCXX);
3056470706bSChuanqi Xu
3066470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {false};
3076470706bSChuanqi Xu preprocess(*PP,
3086470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
3096470706bSChuanqi Xu
3106470706bSChuanqi Xu auto *Callback =
3116470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
31235537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)1);
3136470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedModule());
3146470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedInterfaceUnit());
3156470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
3166470706bSChuanqi Xu }
3176470706bSChuanqi Xu
TEST_F(ModuleDeclStateTest,ImportWixedForm)3186470706bSChuanqi Xu TEST_F(ModuleDeclStateTest, ImportWixedForm) {
3196470706bSChuanqi Xu const char *source = R"(
3206470706bSChuanqi Xu import "HU";
3216470706bSChuanqi Xu @import anything;
3226470706bSChuanqi Xu import M;
3236470706bSChuanqi Xu @import another;
3246470706bSChuanqi Xu import M2;
3256470706bSChuanqi Xu )";
32654cf24dcSChuanqi Xu std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::ObjCXX);
3276470706bSChuanqi Xu
3286470706bSChuanqi Xu std::initializer_list<bool> ImportKinds = {false, true, false, true};
3296470706bSChuanqi Xu preprocess(*PP,
3306470706bSChuanqi Xu std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds));
3316470706bSChuanqi Xu
3326470706bSChuanqi Xu auto *Callback =
3336470706bSChuanqi Xu static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks());
33435537aeaSJie Fu EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)4);
3356470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedModule());
3366470706bSChuanqi Xu EXPECT_FALSE(PP->isInNamedInterfaceUnit());
3376470706bSChuanqi Xu EXPECT_FALSE(PP->isInImplementationUnit());
3386470706bSChuanqi Xu }
3396470706bSChuanqi Xu
3406470706bSChuanqi Xu } // namespace
341