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