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