Skip to content

Commit 3a214d9

Browse files
committed
Frontend: add an argument to disable implicitly built Swift modules
1 parent 736a848 commit 3a214d9

File tree

12 files changed

+90
-19
lines changed

12 files changed

+90
-19
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ class ClangImporter final : public ClangModuleLoader {
473473

474474
bool isSerializable(const clang::Type *type,
475475
bool checkCanonical) const override;
476+
ArrayRef<std::string> getExtraClangArgs() const;
476477
};
477478

478479
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,

include/swift/Frontend/FrontendOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ class FrontendOptions {
258258
/// By default, we include ImplicitObjCHeaderPath directly.
259259
llvm::Optional<std::string> BridgingHeaderDirForPrint;
260260

261+
/// Disable implicitly built Swift modules because they are explicitly
262+
/// built and given to the compiler invocation.
263+
bool DisableImplicitModules = false;
264+
265+
/// The paths to a set of explicitly built modules from interfaces.
266+
std::vector<std::string> ExplicitSwiftModules;
267+
261268
/// The different modes for validating TBD against the LLVM IR.
262269
enum class TBDValidationMode {
263270
Default, ///< Do the default validation for the current platform.

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,21 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
138138
DependencyTracker *tracker, ModuleLoadingMode loadMode,
139139
ArrayRef<std::string> PreferInterfaceForModules,
140140
bool RemarkOnRebuildFromInterface, bool IgnoreSwiftSourceInfoFile,
141-
bool DisableInterfaceFileLock)
141+
bool DisableInterfaceFileLock, bool DisableImplicitSwiftModule)
142142
: SerializedModuleLoaderBase(ctx, tracker, loadMode,
143143
IgnoreSwiftSourceInfoFile),
144144
CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
145145
RemarkOnRebuildFromInterface(RemarkOnRebuildFromInterface),
146146
DisableInterfaceFileLock(DisableInterfaceFileLock),
147+
DisableImplicitSwiftModule(DisableImplicitSwiftModule),
147148
PreferInterfaceForModules(PreferInterfaceForModules)
148149
{}
149150

150151
std::string CacheDir;
151152
std::string PrebuiltCacheDir;
152153
bool RemarkOnRebuildFromInterface;
153154
bool DisableInterfaceFileLock;
155+
bool DisableImplicitSwiftModule;
154156
ArrayRef<std::string> PreferInterfaceForModules;
155157

156158
std::error_code findModuleFilesInDirectory(
@@ -170,14 +172,16 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
170172
ArrayRef<std::string> PreferInterfaceForModules = {},
171173
bool RemarkOnRebuildFromInterface = false,
172174
bool IgnoreSwiftSourceInfoFile = false,
173-
bool DisableInterfaceFileLock = false) {
175+
bool DisableInterfaceFileLock = false,
176+
bool DisableImplicitSwiftModule = false) {
174177
return std::unique_ptr<ModuleInterfaceLoader>(
175178
new ModuleInterfaceLoader(ctx, cacheDir, prebuiltCacheDir,
176179
tracker, loadMode,
177180
PreferInterfaceForModules,
178181
RemarkOnRebuildFromInterface,
179182
IgnoreSwiftSourceInfoFile,
180-
DisableInterfaceFileLock));
183+
DisableInterfaceFileLock,
184+
DisableImplicitSwiftModule));
181185
}
182186

183187
/// Append visible module names to \p names. Note that names are possibly
@@ -192,10 +196,12 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
192196
static bool buildSwiftModuleFromSwiftInterface(
193197
SourceManager &SourceMgr, DiagnosticEngine &Diags,
194198
const SearchPathOptions &SearchPathOpts, const LangOptions &LangOpts,
199+
const ClangImporterOptions &ClangOpts,
195200
StringRef CacheDir, StringRef PrebuiltCacheDir,
196201
StringRef ModuleName, StringRef InPath, StringRef OutPath,
197202
bool SerializeDependencyHashes, bool TrackSystemDependencies,
198-
bool RemarkOnRebuildFromInterface, bool DisableInterfaceFileLock);
203+
bool RemarkOnRebuildFromInterface, bool DisableInterfaceFileLock,
204+
bool DisableImplicitSwiftModules);
199205
};
200206

201207
struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
@@ -238,7 +244,8 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
238244
bool serializeDependencyHashes,
239245
bool trackSystemDependencies,
240246
bool remarkOnRebuildFromInterface,
241-
bool disableInterfaceFileLock);
247+
bool disableInterfaceFileLock,
248+
bool disableImplicitSwiftModule);
242249
bool runInSubContext(StringRef moduleName,
243250
StringRef interfacePath,
244251
StringRef outputPath,
@@ -258,6 +265,7 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
258265
llvm::SmallString<256> &OutPath,
259266
StringRef &CacheHash);
260267
std::string getCacheHash(StringRef useInterfacePath);
268+
void addExtraClangArg(StringRef Arg);
261269
};
262270
}
263271

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ def disable_objc_attr_requires_foundation_module :
214214
def enable_resilience : Flag<["-"], "enable-resilience">,
215215
HelpText<"Deprecated, use -enable-library-evolution instead">;
216216

217+
def disable_implicit_swift_modules: Flag<["-"], "disable-implicit-swift-modules">,
218+
HelpText<"Disable building Swift modules explicitly by the compiler">;
219+
220+
def swift_module_file_EQ : Joined<["-"], "swift-module-file=">,
221+
HelpText<"Specify Swift module explicitly built from textual interface">;
217222
}
218223

219224

lib/ClangImporter/ClangImporter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,10 @@ ClangImporter::createClangInvocation(ClangImporter *importer,
957957
nullptr, false, CC1Args);
958958
}
959959

960+
ArrayRef<std::string> ClangImporter::getExtraClangArgs() const {
961+
return Impl.ExtraClangArgs;
962+
}
963+
960964
std::unique_ptr<ClangImporter>
961965
ClangImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
962966
std::string swiftPCHHash, DependencyTracker *tracker,
@@ -965,7 +969,7 @@ ClangImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
965969
new ClangImporter(ctx, importerOpts, tracker, dwarfImporterDelegate)};
966970
importer->Impl.ClangArgs = getClangArguments(ctx, importerOpts);
967971
ArrayRef<std::string> invocationArgStrs = importer->Impl.ClangArgs;
968-
972+
importer->Impl.ExtraClangArgs = importerOpts.ExtraArgs;
969973
if (importerOpts.DumpClangDiagnostics) {
970974
llvm::errs() << "'";
971975
llvm::interleave(

lib/ClangImporter/ImporterImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
392392

393393
/// Clang arguments used to create the Clang invocation.
394394
std::vector<std::string> ClangArgs;
395+
396+
/// Extra clang args specified via "-Xcc"
397+
std::vector<std::string> ExtraClangArgs;
395398
public:
396399
/// Mapping of already-imported declarations.
397400
llvm::DenseMap<std::pair<const clang::Decl *, Version>, Decl *> ImportedDecls;

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ bool ArgsToFrontendOptionsConverter::convert(
8383

8484
Opts.TrackSystemDeps |= Args.hasArg(OPT_track_system_dependencies);
8585

86+
Opts.DisableImplicitModules |= Args.hasArg(OPT_disable_implicit_swift_modules);
87+
88+
for (auto A: Args.getAllArgValues(OPT_swift_module_file_EQ)) {
89+
Opts.ExplicitSwiftModules.push_back(A);
90+
}
91+
8692
// Always track system dependencies when scanning dependencies.
8793
if (const Arg *ModeArg = Args.getLastArg(OPT_modes_Group)) {
8894
if (ModeArg->getOption().matches(OPT_scan_dependencies))

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,8 @@ bool CompilerInstance::setUpModuleLoaders() {
460460
getDependencyTracker(), MLM, FEOpts.PreferInterfaceForModules,
461461
FEOpts.RemarkOnRebuildFromModuleInterface,
462462
IgnoreSourceInfoFile,
463-
FEOpts.DisableInterfaceFileLock);
463+
FEOpts.DisableInterfaceFileLock,
464+
FEOpts.DisableImplicitModules);
464465
Context->addModuleLoader(std::move(PIML));
465466
}
466467

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -341,12 +341,13 @@ class ModuleInterfaceLoaderImpl {
341341
const ModuleLoadingMode loadMode;
342342
const bool remarkOnRebuildFromInterface;
343343
const bool disableInterfaceLock;
344+
const bool disableImplicitSwiftModule;
344345

345346
ModuleInterfaceLoaderImpl(
346347
ASTContext &ctx, StringRef modulePath, StringRef interfacePath,
347348
StringRef moduleName, StringRef cacheDir, StringRef prebuiltCacheDir,
348349
SourceLoc diagLoc, bool remarkOnRebuildFromInterface,
349-
bool disableInterfaceLock,
350+
bool disableInterfaceLock, bool disableImplicitSwiftModule,
350351
DependencyTracker *dependencyTracker = nullptr,
351352
ModuleLoadingMode loadMode = ModuleLoadingMode::PreferSerialized)
352353
: ctx(ctx), fs(*ctx.SourceMgr.getFileSystem()), diags(ctx.Diags),
@@ -355,7 +356,8 @@ class ModuleInterfaceLoaderImpl {
355356
cacheDir(cacheDir), diagnosticLoc(diagLoc),
356357
dependencyTracker(dependencyTracker), loadMode(loadMode),
357358
remarkOnRebuildFromInterface(remarkOnRebuildFromInterface),
358-
disableInterfaceLock(disableInterfaceLock) {}
359+
disableInterfaceLock(disableInterfaceLock),
360+
disableImplicitSwiftModule(disableImplicitSwiftModule) {}
359361

360362
/// Constructs the full path of the dependency \p dep by prepending the SDK
361363
/// path if necessary.
@@ -835,7 +837,8 @@ class ModuleInterfaceLoaderImpl {
835837
/*serializeDependencyHashes*/false,
836838
trackSystemDependencies,
837839
remarkOnRebuildFromInterface,
838-
disableInterfaceLock);
840+
disableInterfaceLock,
841+
disableImplicitSwiftModule);
839842
// Set up a builder if we need to build the module. It'll also set up
840843
// the subinvocation we'll need to use to compute the cache paths.
841844
ModuleInterfaceBuilder builder(
@@ -965,6 +968,7 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
965968
Ctx, ModPath, InPath, ModuleName,
966969
CacheDir, PrebuiltCacheDir, ModuleID.Loc,
967970
RemarkOnRebuildFromInterface, DisableInterfaceFileLock,
971+
DisableImplicitSwiftModule,
968972
dependencyTracker,
969973
llvm::is_contained(PreferInterfaceForModules,
970974
ModuleName) ?
@@ -1000,10 +1004,12 @@ std::error_code ModuleInterfaceLoader::findModuleFilesInDirectory(
10001004
bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
10011005
SourceManager &SourceMgr, DiagnosticEngine &Diags,
10021006
const SearchPathOptions &SearchPathOpts, const LangOptions &LangOpts,
1007+
const ClangImporterOptions &ClangOpts,
10031008
StringRef CacheDir, StringRef PrebuiltCacheDir,
10041009
StringRef ModuleName, StringRef InPath, StringRef OutPath,
10051010
bool SerializeDependencyHashes, bool TrackSystemDependencies,
1006-
bool RemarkOnRebuildFromInterface, bool DisableInterfaceFileLock) {
1011+
bool RemarkOnRebuildFromInterface, bool DisableInterfaceFileLock,
1012+
bool DisableImplicitSwiftModule) {
10071013
InterfaceSubContextDelegateImpl astDelegate(SourceMgr, Diags,
10081014
SearchPathOpts, LangOpts,
10091015
/*clangImporter*/nullptr,
@@ -1012,7 +1018,15 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
10121018
SerializeDependencyHashes,
10131019
TrackSystemDependencies,
10141020
RemarkOnRebuildFromInterface,
1015-
DisableInterfaceFileLock);
1021+
DisableInterfaceFileLock,
1022+
DisableImplicitSwiftModule);
1023+
// At this point we don't have an ClangImporter instance because the instance
1024+
// is created later when we create a new ASTContext to build the interface.
1025+
// Thus, we have to add these extra clang flags manually here to ensure explict
1026+
// module building works.
1027+
for (auto &Arg: ClangOpts.ExtraArgs) {
1028+
astDelegate.addExtraClangArg(Arg);
1029+
}
10161030
ModuleInterfaceBuilder builder(SourceMgr, Diags, astDelegate, InPath,
10171031
ModuleName, CacheDir, PrebuiltCacheDir,
10181032
DisableInterfaceFileLock);
@@ -1158,6 +1172,12 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
11581172
return false;
11591173
}
11601174

1175+
void InterfaceSubContextDelegateImpl::addExtraClangArg(StringRef arg) {
1176+
subInvocation.getClangImporterOptions().ExtraArgs.push_back(arg);
1177+
GenericArgs.push_back("-Xcc");
1178+
GenericArgs.push_back(ArgSaver.save(arg));
1179+
}
1180+
11611181
InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
11621182
SourceManager &SM,
11631183
DiagnosticEngine &Diags,
@@ -1170,7 +1190,8 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
11701190
bool serializeDependencyHashes,
11711191
bool trackSystemDependencies,
11721192
bool remarkOnRebuildFromInterface,
1173-
bool disableInterfaceFileLock): SM(SM), Diags(Diags), ArgSaver(Allocator) {
1193+
bool disableInterfaceFileLock,
1194+
bool disableImplicitSwiftModule): SM(SM), Diags(Diags), ArgSaver(Allocator) {
11741195
inheritOptionsForBuildingInterface(searchPathOpts, langOpts);
11751196
// Configure front-end input.
11761197
auto &SubFEOpts = subInvocation.getFrontendOptions();
@@ -1190,10 +1211,22 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
11901211
if (trackSystemDependencies) {
11911212
GenericArgs.push_back("-track-system-dependencies");
11921213
}
1193-
// Respect the detailed-record preprocessor setting of the parent context.
1194-
// This, and the "raw" clang module format it implicitly enables, are
1195-
// required by sourcekitd.
1214+
if (disableImplicitSwiftModule) {
1215+
subInvocation.getFrontendOptions().DisableImplicitModules = true;
1216+
GenericArgs.push_back("-disable-implicit-swift-modules");
1217+
}
11961218
if (clangImporter) {
1219+
// We need to add these extra clang flags because explict module building
1220+
// related flags are all there: -fno-implicit-modules, -fmodule-map-file=,
1221+
// and -fmodule-file=.
1222+
// If we don't add these flags, the interface will be built with implicit
1223+
// PCMs.
1224+
for (auto arg: static_cast<ClangImporter*>(clangImporter)->getExtraClangArgs()) {
1225+
addExtraClangArg(arg);
1226+
}
1227+
// Respect the detailed-record preprocessor setting of the parent context.
1228+
// This, and the "raw" clang module format it implicitly enables, are
1229+
// required by sourcekitd.
11971230
auto &Opts = clangImporter->getClangInstance().getPreprocessorOpts();
11981231
if (Opts.DetailedRecord) {
11991232
subInvocation.getClangImporterOptions().DetailedPreprocessingRecord = true;

lib/FrontendTool/FrontendTool.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,12 +781,14 @@ static bool buildModuleFromInterface(CompilerInstance &Instance) {
781781
return ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
782782
Instance.getSourceMgr(), Instance.getDiags(),
783783
Invocation.getSearchPathOptions(), Invocation.getLangOptions(),
784+
Invocation.getClangImporterOptions(),
784785
Invocation.getClangModuleCachePath(),
785786
PrebuiltCachePath, Invocation.getModuleName(), InputPath,
786787
Invocation.getOutputFilename(),
787788
FEOpts.SerializeModuleInterfaceDependencyHashes,
788789
FEOpts.TrackSystemDeps, FEOpts.RemarkOnRebuildFromModuleInterface,
789-
FEOpts.DisableInterfaceFileLock);
790+
FEOpts.DisableInterfaceFileLock,
791+
FEOpts.DisableImplicitModules);
790792
}
791793

792794
static bool compileLLVMIR(CompilerInstance &Instance) {

0 commit comments

Comments
 (0)