1//===- TextStubCommon.cpp -------------------------------------------------===// 2// 3// 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 6// 7//===----------------------------------------------------------------------===// 8// 9// Implememts common Text Stub YAML mappings. 10// 11//===----------------------------------------------------------------------===// 12 13#include "TextStubCommon.h" 14#include "TextAPIContext.h" 15#include "llvm/ADT/StringSwitch.h" 16 17using namespace llvm::MachO; 18 19namespace llvm { 20namespace yaml { 21 22void ScalarTraits<FlowStringRef>::output(const FlowStringRef &Value, void *Ctx, 23 raw_ostream &OS) { 24 ScalarTraits<StringRef>::output(Value, Ctx, OS); 25} 26StringRef ScalarTraits<FlowStringRef>::input(StringRef Value, void *Ctx, 27 FlowStringRef &Out) { 28 return ScalarTraits<StringRef>::input(Value, Ctx, Out.value); 29} 30QuotingType ScalarTraits<FlowStringRef>::mustQuote(StringRef Name) { 31 return ScalarTraits<StringRef>::mustQuote(Name); 32} 33 34void ScalarEnumerationTraits<ObjCConstraintType>::enumeration( 35 IO &IO, ObjCConstraintType &Constraint) { 36 IO.enumCase(Constraint, "none", ObjCConstraintType::None); 37 IO.enumCase(Constraint, "retain_release", ObjCConstraintType::Retain_Release); 38 IO.enumCase(Constraint, "retain_release_for_simulator", 39 ObjCConstraintType::Retain_Release_For_Simulator); 40 IO.enumCase(Constraint, "retain_release_or_gc", 41 ObjCConstraintType::Retain_Release_Or_GC); 42 IO.enumCase(Constraint, "gc", ObjCConstraintType::GC); 43} 44 45void ScalarTraits<PlatformSet>::output(const PlatformSet &Values, void *IO, 46 raw_ostream &OS) { 47 48 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO); 49 assert((!Ctx || Ctx->FileKind != FileType::Invalid) && 50 "File type is not set in context"); 51 52 if (Ctx && Ctx->FileKind == TBD_V3 && Values.count(PlatformKind::macOS) && 53 Values.count(PlatformKind::macCatalyst)) { 54 OS << "zippered"; 55 return; 56 } 57 58 assert(Values.size() == 1U); 59 switch (*Values.begin()) { 60 default: 61 llvm_unreachable("unexpected platform"); 62 break; 63 case PlatformKind::macOS: 64 OS << "macosx"; 65 break; 66 case PlatformKind::iOSSimulator: 67 LLVM_FALLTHROUGH; 68 case PlatformKind::iOS: 69 OS << "ios"; 70 break; 71 case PlatformKind::watchOSSimulator: 72 LLVM_FALLTHROUGH; 73 case PlatformKind::watchOS: 74 OS << "watchos"; 75 break; 76 case PlatformKind::tvOSSimulator: 77 LLVM_FALLTHROUGH; 78 case PlatformKind::tvOS: 79 OS << "tvos"; 80 break; 81 case PlatformKind::bridgeOS: 82 OS << "bridgeos"; 83 break; 84 case PlatformKind::macCatalyst: 85 OS << "iosmac"; 86 break; 87 } 88} 89 90StringRef ScalarTraits<PlatformSet>::input(StringRef Scalar, void *IO, 91 PlatformSet &Values) { 92 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO); 93 assert((!Ctx || Ctx->FileKind != FileType::Invalid) && 94 "File type is not set in context"); 95 96 if (Scalar == "zippered") { 97 if (Ctx && Ctx->FileKind == FileType::TBD_V3) { 98 Values.insert(PlatformKind::macOS); 99 Values.insert(PlatformKind::macCatalyst); 100 return {}; 101 } 102 return "invalid platform"; 103 } 104 105 auto Platform = StringSwitch<PlatformKind>(Scalar) 106 .Case("unknown", PlatformKind::unknown) 107 .Case("macosx", PlatformKind::macOS) 108 .Case("ios", PlatformKind::iOS) 109 .Case("watchos", PlatformKind::watchOS) 110 .Case("tvos", PlatformKind::tvOS) 111 .Case("bridgeos", PlatformKind::bridgeOS) 112 .Case("iosmac", PlatformKind::macCatalyst) 113 .Default(PlatformKind::unknown); 114 115 if (Platform == PlatformKind::macCatalyst) 116 if (Ctx && Ctx->FileKind != FileType::TBD_V3) 117 return "invalid platform"; 118 119 if (Platform == PlatformKind::unknown) 120 return "unknown platform"; 121 122 Values.insert(Platform); 123 return {}; 124} 125 126QuotingType ScalarTraits<PlatformSet>::mustQuote(StringRef) { 127 return QuotingType::None; 128} 129 130void ScalarBitSetTraits<ArchitectureSet>::bitset(IO &IO, 131 ArchitectureSet &Archs) { 132#define ARCHINFO(arch, type, subtype, numbits) \ 133 IO.bitSetCase(Archs, #arch, 1U << static_cast<int>(AK_##arch)); 134#include "llvm/TextAPI/MachO/Architecture.def" 135#undef ARCHINFO 136} 137 138void ScalarTraits<Architecture>::output(const Architecture &Value, void *, 139 raw_ostream &OS) { 140 OS << Value; 141} 142StringRef ScalarTraits<Architecture>::input(StringRef Scalar, void *, 143 Architecture &Value) { 144 Value = getArchitectureFromName(Scalar); 145 return {}; 146} 147QuotingType ScalarTraits<Architecture>::mustQuote(StringRef) { 148 return QuotingType::None; 149} 150 151void ScalarTraits<PackedVersion>::output(const PackedVersion &Value, void *, 152 raw_ostream &OS) { 153 OS << Value; 154} 155StringRef ScalarTraits<PackedVersion>::input(StringRef Scalar, void *, 156 PackedVersion &Value) { 157 if (!Value.parse32(Scalar)) 158 return "invalid packed version string."; 159 return {}; 160} 161QuotingType ScalarTraits<PackedVersion>::mustQuote(StringRef) { 162 return QuotingType::None; 163} 164 165void ScalarTraits<SwiftVersion>::output(const SwiftVersion &Value, void *, 166 raw_ostream &OS) { 167 switch (Value) { 168 case 1: 169 OS << "1.0"; 170 break; 171 case 2: 172 OS << "1.1"; 173 break; 174 case 3: 175 OS << "2.0"; 176 break; 177 case 4: 178 OS << "3.0"; 179 break; 180 default: 181 OS << (unsigned)Value; 182 break; 183 } 184} 185StringRef ScalarTraits<SwiftVersion>::input(StringRef Scalar, void *IO, 186 SwiftVersion &Value) { 187 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO); 188 assert((!Ctx || Ctx->FileKind != FileType::Invalid) && 189 "File type is not set in context"); 190 191 if (Ctx->FileKind == FileType::TBD_V4) { 192 if (Scalar.getAsInteger(10, Value)) 193 return "invalid Swift ABI version."; 194 return {}; 195 } else { 196 Value = StringSwitch<SwiftVersion>(Scalar) 197 .Case("1.0", 1) 198 .Case("1.1", 2) 199 .Case("2.0", 3) 200 .Case("3.0", 4) 201 .Default(0); 202 } 203 204 if (Value != SwiftVersion(0)) 205 return {}; 206 207 if (Scalar.getAsInteger(10, Value)) 208 return "invalid Swift ABI version."; 209 210 return StringRef(); 211} 212QuotingType ScalarTraits<SwiftVersion>::mustQuote(StringRef) { 213 return QuotingType::None; 214} 215 216void ScalarTraits<UUID>::output(const UUID &Value, void *, raw_ostream &OS) { 217 OS << Value.first << ": " << Value.second; 218} 219StringRef ScalarTraits<UUID>::input(StringRef Scalar, void *, UUID &Value) { 220 auto Split = Scalar.split(':'); 221 auto Arch = Split.first.trim(); 222 auto UUID = Split.second.trim(); 223 if (UUID.empty()) 224 return "invalid uuid string pair"; 225 Value.second = std::string(UUID); 226 Value.first = Target{getArchitectureFromName(Arch), PlatformKind::unknown}; 227 return {}; 228} 229 230QuotingType ScalarTraits<UUID>::mustQuote(StringRef) { 231 return QuotingType::Single; 232} 233 234} // end namespace yaml. 235} // end namespace llvm. 236