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