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