xref: /freebsd/contrib/llvm-project/llvm/lib/TextAPI/InterfaceFile.cpp (revision adfed2d835a7f9382941896d15a487dac6fe659c)
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