1//===- TapiUniversal.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// This file defines the Text-based Dynamic Library Stub format.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/Object/TapiUniversal.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Object/TapiFile.h"
16#include "llvm/TextAPI/TextAPIReader.h"
17
18using namespace llvm;
19using namespace MachO;
20using namespace object;
21
22TapiUniversal::TapiUniversal(MemoryBufferRef Source, bool SkipUnknownTriples,
23 Error &Err)
24 : Binary(ID_TapiUniversal, Source) {
25 Expected<std::unique_ptr<InterfaceFile>> Result =
26 TextAPIReader::get(InputBuffer: Source, SkipUnknownTriples);
27 ErrorAsOutParameter ErrAsOuParam(Err);
28 if (!Result) {
29 Err = Result.takeError();
30 return;
31 }
32 ParsedFile = std::move(Result.get());
33
34 auto FlattenObjectInfo = [this](const auto &File,
35 std::optional<size_t> DocIdx = std::nullopt) {
36 StringRef Name = File->getInstallName();
37 for (const Architecture Arch : File->getArchitectures())
38 Libraries.emplace_back(args: Library({.InstallName: Name, .Arch: Arch, .DocumentIdx: DocIdx}));
39 };
40 FlattenObjectInfo(ParsedFile);
41 // Get inlined documents from tapi file.
42 size_t DocIdx = 0;
43 for (const std::shared_ptr<InterfaceFile> &File : ParsedFile->documents())
44 FlattenObjectInfo(File, DocIdx++);
45}
46
47TapiUniversal::~TapiUniversal() = default;
48
49Expected<std::unique_ptr<TapiFile>>
50TapiUniversal::ObjectForArch::getAsObjectFile() const {
51 const auto &InlinedDocuments = Parent->ParsedFile->documents();
52 const Library &CurrLib = Parent->Libraries[Index];
53 assert(
54 (isTopLevelLib() || (CurrLib.DocumentIdx.has_value() &&
55 (InlinedDocuments.size() > *CurrLib.DocumentIdx))) &&
56 "Index into documents exceeds the container for them");
57 InterfaceFile *IF = isTopLevelLib()
58 ? Parent->ParsedFile.get()
59 : InlinedDocuments[*CurrLib.DocumentIdx].get();
60 return std::make_unique<TapiFile>(args: Parent->getMemoryBufferRef(), args&: *IF,
61 args: CurrLib.Arch);
62}
63
64Expected<std::unique_ptr<TapiUniversal>>
65TapiUniversal::create(MemoryBufferRef Source, bool SkipUnknownTriples) {
66 Error Err = Error::success();
67 std::unique_ptr<TapiUniversal> Ret(
68 new TapiUniversal(Source, SkipUnknownTriples, Err));
69 if (Err)
70 return std::move(Err);
71 return std::move(Ret);
72}
73