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::WatchOS: out << "watchos"; break;
     34   case ObjCRuntime::GNUstep: out << "gnustep"; break;
     35   case ObjCRuntime::GCC: out << "gcc"; break;
     36   case ObjCRuntime::ObjFW: out << "objfw"; break;
     37   }
     38   if (value.getVersion() > VersionTuple(0)) {
     39     out << '-' << value.getVersion();
     40   }
     41   return out;
     42 }
     43 
     44 bool ObjCRuntime::tryParse(StringRef input) {
     45   // Look for the last dash.
     46   std::size_t dash = input.rfind('-');
     47 
     48   // We permit dashes in the runtime name, and we also permit the
     49   // version to be omitted, so if we see a dash not followed by a
     50   // digit then we need to ignore it.
     51   if (dash != StringRef::npos && dash + 1 != input.size() &&
     52       (input[dash+1] < '0' || input[dash+1] > '9')) {
     53     dash = StringRef::npos;
     54   }
     55 
     56   // Everything prior to that must be a valid string name.
     57   Kind kind;
     58   StringRef runtimeName = input.substr(0, dash);
     59   Version = VersionTuple(0);
     60   if (runtimeName == "macosx") {
     61     kind = ObjCRuntime::MacOSX;
     62   } else if (runtimeName == "macosx-fragile") {
     63     kind = ObjCRuntime::FragileMacOSX;
     64   } else if (runtimeName == "ios") {
     65     kind = ObjCRuntime::iOS;
     66   } else if (runtimeName == "watchos") {
     67     kind = ObjCRuntime::WatchOS;
     68   } else if (runtimeName == "gnustep") {
     69     // If no version is specified then default to the most recent one that we
     70     // know about.
     71     Version = VersionTuple(1, 6);
     72     kind = ObjCRuntime::GNUstep;
     73   } else if (runtimeName == "gcc") {
     74     kind = ObjCRuntime::GCC;
     75   } else if (runtimeName == "objfw") {
     76     kind = ObjCRuntime::ObjFW;
     77     Version = VersionTuple(0, 8);
     78   } else {
     79     return true;
     80   }
     81   TheKind = kind;
     82 
     83   if (dash != StringRef::npos) {
     84     StringRef verString = input.substr(dash + 1);
     85     if (Version.tryParse(verString))
     86       return true;
     87   }
     88 
     89   if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8))
     90     Version = VersionTuple(0, 8);
     91 
     92   return false;
     93 }
     94