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(PLATFORM_MACOS) && 53 Values.count(PLATFORM_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 PLATFORM_MACOS: 64 OS << "macosx"; 65 break; 66 case PLATFORM_IOSSIMULATOR: 67 LLVM_FALLTHROUGH; 68 case PLATFORM_IOS: 69 OS << "ios"; 70 break; 71 case PLATFORM_WATCHOSSIMULATOR: 72 LLVM_FALLTHROUGH; 73 case PLATFORM_WATCHOS: 74 OS << "watchos"; 75 break; 76 case PLATFORM_TVOSSIMULATOR: 77 LLVM_FALLTHROUGH; 78 case PLATFORM_TVOS: 79 OS << "tvos"; 80 break; 81 case PLATFORM_BRIDGEOS: 82 OS << "bridgeos"; 83 break; 84 case PLATFORM_MACCATALYST: 85 OS << "iosmac"; 86 break; 87 case PLATFORM_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(PLATFORM_MACOS); 102 Values.insert(PLATFORM_MACCATALYST); 103 return {}; 104 } 105 return "invalid platform"; 106 } 107 108 auto Platform = StringSwitch<PlatformType>(Scalar) 109 .Case("macosx", PLATFORM_MACOS) 110 .Case("ios", PLATFORM_IOS) 111 .Case("watchos", PLATFORM_WATCHOS) 112 .Case("tvos", PLATFORM_TVOS) 113 .Case("bridgeos", PLATFORM_BRIDGEOS) 114 .Case("iosmac", PLATFORM_MACCATALYST) 115 .Default(PLATFORM_UNKNOWN); 116 117 if (Platform == PLATFORM_MACCATALYST) 118 if (Ctx && Ctx->FileKind != FileType::TBD_V3) 119 return "invalid platform"; 120 121 if (Platform == PLATFORM_UNKNOWN) 122 return "unknown platform"; 123 124 Values.insert(Platform); 125 return {}; 126 } 127 128 QuotingType ScalarTraits<PlatformSet>::mustQuote(StringRef) { 129 return QuotingType::None; 130 } 131 132 void ScalarBitSetTraits<ArchitectureSet>::bitset(IO &IO, 133 ArchitectureSet &Archs) { 134 #define ARCHINFO(arch, type, subtype, numbits) \ 135 IO.bitSetCase(Archs, #arch, 1U << static_cast<int>(AK_##arch)); 136 #include "llvm/TextAPI/Architecture.def" 137 #undef ARCHINFO 138 } 139 140 void ScalarTraits<Architecture>::output(const Architecture &Value, void *, 141 raw_ostream &OS) { 142 OS << Value; 143 } 144 StringRef ScalarTraits<Architecture>::input(StringRef Scalar, void *, 145 Architecture &Value) { 146 Value = getArchitectureFromName(Scalar); 147 return {}; 148 } 149 QuotingType ScalarTraits<Architecture>::mustQuote(StringRef) { 150 return QuotingType::None; 151 } 152 153 void ScalarTraits<PackedVersion>::output(const PackedVersion &Value, void *, 154 raw_ostream &OS) { 155 OS << Value; 156 } 157 StringRef ScalarTraits<PackedVersion>::input(StringRef Scalar, void *, 158 PackedVersion &Value) { 159 if (!Value.parse32(Scalar)) 160 return "invalid packed version string."; 161 return {}; 162 } 163 QuotingType ScalarTraits<PackedVersion>::mustQuote(StringRef) { 164 return QuotingType::None; 165 } 166 167 void ScalarTraits<SwiftVersion>::output(const SwiftVersion &Value, void *, 168 raw_ostream &OS) { 169 switch (Value) { 170 case 1: 171 OS << "1.0"; 172 break; 173 case 2: 174 OS << "1.1"; 175 break; 176 case 3: 177 OS << "2.0"; 178 break; 179 case 4: 180 OS << "3.0"; 181 break; 182 default: 183 OS << (unsigned)Value; 184 break; 185 } 186 } 187 StringRef ScalarTraits<SwiftVersion>::input(StringRef Scalar, void *IO, 188 SwiftVersion &Value) { 189 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO); 190 assert((!Ctx || Ctx->FileKind != FileType::Invalid) && 191 "File type is not set in context"); 192 193 if (Ctx->FileKind == FileType::TBD_V4) { 194 if (Scalar.getAsInteger(10, Value)) 195 return "invalid Swift ABI version."; 196 return {}; 197 } else { 198 Value = StringSwitch<SwiftVersion>(Scalar) 199 .Case("1.0", 1) 200 .Case("1.1", 2) 201 .Case("2.0", 3) 202 .Case("3.0", 4) 203 .Default(0); 204 } 205 206 if (Value != SwiftVersion(0)) 207 return {}; 208 209 if (Scalar.getAsInteger(10, Value)) 210 return "invalid Swift ABI version."; 211 212 return StringRef(); 213 } 214 QuotingType ScalarTraits<SwiftVersion>::mustQuote(StringRef) { 215 return QuotingType::None; 216 } 217 218 void ScalarTraits<UUID>::output(const UUID &Value, void *, raw_ostream &OS) { 219 OS << Value.first << ": " << Value.second; 220 } 221 StringRef ScalarTraits<UUID>::input(StringRef Scalar, void *, UUID &Value) { 222 auto Split = Scalar.split(':'); 223 auto Arch = Split.first.trim(); 224 auto UUID = Split.second.trim(); 225 if (UUID.empty()) 226 return "invalid uuid string pair"; 227 Value.second = std::string(UUID); 228 Value.first = Target{getArchitectureFromName(Arch), PLATFORM_UNKNOWN}; 229 return {}; 230 } 231 232 QuotingType ScalarTraits<UUID>::mustQuote(StringRef) { 233 return QuotingType::Single; 234 } 235 236 } // end namespace yaml. 237 } // end namespace llvm. 238