Skip to content

Commit 940f5f7

Browse files
committed
[AST] Treat platform modules as non-user
Modules defined within the SDK are considered non-user modules, extend this to any module found within the parent platform directory if there is one. This ensures we include modules such as XCTest and Testing. rdar://131854240
1 parent 7075c05 commit 940f5f7

File tree

6 files changed

+70
-4
lines changed

6 files changed

+70
-4
lines changed

include/swift/AST/SearchPathOptions.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ class SearchPathOptions {
380380

381381
std::optional<StringRef> SysRoot = std::nullopt;
382382

383+
mutable std::optional<std::string> SDKPlatformPath = std::nullopt;
384+
383385
public:
384386
StringRef getSDKPath() const { return SDKPath; }
385387

@@ -398,6 +400,12 @@ class SearchPathOptions {
398400
Lookup.searchPathsDidChange();
399401
}
400402

403+
/// Retrieves the corresponding parent platform path for the SDK, or
404+
/// \c nullopt if there isn't one.
405+
/// NOTE: This computes and caches the result, and as such will not respect
406+
/// a different FileSystem being passed later.
407+
std::optional<StringRef> getSDKPlatformPath(llvm::vfs::FileSystem *FS) const;
408+
401409
std::optional<StringRef> getWinSDKRoot() const { return WinSDKRoot; }
402410
void setWinSDKRoot(StringRef root) {
403411
WinSDKRoot = root;

include/swift/AST/TypeCheckRequests.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4773,8 +4773,9 @@ void simple_display(llvm::raw_ostream &out, const TypeRepr *TyR);
47734773
void simple_display(llvm::raw_ostream &out, ImplicitMemberAction action);
47744774

47754775
/// Computes whether a module is part of the stdlib or contained within the
4776-
/// SDK. If no SDK was specified, falls back to whether the module was
4777-
/// specified as a system module (ie. it's on the system search path).
4776+
/// SDK or the platform directory. If no SDK was specified, falls back to
4777+
/// whether the module was specified as a system module (ie. it's on the system
4778+
/// search path).
47784779
class IsNonUserModuleRequest
47794780
: public SimpleRequest<IsNonUserModuleRequest,
47804781
bool(ModuleDecl *),

lib/AST/Module.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4009,7 +4009,8 @@ FrontendStatsTracer::getTraceFormatter<const SourceFile *>() {
40094009
bool IsNonUserModuleRequest::evaluate(Evaluator &evaluator, ModuleDecl *mod) const {
40104010
// If there's no SDK path, fallback to checking whether the module was
40114011
// in the system search path or a clang system module
4012-
SearchPathOptions &searchPathOpts = mod->getASTContext().SearchPathOpts;
4012+
auto &ctx = mod->getASTContext();
4013+
SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;
40134014
StringRef sdkPath = searchPathOpts.getSDKPath();
40144015
if (sdkPath.empty() && mod->isSystemModule())
40154016
return true;
@@ -4028,9 +4029,14 @@ bool IsNonUserModuleRequest::evaluate(Evaluator &evaluator, ModuleDecl *mod) con
40284029
if (modulePath.empty())
40294030
return false;
40304031

4032+
// If we have a platform path, check against that as it will be a parent of
4033+
// the SDK path.
4034+
auto *FS = ctx.SourceMgr.getFileSystem().get();
4035+
auto sdkOrPlatform = searchPathOpts.getSDKPlatformPath(FS).value_or(sdkPath);
4036+
40314037
StringRef runtimePath = searchPathOpts.RuntimeResourcePath;
40324038
return (!runtimePath.empty() && pathStartsWith(runtimePath, modulePath)) ||
4033-
(!sdkPath.empty() && pathStartsWith(sdkPath, modulePath));
4039+
(!sdkOrPlatform.empty() && pathStartsWith(sdkOrPlatform, modulePath));
40344040
}
40354041

40364042
version::Version ModuleDecl::getLanguageVersionBuiltWith() const {

lib/AST/SearchPathOptions.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,34 @@ void ModuleSearchPathLookup::rebuildLookupTable(const SearchPathOptions *Opts,
8080
State.IsPopulated = true;
8181
}
8282

83+
static std::string computeSDKPlatformPath(StringRef SDKPath,
84+
llvm::vfs::FileSystem *FS) {
85+
if (SDKPath.empty())
86+
return "";
87+
88+
SmallString<128> platformPath;
89+
if (auto err = FS->getRealPath(SDKPath, platformPath))
90+
llvm::sys::path::append(platformPath, SDKPath);
91+
92+
llvm::sys::path::remove_filename(platformPath); // specific SDK
93+
llvm::sys::path::remove_filename(platformPath); // SDKs
94+
llvm::sys::path::remove_filename(platformPath); // Developer
95+
96+
if (!llvm::sys::path::filename(platformPath).endswith(".platform"))
97+
return "";
98+
99+
return platformPath.str().str();
100+
}
101+
102+
std::optional<StringRef>
103+
SearchPathOptions::getSDKPlatformPath(llvm::vfs::FileSystem *FS) const {
104+
if (!SDKPlatformPath)
105+
SDKPlatformPath = computeSDKPlatformPath(getSDKPath(), FS);
106+
if (SDKPlatformPath->empty())
107+
return std::nullopt;
108+
return *SDKPlatformPath;
109+
}
110+
83111
void SearchPathOptions::dump(bool isDarwin) const {
84112
llvm::errs() << "Module import search paths (non system):\n";
85113
for (auto Entry : llvm::enumerate(getImportSearchPaths())) {

test/lit.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,9 @@ if run_vendor == 'apple':
13211321
(config.darwin_xcrun_toolchain, config.variant_sdk))
13221322
extra_frameworks_dir = make_path(config.variant_sdk, "..", "..", "..",
13231323
"Developer", "Library", "Frameworks")
1324+
extra_platform_swift_modules = make_path(config.variant_sdk, "..", "..", "..",
1325+
"Developer", "usr", "lib")
1326+
13241327
target_options = (
13251328
"-target %s %s %s" %
13261329
(config.variant_triple, config.resource_dir_opt, mcp_opt))
@@ -2805,7 +2808,9 @@ config.substitutions.insert(0, ('%test-resource-dir', test_resource_dir))
28052808

28062809
if run_vendor != 'apple':
28072810
extra_frameworks_dir = ''
2811+
extra_platform_swift_modules = ''
28082812
config.substitutions.append(('%xcode-extra-frameworks-dir', extra_frameworks_dir))
2813+
config.substitutions.append(('%xcode-extra-platform-swift-modules', extra_platform_swift_modules))
28092814

28102815
config.substitutions.append(('%target-swiftmodule-name', target_specific_module_triple + '.swiftmodule'))
28112816
config.substitutions.append(('%target-swiftdoc-name', target_specific_module_triple + '.swiftdoc'))
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: ln -s %sdk %t/sdk
3+
4+
// RUN: %batch-code-completion -F %xcode-extra-frameworks-dir -I %xcode-extra-platform-swift-modules
5+
6+
// Works if SDK is specified as a symlink too.
7+
// RUN: %batch-code-completion -sdk %t/sdk -F %xcode-extra-frameworks-dir -I %xcode-extra-platform-swift-modules
8+
9+
// REQUIRES: VENDOR=apple
10+
11+
// rdar://131854240 - Make sure modules found in the platform dir are treated
12+
// as system.
13+
14+
import XCTest
15+
16+
#^COMPLETE^#
17+
// COMPLETE: Decl[Module]/None/IsSystem: XCTest[#Module#]; name=XCTest
18+
// COMPLETE: Decl[FreeFunction]/OtherModule[XCTest]/IsSystem: XCTFail()[#Void#]; name=XCTFail()

0 commit comments

Comments
 (0)