mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add flag to verify just-emitted module interfaces
The driver can now schedule jobs which typecheck just-emitted module interfaces to ensure that they can be consumed later. This can be enabled manually by passing `-verify-emitted-module-interface` to the driver.
This commit is contained in:
@@ -51,9 +51,10 @@ public:
|
||||
GenerateDSYMJob,
|
||||
VerifyDebugInfoJob,
|
||||
GeneratePCHJob,
|
||||
VerifyModuleInterfaceJob,
|
||||
|
||||
JobFirst = CompileJob,
|
||||
JobLast = GeneratePCHJob
|
||||
JobLast = VerifyModuleInterfaceJob
|
||||
};
|
||||
|
||||
static const char *getClassName(Kind AC);
|
||||
@@ -357,6 +358,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class VerifyModuleInterfaceJobAction : public JobAction {
|
||||
virtual void anchor();
|
||||
file_types::ID inputType;
|
||||
|
||||
public:
|
||||
VerifyModuleInterfaceJobAction(const Action * ModuleEmitter,
|
||||
file_types::ID inputType)
|
||||
: JobAction(Action::Kind::VerifyModuleInterfaceJob, { ModuleEmitter },
|
||||
file_types::TY_Nothing), inputType(inputType) {
|
||||
assert(inputType == file_types::TY_SwiftModuleInterfaceFile ||
|
||||
inputType == file_types::TY_PrivateSwiftModuleInterfaceFile);
|
||||
}
|
||||
|
||||
file_types::ID getInputType() const { return inputType; }
|
||||
|
||||
static bool classof(const Action *A) {
|
||||
return A->getKind() == Action::Kind::VerifyModuleInterfaceJob;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace driver
|
||||
} // end namespace swift
|
||||
|
||||
|
||||
@@ -162,6 +162,9 @@ protected:
|
||||
virtual InvocationInfo
|
||||
constructInvocation(const VerifyDebugInfoJobAction &job,
|
||||
const JobContext &context) const;
|
||||
virtual InvocationInfo
|
||||
constructInvocation(const VerifyModuleInterfaceJobAction &job,
|
||||
const JobContext &context) const;
|
||||
virtual InvocationInfo constructInvocation(const GeneratePCHJobAction &job,
|
||||
const JobContext &context) const;
|
||||
virtual InvocationInfo
|
||||
|
||||
@@ -460,6 +460,15 @@ def emit_private_module_interface_path :
|
||||
DoesNotAffectIncrementalBuild, ArgumentIsPath, SupplementaryOutput]>,
|
||||
MetaVarName<"<path>">, HelpText<"Output private module interface file to <path>">;
|
||||
|
||||
def verify_emitted_module_interface :
|
||||
Flag<["-"], "verify-emitted-module-interface">,
|
||||
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
|
||||
HelpText<"Check that module interfaces emitted during compilation typecheck">;
|
||||
def no_verify_emitted_module_interface :
|
||||
Flag<["-"], "no-verify-emitted-module-interface">,
|
||||
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
|
||||
HelpText<"Don't check that module interfaces emitted during compilation typecheck">;
|
||||
|
||||
def avoid_emit_module_source_info :
|
||||
Flag<["-"], "avoid-emit-module-source-info">,
|
||||
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
|
||||
|
||||
@@ -33,6 +33,7 @@ const char *Action::getClassName(Kind AC) {
|
||||
case Kind::GenerateDSYMJob: return "generate-dSYM";
|
||||
case Kind::VerifyDebugInfoJob: return "verify-debug-info";
|
||||
case Kind::GeneratePCHJob: return "generate-pch";
|
||||
case Kind::VerifyModuleInterfaceJob: return "verify-module-interface";
|
||||
}
|
||||
|
||||
llvm_unreachable("invalid class");
|
||||
@@ -65,3 +66,5 @@ void GenerateDSYMJobAction::anchor() {}
|
||||
void VerifyDebugInfoJobAction::anchor() {}
|
||||
|
||||
void GeneratePCHJobAction::anchor() {}
|
||||
|
||||
void VerifyModuleInterfaceJobAction::anchor() {}
|
||||
|
||||
@@ -2208,6 +2208,26 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
|
||||
TopLevelActions.push_back(MergeModuleAction);
|
||||
TopLevelActions.append(AllLinkerInputs.begin(), AllLinkerInputs.end());
|
||||
}
|
||||
|
||||
bool verifyInterfacesByDefault = false;
|
||||
|
||||
if (MergeModuleAction
|
||||
&& Args.hasFlag(options::OPT_verify_emitted_module_interface,
|
||||
options::OPT_no_verify_emitted_module_interface,
|
||||
verifyInterfacesByDefault)) {
|
||||
if (Args.hasArgNoClaim(options::OPT_emit_module_interface,
|
||||
options::OPT_emit_module_interface_path)) {
|
||||
TopLevelActions.push_back(
|
||||
C.createAction<VerifyModuleInterfaceJobAction>(MergeModuleAction,
|
||||
file_types::TY_SwiftModuleInterfaceFile));
|
||||
}
|
||||
|
||||
if (Args.hasArgNoClaim(options::OPT_emit_private_module_interface_path)) {
|
||||
TopLevelActions.push_back(
|
||||
C.createAction<VerifyModuleInterfaceJobAction>(MergeModuleAction,
|
||||
file_types::TY_PrivateSwiftModuleInterfaceFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Driver::handleImmediateArgs(const ArgList &Args, const ToolChain &TC) {
|
||||
|
||||
@@ -111,6 +111,7 @@ std::unique_ptr<Job> ToolChain::constructJob(
|
||||
CASE(GeneratePCHJob)
|
||||
CASE(AutolinkExtractJob)
|
||||
CASE(REPLJob)
|
||||
CASE(VerifyModuleInterfaceJob)
|
||||
#undef CASE
|
||||
case Action::Kind::Input:
|
||||
llvm_unreachable("not a JobAction");
|
||||
|
||||
@@ -1047,6 +1047,41 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job,
|
||||
return II;
|
||||
}
|
||||
|
||||
ToolChain::InvocationInfo
|
||||
ToolChain::constructInvocation(const VerifyModuleInterfaceJobAction &job,
|
||||
const JobContext &context) const {
|
||||
InvocationInfo II{SWIFT_EXECUTABLE_NAME};
|
||||
ArgStringList &Arguments = II.Arguments;
|
||||
II.allowsResponseFiles = true;
|
||||
|
||||
for (auto &s : getDriver().getSwiftProgramArgs())
|
||||
Arguments.push_back(s.c_str());
|
||||
Arguments.push_back("-frontend");
|
||||
|
||||
Arguments.push_back("-typecheck-module-from-interface");
|
||||
|
||||
size_t sizeBefore = Arguments.size();
|
||||
addInputsOfType(Arguments, context.Inputs, context.Args, job.getInputType());
|
||||
|
||||
(void)sizeBefore;
|
||||
assert(Arguments.size() - sizeBefore == 1 &&
|
||||
"should verify exactly one module interface per job");
|
||||
|
||||
addCommonFrontendArgs(context.OI, context.Output, context.Args, Arguments);
|
||||
addRuntimeLibraryFlags(context.OI, Arguments);
|
||||
|
||||
addOutputsOfType(Arguments, context.Output, context.Args,
|
||||
file_types::TY_SerializedDiagnostics,
|
||||
"-serialize-diagnostics-path");
|
||||
|
||||
context.Args.AddLastArg(Arguments, options::OPT_import_objc_header);
|
||||
|
||||
Arguments.push_back("-module-name");
|
||||
Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName));
|
||||
|
||||
return II;
|
||||
}
|
||||
|
||||
ToolChain::InvocationInfo
|
||||
ToolChain::constructInvocation(const ModuleWrapJobAction &job,
|
||||
const JobContext &context) const {
|
||||
|
||||
15
test/ModuleInterface/verify-module-interfaces.swift
Normal file
15
test/ModuleInterface/verify-module-interfaces.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// Check that verification won't reject a valid interface:
|
||||
// RUN: %target-build-swift -emit-library -enable-library-evolution -emit-module-interface -emit-module -swift-version 5 -o %t/MyModule.o -verify-emitted-module-interface -module-name MyModule %s
|
||||
|
||||
// Check that verification will reject an invalid interface:
|
||||
// RUN: not %target-build-swift -emit-library -enable-library-evolution -emit-module-interface -emit-module -swift-version 5 -o %t/MyModule.o -verify-emitted-module-interface -module-name MyModule -Xfrontend -debug-emit-invalid-swiftinterface-syntax %s 2>&1 | %FileCheck %s
|
||||
|
||||
// ...but not if verification is off.
|
||||
// RUN: %target-build-swift -emit-library -enable-library-evolution -emit-module-interface -emit-module -swift-version 5 -o %t/MyModule.o -no-verify-emitted-module-interface -module-name MyModule -Xfrontend -debug-emit-invalid-swiftinterface-syntax %s
|
||||
|
||||
public struct MyStruct {}
|
||||
|
||||
// CHECK: MyModule.swiftinterface:{{[0-9]+}}:{{[0-9]+}}: error: use of unknown directive '#__debug_emit_invalid_swiftinterface_syntax__'
|
||||
// CHECK: MyModule.swiftinterface:{{[0-9]+}}:{{[0-9]+}}: error: failed to build module 'MyModule' from its module interface; it may have been damaged or it may have triggered a bug in the Swift compiler when it was produced
|
||||
Reference in New Issue
Block a user