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