Skip to content
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
3 changes: 3 additions & 0 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ namespace swift {
/// The model of concurrency to be used.
ConcurrencyModel ActiveConcurrencyModel = ConcurrencyModel::Standard;

/// Allows the explicit 'import Builtin' within Swift modules.
bool EnableBuiltinModule = false;

bool isConcurrencyModelTaskToThread() const {
return ActiveConcurrencyModel == ConcurrencyModel::TaskToThread;
}
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,10 @@ def parse_stdlib : Flag<["-"], "parse-stdlib">,
Flags<[FrontendOption, HelpHidden, ModuleInterfaceOption]>,
HelpText<"Parse the input file(s) as the Swift standard library">;

def enable_builtin_module : Flag<["-"], "enable-builtin-module">,
Flags<[FrontendOption, ModuleInterfaceOption]>,
HelpText<"Enables the explicit import of the Builtin module">;

def modes_Group : OptionGroup<"<mode options>">, HelpText<"MODES">;

class ModeOpt : Group<modes_Group>;
Expand Down
1 change: 1 addition & 0 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
inputArgs.AddLastArg(arguments, options::OPT_enable_experimental_cxx_interop);
inputArgs.AddLastArg(arguments, options::OPT_load_plugin_library);
inputArgs.AddLastArg(arguments, options::OPT_load_plugin_executable);
inputArgs.AddLastArg(arguments, options::OPT_enable_builtin_module);

// Pass on any build config options
inputArgs.AddAllArgs(arguments, options::OPT_D);
Expand Down
2 changes: 2 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
.Default(ConcurrencyModel::Standard);
}

Opts.EnableBuiltinModule = Args.hasArg(OPT_enable_builtin_module);

return HadError || UnsupportedOS || UnsupportedArch;
}

Expand Down
10 changes: 8 additions & 2 deletions lib/Frontend/ModuleInterfaceSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,14 @@ static void printImports(raw_ostream &out,

for (auto import : allImports) {
auto importedModule = import.importedModule;
if (importedModule->isOnoneSupportModule() ||
importedModule->isBuiltinModule()) {
if (importedModule->isOnoneSupportModule()) {
continue;
}

// Unless '-enable-builtin-module' was passed, do not print 'import Builtin'
// in the interface. '-parse-stdlib' still implicitly imports it however...
if (importedModule->isBuiltinModule() &&
!M->getASTContext().LangOpts.EnableBuiltinModule) {
continue;
}

Expand Down
39 changes: 26 additions & 13 deletions lib/Sema/ImportResolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,17 +354,26 @@ void ImportResolver::addImport(const UnboundImport &I, ModuleDecl *M) {
// MARK: Import module loading
//===----------------------------------------------------------------------===//

static ModuleDecl *
getModuleImpl(ImportPath::Module modulePath, ModuleDecl *loadingModule,
bool canImportBuiltin) {
ModuleDecl *
ImportResolver::getModule(ImportPath::Module modulePath) {
auto loadingModule = SF.getParentModule();

ASTContext &ctx = loadingModule->getASTContext();

assert(!modulePath.empty());
auto moduleID = modulePath[0];

// The Builtin module cannot be explicitly imported unless we're a .sil file.
if (canImportBuiltin && moduleID.Item == ctx.TheBuiltinModule->getName())
return ctx.TheBuiltinModule;
// The Builtin module cannot be explicitly imported unless:
// 1. We're in a .sil file
// 2. '-enable-builtin-module' was passed.
//
// FIXME: Eventually, it would be nice to separate '-parse-stdlib' from
// implicitly importing Builtin, but we're not there yet.
if (SF.Kind == SourceFileKind::SIL || ctx.LangOpts.EnableBuiltinModule) {
if (moduleID.Item == ctx.TheBuiltinModule->getName()) {
return ctx.TheBuiltinModule;
}
}

// If the imported module name is the same as the current module,
// skip the Swift module loader and use the Clang module loader instead.
Expand All @@ -382,12 +391,6 @@ getModuleImpl(ImportPath::Module modulePath, ModuleDecl *loadingModule,
return ctx.getModule(modulePath);
}

ModuleDecl *
ImportResolver::getModule(ImportPath::Module modulePath) {
return getModuleImpl(modulePath, SF.getParentModule(),
/*canImportBuiltin=*/SF.Kind == SourceFileKind::SIL);
}

NullablePtr<ModuleDecl>
UnboundImport::getTopLevelModule(ModuleDecl *M, SourceFile &SF) {
if (import.module.getModulePath().size() == 1)
Expand Down Expand Up @@ -737,11 +740,21 @@ void UnboundImport::validateResilience(NullablePtr<ModuleDecl> topLevelModule,
if (!topLevelModule || topLevelModule.get()->isNonSwiftModule())
return;

ASTContext &ctx = SF.getASTContext();

// If the module we're validating is the builtin one, then just return because
// this module is essentially a header only import and does not concern
// itself with resiliency. This can occur when one has passed
// '-enable-builtin-module' and is explicitly importing the Builtin module in
// their sources.
if (topLevelModule.get() == ctx.TheBuiltinModule) {
return;
}

if (!SF.getParentModule()->isResilient() ||
topLevelModule.get()->isResilient())
return;

ASTContext &ctx = SF.getASTContext();
ctx.Diags.diagnose(import.module.getModulePath().front().Loc,
diag::module_not_compiled_with_library_evolution,
topLevelModule.get()->getName(),
Expand Down
16 changes: 16 additions & 0 deletions test/Frontend/enable_builtin_module.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: not %target-swift-frontend -typecheck -show-diagnostics-after-fatal -D BUILTIN_IMPORT %s 2>&1 | %FileCheck -check-prefix CHECK-NO-BUILTIN %s
// RUN: not %target-swift-frontend -typecheck -show-diagnostics-after-fatal -enable-builtin-module %s 2>&1 | %FileCheck -check-prefix CHECK-NO-BUILTIN-IMPORT %s
// RUN: %target-swift-frontend -typecheck -enable-builtin-module -D BUILTIN_IMPORT %s

// CHECK-NO-BUILTIN: no such module 'Builtin'

#if BUILTIN_IMPORT
import Builtin
#endif

// CHECK-NO-BUILTIN: cannot find type 'Builtin' in scope
// CHECK-NO-BUILTIN-IMPORT: cannot find type 'Builtin' in scope

func something(_: Builtin.RawPointer) {

}
17 changes: 17 additions & 0 deletions test/ModuleInterface/enable_builtin_module.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -enable-builtin-module
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface)
// RUN: %FileCheck %s < %t.swiftinterface

// CHECK: -enable-builtin-module

// CHECK: import Builtin
// CHECK: import Swift
// CHECK: import _Concurrency
// CHECK: import _StringProcessing
// CHECK: import _SwiftConcurrencyShims

// CHECK: public func something(with x: Builtin.RawPointer)

import Builtin

public func something(with x: Builtin.RawPointer) {}