1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[TextAPI] Arch&Platform to Target

Summary:
This is a patch for updating TextAPI/Macho to read in targets as opposed to arch/platform.
This is because in previous versions tbd files only supported a single platform but that is no longer the case,
so, now its tracked by unique triples.
This precedes a seperate patch that will add  the TBD-v4 format

Reviewers: ributzka, steven_wu, plotfi, compnerd, smeenai

Reviewed By: ributzka

Subscribers: mgorny, hiraditya, dexonsmith, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67527

llvm-svn: 372396
This commit is contained in:
Cyndy Ishida 2019-09-20 14:32:34 +00:00
parent a661d2b4f2
commit 5392f0f014
20 changed files with 615 additions and 226 deletions

View File

@ -14,6 +14,7 @@
#define LLVM_TEXTAPI_MACHO_ARCHITECTURE_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
@ -39,6 +40,9 @@ StringRef getArchitectureName(Architecture Arch);
/// Convert an architecture slice to a CPU Type and Subtype pair.
std::pair<uint32_t, uint32_t> getCPUTypeFromArchitecture(Architecture Arch);
/// Convert a target to an architecture slice.
Architecture mapToArchitecture(const llvm::Triple &Target);
raw_ostream &operator<<(raw_ostream &OS, Architecture Arch);
} // end namespace MachO.

View File

@ -59,6 +59,10 @@ public:
ArchSetType rawValue() const { return ArchSet; }
bool hasX86() const {
return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h);
}
template <typename Ty>
class arch_iterator
: public std::iterator<std::forward_iterator_tag, Architecture, size_t> {

View File

@ -26,21 +26,13 @@
#include "llvm/TextAPI/MachO/Architecture.h"
#include "llvm/TextAPI/MachO/ArchitectureSet.h"
#include "llvm/TextAPI/MachO/PackedVersion.h"
#include "llvm/TextAPI/MachO/Platform.h"
#include "llvm/TextAPI/MachO/Symbol.h"
#include "llvm/TextAPI/MachO/Target.h"
namespace llvm {
namespace MachO {
/// Defines the list of MachO platforms.
enum class PlatformKind : unsigned {
unknown,
macOS = MachO::PLATFORM_MACOS,
iOS = MachO::PLATFORM_IOS,
tvOS = MachO::PLATFORM_TVOS,
watchOS = MachO::PLATFORM_WATCHOS,
bridgeOS = MachO::PLATFORM_BRIDGEOS,
};
/// Defines a list of Objective-C constraints.
enum class ObjCConstraintType : unsigned {
/// No constraint.
@ -89,29 +81,42 @@ public:
InterfaceFileRef(StringRef InstallName) : InstallName(InstallName) {}
InterfaceFileRef(StringRef InstallName, ArchitectureSet Archs)
: InstallName(InstallName), Architectures(Archs) {}
InterfaceFileRef(StringRef InstallName, const TargetList Targets)
: InstallName(InstallName), Targets(std::move(Targets)) {}
StringRef getInstallName() const { return InstallName; };
void addArchitectures(ArchitectureSet Archs) { Architectures |= Archs; }
ArchitectureSet getArchitectures() const { return Architectures; }
bool hasArchitecture(Architecture Arch) const {
return Architectures.has(Arch);
void addTarget(const Target &Target);
template <typename RangeT> void addTargets(RangeT &&Targets) {
for (const auto &Target : Targets)
addTarget(Target(Target));
}
using const_target_iterator = TargetList::const_iterator;
using const_target_range = llvm::iterator_range<const_target_iterator>;
const_target_range targets() const { return {Targets}; }
ArchitectureSet getArchitectures() const {
return mapToArchitectureSet(Targets);
}
PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); }
bool operator==(const InterfaceFileRef &O) const {
return std::tie(InstallName, Architectures) ==
std::tie(O.InstallName, O.Architectures);
return std::tie(InstallName, Targets) == std::tie(O.InstallName, O.Targets);
}
bool operator!=(const InterfaceFileRef &O) const {
return std::tie(InstallName, Targets) != std::tie(O.InstallName, O.Targets);
}
bool operator<(const InterfaceFileRef &O) const {
return std::tie(InstallName, Architectures) <
std::tie(O.InstallName, O.Architectures);
return std::tie(InstallName, Targets) < std::tie(O.InstallName, O.Targets);
}
private:
std::string InstallName;
ArchitectureSet Architectures;
TargetList Targets;
};
} // end namespace MachO.
@ -170,27 +175,43 @@ public:
/// \return The file type.
FileType getFileType() const { return FileKind; }
/// Set the platform.
void setPlatform(PlatformKind Platform_) { Platform = Platform_; }
/// Get the platform.
PlatformKind getPlatform() const { return Platform; }
/// Specify the set of supported architectures by this file.
void setArchitectures(ArchitectureSet Architectures_) {
Architectures = Architectures_;
/// Get the architectures.
///
/// \return The applicable architectures.
ArchitectureSet getArchitectures() const {
return mapToArchitectureSet(Targets);
}
/// Add the set of supported architectures by this file.
void addArchitectures(ArchitectureSet Architectures_) {
Architectures |= Architectures_;
/// Get the platforms.
///
/// \return The applicable platforms.
PlatformSet getPlatforms() const { return mapToPlatformSet(Targets); }
/// Set and add target.
///
/// \param Target the target to add into.
void addTarget(const Target &Target);
/// Set and add targets.
///
/// Add the subset of llvm::triples that is supported by Tapi
///
/// \param Targets the collection of targets.
template <typename RangeT> void addTargets(RangeT &&Targets) {
for (const auto &Target_ : Targets)
addTarget(Target(Target_));
}
/// Add supported architecture by this file..
void addArch(Architecture Arch) { Architectures.set(Arch); }
using const_target_iterator = TargetList::const_iterator;
using const_target_range = llvm::iterator_range<const_target_iterator>;
const_target_range targets() const { return {Targets}; }
/// Get the set of supported architectures.
ArchitectureSet getArchitectures() const { return Architectures; }
using const_filtered_target_iterator =
llvm::filter_iterator<const_target_iterator,
std::function<bool(const Target &)>>;
using const_filtered_target_range =
llvm::iterator_range<const_filtered_target_iterator>;
const_filtered_target_range targets(ArchitectureSet Archs) const;
/// Set the install name of the library.
void setInstallName(StringRef InstallName_) { InstallName = InstallName_; }
@ -244,11 +265,18 @@ public:
/// Check if this file was generated during InstallAPI.
bool isInstallAPI() const { return IsInstallAPI; }
/// Set the parent umbrella framework.
void setParentUmbrella(StringRef Parent) { ParentUmbrella = Parent; }
/// Set the parent umbrella frameworks.
/// \param Target_ The target applicable to Parent
/// \param Parent The name of Parent
void addParentUmbrella(const Target &Target_, StringRef Parent);
const std::vector<std::pair<Target, std::string>> &umbrellas() const {
return ParentUmbrellas;
}
/// Get the parent umbrella framework.
StringRef getParentUmbrella() const { return ParentUmbrella; }
const std::vector<std::pair<Target, std::string>> getParentUmbrellas() const {
return ParentUmbrellas;
}
/// Add an allowable client.
///
@ -258,8 +286,8 @@ public:
/// linker refuses to link this library.
///
/// \param Name The name of the client that is allowed to link this library.
/// \param Architectures The set of architecture for which this applies.
void addAllowableClient(StringRef Name, ArchitectureSet Architectures);
/// \param Target The target triple for which this applies.
void addAllowableClient(StringRef InstallName, const Target &Target);
/// Get the list of allowable clients.
///
@ -271,9 +299,8 @@ public:
/// Add a re-exported library.
///
/// \param InstallName The name of the library to re-export.
/// \param Architectures The set of architecture for which this applies.
void addReexportedLibrary(StringRef InstallName,
ArchitectureSet Architectures);
/// \param Target The target triple for which this applies.
void addReexportedLibrary(StringRef InstallName, const Target &Target);
/// Get the list of re-exported libraries.
///
@ -282,27 +309,27 @@ public:
return ReexportedLibraries;
}
/// Add an architecture/UUID pair.
/// Add an Target/UUID pair.
///
/// \param Arch The architecture for which this applies.
/// \param Target The target triple for which this applies.
/// \param UUID The UUID of the library for the specified architecture.
void addUUID(Architecture Arch, StringRef UUID);
void addUUID(const Target &Target, StringRef UUID);
/// Add an architecture/UUID pair.
/// Add an Target/UUID pair.
///
/// \param Arch The architecture for which this applies.
/// \param Target The target triple for which this applies.
/// \param UUID The UUID of the library for the specified architecture.
void addUUID(Architecture Arch, uint8_t UUID[16]);
void addUUID(const Target &Target, uint8_t UUID[16]);
/// Get the list of architecture/UUID pairs.
/// Get the list of Target/UUID pairs.
///
/// \return Returns a list of architecture/UUID pairs.
const std::vector<std::pair<Architecture, std::string>> &uuids() const {
/// \return Returns a list of Target/UUID pairs.
const std::vector<std::pair<Target, std::string>> &uuids() const {
return UUIDs;
}
/// Add a symbol to the symbols list or extend an existing one.
void addSymbol(SymbolKind Kind, StringRef Name, ArchitectureSet Architectures,
void addSymbol(SymbolKind Kind, StringRef Name, const TargetList &Targets,
SymbolFlags Flags = SymbolFlags::None);
using SymbolMapType = DenseMap<SymbolsMapKey, Symbol *>;
@ -362,10 +389,9 @@ private:
return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
}
TargetList Targets;
std::string Path;
FileType FileKind;
PlatformKind Platform;
ArchitectureSet Architectures;
std::string InstallName;
PackedVersion CurrentVersion;
PackedVersion CompatibilityVersion;
@ -374,10 +400,10 @@ private:
bool IsAppExtensionSafe{false};
bool IsInstallAPI{false};
ObjCConstraintType ObjcConstraint = ObjCConstraintType::None;
std::string ParentUmbrella;
std::vector<std::pair<Target, std::string>> ParentUmbrellas;
std::vector<InterfaceFileRef> AllowableClients;
std::vector<InterfaceFileRef> ReexportedLibraries;
std::vector<std::pair<Architecture, std::string>> UUIDs;
std::vector<std::pair<Target, std::string>> UUIDs;
SymbolMapType Symbols;
};

View File

@ -0,0 +1,40 @@
//===- llvm/TextAPI/MachO/Platform.h - Platform -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Defines the Platforms supported by Tapi and helpers.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TEXTAPI_MACHO_PLATFORM_H
#define LLVM_TEXTAPI_MACHO_PLATFORM_H
#include "llvm/ADT/SmallSet.h"
#include "llvm/BinaryFormat/MachO.h"
namespace llvm {
namespace MachO {
/// Defines the list of MachO platforms.
enum class PlatformKind : unsigned {
unknown,
macOS = MachO::PLATFORM_MACOS,
iOS = MachO::PLATFORM_IOS,
tvOS = MachO::PLATFORM_TVOS,
watchOS = MachO::PLATFORM_WATCHOS,
bridgeOS = MachO::PLATFORM_BRIDGEOS
};
using PlatformSet = SmallSet<PlatformKind, 3>;
PlatformKind mapToPlatformKind(const Triple &Target);
PlatformSet mapToPlatformSet(ArrayRef<Triple> Targets);
StringRef getPlatformName(PlatformKind Platform);
} // end namespace MachO.
} // end namespace llvm.
#endif // LLVM_TEXTAPI_MACHO_PLATFORM_H

View File

@ -14,6 +14,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TextAPI/MachO/ArchitectureSet.h"
#include "llvm/TextAPI/MachO/Target.h"
namespace llvm {
namespace MachO {
@ -49,16 +50,18 @@ enum class SymbolKind : uint8_t {
ObjectiveCInstanceVariable,
};
using TargetList = SmallVector<Target, 20>;
class Symbol {
public:
constexpr Symbol(SymbolKind Kind, StringRef Name,
ArchitectureSet Architectures, SymbolFlags Flags)
: Name(Name), Architectures(Architectures), Kind(Kind), Flags(Flags) {}
Symbol(SymbolKind Kind, StringRef Name, TargetList Targets, SymbolFlags Flags)
: Name(Name), Targets(std::move(Targets)), Kind(Kind), Flags(Flags) {}
void addTarget(Target target) { Targets.emplace_back(target); }
SymbolKind getKind() const { return Kind; }
StringRef getName() const { return Name; }
ArchitectureSet getArchitectures() const { return Architectures; }
void addArchitectures(ArchitectureSet Archs) { Architectures |= Archs; }
ArchitectureSet getArchitectures() const {
return mapToArchitectureSet(Targets);
}
SymbolFlags getFlags() const { return Flags; }
bool isWeakDefined() const {
@ -78,6 +81,17 @@ public:
return (Flags & SymbolFlags::Undefined) == SymbolFlags::Undefined;
}
using const_target_iterator = TargetList::const_iterator;
using const_target_range = llvm::iterator_range<const_target_iterator>;
const_target_range targets() const { return {Targets}; }
using const_filtered_target_iterator =
llvm::filter_iterator<const_target_iterator,
std::function<bool(const Target &)>>;
using const_filtered_target_range =
llvm::iterator_range<const_filtered_target_iterator>;
const_filtered_target_range targets(ArchitectureSet architectures) const;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump(raw_ostream &OS) const;
void dump() const { dump(llvm::errs()); }
@ -85,7 +99,7 @@ public:
private:
StringRef Name;
ArchitectureSet Architectures;
TargetList Targets;
SymbolKind Kind;
SymbolFlags Flags;
};

View File

@ -0,0 +1,66 @@
//===- llvm/TextAPI/Target.h - TAPI Target ----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TEXTAPI_MACHO_TARGET_H
#define LLVM_TEXTAPI_MACHO_TARGET_H
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Error.h"
#include "llvm/TextAPI/MachO/Architecture.h"
#include "llvm/TextAPI/MachO/ArchitectureSet.h"
#include "llvm/TextAPI/MachO/Platform.h"
namespace llvm {
namespace MachO {
// This is similar to a llvm Triple, but the triple doesn't have all the
// information we need. For example there is no enum value for x86_64h. The
// only way to get that information is to parse the triple string.
class Target {
public:
Target() = default;
Target(Architecture Arch, PlatformKind Platform)
: Arch(Arch), Platform(Platform) {}
explicit Target(const llvm::Triple &Triple)
: Arch(mapToArchitecture(Triple)), Platform(mapToPlatformKind(Triple)) {}
operator std::string() const;
Architecture Arch;
PlatformKind Platform;
};
inline bool operator==(const Target &LHS, const Target &RHS) {
return std::tie(LHS.Arch, LHS.Platform) == std::tie(RHS.Arch, RHS.Platform);
}
inline bool operator!=(const Target &LHS, const Target &RHS) {
return std::tie(LHS.Arch, LHS.Platform) != std::tie(RHS.Arch, RHS.Platform);
}
inline bool operator<(const Target &LHS, const Target &RHS) {
return std::tie(LHS.Arch, LHS.Platform) < std::tie(RHS.Arch, RHS.Platform);
}
inline bool operator==(const Target &LHS, const Architecture &RHS) {
return LHS.Arch == RHS;
}
inline bool operator!=(const Target &LHS, const Architecture &RHS) {
return LHS.Arch != RHS;
}
PlatformSet mapToPlatformSet(ArrayRef<Target> Targets);
ArchitectureSet mapToArchitectureSet(ArrayRef<Target> Targets);
raw_ostream &operator<<(raw_ostream &OS, const Target &Target);
} // namespace MachO
} // namespace llvm
#endif // LLVM_TEXTAPI_MACHO_TARGET_H

View File

@ -45,13 +45,13 @@ TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
if (!Symbol->getArchitectures().has(Arch))
continue;
auto Platform = interface.getPlatform();
switch (Symbol->getKind()) {
case SymbolKind::GlobalSymbol:
Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol));
break;
case SymbolKind::ObjectiveCClass:
if (Platform == PlatformKind::macOS && Arch == AK_i386) {
if (interface.getPlatforms().count(PlatformKind::macOS) &&
Arch == AK_i386) {
Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(),
getFlags(Symbol));
} else {

View File

@ -5,7 +5,9 @@ add_llvm_library(LLVMTextAPI
MachO/ArchitectureSet.cpp
MachO/InterfaceFile.cpp
MachO/PackedVersion.cpp
MachO/Platform.cpp
MachO/Symbol.cpp
MachO/Target.cpp
MachO/TextStub.cpp
MachO/TextStubCommon.cpp

View File

@ -68,6 +68,10 @@ std::pair<uint32_t, uint32_t> getCPUTypeFromArchitecture(Architecture Arch) {
return std::make_pair(0, 0);
}
Architecture mapToArchitecture(const Triple &Target) {
return getArchitectureFromName(Target.getArchName());
}
raw_ostream &operator<<(raw_ostream &OS, Architecture Arch) {
OS << getArchitectureName(Arch);
return OS;

View File

@ -27,36 +27,65 @@ typename C::iterator addEntry(C &Container, StringRef InstallName) {
return Container.emplace(I, InstallName);
}
template <typename C>
typename C::iterator addEntry(C &Container, const Target &Target_) {
auto Iter =
lower_bound(Container, Target_, [](const Target &LHS, const Target &RHS) {
return LHS < RHS;
});
if ((Iter != std::end(Container)) && !(Target_ < *Iter))
return Iter;
return Container.insert(Iter, Target_);
}
} // end namespace detail.
void InterfaceFile::addAllowableClient(StringRef Name,
ArchitectureSet Architectures) {
auto Client = detail::addEntry(AllowableClients, Name);
Client->addArchitectures(Architectures);
void InterfaceFileRef::addTarget(const Target &Target) {
detail::addEntry(Targets, Target);
}
void InterfaceFile::addAllowableClient(StringRef InstallName,
const Target &Target) {
auto Client = detail::addEntry(AllowableClients, InstallName);
Client->addTarget(Target);
}
void InterfaceFile::addReexportedLibrary(StringRef InstallName,
ArchitectureSet Architectures) {
const Target &Target) {
auto Lib = detail::addEntry(ReexportedLibraries, InstallName);
Lib->addArchitectures(Architectures);
Lib->addTarget(Target);
}
void InterfaceFile::addUUID(Architecture Arch, StringRef UUID) {
auto I = partition_point(UUIDs,
[=](const std::pair<Architecture, std::string> &O) {
return O.first < Arch;
});
void InterfaceFile::addParentUmbrella(const Target &Target_, StringRef Parent) {
auto Iter = lower_bound(ParentUmbrellas, Target_,
[](const std::pair<Target, std::string> &LHS,
Target RHS) { return LHS.first < RHS; });
if (I != UUIDs.end() && Arch == I->first) {
I->second = UUID;
if ((Iter != ParentUmbrellas.end()) && !(Target_ < Iter->first)) {
Iter->second = Parent;
return;
}
UUIDs.emplace(I, Arch, UUID);
ParentUmbrellas.emplace(Iter, Target_, Parent);
return;
}
void InterfaceFile::addUUID(Architecture Arch, uint8_t UUID[16]) {
void InterfaceFile::addUUID(const Target &Target_, StringRef UUID) {
auto Iter = lower_bound(UUIDs, Target_,
[](const std::pair<Target, std::string> &LHS,
Target RHS) { return LHS.first < RHS; });
if ((Iter != UUIDs.end()) && !(Target_ < Iter->first)) {
Iter->second = UUID;
return;
}
UUIDs.emplace(Iter, Target_, UUID);
return;
}
void InterfaceFile::addUUID(const Target &Target, uint8_t UUID[16]) {
std::stringstream Stream;
for (unsigned i = 0; i < 16; ++i) {
if (i == 4 || i == 6 || i == 8 || i == 10)
@ -64,17 +93,30 @@ void InterfaceFile::addUUID(Architecture Arch, uint8_t UUID[16]) {
Stream << std::setfill('0') << std::setw(2) << std::uppercase << std::hex
<< static_cast<int>(UUID[i]);
}
addUUID(Arch, Stream.str());
addUUID(Target, Stream.str());
}
void InterfaceFile::addTarget(const Target &Target) {
detail::addEntry(Targets, Target);
}
InterfaceFile::const_filtered_target_range
InterfaceFile::targets(ArchitectureSet Archs) const {
std::function<bool(const Target &)> fn = [Archs](const Target &Target_) {
return Archs.has(Target_.Arch);
};
return make_filter_range(Targets, fn);
}
void InterfaceFile::addSymbol(SymbolKind Kind, StringRef Name,
ArchitectureSet Archs, SymbolFlags Flags) {
const TargetList &Targets, SymbolFlags Flags) {
Name = copyString(Name);
auto result = Symbols.try_emplace(SymbolsMapKey{Kind, Name}, nullptr);
if (result.second)
result.first->second = new (Allocator) Symbol{Kind, Name, Archs, Flags};
result.first->second = new (Allocator) Symbol{Kind, Name, Targets, Flags};
else
result.first->second->addArchitectures(Archs);
for (const auto &Target : Targets)
result.first->second->addTarget(Target);
}
} // end namespace MachO.

View File

@ -0,0 +1,61 @@
//===- llvm/TextAPI/MachO/Platform.cpp - Platform ---------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implementations of Platform Helper functions.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/TextAPI/MachO/Platform.h"
namespace llvm {
namespace MachO {
PlatformKind mapToPlatformKind(const Triple &Target) {
switch (Target.getOS()) {
default:
return PlatformKind::unknown;
case Triple::MacOSX:
return PlatformKind::macOS;
case Triple::IOS:
return PlatformKind::iOS;
case Triple::TvOS:
return PlatformKind::tvOS;
case Triple::WatchOS:
return PlatformKind::watchOS;
// TODO: add bridgeOS once in llvm::Triple
}
}
PlatformSet mapToPlatformSet(ArrayRef<Triple> Targets) {
PlatformSet Result;
for (const auto &Target : Targets)
Result.insert(mapToPlatformKind(Target));
return Result;
}
StringRef getPlatformName(PlatformKind Platform) {
switch (Platform) {
case PlatformKind::unknown:
return "unknown";
case PlatformKind::macOS:
return "macOS";
case PlatformKind::iOS:
return "iOS";
case PlatformKind::tvOS:
return "tvOS";
case PlatformKind::watchOS:
return "watchOS";
case PlatformKind::bridgeOS:
return "bridgeOS";
}
}
} // end namespace MachO.
} // end namespace llvm.

View File

@ -45,5 +45,14 @@ LLVM_DUMP_METHOD void Symbol::dump(raw_ostream &OS) const {
}
#endif
Symbol::const_filtered_target_range
Symbol::targets(ArchitectureSet Architectures) const {
std::function<bool(const Target &)> FN =
[Architectures](const Target &Target) {
return Architectures.has(Target.Arch);
};
return make_filter_range(Targets, FN);
}
} // end namespace MachO.
} // end namespace llvm.

View File

@ -0,0 +1,45 @@
//===- tapi/Core/Target.cpp - Target ----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TextAPI/MachO/Target.h"
namespace llvm {
namespace MachO {
Target::operator std::string() const {
return (getArchitectureName(Arch) + " (" + getPlatformName(Platform) + ")")
.str();
}
raw_ostream &operator<<(raw_ostream &OS, const Target &Target) {
OS << std::string(Target);
return OS;
}
PlatformSet mapToPlatformSet(ArrayRef<Target> Targets) {
PlatformSet Result;
for (const auto &Target : Targets)
Result.insert(Target.Platform);
return Result;
}
ArchitectureSet mapToArchitectureSet(ArrayRef<Target> Targets) {
ArchitectureSet Result;
for (const auto &Target : Targets)
Result.set(Target.Arch);
return Result;
}
} // end namespace MachO.
} // end namespace llvm.

View File

@ -246,7 +246,7 @@ template <> struct MappingTraits<const InterfaceFile *> {
NormalizedTBD(IO &IO, const InterfaceFile *&File) {
Architectures = File->getArchitectures();
UUIDs = File->uuids();
Platform = File->getPlatform();
Platforms = File->getPlatforms();
InstallName = File->getInstallName();
CurrentVersion = PackedVersion(File->getCurrentVersion());
CompatibilityVersion = PackedVersion(File->getCompatibilityVersion());
@ -263,7 +263,10 @@ template <> struct MappingTraits<const InterfaceFile *> {
if (File->isInstallAPI())
Flags |= TBDFlags::InstallAPI;
ParentUmbrella = File->getParentUmbrella();
for (const auto &Iter : File->umbrellas()) {
ParentUmbrella = Iter.second;
break;
}
std::set<ArchitectureSet> ArchSet;
for (const auto &Library : File->allowableClients())
@ -396,6 +399,17 @@ template <> struct MappingTraits<const InterfaceFile *> {
}
}
TargetList synthesizeTargets(ArchitectureSet Architectures,
const PlatformSet &Platforms) {
TargetList Targets;
for (auto Platform : Platforms) {
for (const auto &&Architecture : Architectures)
Targets.emplace_back(Architecture, Platform);
}
return Targets;
}
const InterfaceFile *denormalize(IO &IO) {
auto Ctx = reinterpret_cast<TextAPIContext *>(IO.getContext());
assert(Ctx);
@ -403,16 +417,16 @@ template <> struct MappingTraits<const InterfaceFile *> {
auto *File = new InterfaceFile;
File->setPath(Ctx->Path);
File->setFileType(Ctx->FileKind);
File->addTargets(synthesizeTargets(Architectures, Platforms));
for (auto &ID : UUIDs)
File->addUUID(ID.first, ID.second);
File->setPlatform(Platform);
File->setArchitectures(Architectures);
File->setInstallName(InstallName);
File->setCurrentVersion(CurrentVersion);
File->setCompatibilityVersion(CompatibilityVersion);
File->setSwiftABIVersion(SwiftABIVersion);
File->setObjCConstraint(ObjCConstraint);
File->setParentUmbrella(ParentUmbrella);
for (const auto &Target : File->targets())
File->addParentUmbrella(Target, ParentUmbrella);
if (Ctx->FileKind == FileType::TBD_V1) {
File->setTwoLevelNamespace();
@ -425,76 +439,80 @@ template <> struct MappingTraits<const InterfaceFile *> {
}
for (const auto &Section : Exports) {
for (const auto &Library : Section.AllowableClients)
File->addAllowableClient(Library, Section.Architectures);
for (const auto &Library : Section.ReexportedLibraries)
File->addReexportedLibrary(Library, Section.Architectures);
const auto Targets =
synthesizeTargets(Section.Architectures, Platforms);
for (const auto &Lib : Section.AllowableClients)
for (const auto &Target : Targets)
File->addAllowableClient(Lib, Target);
for (const auto &Lib : Section.ReexportedLibraries)
for (const auto &Target : Targets)
File->addReexportedLibrary(Lib, Target);
for (const auto &Symbol : Section.Symbols) {
if (Ctx->FileKind != FileType::TBD_V3 &&
Symbol.value.startswith("_OBJC_EHTYPE_$_"))
File->addSymbol(SymbolKind::ObjectiveCClassEHType,
Symbol.value.drop_front(15), Section.Architectures);
Symbol.value.drop_front(15), Targets);
else
File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
Section.Architectures);
File->addSymbol(SymbolKind::GlobalSymbol, Symbol, Targets);
}
for (auto &Symbol : Section.Classes) {
auto Name = Symbol.value;
if (Ctx->FileKind != FileType::TBD_V3)
Name = Name.drop_front();
File->addSymbol(SymbolKind::ObjectiveCClass, Name,
Section.Architectures);
File->addSymbol(SymbolKind::ObjectiveCClass, Name, Targets);
}
for (auto &Symbol : Section.ClassEHs)
File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
Section.Architectures);
File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol, Targets);
for (auto &Symbol : Section.IVars) {
auto Name = Symbol.value;
if (Ctx->FileKind != FileType::TBD_V3)
Name = Name.drop_front();
File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
Section.Architectures);
Targets);
}
for (auto &Symbol : Section.WeakDefSymbols)
File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
Section.Architectures, SymbolFlags::WeakDefined);
File->addSymbol(SymbolKind::GlobalSymbol, Symbol, Targets,
SymbolFlags::WeakDefined);
for (auto &Symbol : Section.TLVSymbols)
File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
Section.Architectures, SymbolFlags::ThreadLocalValue);
File->addSymbol(SymbolKind::GlobalSymbol, Symbol, Targets,
SymbolFlags::ThreadLocalValue);
}
for (const auto &Section : Undefineds) {
const auto Targets =
synthesizeTargets(Section.Architectures, Platforms);
for (auto &Symbol : Section.Symbols) {
if (Ctx->FileKind != FileType::TBD_V3 &&
Symbol.value.startswith("_OBJC_EHTYPE_$_"))
File->addSymbol(SymbolKind::ObjectiveCClassEHType,
Symbol.value.drop_front(15), Section.Architectures,
Symbol.value.drop_front(15), Targets,
SymbolFlags::Undefined);
else
File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
Section.Architectures, SymbolFlags::Undefined);
File->addSymbol(SymbolKind::GlobalSymbol, Symbol, Targets,
SymbolFlags::Undefined);
}
for (auto &Symbol : Section.Classes) {
auto Name = Symbol.value;
if (Ctx->FileKind != FileType::TBD_V3)
Name = Name.drop_front();
File->addSymbol(SymbolKind::ObjectiveCClass, Name,
Section.Architectures, SymbolFlags::Undefined);
File->addSymbol(SymbolKind::ObjectiveCClass, Name, Targets,
SymbolFlags::Undefined);
}
for (auto &Symbol : Section.ClassEHs)
File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol,
Section.Architectures, SymbolFlags::Undefined);
File->addSymbol(SymbolKind::ObjectiveCClassEHType, Symbol, Targets,
SymbolFlags::Undefined);
for (auto &Symbol : Section.IVars) {
auto Name = Symbol.value;
if (Ctx->FileKind != FileType::TBD_V3)
Name = Name.drop_front();
File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name,
Section.Architectures, SymbolFlags::Undefined);
File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, Name, Targets,
SymbolFlags::Undefined);
}
for (auto &Symbol : Section.WeakRefSymbols)
File->addSymbol(SymbolKind::GlobalSymbol, Symbol,
Section.Architectures,
File->addSymbol(SymbolKind::GlobalSymbol, Symbol, Targets,
SymbolFlags::Undefined | SymbolFlags::WeakReferenced);
}
@ -513,7 +531,7 @@ template <> struct MappingTraits<const InterfaceFile *> {
std::vector<Architecture> Architectures;
std::vector<UUID> UUIDs;
PlatformKind Platform{PlatformKind::unknown};
PlatformSet Platforms;
StringRef InstallName;
PackedVersion CurrentVersion;
PackedVersion CompatibilityVersion;
@ -567,7 +585,7 @@ template <> struct MappingTraits<const InterfaceFile *> {
IO.mapRequired("archs", Keys->Architectures);
if (Ctx->FileKind != FileType::TBD_V1)
IO.mapOptional("uuids", Keys->UUIDs);
IO.mapRequired("platform", Keys->Platform);
IO.mapRequired("platform", Keys->Platforms);
if (Ctx->FileKind != FileType::TBD_V1)
IO.mapOptional("flags", Keys->Flags, TBDFlags::None);
IO.mapRequired("install-name", Keys->InstallName);

View File

@ -41,9 +41,10 @@ void ScalarEnumerationTraits<ObjCConstraintType>::enumeration(
IO.enumCase(Constraint, "gc", ObjCConstraintType::GC);
}
void ScalarTraits<PlatformKind>::output(const PlatformKind &Value, void *,
raw_ostream &OS) {
switch (Value) {
void ScalarTraits<PlatformSet>::output(const PlatformSet &Values, void *IO,
raw_ostream &OS) {
assert(Values.size() == 1U);
switch (*Values.begin()) {
default:
llvm_unreachable("unexpected platform");
break;
@ -64,21 +65,26 @@ void ScalarTraits<PlatformKind>::output(const PlatformKind &Value, void *,
break;
}
}
StringRef ScalarTraits<PlatformKind>::input(StringRef Scalar, void *,
PlatformKind &Value) {
Value = StringSwitch<PlatformKind>(Scalar)
.Case("macosx", PlatformKind::macOS)
.Case("ios", PlatformKind::iOS)
.Case("watchos", PlatformKind::watchOS)
.Case("tvos", PlatformKind::tvOS)
.Case("bridgeos", PlatformKind::bridgeOS)
.Default(PlatformKind::unknown);
if (Value == PlatformKind::unknown)
StringRef ScalarTraits<PlatformSet>::input(StringRef Scalar, void *IO,
PlatformSet &Values) {
auto Platform = StringSwitch<PlatformKind>(Scalar)
.Case("unknown", PlatformKind::unknown)
.Case("macosx", PlatformKind::macOS)
.Case("ios", PlatformKind::iOS)
.Case("watchos", PlatformKind::watchOS)
.Case("tvos", PlatformKind::tvOS)
.Case("bridgeos", PlatformKind::bridgeOS)
.Default(PlatformKind::unknown);
if (Platform == PlatformKind::unknown)
return "unknown platform";
Values.insert(Platform);
return {};
}
QuotingType ScalarTraits<PlatformKind>::mustQuote(StringRef) {
QuotingType ScalarTraits<PlatformSet>::mustQuote(StringRef) {
return QuotingType::None;
}
@ -166,10 +172,11 @@ StringRef ScalarTraits<UUID>::input(StringRef Scalar, void *, UUID &Value) {
auto UUID = Split.second.trim();
if (UUID.empty())
return "invalid uuid string pair";
Value.first = getArchitectureFromName(Arch);
Value.second = UUID;
Value.first = Target{getArchitectureFromName(Arch), PlatformKind::unknown};
return {};
}
QuotingType ScalarTraits<UUID>::mustQuote(StringRef) {
return QuotingType::Single;
}

View File

@ -21,7 +21,7 @@
#include "llvm/TextAPI/MachO/InterfaceFile.h"
#include "llvm/TextAPI/MachO/PackedVersion.h"
using UUID = std::pair<llvm::MachO::Architecture, std::string>;
using UUID = std::pair<llvm::MachO::Target, std::string>;
LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, FlowStringRef)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, SwiftVersion)
@ -41,9 +41,9 @@ template <> struct ScalarEnumerationTraits<MachO::ObjCConstraintType> {
static void enumeration(IO &, MachO::ObjCConstraintType &);
};
template <> struct ScalarTraits<MachO::PlatformKind> {
static void output(const MachO::PlatformKind &, void *, raw_ostream &);
static StringRef input(StringRef, void *, MachO::PlatformKind &);
template <> struct ScalarTraits<MachO::PlatformSet> {
static void output(const MachO::PlatformSet &, void *, raw_ostream &);
static StringRef input(StringRef, void *, MachO::PlatformSet &);
static QuotingType mustQuote(StringRef);
};

View File

@ -220,21 +220,6 @@ static Expected<std::unique_ptr<IFSStub>> readInputFile(StringRef FilePath) {
int writeTbdStub(const llvm::Triple &T, const std::set<IFSSymbol> &Symbols,
const StringRef Format, raw_ostream &Out) {
auto ArchOrError =
[](const llvm::Triple &T) -> llvm::Expected<llvm::MachO::Architecture> {
switch (T.getArch()) {
default:
return createStringError(errc::not_supported, "Invalid Architecture.\n");
case llvm::Triple::ArchType::x86:
return AK_i386;
case llvm::Triple::ArchType::x86_64:
return AK_x86_64;
case llvm::Triple::ArchType::arm:
return AK_armv7;
case llvm::Triple::ArchType::aarch64:
return AK_arm64;
}
}(T);
auto PlatformKindOrError =
[](const llvm::Triple &T) -> llvm::Expected<llvm::MachO::PlatformKind> {
@ -256,19 +241,15 @@ int writeTbdStub(const llvm::Triple &T, const std::set<IFSSymbol> &Symbols,
return createStringError(errc::not_supported, "Invalid Platform.\n");
}(T);
if (!ArchOrError)
return -1;
if (!PlatformKindOrError)
return -1;
Architecture Arch = ArchOrError.get();
PlatformKind Plat = PlatformKindOrError.get();
TargetList Targets({Target(llvm::MachO::mapToArchitecture(T), Plat)});
InterfaceFile File;
File.setFileType(FileType::TBD_V3); // Only supporting v3 for now.
File.setArchitectures(Arch);
File.setPlatform(Plat);
File.addTargets(Targets);
for (const auto &Symbol : Symbols) {
auto Name = Symbol.Name;
@ -286,9 +267,9 @@ int writeTbdStub(const llvm::Triple &T, const std::set<IFSSymbol> &Symbols,
break;
}
if (Symbol.Weak)
File.addSymbol(Kind, Name, Arch, SymbolFlags::WeakDefined);
File.addSymbol(Kind, Name, Targets, SymbolFlags::WeakDefined);
else
File.addSymbol(Kind, Name, Arch);
File.addSymbol(Kind, Name, Targets);
}
SmallString<4096> Buffer;

View File

@ -87,8 +87,13 @@ TEST(TBDv1, ReadFile) {
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V1, File->getFileType());
auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
auto Platform = PlatformKind::iOS;
TargetList Targets;
for (auto &&arch : Archs)
Targets.emplace_back(Target(arch, Platform));
EXPECT_EQ(Archs, File->getArchitectures());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
@ -97,8 +102,8 @@ TEST(TBDv1, ReadFile) {
EXPECT_TRUE(File->isTwoLevelNamespace());
EXPECT_TRUE(File->isApplicationExtensionSafe());
EXPECT_FALSE(File->isInstallAPI());
InterfaceFileRef client("clientA", Archs);
InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
InterfaceFileRef client("clientA", Targets);
InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Targets);
EXPECT_EQ(1U, File->allowableClients().size());
EXPECT_EQ(client, File->allowableClients().front());
EXPECT_EQ(1U, File->reexportedLibraries().size());
@ -117,6 +122,10 @@ TEST(TBDv1, ReadFile) {
EXPECT_EQ(sizeof(TBDv1Symbols) / sizeof(ExportedSymbol), Exports.size());
EXPECT_TRUE(
std::equal(Exports.begin(), Exports.end(), std::begin(TBDv1Symbols)));
File->addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", {Targets[1]});
File->addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
{Targets[1]});
}
TEST(TBDv1, ReadFile2) {
@ -131,8 +140,13 @@ TEST(TBDv1, ReadFile2) {
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V1, File->getFileType());
auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
auto Platform = PlatformKind::iOS;
TargetList Targets;
for (auto &&arch : Archs)
Targets.emplace_back(Target(arch, Platform));
EXPECT_EQ(Archs, File->getArchitectures());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
@ -169,25 +183,27 @@ TEST(TBDv1, WriteFile) {
"...\n";
InterfaceFile File;
TargetList Targets;
for (auto &&arch : AK_i386 | AK_x86_64)
Targets.emplace_back(Target(arch, PlatformKind::macOS));
File.setPath("libfoo.dylib");
File.setInstallName("/usr/lib/libfoo.dylib");
File.setFileType(FileType::TBD_V1);
File.setArchitectures(AK_i386 | AK_x86_64);
File.setPlatform(PlatformKind::macOS);
File.addTargets(Targets);
File.setCurrentVersion(PackedVersion(1, 2, 3));
File.setSwiftABIVersion(5);
File.setObjCConstraint(ObjCConstraintType::Retain_Release);
File.addAllowableClient("clientA", AK_x86_64);
File.addReexportedLibrary("/usr/lib/libfoo.dylib", AK_x86_64);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", AK_i386);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", AK_i386,
File.addAllowableClient("clientA", Targets[1]);
File.addReexportedLibrary("/usr/lib/libfoo.dylib", Targets[1]);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", {Targets[0]});
File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", {Targets[0]},
SymbolFlags::WeakDefined);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", AK_i386,
File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", {Targets[0]},
SymbolFlags::ThreadLocalValue);
File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", AK_x86_64);
File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", AK_x86_64);
File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[1]});
File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", {Targets[1]});
File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
AK_x86_64);
{Targets[1]});
SmallString<4096> Buffer;
raw_svector_ostream OS(Buffer);
@ -206,9 +222,11 @@ TEST(TBDv1, Platform_macOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_macos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::macOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V1, File->getFileType());
EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv1, Platform_iOS) {
@ -221,9 +239,11 @@ TEST(TBDv1, Platform_iOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_ios, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::iOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V1, File->getFileType());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv1, Platform_watchOS) {
@ -236,9 +256,11 @@ TEST(TBDv1, Platform_watchOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_watchos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::watchOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V1, File->getFileType());
EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv1, Platform_tvOS) {
@ -251,9 +273,11 @@ TEST(TBDv1, Platform_tvOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_tvos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::tvOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V1, File->getFileType());
EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv1, Platform_bridgeOS) {
@ -266,9 +290,11 @@ TEST(TBDv1, Platform_bridgeOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_bridgeos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::bridgeOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V1, File->getFileType());
EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv1, Swift_1_0) {

View File

@ -89,8 +89,13 @@ TEST(TBDv2, ReadFile) {
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V2, File->getFileType());
auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
auto Platform = PlatformKind::iOS;
TargetList Targets;
for (auto &&arch : Archs)
Targets.emplace_back(Target(arch, Platform));
EXPECT_EQ(Archs, File->getArchitectures());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
@ -99,8 +104,8 @@ TEST(TBDv2, ReadFile) {
EXPECT_TRUE(File->isTwoLevelNamespace());
EXPECT_TRUE(File->isApplicationExtensionSafe());
EXPECT_TRUE(File->isInstallAPI());
InterfaceFileRef client("clientA", Archs);
InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
InterfaceFileRef client("clientA", Targets);
InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Targets);
EXPECT_EQ(1U, File->allowableClients().size());
EXPECT_EQ(client, File->allowableClients().front());
EXPECT_EQ(1U, File->reexportedLibraries().size());
@ -155,8 +160,13 @@ TEST(TBDv2, ReadFile2) {
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V2, File->getFileType());
auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;
auto Platform = PlatformKind::iOS;
TargetList Targets;
for (auto &&arch : Archs)
Targets.emplace_back(Target(arch, Platform));
EXPECT_EQ(Archs, File->getArchitectures());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
@ -192,27 +202,29 @@ TEST(TBDv2, WriteFile) {
"...\n";
InterfaceFile File;
TargetList Targets;
for (auto &&arch : AK_i386 | AK_x86_64)
Targets.emplace_back(Target(arch, PlatformKind::macOS));
File.setPath("libfoo.dylib");
File.setInstallName("/usr/lib/libfoo.dylib");
File.setFileType(FileType::TBD_V2);
File.setArchitectures(AK_i386 | AK_x86_64);
File.setPlatform(PlatformKind::macOS);
File.addTargets(Targets);
File.setCurrentVersion(PackedVersion(1, 2, 3));
File.setTwoLevelNamespace();
File.setApplicationExtensionSafe();
File.setSwiftABIVersion(5);
File.setObjCConstraint(ObjCConstraintType::Retain_Release);
File.addAllowableClient("clientA", AK_x86_64);
File.addReexportedLibrary("/usr/lib/libfoo.dylib", AK_x86_64);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", AK_i386);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", AK_i386,
File.addAllowableClient("clientA", Targets[1]);
File.addReexportedLibrary("/usr/lib/libfoo.dylib", Targets[1]);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", {Targets[0]});
File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", {Targets[0]},
SymbolFlags::WeakDefined);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", AK_i386,
File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", {Targets[0]},
SymbolFlags::ThreadLocalValue);
File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", AK_x86_64);
File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", AK_x86_64);
File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[1]});
File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", {Targets[1]});
File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
AK_x86_64);
{Targets[1]});
SmallString<4096> Buffer;
raw_svector_ostream OS(Buffer);
@ -232,8 +244,10 @@ TEST(TBDv2, Platform_macOS) {
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_macos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto File = std::move(Result.get());
auto Platform = PlatformKind::macOS;
EXPECT_EQ(FileType::TBD_V2, File->getFileType());
EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv2, Platform_iOS) {
@ -246,9 +260,11 @@ TEST(TBDv2, Platform_iOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_ios, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::iOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V2, File->getFileType());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv2, Platform_watchOS) {
@ -261,9 +277,11 @@ TEST(TBDv2, Platform_watchOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_watchos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::watchOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V2, File->getFileType());
EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv2, Platform_tvOS) {
@ -276,9 +294,11 @@ TEST(TBDv2, Platform_tvOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_tvos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::tvOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V2, File->getFileType());
EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv2, Platform_bridgeOS) {
@ -291,9 +311,11 @@ TEST(TBDv2, Platform_bridgeOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_bridgeos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::bridgeOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V2, File->getFileType());
EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv2, Swift_1_0) {
@ -415,7 +437,6 @@ TEST(TBDv2, UnknownArchitecture) {
"platform: macosx\n"
"install-name: Test.dylib\n"
"...\n";
auto Result = TextAPIReader::get(
MemoryBufferRef(tbd_v2_file_unknown_architecture, "Test.tbd"));
EXPECT_TRUE(!!Result);
@ -423,9 +444,9 @@ TEST(TBDv2, UnknownArchitecture) {
TEST(TBDv2, UnknownPlatform) {
static const char tbd_v2_file_unknown_platform[] = "--- !tapi-tbd-v2\n"
"archs: [ i386 ]\n"
"platform: newOS\n"
"...\n";
"archs: [ i386 ]\n"
"platform: newOS\n"
"...\n";
auto Result = TextAPIReader::get(
MemoryBufferRef(tbd_v2_file_unknown_platform, "Test.tbd"));

View File

@ -23,7 +23,7 @@ struct ExportedSymbol {
bool ThreadLocalValue;
};
using ExportedSymbolSeq = std::vector<ExportedSymbol>;
using UUIDs = std::vector<std::pair<Architecture, std::string>>;
using UUIDs = std::vector<std::pair<Target, std::string>>;
inline bool operator<(const ExportedSymbol &lhs, const ExportedSymbol &rhs) {
return std::tie(lhs.Kind, lhs.Name) < std::tie(rhs.Kind, rhs.Name);
@ -93,11 +93,18 @@ TEST(TBDv3, ReadFile) {
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V3, File->getFileType());
auto Archs = AK_armv7 | AK_arm64;
auto Platform = PlatformKind::iOS;
TargetList Targets;
for (auto &&arch : Archs)
Targets.emplace_back(Target(arch, Platform));
EXPECT_EQ(Archs, File->getArchitectures());
UUIDs uuids = {{AK_armv7, "00000000-0000-0000-0000-000000000000"},
{AK_arm64, "11111111-1111-1111-1111-111111111111"}};
EXPECT_EQ(uuids, File->uuids());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
UUIDs Uuids = {{Target(AK_armv7, PlatformKind::unknown),
"00000000-0000-0000-0000-000000000000"},
{Target(AK_arm64, PlatformKind::unknown),
"11111111-1111-1111-1111-111111111111"}};
EXPECT_EQ(Uuids, File->uuids());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());
EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());
EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());
@ -106,8 +113,8 @@ TEST(TBDv3, ReadFile) {
EXPECT_TRUE(File->isTwoLevelNamespace());
EXPECT_TRUE(File->isApplicationExtensionSafe());
EXPECT_TRUE(File->isInstallAPI());
InterfaceFileRef client("clientA", Archs);
InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Archs);
InterfaceFileRef client("clientA", Targets);
InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Targets);
EXPECT_EQ(1U, File->allowableClients().size());
EXPECT_EQ(client, File->allowableClients().front());
EXPECT_EQ(1U, File->reexportedLibraries().size());
@ -151,27 +158,29 @@ TEST(TBDv3, WriteFile) {
"...\n";
InterfaceFile File;
TargetList Targets;
for (auto &&arch : AK_i386 | AK_x86_64)
Targets.emplace_back(Target(arch, PlatformKind::macOS));
File.setPath("libfoo.dylib");
File.setInstallName("/usr/lib/libfoo.dylib");
File.setFileType(FileType::TBD_V3);
File.setArchitectures(AK_i386 | AK_x86_64);
File.setPlatform(PlatformKind::macOS);
File.addTargets(Targets);
File.setCurrentVersion(PackedVersion(1, 2, 3));
File.setTwoLevelNamespace();
File.setApplicationExtensionSafe();
File.setSwiftABIVersion(5);
File.setObjCConstraint(ObjCConstraintType::Retain_Release);
File.addAllowableClient("clientA", AK_x86_64);
File.addReexportedLibrary("/usr/lib/libfoo.dylib", AK_x86_64);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", AK_i386);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", AK_i386,
File.addAllowableClient("clientA", Targets[1]);
File.addReexportedLibrary("/usr/lib/libfoo.dylib", Targets[1]);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym1", {Targets[0]});
File.addSymbol(SymbolKind::GlobalSymbol, "_sym2", {Targets[0]},
SymbolFlags::WeakDefined);
File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", AK_i386,
File.addSymbol(SymbolKind::GlobalSymbol, "_sym3", {Targets[0]},
SymbolFlags::ThreadLocalValue);
File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", AK_x86_64);
File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", AK_x86_64);
File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[1]});
File.addSymbol(SymbolKind::ObjectiveCClassEHType, "Class1", {Targets[1]});
File.addSymbol(SymbolKind::ObjectiveCInstanceVariable, "Class1._ivar1",
AK_x86_64);
{Targets[1]});
SmallString<4096> Buffer;
raw_svector_ostream OS(Buffer);
@ -190,9 +199,11 @@ TEST(TBDv3, Platform_macOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_macos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::macOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V3, File->getFileType());
EXPECT_EQ(PlatformKind::macOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv3, Platform_iOS) {
@ -205,9 +216,11 @@ TEST(TBDv3, Platform_iOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_ios, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::iOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V3, File->getFileType());
EXPECT_EQ(PlatformKind::iOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv3, Platform_watchOS) {
@ -220,9 +233,11 @@ TEST(TBDv3, Platform_watchOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_watchos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::watchOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V3, File->getFileType());
EXPECT_EQ(PlatformKind::watchOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv3, Platform_tvOS) {
@ -236,8 +251,10 @@ TEST(TBDv3, Platform_tvOS) {
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_tvos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto File = std::move(Result.get());
auto Platform = PlatformKind::tvOS;
EXPECT_EQ(FileType::TBD_V3, File->getFileType());
EXPECT_EQ(PlatformKind::tvOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv3, Platform_bridgeOS) {
@ -250,9 +267,11 @@ TEST(TBDv3, Platform_bridgeOS) {
auto Result =
TextAPIReader::get(MemoryBufferRef(tbd_v1_platform_bridgeos, "Test.tbd"));
EXPECT_TRUE(!!Result);
auto Platform = PlatformKind::bridgeOS;
auto File = std::move(Result.get());
EXPECT_EQ(FileType::TBD_V3, File->getFileType());
EXPECT_EQ(PlatformKind::bridgeOS, File->getPlatform());
EXPECT_EQ(File->getPlatforms().size(), 1U);
EXPECT_EQ(Platform, *File->getPlatforms().begin());
}
TEST(TBDv3, Swift_1_0) {