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