1 | //===- llvm/TextAPI/Symbol.h - TAPI Symbol ----------------------*- 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 | #ifndef LLVM_TEXTAPI_SYMBOL_H |
10 | #define LLVM_TEXTAPI_SYMBOL_H |
11 | |
12 | #include "llvm/ADT/BitmaskEnum.h" |
13 | #include "llvm/ADT/StringRef.h" |
14 | #include "llvm/Support/raw_ostream.h" |
15 | #include "llvm/TextAPI/ArchitectureSet.h" |
16 | #include "llvm/TextAPI/Target.h" |
17 | |
18 | namespace llvm { |
19 | namespace MachO { |
20 | |
21 | // clang-format off |
22 | |
23 | /// Symbol flags. |
24 | enum class SymbolFlags : uint8_t { |
25 | /// No flags |
26 | None = 0, |
27 | |
28 | /// Thread-local value symbol |
29 | ThreadLocalValue = 1U << 0, |
30 | |
31 | /// Weak defined symbol |
32 | WeakDefined = 1U << 1, |
33 | |
34 | /// Weak referenced symbol |
35 | WeakReferenced = 1U << 2, |
36 | |
37 | /// Undefined |
38 | Undefined = 1U << 3, |
39 | |
40 | /// Rexported |
41 | Rexported = 1U << 4, |
42 | |
43 | /// Data Segment |
44 | Data = 1U << 5, |
45 | |
46 | /// Text Segment |
47 | Text = 1U << 6, |
48 | |
49 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Text), |
50 | }; |
51 | |
52 | // clang-format on |
53 | |
54 | /// Mapping of entry types in TextStubs. |
55 | enum class EncodeKind : uint8_t { |
56 | GlobalSymbol, |
57 | ObjectiveCClass, |
58 | ObjectiveCClassEHType, |
59 | ObjectiveCInstanceVariable, |
60 | }; |
61 | |
62 | constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_" ; |
63 | constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_" ; |
64 | constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_" ; |
65 | constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_" ; |
66 | constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_" ; |
67 | |
68 | /// ObjC Interface symbol mappings. |
69 | enum class ObjCIFSymbolKind : uint8_t { |
70 | None = 0, |
71 | /// Is OBJC_CLASS* symbol. |
72 | Class = 1U << 0, |
73 | /// Is OBJC_METACLASS* symbol. |
74 | MetaClass = 1U << 1, |
75 | /// Is OBJC_EHTYPE* symbol. |
76 | EHType = 1U << 2, |
77 | |
78 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/EHType), |
79 | }; |
80 | |
81 | using TargetList = SmallVector<Target, 5>; |
82 | |
83 | // Keep containers that hold Targets in sorted order and uniqued. |
84 | template <typename C> |
85 | typename C::iterator addEntry(C &Container, const Target &Targ) { |
86 | auto Iter = |
87 | lower_bound(Container, Targ, [](const Target &LHS, const Target &RHS) { |
88 | return LHS < RHS; |
89 | }); |
90 | if ((Iter != std::end(Container)) && !(Targ < *Iter)) |
91 | return Iter; |
92 | |
93 | return Container.insert(Iter, Targ); |
94 | } |
95 | |
96 | class Symbol { |
97 | public: |
98 | Symbol(EncodeKind Kind, StringRef Name, TargetList Targets, SymbolFlags Flags) |
99 | : Name(Name), Targets(std::move(Targets)), Kind(Kind), Flags(Flags) {} |
100 | |
101 | void addTarget(Target InputTarget) { addEntry(Container&: Targets, Targ: InputTarget); } |
102 | EncodeKind getKind() const { return Kind; } |
103 | StringRef getName() const { return Name; } |
104 | ArchitectureSet getArchitectures() const { |
105 | return mapToArchitectureSet(Targets); |
106 | } |
107 | SymbolFlags getFlags() const { return Flags; } |
108 | |
109 | bool isWeakDefined() const { |
110 | return (Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined; |
111 | } |
112 | |
113 | bool isWeakReferenced() const { |
114 | return (Flags & SymbolFlags::WeakReferenced) == SymbolFlags::WeakReferenced; |
115 | } |
116 | |
117 | bool isThreadLocalValue() const { |
118 | return (Flags & SymbolFlags::ThreadLocalValue) == |
119 | SymbolFlags::ThreadLocalValue; |
120 | } |
121 | |
122 | bool isUndefined() const { |
123 | return (Flags & SymbolFlags::Undefined) == SymbolFlags::Undefined; |
124 | } |
125 | |
126 | bool isReexported() const { |
127 | return (Flags & SymbolFlags::Rexported) == SymbolFlags::Rexported; |
128 | } |
129 | |
130 | bool isData() const { |
131 | return (Flags & SymbolFlags::Data) == SymbolFlags::Data; |
132 | } |
133 | |
134 | bool isText() const { |
135 | return (Flags & SymbolFlags::Text) == SymbolFlags::Text; |
136 | } |
137 | |
138 | bool hasArchitecture(Architecture Arch) const { |
139 | return mapToArchitectureSet(Targets).contains(Archs: Arch); |
140 | } |
141 | |
142 | bool hasTarget(const Target &Targ) const { |
143 | return llvm::is_contained(Range: Targets, Element: Targ); |
144 | } |
145 | |
146 | using const_target_iterator = TargetList::const_iterator; |
147 | using const_target_range = llvm::iterator_range<const_target_iterator>; |
148 | const_target_range targets() const { return {Targets}; } |
149 | |
150 | using const_filtered_target_iterator = |
151 | llvm::filter_iterator<const_target_iterator, |
152 | std::function<bool(const Target &)>>; |
153 | using const_filtered_target_range = |
154 | llvm::iterator_range<const_filtered_target_iterator>; |
155 | const_filtered_target_range targets(ArchitectureSet architectures) const; |
156 | |
157 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
158 | void dump(raw_ostream &OS) const; |
159 | void dump() const { dump(OS&: llvm::errs()); } |
160 | #endif |
161 | |
162 | bool operator==(const Symbol &O) const; |
163 | |
164 | bool operator!=(const Symbol &O) const { return !(*this == O); } |
165 | |
166 | bool operator<(const Symbol &O) const { |
167 | return std::tie(args: Kind, args: Name) < std::tie(args: O.Kind, args: O.Name); |
168 | } |
169 | |
170 | private: |
171 | StringRef Name; |
172 | TargetList Targets; |
173 | EncodeKind Kind; |
174 | SymbolFlags Flags; |
175 | }; |
176 | |
177 | /// Lightweight struct for passing around symbol information. |
178 | struct SimpleSymbol { |
179 | StringRef Name; |
180 | EncodeKind Kind; |
181 | ObjCIFSymbolKind ObjCInterfaceType; |
182 | |
183 | bool operator<(const SimpleSymbol &O) const { |
184 | return std::tie(args: Name, args: Kind, args: ObjCInterfaceType) < |
185 | std::tie(args: O.Name, args: O.Kind, args: O.ObjCInterfaceType); |
186 | } |
187 | }; |
188 | |
189 | /// Get symbol classification by parsing the name of a symbol. |
190 | /// |
191 | /// \param SymName The name of symbol. |
192 | SimpleSymbol parseSymbol(StringRef SymName); |
193 | |
194 | } // end namespace MachO. |
195 | } // end namespace llvm. |
196 | |
197 | #endif // LLVM_TEXTAPI_SYMBOL_H |
198 | |