blob: cfc437409b5d82f823f0e1f1889bfb3705cb3b33 [file] [log] [blame]
Eugene Zelenko5a520112018-03-28 22:09:09 +00001//===- ObjCRuntime.cpp - Objective-C Runtime Handling ---------------------===//
John McCall5fb5df92012-06-20 06:18:46 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
John McCall5fb5df92012-06-20 06:18:46 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the ObjCRuntime class, which represents the
10// target Objective-C runtime.
11//
12//===----------------------------------------------------------------------===//
Eugene Zelenko5a520112018-03-28 22:09:09 +000013
John McCall5fb5df92012-06-20 06:18:46 +000014#include "clang/Basic/ObjCRuntime.h"
Eugene Zelenko5a520112018-03-28 22:09:09 +000015#include "llvm/ADT/StringRef.h"
Pavel Labathd8c62902018-06-11 10:28:04 +000016#include "llvm/Support/VersionTuple.h"
John McCall5fb5df92012-06-20 06:18:46 +000017#include "llvm/Support/raw_ostream.h"
Eugene Zelenko5a520112018-03-28 22:09:09 +000018#include <cstddef>
19#include <string>
John McCall5fb5df92012-06-20 06:18:46 +000020
21using namespace clang;
22
23std::string ObjCRuntime::getAsString() const {
24 std::string Result;
25 {
26 llvm::raw_string_ostream Out(Result);
27 Out << *this;
28 }
Fangrui Song6907ce22018-07-30 19:24:48 +000029 return Result;
John McCall5fb5df92012-06-20 06:18:46 +000030}
31
32raw_ostream &clang::operator<<(raw_ostream &out, const ObjCRuntime &value) {
33 switch (value.getKind()) {
34 case ObjCRuntime::MacOSX: out << "macosx"; break;
35 case ObjCRuntime::FragileMacOSX: out << "macosx-fragile"; break;
36 case ObjCRuntime::iOS: out << "ios"; break;
Tim Northover756447a2015-10-30 16:30:36 +000037 case ObjCRuntime::WatchOS: out << "watchos"; break;
David Chisnallb601c962012-07-03 20:49:52 +000038 case ObjCRuntime::GNUstep: out << "gnustep"; break;
39 case ObjCRuntime::GCC: out << "gcc"; break;
John McCall775086e2012-07-12 02:07:58 +000040 case ObjCRuntime::ObjFW: out << "objfw"; break;
John McCall5fb5df92012-06-20 06:18:46 +000041 }
42 if (value.getVersion() > VersionTuple(0)) {
43 out << '-' << value.getVersion();
44 }
45 return out;
46}
47
48bool ObjCRuntime::tryParse(StringRef input) {
49 // Look for the last dash.
50 std::size_t dash = input.rfind('-');
51
John McCall18ac1632012-06-20 21:58:02 +000052 // We permit dashes in the runtime name, and we also permit the
53 // version to be omitted, so if we see a dash not followed by a
54 // digit then we need to ignore it.
John McCall5fb5df92012-06-20 06:18:46 +000055 if (dash != StringRef::npos && dash + 1 != input.size() &&
56 (input[dash+1] < '0' || input[dash+1] > '9')) {
57 dash = StringRef::npos;
58 }
59
60 // Everything prior to that must be a valid string name.
61 Kind kind;
62 StringRef runtimeName = input.substr(0, dash);
David Chisnall314896c2012-07-04 10:37:03 +000063 Version = VersionTuple(0);
John McCall5fb5df92012-06-20 06:18:46 +000064 if (runtimeName == "macosx") {
65 kind = ObjCRuntime::MacOSX;
66 } else if (runtimeName == "macosx-fragile") {
67 kind = ObjCRuntime::FragileMacOSX;
68 } else if (runtimeName == "ios") {
69 kind = ObjCRuntime::iOS;
Tim Northover756447a2015-10-30 16:30:36 +000070 } else if (runtimeName == "watchos") {
71 kind = ObjCRuntime::WatchOS;
David Chisnallb601c962012-07-03 20:49:52 +000072 } else if (runtimeName == "gnustep") {
David Chisnall314896c2012-07-04 10:37:03 +000073 // If no version is specified then default to the most recent one that we
74 // know about.
75 Version = VersionTuple(1, 6);
David Chisnallb601c962012-07-03 20:49:52 +000076 kind = ObjCRuntime::GNUstep;
77 } else if (runtimeName == "gcc") {
78 kind = ObjCRuntime::GCC;
John McCall775086e2012-07-12 02:07:58 +000079 } else if (runtimeName == "objfw") {
80 kind = ObjCRuntime::ObjFW;
Benjamin Kramer4d6efbb2013-09-16 16:31:49 +000081 Version = VersionTuple(0, 8);
John McCall5fb5df92012-06-20 06:18:46 +000082 } else {
83 return true;
84 }
85 TheKind = kind;
Benjamin Kramer4d6efbb2013-09-16 16:31:49 +000086
John McCall5fb5df92012-06-20 06:18:46 +000087 if (dash != StringRef::npos) {
88 StringRef verString = input.substr(dash + 1);
Benjamin Kramer4d6efbb2013-09-16 16:31:49 +000089 if (Version.tryParse(verString))
John McCall5fb5df92012-06-20 06:18:46 +000090 return true;
91 }
92
Benjamin Kramer4d6efbb2013-09-16 16:31:49 +000093 if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8))
94 Version = VersionTuple(0, 8);
95
John McCall5fb5df92012-06-20 06:18:46 +000096 return false;
97}