diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-04-10 19:52:24 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-04-10 19:52:24 +0000 |
commit | 8d33cd77dc1086f70f1699ea012702d0df7eba1a (patch) | |
tree | 976310afa012a053d2c2bef63385e2d8e4157b6b | |
parent | 4d8076a0e437d9fd902088cc221ae438714adfae (diff) |
Support -miphoneos-version-min in clang-cc.
- Patch by Shantonu Sen (with a minor tweak to split out
getDarwin{OSX,IPhoneOS}Defines)!
- <rdar://problem/6776277> Need clang-cc/ccc-analyzer support for
-miphoneos-version-min
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68815 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Basic/Targets.cpp | 104 | ||||
-rw-r--r-- | tools/clang-cc/clang-cc.cpp | 62 | ||||
-rwxr-xr-x | utils/ccc-analyzer | 3 |
3 files changed, 141 insertions, 28 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 8ffeb61132..1860075696 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -109,11 +109,11 @@ static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) { } /// getDarwinNumber - Parse the 'darwin number' out of the specific targe -/// triple. For example, if we have darwin8.5 return 8,5,4. If any entry is +/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is /// not defined, return 0's. Return true if we have -darwin in the string or /// false otherwise. -static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) { - Maj = Min = 0; +static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min, unsigned &Revision) { + Maj = Min = Revision = 0; const char *Darwin = strstr(Triple, "-darwin"); if (Darwin == 0) return false; @@ -126,20 +126,47 @@ static bool getDarwinNumber(const char *Triple, unsigned &Maj, unsigned &Min) { // Handle "darwin11". if (Maj == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') { - Maj = 10+Darwin[0]-'0'; + Maj = Maj*10 + (Darwin[0] - '0'); ++Darwin; } // Handle minor version: 10.4.9 -> darwin8.9 -> "1049" - if (Darwin[0] == '.' && Darwin[1] >= '0' && Darwin[1] <= '9' && - Darwin[2] == '\0') - Min = Darwin[1]-'0'; + if (Darwin[0] != '.') + return true; + + ++Darwin; + if (Darwin[0] < '0' || Darwin[0] > '9') + return true; + + Min = Darwin[0]-'0'; + ++Darwin; + + // Handle 10.4.11 -> darwin8.11 + if (Min == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') { + Min = Min*10 + (Darwin[0] - '0'); + ++Darwin; + } + + // Handle revision darwin8.9.1 + if (Darwin[0] != '.') + return true; + + ++Darwin; + if (Darwin[0] < '0' || Darwin[0] > '9') + return true; + + Revision = Darwin[0]-'0'; + ++Darwin; + + if (Revision == 1 && Darwin[0] >= '0' && Darwin[0] <= '9') { + Revision = Revision*10 + (Darwin[0] - '0'); + ++Darwin; + } return true; } -static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts, - const char *Triple) { +static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts) { Define(Defs, "__APPLE__"); Define(Defs, "__MACH__"); Define(Defs, "OBJC_NEW_PROPERTIES"); @@ -152,19 +179,42 @@ static void getDarwinDefines(std::vector<char> &Defs, const LangOptions &Opts, Define(Defs, "__strong", ""); else Define(Defs, "__strong", "__attribute__((objc_gc(strong)))"); - +} + +static void getDarwinOSXDefines(std::vector<char> &Defs, const char *Triple) { // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5. - unsigned Maj, Min; - if (getDarwinNumber(Triple, Maj, Min)) { - char DarwinStr[] = "1000"; + unsigned Maj, Min, Rev; + if (getDarwinNumber(Triple, Maj, Min, Rev)) { + char MacOSXStr[] = "1000"; if (Maj >= 4 && Maj <= 13) { // 10.0-10.9 // darwin7 -> 1030, darwin8 -> 1040, darwin9 -> 1050, etc. - DarwinStr[2] = '0' + Maj-4; + MacOSXStr[2] = '0' + Maj-4; } - + // Handle minor version: 10.4.9 -> darwin8.9 -> "1049" - DarwinStr[3] = Min+'0'; - Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", DarwinStr); + // Cap 10.4.11 -> darwin8.11 -> "1049" + MacOSXStr[3] = std::min(Min, 9U)+'0'; + Define(Defs, "__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", MacOSXStr); + } +} + +static void getDarwinIPhoneOSDefines(std::vector<char> &Defs, + const char *Triple) { + // Figure out which "darwin number" the target triple is. "darwin9" -> 10.5. + unsigned Maj, Min, Rev; + if (getDarwinNumber(Triple, Maj, Min, Rev)) { + // When targetting iPhone OS, interpret the minor version and + // revision as the iPhone OS version + char iPhoneOSStr[] = "10000"; + if (Min >= 2 && Min <= 9) { // iPhone OS 2.0-9.0 + // darwin9.2.0 -> 20000, darwin9.3.0 -> 30000, etc. + iPhoneOSStr[0] = '0' + Min; + } + + // Handle minor version: 2.2 -> darwin9.2.2 -> 20200 + iPhoneOSStr[2] = std::min(Rev, 9U)+'0'; + Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", + iPhoneOSStr); } } @@ -173,8 +223,8 @@ static void GetDarwinLanguageOptions(LangOptions &Opts, const char *Triple) { Opts.NeXTRuntime = true; - unsigned Maj, Min; - if (!getDarwinNumber(Triple, Maj, Min)) + unsigned Maj, Min, Rev; + if (!getDarwinNumber(Triple, Maj, Min, Rev)) return; // Blocks default to on for 10.6 (darwin10) and beyond. @@ -383,7 +433,8 @@ public: virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { PPC32TargetInfo::getTargetDefines(Opts, Defines); - getDarwinDefines(Defines, Opts, getTargetTriple()); + getDarwinDefines(Defines, Opts); + getDarwinOSXDefines(Defines, getTargetTriple()); } /// getDefaultLangOptions - Allow the target to specify default settings for @@ -402,7 +453,8 @@ public: virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { PPC64TargetInfo::getTargetDefines(Opts, Defines); - getDarwinDefines(Defines, Opts, getTargetTriple()); + getDarwinDefines(Defines, Opts); + getDarwinOSXDefines(Defines, getTargetTriple()); } /// getDefaultLangOptions - Allow the target to specify default settings for @@ -682,7 +734,8 @@ public: virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { X86_32TargetInfo::getTargetDefines(Opts, Defines); - getDarwinDefines(Defines, Opts, getTargetTriple()); + getDarwinDefines(Defines, Opts); + getDarwinOSXDefines(Defines, getTargetTriple()); } /// getDefaultLangOptions - Allow the target to specify default settings for @@ -843,7 +896,8 @@ public: virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { X86_64TargetInfo::getTargetDefines(Opts, Defines); - getDarwinDefines(Defines, Opts, getTargetTriple()); + getDarwinDefines(Defines, Opts); + getDarwinOSXDefines(Defines, getTargetTriple()); } /// getDefaultLangOptions - Allow the target to specify default settings for @@ -903,7 +957,6 @@ public: Define(Defs, "__SOFTFP__"); } Define(Defs, "__ARMEL__"); - Define(Defs, "__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", "20000"); } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { @@ -959,7 +1012,8 @@ public: virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { ARMTargetInfo::getTargetDefines(Opts, Defines); - getDarwinDefines(Defines, Opts, getTargetTriple()); + getDarwinDefines(Defines, Opts); + getDarwinIPhoneOSDefines(Defines, getTargetTriple()); } }; } // end anonymous namespace. diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index 8e29dded84..0e38bc7aea 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -857,7 +857,7 @@ Arch("arch", llvm::cl::desc("Specify target architecture (e.g. i686)")); static llvm::cl::opt<std::string> MacOSVersionMin("mmacosx-version-min", - llvm::cl::desc("Specify target Mac OS/X version (e.g. 10.5)")); + llvm::cl::desc("Specify target Mac OS X version (e.g. 10.5)")); // If -mmacosx-version-min=10.3.9 is specified, change the triple from being // something like powerpc-apple-darwin9 to powerpc-apple-darwin7 @@ -867,7 +867,7 @@ static void HandleMacOSVersionMin(std::string &Triple) { std::string::size_type DarwinDashIdx = Triple.find("-darwin"); if (DarwinDashIdx == std::string::npos) { fprintf(stderr, - "-mmacosx-version-min only valid for darwin (Mac OS/X) targets\n"); + "-mmacosx-version-min only valid for darwin (Mac OS X) targets\n"); exit(1); } unsigned DarwinNumIdx = DarwinDashIdx + strlen("-darwin"); @@ -910,6 +910,62 @@ static void HandleMacOSVersionMin(std::string &Triple) { } } +static llvm::cl::opt<std::string> +IPhoneOSVersionMin("miphoneos-version-min", + llvm::cl::desc("Specify target iPhone OS version (e.g. 2.0)")); + +// If -miphoneos-version-min=2.2 is specified, change the triple from being +// something like armv6-apple-darwin10 to armv6-apple-darwin9.2.2. We use +// 9 as the default major Darwin number, and encode the iPhone OS version +// number in the minor version and revision. + +// FIXME: We should have the driver do this instead. +static void HandleIPhoneOSVersionMin(std::string &Triple) { + std::string::size_type DarwinDashIdx = Triple.find("-darwin"); + if (DarwinDashIdx == std::string::npos) { + fprintf(stderr, + "-miphoneos-version-min only valid for darwin (Mac OS X) targets\n"); + exit(1); + } + unsigned DarwinNumIdx = DarwinDashIdx + strlen("-darwin"); + + // Remove the number. + Triple.resize(DarwinNumIdx); + + // Validate that IPhoneOSVersionMin is a 'version number', starting with [2-9].[0-9] + bool IPhoneOSVersionMinIsInvalid = false; + int VersionNum = 0; + if (IPhoneOSVersionMin.size() < 3 || + !isdigit(IPhoneOSVersionMin[0])) { + IPhoneOSVersionMinIsInvalid = true; + } else { + const char *Start = IPhoneOSVersionMin.c_str(); + char *End = 0; + VersionNum = (int)strtol(Start, &End, 10); + + // The version number must be in the range 0-9. + IPhoneOSVersionMinIsInvalid = (unsigned)VersionNum > 9; + + // Turn IPhoneOSVersionMin into a darwin number: e.g. 2.0 is 2 -> 9.2. + Triple += "9." + llvm::itostr(VersionNum); + + if (End[0] == '.' && isdigit(End[1]) && End[2] == '\0') { // 2.2 is ok. + // Add the period piece (.2) to the end of the triple. This gives us + // something like ...-darwin9.2.2 + Triple += End; + } else if (End[0] != '\0') { // "2.2" is ok. 2x is not. + IPhoneOSVersionMinIsInvalid = true; + } + } + + if (IPhoneOSVersionMinIsInvalid) { + fprintf(stderr, + "-miphoneos-version-min=%s is invalid, expected something like '2.0'.\n", + IPhoneOSVersionMin.c_str()); + exit(1); + } +} + /// CreateTargetTriple - Process the various options that affect the target /// triple and build a final aggregate triple that we are compiling for. static std::string CreateTargetTriple() { @@ -947,6 +1003,8 @@ static std::string CreateTargetTriple() { // something like powerpc-apple-darwin9 to powerpc-apple-darwin7 if (!MacOSVersionMin.empty()) HandleMacOSVersionMin(Triple); + else if (!IPhoneOSVersionMin.empty()) + HandleIPhoneOSVersionMin(Triple);; return Triple; } diff --git a/utils/ccc-analyzer b/utils/ccc-analyzer index 09f7824e7b..4e3f6dd354 100755 --- a/utils/ccc-analyzer +++ b/utils/ccc-analyzer @@ -257,7 +257,8 @@ my %CompilerLinkerOptionMap = ( '-arch' => 1, '-v' => 0, '-fpascal-strings' => 0, - '-mmacosx-version-min' => 0 # This is really a 1 argument, but always has '=' + '-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '=' + '-miphoneos-version-min' => 0 # This is really a 1 argument, but always has '=' ); my %IgnoredOptionMap = ( |