r342499 - [Modules] Add platform and environment features to requires clause
Bruno Cardoso Lopes via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 18 10:11:13 PDT 2018
Author: bruno
Date: Tue Sep 18 10:11:13 2018
New Revision: 342499
URL: http://llvm.org/viewvc/llvm-project?rev=342499&view=rev
Log:
[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
Added:
cfe/trunk/test/Modules/target-platform-features.m
Modified:
cfe/trunk/docs/Modules.rst
cfe/trunk/lib/Basic/Module.cpp
Modified: cfe/trunk/docs/Modules.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/Modules.rst?rev=342499&r1=342498&r2=342499&view=diff
==============================================================================
--- cfe/trunk/docs/Modules.rst (original)
+++ cfe/trunk/docs/Modules.rst Tue Sep 18 10:11:13 2018
@@ -411,7 +411,7 @@ A *requires-declaration* specifies the r
*feature*:
``!``:sub:`opt` *identifier*
-The requirements clause allows specific modules or submodules to specify that they are only accessible with certain language dialects or on certain platforms. The feature list is a set of identifiers, defined below. If any of the features is not available in a given translation unit, that translation unit shall not import the module. When building a module for use by a compilation, submodules requiring unavailable features are ignored. The optional ``!`` indicates that a feature is incompatible with the module.
+The requirements clause allows specific modules or submodules to specify that they are only accessible with certain language dialects, platforms, environments and target specific features. The feature list is a set of identifiers, defined below. If any of the features is not available in a given translation unit, that translation unit shall not import the module. When building a module for use by a compilation, submodules requiring unavailable features are ignored. The optional ``!`` indicates that a feature is incompatible with the module.
The following features are defined:
@@ -466,6 +466,11 @@ tls
*target feature*
A specific target feature (e.g., ``sse4``, ``avx``, ``neon``) is available.
+*platform/os*
+ A os/platform variant (e.g. ``freebsd``, ``win32``, ``windows``, ``linux``, ``ios``, ``macos``, ``iossimulator``) is available.
+
+*environment*
+ A environment variant (e.g. ``gnu``, ``gnueabi``, ``android``, ``msvc``) is available.
**Example:** The ``std`` module can be extended to also include C++ and C++11 headers using a *requires-declaration*:
Modified: cfe/trunk/lib/Basic/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=342499&r1=342498&r2=342499&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Module.cpp (original)
+++ cfe/trunk/lib/Basic/Module.cpp Tue Sep 18 10:11:13 2018
@@ -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
.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(),
Added: cfe/trunk/test/Modules/target-platform-features.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/target-platform-features.m?rev=342499&view=auto
==============================================================================
--- cfe/trunk/test/Modules/target-platform-features.m (added)
+++ cfe/trunk/test/Modules/target-platform-features.m Tue Sep 18 10:11:13 2018
@@ -0,0 +1,79 @@
+// Clear and create directories
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: mkdir %t/cache
+// RUN: mkdir %t/InputsA
+
+// RUN: echo "module RequiresMacOS {" >> %t/InputsA/module.map
+// RUN: echo " requires macos" >> %t/InputsA/module.map
+// RUN: echo "}" >> %t/InputsA/module.map
+// RUN: echo "module RequiresNotiOS {" >> %t/InputsA/module.map
+// RUN: echo " requires !ios" >> %t/InputsA/module.map
+// RUN: echo "}" >> %t/InputsA/module.map
+// RUN: echo "module RequiresMain {" >> %t/InputsA/module.map
+// RUN: echo " module SubRequiresNotiOS {" >> %t/InputsA/module.map
+// RUN: echo " requires !ios" >> %t/InputsA/module.map
+// RUN: echo " }" >> %t/InputsA/module.map
+// RUN: echo "}" >> %t/InputsA/module.map
+
+// RUN: %clang_cc1 -triple=x86_64-apple-macosx10.6 -DENABLE_DARWIN -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsA -verify %s
+// expected-no-diagnostics
+
+// RUN: not %clang_cc1 -triple=arm64-apple-ios -DENABLE_DARWIN -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsA %s 2> %t/notios
+// RUN: FileCheck %s -check-prefix=CHECK-IOS < %t/notios
+#ifdef ENABLE_DARWIN
+// CHECK-IOS: module 'RequiresMacOS' requires feature 'macos'
+ at import RequiresMacOS;
+// CHECK-IOS: module 'RequiresNotiOS' is incompatible with feature 'ios'
+ at import RequiresNotiOS;
+// We should never get errors for submodules that don't match
+// CHECK-IOS-NOT: module 'RequiresMain'
+ at import RequiresMain;
+#endif
+
+// RUN: mkdir %t/InputsB
+// RUN: echo "module RequiresiOSSim {" >> %t/InputsB/module.map
+// RUN: echo " requires iossimulator" >> %t/InputsB/module.map
+// RUN: echo "}" >> %t/InputsB/module.map
+// RUN: %clang_cc1 -triple=x86_64-apple-iossimulator -DENABLE_IOSSIM -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsB %s -verify
+// RUN: %clang_cc1 -triple=x86_64-apple-ios-simulator -DENABLE_IOSSIM -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsB %s -verify
+
+#ifdef ENABLE_IOSSIM
+ at import RequiresiOSSim;
+#endif
+
+// RUN: mkdir %t/InputsC
+// RUN: echo "module RequiresLinuxEABIA {" >> %t/InputsC/module.map
+// RUN: echo " requires linux, gnueabi" >> %t/InputsC/module.map
+// RUN: echo "}" >> %t/InputsC/module.map
+// RUN: echo "module RequiresLinuxEABIB {" >> %t/InputsC/module.map
+// RUN: echo " requires gnueabi" >> %t/InputsC/module.map
+// RUN: echo "}" >> %t/InputsC/module.map
+// RUN: echo "module RequiresLinuxEABIC {" >> %t/InputsC/module.map
+// RUN: echo " requires linux" >> %t/InputsC/module.map
+// RUN: echo "}" >> %t/InputsC/module.map
+// RUN: %clang_cc1 -triple=armv8r-none-linux-gnueabi -DENABLE_LINUXEABI -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsC %s -verify
+
+#ifdef ENABLE_LINUXEABI
+ at import RequiresLinuxEABIA;
+ at import RequiresLinuxEABIB;
+ at import RequiresLinuxEABIC;
+#endif
+
+// RUN: mkdir %t/InputsD
+// RUN: echo "module RequiresWinMSVCA {" >> %t/InputsD/module.map
+// RUN: echo " requires windows" >> %t/InputsD/module.map
+// RUN: echo "}" >> %t/InputsD/module.map
+// RUN: echo "module RequiresWinMSVCB {" >> %t/InputsD/module.map
+// RUN: echo " requires windows, msvc" >> %t/InputsD/module.map
+// RUN: echo "}" >> %t/InputsD/module.map
+// RUN: echo "module RequiresWinMSVCC {" >> %t/InputsD/module.map
+// RUN: echo " requires msvc" >> %t/InputsD/module.map
+// RUN: echo "}" >> %t/InputsD/module.map
+// RUN: %clang_cc1 -triple=thumbv7-unknown-windows-msvc -DENABLE_WINMSVC -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c -I%t/InputsD %s -verify
+
+#ifdef ENABLE_WINMSVC
+ at import RequiresWinMSVCA;
+ at import RequiresWinMSVCB;
+ at import RequiresWinMSVCC;
+#endif
More information about the cfe-commits
mailing list