summaryrefslogtreecommitdiffstats
path: root/clang/lib/Basic/Module.cpp
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2018-09-18 17:11:13 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2018-09-18 17:11:13 +0000
commite7240f024f114ad2affcf476167491db7f474956 (patch)
tree80d8eba24d86760af514d036ebb5fb05a8a76170 /clang/lib/Basic/Module.cpp
parentc85da8bd9a9dc3773fa23c572524e98ad429057d (diff)
downloadbcm5719-llvm-e7240f024f114ad2affcf476167491db7f474956.tar.gz
bcm5719-llvm-e7240f024f114ad2affcf476167491db7f474956.zip
[Modules] Add platform and environment features to requires clause
Allows module map writers to add build requirements based on platform/os. This helps when target features and language dialects aren't enough to conditionalize building a module, among other things, it allow module maps for different platforms to live in the same file. rdar://problem/43909745 Differential Revision: https://reviews.llvm.org/D51910 llvm-svn: 342499
Diffstat (limited to 'clang/lib/Basic/Module.cpp')
-rw-r--r--clang/lib/Basic/Module.cpp34
1 files changed, 33 insertions, 1 deletions
diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp
index 9ff976c03b9..440151dd061 100644
--- a/clang/lib/Basic/Module.cpp
+++ b/clang/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,
@@ -93,7 +124,8 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
.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(),
OpenPOWER on IntegriCloud