diff options
Diffstat (limited to 'lib/Basic/Module.cpp')
-rw-r--r-- | lib/Basic/Module.cpp | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index 1a0c190590589..fd552f2baaca3 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -71,6 +71,37 @@ Module::~Module() { } } +static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) { + StringRef Platform = Target.getPlatformName(); + StringRef Env = Target.getTriple().getEnvironmentName(); + + // Attempt to match platform and environment. + if (Platform == Feature || Target.getTriple().getOSName() == Feature || + Env == Feature) + return true; + + auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) { + auto Pos = LHS.find("-"); + if (Pos == StringRef::npos) + return false; + SmallString<128> NewLHS = LHS.slice(0, Pos); + NewLHS += LHS.slice(Pos+1, LHS.size()); + return NewLHS == RHS; + }; + + SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName(); + // Darwin has different but equivalent variants for simulators, example: + // 1. x86_64-apple-ios-simulator + // 2. x86_64-apple-iossimulator + // where both are valid examples of the same platform+environment but in the + // variant (2) the simulator is hardcoded as part of the platform name. Both + // forms above should match for "iossimulator" requirement. + if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator")) + return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature); + + return PlatformEnv == Feature; +} + /// Determine whether a translation unit built using the current /// language options has the given feature. static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, @@ -88,12 +119,13 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Case("c17", LangOpts.C17) .Case("freestanding", LangOpts.Freestanding) .Case("gnuinlineasm", LangOpts.GNUAsm) - .Case("objc", LangOpts.ObjC1) + .Case("objc", LangOpts.ObjC) .Case("objc_arc", LangOpts.ObjCAutoRefCount) .Case("opencl", LangOpts.OpenCL) .Case("tls", Target.isTLSSupported()) .Case("zvector", LangOpts.ZVector) - .Default(Target.hasFeature(Feature)); + .Default(Target.hasFeature(Feature) || + isPlatformEnvironment(Target, Feature)); if (!HasFeature) HasFeature = std::find(LangOpts.ModuleFeatures.begin(), LangOpts.ModuleFeatures.end(), @@ -577,10 +609,6 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, }; std::function<void(Visiting)> VisitModule = [&](Visiting V) { - // Modules that aren't available cannot be made visible. - if (!V.M->isAvailable()) - return; - // Nothing to do for a module that's already visible. unsigned ID = V.M->getVisibilityID(); if (ImportLocs.size() <= ID) @@ -594,8 +622,11 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, // Make any exported modules visible. SmallVector<Module *, 16> Exports; V.M->getExportedModules(Exports); - for (Module *E : Exports) - VisitModule({E, &V}); + for (Module *E : Exports) { + // Don't recurse to unavailable submodules. + if (E->isAvailable()) + VisitModule({E, &V}); + } for (auto &C : V.M->Conflicts) { if (isVisible(C.Other)) { |