1 //===- InterfaceFile.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 Interface File. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/TextAPI/InterfaceFile.h" 14 #include <iomanip> 15 #include <sstream> 16 17 using namespace llvm; 18 using namespace llvm::MachO; 19 20 void InterfaceFileRef::addTarget(const Target &Target) { 21 addEntry(Targets, Target); 22 } 23 24 void InterfaceFile::addAllowableClient(StringRef InstallName, 25 const Target &Target) { 26 auto Client = addEntry(AllowableClients, InstallName); 27 Client->addTarget(Target); 28 } 29 30 void InterfaceFile::addReexportedLibrary(StringRef InstallName, 31 const Target &Target) { 32 auto Lib = addEntry(ReexportedLibraries, InstallName); 33 Lib->addTarget(Target); 34 } 35 36 void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) { 37 auto Iter = lower_bound(ParentUmbrellas, Target_, 38 [](const std::pair<Target, std::string> &LHS, 39 Target RHS) { return LHS.first < RHS; }); 40 41 if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) { 42 Iter->second = std::string(Parent); 43 return; 44 } 45 46 ParentUmbrellas.emplace(Iter, Target_, std::string(Parent)); 47 } 48 49 void InterfaceFile::addRPath(const Target &InputTarget, StringRef RPath) { 50 auto Iter = lower_bound(RPaths, InputTarget, 51 [](const std::pair<Target, std::string> &LHS, 52 Target RHS) { return LHS.first < RHS; }); 53 54 if ((Iter != RPaths.end()) && !(InputTarget < Iter->first)) { 55 Iter->second = std::string(RPath); 56 return; 57 } 58 59 RPaths.emplace(Iter, InputTarget, std::string(RPath)); 60 } 61 62 void InterfaceFile::addTarget(const Target &Target) { 63 addEntry(Targets, Target); 64 } 65 66 InterfaceFile::const_filtered_target_range 67 InterfaceFile::targets(ArchitectureSet Archs) const { 68 std::function<bool(const Target &)> fn = [Archs](const Target &Target_) { 69 return Archs.has(Target_.Arch); 70 }; 71 return make_filter_range(Targets, fn); 72 } 73 74 void InterfaceFile::addDocument(std::shared_ptr<InterfaceFile> &&Document) { 75 auto Pos = llvm::lower_bound(Documents, Document, 76 [](const std::shared_ptr<InterfaceFile> &LHS, 77 const std::shared_ptr<InterfaceFile> &RHS) { 78 return LHS->InstallName < RHS->InstallName; 79 }); 80 Document->Parent = this; 81 Documents.insert(Pos, Document); 82 } 83 84 static bool isYAMLTextStub(const FileType &Kind) { 85 return (Kind >= FileType::TBD_V1) && (Kind < FileType::TBD_V5); 86 } 87 88 bool InterfaceFile::operator==(const InterfaceFile &O) const { 89 if (Targets != O.Targets) 90 return false; 91 if (InstallName != O.InstallName) 92 return false; 93 if ((CurrentVersion != O.CurrentVersion) || 94 (CompatibilityVersion != O.CompatibilityVersion)) 95 return false; 96 if (SwiftABIVersion != O.SwiftABIVersion) 97 return false; 98 if (IsTwoLevelNamespace != O.IsTwoLevelNamespace) 99 return false; 100 if (IsAppExtensionSafe != O.IsAppExtensionSafe) 101 return false; 102 if (ParentUmbrellas != O.ParentUmbrellas) 103 return false; 104 if (AllowableClients != O.AllowableClients) 105 return false; 106 if (ReexportedLibraries != O.ReexportedLibraries) 107 return false; 108 if (*SymbolsSet != *O.SymbolsSet) 109 return false; 110 // Don't compare run search paths for older filetypes that cannot express 111 // them. 112 if (!(isYAMLTextStub(FileKind)) && !(isYAMLTextStub(O.FileKind))) { 113 if (RPaths != O.RPaths) 114 return false; 115 if (mapToPlatformVersionSet(Targets) != mapToPlatformVersionSet(O.Targets)) 116 return false; 117 } 118 119 if (!std::equal(Documents.begin(), Documents.end(), O.Documents.begin(), 120 O.Documents.end(), 121 [](const std::shared_ptr<InterfaceFile> LHS, 122 const std::shared_ptr<InterfaceFile> RHS) { 123 return *LHS == *RHS; 124 })) 125 return false; 126 return true; 127 } 128