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