diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.def b/clang/include/clang/Basic/DiagnosticDriverKinds.def index 778fdf3186d7..bee5cdb1dbec 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.def +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.def @@ -36,6 +36,8 @@ DIAG(err_drv_unable_to_remove_file, ERROR, "unable to remove file: %0") DIAG(err_drv_command_failure, ERROR, "unable to execute command: %0") +DIAG(err_drv_invalid_darwin_version, ERROR, + "invalid Darwin version number: %0") DIAG(warn_drv_input_file_unused, WARNING, "%0: '%1' input file unused when '%2' is present") diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 1422cfaac96b..db64b0cb3d19 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -29,6 +29,8 @@ def err_drv_unable_to_remove_file : Error< "unable to remove file: %0">; def err_drv_command_failure : Error< "unable to execute command: %0">; +def err_drv_invalid_darwin_version : Error< + "invalid Darwin version number: %0">; def warn_drv_input_file_unused : Warning< "%0: '%1' input file unused when '%2' is present">; diff --git a/clang/lib/Driver/HostInfo.cpp b/clang/lib/Driver/HostInfo.cpp index 5f2460f2098e..39a688a4f5cd 100644 --- a/clang/lib/Driver/HostInfo.cpp +++ b/clang/lib/Driver/HostInfo.cpp @@ -11,6 +11,8 @@ #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Option.h" #include "clang/Driver/Options.h" @@ -59,6 +61,37 @@ public: const char *ArchName) const; }; +/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and +/// return the grouped values as integers. Numbers which are not +/// provided are set to 0. +/// +/// \return True if the entire string was parsed (9.2), or all groups +/// were parsed (10.3.5extrastuff). +static bool GetReleaseVersion(const char *Str, unsigned &Major, + unsigned &Minor, unsigned &Micro) { + Major = Minor = Micro = 0; + if (*Str == '\0') + return true; + + char *End; + Major = (unsigned) strtol(Str, &End, 10); + if (*Str != '\0' && *End == '\0') + return true; + if (*End != '.') + return false; + + Str = End+1; + Minor = (unsigned) strtol(Str, &End, 10); + if (*Str != '\0' && *End == '\0') + return true; + if (*End != '.') + return false; + + Str = End+1; + Micro = (unsigned) strtol(Str, &End, 10); + return true; +} + DarwinHostInfo::DarwinHostInfo(const Driver &D, const char *_Arch, const char *_Platform, const char *_OS) : HostInfo(D, _Arch, _Platform, _OS) { @@ -67,7 +100,14 @@ DarwinHostInfo::DarwinHostInfo(const Driver &D, const char *_Arch, getArchName() == "ppc" || getArchName() == "ppc64") && "Unknown Darwin arch."); - // FIXME: How to deal with errors? + assert(memcmp(&getOSName()[0], "darwin", 6) == 0 && + "Unknown Darwin platform."); + const char *Release = &getOSName()[6]; + if (!GetReleaseVersion(Release, DarwinVersion[0], DarwinVersion[1], + DarwinVersion[2])) { + D.Diag(clang::diag::err_drv_invalid_darwin_version) + << Release; + } // We can only call 4.2.1 for now. GCCVersion[0] = 4;