1//===- llvm/TextAPI/RecordSlice.h - TAPI RecordSlice ------------*- C++ -*-===//
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/// \file
10/// \brief Implements the TAPI Record Collection Type.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TEXTAPI_RECORDSLICE_H
15#define LLVM_TEXTAPI_RECORDSLICE_H
16
17#include "llvm/Support/Allocator.h"
18#include "llvm/TextAPI/InterfaceFile.h"
19#include "llvm/TextAPI/PackedVersion.h"
20#include "llvm/TextAPI/Record.h"
21#include "llvm/TextAPI/RecordVisitor.h"
22
23namespace llvm {
24namespace MachO {
25
26// Define collection of records for a library that are tied to a darwin target
27// triple.
28class RecordsSlice {
29public:
30  RecordsSlice(const llvm::Triple &T) : TargetTriple(T), TAPITarget(T) {}
31  /// Get target triple.
32  const llvm::Triple &getTriple() const { return TargetTriple; }
33  /// Get TAPI converted target.
34  const Target &getTarget() const { return TAPITarget; }
35
36  /// Add unspecified record to slice.
37  ///
38  /// Assign specific record type based on properties and symbol name.
39  ///
40  /// \param Name The name of symbol.
41  /// \param Flags The flags that describe attributes of the symbol.
42  /// \param GV The kind of global, if this represents a non obj-c global
43  /// symbol.
44  /// \param Linkage The linkage of symbol.
45  /// \return The non-owning pointer to added record in slice.
46  Record *addRecord(StringRef Name, SymbolFlags Flags,
47                    GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown,
48                    RecordLinkage Linkage = RecordLinkage::Unknown);
49
50  /// Add non-ObjC global record.
51  ///
52  /// \param Name The name of symbol.
53  /// \param Flags The flags that describe attributes of the symbol.
54  /// \param GV The kind of global.
55  /// \param Linkage The linkage of symbol.
56  /// \return The non-owning pointer to added record in slice.
57  GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage,
58                          GlobalRecord::Kind GV,
59                          SymbolFlags Flags = SymbolFlags::None);
60
61  /// Add ObjC Class record.
62  ///
63  /// \param Name The name of class, not symbol.
64  /// \param Linkage The linkage of symbol.
65  /// \param HasEHType Whether symbol represents an eh_type.
66  /// \return The non-owning pointer to added record in slice.
67  ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage,
68                                        bool HasEHType = false);
69
70  /// Add ObjC IVar record.
71  ///
72  /// \param Name The name of ivar, not symbol.
73  /// \param Linkage The linkage of symbol.
74  /// \return The non-owning pointer to added record in slice.
75  ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container, StringRef Name,
76                              RecordLinkage Linkage);
77
78  /// Add ObjC Category record.
79  ///
80  /// \param ClassToExtend The name of class that is being extended by the
81  /// category, not symbol.
82  /// \param Category The name of category.
83  /// \return The non-owning pointer to added record in slice.
84  ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend,
85                                      StringRef Category);
86
87  /// Find ObjC Class.
88  ///
89  /// \param Name name of class, not full symbol name.
90  /// \return The non-owning pointer to record in slice.
91  ObjCInterfaceRecord *findObjCInterface(StringRef Name) const;
92
93  /// Find ObjC Category.
94  ///
95  /// \param ClassToExtend The name of class, not full symbol name.
96  /// \param Categories The name of category.
97  /// \return The non-owning pointer to record in slice.
98  ObjCCategoryRecord *findObjCCategory(StringRef ClassToExtend,
99                                       StringRef Category) const;
100
101  /// Find ObjC Container. This is commonly used for assigning for looking up
102  /// instance variables that are assigned to either a category or class.
103  ///
104  /// \param IsIVar If true, the name is the name of the IVar, otherwise it will
105  /// be looked up as the name of the container.
106  /// \param Name Either the name of ivar or name of container.
107  /// \return The non-owning pointer to record in
108  /// slice.
109  ObjCContainerRecord *findContainer(bool IsIVar, StringRef Name) const;
110
111  /// Find ObjC instance variable.
112  ///
113  /// \param IsScopedName This is used to determine how to parse the name.
114  /// \param Name Either the full name of the symbol or just the ivar.
115  /// \return The non-owning pointer to record in slice.
116  ObjCIVarRecord *findObjCIVar(bool IsScopedName, StringRef Name) const;
117
118  /// Find non-objc global.
119  ///
120  /// \param Name The name of symbol.
121  /// \param GV The Kind of global to find.
122  /// \return The non-owning pointer to record in slice.
123  GlobalRecord *
124  findGlobal(StringRef Name,
125             GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown) const;
126
127  // Determine if library attributes were assigned.
128  bool hasBinaryAttrs() const { return BA.get(); }
129
130  // Determine if record slice is unassigned.
131  bool empty() const {
132    return !hasBinaryAttrs() && Globals.empty() && Classes.empty() &&
133           Categories.empty();
134  }
135
136  // Visit all records known to RecordsSlice.
137  void visit(RecordVisitor &V) const;
138
139  struct BinaryAttrs {
140    std::vector<StringRef> AllowableClients;
141    std::vector<StringRef> RexportedLibraries;
142    std::vector<StringRef> RPaths;
143    StringRef ParentUmbrella;
144    StringRef InstallName;
145    StringRef UUID;
146    StringRef Path;
147    FileType File = FileType::Invalid;
148    llvm::MachO::PackedVersion CurrentVersion;
149    llvm::MachO::PackedVersion CompatVersion;
150    uint8_t SwiftABI = 0;
151    bool TwoLevelNamespace = false;
152    bool AppExtensionSafe = false;
153    bool OSLibNotForSharedCache = false;
154  };
155
156  /// Return reference to BinaryAttrs.
157  BinaryAttrs &getBinaryAttrs();
158
159  /// Store any strings owned by RecordSlice into allocator and return back
160  /// reference to that.
161  StringRef copyString(StringRef String);
162
163private:
164  const llvm::Triple TargetTriple;
165  // Hold tapi converted triple to avoid unecessary casts.
166  const Target TAPITarget;
167
168  /// BumpPtrAllocator to store generated/copied strings.
169  llvm::BumpPtrAllocator StringAllocator;
170
171  /// Promote linkage of requested record. It is no-op if linkage type is lower
172  /// than the current assignment.
173  ///
174  /// \param R The record to update.
175  /// \param L Linkage type to update to.
176  void updateLinkage(Record *R, RecordLinkage L) {
177    R->Linkage = std::max(R->Linkage, L);
178  }
179
180  /// Update set flags of requested record.
181  ///
182  /// \param R The global record to update.
183  /// \param F Flags to update to.
184  void updateFlags(GlobalRecord *R, SymbolFlags F) { R->Flags = F; }
185
186  RecordMap<GlobalRecord> Globals;
187  RecordMap<ObjCInterfaceRecord> Classes;
188  RecordMap<ObjCCategoryRecord, std::pair<StringRef, StringRef>> Categories;
189
190  std::unique_ptr<BinaryAttrs> BA{nullptr};
191};
192
193using Records = llvm::SmallVector<std::shared_ptr<RecordsSlice>, 4>;
194std::unique_ptr<InterfaceFile> convertToInterfaceFile(const Records &Slices);
195
196} // namespace MachO
197} // namespace llvm
198#endif // LLVM_TEXTAPI_RECORDSLICE_H
199