summaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm18/include/llvm/TextAPI/RecordsSlice.h
blob: e6a09c062bb6054bbbc86532d582793ea7b35f1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

//===- llvm/TextAPI/RecordSlice.h - TAPI RecordSlice ------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implements the TAPI Record Collection Type.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_TEXTAPI_RECORDSLICE_H
#define LLVM_TEXTAPI_RECORDSLICE_H

#include "llvm/Support/Allocator.h"
#include "llvm/TextAPI/InterfaceFile.h"
#include "llvm/TextAPI/PackedVersion.h"
#include "llvm/TextAPI/Record.h"
#include "llvm/TextAPI/RecordVisitor.h"

namespace llvm {
namespace MachO {

// Define collection of records for a library that are tied to a darwin target
// triple.
class RecordsSlice {
public:
  RecordsSlice(const llvm::Triple &T) : TargetTriple(T), TAPITarget(T) {}
  /// Get target triple.
  const llvm::Triple &getTriple() const { return TargetTriple; }
  /// Get TAPI converted target.
  const Target &getTarget() const { return TAPITarget; }

  /// Add unspecified record to slice.
  ///
  /// Assign specific record type based on properties and symbol name.
  ///
  /// \param Name The name of symbol.
  /// \param Flags The flags that describe attributes of the symbol.
  /// \param GV The kind of global, if this represents a non obj-c global
  /// symbol.
  /// \param Linkage The linkage of symbol.
  /// \return The non-owning pointer to added record in slice.
  Record *addRecord(StringRef Name, SymbolFlags Flags,
                    GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown,
                    RecordLinkage Linkage = RecordLinkage::Unknown);

  /// Add non-ObjC global record.
  ///
  /// \param Name The name of symbol.
  /// \param Flags The flags that describe attributes of the symbol.
  /// \param GV The kind of global.
  /// \param Linkage The linkage of symbol.
  /// \return The non-owning pointer to added record in slice.
  GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage,
                          GlobalRecord::Kind GV,
                          SymbolFlags Flags = SymbolFlags::None);

  /// Add ObjC Class record.
  ///
  /// \param Name The name of class, not symbol.
  /// \param Linkage The linkage of symbol.
  /// \param HasEHType Whether symbol represents an eh_type.
  /// \return The non-owning pointer to added record in slice.
  ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage,
                                        bool HasEHType = false);

  /// Add ObjC IVar record.
  ///
  /// \param Name The name of ivar, not symbol.
  /// \param Linkage The linkage of symbol.
  /// \return The non-owning pointer to added record in slice.
  ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container, StringRef Name,
                              RecordLinkage Linkage);

  /// Add ObjC Category record.
  ///
  /// \param ClassToExtend The name of class that is being extended by the
  /// category, not symbol.
  /// \param Category The name of category.
  /// \return The non-owning pointer to added record in slice.
  ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend,
                                      StringRef Category);

  /// Find ObjC Class.
  ///
  /// \param Name name of class, not full symbol name.
  /// \return The non-owning pointer to record in slice.
  ObjCInterfaceRecord *findObjCInterface(StringRef Name) const;

  /// Find ObjC Category.
  ///
  /// \param ClassToExtend The name of class, not full symbol name.
  /// \param Categories The name of category.
  /// \return The non-owning pointer to record in slice.
  ObjCCategoryRecord *findObjCCategory(StringRef ClassToExtend,
                                       StringRef Category) const;

  /// Find ObjC Container. This is commonly used for assigning for looking up
  /// instance variables that are assigned to either a category or class.
  ///
  /// \param IsIVar If true, the name is the name of the IVar, otherwise it will
  /// be looked up as the name of the container.
  /// \param Name Either the name of ivar or name of container.
  /// \return The non-owning pointer to record in
  /// slice.
  ObjCContainerRecord *findContainer(bool IsIVar, StringRef Name) const;

  /// Find ObjC instance variable.
  ///
  /// \param IsScopedName This is used to determine how to parse the name.
  /// \param Name Either the full name of the symbol or just the ivar.
  /// \return The non-owning pointer to record in slice.
  ObjCIVarRecord *findObjCIVar(bool IsScopedName, StringRef Name) const;

  /// Find non-objc global.
  ///
  /// \param Name The name of symbol.
  /// \param GV The Kind of global to find.
  /// \return The non-owning pointer to record in slice.
  GlobalRecord *
  findGlobal(StringRef Name,
             GlobalRecord::Kind GV = GlobalRecord::Kind::Unknown) const;

  // Determine if library attributes were assigned.
  bool hasBinaryAttrs() const { return BA.get(); }

  // Determine if record slice is unassigned.
  bool empty() const {
    return !hasBinaryAttrs() && Globals.empty() && Classes.empty() &&
           Categories.empty();
  }

  // Visit all records known to RecordsSlice.
  void visit(RecordVisitor &V) const;

  struct BinaryAttrs {
    std::vector<StringRef> AllowableClients;
    std::vector<StringRef> RexportedLibraries;
    std::vector<StringRef> RPaths;
    StringRef ParentUmbrella;
    StringRef InstallName;
    StringRef UUID;
    StringRef Path;
    FileType File = FileType::Invalid;
    llvm::MachO::PackedVersion CurrentVersion;
    llvm::MachO::PackedVersion CompatVersion;
    uint8_t SwiftABI = 0;
    bool TwoLevelNamespace = false;
    bool AppExtensionSafe = false;
    bool OSLibNotForSharedCache = false;
  };

  /// Return reference to BinaryAttrs.
  BinaryAttrs &getBinaryAttrs();

  /// Store any strings owned by RecordSlice into allocator and return back
  /// reference to that.
  StringRef copyString(StringRef String);

private:
  const llvm::Triple TargetTriple;
  // Hold tapi converted triple to avoid unecessary casts.
  const Target TAPITarget;

  /// BumpPtrAllocator to store generated/copied strings.
  llvm::BumpPtrAllocator StringAllocator;

  /// Promote linkage of requested record. It is no-op if linkage type is lower
  /// than the current assignment.
  ///
  /// \param R The record to update.
  /// \param L Linkage type to update to.
  void updateLinkage(Record *R, RecordLinkage L) {
    R->Linkage = std::max(R->Linkage, L);
  }

  /// Update set flags of requested record.
  ///
  /// \param R The global record to update.
  /// \param F Flags to update to.
  void updateFlags(GlobalRecord *R, SymbolFlags F) { R->Flags = F; }

  RecordMap<GlobalRecord> Globals;
  RecordMap<ObjCInterfaceRecord> Classes;
  RecordMap<ObjCCategoryRecord, std::pair<StringRef, StringRef>> Categories;

  std::unique_ptr<BinaryAttrs> BA{nullptr};
};

using Records = llvm::SmallVector<std::shared_ptr<RecordsSlice>, 4>;
std::unique_ptr<InterfaceFile> convertToInterfaceFile(const Records &Slices);

} // namespace MachO
} // namespace llvm
#endif // LLVM_TEXTAPI_RECORDSLICE_H

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif