LLVM  10.0.0svn
TextStub.cpp
Go to the documentation of this file.
1 //===- TextStub.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 // Implements the text stub file reader/writer.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "TextAPIContext.h"
14 #include "TextStubCommon.h"
15 #include "llvm/ADT/BitmaskEnum.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Allocator.h"
19 #include "llvm/Support/SourceMgr.h"
28 #include <algorithm>
29 #include <set>
30 
31 // clang-format off
32 /*
33 
34  YAML Format specification.
35 
36  The TBD v1 format only support two level address libraries and is per
37  definition application extension safe.
38 
39 --- # the tag !tapi-tbd-v1 is optional and
40  # shouldn't be emitted to support older linker.
41 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
42  # supported by this file.
43 platform: ios # Specifies the platform (macosx, ios, etc)
44 install-name: /u/l/libfoo.dylib #
45 current-version: 1.2.3 # Optional: defaults to 1.0
46 compatibility-version: 1.0 # Optional: defaults to 1.0
47 swift-version: 0 # Optional: defaults to 0
48 objc-constraint: none # Optional: defaults to none
49 exports: # List of export sections
50 ...
51 
52 Each export section is defined as following:
53 
54  - archs: [ arm64 ] # the list of architecture slices
55  allowed-clients: [ client ] # Optional: List of clients
56  re-exports: [ ] # Optional: List of re-exports
57  symbols: [ _sym ] # Optional: List of symbols
58  objc-classes: [] # Optional: List of Objective-C classes
59  objc-ivars: [] # Optional: List of Objective C Instance
60  # Variables
61  weak-def-symbols: [] # Optional: List of weak defined symbols
62  thread-local-symbols: [] # Optional: List of thread local symbols
63 */
64 
65 /*
66 
67  YAML Format specification.
68 
69 --- !tapi-tbd-v2
70 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
71  # supported by this file.
72 uuids: [ armv7:... ] # Optional: List of architecture and UUID pairs.
73 platform: ios # Specifies the platform (macosx, ios, etc)
74 flags: [] # Optional:
75 install-name: /u/l/libfoo.dylib #
76 current-version: 1.2.3 # Optional: defaults to 1.0
77 compatibility-version: 1.0 # Optional: defaults to 1.0
78 swift-version: 0 # Optional: defaults to 0
79 objc-constraint: retain_release # Optional: defaults to retain_release
80 parent-umbrella: # Optional:
81 exports: # List of export sections
82 ...
83 undefineds: # List of undefineds sections
84 ...
85 
86 Each export section is defined as following:
87 
88 - archs: [ arm64 ] # the list of architecture slices
89  allowed-clients: [ client ] # Optional: List of clients
90  re-exports: [ ] # Optional: List of re-exports
91  symbols: [ _sym ] # Optional: List of symbols
92  objc-classes: [] # Optional: List of Objective-C classes
93  objc-ivars: [] # Optional: List of Objective C Instance
94  # Variables
95  weak-def-symbols: [] # Optional: List of weak defined symbols
96  thread-local-symbols: [] # Optional: List of thread local symbols
97 
98 Each undefineds section is defined as following:
99 - archs: [ arm64 ] # the list of architecture slices
100  symbols: [ _sym ] # Optional: List of symbols
101  objc-classes: [] # Optional: List of Objective-C classes
102  objc-ivars: [] # Optional: List of Objective C Instance Variables
103  weak-ref-symbols: [] # Optional: List of weak defined symbols
104 */
105 
106 /*
107 
108  YAML Format specification.
109 
110 --- !tapi-tbd-v3
111 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
112  # supported by this file.
113 uuids: [ armv7:... ] # Optional: List of architecture and UUID pairs.
114 platform: ios # Specifies the platform (macosx, ios, etc)
115 flags: [] # Optional:
116 install-name: /u/l/libfoo.dylib #
117 current-version: 1.2.3 # Optional: defaults to 1.0
118 compatibility-version: 1.0 # Optional: defaults to 1.0
119 swift-abi-version: 0 # Optional: defaults to 0
120 objc-constraint: retain_release # Optional: defaults to retain_release
121 parent-umbrella: # Optional:
122 exports: # List of export sections
123 ...
124 undefineds: # List of undefineds sections
125 ...
126 
127 Each export section is defined as following:
128 
129 - archs: [ arm64 ] # the list of architecture slices
130  allowed-clients: [ client ] # Optional: List of clients
131  re-exports: [ ] # Optional: List of re-exports
132  symbols: [ _sym ] # Optional: List of symbols
133  objc-classes: [] # Optional: List of Objective-C classes
134  objc-eh-types: [] # Optional: List of Objective-C classes
135  # with EH
136  objc-ivars: [] # Optional: List of Objective C Instance
137  # Variables
138  weak-def-symbols: [] # Optional: List of weak defined symbols
139  thread-local-symbols: [] # Optional: List of thread local symbols
140 
141 Each undefineds section is defined as following:
142 - archs: [ arm64 ] # the list of architecture slices
143  symbols: [ _sym ] # Optional: List of symbols
144  objc-classes: [] # Optional: List of Objective-C classes
145  objc-eh-types: [] # Optional: List of Objective-C classes
146  # with EH
147  objc-ivars: [] # Optional: List of Objective C Instance Variables
148  weak-ref-symbols: [] # Optional: List of weak defined symbols
149 */
150 // clang-format on
151 
152 using namespace llvm;
153 using namespace llvm::yaml;
154 using namespace llvm::MachO;
155 
156 namespace {
157 struct ExportSection {
158  std::vector<Architecture> Architectures;
159  std::vector<FlowStringRef> AllowableClients;
160  std::vector<FlowStringRef> ReexportedLibraries;
161  std::vector<FlowStringRef> Symbols;
162  std::vector<FlowStringRef> Classes;
163  std::vector<FlowStringRef> ClassEHs;
164  std::vector<FlowStringRef> IVars;
165  std::vector<FlowStringRef> WeakDefSymbols;
166  std::vector<FlowStringRef> TLVSymbols;
167 };
168 
169 struct UndefinedSection {
170  std::vector<Architecture> Architectures;
171  std::vector<FlowStringRef> Symbols;
172  std::vector<FlowStringRef> Classes;
173  std::vector<FlowStringRef> ClassEHs;
174  std::vector<FlowStringRef> IVars;
175  std::vector<FlowStringRef> WeakRefSymbols;
176 };
177 
178 // clang-format off
179 enum TBDFlags : unsigned {
180  None = 0U,
181  FlatNamespace = 1U << 0,
182  NotApplicationExtensionSafe = 1U << 1,
183  InstallAPI = 1U << 2,
184  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/InstallAPI),
185 };
186 // clang-format on
187 } // end anonymous namespace.
188 
189 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(Architecture)
190 LLVM_YAML_IS_SEQUENCE_VECTOR(ExportSection)
191 LLVM_YAML_IS_SEQUENCE_VECTOR(UndefinedSection)
192 
193 namespace llvm {
194 namespace yaml {
195 
196 template <> struct MappingTraits<ExportSection> {
197  static void mapping(IO &IO, ExportSection &Section) {
198  const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
199  assert((!Ctx || (Ctx && Ctx->FileKind != FileType::Invalid)) &&
200  "File type is not set in YAML context");
201 
202  IO.mapRequired("archs", Section.Architectures);
203  if (Ctx->FileKind == FileType::TBD_V1)
204  IO.mapOptional("allowed-clients", Section.AllowableClients);
205  else
206  IO.mapOptional("allowable-clients", Section.AllowableClients);
207  IO.mapOptional("re-exports", Section.ReexportedLibraries);
208  IO.mapOptional("symbols", Section.Symbols);
209  IO.mapOptional("objc-classes", Section.Classes);
210  if (Ctx->FileKind == FileType::TBD_V3)
211  IO.mapOptional("objc-eh-types", Section.ClassEHs);
212  IO.mapOptional("objc-ivars", Section.IVars);
213  IO.mapOptional("weak-def-symbols", Section.WeakDefSymbols);
214  IO.mapOptional("thread-local-symbols", Section.TLVSymbols);
215  }
216 };
217 
218 template <> struct MappingTraits<UndefinedSection> {
219  static void mapping(IO &IO, UndefinedSection &Section) {
220  const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
221  assert((!Ctx || (Ctx && Ctx->FileKind != FileType::Invalid)) &&
222  "File type is not set in YAML context");
223 
224  IO.mapRequired("archs", Section.Architectures);
225  IO.mapOptional("symbols", Section.Symbols);
226  IO.mapOptional("objc-classes", Section.Classes);
227  if (Ctx->FileKind == FileType::TBD_V3)
228  IO.mapOptional("objc-eh-types", Section.ClassEHs);
229  IO.mapOptional("objc-ivars", Section.IVars);
230  IO.mapOptional("weak-ref-symbols", Section.WeakRefSymbols);
231  }
232 };
233 
234 template <> struct ScalarBitSetTraits<TBDFlags> {
235  static void bitset(IO &IO, TBDFlags &Flags) {
236  IO.bitSetCase(Flags, "flat_namespace", TBDFlags::FlatNamespace);
237  IO.bitSetCase(Flags, "not_app_extension_safe",
238  TBDFlags::NotApplicationExtensionSafe);
239  IO.bitSetCase(Flags, "installapi", TBDFlags::InstallAPI);
240  }
241 };
242 
243 template <> struct MappingTraits<const InterfaceFile *> {
244  struct NormalizedTBD {
245  explicit NormalizedTBD(IO &IO) {}
246  NormalizedTBD(IO &IO, const InterfaceFile *&File) {
247  Architectures = File->getArchitectures();
248  UUIDs = File->uuids();
249  Platform = File->getPlatform();
250  InstallName = File->getInstallName();
252  CompatibilityVersion = PackedVersion(File->getCompatibilityVersion());
253  SwiftABIVersion = File->getSwiftABIVersion();
254  ObjCConstraint = File->getObjCConstraint();
255 
256  Flags = TBDFlags::None;
257  if (!File->isApplicationExtensionSafe())
258  Flags |= TBDFlags::NotApplicationExtensionSafe;
259 
260  if (!File->isTwoLevelNamespace())
261  Flags |= TBDFlags::FlatNamespace;
262 
263  if (File->isInstallAPI())
264  Flags |= TBDFlags::InstallAPI;
265 
266  ParentUmbrella = File->getParentUmbrella();
267 
268  std::set<ArchitectureSet> ArchSet;
269  for (const auto &Library : File->allowableClients())
270  ArchSet.insert(Library.getArchitectures());
271 
272  for (const auto &Library : File->reexportedLibraries())
273  ArchSet.insert(Library.getArchitectures());
274 
275  std::map<const Symbol *, ArchitectureSet> SymbolToArchSet;
276  for (const auto *Symbol : File->exports()) {
277  auto Architectures = Symbol->getArchitectures();
278  SymbolToArchSet[Symbol] = Architectures;
279  ArchSet.insert(Architectures);
280  }
281 
282  for (auto Architectures : ArchSet) {
283  ExportSection Section;
284  Section.Architectures = Architectures;
285 
286  for (const auto &Library : File->allowableClients())
287  if (Library.getArchitectures() == Architectures)
288  Section.AllowableClients.emplace_back(Library.getInstallName());
289 
290  for (const auto &Library : File->reexportedLibraries())
291  if (Library.getArchitectures() == Architectures)
292  Section.ReexportedLibraries.emplace_back(Library.getInstallName());
293 
294  for (const auto &SymArch : SymbolToArchSet) {
295  if (SymArch.second != Architectures)
296  continue;
297 
298  const auto *Symbol = SymArch.first;
299  switch (Symbol->getKind()) {
300  case SymbolKind::GlobalSymbol:
301  if (Symbol->isWeakDefined())
302  Section.WeakDefSymbols.emplace_back(Symbol->getName());
303  else if (Symbol->isThreadLocalValue())
304  Section.TLVSymbols.emplace_back(Symbol->getName());
305  else
306  Section.Symbols.emplace_back(Symbol->getName());
307  break;
308  case SymbolKind::ObjectiveCClass:
309  if (File->getFileType() != FileType::TBD_V3)
310  Section.Classes.emplace_back(
311  copyString("_" + Symbol->getName().str()));
312  else
313  Section.Classes.emplace_back(Symbol->getName());
314  break;
315  case SymbolKind::ObjectiveCClassEHType:
316  if (File->getFileType() != FileType::TBD_V3)
317  Section.Symbols.emplace_back(
318  copyString("_OBJC_EHTYPE_$_" + Symbol->getName().str()));
319  else
320  Section.ClassEHs.emplace_back(Symbol->getName());
321  break;
322  case SymbolKind::ObjectiveCInstanceVariable:
323  if (File->getFileType() != FileType::TBD_V3)
324  Section.IVars.emplace_back(
325  copyString("_" + Symbol->getName().str()));
326  else
327  Section.IVars.emplace_back(Symbol->getName());
328  break;
329  }
330  }
331  llvm::sort(Section.Symbols.begin(), Section.Symbols.end());
332  llvm::sort(Section.Classes.begin(), Section.Classes.end());
333  llvm::sort(Section.ClassEHs.begin(), Section.ClassEHs.end());
334  llvm::sort(Section.IVars.begin(), Section.IVars.end());
335  llvm::sort(Section.WeakDefSymbols.begin(),
336  Section.WeakDefSymbols.end());
337  llvm::sort(Section.TLVSymbols.begin(), Section.TLVSymbols.end());
338  Exports.emplace_back(std::move(Section));
339  }
340 
341  ArchSet.clear();
342  SymbolToArchSet.clear();
343 
344  for (const auto *Symbol : File->undefineds()) {
345  auto Architectures = Symbol->getArchitectures();
346  SymbolToArchSet[Symbol] = Architectures;
347  ArchSet.insert(Architectures);
348  }
349 
350  for (auto Architectures : ArchSet) {
351  UndefinedSection Section;
352  Section.Architectures = Architectures;
353 
354  for (const auto &SymArch : SymbolToArchSet) {
355  if (SymArch.second != Architectures)
356  continue;
357 
358  const auto *Symbol = SymArch.first;
359  switch (Symbol->getKind()) {
360  case SymbolKind::GlobalSymbol:
361  if (Symbol->isWeakReferenced())
362  Section.WeakRefSymbols.emplace_back(Symbol->getName());
363  else
364  Section.Symbols.emplace_back(Symbol->getName());
365  break;
366  case SymbolKind::ObjectiveCClass:
367  if (File->getFileType() != FileType::TBD_V3)
368  Section.Classes.emplace_back(
369  copyString("_" + Symbol->getName().str()));
370  else
371  Section.Classes.emplace_back(Symbol->getName());
372  break;
373  case SymbolKind::ObjectiveCClassEHType:
374  if (File->getFileType() != FileType::TBD_V3)
375  Section.Symbols.emplace_back(
376  copyString("_OBJC_EHTYPE_$_" + Symbol->getName().str()));
377  else
378  Section.ClassEHs.emplace_back(Symbol->getName());
379  break;
380  case SymbolKind::ObjectiveCInstanceVariable:
381  if (File->getFileType() != FileType::TBD_V3)
382  Section.IVars.emplace_back(
383  copyString("_" + Symbol->getName().str()));
384  else
385  Section.IVars.emplace_back(Symbol->getName());
386  break;
387  }
388  }
389  llvm::sort(Section.Symbols.begin(), Section.Symbols.end());
390  llvm::sort(Section.Classes.begin(), Section.Classes.end());
391  llvm::sort(Section.ClassEHs.begin(), Section.ClassEHs.end());
392  llvm::sort(Section.IVars.begin(), Section.IVars.end());
393  llvm::sort(Section.WeakRefSymbols.begin(),
394  Section.WeakRefSymbols.end());
395  Undefineds.emplace_back(std::move(Section));
396  }
397  }
398 
399  const InterfaceFile *denormalize(IO &IO) {
400  auto Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
401  assert(Ctx);
402 
403  auto *File = new InterfaceFile;
404  File->setPath(Ctx->Path);
405  File->setFileType(Ctx->FileKind);
406  for (auto &ID : UUIDs)
407  File->addUUID(ID.first, ID.second);
408  File->setPlatform(Platform);
409  File->setArchitectures(Architectures);
410  File->setInstallName(InstallName);
411  File->setCurrentVersion(CurrentVersion);
412  File->setCompatibilityVersion(CompatibilityVersion);
413  File->setSwiftABIVersion(SwiftABIVersion);
414  File->setObjCConstraint(ObjCConstraint);
415  File->setParentUmbrella(ParentUmbrella);
416 
417  if (Ctx->FileKind == FileType::TBD_V1) {
418  File->setTwoLevelNamespace();
419  File->setApplicationExtensionSafe();
420  } else {
421  File->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace));
422  File->setApplicationExtensionSafe(
423  !(Flags & TBDFlags::NotApplicationExtensionSafe));
424  File->setInstallAPI(Flags & TBDFlags::InstallAPI);
425  }
426 
427  for (const auto &Section : Exports) {
428  for (const auto &Library : Section.AllowableClients)
429  File->addAllowableClient(Library, Section.Architectures);
430  for (const auto &Library : Section.ReexportedLibraries)
431  File->addReexportedLibrary(Library, Section.Architectures);
432 
433  for (const auto &Symbol : Section.Symbols) {
434  if (Ctx->FileKind != FileType::TBD_V3 &&
435  Symbol.value.startswith("_OBJC_EHTYPE_$_"))
436  File->addSymbol(SymbolKind::ObjectiveCClassEHType,
437  Symbol.value.drop_front(15), Section.Architectures);
438  else
439  File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
440  Section.Architectures);
441  }
442  for (auto &Symbol : Section.Classes) {
443  auto Name = Symbol.value;
444  if (Ctx->FileKind != FileType::TBD_V3)
445  Name = Name.drop_front();
446  File->addSymbol(SymbolKind::ObjectiveCClass, Name,
447  Section.Architectures);
448  }
449  for (auto &Symbol : Section.ClassEHs)
450  File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
451  Section.Architectures);
452  for (auto &Symbol : Section.IVars) {
453  auto Name = Symbol.value;
454  if (Ctx->FileKind != FileType::TBD_V3)
455  Name = Name.drop_front();
456  File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
457  Section.Architectures);
458  }
459  for (auto &Symbol : Section.WeakDefSymbols)
460  File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
461  Section.Architectures, SymbolFlags::WeakDefined);
462  for (auto &Symbol : Section.TLVSymbols)
463  File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
464  Section.Architectures, SymbolFlags::ThreadLocalValue);
465  }
466 
467  for (const auto &Section : Undefineds) {
468  for (auto &Symbol : Section.Symbols) {
469  if (Ctx->FileKind != FileType::TBD_V3 &&
470  Symbol.value.startswith("_OBJC_EHTYPE_$_"))
471  File->addSymbol(SymbolKind::ObjectiveCClassEHType,
472  Symbol.value.drop_front(15), Section.Architectures,
473  SymbolFlags::Undefined);
474  else
475  File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
476  Section.Architectures, SymbolFlags::Undefined);
477  }
478  for (auto &Symbol : Section.Classes) {
479  auto Name = Symbol.value;
480  if (Ctx->FileKind != FileType::TBD_V3)
481  Name = Name.drop_front();
482  File->addSymbol(SymbolKind::ObjectiveCClass, Name,
483  Section.Architectures, SymbolFlags::Undefined);
484  }
485  for (auto &Symbol : Section.ClassEHs)
486  File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
487  Section.Architectures, SymbolFlags::Undefined);
488  for (auto &Symbol : Section.IVars) {
489  auto Name = Symbol.value;
490  if (Ctx->FileKind != FileType::TBD_V3)
491  Name = Name.drop_front();
492  File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
493  Section.Architectures, SymbolFlags::Undefined);
494  }
495  for (auto &Symbol : Section.WeakRefSymbols)
496  File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
497  Section.Architectures,
498  SymbolFlags::Undefined | SymbolFlags::WeakReferenced);
499  }
500 
501  return File;
502  }
503 
506  if (String.empty())
507  return {};
508 
509  void *Ptr = Allocator.Allocate(String.size(), 1);
510  memcpy(Ptr, String.data(), String.size());
511  return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
512  }
513 
514  std::vector<Architecture> Architectures;
515  std::vector<UUID> UUIDs;
516  PlatformKind Platform{PlatformKind::unknown};
520  SwiftVersion SwiftABIVersion{0};
524  std::vector<ExportSection> Exports;
525  std::vector<UndefinedSection> Undefineds;
526  };
527 
528  static void mapping(IO &IO, const InterfaceFile *&File) {
529  auto *Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
530  assert((!Ctx || !IO.outputting() ||
531  (Ctx && Ctx->FileKind != FileType::Invalid)) &&
532  "File type is not set in YAML context");
533  MappingNormalization<NormalizedTBD, const InterfaceFile *> Keys(IO, File);
534 
535  // prope file type when reading.
536  if (!IO.outputting()) {
537  if (IO.mapTag("!tapi-tbd-v3", false))
538  Ctx->FileKind = FileType::TBD_V3;
539  else if (IO.mapTag("!tapi-tbd-v2", false))
540  Ctx->FileKind = FileType::TBD_V2;
541  else if (IO.mapTag("!tapi-tbd-v1", false) ||
542  IO.mapTag("tag:yaml.org,2002:map", false))
543  Ctx->FileKind = FileType::TBD_V1;
544  else {
545  IO.setError("unsupported file type");
546  return;
547  }
548  }
549 
550  // Set file type when writing.
551  if (IO.outputting()) {
552  switch (Ctx->FileKind) {
553  default:
554  llvm_unreachable("unexpected file type");
555  case FileType::TBD_V1:
556  // Don't write the tag into the .tbd file for TBD v1.
557  break;
558  case FileType::TBD_V2:
559  IO.mapTag("!tapi-tbd-v2", true);
560  break;
561  case FileType::TBD_V3:
562  IO.mapTag("!tapi-tbd-v3", true);
563  break;
564  }
565  }
566 
567  IO.mapRequired("archs", Keys->Architectures);
568  if (Ctx->FileKind != FileType::TBD_V1)
569  IO.mapOptional("uuids", Keys->UUIDs);
570  IO.mapRequired("platform", Keys->Platform);
571  if (Ctx->FileKind != FileType::TBD_V1)
572  IO.mapOptional("flags", Keys->Flags, TBDFlags::None);
573  IO.mapRequired("install-name", Keys->InstallName);
574  IO.mapOptional("current-version", Keys->CurrentVersion,
575  PackedVersion(1, 0, 0));
576  IO.mapOptional("compatibility-version", Keys->CompatibilityVersion,
577  PackedVersion(1, 0, 0));
578  if (Ctx->FileKind != FileType::TBD_V3)
579  IO.mapOptional("swift-version", Keys->SwiftABIVersion, SwiftVersion(0));
580  else
581  IO.mapOptional("swift-abi-version", Keys->SwiftABIVersion,
582  SwiftVersion(0));
583  IO.mapOptional("objc-constraint", Keys->ObjCConstraint,
584  (Ctx->FileKind == FileType::TBD_V1)
586  : ObjCConstraintType::Retain_Release);
587  if (Ctx->FileKind != FileType::TBD_V1)
588  IO.mapOptional("parent-umbrella", Keys->ParentUmbrella, StringRef());
589  IO.mapOptional("exports", Keys->Exports);
590  if (Ctx->FileKind != FileType::TBD_V1)
591  IO.mapOptional("undefineds", Keys->Undefineds);
592  }
593 };
594 
595 template <>
596 struct DocumentListTraits<std::vector<const MachO::InterfaceFile *>> {
597  static size_t size(IO &IO, std::vector<const MachO::InterfaceFile *> &Seq) {
598  return Seq.size();
599  }
600  static const InterfaceFile *&
601  element(IO &IO, std::vector<const InterfaceFile *> &Seq, size_t Index) {
602  if (Index >= Seq.size())
603  Seq.resize(Index + 1);
604  return Seq[Index];
605  }
606 };
607 
608 } // end namespace yaml.
609 
610 namespace MachO {
611 static void DiagHandler(const SMDiagnostic &Diag, void *Context) {
612  auto *File = static_cast<TextAPIContext *>(Context);
613  SmallString<1024> Message;
614  raw_svector_ostream S(Message);
615 
616  SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), File->Path,
617  Diag.getLineNo(), Diag.getColumnNo(), Diag.getKind(),
618  Diag.getMessage(), Diag.getLineContents(),
619  Diag.getRanges(), Diag.getFixIts());
620 
621  NewDiag.print(nullptr, S);
622  File->ErrorMessage = ("malformed file\n" + Message).str();
623 }
624 
626 TextAPIReader::get(MemoryBufferRef InputBuffer) {
627  TextAPIContext Ctx;
628  Ctx.Path = InputBuffer.getBufferIdentifier();
629  yaml::Input YAMLIn(InputBuffer.getBuffer(), &Ctx, DiagHandler, &Ctx);
630 
631  // Fill vector with interface file objects created by parsing the YAML file.
632  std::vector<const InterfaceFile *> Files;
633  YAMLIn >> Files;
634 
635  // YAMLIn dynamically allocates for Interface file and in case of error,
636  // memory leak will occur unless wrapped around unique_ptr
637  auto File = std::unique_ptr<InterfaceFile>(
638  const_cast<InterfaceFile *>(Files.front()));
639 
640  if (YAMLIn.error())
641  return make_error<StringError>(Ctx.ErrorMessage, YAMLIn.error());
642 
643  return std::move(File);
644 }
645 
646 Error TextAPIWriter::writeToStream(raw_ostream &OS, const InterfaceFile &File) {
647  TextAPIContext Ctx;
648  Ctx.Path = File.getPath();
649  Ctx.FileKind = File.getFileType();
650  llvm::yaml::Output YAMLOut(OS, &Ctx, /*WrapColumn=*/80);
651 
652  std::vector<const InterfaceFile *> Files;
653  Files.emplace_back(&File);
654 
655  // Stream out yaml.
656  YAMLOut << Files;
657 
658  return Error::success();
659 }
660 
661 } // end namespace MachO.
662 } // end namespace llvm.
const NoneType None
Definition: None.h:23
FileType getFileType() const
Get the file type.
PlatformKind
Defines the list of MachO platforms.
Definition: InterfaceFile.h:35
#define LLVM_MARK_AS_BITMASK_ENUM(LargestValue)
LLVM_MARK_AS_BITMASK_ENUM lets you opt in an individual enum type so you can perform bitwise operatio...
Definition: BitmaskEnum.h:41
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:232
LLVMContext & Context
Defines the interface file.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
SMLoc getLoc() const
Definition: SourceMgr.h:287
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) const
Definition: SourceMgr.cpp:368
static void bitset(IO &IO, TBDFlags &Flags)
Definition: TextStub.cpp:235
Text-based stub file (.tbd) version 2.0.
Definition: InterfaceFile.h:73
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
NormalizedTBD(IO &IO, const InterfaceFile *&File)
Definition: TextStub.cpp:246
StringRef getName() const
Definition: Symbol.h:59
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:530
static size_t size(IO &IO, std::vector< const MachO::InterfaceFile *> &Seq)
Definition: TextStub.cpp:597
const InterfaceFile * denormalize(IO &IO)
Definition: TextStub.cpp:399
ArrayRef< SMFixIt > getFixIts() const
Definition: SourceMgr.h:300
const std::vector< std::pair< Architecture, std::string > > & uuids() const
Get the list of architecture/UUID pairs.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
const std::vector< InterfaceFileRef > & allowableClients() const
Get the list of allowable clients.
static void mapping(IO &IO, UndefinedSection &Section)
Definition: TextStub.cpp:219
Definition: BitVector.h:937
bool isWeakReferenced() const
Definition: Symbol.h:68
const std::vector< InterfaceFileRef > & reexportedLibraries() const
Get the list of re-exported libraries.
int getLineNo() const
Definition: SourceMgr.h:289
StringRef getBuffer() const
Definition: MemoryBuffer.h:272
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
Text-based stub file (.tbd) version 1.0.
Definition: InterfaceFile.h:70
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
Definition: TextStub.cpp:611
PlatformKind getPlatform() const
Get the platform.
StringRef getLineContents() const
Definition: SourceMgr.h:293
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:25
const_filtered_symbol_range exports() const
StringRef getPath() const
Get the path from which this file was generated (if applicable).
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:140
Instrumentation for Order File
bool isTwoLevelNamespace() const
Check if the library uses two-level namespace.
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:214
static void mapping(IO &IO, const InterfaceFile *&File)
Definition: TextStub.cpp:528
uint8_t getSwiftABIVersion() const
Get the Swift ABI version of the library.
Text-based stub file (.tbd) version 3.0.
Definition: InterfaceFile.h:76
bool isApplicationExtensionSafe() const
Check if the library is application extension safe.
bool isInstallAPI() const
Check if this file was generated during InstallAPI.
bool isThreadLocalValue() const
Definition: Symbol.h:72
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ObjCConstraintType
Defines a list of Objective-C constraints.
Definition: InterfaceFile.h:45
StringRef getInstallName() const
Get the install name of the library.
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1095
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
Architecture
Defines the architecture slices that are supported by Text-based Stub files.
Definition: Architecture.h:23
static void mapping(IO &IO, ExportSection &Section)
Definition: TextStub.cpp:197
StringRef getMessage() const
Definition: SourceMgr.h:292
ArrayRef< std::pair< unsigned, unsigned > > getRanges() const
Definition: SourceMgr.h:294
StringRef copyString(StringRef String)
Definition: TextStub.cpp:505
StringRef getBufferIdentifier() const
Definition: MemoryBuffer.h:274
SourceMgr::DiagKind getKind() const
Definition: SourceMgr.h:291
ArchitectureSet getArchitectures() const
Get the set of supported architectures.
int getColumnNo() const
Definition: SourceMgr.h:290
ObjCConstraintType getObjCConstraint() const
Get the Objective-C constraint.
ArchitectureSet getArchitectures() const
Definition: Symbol.h:60
std::vector< ExportSection > Exports
Definition: TextStub.cpp:524
PackedVersion getCompatibilityVersion() const
Get the compatibility version of the library.
static const InterfaceFile *& element(IO &IO, std::vector< const InterfaceFile *> &Seq, size_t Index)
Definition: TextStub.cpp:601
bool isWeakDefined() const
Definition: Symbol.h:64
SymbolKind getKind() const
Definition: Symbol.h:58
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
std::vector< UndefinedSection > Undefineds
Definition: TextStub.cpp:525
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
aarch64 promote const
TBDFlags
Definition: TextStub.cpp:179
StringRef getParentUmbrella() const
Get the parent umbrella framework.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
PackedVersion getCurrentVersion() const
Get the current version of the library.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
std::vector< Architecture > Architectures
Definition: TextStub.cpp:514
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
const SourceMgr * getSourceMgr() const
Definition: SourceMgr.h:286
const_filtered_symbol_range undefineds() const
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:261