llvm.org GIT mirror llvm / b075bab
Revert r347823 "[TextAPI] Switch back to a custom Platform enum." It broke the Windows buildbots, e.g. http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/21829/steps/test/logs/stdio This also reverts the follow-ups: r347824, r347827, and r347836. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@347874 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 11 months ago
25 changed file(s) with 0 addition(s) and 3264 deletion(s). Raw diff Collapse all Expand all
+0
-39
include/llvm/TextAPI/MachO/Architecture.def less more
None //===- llvm/TextAPI/Architecture.def - Architecture -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef ARCHINFO
10 #define ARCHINFO(arch)
11 #endif
12
13 ///
14 /// X86 architectures sorted by cpu type and sub type id.
15 ///
16 ARCHINFO(i386, MachO::CPU_TYPE_I386, MachO::CPU_SUBTYPE_I386_ALL)
17 ARCHINFO(x86_64, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_ALL)
18 ARCHINFO(x86_64h, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_H)
19
20
21 ///
22 /// ARM architectures sorted by cpu sub type id.
23 ///
24 ARCHINFO(armv4t, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V4T)
25 ARCHINFO(armv6, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6)
26 ARCHINFO(armv5, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V5TEJ)
27 ARCHINFO(armv7, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7)
28 ARCHINFO(armv7s, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7S)
29 ARCHINFO(armv7k, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7K)
30 ARCHINFO(armv6m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6M)
31 ARCHINFO(armv7m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7M)
32 ARCHINFO(armv7em, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7EM)
33
34
35 ///
36 /// ARM64 architectures sorted by cpu sub type id.
37 ///
38 ARCHINFO(arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL)
+0
-49
include/llvm/TextAPI/MachO/Architecture.h less more
None //===- llvm/TextAPI/Architecture.h - Architecture ---------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Defines the architecture enum and helper methods.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TEXTAPI_MACHO_ARCHITECTURE_H
15 #define LLVM_TEXTAPI_MACHO_ARCHITECTURE_H
16
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/raw_ostream.h"
19
20 namespace llvm {
21 namespace MachO {
22
23 /// Defines the architecture slices that are supported by Text-based Stub files.
24 enum class Architecture : uint8_t {
25 #define ARCHINFO(Arch, Type, SubType) Arch,
26 #include "llvm/TextAPI/MachO/Architecture.def"
27 #undef ARCHINFO
28 unknown, // this has to go last.
29 };
30
31 /// Convert a CPU Type and Subtype pair to an architecture slice.
32 Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType);
33
34 /// Convert a name to an architecture slice.
35 Architecture getArchitectureFromName(StringRef Name);
36
37 /// Convert an architecture slice to a string.
38 StringRef getArchitectureName(Architecture Arch);
39
40 /// Convert an architecture slice to a CPU Type and Subtype pair.
41 std::pair getCPUTypeFromArchitecture(Architecture Arch);
42
43 raw_ostream &operator<<(raw_ostream &OS, Architecture Arch);
44
45 } // end namespace MachO.
46 } // end namespace llvm.
47
48 #endif // LLVM_TEXTAPI_MACHO_ARCHITECTURE_H
+0
-162
include/llvm/TextAPI/MachO/ArchitectureSet.h less more
None //===- llvm/TextAPI/ArchitectureSet.h - ArchitectureSet ---------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Defines the architecture set.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
15 #define LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
16
17 #include "llvm/Support/raw_ostream.h"
18 #include "llvm/TextAPI/MachO/Architecture.h"
19 #include
20 #include
21 #include
22 #include
23
24 namespace llvm {
25 namespace MachO {
26
27 class ArchitectureSet {
28 private:
29 using ArchSetType = uint32_t;
30
31 const static ArchSetType EndIndexVal =
32 std::numeric_limits::max();
33 ArchSetType ArchSet{0};
34
35 public:
36 constexpr ArchitectureSet() = default;
37 constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {}
38 ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); }
39 ArchitectureSet(const std::vector &Archs);
40
41 void set(Architecture Arch) {
42 if (Arch == Architecture::unknown)
43 return;
44 ArchSet |= 1U << static_cast(Arch);
45 }
46
47 void clear(Architecture Arch) { ArchSet &= ~(1U << static_cast(Arch)); }
48
49 bool has(Architecture Arch) const {
50 return ArchSet & (1U << static_cast(Arch));
51 }
52
53 bool contains(ArchitectureSet Archs) const {
54 return (ArchSet & Archs.ArchSet) == Archs.ArchSet;
55 }
56
57 size_t count() const;
58
59 bool empty() const { return ArchSet == 0; }
60
61 ArchSetType rawValue() const { return ArchSet; }
62
63 template
64 class arch_iterator
65 : public std::iterator {
66 private:
67 ArchSetType Index;
68 Ty *ArchSet;
69
70 void findNextSetBit() {
71 if (Index == EndIndexVal)
72 return;
73
74 do {
75 if (*ArchSet & (1UL << ++Index))
76 return;
77 } while (Index < sizeof(Ty) * 8);
78
79 Index = EndIndexVal;
80 }
81
82 public:
83 arch_iterator(Ty *ArchSet, ArchSetType Index = 0)
84 : Index(Index), ArchSet(ArchSet) {
85 if (Index != EndIndexVal && !(*ArchSet & (1UL << Index)))
86 findNextSetBit();
87 }
88
89 Architecture operator*() const { return static_cast(Index); }
90
91 arch_iterator &operator++() {
92 findNextSetBit();
93 return *this;
94 }
95
96 arch_iterator operator++(int) {
97 auto tmp = *this;
98 findNextSetBit();
99 return tmp;
100 }
101
102 bool operator==(const arch_iterator &o) const {
103 return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet);
104 }
105
106 bool operator!=(const arch_iterator &o) const { return !(*this == o); }
107 };
108
109 ArchitectureSet operator&(const ArchitectureSet &o) {
110 return {ArchSet & o.ArchSet};
111 }
112
113 ArchitectureSet operator|(const ArchitectureSet &o) {
114 return {ArchSet | o.ArchSet};
115 }
116
117 ArchitectureSet &operator|=(const ArchitectureSet &o) {
118 ArchSet |= o.ArchSet;
119 return *this;
120 }
121
122 ArchitectureSet &operator|=(const Architecture &Arch) {
123 set(Arch);
124 return *this;
125 }
126
127 bool operator==(const ArchitectureSet &o) const {
128 return ArchSet == o.ArchSet;
129 }
130
131 bool operator!=(const ArchitectureSet &o) const {
132 return ArchSet != o.ArchSet;
133 }
134
135 bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; }
136
137 using iterator = arch_iterator;
138 using const_iterator = arch_iterator;
139
140 iterator begin() { return {&ArchSet}; }
141 iterator end() { return {&ArchSet, EndIndexVal}; }
142
143 const_iterator begin() const { return {&ArchSet}; }
144 const_iterator end() const { return {&ArchSet, EndIndexVal}; }
145
146 operator std::string() const;
147 operator std::vector() const;
148 void print(raw_ostream &OS) const;
149 };
150
151 inline ArchitectureSet operator|(const Architecture &lhs,
152 const Architecture &rhs) {
153 return ArchitectureSet(lhs) | ArchitectureSet(rhs);
154 }
155
156 raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set);
157
158 } // end namespace MachO.
159 } // end namespace llvm.
160
161 #endif // LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
+0
-439
include/llvm/TextAPI/MachO/InterfaceFile.h less more
None //===- llvm/TextAPI/IntefaceFile.h - TAPI Interface File --------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief A generic and abstract interface representation for linkable objects.
11 /// This could be an MachO executable, bundle, dylib, or text-based stub
12 /// file.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_TEXTAPI_MACHO_INTERFACE_FILE_H
17 #define LLVM_TEXTAPI_MACHO_INTERFACE_FILE_H
18
19 #include "llvm/ADT/BitmaskEnum.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/Hashing.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/iterator.h"
24 #include "llvm/BinaryFormat/MachO.h"
25 #include "llvm/BinaryFormat/Magic.h"
26 #include "llvm/Support/Allocator.h"
27 #include "llvm/Support/Error.h"
28 #include "llvm/TextAPI/MachO/Architecture.h"
29 #include "llvm/TextAPI/MachO/ArchitectureSet.h"
30 #include "llvm/TextAPI/MachO/PackedVersion.h"
31 #include "llvm/TextAPI/MachO/Symbol.h"
32
33 namespace llvm {
34 namespace MachO {
35
36 /// Defines the list of MachO platforms.
37 enum class PlatformKind : unsigned {
38 unknown,
39 macOS = MachO::PLATFORM_MACOS,
40 iOS = MachO::PLATFORM_IOS,
41 tvOS = MachO::PLATFORM_TVOS,
42 watchOS = MachO::PLATFORM_WATCHOS,
43 bridgeOS = MachO::PLATFORM_BRIDGEOS,
44 };
45
46 /// Defines a list of Objective-C constraints.
47 enum class ObjCConstraintType : unsigned {
48 /// No constraint.
49 None = 0,
50
51 /// Retain/Release.
52 Retain_Release = 1,
53
54 /// Retain/Release for Simulator.
55 Retain_Release_For_Simulator = 2,
56
57 /// Retain/Release or Garbage Collection.
58 Retain_Release_Or_GC = 3,
59
60 /// Garbage Collection.
61 GC = 4,
62 };
63
64 // clang-format off
65
66 /// Defines the file type this file represents.
67 enum FileType : unsigned {
68 /// Invalid file type.
69 Invalid = 0U,
70
71 /// Text-based stub file (.tbd) version 1.0
72 TBD_V1 = 1U << 0,
73
74 /// Text-based stub file (.tbd) version 2.0
75 TBD_V2 = 1U << 1,
76
77 /// Text-based stub file (.tbd) version 3.0
78 TBD_V3 = 1U << 2,
79
80 All = ~0U,
81
82 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/All),
83 };
84
85 // clang-format on
86
87 /// Reference to an interface file.
88 class InterfaceFileRef {
89 public:
90 InterfaceFileRef() = default;
91
92 InterfaceFileRef(StringRef InstallName) : InstallName(InstallName) {}
93
94 InterfaceFileRef(StringRef InstallName, ArchitectureSet Archs)
95 : InstallName(InstallName), Architectures(Archs) {}
96
97 StringRef getInstallName() const { return InstallName; };
98 void addArchitectures(ArchitectureSet Archs) { Architectures |= Archs; }
99 ArchitectureSet getArchitectures() const { return Architectures; }
100 bool hasArchitecture(Architecture Arch) const {
101 return Architectures.has(Arch);
102 }
103
104 bool operator==(const InterfaceFileRef &O) const {
105 return std::tie(InstallName, Architectures) ==
106 std::tie(O.InstallName, O.Architectures);
107 }
108
109 bool operator<(const InterfaceFileRef &O) const {
110 return std::tie(InstallName, Architectures) <
111 std::tie(O.InstallName, O.Architectures);
112 }
113
114 private:
115 std::string InstallName;
116 ArchitectureSet Architectures;
117 };
118
119 } // end namespace MachO.
120
121 struct SymbolsMapKey {
122 MachO::SymbolKind Kind;
123 StringRef Name;
124
125 SymbolsMapKey(MachO::SymbolKind Kind, StringRef Name)
126 : Kind(Kind), Name(Name) {}
127 };
128 template <> struct DenseMapInfo {
129 static inline SymbolsMapKey getEmptyKey() {
130 return SymbolsMapKey(MachO::SymbolKind::GlobalSymbol, StringRef{});
131 }
132
133 static inline SymbolsMapKey getTombstoneKey() {
134 return SymbolsMapKey(MachO::SymbolKind::ObjectiveCInstanceVariable,
135 StringRef{});
136 }
137
138 static unsigned getHashValue(const SymbolsMapKey &Key) {
139 return hash_combine(hash_value(Key.Kind), hash_value(Key.Name));
140 }
141
142 static bool isEqual(const SymbolsMapKey &LHS, const SymbolsMapKey &RHS) {
143 return std::tie(LHS.Kind, LHS.Name) == std::tie(RHS.Kind, RHS.Name);
144 }
145 };
146
147 namespace MachO {
148
149 /// Defines the interface file.
150 class InterfaceFile {
151 public:
152 /// Set the path from which this file was generated (if applicable).
153 ///
154 /// \param Path_ The path to the source file.
155 void setPath(StringRef Path_) { Path = Path_; }
156
157 /// Get the path from which this file was generated (if applicable).
158 ///
159 /// \return The path to the source file or empty.
160 StringRef getPath() const { return Path; }
161
162 /// Set the file type.
163 ///
164 /// This is used by the YAML writer to identify the specification it should
165 /// use for writing the file.
166 ///
167 /// \param Kind The file type.
168 void setFileType(FileType Kind) { FileKind = Kind; }
169
170 /// Get the file type.
171 ///
172 /// \return The file type.
173 FileType getFileType() const { return FileKind; }
174
175 /// Set the platform.
176 void setPlatform(PlatformKind Platform_) { Platform = Platform_; }
177
178 /// Get the platform.
179 PlatformKind getPlatform() const { return Platform; }
180
181 /// Specify the set of supported architectures by this file.
182 void setArchitectures(ArchitectureSet Architectures_) {
183 Architectures = Architectures_;
184 }
185
186 /// Add the set of supported architectures by this file.
187 void addArchitectures(ArchitectureSet Architectures_) {
188 Architectures |= Architectures_;
189 }
190
191 /// Add supported architecture by this file..
192 void addArch(Architecture Arch) { Architectures.set(Arch); }
193
194 /// Get the set of supported architectures.
195 ArchitectureSet getArchitectures() const { return Architectures; }
196
197 /// Set the install name of the library.
198 void setInstallName(StringRef InstallName_) { InstallName = InstallName_; }
199
200 /// Get the install name of the library.
201 StringRef getInstallName() const { return InstallName; }
202
203 /// Set the current version of the library.
204 void setCurrentVersion(PackedVersion Version) { CurrentVersion = Version; }
205
206 /// Get the current version of the library.
207 PackedVersion getCurrentVersion() const { return CurrentVersion; }
208
209 /// Set the compatibility version of the library.
210 void setCompatibilityVersion(PackedVersion Version) {
211 CompatibilityVersion = Version;
212 }
213
214 /// Get the compatibility version of the library.
215 PackedVersion getCompatibilityVersion() const { return CompatibilityVersion; }
216
217 /// Set the Swift ABI version of the library.
218 void setSwiftABIVersion(uint8_t Version) { SwiftABIVersion = Version; }
219
220 /// Get the Swift ABI version of the library.
221 uint8_t getSwiftABIVersion() const { return SwiftABIVersion; }
222
223 /// Specify if the library uses two-level namespace (or flat namespace).
224 void setTwoLevelNamespace(bool V = true) { IsTwoLevelNamespace = V; }
225
226 /// Check if the library uses two-level namespace.
227 bool isTwoLevelNamespace() const { return IsTwoLevelNamespace; }
228
229 /// Specify if the library is application extension safe (or not).
230 void setApplicationExtensionSafe(bool V = true) { IsAppExtensionSafe = V; }
231
232 /// Check if the library is application extension safe.
233 bool isApplicationExtensionSafe() const { return IsAppExtensionSafe; }
234
235 /// Set the Objective-C constraint.
236 void setObjCConstraint(ObjCConstraintType Constraint) {
237 ObjcConstraint = Constraint;
238 }
239
240 /// Get the Objective-C constraint.
241 ObjCConstraintType getObjCConstraint() const { return ObjcConstraint; }
242
243 /// Specify if this file was generated during InstallAPI (or not).
244 void setInstallAPI(bool V = true) { IsInstallAPI = V; }
245
246 /// Check if this file was generated during InstallAPI.
247 bool isInstallAPI() const { return IsInstallAPI; }
248
249 /// Set the parent umbrella framework.
250 void setParentUmbrella(StringRef Parent) { ParentUmbrella = Parent; }
251
252 /// Get the parent umbrella framework.
253 StringRef getParentUmbrella() const { return ParentUmbrella; }
254
255 /// Add an allowable client.
256 ///
257 /// Mach-O Dynamic libraries have the concept of allowable clients that are
258 /// checked during static link time. The name of the application or library
259 /// that is being generated needs to match one of the allowable clients or the
260 /// linker refuses to link this library.
261 ///
262 /// \param Name The name of the client that is allowed to link this library.
263 /// \param Architectures The set of architecture for which this applies.
264 void addAllowableClient(StringRef Name, ArchitectureSet Architectures);
265
266 /// Get the list of allowable clients.
267 ///
268 /// \return Returns a list of allowable clients.
269 const std::vector &allowableClients() const {
270 return AllowableClients;
271 }
272
273 /// Add a re-exported library.
274 ///
275 /// \param InstallName The name of the library to re-export.
276 /// \param Architectures The set of architecture for which this applies.
277 void addReexportedLibrary(StringRef InstallName,
278 ArchitectureSet Architectures);
279
280 /// Get the list of re-exported libraries.
281 ///
282 /// \return Returns a list of re-exported libraries.
283 const std::vector &reexportedLibraries() const {
284 return ReexportedLibraries;
285 }
286
287 /// Add an architecture/UUID pair.
288 ///
289 /// \param Arch The architecture for which this applies.
290 /// \param UUID The UUID of the library for the specified architecture.
291 void addUUID(Architecture Arch, StringRef UUID);
292
293 /// Add an architecture/UUID pair.
294 ///
295 /// \param Arch The architecture for which this applies.
296 /// \param UUID The UUID of the library for the specified architecture.
297 void addUUID(Architecture Arch, uint8_t UUID[16]);
298
299 /// Get the list of architecture/UUID pairs.
300 ///
301 /// \return Returns a list of architecture/UUID pairs.
302 const std::vector> &uuids() const {
303 return UUIDs;
304 }
305
306 /// Add a symbol to the symbols list or extend an existing one.
307 void addSymbol(SymbolKind Kind, StringRef Name, ArchitectureSet Architectures,
308 SymbolFlags Flags = SymbolFlags::None);
309
310 using SymbolMapType = DenseMap;
311 struct const_symbol_iterator
312 : public iterator_adaptor_base<
313 const_symbol_iterator, SymbolMapType::const_iterator,
314 std::forward_iterator_tag, const Symbol *, ptrdiff_t,
315 const Symbol *, const Symbol *> {
316 const_symbol_iterator() = default;
317
318 template
319 const_symbol_iterator(U &&u)
320 : iterator_adaptor_base(std::forward(u)) {}
321
322 reference operator*() const { return I->second; }
323 pointer operator->() const { return I->second; }
324 };
325 using const_symbol_range = iterator_range;
326
327 // Custom iterator to return only exported symbols.
328 struct const_export_iterator
329 : public iterator_adaptor_base<
330 const_export_iterator, const_symbol_iterator,
331 std::forward_iterator_tag, const Symbol *> {
332 const_symbol_iterator _end;
333
334 void skipToNextSymbol() {
335 while (I != _end && I->isUndefined())
336 ++I;
337 }
338
339 const_export_iterator() = default;
340 template
341 const_export_iterator(U &&it, U &&end)
342 : iterator_adaptor_base(std::forward(it)),
343 _end(std::forward(end)) {
344 skipToNextSymbol();
345 }
346
347 const_export_iterator &operator++() {
348 ++I;
349 skipToNextSymbol();
350 return *this;
351 }
352
353 const_export_iterator operator++(int) {
354 const_export_iterator tmp(*this);
355 ++(*this);
356 return tmp;
357 }
358 };
359 using const_export_range = llvm::iterator_range;
360
361 // Custom iterator to return only undefined symbols.
362 struct const_undefined_iterator
363 : public iterator_adaptor_base<
364 const_undefined_iterator, const_symbol_iterator,
365 std::forward_iterator_tag, const Symbol *> {
366 const_symbol_iterator _end;
367
368 void skipToNextSymbol() {
369 while (I != _end && !I->isUndefined())
370 ++I;
371 }
372
373 const_undefined_iterator() = default;
374 template
375 const_undefined_iterator(U &&it, U &&end)
376 : iterator_adaptor_base(std::forward(it)),
377 _end(std::forward(end)) {
378 skipToNextSymbol();
379 }
380
381 const_undefined_iterator &operator++() {
382 ++I;
383 skipToNextSymbol();
384 return *this;
385 }
386
387 const_undefined_iterator operator++(int) {
388 const_undefined_iterator tmp(*this);
389 ++(*this);
390 return tmp;
391 }
392 };
393 using const_undefined_range = llvm::iterator_range;
394
395 const_symbol_range symbols() const {
396 return {Symbols.begin(), Symbols.end()};
397 }
398 const_export_range exports() const {
399 return {{Symbols.begin(), Symbols.end()}, {Symbols.end(), Symbols.end()}};
400 }
401 const_undefined_range undefineds() const {
402 return {{Symbols.begin(), Symbols.end()}, {Symbols.end(), Symbols.end()}};
403 }
404
405 private:
406 llvm::BumpPtrAllocator Allocator;
407 StringRef copyString(StringRef String) {
408 if (String.empty())
409 return {};
410
411 void *Ptr = Allocator.Allocate(String.size(), 1);
412 memcpy(Ptr, String.data(), String.size());
413 return StringRef(reinterpret_cast(Ptr), String.size());
414 }
415
416 std::string Path;
417 FileType FileKind;
418 PlatformKind Platform;
419 ArchitectureSet Architectures;
420 std::string InstallName;
421 PackedVersion CurrentVersion;
422 PackedVersion CompatibilityVersion;
423 uint8_t SwiftABIVersion{0};
424 bool IsTwoLevelNamespace{false};
425 bool IsAppExtensionSafe{false};
426 bool IsInstallAPI{false};
427 ObjCConstraintType ObjcConstraint = ObjCConstraintType::None;
428 std::string ParentUmbrella;
429 std::vector AllowableClients;
430 std::vector ReexportedLibraries;
431 std::vector> UUIDs;
432 SymbolMapType Symbols;
433 };
434
435 } // end namespace MachO.
436 } // end namespace llvm.
437
438 #endif // LLVM_TEXTAPI_MACHO_INTERFACE_FILE_H
+0
-66
include/llvm/TextAPI/MachO/PackedVersion.h less more
None //===- llvm/TextAPI/PackedVersion.h - PackedVersion -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Defines the Mach-O packed version format.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TEXTAPI_MACHO_PACKED_VERSION_H
15 #define LLVM_TEXTAPI_MACHO_PACKED_VERSION_H
16
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/raw_ostream.h"
19
20 namespace llvm {
21 namespace MachO {
22
23 class PackedVersion {
24 uint32_t Version{0};
25
26 public:
27 constexpr PackedVersion() = default;
28 explicit constexpr PackedVersion(uint32_t RawVersion) : Version(RawVersion) {}
29 PackedVersion(unsigned Major, unsigned Minor, unsigned Subminor)
30 : Version((Major << 16) | ((Minor & 0xff) << 8) | (Subminor & 0xff)) {}
31
32 bool empty() const { return Version == 0; }
33
34 /// Retrieve the major version number.
35 unsigned getMajor() const { return Version >> 16; }
36
37 /// Retrieve the minor version number, if provided.
38 unsigned getMinor() const { return (Version >> 8) & 0xff; }
39
40 /// Retrieve the subminor version number, if provided.
41 unsigned getSubminor() const { return Version & 0xff; }
42
43 bool parse32(StringRef Str);
44 std::pair parse64(StringRef Str);
45
46 bool operator<(const PackedVersion &O) const { return Version < O.Version; }
47
48 bool operator==(const PackedVersion &O) const { return Version == O.Version; }
49
50 bool operator!=(const PackedVersion &O) const { return Version != O.Version; }
51
52 uint32_t rawValue() const { return Version; }
53
54 void print(raw_ostream &OS) const;
55 };
56
57 inline raw_ostream &operator<<(raw_ostream &OS, const PackedVersion &Version) {
58 Version.print(OS);
59 return OS;
60 }
61
62 } // end namespace MachO.
63 } // end namespace llvm.
64
65 #endif // LLVM_TEXTAPI_MACHO_PACKED_VERSION_H
+0
-102
include/llvm/TextAPI/MachO/Symbol.h less more
None //===- llvm/TextAPI/Symbol.h - TAPI Symbol ----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Symbol
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TEXTAPI_MACHO_SYMBOL_H
15 #define LLVM_TEXTAPI_MACHO_SYMBOL_H
16
17 #include "llvm/ADT/BitmaskEnum.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/TextAPI/MachO/ArchitectureSet.h"
22
23 namespace llvm {
24 namespace MachO {
25
26 // clang-format off
27
28 /// Symbol flags.
29 enum class SymbolFlags : uint8_t {
30 /// No flags
31 None = 0,
32
33 /// Thread-local value symbol
34 ThreadLocalValue = 1U << 0,
35
36 /// Weak defined symbol
37 WeakDefined = 1U << 1,
38
39 /// Weak referenced symbol
40 WeakReferenced = 1U << 2,
41
42 /// Undefined
43 Undefined = 1U << 3,
44
45 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Undefined),
46 };
47
48 // clang-format on
49
50 enum class SymbolKind : uint8_t {
51 GlobalSymbol,
52 ObjectiveCClass,
53 ObjectiveCClassEHType,
54 ObjectiveCInstanceVariable,
55 };
56
57 class Symbol {
58 public:
59 constexpr Symbol(SymbolKind Kind, StringRef Name,
60 ArchitectureSet Architectures, SymbolFlags Flags)
61 : Name(Name), Architectures(Architectures), Kind(Kind), Flags(Flags) {}
62
63 SymbolKind getKind() const { return Kind; }
64 StringRef getName() const { return Name; }
65 ArchitectureSet getArchitectures() const { return Architectures; }
66 void addArchitectures(ArchitectureSet Archs) { Architectures |= Archs; }
67 SymbolFlags getFlags() const { return Flags; }
68
69 bool isWeakDefined() const {
70 return (Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined;
71 }
72
73 bool isWeakReferenced() const {
74 return (Flags & SymbolFlags::WeakReferenced) == SymbolFlags::WeakReferenced;
75 }
76
77 bool isThreadLocalValue() const {
78 return (Flags & SymbolFlags::ThreadLocalValue) ==
79 SymbolFlags::ThreadLocalValue;
80 }
81
82 bool isUndefined() const {
83 return (Flags & SymbolFlags::Undefined) == SymbolFlags::Undefined;
84 }
85
86 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
87 void dump(raw_ostream &OS) const;
88 void dump() const { dump(llvm::errs()); }
89 #endif
90
91 private:
92 StringRef Name;
93 ArchitectureSet Architectures;
94 SymbolKind Kind;
95 SymbolFlags Flags;
96 };
97
98 } // end namespace MachO.
99 } // end namespace llvm.
100
101 #endif // LLVM_TEXTAPI_MACHO_SYMBOL_H
+0
-35
include/llvm/TextAPI/MachO/TextAPIReader.h less more
None //===--- TextAPIReader.h - Text API Reader ----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TEXTAPI_MACHO_READER_H
10 #define LLVM_TEXTAPI_MACHO_READER_H
11
12 #include "llvm/Support/Error.h"
13 #include "llvm/Support/MemoryBuffer.h"
14
15 namespace llvm {
16 namespace MachO {
17
18 class InterfaceFile;
19
20 class TextAPIReader {
21 public:
22 static Expected>
23 get(std::unique_ptr InputBuffer);
24
25 static Expected>
26 getUnmanaged(llvm::MemoryBuffer *InputBuffer);
27
28 TextAPIReader() = delete;
29 };
30
31 } // end namespace MachO.
32 } // end namespace llvm.
33
34 #endif // LLVM_TEXTAPI_MACHO_READER_H
+0
-30
include/llvm/TextAPI/MachO/TextAPIWriter.h less more
None //===--- TextAPIWriter.h - Text API Writer ----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TEXTAPI_MACHO_WRITER_H
10 #define LLVM_TEXTAPI_MACHO_WRITER_H
11
12 #include "llvm/Support/MemoryBuffer.h"
13
14 namespace llvm {
15 namespace MachO {
16
17 class InterfaceFile;
18
19 class TextAPIWriter {
20 public:
21 TextAPIWriter() = delete;
22
23 static Error writeToStream(raw_ostream &os, const InterfaceFile &);
24 };
25
26 } // end namespace MachO.
27 } // end namespace llvm.
28
29 #endif // LLVM_TEXTAPI_MACHO_WRITER_H
1111 add_subdirectory(Analysis)
1212 add_subdirectory(LTO)
1313 add_subdirectory(MC)
14 add_subdirectory(TextAPI)
1514 add_subdirectory(Object)
1615 add_subdirectory(ObjectYAML)
1716 add_subdirectory(Option)
4141 TableGen
4242 Target
4343 Testing
44 TextAPI
4544 ToolDrivers
4645 Transforms
4746 WindowsManifest
+0
-12
lib/TextAPI/CMakeLists.txt less more
None add_llvm_library(LLVMTextAPI
1 MachO/Architecture.cpp
2 MachO/ArchitectureSet.cpp
3 MachO/InterfaceFile.cpp
4 MachO/PackedVersion.cpp
5 MachO/Symbol.cpp
6 MachO/TextStub.cpp
7 MachO/TextStubCommon.cpp
8
9 ADDITIONAL_HEADER_DIRS
10 "${LLVM_MAIN_INCLUDE_DIR}/llvm/TextAPI"
11 )
+0
-22
lib/TextAPI/LLVMBuild.txt less more
None ;===- ./lib/TextAPI/LLVMBuild.txt ------------------------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = TextAPI
20 parent = Libraries
21 required_libraries = Support BinaryFormat
+0
-79
lib/TextAPI/MachO/Architecture.cpp less more
None //===- llvm/TextAPI/Architecture.cpp - Architecture -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Implements the architecture helper functions.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/TextAPI/MachO/Architecture.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/BinaryFormat/MachO.h"
17
18 namespace llvm {
19 namespace MachO {
20
21 Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType) {
22 #define ARCHINFO(Arch, Type, Subtype) \
23 if (CPUType == (Type) && \
24 (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) == (Subtype)) \
25 return Architecture::Arch;
26 #include "llvm/TextAPI/MachO/Architecture.def"
27 #undef ARCHINFO
28
29 return Architecture::unknown;
30 }
31
32 Architecture getArchitectureFromName(StringRef Name) {
33 return StringSwitch(Name)
34 #define ARCHINFO(Arch, Type, Subtype) .Case(#Arch, Architecture::Arch)
35 #include "llvm/TextAPI/MachO/Architecture.def"
36 #undef ARCHINFO
37 .Default(Architecture::unknown);
38 }
39
40 StringRef getArchitectureName(Architecture Arch) {
41 switch (Arch) {
42 #define ARCHINFO(Arch, Type, Subtype) \
43 case Architecture::Arch: \
44 return #Arch;
45 #include "llvm/TextAPI/MachO/Architecture.def"
46 #undef ARCHINFO
47 case Architecture::unknown:
48 return "unknown";
49 }
50
51 // Appease some compilers that cannot figure out that this is a fully covered
52 // switch statement.
53 return "unknown";
54 }
55
56 std::pair getCPUTypeFromArchitecture(Architecture Arch) {
57 switch (Arch) {
58 #define ARCHINFO(Arch, Type, Subtype) \
59 case Architecture::Arch: \
60 return std::make_pair(Type, Subtype);
61 #include "llvm/TextAPI/MachO/Architecture.def"
62 #undef ARCHINFO
63 case Architecture::unknown:
64 return std::make_pair(0, 0);
65 }
66
67 // Appease some compilers that cannot figure out that this is a fully covered
68 // switch statement.
69 return std::make_pair(0, 0);
70 }
71
72 raw_ostream &operator<<(raw_ostream &OS, Architecture Arch) {
73 OS << getArchitectureName(Arch);
74 return OS;
75 }
76
77 } // end namespace MachO.
78 } // end namespace llvm.
+0
-71
lib/TextAPI/MachO/ArchitectureSet.cpp less more
None //===- llvm/TextAPI/ArchitectureSet.cpp - Architecture Set ------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Implements the architecture set.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/TextAPI/MachO/ArchitectureSet.h"
15
16 namespace llvm {
17 namespace MachO {
18
19 ArchitectureSet::ArchitectureSet(const std::vector &Archs)
20 : ArchitectureSet() {
21 for (auto Arch : Archs) {
22 if (Arch == Architecture::unknown)
23 continue;
24 set(Arch);
25 }
26 }
27
28 size_t ArchitectureSet::count() const {
29 // popcnt
30 size_t Cnt = 0;
31 for (unsigned i = 0; i < sizeof(ArchSetType) * 8; ++i)
32 if (ArchSet & (1U << i))
33 ++Cnt;
34 return Cnt;
35 }
36
37 ArchitectureSet::operator std::string() const {
38 if (empty())
39 return "[(empty)]";
40
41 std::string result;
42 auto size = count();
43 for (auto arch : *this) {
44 result.append(getArchitectureName(arch));
45 size -= 1;
46 if (size)
47 result.append(" ");
48 }
49 return result;
50 }
51
52 ArchitectureSet::operator std::vector() const {
53 std::vector archs;
54 for (auto arch : *this) {
55 if (arch == Architecture::unknown)
56 continue;
57 archs.emplace_back(arch);
58 }
59 return archs;
60 }
61
62 void ArchitectureSet::print(raw_ostream &os) const { os << std::string(*this); }
63
64 raw_ostream &operator<<(raw_ostream &os, ArchitectureSet set) {
65 set.print(os);
66 return os;
67 }
68
69 } // end namespace MachO.
70 } // end namespace llvm.
+0
-86
lib/TextAPI/MachO/InterfaceFile.cpp less more
None //===- lib/TextAPI/InterfaceFile.cpp - Interface File -----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Implements the Interface File.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/TextAPI/MachO/InterfaceFile.h"
15 #include
16 #include
17
18 using namespace llvm::MachO;
19
20 namespace llvm {
21 namespace MachO {
22 namespace detail {
23 template
24 typename C::iterator addEntry(C &Container, StringRef InstallName) {
25 auto I =
26 std::lower_bound(std::begin(Container), std::end(Container), InstallName,
27 [](const InterfaceFileRef &LHS, const StringRef &RHS) {
28 return LHS.getInstallName() < RHS;
29 });
30 if ((I != std::end(Container)) && !(InstallName < I->getInstallName()))
31 return I;
32
33 return Container.emplace(I, InstallName);
34 }
35 } // end namespace detail.
36
37 void InterfaceFile::addAllowableClient(StringRef Name,
38 ArchitectureSet Architectures) {
39 auto Client = detail::addEntry(AllowableClients, Name);
40 Client->addArchitectures(Architectures);
41 }
42
43 void InterfaceFile::addReexportedLibrary(StringRef InstallName,
44 ArchitectureSet Architectures) {
45 auto Lib = detail::addEntry(ReexportedLibraries, InstallName);
46 Lib->addArchitectures(Architectures);
47 }
48
49 void InterfaceFile::addUUID(Architecture Arch, StringRef UUID) {
50 auto I = std::lower_bound(UUIDs.begin(), UUIDs.end(), Arch,
51 [](const std::pair &LHS,
52 Architecture RHS) { return LHS.first < RHS; });
53
54 if ((I != UUIDs.end()) && !(Arch < I->first)) {
55 I->second = UUID;
56 return;
57 }
58
59 UUIDs.emplace(I, Arch, UUID);
60 return;
61 }
62
63 void InterfaceFile::addUUID(Architecture Arch, uint8_t UUID[16]) {
64 std::stringstream Stream;
65 for (unsigned i = 0; i < 16; ++i) {
66 if (i == 4 || i == 6 || i == 8 || i == 10)
67 Stream << '-';
68 Stream << std::setfill('0') << std::setw(2) << std::uppercase << std::hex
69 << static_cast(UUID[i]);
70 }
71 addUUID(Arch, Stream.str());
72 }
73
74 void InterfaceFile::addSymbol(SymbolKind Kind, StringRef Name,
75 ArchitectureSet Archs, SymbolFlags Flags) {
76 Name = copyString(Name);
77 auto result = Symbols.try_emplace(SymbolsMapKey{Kind, Name}, nullptr);
78 if (result.second)
79 result.first->second = new (Allocator) Symbol{Kind, Name, Archs, Flags};
80 else
81 result.first->second->addArchitectures(Archs);
82 }
83
84 } // end namespace MachO.
85 } // end namespace llvm.
+0
-115
lib/TextAPI/MachO/PackedVersion.cpp less more
None //===- llvm/TextAPI/PackedVersion.cpp - PackedVersion -----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Implements the Mach-O packed version.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/TextAPI/MachO/PackedVersion.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/raw_ostream.h"
20
21 namespace llvm {
22 namespace MachO {
23
24 bool PackedVersion::parse32(StringRef Str) {
25 Version = 0;
26
27 if (Str.empty())
28 return false;
29
30 SmallVector Parts;
31 SplitString(Str, Parts, ".");
32
33 if (Parts.size() > 3)
34 return false;
35
36 unsigned long long Num;
37 if (getAsUnsignedInteger(Parts[0], 10, Num))
38 return false;
39
40 if (Num > UINT16_MAX)
41 return false;
42
43 Version = Num << 16;
44
45 for (unsigned i = 1, ShiftNum = 8; i < Parts.size(); ++i, ShiftNum -= 8) {
46 if (getAsUnsignedInteger(Parts[i], 10, Num))
47 return false;
48
49 if (Num > UINT8_MAX)
50 return false;
51
52 Version |= (Num << ShiftNum);
53 }
54
55 return true;
56 }
57
58 std::pair PackedVersion::parse64(StringRef Str) {
59 bool Truncated = false;
60 Version = 0;
61
62 if (Str.empty())
63 return std::make_pair(false, Truncated);
64
65 SmallVector Parts;
66 SplitString(Str, Parts, ".");
67
68 if (Parts.size() > 5)
69 return std::make_pair(false, Truncated);
70
71 unsigned long long Num;
72 if (getAsUnsignedInteger(Parts[0], 10, Num))
73 return std::make_pair(false, Truncated);
74
75 if (Num > 0xFFFFFFULL)
76 return std::make_pair(false, Truncated);
77
78 if (Num > 0xFFFFULL) {
79 Num = 0xFFFFULL;
80 Truncated = true;
81 }
82 Version = Num << 16;
83
84 for (unsigned i = 1, ShiftNum = 8; i < Parts.size() && i < 3;
85 ++i, ShiftNum -= 8) {
86 if (getAsUnsignedInteger(Parts[i], 10, Num))
87 return std::make_pair(false, Truncated);
88
89 if (Num > 0x3FFULL)
90 return std::make_pair(false, Truncated);
91
92 if (Num > 0xFFULL) {
93 Num = 0xFFULL;
94 Truncated = true;
95 }
96 Version |= (Num << ShiftNum);
97 }
98
99 if (Parts.size() > 3)
100 Truncated = true;
101
102 return std::make_pair(true, Truncated);
103 }
104
105 void PackedVersion::print(raw_ostream &OS) const {
106 OS << format("%d", getMajor());
107 if (getMinor() || getSubminor())
108 OS << format(".%d", getMinor());
109 if (getSubminor())
110 OS << format(".%d", getSubminor());
111 }
112
113 } // end namespace MachO.
114 } // end namespace llvm.
+0
-51
lib/TextAPI/MachO/Symbol.cpp less more
None //===- lib/TextAPI/Symbol.cpp - Symbol --------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Implements the Symbol
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/TextAPI/MachO/Symbol.h"
15 #include
16
17 namespace llvm {
18 namespace MachO {
19
20 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
21 LLVM_DUMP_METHOD void Symbol::dump(raw_ostream &OS) const {
22 std::string Result;
23 if (isUndefined())
24 Result += "(undef) ";
25 if (isWeakDefined())
26 Result += "(weak-def) ";
27 if (isWeakReferenced())
28 Result += "(weak-ref) ";
29 if (isThreadLocalValue())
30 Result += "(tlv) ";
31 switch (Kind) {
32 case SymbolKind::GlobalSymbol:
33 Result + Name.str();
34 break;
35 case SymbolKind::ObjectiveCClass:
36 Result + "(ObjC Class) " + Name.str();
37 break;
38 case SymbolKind::ObjectiveCClassEHType:
39 Result + "(ObjC Class EH) " + Name.str();
40 break;
41 case SymbolKind::ObjectiveCInstanceVariable:
42 Result + "(ObjC IVar) " + Name.str();
43 break;
44 }
45 OS << Result;
46 }
47 #endif
48
49 } // end namespace MachO.
50 } // end namespace llvm.
+0
-35
lib/TextAPI/MachO/TextAPIContext.h less more
None //===- llvm/TextAPI/YAMLContext.h - YAML Context ----------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Defines the YAML Context for the TextAPI Reader/Writer
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TEXTAPI_MACHO_CONTEXT_H
15 #define LLVM_TEXTAPI_MACHO_CONTEXT_H
16
17 #include "llvm/Support/MemoryBuffer.h"
18 #include
19
20 namespace llvm {
21 namespace MachO {
22
23 enum FileType : unsigned;
24
25 struct TextAPIContext {
26 std::string ErrorMessage;
27 std::string Path;
28 FileType FileKind;
29 };
30
31 } // end namespace MachO.
32 } // end namespace llvm.
33
34 #endif // LLVM_TEXTAPI_MACHO_CONTEXT_H
+0
-660
lib/TextAPI/MachO/TextStub.cpp less more
None //===- llvm/TextAPI/TextStub.cpp - Text Stub --------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Implements the text stub file reader/writer.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "TextAPIContext.h"
15 #include "TextStubCommon.h"
16 #include "llvm/ADT/BitmaskEnum.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/Allocator.h"
20 #include "llvm/Support/SourceMgr.h"
21 #include "llvm/Support/YAMLTraits.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include "llvm/TextAPI/MachO/Architecture.h"
24 #include "llvm/TextAPI/MachO/ArchitectureSet.h"
25 #include "llvm/TextAPI/MachO/InterfaceFile.h"
26 #include "llvm/TextAPI/MachO/PackedVersion.h"
27 #include "llvm/TextAPI/MachO/TextAPIReader.h"
28 #include "llvm/TextAPI/MachO/TextAPIWriter.h"
29 #include
30 #include
31
32 // clang-format off
33 /*
34
35 YAML Format specification.
36
37 The TBD v1 format only support two level address libraries and is per
38 definition application extension safe.
39
40 --- # the tag !tapi-tbd-v1 is optional and
41 # shouldn't be emitted to support older linker.
42 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
43 # supported by this file.
44 platform: ios # Specifies the platform (macosx, ios, etc)
45 install-name: /u/l/libfoo.dylib #
46 current-version: 1.2.3 # Optional: defaults to 1.0
47 compatibility-version: 1.0 # Optional: defaults to 1.0
48 swift-version: 0 # Optional: defaults to 0
49 objc-constraint: none # Optional: defaults to none
50 exports: # List of export sections
51 ...
52
53 Each export section is defined as following:
54
55 - archs: [ arm64 ] # the list of architecture slices
56 allowed-clients: [ client ] # Optional: List of clients
57 re-exports: [ ] # Optional: List of re-exports
58 symbols: [ _sym ] # Optional: List of symbols
59 objc-classes: [] # Optional: List of Objective-C classes
60 objc-ivars: [] # Optional: List of Objective C Instance
61 # Variables
62 weak-def-symbols: [] # Optional: List of weak defined symbols
63 thread-local-symbols: [] # Optional: List of thread local symbols
64 */
65
66 /*
67
68 YAML Format specification.
69
70 --- !tapi-tbd-v2
71 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
72 # supported by this file.
73 uuids: [ armv7:... ] # Optional: List of architecture and UUID pairs.
74 platform: ios # Specifies the platform (macosx, ios, etc)
75 flags: [] # Optional:
76 install-name: /u/l/libfoo.dylib #
77 current-version: 1.2.3 # Optional: defaults to 1.0
78 compatibility-version: 1.0 # Optional: defaults to 1.0
79 swift-version: 0 # Optional: defaults to 0
80 objc-constraint: retain_release # Optional: defaults to retain_release
81 parent-umbrella: # Optional:
82 exports: # List of export sections
83 ...
84 undefineds: # List of undefineds sections
85 ...
86
87 Each export section is defined as following:
88
89 - archs: [ arm64 ] # the list of architecture slices
90 allowed-clients: [ client ] # Optional: List of clients
91 re-exports: [ ] # Optional: List of re-exports
92 symbols: [ _sym ] # Optional: List of symbols
93 objc-classes: [] # Optional: List of Objective-C classes
94 objc-ivars: [] # Optional: List of Objective C Instance
95 # Variables
96 weak-def-symbols: [] # Optional: List of weak defined symbols
97 thread-local-symbols: [] # Optional: List of thread local symbols
98
99 Each undefineds section is defined as following:
100 - archs: [ arm64 ] # the list of architecture slices
101 symbols: [ _sym ] # Optional: List of symbols
102 objc-classes: [] # Optional: List of Objective-C classes
103 objc-ivars: [] # Optional: List of Objective C Instance Variables
104 weak-ref-symbols: [] # Optional: List of weak defined symbols
105 */
106
107 /*
108
109 YAML Format specification.
110
111 --- !tapi-tbd-v3
112 archs: [ armv7, armv7s, arm64 ] # the list of architecture slices that are
113 # supported by this file.
114 uuids: [ armv7:... ] # Optional: List of architecture and UUID pairs.
115 platform: ios # Specifies the platform (macosx, ios, etc)
116 flags: [] # Optional:
117 install-name: /u/l/libfoo.dylib #
118 current-version: 1.2.3 # Optional: defaults to 1.0
119 compatibility-version: 1.0 # Optional: defaults to 1.0
120 swift-abi-version: 0 # Optional: defaults to 0
121 objc-constraint: retain_release # Optional: defaults to retain_release
122 parent-umbrella: # Optional:
123 exports: # List of export sections
124 ...
125 undefineds: # List of undefineds sections
126 ...
127
128 Each export section is defined as following:
129
130 - archs: [ arm64 ] # the list of architecture slices
131 allowed-clients: [ client ] # Optional: List of clients
132 re-exports: [ ] # Optional: List of re-exports
133 symbols: [ _sym ] # Optional: List of symbols
134 objc-classes: [] # Optional: List of Objective-C classes
135 objc-eh-types: [] # Optional: List of Objective-C classes
136 # with EH
137 objc-ivars: [] # Optional: List of Objective C Instance
138 # Variables
139 weak-def-symbols: [] # Optional: List of weak defined symbols
140 thread-local-symbols: [] # Optional: List of thread local symbols
141
142 Each undefineds section is defined as following:
143 - archs: [ arm64 ] # the list of architecture slices
144 symbols: [ _sym ] # Optional: List of symbols
145 objc-classes: [] # Optional: List of Objective-C classes
146 objc-eh-types: [] # Optional: List of Objective-C classes
147 # with EH
148 objc-ivars: [] # Optional: List of Objective C Instance Variables
149 weak-ref-symbols: [] # Optional: List of weak defined symbols
150 */
151 // clang-format on
152
153 using namespace llvm;
154 using namespace llvm::yaml;
155 using namespace llvm::MachO;
156
157 namespace {
158 struct ExportSection {
159 std::vector Architectures;
160 std::vector AllowableClients;
161 std::vector ReexportedLibraries;
162 std::vector Symbols;
163 std::vector Classes;
164 std::vector ClassEHs;
165 std::vector IVars;
166 std::vector WeakDefSymbols;
167 std::vector TLVSymbols;
168 };
169
170 struct UndefinedSection {
171 std::vector Architectures;
172 std::vector Symbols;
173 std::vector Classes;
174 std::vector ClassEHs;
175 std::vector IVars;
176 std::vector WeakRefSymbols;
177 };
178
179 // clang-format off
180 enum TBDFlags : unsigned {
181 None = 0U,
182 FlatNamespace = 1U << 0,
183 NotApplicationExtensionSafe = 1U << 1,
184 InstallAPI = 1U << 2,
185 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/InstallAPI),
186 };
187 // clang-format on
188 } // end anonymous namespace.
189
190 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(Architecture)
191 LLVM_YAML_IS_SEQUENCE_VECTOR(ExportSection)
192 LLVM_YAML_IS_SEQUENCE_VECTOR(UndefinedSection)
193
194 namespace llvm {
195 namespace yaml {
196
197 template <> struct MappingTraits {
198 static void mapping(IO &IO, ExportSection &Section) {
199 const auto *Ctx = reinterpret_cast(IO.getContext());
200 assert((!Ctx || (Ctx && Ctx->FileKind != FileType::Invalid)) &&
201 "File type is not set in YAML context");
202
203 IO.mapRequired("archs", Section.Architectures);
204 if (Ctx->FileKind == FileType::TBD_V1)
205 IO.mapOptional("allowed-clients", Section.AllowableClients);
206 else
207 IO.mapOptional("allowable-clients", Section.AllowableClients);
208 IO.mapOptional("re-exports", Section.ReexportedLibraries);
209 IO.mapOptional("symbols", Section.Symbols);
210 IO.mapOptional("objc-classes", Section.Classes);
211 if (Ctx->FileKind == FileType::TBD_V3)
212 IO.mapOptional("objc-eh-types", Section.ClassEHs);
213 IO.mapOptional("objc-ivars", Section.IVars);
214 IO.mapOptional("weak-def-symbols", Section.WeakDefSymbols);
215 IO.mapOptional("thread-local-symbols", Section.TLVSymbols);
216 }
217 };
218
219 template <> struct MappingTraits {
220 static void mapping(IO &IO, UndefinedSection &Section) {
221 const auto *Ctx = reinterpret_cast(IO.getContext());
222 assert((!Ctx || (Ctx && Ctx->FileKind != FileType::Invalid)) &&
223 "File type is not set in YAML context");
224
225 IO.mapRequired("archs", Section.Architectures);
226 IO.mapOptional("symbols", Section.Symbols);
227 IO.mapOptional("objc-classes", Section.Classes);
228 if (Ctx->FileKind == FileType::TBD_V3)
229 IO.mapOptional("objc-eh-types", Section.ClassEHs);
230 IO.mapOptional("objc-ivars", Section.IVars);
231 IO.mapOptional("weak-ref-symbols", Section.WeakRefSymbols);
232 }
233 };
234
235 template <> struct ScalarBitSetTraits {
236 static void bitset(IO &IO, TBDFlags &Flags) {
237 IO.bitSetCase(Flags, "flat_namespace", TBDFlags::FlatNamespace);
238 IO.bitSetCase(Flags, "not_app_extension_safe",
239 TBDFlags::NotApplicationExtensionSafe);
240 IO.bitSetCase(Flags, "installapi", TBDFlags::InstallAPI);
241 }
242 };
243
244 template <> struct MappingTraits {
245 struct NormalizedTBD {
246 explicit NormalizedTBD(IO &IO) {}
247 NormalizedTBD(IO &IO, const InterfaceFile *&File) {
248 Architectures = File->getArchitectures();
249 UUIDs = File->uuids();
250 Platform = File->getPlatform();
251 InstallName = File->getInstallName();
252 CurrentVersion = PackedVersion(File->getCurrentVersion());
253 CompatibilityVersion = PackedVersion(File->getCompatibilityVersion());
254 SwiftABIVersion = File->getSwiftABIVersion();
255 ObjCConstraint = File->getObjCConstraint();
256
257 Flags = TBDFlags::None;
258 if (!File->isApplicationExtensionSafe())
259 Flags |= TBDFlags::NotApplicationExtensionSafe;
260
261 if (!File->isTwoLevelNamespace())
262 Flags |= TBDFlags::FlatNamespace;
263
264 if (File->isInstallAPI())
265 Flags |= TBDFlags::InstallAPI;
266
267 ParentUmbrella = File->getParentUmbrella();
268
269 std::set ArchSet;
270 for (const auto &Library : File->allowableClients())
271 ArchSet.insert(Library.getArchitectures());
272
273 for (const auto &Library : File->reexportedLibraries())
274 ArchSet.insert(Library.getArchitectures());
275
276 std::map SymbolToArchSet;
277 for (const auto *Symbol : File->exports()) {
278 auto Architectures = Symbol->getArchitectures();
279 SymbolToArchSet[Symbol] = Architectures;
280 ArchSet.insert(Architectures);
281 }
282
283 for (auto Architectures : ArchSet) {
284 ExportSection Section;
285 Section.Architectures = Architectures;
286
287 for (const auto &Library : File->allowableClients())
288 if (Library.getArchitectures() == Architectures)
289 Section.AllowableClients.emplace_back(Library.getInstallName());
290
291 for (const auto &Library : File->reexportedLibraries())
292 if (Library.getArchitectures() == Architectures)
293 Section.ReexportedLibraries.emplace_back(Library.getInstallName());
294
295 for (const auto &SymArch : SymbolToArchSet) {
296 if (SymArch.second != Architectures)
297 continue;
298
299 const auto *Symbol = SymArch.first;
300 switch (Symbol->getKind()) {
301 case SymbolKind::GlobalSymbol:
302 if (Symbol->isWeakDefined())
303 Section.WeakDefSymbols.emplace_back(Symbol->getName());
304 else if (Symbol->isThreadLocalValue())
305 Section.TLVSymbols.emplace_back(Symbol->getName());
306 else
307 Section.Symbols.emplace_back(Symbol->getName());
308 break;
309 case SymbolKind::ObjectiveCClass:
310 if (File->getFileType() != FileType::TBD_V3)
311 Section.Classes.emplace_back(
312 copyString("_" + Symbol->getName().str()));
313 else
314 Section.Classes.emplace_back(Symbol->getName());
315 break;
316 case SymbolKind::ObjectiveCClassEHType:
317 if (File->getFileType() != FileType::TBD_V3)
318 Section.Symbols.emplace_back(
319 copyString("_OBJC_EHTYPE_$_" + Symbol->getName().str()));
320 else
321 Section.ClassEHs.emplace_back(Symbol->getName());
322 break;
323 case SymbolKind::ObjectiveCInstanceVariable:
324 if (File->getFileType() != FileType::TBD_V3)
325 Section.IVars.emplace_back(
326 copyString("_" + Symbol->getName().str()));
327 else
328 Section.IVars.emplace_back(Symbol->getName());
329 break;
330 }
331 }
332 llvm::sort(Section.Symbols.begin(), Section.Symbols.end());
333 llvm::sort(Section.Classes.begin(), Section.Classes.end());
334 llvm::sort(Section.ClassEHs.begin(), Section.ClassEHs.end());
335 llvm::sort(Section.IVars.begin(), Section.IVars.end());
336 llvm::sort(Section.WeakDefSymbols.begin(),
337 Section.WeakDefSymbols.end());
338 llvm::sort(Section.TLVSymbols.begin(), Section.TLVSymbols.end());
339 Exports.emplace_back(std::move(Section));
340 }
341
342 ArchSet.clear();
343 SymbolToArchSet.clear();
344
345 for (const auto *Symbol : File->undefineds()) {
346 auto Architectures = Symbol->getArchitectures();
347 SymbolToArchSet[Symbol] = Architectures;
348 ArchSet.insert(Architectures);
349 }
350
351 for (auto Architectures : ArchSet) {
352 UndefinedSection Section;
353 Section.Architectures = Architectures;
354
355 for (const auto &SymArch : SymbolToArchSet) {
356 if (SymArch.second != Architectures)
357 continue;
358
359 const auto *Symbol = SymArch.first;
360 switch (Symbol->getKind()) {
361 case SymbolKind::GlobalSymbol:
362 if (Symbol->isWeakReferenced())
363 Section.WeakRefSymbols.emplace_back(Symbol->getName());
364 else
365 Section.Symbols.emplace_back(Symbol->getName());
366 break;
367 case SymbolKind::ObjectiveCClass:
368 if (File->getFileType() != FileType::TBD_V3)
369 Section.Classes.emplace_back(
370 copyString("_" + Symbol->getName().str()));
371 else
372 Section.Classes.emplace_back(Symbol->getName());
373 break;
374 case SymbolKind::ObjectiveCClassEHType:
375 if (File->getFileType() != FileType::TBD_V3)
376 Section.Symbols.emplace_back(
377 copyString("_OBJC_EHTYPE_$_" + Symbol->getName().str()));
378 else
379 Section.ClassEHs.emplace_back(Symbol->getName());
380 break;
381 case SymbolKind::ObjectiveCInstanceVariable:
382 if (File->getFileType() != FileType::TBD_V3)
383 Section.IVars.emplace_back(
384 copyString("_" + Symbol->getName().str()));
385 else
386 Section.IVars.emplace_back(Symbol->getName());
387 break;
388 }
389 }
390 llvm::sort(Section.Symbols.begin(), Section.Symbols.end());
391 llvm::sort(Section.Classes.begin(), Section.Classes.end());
392 llvm::sort(Section.ClassEHs.begin(), Section.ClassEHs.end());
393 llvm::sort(Section.IVars.begin(), Section.IVars.end());
394 llvm::sort(Section.WeakRefSymbols.begin(),
395 Section.WeakRefSymbols.end());
396 Undefineds.emplace_back(std::move(Section));
397 }
398 }
399
400 const InterfaceFile *denormalize(IO &IO) {
401 auto Ctx = reinterpret_cast(IO.getContext());
402 assert(Ctx);
403
404 auto *File = new InterfaceFile;
405 File->setPath(Ctx->Path);
406 File->setFileType(Ctx->FileKind);
407 for (auto &ID : UUIDs)
408 File->addUUID(ID.first, ID.second);
409 File->setPlatform(Platform);
410 File->setArchitectures(Architectures);
411 File->setInstallName(InstallName);
412 File->setCurrentVersion(CurrentVersion);
413 File->setCompatibilityVersion(CompatibilityVersion);
414 File->setSwiftABIVersion(SwiftABIVersion);
415 File->setObjCConstraint(ObjCConstraint);
416 File->setParentUmbrella(ParentUmbrella);
417
418 if (Ctx->FileKind == FileType::TBD_V1) {
419 File->setTwoLevelNamespace();
420 File->setApplicationExtensionSafe();
421 } else {
422 File->setTwoLevelNamespace(!(Flags & TBDFlags::FlatNamespace));
423 File->setApplicationExtensionSafe(
424 !(Flags & TBDFlags::NotApplicationExtensionSafe));
425 File->setInstallAPI(Flags & TBDFlags::InstallAPI);
426 }
427
428 for (const auto &Section : Exports) {
429 for (const auto &Library : Section.AllowableClients)
430 File->addAllowableClient(Library, Section.Architectures);
431 for (const auto &Library : Section.ReexportedLibraries)
432 File->addReexportedLibrary(Library, Section.Architectures);
433
434 for (const auto &Symbol : Section.Symbols) {
435 if (Ctx->FileKind != FileType::TBD_V3 &&
436 Symbol.value.startswith("_OBJC_EHTYPE_$_"))
437 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
438 Symbol.value.drop_front(15), Section.Architectures);
439 else
440 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
441 Section.Architectures);
442 }
443 for (auto &Symbol : Section.Classes) {
444 auto Name = Symbol.value;
445 if (Ctx->FileKind != FileType::TBD_V3)
446 Name = Name.drop_front();
447 File->addSymbol(SymbolKind::ObjectiveCClass, Name,
448 Section.Architectures);
449 }
450 for (auto &Symbol : Section.ClassEHs)
451 File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
452 Section.Architectures);
453 for (auto &Symbol : Section.IVars) {
454 auto Name = Symbol.value;
455 if (Ctx->FileKind != FileType::TBD_V3)
456 Name = Name.drop_front();
457 File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
458 Section.Architectures);
459 }
460 for (auto &Symbol : Section.WeakDefSymbols)
461 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
462 Section.Architectures, SymbolFlags::WeakDefined);
463 for (auto &Symbol : Section.TLVSymbols)
464 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
465 Section.Architectures, SymbolFlags::ThreadLocalValue);
466 }
467
468 for (const auto &Section : Undefineds) {
469 for (auto &Symbol : Section.Symbols) {
470 if (Ctx->FileKind != FileType::TBD_V3 &&
471 Symbol.value.startswith("_OBJC_EHTYPE_$_"))
472 File->addSymbol(SymbolKind::ObjectiveCClassEHType,
473 Symbol.value.drop_front(15), Section.Architectures,
474 SymbolFlags::Undefined);
475 else
476 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
477 Section.Architectures, SymbolFlags::Undefined);
478 }
479 for (auto &Symbol : Section.Classes) {
480 auto Name = Symbol.value;
481 if (Ctx->FileKind != FileType::TBD_V3)
482 Name = Name.drop_front();
483 File->addSymbol(SymbolKind::ObjectiveCClass, Name,
484 Section.Architectures, SymbolFlags::Undefined);
485 }
486 for (auto &Symbol : Section.ClassEHs)
487 File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
488 Section.Architectures, SymbolFlags::Undefined);
489 for (auto &Symbol : Section.IVars) {
490 auto Name = Symbol.value;
491 if (Ctx->FileKind != FileType::TBD_V3)
492 Name = Name.drop_front();
493 File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
494 Section.Architectures, SymbolFlags::Undefined);
495 }
496 for (auto &Symbol : Section.WeakRefSymbols)
497 File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
498 Section.Architectures,
499 SymbolFlags::Undefined | SymbolFlags::WeakReferenced);
500 }
501
502 return File;
503 }
504
505 llvm::BumpPtrAllocator Allocator;
506 StringRef copyString(StringRef String) {
507 if (String.empty())
508 return {};
509
510 void *Ptr = Allocator.Allocate(String.size(), 1);
511 memcpy(Ptr, String.data(), String.size());
512 return StringRef(reinterpret_cast(Ptr), String.size());
513 }
514
515 std::vector Architectures;
516 std::vector UUIDs;
517 PlatformKind Platform{PlatformKind::unknown};
518 StringRef InstallName;
519 PackedVersion CurrentVersion;
520 PackedVersion CompatibilityVersion;
521 SwiftVersion SwiftABIVersion{0};
522 ObjCConstraintType ObjCConstraint{ObjCConstraintType::None};
523 TBDFlags Flags{TBDFlags::None};
524 StringRef ParentUmbrella;
525 std::vector Exports;
526 std::vector Undefineds;
527 };
528
529 static void mapping(IO &IO, const InterfaceFile *&File) {
530 auto *Ctx = reinterpret_cast(IO.getContext());
531 assert((!Ctx || !IO.outputting() ||
532 (Ctx && Ctx->FileKind != FileType::Invalid)) &&
533 "File type is not set in YAML context");
534 MappingNormalization Keys(IO, File);
535
536 // prope file type when reading.
537 if (!IO.outputting()) {
538 if (IO.mapTag("!tapi-tbd-v2", false))
539 Ctx->FileKind = FileType::TBD_V2;
540 else if (IO.mapTag("!tapi-tbd-v3", false))
541 Ctx->FileKind = FileType::TBD_V2;
542 else if (IO.mapTag("!tapi-tbd-v1", false) ||
543 IO.mapTag("tag:yaml.org,2002:map", false))
544 Ctx->FileKind = FileType::TBD_V1;
545 else {
546 IO.setError("unsupported file type");
547 return;
548 }
549 }
550
551 // Set file tyoe when writing.
552 if (IO.outputting()) {
553 switch (Ctx->FileKind) {
554 default:
555 llvm_unreachable("unexpected file type");
556 case FileType::TBD_V1:
557 // Don't write the tag into the .tbd file for TBD v1.
558 break;
559 case FileType::TBD_V2:
560 IO.mapTag("!tapi-tbd-v2", true);
561 break;
562 case FileType::TBD_V3:
563 IO.mapTag("!tapi-tbd-v3", true);
564 break;
565 }
566 }
567
568 IO.mapRequired("archs", Keys->Architectures);
569 if (Ctx->FileKind != FileType::TBD_V1)
570 IO.mapOptional("uuids", Keys->UUIDs);
571 IO.mapRequired("platform", Keys->Platform);
572 if (Ctx->FileKind != FileType::TBD_V1)
573 IO.mapOptional("flags", Keys->Flags, TBDFlags::None);
574 IO.mapRequired("install-name", Keys->InstallName);
575 IO.mapOptional("current-version", Keys->CurrentVersion,
576 PackedVersion(1, 0, 0));
577 IO.mapOptional("compatibility-version", Keys->CompatibilityVersion,
578 PackedVersion(1, 0, 0));
579 if (Ctx->FileKind != FileType::TBD_V3)
580 IO.mapOptional("swift-version", Keys->SwiftABIVersion, SwiftVersion(0));
581 else
582 IO.mapOptional("swift-abi-version", Keys->SwiftABIVersion,
583 SwiftVersion(0));
584 IO.mapOptional("objc-constraint", Keys->ObjCConstraint,
585 (Ctx->FileKind == FileType::TBD_V1)
586 ? ObjCConstraintType::None
587 : ObjCConstraintType::Retain_Release);
588 if (Ctx->FileKind != FileType::TBD_V1)
589 IO.mapOptional("parent-umbrella", Keys->ParentUmbrella, StringRef());
590 IO.mapOptional("exports", Keys->Exports);
591 if (Ctx->FileKind != FileType::TBD_V1)
592 IO.mapOptional("undefineds", Keys->Undefineds);
593 }
594 };
595
596 template <>
597 struct DocumentListTraits> {
598 static size_t size(IO &IO, std::vector &Seq) {
599 return Seq.size();
600 }
601 static const InterfaceFile *&
602 element(IO &IO, std::vector &Seq, size_t Index) {
603 if (Index >= Seq.size())
604 Seq.resize(Index + 1);
605 return Seq[Index];
606 }
607 };
608
609 } // end namespace yaml.
610
611 namespace MachO {
612 static void DiagHandler(const SMDiagnostic &Diag, void *Context) {
613 auto *File = static_cast(Context);
614 SmallString<1024> Message;
615 raw_svector_ostream S(Message);
616
617 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), File->Path,
618 Diag.getLineNo(), Diag.getColumnNo(), Diag.getKind(),
619 Diag.getMessage(), Diag.getLineContents(),
620 Diag.getRanges(), Diag.getFixIts());
621
622 NewDiag.print(nullptr, S);
623 File->ErrorMessage = ("malformed file\n" + Message).str();
624 }
625
626 Expected>
627 TextAPIReader::get(std::unique_ptr InputBuffer) {
628 TextAPIContext Ctx;
629 Ctx.Path = InputBuffer->getBufferIdentifier();
630 yaml::Input YAMLIn(InputBuffer->getBuffer(), &Ctx, DiagHandler, &Ctx);
631
632 // Fill vector with interface file objects created by parsing the YAML file.
633 std::vector Files;
634 YAMLIn >> Files;
635
636 if (YAMLIn.error())
637 return make_error(Ctx.ErrorMessage, YAMLIn.error());
638
639 auto *File = const_cast(Files.front());
640 return std::unique_ptr(File);
641 }
642
643 Error TextAPIWriter::writeToStream(raw_ostream &OS, const InterfaceFile &File) {
644 TextAPIContext Ctx;
645 Ctx.Path = File.getPath();
646 Ctx.FileKind = File.getFileType();
647 llvm::yaml::Output YAMLOut(OS, &Ctx, /*WrapColumn=*/80);
648
649 std::vector Files;
650 Files.emplace_back(&File);
651
652 // Stream out yaml.
653 YAMLOut << Files;
654
655 return Error::success();
656 }
657
658 } // end namespace MachO.
659 } // end namespace llvm.
+0
-180
lib/TextAPI/MachO/TextStubCommon.cpp less more
None //===- lib/TextAPI/TextStubCommon.cpp - Text Stub Common --------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Implememts common Text Stub YAML mappings.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "TextStubCommon.h"
15 #include "TextAPIContext.h"
16
17 using namespace llvm::MachO;
18
19 namespace llvm {
20 namespace yaml {
21
22 void ScalarTraits::output(const FlowStringRef &Value, void *Ctx,
23 raw_ostream &OS) {
24 ScalarTraits::output(Value, Ctx, OS);
25 }
26 StringRef ScalarTraits::input(StringRef Value, void *Ctx,
27 FlowStringRef &Out) {
28 return ScalarTraits::input(Value, Ctx, Out.value);
29 }
30 QuotingType ScalarTraits::mustQuote(StringRef Name) {
31 return ScalarTraits::mustQuote(Name);
32 }
33
34 void ScalarEnumerationTraits::enumeration(
35 IO &IO, ObjCConstraintType &Constraint) {
36 IO.enumCase(Constraint, "none", ObjCConstraintType::None);
37 IO.enumCase(Constraint, "retain_release", ObjCConstraintType::Retain_Release);
38 IO.enumCase(Constraint, "retain_release_for_simulator",
39 ObjCConstraintType::Retain_Release_For_Simulator);
40 IO.enumCase(Constraint, "retain_release_or_gc",
41 ObjCConstraintType::Retain_Release_Or_GC);
42 IO.enumCase(Constraint, "gc", ObjCConstraintType::GC);
43 }
44
45 void ScalarTraits::output(const PlatformKind &Value, void *,
46 raw_ostream &OS) {
47 switch (Value) {
48 default:
49 llvm_unreachable("unexpected platform");
50 break;
51 case PlatformKind::macOS:
52 OS << "macosx";
53 break;
54 case PlatformKind::iOS:
55 OS << "ios";
56 break;
57 case PlatformKind::watchOS:
58 OS << "watchos";
59 break;
60 case PlatformKind::tvOS:
61 OS << "tvos";
62 break;
63 case PlatformKind::bridgeOS:
64 OS << "bridgeos";
65 break;
66 }
67 }
68 StringRef ScalarTraits::input(StringRef Scalar, void *,
69 PlatformKind &Value) {
70 Value = StringSwitch(Scalar)
71 .Case("macosx", PlatformKind::macOS)
72 .Case("ios", PlatformKind::iOS)
73 .Case("watchos", PlatformKind::watchOS)
74 .Case("tvos", PlatformKind::tvOS)
75 .Case("bridgeos", PlatformKind::bridgeOS)
76 .Default(PlatformKind::unknown);
77
78 if (Value == PlatformKind::unknown)
79 return "unknown platform";
80 return {};
81 }
82 QuotingType ScalarTraits::mustQuote(StringRef) {
83 return QuotingType::None;
84 }
85
86 void ScalarBitSetTraits::bitset(IO &IO,
87 ArchitectureSet &Archs) {
88 #define ARCHINFO(arch, type, subtype) \
89 IO.bitSetCase(Archs, #arch, 1U << static_cast(Architecture::arch));
90 #include "llvm/TextAPI/MachO/Architecture.def"
91 #undef ARCHINFO
92 }
93
94 void ScalarTraits::output(const Architecture &Value, void *,
95 raw_ostream &OS) {
96 OS << Value;
97 }
98 StringRef ScalarTraits::input(StringRef Scalar, void *,
99 Architecture &Value) {
100 Value = getArchitectureFromName(Scalar);
101 return {};
102 }
103 QuotingType ScalarTraits::mustQuote(StringRef) {
104 return QuotingType::None;
105 }
106
107 void ScalarTraits::output(const PackedVersion &Value, void *,
108 raw_ostream &OS) {
109 OS << Value;
110 }
111 StringRef ScalarTraits::input(StringRef Scalar, void *,
112 PackedVersion &Value) {
113 if (!Value.parse32(Scalar))
114 return "invalid packed version string.";
115 return {};
116 }
117 QuotingType ScalarTraits::mustQuote(StringRef) {
118 return QuotingType::None;
119 }
120
121 void ScalarTraits::output(const SwiftVersion &Value, void *,
122 raw_ostream &OS) {
123 switch (Value) {
124 case 1:
125 OS << "1.0";
126 break;
127 case 2:
128 OS << "1.1";
129 break;
130 case 3:
131 OS << "2.0";
132 break;
133 case 4:
134 OS << "3.0";
135 break;
136 default:
137 OS << (unsigned)Value;
138 break;
139 }
140 }
141 StringRef ScalarTraits::input(StringRef Scalar, void *,
142 SwiftVersion &Value) {
143 Value = StringSwitch(Scalar)
144 .Case("1.0", 1)
145 .Case("1.1", 2)
146 .Case("2.0", 3)
147 .Case("3.0", 4)
148 .Default(0);
149 if (Value != SwiftVersion(0))
150 return {};
151
152 if (Scalar.getAsInteger(10, Value))
153 return "invalid Swift ABI version.";
154
155 return StringRef();
156 }
157 QuotingType ScalarTraits::mustQuote(StringRef) {
158 return QuotingType::None;
159 }
160
161 void ScalarTraits::output(const UUID &Value, void *, raw_ostream &OS) {
162 OS << Value.first << ": " << Value.second;
163 }
164 StringRef ScalarTraits::input(StringRef Scalar, void *, UUID &Value) {
165 auto Split = Scalar.split(':');
166 auto Arch = Split.first.trim();
167 auto UUID = Split.second.trim();
168 if (UUID.empty())
169 return "invalid uuid string pair";
170 Value.first = getArchitectureFromName(Arch);
171 Value.second = UUID;
172 return {};
173 }
174 QuotingType ScalarTraits::mustQuote(StringRef) {
175 return QuotingType::Single;
176 }
177
178 } // end namespace yaml.
179 } // end namespace llvm.
+0
-83
lib/TextAPI/MachO/TextStubCommon.h less more
None //===- llvm/TextAPI/TextStubCommon.h - Text Stub Common ---------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief Defines common Text Stub YAML mappings.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TEXTAPI_TEXT_STUB_COMMON_H
15 #define LLVM_TEXTAPI_TEXT_STUB_COMMON_H
16
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/Support/YAMLTraits.h"
20 #include "llvm/TextAPI/MachO/Architecture.h"
21 #include "llvm/TextAPI/MachO/ArchitectureSet.h"
22 #include "llvm/TextAPI/MachO/InterfaceFile.h"
23 #include "llvm/TextAPI/MachO/PackedVersion.h"
24
25 using UUID = std::pair;
26
27 LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, FlowStringRef)
28 LLVM_YAML_STRONG_TYPEDEF(uint8_t, SwiftVersion)
29 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(UUID)
30 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FlowStringRef)
31
32 namespace llvm {
33 namespace yaml {
34
35 template <> struct ScalarTraits {
36 static void output(const FlowStringRef &, void *, raw_ostream &);
37 static StringRef input(StringRef, void *, FlowStringRef &);
38 static QuotingType mustQuote(StringRef);
39 };
40
41 template <> struct ScalarEnumerationTraits {
42 static void enumeration(IO &, MachO::ObjCConstraintType &);
43 };
44
45 template <> struct ScalarTraits {
46 static void output(const MachO::PlatformKind &, void *, raw_ostream &);
47 static StringRef input(StringRef, void *, MachO::PlatformKind &);
48 static QuotingType mustQuote(StringRef);
49 };
50
51 template <> struct ScalarBitSetTraits {
52 static void bitset(IO &, MachO::ArchitectureSet &);
53 };
54
55 template <> struct ScalarTraits {
56 static void output(const MachO::Architecture &, void *, raw_ostream &);
57 static StringRef input(StringRef, void *, MachO::Architecture &);
58 static QuotingType mustQuote(StringRef);
59 };
60
61 template <> struct ScalarTraits {
62 static void output(const MachO::PackedVersion &, void *, raw_ostream &);
63 static StringRef input(StringRef, void *, MachO::PackedVersion &);
64 static QuotingType mustQuote(StringRef);
65 };
66
67 template <> struct ScalarTraits {
68 static void output(const SwiftVersion &, void *, raw_ostream &);
69 static StringRef input(StringRef, void *, SwiftVersion &);
70 static QuotingType mustQuote(StringRef);
71 };
72
73 template <> struct ScalarTraits {
74 static void output(const UUID &, void *, raw_ostream &);
75 static StringRef input(StringRef, void *, UUID &);
76 static QuotingType mustQuote(StringRef);
77 };
78
79 } // end namespace yaml.
80 } // end namespace llvm.
81
82 #endif // LLVM_TEXTAPI_TEXT_STUB_COMMON_H
3030 add_subdirectory(ProfileData)
3131 add_subdirectory(Support)
3232 add_subdirectory(Target)
33 add_subdirectory(TextAPI)
3433 add_subdirectory(Transforms)
3534 add_subdirectory(XRay)
3635 add_subdirectory(tools)
+0
-8
unittests/TextAPI/CMakeLists.txt less more
None set(LLVM_LINK_COMPONENTS
1 TextAPI
2 )
3
4 add_llvm_unittest(TextAPITests
5 TextStubV1Tests.cpp
6 TextStubV2Tests.cpp
7 )
+0
-456
unittests/TextAPI/TextStubV1Tests.cpp less more
None //===-- TextStubV1Tests.cpp - TBD V1 File Test ----------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 #include "llvm/TextAPI/MachO/InterfaceFile.h"
9 #include "llvm/TextAPI/MachO/TextAPIReader.h"
10 #include "llvm/TextAPI/MachO/TextAPIWriter.h"
11 #include "gtest/gtest.h"
12 #include
13 #include
14
15 using namespace llvm;
16 using namespace llvm::MachO;
17
18 struct ExportedSymbol {
19 SymbolKind Kind;
20 std::string Name;
21 bool WeakDefined;
22 bool ThreadLocalValue;
23 };
24 using ExportedSymbolSeq = std::vector;
25
26 inline bool operator<(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
27 return std::tie(lhs.Kind, lhs.Name) < std::tie(rhs.Kind, rhs.Name);
28 }
29
30 inline bool operator==(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
31 return std::tie(lhs.Kind, lhs.Name, lhs.WeakDefined, lhs.ThreadLocalValue) ==
32 std::tie(rhs.Kind, rhs.Name, rhs.WeakDefined, rhs.ThreadLocalValue);
33 }
34
35 static ExportedSymbol TBDv1Symbols[] = {
36 {SymbolKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},
37 {SymbolKind::GlobalSymbol, "_sym1", false, false},
38 {SymbolKind::GlobalSymbol, "_sym2", false, false},
39 {SymbolKind::GlobalSymbol, "_sym3", false, false},
40 {SymbolKind::GlobalSymbol, "_sym4", false, false},
41 {SymbolKind::GlobalSymbol, "_sym5", false, false},
42 {SymbolKind::GlobalSymbol, "_tlv1", false, true},
43 {SymbolKind::GlobalSymbol, "_tlv2", false, true},
44 {SymbolKind::GlobalSymbol, "_tlv3", false, true},
45 {SymbolKind::GlobalSymbol, "_weak1", true, false},
46 {SymbolKind::GlobalSymbol, "_weak2", true, false},
47 {SymbolKind::GlobalSymbol, "_weak3", true, false},
48 {SymbolKind::ObjectiveCClass, "class1", false, false},
49 {SymbolKind::ObjectiveCClass, "class2", false, false},
50 {SymbolKind::ObjectiveCClass, "class3", false, false},
51 {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},
52 {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},
53 {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},
54 };
55
56 namespace TBDv1 {
57
58 TEST(TBDv1, ReadFile) {
59 static const char tbd_v1_file1[] =
60 "---\n"
61 "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
62 "platform: ios\n"
63 "install-name: Test.dylib\n"
64 "current-version: 2.3.4\n"
65 "compatibility-version: 1.0\n"
66 "swift-version: 1.1\n"
67 "exports:\n"
68 " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
69 " allowed-clients: [ clientA ]\n"
70 " re-exports: [ /usr/lib/libfoo.dylib ]\n"
71 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
72 " objc-classes: [ _class1, _class2 ]\n"
73 " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
74 " weak-def-symbols: [ _weak1, _weak2 ]\n"
75 " thread-local-symbols: [ _tlv1, _tlv2 ]\n"
76 " - archs: [ armv7, armv7s, armv7k ]\n"
77 " symbols: [ _sym5 ]\n"
78 " objc-classes: [ _class3 ]\n"
79 " objc-ivars: [ _class1._ivar3 ]\n"
80 " weak-def-symbols: [ _weak3 ]\n"
81 " thread-local-symbols: [ _tlv3 ]\n"
82 "...\n";
83
84 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_file1, "Test.tbd");
85 auto Result = TextAPIReader::get(std::move(Buffer));
86 EXPECT_TRUE(!!Result);
87 auto File = std::move(Result.get());
88 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
89 auto Archs = Architecture::armv7 | Architecture::armv7s |
90 Architecture::armv7k | Architecture::arm64;
91 EXPECT_EQ(Archs, File->getArchitectures());
92 EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
93 EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
94 EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
95 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
96 EXPECT_EQ(2U, File->getSwiftABIVersion());
97 EXPECT_EQ(ObjCConstraintType::None, File->getObjCConstraint());
98 EXPECT_TRUE(File->isTwoLevelNamespace());
99 EXPECT_TRUE(File->isApplicationExtensionSafe());
100 EXPECT_FALSE(File->isInstallAPI());
101 InterfaceFileRef client("clientA", Archs);
102 InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
103 EXPECT_EQ(1U, File->allowableClients().size());
104 EXPECT_EQ(client, File->allowableClients().front());
105 EXPECT_EQ(1U, File->reexportedLibraries().size());
106 EXPECT_EQ(reexport, File->reexportedLibraries().front());
107
108 ExportedSymbolSeq Exports;
109 for (const auto *Sym : File->symbols()) {
110 EXPECT_FALSE(Sym->isWeakReferenced());
111 EXPECT_FALSE(Sym->isUndefined());
112 Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName(),
113 Sym->isWeakDefined(),
114 Sym->isThreadLocalValue()});
115 }
116 llvm::sort(Exports.begin(), Exports.end());
117
118 EXPECT_EQ(sizeof(TBDv1Symbols) / sizeof(ExportedSymbol), Exports.size());
119 EXPECT_TRUE(
120 std::equal(Exports.begin(), Exports.end(), std::begin(TBDv1Symbols)));
121 }
122
123 TEST(TBDv1, ReadFile2) {
124 static const char tbd_v1_file2[] = "--- !tapi-tbd-v1\n"
125 "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
126 "platform: ios\n"
127 "install-name: Test.dylib\n"
128 "...\n";
129
130 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_file2, "Test.tbd");
131 auto Result = TextAPIReader::get(std::move(Buffer));
132 EXPECT_TRUE(!!Result);
133 auto File = std::move(Result.get());
134 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
135 auto Archs = Architecture::armv7 | Architecture::armv7s |
136 Architecture::armv7k | Architecture::arm64;
137 EXPECT_EQ(Archs, File->getArchitectures());
138 EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
139 EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
140 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
141 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
142 EXPECT_EQ(0U, File->getSwiftABIVersion());
143 EXPECT_EQ(ObjCConstraintType::None, File->getObjCConstraint());
144 EXPECT_TRUE(File->isTwoLevelNamespace());
145 EXPECT_TRUE(File->isApplicationExtensionSafe());
146 EXPECT_FALSE(File->isInstallAPI());
147 EXPECT_EQ(0U, File->allowableClients().size());
148 EXPECT_EQ(0U, File->reexportedLibraries().size());
149 }
150
151 TEST(TBDv1, WriteFile) {
152 static const char tbd_v1_file3[] =
153 "---\n"
154 "archs: [ i386, x86_64 ]\n"
155 "platform: macosx\n"
156 "install-name: '/usr/lib/libfoo.dylib'\n"
157 "current-version: 1.2.3\n"
158 "compatibility-version: 0\n"
159 "swift-version: 5\n"
160 "objc-constraint: retain_release\n"
161 "exports: \n"
162 " - archs: [ i386 ]\n"
163 " symbols: [ _sym1 ]\n"
164 " weak-def-symbols: [ _sym2 ]\n"
165 " thread-local-symbols: [ _sym3 ]\n"
166 " - archs: [ x86_64 ]\n"
167 " allowed-clients: [ clientA ]\n"
168 " re-exports: [ '/usr/lib/libfoo.dylib' ]\n"
169 " symbols: [ '_OBJC_EHTYPE_$_Class1' ]\n"
170 " objc-classes: [ _Class1 ]\n"
171 " objc-ivars: [ _Class1._ivar1 ]\n"
172 "...\n";
173
174 InterfaceFile File;
175 File.setPath("libfoo.dylib");
176 File.setInstallName("/usr/lib/libfoo.dylib");
177 File.setFileType(FileType::TBD_V1);
178 File.setArchitectures(Architecture::i386 | Architecture::x86_64);
179 File.setPlatform(PlatformKind::macOS);
180 File.setCurrentVersion(PackedVersion(1, 2, 3));
181 File.setSwiftABIVersion(5);
182 File.setObjCConstraint(ObjCConstraintType::Retain_Release);
183 File.addAllowableClient("clientA", Architecture::x86_64);
184 File.addReexportedLibrary("/usr/lib/libfoo.dylib", Architecture::x86_64);
185 File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", Architecture::i386);
186 File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", Architecture::i386,
187 SymbolFlags::WeakDefined);
188 File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", Architecture::i386,
189 SymbolFlags::ThreadLocalValue);
190 File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", Architecture::x86_64);
191 File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1",
192 Architecture::x86_64);
193 File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
194 Architecture::x86_64);
195
196 SmallString<4096> Buffer;
197 raw_svector_ostream OS(Buffer);
198 auto Result = TextAPIWriter::writeToStream(OS, File);
199 EXPECT_FALSE(Result);
200 EXPECT_STREQ(tbd_v1_file3, Buffer.c_str());
201 }
202
203 TEST(TBDv1, Platform_macOS) {
204 static const char tbd_v1_platform_macos[] = "---\n"
205 "archs: [ x86_64 ]\n"
206 "platform: macosx\n"
207 "install-name: Test.dylib\n"
208 "...\n";
209
210 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_macos, "Test.tbd");
211 auto Result = TextAPIReader::get(std::move(Buffer));
212 EXPECT_TRUE(!!Result);
213 auto File = std::move(Result.get());
214 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
215 EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
216 }
217
218 TEST(TBDv1, Platform_iOS) {
219 static const char tbd_v1_platform_ios[] = "---\n"
220 "archs: [ arm64 ]\n"
221 "platform: ios\n"
222 "install-name: Test.dylib\n"
223 "...\n";
224
225 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_ios, "Test.tbd");
226 auto Result = TextAPIReader::get(std::move(Buffer));
227 EXPECT_TRUE(!!Result);
228 auto File = std::move(Result.get());
229 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
230 EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
231 }
232
233 TEST(TBDv1, Platform_watchOS) {
234 static const char tbd_v1_platform_watchos[] = "---\n"
235 "archs: [ armv7k ]\n"
236 "platform: watchos\n"
237 "install-name: Test.dylib\n"
238 "...\n";
239
240 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_watchos, "Test.tbd");
241 auto Result = TextAPIReader::get(std::move(Buffer));
242 EXPECT_TRUE(!!Result);
243 auto File = std::move(Result.get());
244 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
245 EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
246 }
247
248 TEST(TBDv1, Platform_tvOS) {
249 static const char tbd_v1_platform_tvos[] = "---\n"
250 "archs: [ arm64 ]\n"
251 "platform: tvos\n"
252 "install-name: Test.dylib\n"
253 "...\n";
254
255 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_tvos, "Test.tbd");
256 auto Result = TextAPIReader::get(std::move(Buffer));
257 EXPECT_TRUE(!!Result);
258 auto File = std::move(Result.get());
259 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
260 EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
261 }
262
263 TEST(TBDv1, Platform_bridgeOS) {
264 static const char tbd_v1_platform_bridgeos[] = "---\n"
265 "archs: [ armv7k ]\n"
266 "platform: bridgeos\n"
267 "install-name: Test.dylib\n"
268 "...\n";
269
270 auto Buffer =
271 MemoryBuffer::getMemBuffer(tbd_v1_platform_bridgeos, "Test.tbd");
272 auto Result = TextAPIReader::get(std::move(Buffer));
273 EXPECT_TRUE(!!Result);
274 auto File = std::move(Result.get());
275 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
276 EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
277 }
278
279 TEST(TBDv1, Swift_1_0) {
280 static const char tbd_v1_swift_1_0[] = "---\n"
281 "archs: [ arm64 ]\n"
282 "platform: ios\n"
283 "install-name: Test.dylib\n"
284 "swift-version: 1.0\n"
285 "...\n";
286
287 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_0, "Test.tbd");
288 auto Result = TextAPIReader::get(std::move(Buffer));
289 EXPECT_TRUE(!!Result);
290 auto File = std::move(Result.get());
291 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
292 EXPECT_EQ(1U, File->getSwiftABIVersion());
293 }
294
295 TEST(TBDv1, Swift_1_1) {
296 static const char tbd_v1_swift_1_1[] = "---\n"
297 "archs: [ arm64 ]\n"
298 "platform: ios\n"
299 "install-name: Test.dylib\n"
300 "swift-version: 1.1\n"
301 "...\n";
302
303 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_1, "Test.tbd");
304 auto Result = TextAPIReader::get(std::move(Buffer));
305 EXPECT_TRUE(!!Result);
306 auto File = std::move(Result.get());
307 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
308 EXPECT_EQ(2U, File->getSwiftABIVersion());
309 }
310
311 TEST(TBDv1, Swift_2_0) {
312 static const char tbd_v1_swift_2_0[] = "---\n"
313 "archs: [ arm64 ]\n"
314 "platform: ios\n"
315 "install-name: Test.dylib\n"
316 "swift-version: 2.0\n"
317 "...\n";
318
319 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_2_0, "Test.tbd");
320 auto Result = TextAPIReader::get(std::move(Buffer));
321 EXPECT_TRUE(!!Result);
322 auto File = std::move(Result.get());
323 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
324 EXPECT_EQ(3U, File->getSwiftABIVersion());
325 }
326
327 TEST(TBDv1, Swift_3_0) {
328 static const char tbd_v1_swift_3_0[] = "---\n"
329 "archs: [ arm64 ]\n"
330 "platform: ios\n"
331 "install-name: Test.dylib\n"
332 "swift-version: 3.0\n"
333 "...\n";
334
335 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_3_0, "Test.tbd");
336 auto Result = TextAPIReader::get(std::move(Buffer));
337 EXPECT_TRUE(!!Result);
338 auto File = std::move(Result.get());
339 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
340 EXPECT_EQ(4U, File->getSwiftABIVersion());
341 }
342
343 TEST(TBDv1, Swift_4_0) {
344 static const char tbd_v1_swift_4_0[] = "---\n"
345 "archs: [ arm64 ]\n"
346 "platform: ios\n"
347 "install-name: Test.dylib\n"
348 "swift-version: 4.0\n"
349 "...\n";
350
351 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_4_0, "Test.tbd");
352 auto Result = TextAPIReader::get(std::move(Buffer));
353 EXPECT_FALSE(!!Result);
354 auto errorMessage = toString(Result.takeError());
355 EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI "
356 "version.\nswift-version: 4.0\n ^~~\n",
357 errorMessage);
358 }
359
360 TEST(TBDv1, Swift_5) {
361 static const char tbd_v1_swift_5[] = "---\n"
362 "archs: [ arm64 ]\n"
363 "platform: ios\n"
364 "install-name: Test.dylib\n"
365 "swift-version: 5\n"
366 "...\n";
367
368 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_5, "Test.tbd");
369 auto Result = TextAPIReader::get(std::move(Buffer));
370 EXPECT_TRUE(!!Result);
371 auto File = std::move(Result.get());
372 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
373 EXPECT_EQ(5U, File->getSwiftABIVersion());
374 }
375
376 TEST(TBDv1, Swift_99) {
377 static const char tbd_v1_swift_99[] = "---\n"
378 "archs: [ arm64 ]\n"
379 "platform: ios\n"
380 "install-name: Test.dylib\n"
381 "swift-version: 99\n"
382 "...\n";
383
384 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_99, "Test.tbd");
385 auto Result = TextAPIReader::get(std::move(Buffer));
386 EXPECT_TRUE(!!Result);
387 auto File = std::move(Result.get());
388 EXPECT_EQ(FileType::TBD_V1, File->getFileType());
389 EXPECT_EQ(99U, File->getSwiftABIVersion());
390 }
391
392 TEST(TBDv1, UnknownArchitecture) {
393 static const char tbd_v1_file_unknown_architecture[] =
394 "---\n"
395 "archs: [ foo ]\n"
396 "platform: macosx\n"
397 "install-name: Test.dylib\n"
398 "...\n";
399
400 auto Buffer =
401 MemoryBuffer::getMemBuffer(tbd_v1_file_unknown_architecture, "Test.tbd");
402 auto Result = TextAPIReader::get(std::move(Buffer));
403 EXPECT_TRUE(!!Result);
404 }
405
406 TEST(TBDv1, UnknownPlatform) {
407 static const char tbd_v1_file_unknown_platform[] = "---\n"
408 "archs: [ i386 ]\n"
409 "platform: newOS\n"
410 "...\n";
411
412 auto Buffer =
413 MemoryBuffer::getMemBuffer(tbd_v1_file_unknown_platform, "Test.tbd");
414 auto Result = TextAPIReader::get(std::move(Buffer));
415 EXPECT_FALSE(!!Result);
416 auto errorMessage = toString(Result.takeError());
417 EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
418 "newOS\n ^~~~~\n",
419 errorMessage);
420 }
421
422 TEST(TBDv1, MalformedFile1) {
423 static const char malformed_file1[] = "---\n"
424 "archs: [ arm64 ]\n"
425 "foobar: \"Unsupported key\"\n"
426 "...\n";
427
428 auto Buffer = MemoryBuffer::getMemBuffer(malformed_file1, "Test.tbd");
429 auto Result = TextAPIReader::get(std::move(Buffer));
430 EXPECT_FALSE(!!Result);
431 auto errorMessage = toString(Result.takeError());
432 ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
433 "'platform'\narchs: [ arm64 ]\n^\n",
434 errorMessage);
435 }
436
437 TEST(TBDv1, MalformedFile2) {
438 static const char malformed_file2[] = "---\n"
439 "archs: [ arm64 ]\n"
440 "platform: ios\n"
441 "install-name: Test.dylib\n"
442 "foobar: \"Unsupported key\"\n"
443 "...\n";
444
445 auto Buffer = MemoryBuffer::getMemBuffer(malformed_file2, "Test.tbd");
446 auto Result = TextAPIReader::get(std::move(Buffer));
447 EXPECT_FALSE(!!Result);
448 auto errorMessage = toString(Result.takeError());
449 ASSERT_EQ(
450 "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
451 "\"Unsupported key\"\n ^~~~~~~~~~~~~~~~~\n",
452 errorMessage);
453 }
454
455 } // end namespace TBDv1.
+0
-481
unittests/TextAPI/TextStubV2Tests.cpp less more
None //===-- TextStubV2Tests.cpp - TBD V2 File Test ----------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 #include "llvm/TextAPI/MachO/InterfaceFile.h"
9 #include "llvm/TextAPI/MachO/TextAPIReader.h"
10 #include "llvm/TextAPI/MachO/TextAPIWriter.h"
11 #include "gtest/gtest.h"
12 #include
13 #include
14
15 using namespace llvm;
16 using namespace llvm::MachO;
17
18 struct ExportedSymbol {
19 SymbolKind Kind;
20 std::string Name;
21 bool WeakDefined;
22 bool ThreadLocalValue;
23 };
24 using ExportedSymbolSeq = std::vector;
25
26 inline bool operator<(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
27 return std::tie(lhs.Kind, lhs.Name) < std::tie(rhs.Kind, rhs.Name);
28 }
29
30 inline bool operator==(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
31 return std::tie(lhs.Kind, lhs.Name, lhs.WeakDefined, lhs.ThreadLocalValue) ==
32 std::tie(rhs.Kind, rhs.Name, rhs.WeakDefined, rhs.ThreadLocalValue);
33 }
34
35 static ExportedSymbol TBDv2Symbols[] = {
36 {SymbolKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},
37 {SymbolKind::GlobalSymbol, "_sym1", false, false},
38 {SymbolKind::GlobalSymbol, "_sym2", false, false},
39 {SymbolKind::GlobalSymbol, "_sym3", false, false},
40 {SymbolKind::GlobalSymbol, "_sym4", false, false},
41 {SymbolKind::GlobalSymbol, "_sym5", false, false},
42 {SymbolKind::GlobalSymbol, "_tlv1", false, true},
43 {SymbolKind::GlobalSymbol, "_tlv2", false, true},
44 {SymbolKind::GlobalSymbol, "_tlv3", false, true},
45 {SymbolKind::GlobalSymbol, "_weak1", true, false},
46 {SymbolKind::GlobalSymbol, "_weak2", true, false},
47 {SymbolKind::GlobalSymbol, "_weak3", true, false},
48 {SymbolKind::ObjectiveCClass, "class1", false, false},
49 {SymbolKind::ObjectiveCClass, "class2", false, false},
50 {SymbolKind::ObjectiveCClass, "class3", false, false},
51 {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},
52 {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},
53 {SymbolKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},
54 };
55
56 namespace TBDv2 {
57
58 TEST(TBDv2, ReadFile) {
59 static const char tbd_v2_file1[] =
60 "--- !tapi-tbd-v2\n"
61 "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
62 "platform: ios\n"
63 "flags: [ installapi ]\n"
64 "install-name: Test.dylib\n"
65 "current-version: 2.3.4\n"
66 "compatibility-version: 1.0\n"
67 "swift-version: 1.1\n"
68 "parent-umbrella: Umbrella.dylib\n"
69 "exports:\n"
70 " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
71 " allowable-clients: [ clientA ]\n"
72 " re-exports: [ /usr/lib/libfoo.dylib ]\n"
73 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
74 " objc-classes: [ _class1, _class2 ]\n"
75 " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
76 " weak-def-symbols: [ _weak1, _weak2 ]\n"
77 " thread-local-symbols: [ _tlv1, _tlv2 ]\n"
78 " - archs: [ armv7, armv7s, armv7k ]\n"
79 " symbols: [ _sym5 ]\n"
80 " objc-classes: [ _class3 ]\n"
81 " objc-ivars: [ _class1._ivar3 ]\n"
82 " weak-def-symbols: [ _weak3 ]\n"
83 " thread-local-symbols: [ _tlv3 ]\n"
84 "...\n";
85
86 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v2_file1, "Test.tbd");
87 auto Result = TextAPIReader::get(std::move(Buffer));
88 EXPECT_TRUE(!!Result);
89 auto File = std::move(Result.get());
90 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
91 auto Archs = Architecture::armv7 | Architecture::armv7s |
92 Architecture::armv7k | Architecture::arm64;
93 EXPECT_EQ(Archs, File->getArchitectures());
94 EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
95 EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
96 EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
97 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
98 EXPECT_EQ(2U, File->getSwiftABIVersion());
99 EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
100 EXPECT_TRUE(File->isTwoLevelNamespace());
101 EXPECT_TRUE(File->isApplicationExtensionSafe());
102 EXPECT_TRUE(File->isInstallAPI());
103 InterfaceFileRef client("clientA", Archs);
104 InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
105 EXPECT_EQ(1U, File->allowableClients().size());
106 EXPECT_EQ(client, File->allowableClients().front());
107 EXPECT_EQ(1U, File->reexportedLibraries().size());
108 EXPECT_EQ(reexport, File->reexportedLibraries().front());
109
110 ExportedSymbolSeq Exports;
111 for (const auto *Sym : File->symbols()) {
112 EXPECT_FALSE(Sym->isWeakReferenced());
113 EXPECT_FALSE(Sym->isUndefined());
114 Exports.emplace_back(ExportedSymbol{Sym->getKind(), Sym->getName(),
115 Sym->isWeakDefined(),
116 Sym->isThreadLocalValue()});
117 }
118 llvm::sort(Exports.begin(), Exports.end());
119
120 EXPECT_EQ(sizeof(TBDv2Symbols) / sizeof(ExportedSymbol), Exports.size());
121 EXPECT_TRUE(
122 std::equal(Exports.begin(), Exports.end(), std::begin(TBDv2Symbols)));
123 }
124
125 TEST(TBDv2, ReadFile2) {
126 static const char tbd_v2_file2[] =
127 "--- !tapi-tbd-v2\n"
128 "archs: [ armv7, armv7s, armv7k, arm64 ]\n"
129 "platform: ios\n"
130 "flags: [ flat_namespace, not_app_extension_safe ]\n"
131 "install-name: Test.dylib\n"
132 "swift-version: 1.1\n"
133 "exports:\n"
134 " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
135 " symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"
136 " objc-classes: [ _class1, _class2 ]\n"
137 " objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"
138 " weak-def-symbols: [ _weak1, _weak2 ]\n"
139 " thread-local-symbols: [ _tlv1, _tlv2 ]\n"
140 " - archs: [ armv7, armv7s, armv7k ]\n"
141 " symbols: [ _sym5 ]\n"
142 " objc-classes: [ _class3 ]\n"
143 " objc-ivars: [ _class1._ivar3 ]\n"
144 " weak-def-symbols: [ _weak3 ]\n"
145 " thread-local-symbols: [ _tlv3 ]\n"
146 "undefineds:\n"
147 " - archs: [ armv7, armv7s, armv7k, arm64 ]\n"
148 " symbols: [ _undefSym1, _undefSym2, _undefSym3 ]\n"
149 " objc-classes: [ _undefClass1, _undefClass2 ]\n"
150 " objc-ivars: [ _undefClass1._ivar1, _undefClass1._ivar2 ]\n"
151 " weak-ref-symbols: [ _undefWeak1, _undefWeak2 ]\n"
152 "...\n";
153
154 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v2_file2, "Test.tbd");
155 auto Result = TextAPIReader::get(std::move(Buffer));
156 EXPECT_TRUE(!!Result);
157 auto File = std::move(Result.get());
158 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
159 auto Archs = Architecture::armv7 | Architecture::armv7s |
160 Architecture::armv7k | Architecture::arm64;
161 EXPECT_EQ(Archs, File->getArchitectures());
162 EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
163 EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
164 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
165 EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
166 EXPECT_EQ(2U, File->getSwiftABIVersion());
167 EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());
168 EXPECT_FALSE(File->isTwoLevelNamespace());
169 EXPECT_FALSE(File->isApplicationExtensionSafe());
170 EXPECT_FALSE(File->isInstallAPI());
171 EXPECT_EQ(0U, File->allowableClients().size());
172 EXPECT_EQ(0U, File->reexportedLibraries().size());
173 }
174
175 TEST(TBDv2, WriteFile) {
176 static const char tbd_v2_file3[] =
177 "--- !tapi-tbd-v2\n"
178 "archs: [ i386, x86_64 ]\n"
179 "platform: macosx\n"
180 "install-name: '/usr/lib/libfoo.dylib'\n"
181 "current-version: 1.2.3\n"
182 "compatibility-version: 0\n"
183 "swift-version: 5\n"
184 "exports: \n"
185 " - archs: [ i386 ]\n"
186 " symbols: [ _sym1 ]\n"
187 " weak-def-symbols: [ _sym2 ]\n"
188 " thread-local-symbols: [ _sym3 ]\n"
189 " - archs: [ x86_64 ]\n"
190 " allowable-clients: [ clientA ]\n"
191 " re-exports: [ '/usr/lib/libfoo.dylib' ]\n"
192 " symbols: [ '_OBJC_EHTYPE_$_Class1' ]\n"
193 " objc-classes: [ _Class1 ]\n"
194 " objc-ivars: [ _Class1._ivar1 ]\n"
195 "...\n";
196
197 InterfaceFile File;
198 File.setPath("libfoo.dylib");
199 File.setInstallName("/usr/lib/libfoo.dylib");
200 File.setFileType(FileType::TBD_V2);
201 File.setArchitectures(Architecture::i386 | Architecture::x86_64);
202 File.setPlatform(PlatformKind::macOS);
203 File.setCurrentVersion(PackedVersion(1, 2, 3));
204 File.setTwoLevelNamespace();
205 File.setApplicationExtensionSafe();
206 File.setSwiftABIVersion(5);
207 File.setObjCConstraint(ObjCConstraintType::Retain_Release);
208 File.addAllowableClient("clientA", Architecture::x86_64);
209 File.addReexportedLibrary("/usr/lib/libfoo.dylib", Architecture::x86_64);
210 File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", Architecture::i386);
211 File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", Architecture::i386,
212 SymbolFlags::WeakDefined);
213 File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", Architecture::i386,
214 SymbolFlags::ThreadLocalValue);
215 File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", Architecture::x86_64);
216 File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1",
217 Architecture::x86_64);
218 File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
219 Architecture::x86_64);
220
221 SmallString<4096> Buffer;
222 raw_svector_ostream OS(Buffer);
223 auto Result = TextAPIWriter::writeToStream(OS, File);
224 EXPECT_FALSE(Result);
225 EXPECT_STREQ(tbd_v2_file3, Buffer.c_str());
226 }
227
228 TEST(TBDv2, Platform_macOS) {
229 static const char tbd_v1_platform_macos[] = "--- !tapi-tbd-v2\n"
230 "archs: [ x86_64 ]\n"
231 "platform: macosx\n"
232 "install-name: Test.dylib\n"
233 "...\n";
234
235 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_macos, "Test.tbd");
236 auto Result = TextAPIReader::get(std::move(Buffer));
237 EXPECT_TRUE(!!Result);
238 auto File = std::move(Result.get());
239 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
240 EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
241 }
242
243 TEST(TBDv2, Platform_iOS) {
244 static const char tbd_v1_platform_ios[] = "--- !tapi-tbd-v2\n"
245 "archs: [ arm64 ]\n"
246 "platform: ios\n"
247 "install-name: Test.dylib\n"
248 "...\n";
249
250 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_ios, "Test.tbd");
251 auto Result = TextAPIReader::get(std::move(Buffer));
252 EXPECT_TRUE(!!Result);
253 auto File = std::move(Result.get());
254 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
255 EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
256 }
257
258 TEST(TBDv2, Platform_watchOS) {
259 static const char tbd_v1_platform_watchos[] = "--- !tapi-tbd-v2\n"
260 "archs: [ armv7k ]\n"
261 "platform: watchos\n"
262 "install-name: Test.dylib\n"
263 "...\n";
264
265 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_watchos, "Test.tbd");
266 auto Result = TextAPIReader::get(std::move(Buffer));
267 EXPECT_TRUE(!!Result);
268 auto File = std::move(Result.get());
269 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
270 EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
271 }
272
273 TEST(TBDv2, Platform_tvOS) {
274 static const char tbd_v1_platform_tvos[] = "--- !tapi-tbd-v2\n"
275 "archs: [ arm64 ]\n"
276 "platform: tvos\n"
277 "install-name: Test.dylib\n"
278 "...\n";
279
280 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_platform_tvos, "Test.tbd");
281 auto Result = TextAPIReader::get(std::move(Buffer));
282 EXPECT_TRUE(!!Result);
283 auto File = std::move(Result.get());
284 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
285 EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
286 }
287
288 TEST(TBDv2, Platform_bridgeOS) {
289 static const char tbd_v1_platform_bridgeos[] = "--- !tapi-tbd-v2\n"
290 "archs: [ armv7k ]\n"
291 "platform: bridgeos\n"
292 "install-name: Test.dylib\n"
293 "...\n";
294
295 auto Buffer =
296 MemoryBuffer::getMemBuffer(tbd_v1_platform_bridgeos, "Test.tbd");
297 auto Result = TextAPIReader::get(std::move(Buffer));
298 EXPECT_TRUE(!!Result);
299 auto File = std::move(Result.get());
300 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
301 EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
302 }
303
304 TEST(TBDv2, Swift_1_0) {
305 static const char tbd_v1_swift_1_0[] = "--- !tapi-tbd-v2\n"
306 "archs: [ arm64 ]\n"
307 "platform: ios\n"
308 "install-name: Test.dylib\n"
309 "swift-version: 1.0\n"
310 "...\n";
311
312 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_0, "Test.tbd");
313 auto Result = TextAPIReader::get(std::move(Buffer));
314 EXPECT_TRUE(!!Result);
315 auto File = std::move(Result.get());
316 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
317 EXPECT_EQ(1U, File->getSwiftABIVersion());
318 }
319
320 TEST(TBDv2, Swift_1_1) {
321 static const char tbd_v1_swift_1_1[] = "--- !tapi-tbd-v2\n"
322 "archs: [ arm64 ]\n"
323 "platform: ios\n"
324 "install-name: Test.dylib\n"
325 "swift-version: 1.1\n"
326 "...\n";
327
328 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_1_1, "Test.tbd");
329 auto Result = TextAPIReader::get(std::move(Buffer));
330 EXPECT_TRUE(!!Result);
331 auto File = std::move(Result.get());
332 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
333 EXPECT_EQ(2U, File->getSwiftABIVersion());
334 }
335
336 TEST(TBDv2, Swift_2_0) {
337 static const char tbd_v1_swift_2_0[] = "--- !tapi-tbd-v2\n"
338 "archs: [ arm64 ]\n"
339 "platform: ios\n"
340 "install-name: Test.dylib\n"
341 "swift-version: 2.0\n"
342 "...\n";
343
344 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_2_0, "Test.tbd");
345 auto Result = TextAPIReader::get(std::move(Buffer));
346 EXPECT_TRUE(!!Result);
347 auto File = std::move(Result.get());
348 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
349 EXPECT_EQ(3U, File->getSwiftABIVersion());
350 }
351
352 TEST(TBDv2, Swift_3_0) {
353 static const char tbd_v1_swift_3_0[] = "--- !tapi-tbd-v2\n"
354 "archs: [ arm64 ]\n"
355 "platform: ios\n"
356 "install-name: Test.dylib\n"
357 "swift-version: 3.0\n"
358 "...\n";
359
360 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_3_0, "Test.tbd");
361 auto Result = TextAPIReader::get(std::move(Buffer));
362 EXPECT_TRUE(!!Result);
363 auto File = std::move(Result.get());
364 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
365 EXPECT_EQ(4U, File->getSwiftABIVersion());
366 }
367
368 TEST(TBDv2, Swift_4_0) {
369 static const char tbd_v1_swift_4_0[] = "--- !tapi-tbd-v2\n"
370 "archs: [ arm64 ]\n"
371 "platform: ios\n"
372 "install-name: Test.dylib\n"
373 "swift-version: 4.0\n"
374 "...\n";
375
376 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_4_0, "Test.tbd");
377 auto Result = TextAPIReader::get(std::move(Buffer));
378 EXPECT_FALSE(!!Result);
379 auto errorMessage = toString(Result.takeError());
380 EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI "
381 "version.\nswift-version: 4.0\n ^~~\n",
382 errorMessage);
383 }
384
385 TEST(TBDv2, Swift_5) {
386 static const char tbd_v1_swift_5[] = "--- !tapi-tbd-v2\n"
387 "archs: [ arm64 ]\n"
388 "platform: ios\n"
389 "install-name: Test.dylib\n"
390 "swift-version: 5\n"
391 "...\n";
392
393 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_5, "Test.tbd");
394 auto Result = TextAPIReader::get(std::move(Buffer));
395 EXPECT_TRUE(!!Result);
396 auto File = std::move(Result.get());
397 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
398 EXPECT_EQ(5U, File->getSwiftABIVersion());
399 }
400
401 TEST(TBDv2, Swift_99) {
402 static const char tbd_v1_swift_99[] = "--- !tapi-tbd-v2\n"
403 "archs: [ arm64 ]\n"
404 "platform: ios\n"
405 "install-name: Test.dylib\n"
406 "swift-version: 99\n"
407 "...\n";
408
409 auto Buffer = MemoryBuffer::getMemBuffer(tbd_v1_swift_99, "Test.tbd");
410 auto Result = TextAPIReader::get(std::move(Buffer));
411 EXPECT_TRUE(!!Result);
412 auto File = std::move(Result.get());
413 EXPECT_EQ(FileType::TBD_V2, File->getFileType());
414 EXPECT_EQ(99U, File->getSwiftABIVersion());
415 }
416
417 TEST(TBDv2, UnknownArchitecture) {
418 static const char tbd_v2_file_unknown_architecture[] =
419 "--- !tapi-tbd-v2\n"
420 "archs: [ foo ]\n"
421 "platform: macosx\n"
422 "install-name: Test.dylib\n"
423 "...\n";
424
425 auto Buffer =
426 MemoryBuffer::getMemBuffer(tbd_v2_file_unknown_architecture, "Test.tbd");
427 auto Result = TextAPIReader::get(std::move(Buffer));
428 EXPECT_TRUE(!!Result);
429 }
430
431 TEST(TBDv2, UnknownPlatform) {
432 static const char tbd_v2_file_unknown_platform[] = "--- !tapi-tbd-v2\n"
433 "archs: [ i386 ]\n"
434 "platform: newOS\n"
435 "...\n";
436
437 auto Buffer =
438 MemoryBuffer::getMemBuffer(tbd_v2_file_unknown_platform, "Test.tbd");
439 auto Result = TextAPIReader::get(std::move(Buffer));
440 EXPECT_FALSE(!!Result);
441 auto errorMessage = toString(Result.takeError());
442 EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "
443 "newOS\n ^~~~~\n",
444 errorMessage);
445 }
446
447 TEST(TBDv2, MalformedFile1) {
448 static const char malformed_file1[] = "--- !tapi-tbd-v2\n"
449 "archs: [ arm64 ]\n"
450 "foobar: \"Unsupported key\"\n"
451 "...\n";
452
453 auto Buffer = MemoryBuffer::getMemBuffer(malformed_file1, "Test.tbd");
454 auto Result = TextAPIReader::get(std::move(Buffer));
455 EXPECT_FALSE(!!Result);
456 auto errorMessage = toString(Result.takeError());
457 ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "
458 "'platform'\narchs: [ arm64 ]\n^\n",
459 errorMessage);
460 }
461
462 TEST(TBDv2, MalformedFile2) {
463 static const char malformed_file2[] = "--- !tapi-tbd-v2\n"
464 "archs: [ arm64 ]\n"
465 "platform: ios\n"
466 "install-name: Test.dylib\n"
467 "foobar: \"Unsupported key\"\n"
468 "...\n";
469
470 auto Buffer = MemoryBuffer::getMemBuffer(malformed_file2, "Test.tbd");
471 auto Result = TextAPIReader::get(std::move(Buffer));
472 EXPECT_FALSE(!!Result);
473 auto errorMessage = toString(Result.takeError());
474 ASSERT_EQ(
475 "malformed file\nTest.tbd:5:9: error: unknown key 'foobar'\nfoobar: "
476 "\"Unsupported key\"\n ^~~~~~~~~~~~~~~~~\n",
477 errorMessage);
478 }
479
480 } // namespace TBDv2