@@ -609,42 +609,60 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
609
609
}
610
610
611
611
void ModuleDecl::setIsSystemModule (bool flag) {
612
+ bool previous = Bits.ModuleDecl .IsSystemModule ;
613
+
612
614
Bits.ModuleDecl .IsSystemModule = flag;
613
- updateNonUserModule (/* newFile=*/ nullptr );
615
+
616
+ if (flag && previous != flag) {
617
+ updateNonUserModule (/* newFile=*/ nullptr );
618
+ }
614
619
}
615
620
616
621
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)
621
628
return false ;
622
629
}
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 ;
624
637
}
625
638
626
639
void ModuleDecl::updateNonUserModule (FileUnit *newUnit) {
627
640
if (isNonUserModule ())
628
641
return ;
629
642
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 ;
631
646
StringRef sdkPath = searchPathOpts.getSDKPath ();
632
-
633
- if (isStdlibModule () || (sdkPath.empty () && isSystemModule ())) {
647
+ if (sdkPath.empty () && isSystemModule ()) {
634
648
Bits.ModuleDecl .IsNonUserModule = true ;
635
649
return ;
636
650
}
637
651
638
- // If we loaded a serialized module, check if it was compiler adjacent or in
639
- // the SDK.
640
-
641
652
auto *LF = dyn_cast_or_null<LoadedFile>(newUnit);
642
653
if (!LF)
643
654
return ;
644
655
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).
646
659
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)) ||
648
666
(!sdkPath.empty () && prefixMatches (sdkPath, modulePath))) {
649
667
Bits.ModuleDecl .IsNonUserModule = true ;
650
668
}
@@ -670,7 +688,9 @@ void ModuleDecl::addFile(FileUnit &newFile) {
670
688
Files.push_back (&newFile);
671
689
clearLookupCache ();
672
690
673
- updateNonUserModule (&newFile);
691
+ if (Files.size () == 1 ) {
692
+ updateNonUserModule (&newFile);
693
+ }
674
694
}
675
695
676
696
void ModuleDecl::addAuxiliaryFile (SourceFile &sourceFile) {
0 commit comments