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