Skip to content

Commit 83f807d

Browse files
authored
Merge pull request swiftlang#32125 from nkcsgexi/add-flag-disable-swift-implicit
DependenciesScanner: propagate front-end arguments for disabling implicit Swift/Clang modules
2 parents 1e0b2de + 0d74428 commit 83f807d

17 files changed

+153
-132
lines changed

include/swift/AST/SearchPathOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ class SearchPathOptions {
8282
/// would for a non-system header.
8383
bool DisableModulesValidateSystemDependencies = false;
8484

85+
/// The paths to a set of explicitly built modules from interfaces.
86+
std::vector<std::string> ExplicitSwiftModules;
87+
8588
private:
8689
static StringRef
8790
pathStringFromFrameworkSearchPath(const FrameworkSearchPath &next) {

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/ClangImporter/ClangImporterOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class ClangImporterOptions {
103103
/// DWARFImporter delegate.
104104
bool DisableSourceImport = false;
105105

106+
/// When set, use ExtraArgs alone to configure clang instance because ExtraArgs
107+
/// contains the full option set.
108+
bool ExtraArgsOnly = false;
109+
106110
/// Return a hash code of any components from these options that should
107111
/// contribute to a Swift Bridging PCH hash.
108112
llvm::hash_code getPCHHashComponents() const {

include/swift/Frontend/FrontendOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,10 @@ 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+
261265
/// The different modes for validating TBD against the LLVM IR.
262266
enum class TBDValidationMode {
263267
Default, ///< Do the default validation for the current platform.

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ class LangOptions;
127127
class SearchPathOptions;
128128
class CompilerInvocation;
129129

130+
struct ModuleInterfaceLoaderOptions {
131+
bool remarkOnRebuildFromInterface = false;
132+
bool disableInterfaceLock = false;
133+
bool disableImplicitSwiftModule = false;
134+
ModuleInterfaceLoaderOptions(const FrontendOptions &Opts):
135+
remarkOnRebuildFromInterface(Opts.RemarkOnRebuildFromModuleInterface),
136+
disableInterfaceLock(Opts.DisableInterfaceFileLock),
137+
disableImplicitSwiftModule(Opts.DisableImplicitModules) {}
138+
ModuleInterfaceLoaderOptions() = default;
139+
};
130140
/// A ModuleLoader that runs a subordinate \c CompilerInvocation and
131141
/// \c CompilerInstance to convert .swiftinterface files to .swiftmodule
132142
/// files on the fly, caching the resulting .swiftmodules in the module cache
@@ -137,21 +147,17 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
137147
ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
138148
DependencyTracker *tracker, ModuleLoadingMode loadMode,
139149
ArrayRef<std::string> PreferInterfaceForModules,
140-
bool RemarkOnRebuildFromInterface, bool IgnoreSwiftSourceInfoFile,
141-
bool DisableInterfaceFileLock)
150+
bool IgnoreSwiftSourceInfoFile, ModuleInterfaceLoaderOptions Opts)
142151
: SerializedModuleLoaderBase(ctx, tracker, loadMode,
143152
IgnoreSwiftSourceInfoFile),
144153
CacheDir(cacheDir), PrebuiltCacheDir(prebuiltCacheDir),
145-
RemarkOnRebuildFromInterface(RemarkOnRebuildFromInterface),
146-
DisableInterfaceFileLock(DisableInterfaceFileLock),
147-
PreferInterfaceForModules(PreferInterfaceForModules)
148-
{}
154+
PreferInterfaceForModules(PreferInterfaceForModules),
155+
Opts(Opts) {}
149156

150157
std::string CacheDir;
151158
std::string PrebuiltCacheDir;
152-
bool RemarkOnRebuildFromInterface;
153-
bool DisableInterfaceFileLock;
154159
ArrayRef<std::string> PreferInterfaceForModules;
160+
ModuleInterfaceLoaderOptions Opts;
155161

156162
std::error_code findModuleFilesInDirectory(
157163
AccessPathElem ModuleID,
@@ -168,16 +174,14 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
168174
create(ASTContext &ctx, StringRef cacheDir, StringRef prebuiltCacheDir,
169175
DependencyTracker *tracker, ModuleLoadingMode loadMode,
170176
ArrayRef<std::string> PreferInterfaceForModules = {},
171-
bool RemarkOnRebuildFromInterface = false,
172-
bool IgnoreSwiftSourceInfoFile = false,
173-
bool DisableInterfaceFileLock = false) {
177+
ModuleInterfaceLoaderOptions Opts = ModuleInterfaceLoaderOptions(),
178+
bool IgnoreSwiftSourceInfoFile = false) {
174179
return std::unique_ptr<ModuleInterfaceLoader>(
175180
new ModuleInterfaceLoader(ctx, cacheDir, prebuiltCacheDir,
176181
tracker, loadMode,
177182
PreferInterfaceForModules,
178-
RemarkOnRebuildFromInterface,
179183
IgnoreSwiftSourceInfoFile,
180-
DisableInterfaceFileLock));
184+
Opts));
181185
}
182186

183187
/// Append visible module names to \p names. Note that names are possibly
@@ -192,10 +196,11 @@ 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+
ModuleInterfaceLoaderOptions Opts);
199204
};
200205

201206
struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
@@ -231,14 +236,13 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
231236
DiagnosticEngine &Diags,
232237
const SearchPathOptions &searchPathOpts,
233238
const LangOptions &langOpts,
239+
ModuleInterfaceLoaderOptions LoaderOpts,
234240
ClangModuleLoader *clangImporter,
235241
bool buildModuleCacheDirIfAbsent,
236242
StringRef moduleCachePath,
237243
StringRef prebuiltCachePath,
238244
bool serializeDependencyHashes,
239-
bool trackSystemDependencies,
240-
bool remarkOnRebuildFromInterface,
241-
bool disableInterfaceFileLock);
245+
bool trackSystemDependencies);
242246
bool runInSubContext(StringRef moduleName,
243247
StringRef interfacePath,
244248
StringRef outputPath,
@@ -258,6 +262,7 @@ struct InterfaceSubContextDelegateImpl: InterfaceSubContextDelegate {
258262
llvm::SmallString<256> &OutPath,
259263
StringRef &CacheHash);
260264
std::string getCacheHash(StringRef useInterfacePath);
265+
void addExtraClangArg(StringRef Arg);
261266
};
262267
}
263268

include/swift/Option/FrontendOptions.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ 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
221+
: Separate<["-"], "swift-module-file">, MetaVarName<"<path>">,
222+
HelpText<"Specify Swift module explicitly built from textual interface">;
217223
}
218224

219225

@@ -712,4 +718,6 @@ def target_sdk_version : Separate<["-"], "target-sdk-version">,
712718
def target_variant_sdk_version : Separate<["-"], "target-variant-sdk-version">,
713719
HelpText<"The version of target variant SDK used for compilation">;
714720

721+
def extra_clang_options_only : Flag<["-"], "only-use-extra-clang-opts">,
722+
HelpText<"Options passed via -Xcc are sufficient for Clang configuration">;
715723
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

lib/ClangImporter/ClangImporter.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,9 @@ ClangImporter::getOrCreatePCH(const ClangImporterOptions &ImporterOptions,
908908
std::vector<std::string>
909909
ClangImporter::getClangArguments(ASTContext &ctx,
910910
const ClangImporterOptions &importerOpts) {
911+
if (importerOpts.ExtraArgsOnly) {
912+
return importerOpts.ExtraArgs;
913+
}
911914
std::vector<std::string> invocationArgStrs;
912915
// Clang expects this to be like an actual command line. So we need to pass in
913916
// "clang" for argv[0]
@@ -957,6 +960,10 @@ ClangImporter::createClangInvocation(ClangImporter *importer,
957960
nullptr, false, CC1Args);
958961
}
959962

963+
ArrayRef<std::string> ClangImporter::getExtraClangArgs() const {
964+
return Impl.ExtraClangArgs;
965+
}
966+
960967
std::unique_ptr<ClangImporter>
961968
ClangImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
962969
std::string swiftPCHHash, DependencyTracker *tracker,
@@ -965,7 +972,7 @@ ClangImporter::create(ASTContext &ctx, const ClangImporterOptions &importerOpts,
965972
new ClangImporter(ctx, importerOpts, tracker, dwarfImporterDelegate)};
966973
importer->Impl.ClangArgs = getClangArguments(ctx, importerOpts);
967974
ArrayRef<std::string> invocationArgStrs = importer->Impl.ClangArgs;
968-
975+
importer->Impl.ExtraClangArgs = importerOpts.ExtraArgs;
969976
if (importerOpts.DumpClangDiagnostics) {
970977
llvm::errs() << "'";
971978
llvm::interleave(

lib/ClangImporter/ClangModuleDependencyScanner.cpp

Lines changed: 9 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -188,20 +188,6 @@ static ClangModuleDependenciesCacheImpl *getOrCreateClangImpl(
188188
return clangImpl;
189189
}
190190

191-
static std::string getModuleFilePath(StringRef moduleCacheDir,
192-
StringRef moduleName,
193-
StringRef contextHash) {
194-
SmallString<128> outputPath(moduleCacheDir);
195-
llvm::sys::path::append(outputPath, (llvm::Twine(moduleName)
196-
+ "-" + contextHash + ".pcm").str());
197-
return outputPath.str().str();
198-
}
199-
200-
static std::string getModuleFilePath(StringRef moduleCacheDir,
201-
const ModuleDeps &dep) {
202-
return getModuleFilePath(moduleCacheDir, dep.ModuleName, dep.ContextHash);
203-
}
204-
205191
/// Record the module dependencies we found by scanning Clang modules into
206192
/// the module dependencies cache.
207193
void ClangImporter::recordModuleDependencies(
@@ -213,23 +199,7 @@ void ClangImporter::recordModuleDependencies(
213199
};
214200
auto ModuleCacheDir = swift::getModuleCachePathFromClang(getClangInstance());
215201

216-
// A map keyed by module name and context hash.
217-
llvm::StringMap<llvm::StringMap<ModuleInfo>> moduleInfoMap;
218-
219-
// Traverse all Clang modules to populate moduleInfoMap for cross
220-
// referencing later.
221-
for (const auto &clangModuleDep : clangDependencies.DiscoveredModules) {
222-
moduleInfoMap[clangModuleDep.ModuleName][clangModuleDep.ContextHash] =
223-
{
224-
// Keep track of pcm path for output.
225-
getModuleFilePath(ModuleCacheDir, clangModuleDep),
226-
// Keep track of modulemap file for input.
227-
clangModuleDep.ClangModuleMapFile
228-
};
229-
}
230202
for (const auto &clangModuleDep : clangDependencies.DiscoveredModules) {
231-
assert(moduleInfoMap[clangModuleDep.ModuleName]
232-
.count(clangModuleDep.ContextHash));
233203
// If we've already cached this information, we're done.
234204
if (cache.hasDependencies(clangModuleDep.ModuleName,
235205
ModuleDependenciesKind::Clang))
@@ -241,48 +211,32 @@ void ClangImporter::recordModuleDependencies(
241211
fileDeps.push_back(fileDep.getKey().str());
242212
}
243213
// Inherit all Clang driver args when creating the clang importer.
244-
std::vector<std::string> allArgs = Impl.ClangArgs;
214+
ArrayRef<std::string> allArgs = Impl.ClangArgs;
245215
ClangImporterOptions Opts;
246-
std::vector<std::string> cc1Args;
247216

248-
// Calling this to convert driver args to CC1 args.
249-
createClangInvocation(this, Opts, allArgs, &cc1Args);
217+
// Ensure the arguments we collected is sufficient to create a Clang
218+
// invocation.
219+
assert(createClangInvocation(this, Opts, allArgs));
220+
250221
std::vector<std::string> swiftArgs;
251222
// We are using Swift frontend mode.
252223
swiftArgs.push_back("-frontend");
224+
// We pass the entire argument list via -Xcc, so the invocation should
225+
// use extra clang options alone.
226+
swiftArgs.push_back("-only-use-extra-clang-opts");
253227
auto addClangArg = [&](StringRef arg) {
254-
swiftArgs.push_back("-Xcc");
255-
swiftArgs.push_back("-Xclang");
256228
swiftArgs.push_back("-Xcc");
257229
swiftArgs.push_back(arg.str());
258230
};
259231
// Add all args inheritted from creating the importer.
260-
for (auto arg: cc1Args) {
261-
addClangArg(arg);
262-
}
263-
// Add all args reported from the Clang dependencies scanner.
264-
for(auto arg: clangModuleDep.NonPathCommandLine) {
232+
for (auto arg: allArgs) {
265233
addClangArg(arg);
266234
}
267-
268-
// Add -fmodule-map-file and -fmodule-file for direct dependencies.
269-
for (auto &dep: clangModuleDep.ClangModuleDeps) {
270-
assert(moduleInfoMap[dep.ModuleName].count(dep.ContextHash));
271-
addClangArg((llvm::Twine("-fmodule-map-file=")
272-
+ moduleInfoMap[dep.ModuleName][dep.ContextHash].ModuleMapPath).str());
273-
addClangArg((llvm::Twine("-fmodule-file=")
274-
+ moduleInfoMap[dep.ModuleName][dep.ContextHash].PCMPath).str());
275-
}
276235
// Swift frontend action: -emit-pcm
277236
swiftArgs.push_back("-emit-pcm");
278237
swiftArgs.push_back("-module-name");
279238
swiftArgs.push_back(clangModuleDep.ModuleName);
280239

281-
// Swift frontend option for output file path (Foo.pcm).
282-
swiftArgs.push_back("-o");
283-
swiftArgs.push_back(moduleInfoMap[clangModuleDep.ModuleName]
284-
[clangModuleDep.ContextHash].PCMPath);
285-
286240
// Swift frontend option for input file path (Foo.modulemap).
287241
swiftArgs.push_back(clangModuleDep.ClangModuleMapFile);
288242
// Module-level dependencies.

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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ 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+
8688
// Always track system dependencies when scanning dependencies.
8789
if (const Arg *ModeArg = Args.getLastArg(OPT_modes_Group)) {
8890
if (ModeArg->getOption().matches(OPT_scan_dependencies))

0 commit comments

Comments
 (0)