1 //===- llvm/TextAPI/TextStub.cpp - Text Stub --------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Implements the text stub file reader/writer.
13 //===----------------------------------------------------------------------===//
15 #include "TextAPIContext.h"
16 #include "TextStubCommon.h"
17 #include "llvm/ADT/BitmaskEnum.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/Allocator.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "llvm/Support/YAMLTraits.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include "llvm/TextAPI/MachO/Architecture.h"
25 #include "llvm/TextAPI/MachO/ArchitectureSet.h"
26 #include "llvm/TextAPI/MachO/InterfaceFile.h"
27 #include "llvm/TextAPI/MachO/PackedVersion.h"
28 #include "llvm/TextAPI/MachO/TextAPIReader.h"
29 #include "llvm/TextAPI/MachO/TextAPIWriter.h"
36 YAML Format specification.
38 The TBD v1 format only support two level address libraries and is per
39 definition application extension safe.
41 --- # the tag !tapi-tbd-v1 is optional and
42 # shouldn't be emitted to support older linker.
43 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
44 # supported by this file.
45 platform: ios # Specifies the platform (macosx, ios, etc)
46 install-name: /u/l/libfoo.dylib #
47 current-version: 1.2.3 # Optional: defaults to 1.0
48 compatibility-version: 1.0 # Optional: defaults to 1.0
49 swift-version: 0 # Optional: defaults to 0
50 objc-constraint: none # Optional: defaults to none
51 exports: # List of export sections
54 Each export section is defined as following:
56 - archs: [ arm64 ] # the list of architecture slices
57 allowed-clients: [ client ] # Optional: List of clients
58 re-exports: [ ] # Optional: List of re-exports
59 symbols: [ _sym ] # Optional: List of symbols
60 objc-classes: [] # Optional: List of Objective-C classes
61 objc-ivars: [] # Optional: List of Objective C Instance
63 weak-def-symbols: [] # Optional: List of weak defined symbols
64 thread-local-symbols: [] # Optional: List of thread local symbols
69 YAML Format specification.
72 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
73 # supported by this file.
74 uuids: [ armv7:... ] # Optional: List of architecture and UUID pairs.
75 platform: ios # Specifies the platform (macosx, ios, etc)
77 install-name: /u/l/libfoo.dylib #
78 current-version: 1.2.3 # Optional: defaults to 1.0
79 compatibility-version: 1.0 # Optional: defaults to 1.0
80 swift-version: 0 # Optional: defaults to 0
81 objc-constraint: retain_release # Optional: defaults to retain_release
82 parent-umbrella: # Optional:
83 exports: # List of export sections
85 undefineds: # List of undefineds sections
88 Each export section is defined as following:
90 - archs: [ arm64 ] # the list of architecture slices
91 allowed-clients: [ client ] # Optional: List of clients
92 re-exports: [ ] # Optional: List of re-exports
93 symbols: [ _sym ] # Optional: List of symbols
94 objc-classes: [] # Optional: List of Objective-C classes
95 objc-ivars: [] # Optional: List of Objective C Instance
97 weak-def-symbols: [] # Optional: List of weak defined symbols
98 thread-local-symbols: [] # Optional: List of thread local symbols
100 Each undefineds section is defined as following:
101 - archs: [ arm64 ] # the list of architecture slices
102 symbols: [ _sym ] # Optional: List of symbols
103 objc-classes: [] # Optional: List of Objective-C classes
104 objc-ivars: [] # Optional: List of Objective C Instance Variables
105 weak-ref-symbols: [] # Optional: List of weak defined symbols
110 YAML Format specification.
113 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
114 # supported by this file.
115 uuids: [ armv7:... ] # Optional: List of architecture and UUID pairs.
116 platform: ios # Specifies the platform (macosx, ios, etc)
117 flags: [] # Optional:
118 install-name: /u/l/libfoo.dylib #
119 current-version: 1.2.3 # Optional: defaults to 1.0
120 compatibility-version: 1.0 # Optional: defaults to 1.0
121 swift-abi-version: 0 # Optional: defaults to 0
122 objc-constraint: retain_release # Optional: defaults to retain_release
123 parent-umbrella: # Optional:
124 exports: # List of export sections
126 undefineds: # List of undefineds sections
129 Each export section is defined as following:
131 - archs: [ arm64 ] # the list of architecture slices
132 allowed-clients: [ client ] # Optional: List of clients
133 re-exports: [ ] # Optional: List of re-exports
134 symbols: [ _sym ] # Optional: List of symbols
135 objc-classes: [] # Optional: List of Objective-C classes
136 objc-eh-types: [] # Optional: List of Objective-C classes
138 objc-ivars: [] # Optional: List of Objective C Instance
140 weak-def-symbols: [] # Optional: List of weak defined symbols
141 thread-local-symbols: [] # Optional: List of thread local symbols
143 Each undefineds section is defined as following:
144 - archs: [ arm64 ] # the list of architecture slices
145 symbols: [ _sym ] # Optional: List of symbols
146 objc-classes: [] # Optional: List of Objective-C classes
147 objc-eh-types: [] # Optional: List of Objective-C classes
149 objc-ivars: [] # Optional: List of Objective C Instance Variables
150 weak-ref-symbols: [] # Optional: List of weak defined symbols
154 using namespace llvm;
155 using namespace llvm::yaml;
156 using namespace llvm::MachO;
159 struct ExportSection {
160 std::vector<Architecture> Architectures;
161 std::vector<FlowStringRef> AllowableClients;
162 std::vector<FlowStringRef> ReexportedLibraries;
163 std::vector<FlowStringRef> Symbols;
164 std::vector<FlowStringRef> Classes;
165 std::vector<FlowStringRef> ClassEHs;
166 std::vector<FlowStringRef> IVars;
167 std::vector<FlowStringRef> WeakDefSymbols;
168 std::vector<FlowStringRef> TLVSymbols;
171 struct UndefinedSection {
172 std::vector<Architecture> Architectures;
173 std::vector<FlowStringRef> Symbols;
174 std::vector<FlowStringRef> Classes;
175 std::vector<FlowStringRef> ClassEHs;
176 std::vector<FlowStringRef> IVars;
177 std::vector<FlowStringRef> WeakRefSymbols;
181 enum TBDFlags : unsigned {
183 FlatNamespace = 1U << 0,
184 NotApplicationExtensionSafe = 1U << 1,
185 InstallAPI = 1U << 2,
186 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/InstallAPI),
189 } // end anonymous namespace.
191 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(Architecture)
192 LLVM_YAML_IS_SEQUENCE_VECTOR(ExportSection)
193 LLVM_YAML_IS_SEQUENCE_VECTOR(UndefinedSection)
198 template <> struct MappingTraits<ExportSection> {
199 static void mapping(IO &IO, ExportSection &Section) {
200 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
201 assert((!Ctx || (Ctx && Ctx->FileKind != FileType::Invalid)) &&
202 "File type is not set in YAML context");
204 IO.mapRequired("archs", Section.Architectures);
205 if (Ctx->FileKind == FileType::TBD_V1)
206 IO.mapOptional("allowed-clients", Section.AllowableClients);
208 IO.mapOptional("allowable-clients", Section.AllowableClients);
209 IO.mapOptional("re-exports", Section.ReexportedLibraries);
210 IO.mapOptional("symbols", Section.Symbols);
211 IO.mapOptional("objc-classes", Section.Classes);
212 if (Ctx->FileKind == FileType::TBD_V3)
213 IO.mapOptional("objc-eh-types", Section.ClassEHs);
214 IO.mapOptional("objc-ivars", Section.IVars);
215 IO.mapOptional("weak-def-symbols", Section.WeakDefSymbols);
216 IO.mapOptional("thread-local-symbols", Section.TLVSymbols);
220 template <> struct MappingTraits<UndefinedSection> {
221 static void mapping(IO &IO, UndefinedSection &Section) {
222 const auto *Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
223 assert((!Ctx || (Ctx && Ctx->FileKind != FileType::Invalid)) &&
224 "File type is not set in YAML context");
226 IO.mapRequired("archs", Section.Architectures);
227 IO.mapOptional("symbols", Section.Symbols);
228 IO.mapOptional("objc-classes", Section.Classes);
229 if (Ctx->FileKind == FileType::TBD_V3)
230 IO.mapOptional("objc-eh-types", Section.ClassEHs);
231 IO.mapOptional("objc-ivars", Section.IVars);
232 IO.mapOptional("weak-ref-symbols", Section.WeakRefSymbols);
236 template <> struct ScalarBitSetTraits<TBDFlags> {
237 static void bitset(IO &IO, TBDFlags &Flags) {
238 IO.bitSetCase(Flags, "flat_namespace", TBDFlags::FlatNamespace);
239 IO.bitSetCase(Flags, "not_app_extension_safe",
240 TBDFlags::NotApplicationExtensionSafe);
241 IO.bitSetCase(Flags, "installapi", TBDFlags::InstallAPI);
245 template <> struct MappingTraits<const InterfaceFile *> {
246 struct NormalizedTBD {
247 explicit NormalizedTBD(IO &IO) {}
248 NormalizedTBD(IO &IO, const InterfaceFile *&File) {
249 Architectures = File->getArchitectures();
250 UUIDs = File->uuids();
251 Platform = File->getPlatform();
252 InstallName = File->getInstallName();
253 CurrentVersion = PackedVersion(File->getCurrentVersion());
254 CompatibilityVersion = PackedVersion(File->getCompatibilityVersion());
255 SwiftABIVersion = File->getSwiftABIVersion();
256 ObjCConstraint = File->getObjCConstraint();
258 Flags = TBDFlags::None;
259 if (!File->isApplicationExtensionSafe())
260 Flags |= TBDFlags::NotApplicationExtensionSafe;
262 if (!File->isTwoLevelNamespace())
263 Flags |= TBDFlags::FlatNamespace;
265 if (File->isInstallAPI())
266 Flags |= TBDFlags::InstallAPI;
268 ParentUmbrella = File->getParentUmbrella();
270 std::set<ArchitectureSet> ArchSet;
271 for (const auto &Library : File->allowableClients())
272 ArchSet.insert(Library.getArchitectures());
274 for (const auto &Library : File->reexportedLibraries())
275 ArchSet.insert(Library.getArchitectures());
277 std::map<const Symbol *, ArchitectureSet> SymbolToArchSet;
278 for (const auto *Symbol : File->exports()) {
279 auto Architectures = Symbol->getArchitectures();
280 SymbolToArchSet[Symbol] = Architectures;
281 ArchSet.insert(Architectures);
284 for (auto Architectures : ArchSet) {
285 ExportSection Section;
286 Section.Architectures = Architectures;
288 for (const auto &Library : File->allowableClients())
289 if (Library.getArchitectures() == Architectures)
290 Section.AllowableClients.emplace_back(Library.getInstallName());
292 for (const auto &Library : File->reexportedLibraries())
293 if (Library.getArchitectures() == Architectures)
294 Section.ReexportedLibraries.emplace_back(Library.getInstallName());
296 for (const auto &SymArch : SymbolToArchSet) {
297 if (SymArch.second != Architectures)
300 const auto *Symbol = SymArch.first;
301 switch (Symbol->getKind()) {
302 case SymbolKind::GlobalSymbol:
303 if (Symbol->isWeakDefined())
304 Section.WeakDefSymbols.emplace_back(Symbol->getName());
305 else if (Symbol->isThreadLocalValue())
306 Section.TLVSymbols.emplace_back(Symbol->getName());
308 Section.Symbols.emplace_back(Symbol->getName());
310 case SymbolKind::ObjectiveCClass:
311 if (File->getFileType() != FileType::TBD_V3)
312 Section.Classes.emplace_back(
313 copyString("_" + Symbol->getName().str()));
315 Section.Classes.emplace_back(Symbol->getName());
317 case SymbolKind::ObjectiveCClassEHType:
318 if (File->getFileType() != FileType::TBD_V3)
319 Section.Symbols.emplace_back(
320 copyString("_OBJC_EHTYPE_$_" + Symbol->getName().str()));
322 Section.ClassEHs.emplace_back(Symbol->getName());
324 case SymbolKind::ObjectiveCInstanceVariable:
325 if (File->getFileType() != FileType::TBD_V3)
326 Section.IVars.emplace_back(
327 copyString("_" + Symbol->getName().str()));
329 Section.IVars.emplace_back(Symbol->getName());
333 llvm::sort(Section.Symbols.begin(), Section.Symbols.end());
334 llvm::sort(Section.Classes.begin(), Section.Classes.end());
335 llvm::sort(Section.ClassEHs.begin(), Section.ClassEHs.end());
336 llvm::sort(Section.IVars.begin(), Section.IVars.end());
337 llvm::sort(Section.WeakDefSymbols.begin(),
338 Section.WeakDefSymbols.end());
339 llvm::sort(Section.TLVSymbols.begin(), Section.TLVSymbols.end());
340 Exports.emplace_back(std::move(Section));
344 SymbolToArchSet.clear();
346 for (const auto *Symbol : File->undefineds()) {
347 auto Architectures = Symbol->getArchitectures();
348 SymbolToArchSet[Symbol] = Architectures;
349 ArchSet.insert(Architectures);
352 for (auto Architectures : ArchSet) {
353 UndefinedSection Section;
354 Section.Architectures = Architectures;
356 for (const auto &SymArch : SymbolToArchSet) {
357 if (SymArch.second != Architectures)
360 const auto *Symbol = SymArch.first;
361 switch (Symbol->getKind()) {
362 case SymbolKind::GlobalSymbol:
363 if (Symbol->isWeakReferenced())
364 Section.WeakRefSymbols.emplace_back(Symbol->getName());
366 Section.Symbols.emplace_back(Symbol->getName());
368 case SymbolKind::ObjectiveCClass:
369 if (File->getFileType() != FileType::TBD_V3)
370 Section.Classes.emplace_back(
371 copyString("_" + Symbol->getName().str()));
373 Section.Classes.emplace_back(Symbol->getName());
375 case SymbolKind::ObjectiveCClassEHType:
376 if (File->getFileType() != FileType::TBD_V3)
377 Section.Symbols.emplace_back(
378 copyString("_OBJC_EHTYPE_$_" + Symbol->getName().str()));
380 Section.ClassEHs.emplace_back(Symbol->getName());
382 case SymbolKind::ObjectiveCInstanceVariable:
383 if (File->getFileType() != FileType::TBD_V3)
384 Section.IVars.emplace_back(
385 copyString("_" + Symbol->getName().str()));
387 Section.IVars.emplace_back(Symbol->getName());
391 llvm::sort(Section.Symbols.begin(), Section.Symbols.end());
392 llvm::sort(Section.Classes.begin(), Section.Classes.end());
393 llvm::sort(Section.ClassEHs.begin(), Section.ClassEHs.end());
394 llvm::sort(Section.IVars.begin(), Section.IVars.end());
395 llvm::sort(Section.WeakRefSymbols.begin(),
396 Section.WeakRefSymbols.end());
397 Undefineds.emplace_back(std::move(Section));
401 const InterfaceFile *denormalize(IO &IO) {
402 auto Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
405 auto *File = new InterfaceFile;
406 File->setPath(Ctx->Path);
407 File->setFileType(Ctx->FileKind);
408 for (auto &ID : UUIDs)
409 File->addUUID(ID.first, ID.second);
410 File->setPlatform(Platform);
411 File->setArchitectures(Architectures);
412 File->setInstallName(InstallName);
413 File->setCurrentVersion(CurrentVersion);
414 File->setCompatibilityVersion(CompatibilityVersion);
415 File->setSwiftABIVersion(SwiftABIVersion);
416 File->setObjCConstraint(ObjCConstraint);
417 File->setParentUmbrella(ParentUmbrella);
419 if (Ctx->FileKind == FileType::TBD_V1) {
420 File->setTwoLevelNamespace();
421 File->setApplicationExtensionSafe();
423 File->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace));
424 File->setApplicationExtensionSafe(
425 !(Flags & TBDFlags::NotApplicationExtensionSafe));
426 File->setInstallAPI(Flags & TBDFlags::InstallAPI);
429 for (const auto &Section : Exports) {
430 for (const auto &Library : Section.AllowableClients)
431 File->addAllowableClient(Library, Section.Architectures);
432 for (const auto &Library : Section.ReexportedLibraries)
433 File->addReexportedLibrary(Library, Section.Architectures);
435 for (const auto &Symbol : Section.Symbols) {
436 if (Ctx->FileKind != FileType::TBD_V3 &&
437 Symbol.value.startswith("_OBJC_EHTYPE_$_"))
438 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
439 Symbol.value.drop_front(15), Section.Architectures);
441 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
442 Section.Architectures);
444 for (auto &Symbol : Section.Classes) {
445 auto Name = Symbol.value;
446 if (Ctx->FileKind != FileType::TBD_V3)
447 Name = Name.drop_front();
448 File->addSymbol(SymbolKind::ObjectiveCClass, Name,
449 Section.Architectures);
451 for (auto &Symbol : Section.ClassEHs)
452 File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
453 Section.Architectures);
454 for (auto &Symbol : Section.IVars) {
455 auto Name = Symbol.value;
456 if (Ctx->FileKind != FileType::TBD_V3)
457 Name = Name.drop_front();
458 File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
459 Section.Architectures);
461 for (auto &Symbol : Section.WeakDefSymbols)
462 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
463 Section.Architectures, SymbolFlags::WeakDefined);
464 for (auto &Symbol : Section.TLVSymbols)
465 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
466 Section.Architectures, SymbolFlags::ThreadLocalValue);
469 for (const auto &Section : Undefineds) {
470 for (auto &Symbol : Section.Symbols) {
471 if (Ctx->FileKind != FileType::TBD_V3 &&
472 Symbol.value.startswith("_OBJC_EHTYPE_$_"))
473 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
474 Symbol.value.drop_front(15), Section.Architectures,
475 SymbolFlags::Undefined);
477 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
478 Section.Architectures, SymbolFlags::Undefined);
480 for (auto &Symbol : Section.Classes) {
481 auto Name = Symbol.value;
482 if (Ctx->FileKind != FileType::TBD_V3)
483 Name = Name.drop_front();
484 File->addSymbol(SymbolKind::ObjectiveCClass, Name,
485 Section.Architectures, SymbolFlags::Undefined);
487 for (auto &Symbol : Section.ClassEHs)
488 File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
489 Section.Architectures, SymbolFlags::Undefined);
490 for (auto &Symbol : Section.IVars) {
491 auto Name = Symbol.value;
492 if (Ctx->FileKind != FileType::TBD_V3)
493 Name = Name.drop_front();
494 File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
495 Section.Architectures, SymbolFlags::Undefined);
497 for (auto &Symbol : Section.WeakRefSymbols)
498 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
499 Section.Architectures,
500 SymbolFlags::Undefined | SymbolFlags::WeakReferenced);
506 llvm::BumpPtrAllocator Allocator;
507 StringRef copyString(StringRef String) {
511 void *Ptr = Allocator.Allocate(String.size(), 1);
512 memcpy(Ptr, String.data(), String.size());
513 return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
516 std::vector<Architecture> Architectures;
517 std::vector<UUID> UUIDs;
518 PlatformKind Platform{PlatformKind::unknown};
519 StringRef InstallName;
520 PackedVersion CurrentVersion;
521 PackedVersion CompatibilityVersion;
522 SwiftVersion SwiftABIVersion{0};
523 ObjCConstraintType ObjCConstraint{ObjCConstraintType::None};
524 TBDFlags Flags{TBDFlags::None};
525 StringRef ParentUmbrella;
526 std::vector<ExportSection> Exports;
527 std::vector<UndefinedSection> Undefineds;
530 static void mapping(IO &IO, const InterfaceFile *&File) {
531 auto *Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
532 assert((!Ctx || !IO.outputting() ||
533 (Ctx && Ctx->FileKind != FileType::Invalid)) &&
534 "File type is not set in YAML context");
535 MappingNormalization<NormalizedTBD, const InterfaceFile *> Keys(IO, File);
537 // prope file type when reading.
538 if (!IO.outputting()) {
539 if (IO.mapTag("!tapi-tbd-v2", false))
540 Ctx->FileKind = FileType::TBD_V2;
541 else if (IO.mapTag("!tapi-tbd-v3", false))
542 Ctx->FileKind = FileType::TBD_V2;
543 else if (IO.mapTag("!tapi-tbd-v1", false) ||
544 IO.mapTag("tag:yaml.org,2002:map", false))
545 Ctx->FileKind = FileType::TBD_V1;
547 IO.setError("unsupported file type");
552 // Set file tyoe when writing.
553 if (IO.outputting()) {
554 switch (Ctx->FileKind) {
556 llvm_unreachable("unexpected file type");
557 case FileType::TBD_V1:
558 // Don't write the tag into the .tbd file for TBD v1.
560 case FileType::TBD_V2:
561 IO.mapTag("!tapi-tbd-v2", true);
563 case FileType::TBD_V3:
564 IO.mapTag("!tapi-tbd-v3", true);
569 IO.mapRequired("archs", Keys->Architectures);
570 if (Ctx->FileKind != FileType::TBD_V1)
571 IO.mapOptional("uuids", Keys->UUIDs);
572 IO.mapRequired("platform", Keys->Platform);
573 if (Ctx->FileKind != FileType::TBD_V1)
574 IO.mapOptional("flags", Keys->Flags, TBDFlags::None);
575 IO.mapRequired("install-name", Keys->InstallName);
576 IO.mapOptional("current-version", Keys->CurrentVersion,
577 PackedVersion(1, 0, 0));
578 IO.mapOptional("compatibility-version", Keys->CompatibilityVersion,
579 PackedVersion(1, 0, 0));
580 if (Ctx->FileKind != FileType::TBD_V3)
581 IO.mapOptional("swift-version", Keys->SwiftABIVersion, SwiftVersion(0));
583 IO.mapOptional("swift-abi-version", Keys->SwiftABIVersion,
585 IO.mapOptional("objc-constraint", Keys->ObjCConstraint,
586 (Ctx->FileKind == FileType::TBD_V1)
587 ? ObjCConstraintType::None
588 : ObjCConstraintType::Retain_Release);
589 if (Ctx->FileKind != FileType::TBD_V1)
590 IO.mapOptional("parent-umbrella", Keys->ParentUmbrella, StringRef());
591 IO.mapOptional("exports", Keys->Exports);
592 if (Ctx->FileKind != FileType::TBD_V1)
593 IO.mapOptional("undefineds", Keys->Undefineds);
598 struct DocumentListTraits<std::vector<const MachO::InterfaceFile *>> {
599 static size_t size(IO &IO, std::vector<const MachO::InterfaceFile *> &Seq) {
602 static const InterfaceFile *&
603 element(IO &IO, std::vector<const InterfaceFile *> &Seq, size_t Index) {
604 if (Index >= Seq.size())
605 Seq.resize(Index + 1);
610 } // end namespace yaml.
613 static void DiagHandler(const SMDiagnostic &Diag, void *Context) {
614 auto *File = static_cast<TextAPIContext *>(Context);
615 SmallString<1024> Message;
616 raw_svector_ostream S(Message);
618 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), File->Path,
619 Diag.getLineNo(), Diag.getColumnNo(), Diag.getKind(),
620 Diag.getMessage(), Diag.getLineContents(),
621 Diag.getRanges(), Diag.getFixIts());
623 NewDiag.print(nullptr, S);
624 File->ErrorMessage = ("malformed file\n" + Message).str();
627 Expected<std::unique_ptr<InterfaceFile>>
628 TextAPIReader::get(std::unique_ptr<MemoryBuffer> InputBuffer) {
630 Ctx.Path = InputBuffer->getBufferIdentifier();
631 yaml::Input YAMLIn(InputBuffer->getBuffer(), &Ctx, DiagHandler, &Ctx);
633 // Fill vector with interface file objects created by parsing the YAML file.
634 std::vector<const InterfaceFile *> Files;
638 return make_error<StringError>(Ctx.ErrorMessage, YAMLIn.error());
640 auto *File = const_cast<InterfaceFile *>(Files.front());
641 return std::unique_ptr<InterfaceFile>(File);
644 Error TextAPIWriter::writeToStream(raw_ostream &OS, const InterfaceFile &File) {
646 Ctx.Path = File.getPath();
647 Ctx.FileKind = File.getFileType();
648 llvm::yaml::Output YAMLOut(OS, &Ctx, /*WrapColumn=*/80);
650 std::vector<const InterfaceFile *> Files;
651 Files.emplace_back(&File);
656 return Error::success();
659 } // end namespace MachO.
660 } // end namespace llvm.