Mercurial > hg > CbC > CbC_llvm
view clang/unittests/Lex/ModuleDeclStateTest.cpp @ 266:00f31e85ec16 default tip
Added tag current for changeset 31d058e83c98
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Oct 2023 10:13:55 +0900 |
parents | 1f2b6ac9f198 |
children |
line wrap: on
line source
//===- unittests/Lex/ModuleDeclStateTest.cpp - PPCallbacks tests ------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===--------------------------------------------------------------===// #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/ModuleLoader.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" #include "gtest/gtest.h" #include <cstddef> #include <initializer_list> using namespace clang; namespace { class CheckNamedModuleImportingCB : public PPCallbacks { Preprocessor &PP; std::vector<bool> IsImportingNamedModulesAssertions; std::size_t NextCheckingIndex; public: CheckNamedModuleImportingCB(Preprocessor &PP, std::initializer_list<bool> lists) : PP(PP), IsImportingNamedModulesAssertions(lists), NextCheckingIndex(0) { } void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported) override { ASSERT_TRUE(NextCheckingIndex < IsImportingNamedModulesAssertions.size()); EXPECT_EQ(PP.isInImportingCXXNamedModules(), IsImportingNamedModulesAssertions[NextCheckingIndex]); NextCheckingIndex++; ASSERT_EQ(Imported, nullptr); } // Currently, only the named module will be handled by `moduleImport` // callback. std::size_t importNamedModuleNum() { return NextCheckingIndex; } }; class ModuleDeclStateTest : public ::testing::Test { protected: ModuleDeclStateTest() : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()), Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()), SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions) { TargetOpts->Triple = "x86_64-unknown-linux-gnu"; Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); } std::unique_ptr<Preprocessor> getPreprocessor(const char *source, Language Lang) { std::unique_ptr<llvm::MemoryBuffer> Buf = llvm::MemoryBuffer::getMemBuffer(source); SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); std::vector<std::string> Includes; LangOptions::setLangDefaults(LangOpts, Lang, Target->getTriple(), Includes, LangStandard::lang_cxx20); LangOpts.CPlusPlusModules = true; if (Lang != Language::CXX) { LangOpts.Modules = true; LangOpts.ImplicitModules = true; } HeaderInfo.emplace(std::make_shared<HeaderSearchOptions>(), SourceMgr, Diags, LangOpts, Target.get()); return std::make_unique<Preprocessor>( std::make_shared<PreprocessorOptions>(), Diags, LangOpts, SourceMgr, *HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); } void preprocess(Preprocessor &PP, std::unique_ptr<PPCallbacks> C) { PP.Initialize(*Target); PP.addPPCallbacks(std::move(C)); PP.EnterMainSourceFile(); while (1) { Token tok; PP.Lex(tok); if (tok.is(tok::eof)) break; } } FileSystemOptions FileMgrOpts; FileManager FileMgr; IntrusiveRefCntPtr<DiagnosticIDs> DiagID; DiagnosticsEngine Diags; SourceManager SourceMgr; std::shared_ptr<TargetOptions> TargetOpts; IntrusiveRefCntPtr<TargetInfo> Target; LangOptions LangOpts; TrivialModuleLoader ModLoader; std::optional<HeaderSearch> HeaderInfo; }; TEST_F(ModuleDeclStateTest, NamedModuleInterface) { const char *source = R"( export module foo; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0); EXPECT_TRUE(PP->isInNamedModule()); EXPECT_TRUE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); EXPECT_EQ(PP->getNamedModuleName(), "foo"); } TEST_F(ModuleDeclStateTest, NamedModuleImplementation) { const char *source = R"( module foo; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0); EXPECT_TRUE(PP->isInNamedModule()); EXPECT_FALSE(PP->isInNamedInterfaceUnit()); EXPECT_TRUE(PP->isInImplementationUnit()); EXPECT_EQ(PP->getNamedModuleName(), "foo"); } TEST_F(ModuleDeclStateTest, ModuleImplementationPartition) { const char *source = R"( module foo:part; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0); EXPECT_TRUE(PP->isInNamedModule()); EXPECT_FALSE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); EXPECT_EQ(PP->getNamedModuleName(), "foo:part"); } TEST_F(ModuleDeclStateTest, ModuleInterfacePartition) { const char *source = R"( export module foo:part; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0); EXPECT_TRUE(PP->isInNamedModule()); EXPECT_TRUE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); EXPECT_EQ(PP->getNamedModuleName(), "foo:part"); } TEST_F(ModuleDeclStateTest, ModuleNameWithDot) { const char *source = R"( export module foo.dot:part.dot; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0); EXPECT_TRUE(PP->isInNamedModule()); EXPECT_TRUE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); EXPECT_EQ(PP->getNamedModuleName(), "foo.dot:part.dot"); } TEST_F(ModuleDeclStateTest, NotModule) { const char *source = R"( // export module foo:part; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)0); EXPECT_FALSE(PP->isInNamedModule()); EXPECT_FALSE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); } TEST_F(ModuleDeclStateTest, ModuleWithGMF) { const char *source = R"( module; #include "bar.h" #include <zoo.h> import "bar"; import <zoo>; export module foo:part; import "HU"; import M; import :another; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {true, true}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)2); EXPECT_TRUE(PP->isInNamedModule()); EXPECT_TRUE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); EXPECT_EQ(PP->getNamedModuleName(), "foo:part"); } TEST_F(ModuleDeclStateTest, ModuleWithGMFWithClangNamedModule) { const char *source = R"( module; #include "bar.h" #include <zoo.h> import "bar"; import <zoo>; export module foo:part; import "HU"; import M; import :another; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {true, true}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)2); EXPECT_TRUE(PP->isInNamedModule()); EXPECT_TRUE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); EXPECT_EQ(PP->getNamedModuleName(), "foo:part"); } TEST_F(ModuleDeclStateTest, ImportsInNormalTU) { const char *source = R"( #include "bar.h" #include <zoo.h> import "bar"; import <zoo>; import "HU"; import M; // We can't import a partition in non-module TU. import :another; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::CXX); std::initializer_list<bool> ImportKinds = {true}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)1); EXPECT_FALSE(PP->isInNamedModule()); EXPECT_FALSE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); } TEST_F(ModuleDeclStateTest, ImportAClangNamedModule) { const char *source = R"( @import anything; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::ObjCXX); std::initializer_list<bool> ImportKinds = {false}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)1); EXPECT_FALSE(PP->isInNamedModule()); EXPECT_FALSE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); } TEST_F(ModuleDeclStateTest, ImportWixedForm) { const char *source = R"( import "HU"; @import anything; import M; @import another; import M2; )"; std::unique_ptr<Preprocessor> PP = getPreprocessor(source, Language::ObjCXX); std::initializer_list<bool> ImportKinds = {false, true, false, true}; preprocess(*PP, std::make_unique<CheckNamedModuleImportingCB>(*PP, ImportKinds)); auto *Callback = static_cast<CheckNamedModuleImportingCB *>(PP->getPPCallbacks()); EXPECT_EQ(Callback->importNamedModuleNum(), (size_t)4); EXPECT_FALSE(PP->isInNamedModule()); EXPECT_FALSE(PP->isInNamedInterfaceUnit()); EXPECT_FALSE(PP->isInImplementationUnit()); } } // namespace