mirror of
https://github.com/intel/llvm.git
synced 2026-01-25 10:55:58 +08:00
[C++20] [Modules] Remove unmaintained Header Module
Currently there is a -emit-header-module mode, which can combine several headers together as a module interface. However, this breaks our assumption (for standard c++ modules) about module interface. The module interface should come from a module interface unit. And if it is a header, it should be a header unit. And currently we have no ideas to combine several headers together. So I think this mode is an experimental one and it is not maintained and it is not used. So it will be better to remove them. Reviewed By: Bigcheese, dblaikie, bruno Differential Revision: https://reviews.llvm.org/D137609
This commit is contained in:
@@ -436,26 +436,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class HeaderModulePrecompileJobAction : public PrecompileJobAction {
|
||||
void anchor() override;
|
||||
|
||||
const char *ModuleName;
|
||||
|
||||
public:
|
||||
HeaderModulePrecompileJobAction(Action *Input, types::ID OutputType,
|
||||
const char *ModuleName);
|
||||
|
||||
static bool classof(const Action *A) {
|
||||
return A->getKind() == HeaderModulePrecompileJobClass;
|
||||
}
|
||||
|
||||
void addModuleHeaderInput(Action *Input) {
|
||||
getInputs().push_back(Input);
|
||||
}
|
||||
|
||||
const char *getModuleName() const { return ModuleName; }
|
||||
};
|
||||
|
||||
class ExtractAPIJobAction : public JobAction {
|
||||
void anchor() override;
|
||||
|
||||
|
||||
@@ -5934,8 +5934,6 @@ def emit_module : Flag<["-"], "emit-module">,
|
||||
HelpText<"Generate pre-compiled module file from a module map">;
|
||||
def emit_module_interface : Flag<["-"], "emit-module-interface">,
|
||||
HelpText<"Generate pre-compiled module file from a C++ module interface">;
|
||||
def emit_header_module : Flag<["-"], "emit-header-module">,
|
||||
HelpText<"Generate pre-compiled module file from a set of header files">;
|
||||
def emit_header_unit : Flag<["-"], "emit-header-unit">,
|
||||
HelpText<"Generate C++20 header units from header files">;
|
||||
def emit_pch : Flag<["-"], "emit-pch">,
|
||||
|
||||
@@ -155,19 +155,6 @@ private:
|
||||
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
|
||||
};
|
||||
|
||||
class GenerateHeaderModuleAction : public GenerateModuleAction {
|
||||
/// The synthesized module input buffer for the current compilation.
|
||||
std::unique_ptr<llvm::MemoryBuffer> Buffer;
|
||||
std::vector<std::string> ModuleHeaders;
|
||||
|
||||
private:
|
||||
bool PrepareToExecuteAction(CompilerInstance &CI) override;
|
||||
bool BeginSourceFileAction(CompilerInstance &CI) override;
|
||||
|
||||
std::unique_ptr<raw_pwrite_stream>
|
||||
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
|
||||
};
|
||||
|
||||
class GenerateHeaderUnitAction : public GenerateModuleAction {
|
||||
|
||||
private:
|
||||
|
||||
@@ -87,9 +87,6 @@ enum ActionKind {
|
||||
/// Generate pre-compiled module from a C++ module interface file.
|
||||
GenerateModuleInterface,
|
||||
|
||||
/// Generate pre-compiled module from a set of header files.
|
||||
GenerateHeaderModule,
|
||||
|
||||
/// Generate a C++20 header unit module from a header file.
|
||||
GenerateHeaderUnit,
|
||||
|
||||
|
||||
@@ -566,9 +566,6 @@ public:
|
||||
/// \returns The newly-created module.
|
||||
Module *createModuleForInterfaceUnit(SourceLocation Loc, StringRef Name);
|
||||
|
||||
/// Create a header module from the specified list of headers.
|
||||
Module *createHeaderModule(StringRef Name, ArrayRef<Module::Header> Headers);
|
||||
|
||||
/// Create a C++20 header unit.
|
||||
Module *createHeaderUnit(SourceLocation Loc, StringRef Name,
|
||||
Module::Header H);
|
||||
|
||||
@@ -25,7 +25,6 @@ const char *Action::getClassName(ActionClass AC) {
|
||||
return "offload";
|
||||
case PreprocessJobClass: return "preprocessor";
|
||||
case PrecompileJobClass: return "precompiler";
|
||||
case HeaderModulePrecompileJobClass: return "header-module-precompiler";
|
||||
case ExtractAPIJobClass:
|
||||
return "api-extractor";
|
||||
case AnalyzeJobClass: return "analyzer";
|
||||
@@ -352,13 +351,6 @@ PrecompileJobAction::PrecompileJobAction(ActionClass Kind, Action *Input,
|
||||
assert(isa<PrecompileJobAction>((Action*)this) && "invalid action kind");
|
||||
}
|
||||
|
||||
void HeaderModulePrecompileJobAction::anchor() {}
|
||||
|
||||
HeaderModulePrecompileJobAction::HeaderModulePrecompileJobAction(
|
||||
Action *Input, types::ID OutputType, const char *ModuleName)
|
||||
: PrecompileJobAction(HeaderModulePrecompileJobClass, Input, OutputType),
|
||||
ModuleName(ModuleName) {}
|
||||
|
||||
void ExtractAPIJobAction::anchor() {}
|
||||
|
||||
ExtractAPIJobAction::ExtractAPIJobAction(Action *Inputs, types::ID OutputType)
|
||||
|
||||
@@ -3957,7 +3957,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
|
||||
: nullptr;
|
||||
|
||||
// Construct the actions to perform.
|
||||
HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
|
||||
ExtractAPIJobAction *ExtractAPIAction = nullptr;
|
||||
ActionList LinkerInputs;
|
||||
ActionList MergerInputs;
|
||||
@@ -4012,16 +4011,6 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
|
||||
break;
|
||||
}
|
||||
|
||||
// Each precompiled header file after a module file action is a module
|
||||
// header of that same module file, rather than being compiled to a
|
||||
// separate PCH.
|
||||
if (Phase == phases::Precompile && HeaderModuleAction &&
|
||||
getPrecompiledType(InputType) == types::TY_PCH) {
|
||||
HeaderModuleAction->addModuleHeaderInput(Current);
|
||||
Current = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Phase == phases::Precompile && ExtractAPIAction) {
|
||||
ExtractAPIAction->addHeaderInput(Current);
|
||||
Current = nullptr;
|
||||
@@ -4038,9 +4027,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
|
||||
if (NewCurrent == Current)
|
||||
continue;
|
||||
|
||||
if (auto *HMA = dyn_cast<HeaderModulePrecompileJobAction>(NewCurrent))
|
||||
HeaderModuleAction = HMA;
|
||||
else if (auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
|
||||
if (auto *EAA = dyn_cast<ExtractAPIJobAction>(NewCurrent))
|
||||
ExtractAPIAction = EAA;
|
||||
|
||||
Current = NewCurrent;
|
||||
@@ -4524,9 +4511,6 @@ Action *Driver::ConstructPhaseAction(
|
||||
OutputTy = types::TY_Nothing;
|
||||
}
|
||||
|
||||
if (ModName)
|
||||
return C.MakeAction<HeaderModulePrecompileJobAction>(Input, OutputTy,
|
||||
ModName);
|
||||
return C.MakeAction<PrecompileJobAction>(Input, OutputTy);
|
||||
}
|
||||
case phases::Compile: {
|
||||
@@ -5303,10 +5287,6 @@ InputInfoList Driver::BuildJobsForActionNoCache(
|
||||
if (JA->getType() == types::TY_dSYM)
|
||||
BaseInput = InputInfos[0].getFilename();
|
||||
|
||||
// ... and in header module compilations, which use the module name.
|
||||
if (auto *ModuleJA = dyn_cast<HeaderModulePrecompileJobAction>(JA))
|
||||
BaseInput = ModuleJA->getModuleName();
|
||||
|
||||
// Append outputs of offload device jobs to the input list
|
||||
if (!OffloadDependencesInputInfo.empty())
|
||||
InputInfos.append(OffloadDependencesInputInfo.begin(),
|
||||
|
||||
@@ -4539,7 +4539,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
bool IsHIP = JA.isOffloading(Action::OFK_HIP);
|
||||
bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
|
||||
bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
|
||||
bool IsHeaderModulePrecompile = isa<HeaderModulePrecompileJobAction>(JA);
|
||||
bool IsExtractAPI = isa<ExtractAPIJobAction>(JA);
|
||||
bool IsDeviceOffloadAction = !(JA.isDeviceOffloading(Action::OFK_None) ||
|
||||
JA.isDeviceOffloading(Action::OFK_Host));
|
||||
@@ -4554,28 +4553,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
bool IsUsingLTO = D.isUsingLTO(IsDeviceOffloadAction);
|
||||
auto LTOMode = D.getLTOMode(IsDeviceOffloadAction);
|
||||
|
||||
// A header module compilation doesn't have a main input file, so invent a
|
||||
// fake one as a placeholder.
|
||||
const char *ModuleName = [&] {
|
||||
auto *ModuleNameArg = Args.getLastArg(options::OPT_fmodule_name_EQ);
|
||||
return ModuleNameArg ? ModuleNameArg->getValue() : "";
|
||||
}();
|
||||
InputInfo HeaderModuleInput(Inputs[0].getType(), ModuleName, ModuleName);
|
||||
|
||||
// Extract API doesn't have a main input file, so invent a fake one as a
|
||||
// placeholder.
|
||||
InputInfo ExtractAPIPlaceholderInput(Inputs[0].getType(), "extract-api",
|
||||
"extract-api");
|
||||
|
||||
const InputInfo &Input = [&]() -> const InputInfo & {
|
||||
if (IsHeaderModulePrecompile)
|
||||
return HeaderModuleInput;
|
||||
if (IsExtractAPI)
|
||||
return ExtractAPIPlaceholderInput;
|
||||
return Inputs[0];
|
||||
}();
|
||||
|
||||
InputInfoList ModuleHeaderInputs;
|
||||
InputInfoList ExtractAPIInputs;
|
||||
InputInfoList HostOffloadingInputs;
|
||||
const InputInfo *CudaDeviceInput = nullptr;
|
||||
@@ -4583,15 +4571,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
for (const InputInfo &I : Inputs) {
|
||||
if (&I == &Input || I.getType() == types::TY_Nothing) {
|
||||
// This is the primary input or contains nothing.
|
||||
} else if (IsHeaderModulePrecompile &&
|
||||
types::getPrecompiledType(I.getType()) == types::TY_PCH) {
|
||||
types::ID Expected = HeaderModuleInput.getType();
|
||||
if (I.getType() != Expected) {
|
||||
D.Diag(diag::err_drv_module_header_wrong_kind)
|
||||
<< I.getFilename() << types::getTypeName(I.getType())
|
||||
<< types::getTypeName(Expected);
|
||||
}
|
||||
ModuleHeaderInputs.push_back(I);
|
||||
} else if (IsExtractAPI) {
|
||||
auto ExpectedInputType = ExtractAPIPlaceholderInput.getType();
|
||||
if (I.getType() != ExpectedInputType) {
|
||||
@@ -4779,9 +4758,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
if (JA.getType() == types::TY_Nothing)
|
||||
CmdArgs.push_back("-fsyntax-only");
|
||||
else if (JA.getType() == types::TY_ModuleFile)
|
||||
CmdArgs.push_back(IsHeaderModulePrecompile
|
||||
? "-emit-header-module"
|
||||
: "-emit-module-interface");
|
||||
CmdArgs.push_back("-emit-module-interface");
|
||||
else if (JA.getType() == types::TY_HeaderUnit)
|
||||
CmdArgs.push_back("-emit-header-unit");
|
||||
else
|
||||
@@ -7376,9 +7353,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
addDashXForInput(Args, Input, CmdArgs);
|
||||
|
||||
ArrayRef<InputInfo> FrontendInputs = Input;
|
||||
if (IsHeaderModulePrecompile)
|
||||
FrontendInputs = ModuleHeaderInputs;
|
||||
else if (IsExtractAPI)
|
||||
if (IsExtractAPI)
|
||||
FrontendInputs = ExtractAPIInputs;
|
||||
else if (Input.isNothing())
|
||||
FrontendInputs = {};
|
||||
|
||||
@@ -2469,7 +2469,6 @@ static const auto &getFrontendActionTable() {
|
||||
|
||||
{frontend::GenerateModule, OPT_emit_module},
|
||||
{frontend::GenerateModuleInterface, OPT_emit_module_interface},
|
||||
{frontend::GenerateHeaderModule, OPT_emit_header_module},
|
||||
{frontend::GenerateHeaderUnit, OPT_emit_header_unit},
|
||||
{frontend::GeneratePCH, OPT_emit_pch},
|
||||
{frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
|
||||
@@ -4129,7 +4128,6 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
|
||||
case frontend::FixIt:
|
||||
case frontend::GenerateModule:
|
||||
case frontend::GenerateModuleInterface:
|
||||
case frontend::GenerateHeaderModule:
|
||||
case frontend::GenerateHeaderUnit:
|
||||
case frontend::GeneratePCH:
|
||||
case frontend::GenerateInterfaceStubs:
|
||||
|
||||
@@ -265,77 +265,6 @@ GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
|
||||
return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
|
||||
}
|
||||
|
||||
bool GenerateHeaderModuleAction::PrepareToExecuteAction(
|
||||
CompilerInstance &CI) {
|
||||
if (!CI.getLangOpts().Modules) {
|
||||
CI.getDiagnostics().Report(diag::err_header_module_requires_modules);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &Inputs = CI.getFrontendOpts().Inputs;
|
||||
if (Inputs.empty())
|
||||
return GenerateModuleAction::BeginInvocation(CI);
|
||||
|
||||
auto Kind = Inputs[0].getKind();
|
||||
|
||||
// Convert the header file inputs into a single module input buffer.
|
||||
SmallString<256> HeaderContents;
|
||||
ModuleHeaders.reserve(Inputs.size());
|
||||
for (const FrontendInputFile &FIF : Inputs) {
|
||||
// FIXME: We should support re-compiling from an AST file.
|
||||
if (FIF.getKind().getFormat() != InputKind::Source || !FIF.isFile()) {
|
||||
CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
|
||||
<< (FIF.isFile() ? FIF.getFile()
|
||||
: FIF.getBuffer().getBufferIdentifier());
|
||||
return true;
|
||||
}
|
||||
|
||||
HeaderContents += "#include \"";
|
||||
HeaderContents += FIF.getFile();
|
||||
HeaderContents += "\"\n";
|
||||
ModuleHeaders.push_back(std::string(FIF.getFile()));
|
||||
}
|
||||
Buffer = llvm::MemoryBuffer::getMemBufferCopy(
|
||||
HeaderContents, Module::getModuleInputBufferName());
|
||||
|
||||
// Set that buffer up as our "real" input.
|
||||
Inputs.clear();
|
||||
Inputs.push_back(
|
||||
FrontendInputFile(Buffer->getMemBufferRef(), Kind, /*IsSystem*/ false));
|
||||
|
||||
return GenerateModuleAction::PrepareToExecuteAction(CI);
|
||||
}
|
||||
|
||||
bool GenerateHeaderModuleAction::BeginSourceFileAction(
|
||||
CompilerInstance &CI) {
|
||||
CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderModule);
|
||||
|
||||
// Synthesize a Module object for the given headers.
|
||||
auto &HS = CI.getPreprocessor().getHeaderSearchInfo();
|
||||
SmallVector<Module::Header, 16> Headers;
|
||||
for (StringRef Name : ModuleHeaders) {
|
||||
Optional<FileEntryRef> FE = HS.LookupFile(
|
||||
Name, SourceLocation(), /*Angled*/ false, nullptr, nullptr, None,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
if (!FE) {
|
||||
CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
|
||||
<< Name;
|
||||
continue;
|
||||
}
|
||||
Headers.push_back(
|
||||
{std::string(Name), std::string(Name), &FE->getFileEntry()});
|
||||
}
|
||||
HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers);
|
||||
|
||||
return GenerateModuleAction::BeginSourceFileAction(CI);
|
||||
}
|
||||
|
||||
std::unique_ptr<raw_pwrite_stream>
|
||||
GenerateHeaderModuleAction::CreateOutputFile(CompilerInstance &CI,
|
||||
StringRef InFile) {
|
||||
return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
|
||||
}
|
||||
|
||||
bool GenerateHeaderUnitAction::BeginSourceFileAction(CompilerInstance &CI) {
|
||||
if (!CI.getLangOpts().CPlusPlusModules) {
|
||||
CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
|
||||
|
||||
@@ -65,8 +65,6 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
|
||||
return std::make_unique<GenerateModuleFromModuleMapAction>();
|
||||
case GenerateModuleInterface:
|
||||
return std::make_unique<GenerateModuleInterfaceAction>();
|
||||
case GenerateHeaderModule:
|
||||
return std::make_unique<GenerateHeaderModuleAction>();
|
||||
case GenerateHeaderUnit:
|
||||
return std::make_unique<GenerateHeaderUnitAction>();
|
||||
case GeneratePCH: return std::make_unique<GeneratePCHAction>();
|
||||
|
||||
@@ -899,29 +899,6 @@ Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
|
||||
return Result;
|
||||
}
|
||||
|
||||
Module *ModuleMap::createHeaderModule(StringRef Name,
|
||||
ArrayRef<Module::Header> Headers) {
|
||||
assert(LangOpts.CurrentModule == Name && "module name mismatch");
|
||||
assert(!Modules[Name] && "redefining existing module");
|
||||
|
||||
auto *Result =
|
||||
new Module(Name, SourceLocation(), nullptr, /*IsFramework*/ false,
|
||||
/*IsExplicit*/ false, NumCreatedModules++);
|
||||
Result->Kind = Module::ModuleInterfaceUnit;
|
||||
Modules[Name] = SourceModule = Result;
|
||||
|
||||
for (const Module::Header &H : Headers) {
|
||||
auto *M = new Module(H.NameAsWritten, SourceLocation(), Result,
|
||||
/*IsFramework*/ false,
|
||||
/*IsExplicit*/ true, NumCreatedModules++);
|
||||
// Header modules are implicitly 'export *'.
|
||||
M->Exports.push_back(Module::ExportDecl(nullptr, true));
|
||||
addHeader(M, H, NormalHeader);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
Module *ModuleMap::createHeaderUnit(SourceLocation Loc, StringRef Name,
|
||||
Module::Header H) {
|
||||
assert(LangOpts.CurrentModule == Name && "module name mismatch");
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#define ATTRS [[ ]]
|
||||
@@ -1,18 +0,0 @@
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-header-module -fmodule-name=attrs -x c++-header %S/Inputs/empty.h %S/Inputs/attrs.h -o %t.pcm
|
||||
// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -E -verify -I%S/Inputs | FileCheck %s
|
||||
|
||||
#define SEMI ;
|
||||
// expected-error@+1 {{semicolon terminating header import declaration cannot be produced by a macro}}
|
||||
import "empty.h" SEMI // CHECK: import attrs.{{.*}};
|
||||
|
||||
#define IMPORT import "empty.h"
|
||||
IMPORT; // CHECK: import attrs.{{.*}};
|
||||
|
||||
#define IMPORT_ANGLED import <empty.h>
|
||||
IMPORT_ANGLED; // CHECK: import attrs.{{.*}};
|
||||
|
||||
// Ensure that macros only become visible at the semicolon.
|
||||
// CHECK: import attrs.{{.*}} ATTRS ;
|
||||
import "attrs.h" ATTRS ;
|
||||
// CHECK: {{\[\[}} ]] int n;
|
||||
ATTRS int n;
|
||||
@@ -1,32 +0,0 @@
|
||||
// RUN: %clang_cc1 -std=c++2a -emit-header-module -fmodule-name=attrs -x c++-header %S/Inputs/empty.h %S/Inputs/attrs.h -o %t.pcm
|
||||
// RUN: %clang_cc1 -std=c++2a %s -fmodule-file=%t.pcm -fsyntax-only -verify -I%S/Inputs
|
||||
|
||||
template<int> struct import; // expected-note 2{{previous}}
|
||||
constexpr struct { int h; } empty = {0};
|
||||
struct A;
|
||||
struct B;
|
||||
struct C;
|
||||
template<> struct import<0> {
|
||||
static A a;
|
||||
static B b;
|
||||
static C c;
|
||||
};
|
||||
|
||||
// OK, not an import-declaration.
|
||||
struct A {}
|
||||
::import
|
||||
<empty.h>::a;
|
||||
|
||||
// This is invalid: the tokens after 'import' are a header-name, so cannot be
|
||||
// parsed as a template-argument-list.
|
||||
struct B {}
|
||||
import // expected-error {{redefinition of 'import'}} expected-error {{expected ';'}}
|
||||
<empty.h>::b; // (error recovery skips these tokens)
|
||||
|
||||
// Likewise, this is ill-formed after the tokens are reconstituted into a
|
||||
// header-name token.
|
||||
struct C {}
|
||||
import // expected-error {{redefinition of 'import'}} expected-error {{expected ';'}}
|
||||
<
|
||||
empty.h // (error recovery skips these tokens)
|
||||
>::c;
|
||||
@@ -1,11 +1,11 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t
|
||||
// RUN: %clang_cc1 -std=c++2a -x c++-header %S/Inputs/header.h -emit-header-module -fmodule-name=FIXME -o %t/h.pcm
|
||||
// RUN: %clang_cc1 -std=c++2a %s -DX_INTERFACE -emit-module-interface -o %t/x.pcm
|
||||
// RUN: %clang_cc1 -std=c++2a %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm
|
||||
// RUN: %clang_cc1 -std=c++2a %s -DINTERFACE -fmodule-file=%t/x.pcm -fmodule-file=%t/y.pcm -emit-module-interface -o %t/m.pcm
|
||||
// RUN: %clang_cc1 -std=c++2a %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
|
||||
// RUN: %clang_cc1 -std=c++2a %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
|
||||
// RUN: %clang_cc1 -std=c++20 -x c++-header %S/Inputs/header.h -emit-header-unit -o %t/h.pcm
|
||||
// RUN: %clang_cc1 -std=c++20 %s -DX_INTERFACE -emit-module-interface -o %t/x.pcm
|
||||
// RUN: %clang_cc1 -std=c++20 %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm
|
||||
// RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -fmodule-file=%t/x.pcm -fmodule-file=%t/y.pcm -emit-module-interface -o %t/m.pcm
|
||||
// RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
|
||||
// RUN: %clang_cc1 -std=c++20 %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=%t/m.pcm -verify
|
||||
|
||||
#if defined(X_INTERFACE)
|
||||
export module X;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
// Check compiling a header module to a .pcm file.
|
||||
//
|
||||
// RUN: %clang -fmodules-ts -fmodule-name=foobar -x c++-header --precompile %S/Inputs/header1.h %S/Inputs/header2.h %S/Inputs/header3.h -o %t.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE
|
||||
//
|
||||
// CHECK-PRECOMPILE: -cc1 {{.*}} -emit-header-module
|
||||
// CHECK-PRECOMPILE-SAME: -fmodules-ts
|
||||
// CHECK-PRECOMPILE-SAME: -fno-implicit-modules
|
||||
// CHECK-PRECOMPILE-SAME: -fmodule-name=foobar
|
||||
// CHECK-PRECOMPILE-SAME: -o {{.*}}.pcm
|
||||
// CHECK-PRECOMPILE-SAME: -x c++-header
|
||||
// CHECK-PRECOMPILE-SAME: header1.h
|
||||
// CHECK-PRECOMPILE-SAME: header2.h
|
||||
// CHECK-PRECOMPILE-SAME: header3.h
|
||||
//
|
||||
// RUN: %clang -fmodules-ts -fmodule-name=foobar -x c++-header -fsyntax-only %S/Inputs/header1.h %S/Inputs/header2.h %S/Inputs/header3.h -v 2>&1 | FileCheck %s --check-prefix=CHECK-SYNTAX-ONLY
|
||||
// CHECK-SYNTAX-ONLY: -cc1 {{.*}} -fsyntax-only
|
||||
// CHECK-SYNTAX-ONLY-SAME: -fmodules-ts
|
||||
// CHECK-SYNTAX-ONLY-SAME: -fno-implicit-modules
|
||||
// CHECK-SYNTAX-ONLY-SAME: -fmodule-name=foobar
|
||||
// CHECK-SYNTAX-ONLY-NOT: -o{{ }}
|
||||
// CHECK-SYNTAX-ONLY-SAME: -x c++-header
|
||||
// CHECK-SYNTAX-ONLY-SAME: header1.h
|
||||
// CHECK-SYNTAX-ONLY-SAME: header2.h
|
||||
// CHECK-SYNTAX-ONLY-SAME: header3.h
|
||||
@@ -39,37 +39,4 @@
|
||||
// RUN: cp %s %t/module.cppm
|
||||
// RUN: %clang -std=c++2a --precompile %t/module.cppm -o %t/module.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE
|
||||
|
||||
// Check compiling a header unit to a .pcm file.
|
||||
//
|
||||
// RUN: echo '#define FOO BAR' > %t/foo.h
|
||||
// RUN: %clang -std=c++2a --precompile -x c++-header %t/foo.h -fmodule-name=header -o %t/foo.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-HEADER-UNIT
|
||||
//
|
||||
// CHECK-HEADER-UNIT: -cc1
|
||||
// CHECK-HEADER-UNIT-SAME: -emit-header-module
|
||||
// CHECK-HEADER-UNIT-SAME: -fmodule-name=header
|
||||
// CHECK-HEADER-UNIT-SAME: -o {{.*}}foo.pcm
|
||||
// CHECK-HEADER-UNIT-SAME: -x c++-header
|
||||
// CHECK-HEADER-UNIT-SAME: foo.h
|
||||
|
||||
// Check use of header unit.
|
||||
//
|
||||
// RUN: %clang -std=c++2a -fmodule-file=%t/module.pcm -fmodule-file=%t/foo.pcm -I%t -DIMPORT -Dexport= %s -E -o - -v 2>&1 | FileCheck %s --check-prefix=CHECK-HEADER-UNIT-USE
|
||||
//
|
||||
// CHECK-HEADER-UNIT-USE: -cc1
|
||||
// CHECK-HEADER-UNIT-USE: -E
|
||||
// CHECK-HEADER-UNIT-USE: -fmodule-file={{.*}}module.pcm
|
||||
// CHECK-HEADER-UNIT-USE: -fmodule-file={{.*}}foo.pcm
|
||||
|
||||
// Note, we use -Dexport= to make this a module implementation unit when building the implementation.
|
||||
export module foo;
|
||||
|
||||
#ifdef IMPORT
|
||||
// CHECK-HEADER-UNIT-USE: FOO;
|
||||
FOO;
|
||||
|
||||
// CHECK-HEADER-UNIT-USE: import header.{{.*}}foo.h{{.*}};
|
||||
import "foo.h";
|
||||
|
||||
// CHECK-HEADER-UNIT-USE: BAR;
|
||||
FOO;
|
||||
#endif
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
// RUN: rm -rf %t && mkdir %t
|
||||
// RUN: not %clang_cc1 -emit-header-module %s -o %t/out.pcm -serialize-diagnostic-file %t/diag 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: header module compilation requires '-fmodules', '-std=c++20', or '-fmodules-ts'
|
||||
@@ -1,48 +0,0 @@
|
||||
// RUN: %clang_cc1 -fmodules-ts -fmodule-name=ab -x c++-header %S/Inputs/no-module-map/a.h %S/Inputs/no-module-map/b.h -emit-header-module -o %t.pcm
|
||||
// RUN: %clang_cc1 -fmodules-ts -fmodule-file=%t.pcm %s -I%S/Inputs/no-module-map -verify
|
||||
// RUN: %clang_cc1 -fmodules-ts -fmodule-file=%t.pcm %s -I%S/Inputs/no-module-map -verify -DA
|
||||
// RUN: %clang_cc1 -fmodules-ts -fmodule-file=%t.pcm %s -I%S/Inputs/no-module-map -verify -DB
|
||||
// RUN: %clang_cc1 -fmodules-ts -fmodule-file=%t.pcm %s -I%S/Inputs/no-module-map -verify -DA -DB
|
||||
|
||||
// RUN: %clang_cc1 -E %t.pcm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -frewrite-imports -E %t.pcm -o - | FileCheck %s
|
||||
// CHECK: # {{.*}}a.h
|
||||
// CHECK: # {{.*}}b.h
|
||||
|
||||
#ifdef B
|
||||
// expected-no-diagnostics
|
||||
#endif
|
||||
|
||||
#ifdef A
|
||||
#include "a.h"
|
||||
#endif
|
||||
|
||||
#ifdef B
|
||||
#include "b.h"
|
||||
#endif
|
||||
|
||||
#if defined(A) || defined(B)
|
||||
#ifndef A_H
|
||||
#error A_H should be defined
|
||||
#endif
|
||||
#else
|
||||
#ifdef A_H
|
||||
#error A_H should not be defined
|
||||
#endif
|
||||
// expected-error@+3 {{must be imported from}}
|
||||
// expected-note@* {{declaration}}
|
||||
#endif
|
||||
void use_a() { a(); }
|
||||
|
||||
#if defined(B)
|
||||
#ifndef B_H
|
||||
#error B_H should be defined
|
||||
#endif
|
||||
#else
|
||||
#ifdef B_H
|
||||
#error B_H should not be defined
|
||||
#endif
|
||||
// expected-error@+3 {{must be imported from}}
|
||||
// expected-note@* {{declaration}}
|
||||
#endif
|
||||
void use_b() { b(); }
|
||||
Reference in New Issue
Block a user