[cfe-commits] r143871 - in /cfe/trunk/lib/Driver: ToolChains.cpp ToolChains.h

Chandler Carruth chandlerc at gmail.com
Sun Nov 6 01:39:46 PST 2011


Author: chandlerc
Date: Sun Nov  6 03:39:46 2011
New Revision: 143871

URL: http://llvm.org/viewvc/llvm-project?rev=143871&view=rev
Log:
Lift the GCCVersion type into the header file and start persisting it in
the detected GCC installation. This allows us to expose another aspect
of what we detected: the GCC version. This will be used shortly.

Modified:
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Driver/ToolChains.h

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=143871&r1=143870&r2=143871&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Sun Nov  6 03:39:46 2011
@@ -1519,87 +1519,62 @@
   return UnknownDistro;
 }
 
-/// \brief Struct to store and manipulate GCC versions.
+/// \brief Parse a GCCVersion object out of a string of text.
 ///
-/// We rely on assumptions about the form and structure of GCC version
-/// numbers: they consist of at most three '.'-separated components, and each
-/// component is a non-negative integer except for the last component. For the
-/// last component we are very flexible in order to tolerate release candidates
-/// or 'x' wildcards.
-///
-/// Note that the ordering established among GCCVersions is based on the
-/// preferred version string to use. For example we prefer versions without
-/// a hard-coded patch number to those with a hard coded patch number.
-///
-/// Currently this doesn't provide any logic for textual suffixes to patches in
-/// the way that (for example) Debian's version format does. If that ever
-/// becomes necessary, it can be added.
-struct Linux::GCCVersion {
-  /// \brief The unparsed text of the version.
-  StringRef Text;
-
-  /// \brief The parsed major, minor, and patch numbers.
-  int Major, Minor, Patch;
-
-  /// \brief Any textual suffix on the patch number.
-  StringRef PatchSuffix;
-
-  static GCCVersion Parse(StringRef VersionText) {
-    const GCCVersion BadVersion = { VersionText, -1, -1, -1, "" };
-    std::pair<StringRef, StringRef> First = VersionText.split('.');
-    std::pair<StringRef, StringRef> Second = First.second.split('.');
-
-    GCCVersion GoodVersion = { VersionText, -1, -1, -1, "" };
-    if (First.first.getAsInteger(10, GoodVersion.Major) ||
-        GoodVersion.Major < 0)
-      return BadVersion;
-    if (Second.first.getAsInteger(10, GoodVersion.Minor) ||
-        GoodVersion.Minor < 0)
-      return BadVersion;
-
-    // First look for a number prefix and parse that if present. Otherwise just
-    // stash the entire patch string in the suffix, and leave the number
-    // unspecified. This covers versions strings such as:
-    //   4.4
-    //   4.4.0
-    //   4.4.x
-    //   4.4.2-rc4
-    //   4.4.x-patched
-    // And retains any patch number it finds.
-    StringRef PatchText = GoodVersion.PatchSuffix = Second.second;
-    if (!PatchText.empty()) {
-      if (unsigned EndNumber = PatchText.find_first_not_of("0123456789")) {
-        // Try to parse the number and any suffix.
-        if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
-            GoodVersion.Patch < 0)
-          return BadVersion;
-        GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
-      }
+/// This is the primary means of forming GCCVersion objects.
+/*static*/ Linux::GCCVersion Linux::GCCVersion::Parse(StringRef VersionText) {
+  const GCCVersion BadVersion = { VersionText, -1, -1, -1, "" };
+  std::pair<StringRef, StringRef> First = VersionText.split('.');
+  std::pair<StringRef, StringRef> Second = First.second.split('.');
+
+  GCCVersion GoodVersion = { VersionText, -1, -1, -1, "" };
+  if (First.first.getAsInteger(10, GoodVersion.Major) ||
+      GoodVersion.Major < 0)
+    return BadVersion;
+  if (Second.first.getAsInteger(10, GoodVersion.Minor) ||
+      GoodVersion.Minor < 0)
+    return BadVersion;
+
+  // First look for a number prefix and parse that if present. Otherwise just
+  // stash the entire patch string in the suffix, and leave the number
+  // unspecified. This covers versions strings such as:
+  //   4.4
+  //   4.4.0
+  //   4.4.x
+  //   4.4.2-rc4
+  //   4.4.x-patched
+  // And retains any patch number it finds.
+  StringRef PatchText = GoodVersion.PatchSuffix = Second.second;
+  if (!PatchText.empty()) {
+    if (unsigned EndNumber = PatchText.find_first_not_of("0123456789")) {
+      // Try to parse the number and any suffix.
+      if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
+          GoodVersion.Patch < 0)
+        return BadVersion;
+      GoodVersion.PatchSuffix = PatchText.substr(EndNumber);
     }
-
-    return GoodVersion;
   }
 
-  bool operator<(const GCCVersion &RHS) const {
-    if (Major < RHS.Major) return true; if (Major > RHS.Major) return false;
-    if (Minor < RHS.Minor) return true; if (Minor > RHS.Minor) return false;
-
-    // Note that we rank versions with *no* patch specified is better than ones
-    // hard-coding a patch version. Thus if the RHS has no patch, it always
-    // wins, and the LHS only wins if it has no patch and the RHS does have
-    // a patch.
-    if (RHS.Patch == -1) return true;   if (Patch == -1) return false;
-    if (Patch < RHS.Patch) return true; if (Patch > RHS.Patch) return false;
-
-    // Finally, between completely tied version numbers, the version with the
-    // suffix loses as we prefer full releases.
-    if (RHS.PatchSuffix.empty()) return true;
-    return false;
-  }
-  bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
-  bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
-  bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
-};
+  return GoodVersion;
+}
+
+/// \brief Less-than for GCCVersion, implementing a Strict Weak Ordering.
+bool Linux::GCCVersion::operator<(const GCCVersion &RHS) const {
+  if (Major < RHS.Major) return true; if (Major > RHS.Major) return false;
+  if (Minor < RHS.Minor) return true; if (Minor > RHS.Minor) return false;
+
+  // Note that we rank versions with *no* patch specified is better than ones
+  // hard-coding a patch version. Thus if the RHS has no patch, it always
+  // wins, and the LHS only wins if it has no patch and the RHS does have
+  // a patch.
+  if (RHS.Patch == -1) return true;   if (Patch == -1) return false;
+  if (Patch < RHS.Patch) return true; if (Patch > RHS.Patch) return false;
+
+  // Finally, between completely tied version numbers, the version with the
+  // suffix loses as we prefer full releases.
+  if (RHS.PatchSuffix.empty()) return true;
+  return false;
+}
 
 /// \brief Construct a GCCInstallationDetector from the driver.
 ///
@@ -1656,7 +1631,7 @@
 
   // Loop over the various components which exist and select the best GCC
   // installation available. GCC installs are ranked by version number.
-  GCCVersion BestVersion = GCCVersion::Parse("0.0.0");
+  Version = GCCVersion::Parse("0.0.0");
   for (unsigned i = 0, ie = Prefixes.size(); i < ie; ++i) {
     if (!llvm::sys::fs::exists(Prefixes[i]))
       continue;
@@ -1665,7 +1640,7 @@
       if (!llvm::sys::fs::exists(LibDir))
         continue;
       for (unsigned k = 0, ke = CandidateTriples.size(); k < ke; ++k)
-        ScanLibDirForGCCTriple(LibDir, CandidateTriples[k], BestVersion);
+        ScanLibDirForGCCTriple(LibDir, CandidateTriples[k]);
     }
   }
 }
@@ -1730,8 +1705,7 @@
 }
 
 void Linux::GCCInstallationDetector::ScanLibDirForGCCTriple(
-    const std::string &LibDir, StringRef CandidateTriple,
-    GCCVersion &BestVersion) {
+    const std::string &LibDir, StringRef CandidateTriple) {
   // There are various different suffixes involving the triple we
   // check for. We also record what is necessary to walk from each back
   // up to the lib directory.
@@ -1763,12 +1737,12 @@
       static const GCCVersion MinVersion = { "4.1.1", 4, 1, 1, "" };
       if (CandidateVersion < MinVersion)
         continue;
-      if (CandidateVersion <= BestVersion)
+      if (CandidateVersion <= Version)
         continue;
       if (!llvm::sys::fs::exists(LI->path() + "/crtbegin.o"))
         continue;
 
-      BestVersion = CandidateVersion;
+      Version = CandidateVersion;
       GccTriple = CandidateTriple.str();
       // FIXME: We hack together the directory name here instead of
       // using LI to ensure stable path separators across Windows and

Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=143871&r1=143870&r2=143871&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Sun Nov  6 03:39:46 2011
@@ -372,7 +372,38 @@
 };
 
 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
-  struct GCCVersion;
+  /// \brief Struct to store and manipulate GCC versions.
+  ///
+  /// We rely on assumptions about the form and structure of GCC version
+  /// numbers: they consist of at most three '.'-separated components, and each
+  /// component is a non-negative integer except for the last component. For
+  /// the last component we are very flexible in order to tolerate release
+  /// candidates or 'x' wildcards.
+  ///
+  /// Note that the ordering established among GCCVersions is based on the
+  /// preferred version string to use. For example we prefer versions without
+  /// a hard-coded patch number to those with a hard coded patch number.
+  ///
+  /// Currently this doesn't provide any logic for textual suffixes to patches
+  /// in the way that (for example) Debian's version format does. If that ever
+  /// becomes necessary, it can be added.
+  struct GCCVersion {
+    /// \brief The unparsed text of the version.
+    StringRef Text;
+
+    /// \brief The parsed major, minor, and patch numbers.
+    int Major, Minor, Patch;
+
+    /// \brief Any textual suffix on the patch number.
+    StringRef PatchSuffix;
+
+    static GCCVersion Parse(StringRef VersionText);
+    bool operator<(const GCCVersion &RHS) const;
+    bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
+    bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
+    bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
+  };
+
 
   /// \brief This is a class to find a viable GCC installation for Clang to
   /// use.
@@ -389,6 +420,8 @@
     std::string GccInstallPath;
     std::string GccParentLibPath;
 
+    GCCVersion Version;
+
   public:
     GCCInstallationDetector(const Driver &D);
 
@@ -404,14 +437,16 @@
     /// \brief Get the detected GCC parent lib path.
     StringRef getParentLibPath() const { return GccParentLibPath; }
 
+    /// \brief Get the detected GCC version string.
+    StringRef getVersion() const { return Version.Text; }
+
   private:
     static void CollectLibDirsAndTriples(llvm::Triple::ArchType HostArch,
                                          SmallVectorImpl<StringRef> &LibDirs,
                                          SmallVectorImpl<StringRef> &Triples);
 
     void ScanLibDirForGCCTriple(const std::string &LibDir,
-                                StringRef CandidateTriple,
-                                GCCVersion &BestVersion);
+                                StringRef CandidateTriple);
   };
 
   GCCInstallationDetector GCCInstallation;





More information about the cfe-commits mailing list