mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge remote-tracking branch 'origin/main' into rebranch
This commit is contained in:
@@ -110,6 +110,8 @@ ERROR(error_cannot_direct_cc1_pcm_build_in_mode,none,
|
||||
"'-direct-clang-cc1-module-build' only supported when building a PCM ('-emit-pcm')'", ())
|
||||
ERROR(error_unsupported_option_argument,none,
|
||||
"unsupported argument '%1' to option '%0'", (StringRef, StringRef))
|
||||
ERROR(error_swift_module_file_requires_delimeter,none,
|
||||
"-swift-module-file= argument requires format <name>=<path>, got: '%0'", (StringRef))
|
||||
ERROR(error_immediate_mode_missing_stdlib,none,
|
||||
"could not load the swift standard library", ())
|
||||
ERROR(error_immediate_mode_missing_library,none,
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
|
||||
/// The Swift frontend invocation arguments to build the Swift module from the
|
||||
/// interface.
|
||||
const std::vector<std::string> buildCommandLine;
|
||||
std::vector<std::string> buildCommandLine;
|
||||
|
||||
/// The hash value that will be used for the generated module
|
||||
const std::string contextHash;
|
||||
@@ -186,6 +186,10 @@ public:
|
||||
static bool classof(const ModuleDependencyInfoStorageBase *base) {
|
||||
return base->dependencyKind == ModuleDependencyKind::SwiftInterface;
|
||||
}
|
||||
|
||||
void updateCommandLine(const std::vector<std::string> &newCommandLine) {
|
||||
buildCommandLine = newCommandLine;
|
||||
}
|
||||
};
|
||||
|
||||
/// Describes the dependencies of a Swift module
|
||||
@@ -433,6 +437,11 @@ public:
|
||||
storage->resolvedModuleDependencies.assign(dependencyIDs.begin(), dependencyIDs.end());
|
||||
}
|
||||
|
||||
void updateCommandLine(const std::vector<std::string> &newCommandLine) {
|
||||
assert(isSwiftInterfaceModule() && "Can only update command line on Swift interface dependency");
|
||||
cast<SwiftInterfaceModuleDependenciesStorage>(storage.get())->updateCommandLine(newCommandLine);
|
||||
}
|
||||
|
||||
bool isResolved() const {
|
||||
return storage->resolved;
|
||||
}
|
||||
@@ -752,4 +761,17 @@ public:
|
||||
|
||||
} // namespace swift
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<swift::ModuleDependencyID> {
|
||||
using UnderlyingKindType = std::underlying_type<swift::ModuleDependencyKind>::type;
|
||||
std::size_t operator()(const swift::ModuleDependencyID &id) const {
|
||||
auto underlyingKindValue = static_cast<UnderlyingKindType>(id.second);
|
||||
|
||||
return (hash<string>()(id.first) ^
|
||||
(hash<UnderlyingKindType>()(underlyingKindValue)));
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif /* SWIFT_AST_MODULE_DEPENDENCIES_H */
|
||||
|
||||
@@ -355,6 +355,10 @@ public:
|
||||
/// A map of explicit Swift module information.
|
||||
std::string ExplicitSwiftModuleMap;
|
||||
|
||||
/// Module inputs specified with -swift-module-input,
|
||||
/// <ModuleName, Path to .swiftmodule file>
|
||||
std::vector<std::pair<std::string, std::string>> ExplicitSwiftModuleInputs;
|
||||
|
||||
/// A map of placeholder Swift module dependency information.
|
||||
std::string PlaceholderDependencyModuleMap;
|
||||
|
||||
|
||||
@@ -129,7 +129,8 @@ class SearchPathOptions;
|
||||
class CompilerInvocation;
|
||||
|
||||
/// A ModuleLoader that loads explicitly built Swift modules specified via
|
||||
/// -swift-module-file
|
||||
/// -swift-module-file or modules found in a provided
|
||||
/// -explicit-swift-module-map-file JSON input.
|
||||
class ExplicitSwiftModuleLoader: public SerializedModuleLoaderBase {
|
||||
explicit ExplicitSwiftModuleLoader(ASTContext &ctx, DependencyTracker *tracker,
|
||||
ModuleLoadingMode loadMode,
|
||||
@@ -164,6 +165,7 @@ public:
|
||||
create(ASTContext &ctx,
|
||||
DependencyTracker *tracker, ModuleLoadingMode loadMode,
|
||||
StringRef ExplicitSwiftModuleMap,
|
||||
const std::vector<std::pair<std::string, std::string>> &ExplicitSwiftModuleInputs,
|
||||
bool IgnoreSwiftSourceInfoFile);
|
||||
|
||||
/// Append visible module names to \p names. Note that names are possibly
|
||||
|
||||
@@ -185,6 +185,10 @@ def disable_typo_correction : Flag<["-"], "disable-typo-correction">,
|
||||
def disable_implicit_swift_modules: Flag<["-"], "disable-implicit-swift-modules">,
|
||||
HelpText<"Disable building Swift modules implicitly by the compiler">;
|
||||
|
||||
def swift_module_file: Joined<["-"], "swift-module-file=">,
|
||||
MetaVarName<"<name>=<path>">,
|
||||
HelpText<"Specify Swift module input explicitly built from textual interface">;
|
||||
|
||||
def explicit_swift_module_map
|
||||
: Separate<["-"], "explicit-swift-module-map-file">, MetaVarName<"<path>">,
|
||||
HelpText<"Specify a JSON file containing information of explicit Swift modules">;
|
||||
|
||||
@@ -153,15 +153,15 @@ void ClangImporter::recordModuleDependencies(
|
||||
// We are using Swift frontend mode.
|
||||
swiftArgs.push_back("-frontend");
|
||||
|
||||
// We pass the entire argument list via -Xcc, so the invocation should
|
||||
// use extra clang options alone.
|
||||
swiftArgs.push_back("-only-use-extra-clang-opts");
|
||||
|
||||
// Swift frontend action: -emit-pcm
|
||||
swiftArgs.push_back("-emit-pcm");
|
||||
swiftArgs.push_back("-module-name");
|
||||
swiftArgs.push_back(clangModuleDep.ID.ModuleName);
|
||||
|
||||
// We pass the entire argument list via -Xcc, so the invocation should
|
||||
// use extra clang options alone.
|
||||
swiftArgs.push_back("-only-use-extra-clang-opts");
|
||||
|
||||
auto pcmPath = moduleCacheRelativeLookupModuleOutput(
|
||||
clangModuleDep.ID, ModuleOutputKind::ModuleFile,
|
||||
getModuleCachePathFromClang(getClangInstance()));
|
||||
|
||||
@@ -656,19 +656,6 @@ struct llvm::DenseMapInfo<ModuleIdentifierArrayKind> {
|
||||
}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<ModuleDependencyID> {
|
||||
using UnderlyingKindType = std::underlying_type<ModuleDependencyKind>::type;
|
||||
std::size_t operator()(const ModuleDependencyID &id) const {
|
||||
auto underlyingKindValue = static_cast<UnderlyingKindType>(id.second);
|
||||
|
||||
return (hash<string>()(id.first) ^
|
||||
(hash<UnderlyingKindType>()(underlyingKindValue)));
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
namespace swift {
|
||||
|
||||
class ModuleDependenciesCacheSerializer {
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "swift/Strings.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SetOperations.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
@@ -47,6 +48,7 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace swift;
|
||||
using namespace swift::dependencies;
|
||||
@@ -157,6 +159,149 @@ static void findAllImportedClangModules(ASTContext &ctx, StringRef moduleName,
|
||||
}
|
||||
}
|
||||
|
||||
// Get all dependencies's IDs of this module from its cached
|
||||
// ModuleDependencyInfo
|
||||
static ArrayRef<ModuleDependencyID>
|
||||
getDependencies(const ModuleDependencyID &moduleID,
|
||||
const ModuleDependenciesCache &cache) {
|
||||
const auto &optionalModuleInfo =
|
||||
cache.findDependency(moduleID.first, moduleID.second);
|
||||
assert(optionalModuleInfo.has_value());
|
||||
return optionalModuleInfo.value()->getModuleDependencies();
|
||||
}
|
||||
|
||||
/// Implements a topological sort via recursion and reverse postorder DFS.
|
||||
/// Does not bother handling cycles, relying on a DAG guarantee by the client.
|
||||
static std::vector<ModuleDependencyID>
|
||||
computeTopologicalSortOfExplicitDependencies(
|
||||
const ModuleDependencyIDSetVector &allModules,
|
||||
const ModuleDependenciesCache &cache) {
|
||||
std::unordered_set<ModuleDependencyID> visited;
|
||||
std::vector<ModuleDependencyID> result;
|
||||
std::stack<ModuleDependencyID> stack;
|
||||
|
||||
// Must be explicitly-typed to allow recursion
|
||||
std::function<void(const ModuleDependencyID &)> visit;
|
||||
visit = [&visit, &cache, &visited, &result,
|
||||
&stack](const ModuleDependencyID &moduleID) {
|
||||
// Mark this node as visited -- we are done if it already was.
|
||||
if (!visited.insert(moduleID).second)
|
||||
return;
|
||||
|
||||
// Otherwise, visit each adjacent node.
|
||||
for (const auto &succID : getDependencies(moduleID, cache)) {
|
||||
// We don't worry if successor is already in this current stack,
|
||||
// since that would mean we have found a cycle, which should not
|
||||
// be possible because we checked for cycles earlier.
|
||||
stack.push(succID);
|
||||
visit(succID);
|
||||
auto top = stack.top();
|
||||
stack.pop();
|
||||
assert(top == succID);
|
||||
}
|
||||
|
||||
// Add to the result.
|
||||
result.push_back(moduleID);
|
||||
};
|
||||
|
||||
for (const auto &modID : allModules) {
|
||||
assert(stack.empty());
|
||||
stack.push(modID);
|
||||
visit(modID);
|
||||
auto top = stack.top();
|
||||
stack.pop();
|
||||
assert(top == modID);
|
||||
}
|
||||
|
||||
std::reverse(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// For each module in the graph, compute a set of all its dependencies,
|
||||
/// direct *and* transitive.
|
||||
static std::unordered_map<ModuleDependencyID,
|
||||
std::set<ModuleDependencyID>>
|
||||
computeTransitiveClosureOfExplicitDependencies(
|
||||
const std::vector<ModuleDependencyID> &topologicallySortedModuleList,
|
||||
const ModuleDependenciesCache &cache) {
|
||||
// The usage of an ordered ::set is important to ensure the
|
||||
// dependencies are listed in a deterministic order.
|
||||
std::unordered_map<ModuleDependencyID, std::set<ModuleDependencyID>>
|
||||
result;
|
||||
for (const auto &modID : topologicallySortedModuleList)
|
||||
result[modID] = {modID};
|
||||
|
||||
// Traverse the set of modules in reverse topological order, assimilating
|
||||
// transitive closures
|
||||
for (auto it = topologicallySortedModuleList.rbegin(),
|
||||
end = topologicallySortedModuleList.rend();
|
||||
it != end; ++it) {
|
||||
const auto &modID = *it;
|
||||
auto &modReachableSet = result[modID];
|
||||
for (const auto &succID : getDependencies(modID, cache)) {
|
||||
const auto &succReachableSet = result[succID];
|
||||
llvm::set_union(modReachableSet, succReachableSet);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
resolveExplicitModuleInputs(ModuleDependencyID moduleID,
|
||||
const ModuleDependencyInfo &resolvingDepInfo,
|
||||
const std::set<ModuleDependencyID> &dependencies,
|
||||
ModuleDependenciesCache &cache) {
|
||||
auto resolvingInterfaceDepDetails =
|
||||
resolvingDepInfo.getAsSwiftInterfaceModule();
|
||||
assert(resolvingInterfaceDepDetails &&
|
||||
"Expected Swift Interface dependency.");
|
||||
|
||||
auto commandLine = resolvingInterfaceDepDetails->buildCommandLine;
|
||||
for (const auto &depModuleID : dependencies) {
|
||||
const auto optionalDepInfo =
|
||||
cache.findDependency(depModuleID.first, depModuleID.second);
|
||||
assert(optionalDepInfo.has_value());
|
||||
const auto depInfo = optionalDepInfo.value();
|
||||
switch (depModuleID.second) {
|
||||
case swift::ModuleDependencyKind::SwiftInterface: {
|
||||
auto interfaceDepDetails = depInfo->getAsSwiftInterfaceModule();
|
||||
assert(interfaceDepDetails && "Expected Swift Interface dependency.");
|
||||
commandLine.push_back("-swift-module-file=" + depModuleID.first + "=" +
|
||||
interfaceDepDetails->moduleOutputPath);
|
||||
} break;
|
||||
case swift::ModuleDependencyKind::SwiftBinary: {
|
||||
auto binaryDepDetails = depInfo->getAsSwiftBinaryModule();
|
||||
assert(binaryDepDetails && "Expected Swift Binary Module dependency.");
|
||||
commandLine.push_back("-swift-module-file=" + depModuleID.first + "=" +
|
||||
binaryDepDetails->compiledModulePath);
|
||||
} break;
|
||||
case swift::ModuleDependencyKind::SwiftPlaceholder: {
|
||||
auto placeholderDetails = depInfo->getAsPlaceholderDependencyModule();
|
||||
assert(placeholderDetails && "Expected Swift Placeholder dependency.");
|
||||
commandLine.push_back("-swift-module-file=" + depModuleID.first + "=" +
|
||||
placeholderDetails->compiledModulePath);
|
||||
} break;
|
||||
case swift::ModuleDependencyKind::Clang: {
|
||||
auto clangDepDetails = depInfo->getAsClangModule();
|
||||
assert(clangDepDetails && "Expected Clang Module dependency.");
|
||||
commandLine.push_back("-Xcc");
|
||||
commandLine.push_back("-fmodule-file=" + depModuleID.first + "=" +
|
||||
clangDepDetails->pcmOutputPath);
|
||||
commandLine.push_back("-Xcc");
|
||||
commandLine.push_back("-fmodule-map-file=" +
|
||||
clangDepDetails->moduleMapFile);
|
||||
} break;
|
||||
default:
|
||||
llvm_unreachable("Unhandled dependency kind.");
|
||||
}
|
||||
}
|
||||
|
||||
// Update the dependency in the cache with the modified command-line.
|
||||
auto dependencyInfoCopy = resolvingDepInfo;
|
||||
dependencyInfoCopy.updateCommandLine(commandLine);
|
||||
cache.updateDependency(moduleID, dependencyInfoCopy);
|
||||
}
|
||||
|
||||
/// Resolve the direct dependencies of the given module.
|
||||
static ArrayRef<ModuleDependencyID>
|
||||
resolveDirectDependencies(CompilerInstance &instance, ModuleDependencyID module,
|
||||
@@ -1475,8 +1620,29 @@ swift::dependencies::performModuleScan(CompilerInstance &instance,
|
||||
if (diagnoseCycle(instance, cache, mainModuleID, ASTDelegate))
|
||||
return std::make_error_code(std::errc::not_supported);
|
||||
|
||||
// Resolve Swift dependency command-line arguments
|
||||
// Must happen after cycle detection, because it relies on
|
||||
// the DAG property of the dependency graph.
|
||||
auto topoSortedModuleList =
|
||||
computeTopologicalSortOfExplicitDependencies(allModules, cache);
|
||||
auto moduleTransitiveClosures =
|
||||
computeTransitiveClosureOfExplicitDependencies(topoSortedModuleList,
|
||||
cache);
|
||||
for (const auto &dependencyClosure : moduleTransitiveClosures) {
|
||||
auto &modID = dependencyClosure.first;
|
||||
// For main module or binary modules, no command-line to resolve.
|
||||
// For Clang modules, their dependencies are resolved by the clang Scanner
|
||||
// itself for us.
|
||||
if (modID.second != ModuleDependencyKind::SwiftInterface)
|
||||
continue;
|
||||
auto optionalDeps = cache.findDependency(modID.first, modID.second);
|
||||
assert(optionalDeps.has_value());
|
||||
auto deps = optionalDeps.value();
|
||||
resolveExplicitModuleInputs(modID, *deps, dependencyClosure.second, cache);
|
||||
}
|
||||
|
||||
auto dependencyGraph = generateFullDependencyGraph(
|
||||
instance, cache, ASTDelegate, allModules.getArrayRef());
|
||||
instance, cache, ASTDelegate, topoSortedModuleList);
|
||||
// Update the dependency tracker.
|
||||
if (auto depTracker = instance.getDependencyTracker()) {
|
||||
for (auto module : allModules) {
|
||||
|
||||
@@ -1363,6 +1363,25 @@ static void ParseSymbolGraphArgs(symbolgraphgen::SymbolGraphOptions &Opts,
|
||||
Opts.IncludeClangDocs = false;
|
||||
}
|
||||
|
||||
static bool validateSwiftModuleFileArgumentAndAdd(const std::string &swiftModuleArgument,
|
||||
DiagnosticEngine &Diags,
|
||||
std::vector<std::pair<std::string, std::string>> &ExplicitSwiftModuleInputs) {
|
||||
std::size_t foundDelimeterPos = swiftModuleArgument.find_first_of("=");
|
||||
if (foundDelimeterPos == std::string::npos) {
|
||||
Diags.diagnose(SourceLoc(), diag::error_swift_module_file_requires_delimeter,
|
||||
swiftModuleArgument);
|
||||
return true;
|
||||
}
|
||||
std::string moduleName = swiftModuleArgument.substr(0, foundDelimeterPos),
|
||||
modulePath = swiftModuleArgument.substr(foundDelimeterPos+1);
|
||||
if (!Lexer::isIdentifier(moduleName)) {
|
||||
Diags.diagnose(SourceLoc(), diag::error_bad_module_name, moduleName, false);
|
||||
return true;
|
||||
}
|
||||
ExplicitSwiftModuleInputs.emplace_back(std::make_pair(moduleName, modulePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ParseSearchPathArgs(SearchPathOptions &Opts,
|
||||
ArgList &Args,
|
||||
DiagnosticEngine &Diags,
|
||||
@@ -1415,6 +1434,11 @@ static bool ParseSearchPathArgs(SearchPathOptions &Opts,
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_explicit_swift_module_map))
|
||||
Opts.ExplicitSwiftModuleMap = A->getValue();
|
||||
for (auto A : Args.getAllArgValues(options::OPT_swift_module_file)) {
|
||||
if (validateSwiftModuleFileArgumentAndAdd(A, Diags,
|
||||
Opts.ExplicitSwiftModuleInputs))
|
||||
return true;
|
||||
}
|
||||
for (auto A: Args.filtered(OPT_candidate_module_file)) {
|
||||
Opts.CandidateCompiledModules.push_back(resolveSearchPath(A->getValue()));
|
||||
}
|
||||
|
||||
@@ -566,10 +566,12 @@ bool CompilerInstance::setUpModuleLoaders() {
|
||||
bool ExplicitModuleBuild =
|
||||
Invocation.getFrontendOptions().DisableImplicitModules;
|
||||
if (ExplicitModuleBuild ||
|
||||
!Invocation.getSearchPathOptions().ExplicitSwiftModuleMap.empty()) {
|
||||
!Invocation.getSearchPathOptions().ExplicitSwiftModuleMap.empty() ||
|
||||
!Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs.empty()) {
|
||||
ESML = ExplicitSwiftModuleLoader::create(
|
||||
*Context, getDependencyTracker(), MLM,
|
||||
Invocation.getSearchPathOptions().ExplicitSwiftModuleMap,
|
||||
Invocation.getSearchPathOptions().ExplicitSwiftModuleInputs,
|
||||
IgnoreSourceInfoFile);
|
||||
}
|
||||
|
||||
|
||||
@@ -1897,6 +1897,16 @@ struct ExplicitSwiftModuleLoader::Implementation {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addCommandLineExplicitInputs(
|
||||
const std::vector<std::pair<std::string, std::string>>
|
||||
&commandLineExplicitInputs) {
|
||||
for (const auto &moduleInput : commandLineExplicitInputs) {
|
||||
ExplicitModuleInfo entry;
|
||||
entry.modulePath = moduleInput.second;
|
||||
ExplicitModuleMap.try_emplace(moduleInput.first, std::move(entry));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ExplicitSwiftModuleLoader::ExplicitSwiftModuleLoader(
|
||||
@@ -2057,6 +2067,7 @@ std::unique_ptr<ExplicitSwiftModuleLoader>
|
||||
ExplicitSwiftModuleLoader::create(ASTContext &ctx,
|
||||
DependencyTracker *tracker, ModuleLoadingMode loadMode,
|
||||
StringRef ExplicitSwiftModuleMap,
|
||||
const std::vector<std::pair<std::string, std::string>> &ExplicitSwiftModuleInputs,
|
||||
bool IgnoreSwiftSourceInfoFile) {
|
||||
auto result = std::unique_ptr<ExplicitSwiftModuleLoader>(
|
||||
new ExplicitSwiftModuleLoader(ctx, tracker, loadMode,
|
||||
@@ -2067,6 +2078,11 @@ ExplicitSwiftModuleLoader::create(ASTContext &ctx,
|
||||
// Parse a JSON file to collect explicitly built modules.
|
||||
Impl.parseSwiftExplicitModuleMap(ExplicitSwiftModuleMap);
|
||||
}
|
||||
// If some modules are provided with explicit
|
||||
// '-swift-module-file' options, add those as well.
|
||||
if (!ExplicitSwiftModuleInputs.empty()) {
|
||||
Impl.addCommandLineExplicitInputs(ExplicitSwiftModuleInputs);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -112,21 +112,38 @@ ErrorOr<ModuleDependencyInfo> ModuleDependencyScanner::scanInterfaceFile(
|
||||
StringRef(),
|
||||
SourceLoc(),
|
||||
[&](ASTContext &Ctx, ModuleDecl *mainMod,
|
||||
ArrayRef<StringRef> Args,
|
||||
ArrayRef<StringRef> BaseArgs,
|
||||
ArrayRef<StringRef> PCMArgs, StringRef Hash) {
|
||||
assert(mainMod);
|
||||
std::string InPath = moduleInterfacePath.str();
|
||||
auto compiledCandidates = getCompiledCandidates(Ctx, realModuleName.str(),
|
||||
InPath);
|
||||
std::vector<std::string> Args(BaseArgs.begin(), BaseArgs.end());
|
||||
|
||||
// Add explicit Swift dependency compilation flags
|
||||
Args.push_back("-explicit-interface-module-build");
|
||||
Args.push_back("-disable-implicit-swift-modules");
|
||||
Args.push_back("-Xcc"); Args.push_back("-fno-implicit-modules");
|
||||
Args.push_back("-Xcc"); Args.push_back("-fno-implicit-module-maps");
|
||||
for (const auto &candidate : compiledCandidates) {
|
||||
Args.push_back("-candidate-module-file");
|
||||
Args.push_back(candidate);
|
||||
}
|
||||
|
||||
// Compute the output path and add it to the command line
|
||||
SmallString<128> outputPathBase(moduleCachePath);
|
||||
llvm::sys::path::append(
|
||||
outputPathBase,
|
||||
moduleName.str() + "-" + Hash + "." +
|
||||
file_types::getExtension(file_types::TY_SwiftModuleFile));
|
||||
Args.push_back("-o");
|
||||
Args.push_back(outputPathBase.str().str());
|
||||
|
||||
std::vector<StringRef> ArgsRefs(Args.begin(), Args.end());
|
||||
Result = ModuleDependencyInfo::forSwiftInterfaceModule(
|
||||
outputPathBase.str().str(), InPath, compiledCandidates, Args, PCMArgs,
|
||||
outputPathBase.str().str(), InPath, compiledCandidates, ArgsRefs, PCMArgs,
|
||||
Hash, isFramework);
|
||||
|
||||
// Open the interface file.
|
||||
auto &fs = *Ctx.SourceMgr.getFileSystem();
|
||||
auto interfaceBuf = fs.getBufferForFile(moduleInterfacePath);
|
||||
|
||||
55
test/ScanDependencies/explicit-swift-dependencies.swift
Normal file
55
test/ScanDependencies/explicit-swift-dependencies.swift
Normal file
@@ -0,0 +1,55 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: mkdir -p %t/clang-module-cache
|
||||
|
||||
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4
|
||||
// Check the contents of the JSON output
|
||||
// RUN: %FileCheck %s < %t/deps.json
|
||||
|
||||
// REQUIRES: executable_test
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
|
||||
import F
|
||||
|
||||
// CHECK: "mainModuleName": "deps"
|
||||
|
||||
/// --------Main module
|
||||
// CHECK-LABEL: "modulePath": "deps.swiftmodule",
|
||||
// CHECK-NEXT: sourceFiles
|
||||
// CHECK-NEXT: explicit-swift-dependencies.swift
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "directDependencies": [
|
||||
// CHECK-DAG: "swift": "F"
|
||||
// CHECK-DAG: "swift": "Swift"
|
||||
// CHECK-DAG: "swift": "SwiftOnoneSupport"
|
||||
// CHECK-DAG: "swift": "_Concurrency"
|
||||
// CHECK-DAG: "clang": "_SwiftConcurrencyShims"
|
||||
// CHECK-DAG: "swift": "_StringProcessing"
|
||||
// CHECK: ],
|
||||
|
||||
/// --------Swift module F
|
||||
// CHECK: "modulePath": "{{.*}}{{/|\\}}F-{{.*}}.swiftmodule",
|
||||
// CHECK: directDependencies
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-DAG: "clang": "F"
|
||||
// CHECK-DAG: "swift": "Swift"
|
||||
// CHECK-DAG: "swift": "SwiftOnoneSupport"
|
||||
|
||||
|
||||
// CHECK: "commandLine": [
|
||||
// CHECK-NEXT: "-frontend",
|
||||
// CHECK-NEXT: "-compile-module-from-interface",
|
||||
// CHECK-NEXT: "-target",
|
||||
// ...
|
||||
// CHECK: "-explicit-interface-module-build",
|
||||
// CHECK-NEXT: "-disable-implicit-swift-modules",
|
||||
// CHECK-NEXT: "-Xcc",
|
||||
// CHECK-NEXT: "-fno-implicit-modules",
|
||||
// CHECK-NEXT: "-Xcc",
|
||||
// CHECK-NEXT: "-fno-implicit-module-maps",
|
||||
// CHECK-NEXT: "-o",
|
||||
// CHECK-NEXT: "{{.*}}{{/|\\}}F-{{.*}}.swiftmodule"
|
||||
// CHECK-DAG: "-swift-module-file=Swift={{.*}}{{/|\\}}Swift-{{.*}}.swiftmodule"
|
||||
// CHECK-DAG: "-swift-module-file=SwiftOnoneSupport={{.*}}{{/|\\}}SwiftOnoneSupport-{{.*}}.swiftmodule"
|
||||
// CHECK-DAG: "-fmodule-file=F={{.*}}{{/|\\}}F-{{.*}}.pcm",
|
||||
// CHECK-DAG: "-fmodule-file=SwiftShims={{.*}}{{/|\\}}SwiftShims-{{.*}}.pcm",
|
||||
@@ -62,40 +62,24 @@ import SubE
|
||||
// CHECK-NEXT: "F"
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
/// --------Clang module C
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}/C-{{.*}}.pcm",
|
||||
|
||||
// CHECK: "sourceFiles": [
|
||||
// CHECK-DAG: module.modulemap
|
||||
// CHECK-DAG: C.h
|
||||
/// --------Swift module A
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}A-{{.*}}.swiftmodule",
|
||||
|
||||
// CHECK: directDependencies
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang": "B"
|
||||
// CHECK-DAG: "clang": "A"
|
||||
// CHECK-DAG: "swift": "Swift"
|
||||
|
||||
// CHECK: "moduleMapPath"
|
||||
// CHECK-SAME: module.modulemap
|
||||
|
||||
// CHECK: "contextHash"
|
||||
// CHECK-SAME: "{{.*}}"
|
||||
|
||||
// CHECK: "commandLine": [
|
||||
// CHECK-NEXT: "-frontend"
|
||||
// CHECK-NEXT: "-only-use-extra-clang-opts
|
||||
// CHECK-NOT: "BUILD_DIR/bin/clang"
|
||||
// CHECK: "-emit-pcm",
|
||||
// CHECK: "-module-name",
|
||||
// CHECK-NEXT: "C"
|
||||
|
||||
/// --------Swift module E
|
||||
// CHECK: "swift": "E"
|
||||
// CHECK-LABEL: modulePath": "{{.*}}{{/|\\}}E-{{.*}}.swiftmodule"
|
||||
// CHECK: "directDependencies"
|
||||
/// --------Swift module F
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}F-{{.*}}.swiftmodule",
|
||||
// CHECK-NEXT: "sourceFiles": [
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "directDependencies": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "swift": "Swift"
|
||||
|
||||
// CHECK: "moduleInterfacePath"
|
||||
// CHECK-SAME: E.swiftinterface
|
||||
// CHECK-DAG: "clang": "F"
|
||||
// CHECK-DAG: "swift": "Swift"
|
||||
// CHECK-DAG: "swift": "SwiftOnoneSupport"
|
||||
// CHECK: ],
|
||||
|
||||
/// --------Swift module G
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}G-{{.*}}.swiftmodule"
|
||||
@@ -121,6 +105,16 @@ import SubE
|
||||
// CHECK" "-fapinotes-swift-version=5"
|
||||
// CHECK" ]
|
||||
|
||||
/// --------Swift module E
|
||||
// CHECK: "swift": "E"
|
||||
// CHECK-LABEL: modulePath": "{{.*}}{{/|\\}}E-{{.*}}.swiftmodule"
|
||||
// CHECK: "directDependencies"
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "swift": "Swift"
|
||||
|
||||
// CHECK: "moduleInterfacePath"
|
||||
// CHECK-SAME: E.swiftinterface
|
||||
|
||||
/// --------Swift module Swift
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}Swift-{{.*}}.swiftmodule",
|
||||
|
||||
@@ -128,24 +122,34 @@ import SubE
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang": "SwiftShims"
|
||||
|
||||
/// --------Swift module F
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}F-{{.*}}.swiftmodule",
|
||||
// CHECK-NEXT: "sourceFiles": [
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "directDependencies": [
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-DAG: "clang": "F"
|
||||
// CHECK-DAG: "swift": "Swift"
|
||||
// CHECK-DAG: "swift": "SwiftOnoneSupport"
|
||||
// CHECK: ],
|
||||
|
||||
/// --------Swift module A
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}A-{{.*}}.swiftmodule",
|
||||
/// --------Clang module SwiftShims
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}/SwiftShims-{{.*}}.pcm",
|
||||
|
||||
/// --------Clang module C
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}/C-{{.*}}.pcm",
|
||||
|
||||
// CHECK: "sourceFiles": [
|
||||
// CHECK-DAG: module.modulemap
|
||||
// CHECK-DAG: C.h
|
||||
|
||||
// CHECK: directDependencies
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-DAG: "clang": "A"
|
||||
// CHECK-DAG: "swift": "Swift"
|
||||
// CHECK-NEXT: "clang": "B"
|
||||
|
||||
// CHECK: "moduleMapPath"
|
||||
// CHECK-SAME: module.modulemap
|
||||
|
||||
// CHECK: "contextHash"
|
||||
// CHECK-SAME: "{{.*}}"
|
||||
|
||||
// CHECK: "commandLine": [
|
||||
// CHECK-NEXT: "-frontend"
|
||||
// CHECK-NOT: "BUILD_DIR/bin/clang"
|
||||
// CHECK: "-emit-pcm",
|
||||
// CHECK: "-module-name",
|
||||
// CHECK-NEXT: "C"
|
||||
// CHECK-NEXT: "-only-use-extra-clang-opts
|
||||
|
||||
/// --------Clang module B
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}/B-{{.*}}.pcm",
|
||||
@@ -158,7 +162,3 @@ import SubE
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "clang": "A"
|
||||
// CHECK-NEXT: }
|
||||
|
||||
/// --------Clang module SwiftShims
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}/SwiftShims-{{.*}}.pcm",
|
||||
|
||||
|
||||
@@ -71,13 +71,6 @@ import SomeExternalModule
|
||||
// CHECK-NEXT: "F"
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
/// --------Swift external module SomeExternalModule
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}SomeExternalModule.swiftmodule",
|
||||
// CHECK-NEXT: "details": {
|
||||
// CHECK-NEXT: "swiftPlaceholder": {
|
||||
// CHECK-NEXT: "moduleDocPath": "BUILD_DIR/{{.*}}/ScanDependencies/Output/module_deps_external.swift.tmp/inputs/SomeExternalModule.swiftdoc",
|
||||
// CHECK-NEXT: "moduleSourceInfoPath": "BUILD_DIR/{{.*}}/ScanDependencies/Output/module_deps_external.swift.tmp/inputs/SomeExternalModule.swiftsourceinfo"
|
||||
|
||||
/// --------Swift module Swift
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}Swift-{{.*}}.swiftmodule",
|
||||
|
||||
@@ -93,3 +86,10 @@ import SomeExternalModule
|
||||
// CHECK-MAKE-DEPS-SAME: Bridging.h
|
||||
// CHECK-MAKE-DEPS-SAME: BridgingOther.h
|
||||
// CHECK-MAKE-DEPS-SAME: module.modulemap
|
||||
|
||||
/// --------Swift external module SomeExternalModule
|
||||
// CHECK-LABEL: "modulePath": "{{.*}}{{/|\\}}SomeExternalModule.swiftmodule",
|
||||
// CHECK-NEXT: "details": {
|
||||
// CHECK-NEXT: "swiftPlaceholder": {
|
||||
// CHECK-NEXT: "moduleDocPath": "BUILD_DIR/{{.*}}/ScanDependencies/Output/module_deps_external.swift.tmp/inputs/SomeExternalModule.swiftdoc",
|
||||
// CHECK-NEXT: "moduleSourceInfoPath": "BUILD_DIR/{{.*}}/ScanDependencies/Output/module_deps_external.swift.tmp/inputs/SomeExternalModule.swiftsourceinfo"
|
||||
|
||||
Reference in New Issue
Block a user