Home | History | Annotate | Download | only in Basic
      1 //===- ObjCRuntime.cpp - Objective-C Runtime Handling -----------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the ObjCRuntime class, which represents the
     11 // target Objective-C runtime.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 #include "clang/Basic/ObjCRuntime.h"
     15 #include "llvm/Support/raw_ostream.h"
     16 
     17 using namespace clang;
     18 
     19 std::string ObjCRuntime::getAsString() const {
     20   std::string Result;
     21   {
     22     llvm::raw_string_ostream Out(Result);
     23     Out << *this;
     24   }
     25   return Result;
     26 }
     27 
     28 raw_ostream &clang::operator<<(raw_ostream &out, const ObjCRuntime &value) {
     29   switch (value.getKind()) {
     30   case ObjCRuntime::MacOSX: out << "macosx"; break;
     31   case ObjCRuntime::FragileMacOSX: out << "macosx-fragile"; break;
     32   case ObjCRuntime::iOS: out << "ios"; break;
     33   case ObjCRuntime::GNUstep: out << "gnustep"; break;
     34   case ObjCRuntime::GCC: out << "gcc"; break;
     35   case ObjCRuntime::ObjFW: out << "objfw"; break;
     36   }
     37   if (value.getVersion() > VersionTuple(0)) {
     38     out << '-' << value.getVersion();
     39   }
     40   return out;
     41 }
     42 
     43 bool ObjCRuntime::tryParse(StringRef input) {
     44   // Look for the last dash.
     45   std::size_t dash = input.rfind('-');
     46 
     47   // We permit dashes in the runtime name, and we also permit the
     48   // version to be omitted, so if we see a dash not followed by a
     49   // digit then we need to ignore it.
     50   if (dash != StringRef::npos && dash + 1 != input.size() &&
     51       (input[dash+1] < '0' || input[dash+1] > '9')) {
     52     dash = StringRef::npos;
     53   }
     54 
     55   // Everything prior to that must be a valid string name.
     56   Kind kind;
     57   StringRef runtimeName = input.substr(0, dash);
     58   Version = VersionTuple(0);
     59   if (runtimeName == "macosx") {
     60     kind = ObjCRuntime::MacOSX;
     61   } else if (runtimeName == "macosx-fragile") {
     62     kind = ObjCRuntime::FragileMacOSX;
     63   } else if (runtimeName == "ios") {
     64     kind = ObjCRuntime::iOS;
     65   } else if (runtimeName == "gnustep") {
     66     // If no version is specified then default to the most recent one that we
     67     // know about.
     68     Version = VersionTuple(1, 6);
     69     kind = ObjCRuntime::GNUstep;
     70   } else if (runtimeName == "gcc") {
     71     kind = ObjCRuntime::GCC;
     72   } else if (runtimeName == "objfw") {
     73     kind = ObjCRuntime::ObjFW;
     74     Version = VersionTuple(0, 8);
     75   } else {
     76     return true;
     77   }
     78   TheKind = kind;
     79 
     80   if (dash != StringRef::npos) {
     81     StringRef verString = input.substr(dash + 1);
     82     if (Version.tryParse(verString))
     83       return true;
     84   }
     85 
     86   if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8))
     87     Version = VersionTuple(0, 8);
     88 
     89   return false;
     90 }
     91