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 17 using namespace llvm::MachO; 18 19 namespace llvm { 20 namespace yaml { 21 22 void ScalarTraits<FlowStringRef>::output(const FlowStringRef &Value, void *Ctx, 23 raw_ostream &OS) { 24 ScalarTraits<StringRef>::output(Value, Ctx, OS); 25 } 26 StringRef ScalarTraits<FlowStringRef>::input(StringRef Value, void *Ctx, 27 FlowStringRef &Out) { 28 return ScalarTraits<StringRef>::input(Value, Ctx, Out.value); 29 } 30 QuotingType ScalarTraits<FlowStringRef>::mustQuote(StringRef Name) { 31 return ScalarTraits<StringRef>::mustQuote(Name); 32 } 33 34 void 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 45 void 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 case PlatformKind::driverKit: 88 OS << "driverkit"; 89 break; 90 } 91 } 92 93 StringRef ScalarTraits<PlatformSet>::input(StringRef Scalar, void *IO, 94 PlatformSet &Values) { 95 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO); 96 assert((!Ctx || Ctx->FileKind != FileType::Invalid) && 97 "File type is not set in context"); 98 99 if (Scalar == "zippered") { 100 if (Ctx && Ctx->FileKind == FileType::TBD_V3) { 101 Values.insert(PlatformKind::macOS); 102 Values.insert(PlatformKind::macCatalyst); 103 return {}; 104 } 105 return "invalid platform"; 106 } 107 108 auto Platform = StringSwitch<PlatformKind>(Scalar) 109 .Case("unknown", PlatformKind::unknown) 110 .Case("macosx", PlatformKind::macOS) 111 .Case("ios", PlatformKind::iOS) 112 .Case("watchos", PlatformKind::watchOS) 113 .Case("tvos", PlatformKind::tvOS) 114 .Case("bridgeos", PlatformKind::bridgeOS) 115 .Case("iosmac", PlatformKind::macCatalyst) 116 .Default(PlatformKind::unknown); 117 118 if (Platform == PlatformKind::macCatalyst) 119 if (Ctx && Ctx->FileKind != FileType::TBD_V3) 120 return "invalid platform"; 121 122 if (Platform == PlatformKind::unknown) 123 return "unknown platform"; 124 125 Values.insert(Platform); 126 return {}; 127 } 128 129 QuotingType ScalarTraits<PlatformSet>::mustQuote(StringRef) { 130 return QuotingType::None; 131 } 132 133 void ScalarBitSetTraits<ArchitectureSet>::bitset(IO &IO, 134 ArchitectureSet &Archs) { 135 #define ARCHINFO(arch, type, subtype, numbits) \ 136 IO.bitSetCase(Archs, #arch, 1U << static_cast<int>(AK_##arch)); 137 #include "llvm/TextAPI/Architecture.def" 138 #undef ARCHINFO 139 } 140 141 void ScalarTraits<Architecture>::output(const Architecture &Value, void *, 142 raw_ostream &OS) { 143 OS << Value; 144 } 145 StringRef ScalarTraits<Architecture>::input(StringRef Scalar, void *, 146 Architecture &Value) { 147 Value = getArchitectureFromName(Scalar); 148 return {}; 149 } 150 QuotingType ScalarTraits<Architecture>::mustQuote(StringRef) { 151 return QuotingType::None; 152 } 153 154 void ScalarTraits<PackedVersion>::output(const PackedVersion &Value, void *, 155 raw_ostream &OS) { 156 OS << Value; 157 } 158 StringRef ScalarTraits<PackedVersion>::input(StringRef Scalar, void *, 159 PackedVersion &Value) { 160 if (!Value.parse32(Scalar)) 161 return "invalid packed version string."; 162 return {}; 163 } 164 QuotingType ScalarTraits<PackedVersion>::mustQuote(StringRef) { 165 return QuotingType::None; 166 } 167 168 void ScalarTraits<SwiftVersion>::output(const SwiftVersion &Value, void *, 169 raw_ostream &OS) { 170 switch (Value) { 171 case 1: 172 OS << "1.0"; 173 break; 174 case 2: 175 OS << "1.1"; 176 break; 177 case 3: 178 OS << "2.0"; 179 break; 180 case 4: 181 OS << "3.0"; 182 break; 183 default: 184 OS << (unsigned)Value; 185 break; 186 } 187 } 188 StringRef ScalarTraits<SwiftVersion>::input(StringRef Scalar, void *IO, 189 SwiftVersion &Value) { 190 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO); 191 assert((!Ctx || Ctx->FileKind != FileType::Invalid) && 192 "File type is not set in context"); 193 194 if (Ctx->FileKind == FileType::TBD_V4) { 195 if (Scalar.getAsInteger(10, Value)) 196 return "invalid Swift ABI version."; 197 return {}; 198 } else { 199 Value = StringSwitch<SwiftVersion>(Scalar) 200 .Case("1.0", 1) 201 .Case("1.1", 2) 202 .Case("2.0", 3) 203 .Case("3.0", 4) 204 .Default(0); 205 } 206 207 if (Value != SwiftVersion(0)) 208 return {}; 209 210 if (Scalar.getAsInteger(10, Value)) 211 return "invalid Swift ABI version."; 212 213 return StringRef(); 214 } 215 QuotingType ScalarTraits<SwiftVersion>::mustQuote(StringRef) { 216 return QuotingType::None; 217 } 218 219 void ScalarTraits<UUID>::output(const UUID &Value, void *, raw_ostream &OS) { 220 OS << Value.first << ": " << Value.second; 221 } 222 StringRef ScalarTraits<UUID>::input(StringRef Scalar, void *, UUID &Value) { 223 auto Split = Scalar.split(':'); 224 auto Arch = Split.first.trim(); 225 auto UUID = Split.second.trim(); 226 if (UUID.empty()) 227 return "invalid uuid string pair"; 228 Value.second = std::string(UUID); 229 Value.first = Target{getArchitectureFromName(Arch), PlatformKind::unknown}; 230 return {}; 231 } 232 233 QuotingType ScalarTraits<UUID>::mustQuote(StringRef) { 234 return QuotingType::Single; 235 } 236 237 } // end namespace yaml. 238 } // end namespace llvm. 239