1219019Sgabor//===- ObjCRuntime.cpp - Objective-C Runtime Handling ---------------------===// 2219019Sgabor// 3219019Sgabor// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4219019Sgabor// See https://llvm.org/LICENSE.txt for license information. 5219019Sgabor// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6219019Sgabor// 7219019Sgabor//===----------------------------------------------------------------------===// 8219019Sgabor// 9219019Sgabor// This file implements the ObjCRuntime class, which represents the 10219019Sgabor// target Objective-C runtime. 11219019Sgabor// 12219019Sgabor//===----------------------------------------------------------------------===// 13219019Sgabor 14219019Sgabor#include "clang/Basic/ObjCRuntime.h" 15219019Sgabor#include "llvm/ADT/StringRef.h" 16219019Sgabor#include "llvm/Support/VersionTuple.h" 17219019Sgabor#include "llvm/Support/raw_ostream.h" 18219019Sgabor#include <cstddef> 19219019Sgabor#include <string> 20219019Sgabor 21219019Sgaborusing namespace clang; 22219019Sgabor 23219019Sgaborstd::string ObjCRuntime::getAsString() const { 24219019Sgabor std::string Result; 25219019Sgabor { 26219019Sgabor llvm::raw_string_ostream Out(Result); 27219019Sgabor Out << *this; 28219019Sgabor } 29219019Sgabor return Result; 30219019Sgabor} 31219019Sgabor 32219019Sgaborraw_ostream &clang::operator<<(raw_ostream &out, const ObjCRuntime &value) { 33219019Sgabor switch (value.getKind()) { 34219019Sgabor case ObjCRuntime::MacOSX: out << "macosx"; break; 35219019Sgabor case ObjCRuntime::FragileMacOSX: out << "macosx-fragile"; break; 36219019Sgabor case ObjCRuntime::iOS: out << "ios"; break; 37219019Sgabor case ObjCRuntime::WatchOS: out << "watchos"; break; 38219019Sgabor case ObjCRuntime::GNUstep: out << "gnustep"; break; 39219019Sgabor case ObjCRuntime::GCC: out << "gcc"; break; 40219019Sgabor case ObjCRuntime::ObjFW: out << "objfw"; break; 41219019Sgabor } 42219019Sgabor if (value.getVersion() > VersionTuple(0)) { 43219019Sgabor out << '-' << value.getVersion(); 44219019Sgabor } 45219019Sgabor return out; 46219019Sgabor} 47219019Sgabor 48219019Sgaborbool ObjCRuntime::tryParse(StringRef input) { 49219019Sgabor // Look for the last dash. 50219019Sgabor std::size_t dash = input.rfind('-'); 51219019Sgabor 52219019Sgabor // We permit dashes in the runtime name, and we also permit the 53219019Sgabor // version to be omitted, so if we see a dash not followed by a 54219019Sgabor // digit then we need to ignore it. 55219019Sgabor if (dash != StringRef::npos && dash + 1 != input.size() && 56219019Sgabor (input[dash+1] < '0' || input[dash+1] > '9')) { 57219019Sgabor dash = StringRef::npos; 58219019Sgabor } 59219019Sgabor 60219019Sgabor // Everything prior to that must be a valid string name. 61219019Sgabor Kind kind; 62219019Sgabor StringRef runtimeName = input.substr(0, dash); 63219019Sgabor Version = VersionTuple(0); 64219019Sgabor if (runtimeName == "macosx") { 65219019Sgabor kind = ObjCRuntime::MacOSX; 66219019Sgabor } else if (runtimeName == "macosx-fragile") { 67219019Sgabor kind = ObjCRuntime::FragileMacOSX; 68219019Sgabor } else if (runtimeName == "ios") { 69219019Sgabor kind = ObjCRuntime::iOS; 70219019Sgabor } else if (runtimeName == "watchos") { 71219019Sgabor kind = ObjCRuntime::WatchOS; 72219019Sgabor } else if (runtimeName == "gnustep") { 73219019Sgabor // If no version is specified then default to the most recent one that we 74219019Sgabor // know about. 75219019Sgabor Version = VersionTuple(1, 6); 76219019Sgabor kind = ObjCRuntime::GNUstep; 77219019Sgabor } else if (runtimeName == "gcc") { 78219019Sgabor kind = ObjCRuntime::GCC; 79219019Sgabor } else if (runtimeName == "objfw") { 80219019Sgabor kind = ObjCRuntime::ObjFW; 81219019Sgabor Version = VersionTuple(0, 8); 82219019Sgabor } else { 83219019Sgabor return true; 84219019Sgabor } 85219019Sgabor TheKind = kind; 86219019Sgabor 87219019Sgabor if (dash != StringRef::npos) { 88219019Sgabor StringRef verString = input.substr(dash + 1); 89219019Sgabor if (Version.tryParse(verString)) 90219019Sgabor return true; 91219019Sgabor } 92219019Sgabor 93219019Sgabor if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8)) 94219019Sgabor Version = VersionTuple(0, 8); 95219019Sgabor 96219019Sgabor return false; 97219019Sgabor} 98219019Sgabor