Skip to content

Commit 2041a3f

Browse files
committed
[AST] Do not copy SearchPathOptions
`updateNonUserModule` was accidentally copying `SearchPathOptions`. Take a reference to it instead. Also avoid calling `updateNonUserModule` when it isn't needed. Resolves rdar://107155587.
1 parent cd52979 commit 2041a3f

File tree

2 files changed

+36
-16
lines changed

2 files changed

+36
-16
lines changed

include/swift/AST/Module.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ class ModuleDecl
663663
/// \returns true if this module is part of the stdlib or contained within
664664
/// the SDK. If no SDK was specified, also falls back to whether the module
665665
/// was specified as a system module (ie. it's on the system search path).
666-
bool isNonUserModule() const { return Bits.ModuleDecl.IsNonUserModule; }
666+
bool isNonUserModule() const;
667667

668668
private:
669669
/// Update whether this module is a non-user module, see \c isNonUserModule.

lib/AST/Module.cpp

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -609,42 +609,60 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
609609
}
610610

611611
void ModuleDecl::setIsSystemModule(bool flag) {
612+
bool previous = Bits.ModuleDecl.IsSystemModule;
613+
612614
Bits.ModuleDecl.IsSystemModule = flag;
613-
updateNonUserModule(/*newFile=*/nullptr);
615+
616+
if (flag && previous != flag) {
617+
updateNonUserModule(/*newFile=*/nullptr);
618+
}
614619
}
615620

616621
static bool prefixMatches(StringRef prefix, StringRef path) {
617-
auto i = llvm::sys::path::begin(prefix), e = llvm::sys::path::end(prefix);
618-
for (auto pi = llvm::sys::path::begin(path), pe = llvm::sys::path::end(path);
619-
i != e && pi != pe; ++i, ++pi) {
620-
if (*i != *pi)
622+
auto prefixIt = llvm::sys::path::begin(prefix),
623+
prefixEnd = llvm::sys::path::end(prefix);
624+
for (auto pathIt = llvm::sys::path::begin(path),
625+
pathEnd = llvm::sys::path::end(path);
626+
prefixIt != prefixEnd && pathIt != pathEnd; ++prefixIt, ++pathIt) {
627+
if (*prefixIt != *pathIt)
621628
return false;
622629
}
623-
return i == e;
630+
return prefixIt == prefixEnd;
631+
}
632+
633+
bool ModuleDecl::isNonUserModule() const {
634+
return const_cast<ModuleDecl *>(this)
635+
->getTopLevelModule()
636+
->Bits.ModuleDecl.IsNonUserModule;
624637
}
625638

626639
void ModuleDecl::updateNonUserModule(FileUnit *newUnit) {
627640
if (isNonUserModule())
628641
return;
629642

630-
SearchPathOptions searchPathOpts = getASTContext().SearchPathOpts;
643+
// If there's no SDK path, fallback to checking whther the module was
644+
// in the system search path or a clang system module.
645+
SearchPathOptions &searchPathOpts = getASTContext().SearchPathOpts;
631646
StringRef sdkPath = searchPathOpts.getSDKPath();
632-
633-
if (isStdlibModule() || (sdkPath.empty() && isSystemModule())) {
647+
if (sdkPath.empty() && isSystemModule()) {
634648
Bits.ModuleDecl.IsNonUserModule = true;
635649
return;
636650
}
637651

638-
// If we loaded a serialized module, check if it was compiler adjacent or in
639-
// the SDK.
640-
641652
auto *LF = dyn_cast_or_null<LoadedFile>(newUnit);
642653
if (!LF)
643654
return;
644655

645-
StringRef runtimePath = searchPathOpts.RuntimeResourcePath;
656+
// Clang submodules have no source path. We'll check them by retrieving
657+
// the top level module on request (though in general, nothing asking for
658+
// whether a module is a non-user module should be working on submodules).
646659
StringRef modulePath = LF->getSourceFilename();
647-
if ((!runtimePath.empty() && prefixMatches(runtimePath, modulePath)) ||
660+
if (modulePath.empty())
661+
return;
662+
663+
StringRef runtimePath = searchPathOpts.RuntimeResourcePath;
664+
if (isStdlibModule() ||
665+
(!runtimePath.empty() && prefixMatches(runtimePath, modulePath)) ||
648666
(!sdkPath.empty() && prefixMatches(sdkPath, modulePath))) {
649667
Bits.ModuleDecl.IsNonUserModule = true;
650668
}
@@ -670,7 +688,9 @@ void ModuleDecl::addFile(FileUnit &newFile) {
670688
Files.push_back(&newFile);
671689
clearLookupCache();
672690

673-
updateNonUserModule(&newFile);
691+
if (Files.size() == 1) {
692+
updateNonUserModule(&newFile);
693+
}
674694
}
675695

676696
void ModuleDecl::addAuxiliaryFile(SourceFile &sourceFile) {

0 commit comments

Comments
 (0)