Skip to content

[Frontend][NFC] Formalize isModuleExternallyConsumed #31145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions include/swift/Frontend/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,25 @@ class CompilerInvocation {

std::string getLdAddCFileOutputPathForWholeModule() const;

public:
/// Given the current configuration of this frontend invocation, a set of
/// supplementary output paths, and a module, compute the appropriate set of
/// serialization options.
///
/// FIXME: The \p module parameter supports the
/// \c SerializeOptionsForDebugging hack.
SerializationOptions
computeSerializationOptions(const SupplementaryOutputPaths &outs,
bool moduleIsPublic) const;
const ModuleDecl *module) const;

/// Returns an approximation of whether the given module could be
/// redistributed and consumed by external clients.
///
/// FIXME: The scope of this computation should be limited entirely to
/// PrintAsObjC. Unfortunately, it has been co-opted to support the
/// \c SerializeOptionsForDebugging hack. Once this information can be
/// transferred from module files to the dSYMs, remove this.
bool isModuleExternallyConsumed(const ModuleDecl *mod) const;
};

/// A class which manages the state and execution of the compiler.
Expand Down Expand Up @@ -555,9 +571,7 @@ class CompilerInstance {
/// Returns true if there was an error during setup.
bool setup(const CompilerInvocation &Invocation);

const CompilerInvocation &getInvocation() {
return Invocation;
}
const CompilerInvocation &getInvocation() const { return Invocation; }

/// If a code completion buffer has been set, returns the corresponding source
/// file.
Expand Down
27 changes: 27 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1701,3 +1701,30 @@ CompilerInvocation::setUpInputForSILTool(
}
return fileBufOrErr;
}

bool CompilerInvocation::isModuleExternallyConsumed(
const ModuleDecl *mod) const {
// Modules for executables aren't expected to be consumed by other modules.
// This picks up all kinds of entrypoints, including script mode,
// @UIApplicationMain and @NSApplicationMain.
if (mod->hasEntryPoint()) {
return false;
}

// If an implicit Objective-C header was needed to construct this module, it
// must be the product of a library target.
if (!getFrontendOptions().ImplicitObjCHeaderPath.empty()) {
return false;
}

// App extensions are special beasts because they build without entrypoints
// like library targets, but they behave like executable targets because
// their associated modules are not suitable for distribution.
if (mod->getASTContext().LangOpts.EnableAppExtensionRestrictions) {
return false;
}

// FIXME: This is still a lousy approximation of whether the module file will
// be externally consumed.
return true;
}
5 changes: 3 additions & 2 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ CompilerInvocation::getPrivateModuleInterfaceOutputPathForWholeModule() const {
}

SerializationOptions CompilerInvocation::computeSerializationOptions(
const SupplementaryOutputPaths &outs, bool moduleIsPublic) const {
const SupplementaryOutputPaths &outs, const ModuleDecl *module) const {
const FrontendOptions &opts = getFrontendOptions();

SerializationOptions serializationOpts;
Expand All @@ -171,7 +171,8 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
// so only serialize them if the module isn't going to be shipped to
// the public.
serializationOpts.SerializeOptionsForDebugging =
opts.SerializeOptionsForDebugging.getValueOr(!moduleIsPublic);
opts.SerializeOptionsForDebugging.getValueOr(
!isModuleExternallyConsumed(module));

return serializationOpts;
}
Expand Down
47 changes: 18 additions & 29 deletions lib/FrontendTool/FrontendTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,20 +1074,19 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
std::unique_ptr<SILModule> SM,
ModuleOrSourceFile MSF,
const PrimarySpecificPaths &PSPs,
bool moduleIsPublic, int &ReturnValue,
int &ReturnValue,
FrontendObserver *observer);

static bool
performCompileStepsPostSema(const CompilerInvocation &Invocation,
CompilerInstance &Instance,
bool moduleIsPublic, int &ReturnValue,
FrontendObserver *observer) {
static bool performCompileStepsPostSema(const CompilerInvocation &Invocation,
CompilerInstance &Instance,
int &ReturnValue,
FrontendObserver *observer) {
auto mod = Instance.getMainModule();
if (auto SM = Instance.takeSILModule()) {
const PrimarySpecificPaths PSPs =
Instance.getPrimarySpecificPathsForAtMostOnePrimary();
return performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
mod, PSPs, moduleIsPublic,
mod, PSPs,
ReturnValue, observer);
}

Expand All @@ -1100,7 +1099,7 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
const PrimarySpecificPaths PSPs =
Instance.getPrimarySpecificPathsForWholeModuleOptimizationMode();
return performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
mod, PSPs, moduleIsPublic,
mod, PSPs,
ReturnValue, observer);
}
// If there are primary source files, build a separate SILModule for
Expand All @@ -1113,7 +1112,7 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
const PrimarySpecificPaths PSPs =
Instance.getPrimarySpecificPathsForSourceFile(*PrimaryFile);
result |= performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
PrimaryFile, PSPs, moduleIsPublic,
PrimaryFile, PSPs,
ReturnValue, observer);
}

Expand All @@ -1131,7 +1130,7 @@ performCompileStepsPostSema(const CompilerInvocation &Invocation,
const PrimarySpecificPaths &PSPs =
Instance.getPrimarySpecificPathsForPrimary(SASTF->getFilename());
result |= performCompileStepsPostSILGen(Instance, Invocation, std::move(SM),
mod, PSPs, moduleIsPublic,
mod, PSPs,
ReturnValue, observer);
}
}
Expand All @@ -1158,8 +1157,7 @@ emitIndexData(const CompilerInvocation &Invocation, const CompilerInstance &Inst
/// `-typecheck`, but skipped for any mode that runs SIL diagnostics if there's
/// an error found there (to get those diagnostics back to the user faster).
static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
CompilerInstance &Instance, const CompilerInvocation &Invocation,
bool moduleIsPublic) {
CompilerInstance &Instance, const CompilerInvocation &Invocation) {
const FrontendOptions &opts = Invocation.getFrontendOptions();

// Record whether we failed to emit any of these outputs, but keep going; one
Expand All @@ -1182,7 +1180,8 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
}
hadAnyError |= printAsObjCIfNeeded(
Invocation.getObjCHeaderOutputPathForAtMostOnePrimary(),
Instance.getMainModule(), BridgingHeaderPathForPrint, moduleIsPublic);
Instance.getMainModule(), BridgingHeaderPathForPrint,
Invocation.isModuleExternallyConsumed(Instance.getMainModule()));
}

if (opts.InputsAndOutputs.hasModuleInterfaceOutputPath()) {
Expand Down Expand Up @@ -1315,13 +1314,6 @@ static bool performCompile(CompilerInstance &Instance,
(void)emitLoadedModuleTraceForAllPrimariesIfNeeded(
Instance.getMainModule(), Instance.getDependencyTracker(), opts);

// FIXME: This is still a lousy approximation of whether the module file will
// be externally consumed.
bool moduleIsPublic =
!Instance.getMainModule()->hasEntryPoint() &&
opts.ImplicitObjCHeaderPath.empty() &&
!Context.LangOpts.EnableAppExtensionRestrictions;

// We've just been told to perform a typecheck, so we can return now.
if (Action == FrontendOptions::ActionType::Typecheck) {
if (emitIndexData(Invocation, Instance))
Expand All @@ -1336,8 +1328,7 @@ static bool performCompile(CompilerInstance &Instance,
// guarding the emission of whole-module supplementary outputs.
if (opts.InputsAndOutputs.isWholeModule()) {
if (emitAnyWholeModulePostTypeCheckSupplementaryOutputs(Instance,
Invocation,
moduleIsPublic)) {
Invocation)) {
return true;
}
}
Expand All @@ -1347,8 +1338,8 @@ static bool performCompile(CompilerInstance &Instance,
assert(FrontendOptions::doesActionGenerateSIL(Action) &&
"All actions not requiring SILGen must have been handled!");

return performCompileStepsPostSema(Invocation, Instance, moduleIsPublic,
ReturnValue, observer);
return performCompileStepsPostSema(Invocation, Instance, ReturnValue,
observer);
}

static bool serializeSIB(SILModule *SM, const PrimarySpecificPaths &PSPs,
Expand Down Expand Up @@ -1575,9 +1566,8 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
std::unique_ptr<SILModule> SM,
ModuleOrSourceFile MSF,
const PrimarySpecificPaths &PSPs,
bool moduleIsPublic, int &ReturnValue,
int &ReturnValue,
FrontendObserver *observer) {

FrontendOptions opts = Invocation.getFrontendOptions();
FrontendOptions::ActionType Action = opts.RequestedAction;
const ASTContext &Context = Instance.getASTContext();
Expand Down Expand Up @@ -1618,7 +1608,7 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
return;

SerializationOptions serializationOpts =
Invocation.computeSerializationOptions(outs, moduleIsPublic);
Invocation.computeSerializationOptions(outs, Instance.getMainModule());
serialize(MSF, serializationOpts, SM.get());
};

Expand All @@ -1633,8 +1623,7 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
if (observer)
observer->performedSILProcessing(*SM);

emitAnyWholeModulePostTypeCheckSupplementaryOutputs(Instance, Invocation,
moduleIsPublic);
emitAnyWholeModulePostTypeCheckSupplementaryOutputs(Instance, Invocation);

if (Action == FrontendOptions::ActionType::EmitSIB)
return serializeSIB(SM.get(), PSPs, Context, MSF);
Expand Down