1260611a32535c851237926bfcf78869b13c07d5bJohn McCall//===- ObjCRuntime.cpp - Objective-C Runtime Handling -----------*- C++ -*-===//
2260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
3260611a32535c851237926bfcf78869b13c07d5bJohn McCall//                     The LLVM Compiler Infrastructure
4260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
5260611a32535c851237926bfcf78869b13c07d5bJohn McCall// This file is distributed under the University of Illinois Open Source
6260611a32535c851237926bfcf78869b13c07d5bJohn McCall// License. See LICENSE.TXT for details.
7260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
8260611a32535c851237926bfcf78869b13c07d5bJohn McCall//===----------------------------------------------------------------------===//
9260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
10260611a32535c851237926bfcf78869b13c07d5bJohn McCall// This file implements the ObjCRuntime class, which represents the
11260611a32535c851237926bfcf78869b13c07d5bJohn McCall// target Objective-C runtime.
12260611a32535c851237926bfcf78869b13c07d5bJohn McCall//
13260611a32535c851237926bfcf78869b13c07d5bJohn McCall//===----------------------------------------------------------------------===//
14260611a32535c851237926bfcf78869b13c07d5bJohn McCall#include "clang/Basic/ObjCRuntime.h"
15260611a32535c851237926bfcf78869b13c07d5bJohn McCall#include "llvm/Support/raw_ostream.h"
16260611a32535c851237926bfcf78869b13c07d5bJohn McCall
17260611a32535c851237926bfcf78869b13c07d5bJohn McCallusing namespace clang;
18260611a32535c851237926bfcf78869b13c07d5bJohn McCall
19260611a32535c851237926bfcf78869b13c07d5bJohn McCallstd::string ObjCRuntime::getAsString() const {
20260611a32535c851237926bfcf78869b13c07d5bJohn McCall  std::string Result;
21260611a32535c851237926bfcf78869b13c07d5bJohn McCall  {
22260611a32535c851237926bfcf78869b13c07d5bJohn McCall    llvm::raw_string_ostream Out(Result);
23260611a32535c851237926bfcf78869b13c07d5bJohn McCall    Out << *this;
24260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
25260611a32535c851237926bfcf78869b13c07d5bJohn McCall  return Result;
26260611a32535c851237926bfcf78869b13c07d5bJohn McCall}
27260611a32535c851237926bfcf78869b13c07d5bJohn McCall
28260611a32535c851237926bfcf78869b13c07d5bJohn McCallraw_ostream &clang::operator<<(raw_ostream &out, const ObjCRuntime &value) {
29260611a32535c851237926bfcf78869b13c07d5bJohn McCall  switch (value.getKind()) {
30260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::MacOSX: out << "macosx"; break;
31260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::FragileMacOSX: out << "macosx-fragile"; break;
32260611a32535c851237926bfcf78869b13c07d5bJohn McCall  case ObjCRuntime::iOS: out << "ios"; break;
3311d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GNUstep: out << "gnustep"; break;
3411d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  case ObjCRuntime::GCC: out << "gcc"; break;
35f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall  case ObjCRuntime::ObjFW: out << "objfw"; break;
36260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
37260611a32535c851237926bfcf78869b13c07d5bJohn McCall  if (value.getVersion() > VersionTuple(0)) {
38260611a32535c851237926bfcf78869b13c07d5bJohn McCall    out << '-' << value.getVersion();
39260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
40260611a32535c851237926bfcf78869b13c07d5bJohn McCall  return out;
41260611a32535c851237926bfcf78869b13c07d5bJohn McCall}
42260611a32535c851237926bfcf78869b13c07d5bJohn McCall
43260611a32535c851237926bfcf78869b13c07d5bJohn McCallbool ObjCRuntime::tryParse(StringRef input) {
44260611a32535c851237926bfcf78869b13c07d5bJohn McCall  // Look for the last dash.
45260611a32535c851237926bfcf78869b13c07d5bJohn McCall  std::size_t dash = input.rfind('-');
46260611a32535c851237926bfcf78869b13c07d5bJohn McCall
470b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall  // We permit dashes in the runtime name, and we also permit the
480b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall  // version to be omitted, so if we see a dash not followed by a
490b92fcb1353d2d8b31b6c485e6caa14568aca43bJohn McCall  // digit then we need to ignore it.
50260611a32535c851237926bfcf78869b13c07d5bJohn McCall  if (dash != StringRef::npos && dash + 1 != input.size() &&
51260611a32535c851237926bfcf78869b13c07d5bJohn McCall      (input[dash+1] < '0' || input[dash+1] > '9')) {
52260611a32535c851237926bfcf78869b13c07d5bJohn McCall    dash = StringRef::npos;
53260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
54260611a32535c851237926bfcf78869b13c07d5bJohn McCall
55260611a32535c851237926bfcf78869b13c07d5bJohn McCall  // Everything prior to that must be a valid string name.
56260611a32535c851237926bfcf78869b13c07d5bJohn McCall  Kind kind;
57260611a32535c851237926bfcf78869b13c07d5bJohn McCall  StringRef runtimeName = input.substr(0, dash);
58a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall  Version = VersionTuple(0);
59260611a32535c851237926bfcf78869b13c07d5bJohn McCall  if (runtimeName == "macosx") {
60260611a32535c851237926bfcf78869b13c07d5bJohn McCall    kind = ObjCRuntime::MacOSX;
61260611a32535c851237926bfcf78869b13c07d5bJohn McCall  } else if (runtimeName == "macosx-fragile") {
62260611a32535c851237926bfcf78869b13c07d5bJohn McCall    kind = ObjCRuntime::FragileMacOSX;
63260611a32535c851237926bfcf78869b13c07d5bJohn McCall  } else if (runtimeName == "ios") {
64260611a32535c851237926bfcf78869b13c07d5bJohn McCall    kind = ObjCRuntime::iOS;
6511d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  } else if (runtimeName == "gnustep") {
66a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall    // If no version is specified then default to the most recent one that we
67a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall    // know about.
68a422cd0ed4da8cb5a172498f29bb02065707c6ceDavid Chisnall    Version = VersionTuple(1, 6);
6911d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    kind = ObjCRuntime::GNUstep;
7011d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall  } else if (runtimeName == "gcc") {
7111d3f4cc27e6b923fc32481dc1bb5ec46c7d1f4bDavid Chisnall    kind = ObjCRuntime::GCC;
72f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall  } else if (runtimeName == "objfw") {
73f7226fbe677a9c7578fa0613491ed15c6dc6a5e1John McCall    kind = ObjCRuntime::ObjFW;
74260611a32535c851237926bfcf78869b13c07d5bJohn McCall  } else {
75260611a32535c851237926bfcf78869b13c07d5bJohn McCall    return true;
76260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
77260611a32535c851237926bfcf78869b13c07d5bJohn McCall  TheKind = kind;
78260611a32535c851237926bfcf78869b13c07d5bJohn McCall
79260611a32535c851237926bfcf78869b13c07d5bJohn McCall  if (dash != StringRef::npos) {
80260611a32535c851237926bfcf78869b13c07d5bJohn McCall    StringRef verString = input.substr(dash + 1);
81260611a32535c851237926bfcf78869b13c07d5bJohn McCall    if (Version.tryParse(verString))
82260611a32535c851237926bfcf78869b13c07d5bJohn McCall      return true;
83260611a32535c851237926bfcf78869b13c07d5bJohn McCall  }
84260611a32535c851237926bfcf78869b13c07d5bJohn McCall
85260611a32535c851237926bfcf78869b13c07d5bJohn McCall  return false;
86260611a32535c851237926bfcf78869b13c07d5bJohn McCall}
87