Home | History | Annotate | Line # | Download | only in Basic
      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