xref: /llvm-project/clang/lib/Basic/ObjCRuntime.cpp (revision 2946cd701067404b99c39fb29dc9c74bd7193eb3)
15a52011cSEugene Zelenko //===- ObjCRuntime.cpp - Objective-C Runtime Handling ---------------------===//
25fb5df9cSJohn McCall //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65fb5df9cSJohn McCall //
75fb5df9cSJohn McCall //===----------------------------------------------------------------------===//
85fb5df9cSJohn McCall //
95fb5df9cSJohn McCall // This file implements the ObjCRuntime class, which represents the
105fb5df9cSJohn McCall // target Objective-C runtime.
115fb5df9cSJohn McCall //
125fb5df9cSJohn McCall //===----------------------------------------------------------------------===//
135a52011cSEugene Zelenko 
145fb5df9cSJohn McCall #include "clang/Basic/ObjCRuntime.h"
155a52011cSEugene Zelenko #include "llvm/ADT/StringRef.h"
16d8c6290bSPavel Labath #include "llvm/Support/VersionTuple.h"
175fb5df9cSJohn McCall #include "llvm/Support/raw_ostream.h"
185a52011cSEugene Zelenko #include <cstddef>
195a52011cSEugene Zelenko #include <string>
205fb5df9cSJohn McCall 
215fb5df9cSJohn McCall using namespace clang;
225fb5df9cSJohn McCall 
getAsString() const235fb5df9cSJohn McCall std::string ObjCRuntime::getAsString() const {
245fb5df9cSJohn McCall   std::string Result;
255fb5df9cSJohn McCall   {
265fb5df9cSJohn McCall     llvm::raw_string_ostream Out(Result);
275fb5df9cSJohn McCall     Out << *this;
285fb5df9cSJohn McCall   }
295fb5df9cSJohn McCall   return Result;
305fb5df9cSJohn McCall }
315fb5df9cSJohn McCall 
operator <<(raw_ostream & out,const ObjCRuntime & value)325fb5df9cSJohn McCall raw_ostream &clang::operator<<(raw_ostream &out, const ObjCRuntime &value) {
335fb5df9cSJohn McCall   switch (value.getKind()) {
345fb5df9cSJohn McCall   case ObjCRuntime::MacOSX: out << "macosx"; break;
355fb5df9cSJohn McCall   case ObjCRuntime::FragileMacOSX: out << "macosx-fragile"; break;
365fb5df9cSJohn McCall   case ObjCRuntime::iOS: out << "ios"; break;
37756447a6STim Northover   case ObjCRuntime::WatchOS: out << "watchos"; break;
38b601c968SDavid Chisnall   case ObjCRuntime::GNUstep: out << "gnustep"; break;
39b601c968SDavid Chisnall   case ObjCRuntime::GCC: out << "gcc"; break;
40775086e6SJohn McCall   case ObjCRuntime::ObjFW: out << "objfw"; break;
415fb5df9cSJohn McCall   }
425fb5df9cSJohn McCall   if (value.getVersion() > VersionTuple(0)) {
435fb5df9cSJohn McCall     out << '-' << value.getVersion();
445fb5df9cSJohn McCall   }
455fb5df9cSJohn McCall   return out;
465fb5df9cSJohn McCall }
475fb5df9cSJohn McCall 
tryParse(StringRef input)485fb5df9cSJohn McCall bool ObjCRuntime::tryParse(StringRef input) {
495fb5df9cSJohn McCall   // Look for the last dash.
505fb5df9cSJohn McCall   std::size_t dash = input.rfind('-');
515fb5df9cSJohn McCall 
5218ac1632SJohn McCall   // We permit dashes in the runtime name, and we also permit the
5318ac1632SJohn McCall   // version to be omitted, so if we see a dash not followed by a
5418ac1632SJohn McCall   // digit then we need to ignore it.
555fb5df9cSJohn McCall   if (dash != StringRef::npos && dash + 1 != input.size() &&
565fb5df9cSJohn McCall       (input[dash+1] < '0' || input[dash+1] > '9')) {
575fb5df9cSJohn McCall     dash = StringRef::npos;
585fb5df9cSJohn McCall   }
595fb5df9cSJohn McCall 
605fb5df9cSJohn McCall   // Everything prior to that must be a valid string name.
615fb5df9cSJohn McCall   Kind kind;
625fb5df9cSJohn McCall   StringRef runtimeName = input.substr(0, dash);
63314896c9SDavid Chisnall   Version = VersionTuple(0);
645fb5df9cSJohn McCall   if (runtimeName == "macosx") {
655fb5df9cSJohn McCall     kind = ObjCRuntime::MacOSX;
665fb5df9cSJohn McCall   } else if (runtimeName == "macosx-fragile") {
675fb5df9cSJohn McCall     kind = ObjCRuntime::FragileMacOSX;
685fb5df9cSJohn McCall   } else if (runtimeName == "ios") {
695fb5df9cSJohn McCall     kind = ObjCRuntime::iOS;
70756447a6STim Northover   } else if (runtimeName == "watchos") {
71756447a6STim Northover     kind = ObjCRuntime::WatchOS;
72b601c968SDavid Chisnall   } else if (runtimeName == "gnustep") {
73314896c9SDavid Chisnall     // If no version is specified then default to the most recent one that we
74314896c9SDavid Chisnall     // know about.
75314896c9SDavid Chisnall     Version = VersionTuple(1, 6);
76b601c968SDavid Chisnall     kind = ObjCRuntime::GNUstep;
77b601c968SDavid Chisnall   } else if (runtimeName == "gcc") {
78b601c968SDavid Chisnall     kind = ObjCRuntime::GCC;
79775086e6SJohn McCall   } else if (runtimeName == "objfw") {
80775086e6SJohn McCall     kind = ObjCRuntime::ObjFW;
814d6efbb2SBenjamin Kramer     Version = VersionTuple(0, 8);
825fb5df9cSJohn McCall   } else {
835fb5df9cSJohn McCall     return true;
845fb5df9cSJohn McCall   }
855fb5df9cSJohn McCall   TheKind = kind;
865fb5df9cSJohn McCall 
875fb5df9cSJohn McCall   if (dash != StringRef::npos) {
885fb5df9cSJohn McCall     StringRef verString = input.substr(dash + 1);
895fb5df9cSJohn McCall     if (Version.tryParse(verString))
905fb5df9cSJohn McCall       return true;
915fb5df9cSJohn McCall   }
925fb5df9cSJohn McCall 
934d6efbb2SBenjamin Kramer   if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8))
944d6efbb2SBenjamin Kramer     Version = VersionTuple(0, 8);
954d6efbb2SBenjamin Kramer 
965fb5df9cSJohn McCall   return false;
975fb5df9cSJohn McCall }
98