brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.0 KiB · 548f748 Raw
492 lines · cpp
1//===-- TextStubV2Tests.cpp - TBD V2 File Test ----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===-----------------------------------------------------------------------===/8#include "TextStubHelpers.h"9#include "llvm/TextAPI/InterfaceFile.h"10#include "llvm/TextAPI/TextAPIReader.h"11#include "llvm/TextAPI/TextAPIWriter.h"12#include "gtest/gtest.h"13#include <string>14 15using namespace llvm;16using namespace llvm::MachO;17 18static ExportedSymbol TBDv2Symbols[] = {19    {EncodeKind::GlobalSymbol, "$ld$hide$os9.0$_sym1", false, false},20    {EncodeKind::GlobalSymbol, "_sym1", false, false},21    {EncodeKind::GlobalSymbol, "_sym2", false, false},22    {EncodeKind::GlobalSymbol, "_sym3", false, false},23    {EncodeKind::GlobalSymbol, "_sym4", false, false},24    {EncodeKind::GlobalSymbol, "_sym5", false, false},25    {EncodeKind::GlobalSymbol, "_tlv1", false, true},26    {EncodeKind::GlobalSymbol, "_tlv2", false, true},27    {EncodeKind::GlobalSymbol, "_tlv3", false, true},28    {EncodeKind::GlobalSymbol, "_weak1", true, false},29    {EncodeKind::GlobalSymbol, "_weak2", true, false},30    {EncodeKind::GlobalSymbol, "_weak3", true, false},31    {EncodeKind::ObjectiveCClass, "class1", false, false},32    {EncodeKind::ObjectiveCClass, "class2", false, false},33    {EncodeKind::ObjectiveCClass, "class3", false, false},34    {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar1", false, false},35    {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar2", false, false},36    {EncodeKind::ObjectiveCInstanceVariable, "class1._ivar3", false, false},37};38 39namespace TBDv2 {40 41TEST(TBDv2, ReadFile) {42  static const char TBDv2File1[] =43      "--- !tapi-tbd-v2\n"44      "archs: [ armv7, armv7s, armv7k, arm64 ]\n"45      "platform: ios\n"46      "flags: [ installapi ]\n"47      "install-name: Test.dylib\n"48      "current-version: 2.3.4\n"49      "compatibility-version: 1.0\n"50      "swift-version: 1.1\n"51      "parent-umbrella: Umbrella.dylib\n"52      "exports:\n"53      "  - archs: [ armv7, armv7s, armv7k, arm64 ]\n"54      "    allowable-clients: [ clientA ]\n"55      "    re-exports: [ /usr/lib/libfoo.dylib ]\n"56      "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"57      "    objc-classes: [ _class1, _class2 ]\n"58      "    objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"59      "    weak-def-symbols: [ _weak1, _weak2 ]\n"60      "    thread-local-symbols: [ _tlv1, _tlv2 ]\n"61      "  - archs: [ armv7, armv7s, armv7k ]\n"62      "    symbols: [ _sym5 ]\n"63      "    objc-classes: [ _class3 ]\n"64      "    objc-ivars: [ _class1._ivar3 ]\n"65      "    weak-def-symbols: [ _weak3 ]\n"66      "    thread-local-symbols: [ _tlv3 ]\n"67      "...\n";68 69  Expected<TBDFile> Result =70      TextAPIReader::get(MemoryBufferRef(TBDv2File1, "Test.tbd"));71  EXPECT_TRUE(!!Result);72  TBDFile File = std::move(Result.get());73  EXPECT_EQ(FileType::TBD_V2, File->getFileType());74  auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;75  auto Platform = PLATFORM_IOS;76  TargetList Targets;77  for (auto &&arch : Archs)78    Targets.emplace_back(Target(arch, Platform));79  EXPECT_EQ(Archs, File->getArchitectures());80  EXPECT_EQ(File->getPlatforms().size(), 1U);81  EXPECT_EQ(Platform, *File->getPlatforms().begin());82  EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());83  EXPECT_EQ(PackedVersion(2, 3, 4), File->getCurrentVersion());84  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());85  EXPECT_EQ(2U, File->getSwiftABIVersion());86  EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());87  EXPECT_TRUE(File->isTwoLevelNamespace());88  EXPECT_TRUE(File->isApplicationExtensionSafe());89  InterfaceFileRef client("clientA", Targets);90  InterfaceFileRef reexport("/usr/lib/libfoo.dylib", Targets);91  EXPECT_EQ(1U, File->allowableClients().size());92  EXPECT_EQ(client, File->allowableClients().front());93  EXPECT_EQ(1U, File->reexportedLibraries().size());94  EXPECT_EQ(reexport, File->reexportedLibraries().front());95 96  ExportedSymbolSeq Exports;97  for (const auto *Sym : File->symbols()) {98    EXPECT_FALSE(Sym->isWeakReferenced());99    EXPECT_FALSE(Sym->isUndefined());100    Exports.emplace_back(101        ExportedSymbol{Sym->getKind(), std::string(Sym->getName()),102                       Sym->isWeakDefined(), Sym->isThreadLocalValue()});103  }104  llvm::sort(Exports);105 106  EXPECT_EQ(std::size(TBDv2Symbols), Exports.size());107  EXPECT_TRUE(108      std::equal(Exports.begin(), Exports.end(), std::begin(TBDv2Symbols)));109}110 111TEST(TBDv2, ReadFile2) {112  static const char TBDv2File2[] =113      "--- !tapi-tbd-v2\n"114      "archs: [ armv7, armv7s, armv7k, arm64 ]\n"115      "platform: ios\n"116      "flags: [ flat_namespace, not_app_extension_safe ]\n"117      "install-name: Test.dylib\n"118      "swift-version: 1.1\n"119      "exports:\n"120      "  - archs: [ armv7, armv7s, armv7k, arm64 ]\n"121      "    symbols: [ _sym1, _sym2, _sym3, _sym4, $ld$hide$os9.0$_sym1 ]\n"122      "    objc-classes: [ _class1, _class2 ]\n"123      "    objc-ivars: [ _class1._ivar1, _class1._ivar2 ]\n"124      "    weak-def-symbols: [ _weak1, _weak2 ]\n"125      "    thread-local-symbols: [ _tlv1, _tlv2 ]\n"126      "  - archs: [ armv7, armv7s, armv7k ]\n"127      "    symbols: [ _sym5 ]\n"128      "    objc-classes: [ _class3 ]\n"129      "    objc-ivars: [ _class1._ivar3 ]\n"130      "    weak-def-symbols: [ _weak3 ]\n"131      "    thread-local-symbols: [ _tlv3 ]\n"132      "undefineds:\n"133      "  - archs: [ armv7, armv7s, armv7k, arm64 ]\n"134      "    symbols: [ _undefSym1, _undefSym2, _undefSym3 ]\n"135      "    objc-classes: [ _undefClass1, _undefClass2 ]\n"136      "    objc-ivars: [ _undefClass1._ivar1, _undefClass1._ivar2 ]\n"137      "    weak-ref-symbols: [ _undefWeak1, _undefWeak2 ]\n"138      "...\n";139 140  Expected<TBDFile> Result =141      TextAPIReader::get(MemoryBufferRef(TBDv2File2, "Test.tbd"));142  EXPECT_TRUE(!!Result);143  TBDFile File = std::move(Result.get());144  EXPECT_EQ(FileType::TBD_V2, File->getFileType());145  auto Archs = AK_armv7 | AK_armv7s | AK_armv7k | AK_arm64;146  auto Platform = PLATFORM_IOS;147  TargetList Targets;148  for (auto &&arch : Archs)149    Targets.emplace_back(Target(arch, Platform));150  EXPECT_EQ(Archs, File->getArchitectures());151  EXPECT_EQ(File->getPlatforms().size(), 1U);152  EXPECT_EQ(Platform, *File->getPlatforms().begin());153  EXPECT_EQ(std::string("Test.dylib"), File->getInstallName());154  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCurrentVersion());155  EXPECT_EQ(PackedVersion(1, 0, 0), File->getCompatibilityVersion());156  EXPECT_EQ(2U, File->getSwiftABIVersion());157  EXPECT_EQ(ObjCConstraintType::Retain_Release, File->getObjCConstraint());158  EXPECT_FALSE(File->isTwoLevelNamespace());159  EXPECT_FALSE(File->isApplicationExtensionSafe());160  EXPECT_EQ(0U, File->allowableClients().size());161  EXPECT_EQ(0U, File->reexportedLibraries().size());162}163 164TEST(TBDv2, WriteFile) {165  static const char TBDv2File3[] =166      "--- !tapi-tbd-v2\n"167      "archs:           [ i386, x86_64 ]\n"168      "platform:        macosx\n"169      "install-name:    '/usr/lib/libfoo.dylib'\n"170      "current-version: 1.2.3\n"171      "compatibility-version: 0\n"172      "swift-version:   5\n"173      "exports:\n"174      "  - archs:           [ i386 ]\n"175      "    symbols:         [ _sym1 ]\n"176      "    weak-def-symbols: [ _sym2 ]\n"177      "    thread-local-symbols: [ _sym3 ]\n"178      "  - archs:           [ x86_64 ]\n"179      "    allowable-clients: [ clientA ]\n"180      "    re-exports:      [ '/usr/lib/libfoo.dylib' ]\n"181      "    symbols:         [ '_OBJC_EHTYPE_$_Class1' ]\n"182      "    objc-classes:    [ _Class1 ]\n"183      "    objc-ivars:      [ _Class1._ivar1 ]\n"184      "...\n";185 186  InterfaceFile File;187  TargetList Targets;188  for (auto &&arch : AK_i386 | AK_x86_64)189    Targets.emplace_back(Target(arch, PLATFORM_MACOS));190  File.setPath("libfoo.dylib");191  File.setInstallName("/usr/lib/libfoo.dylib");192  File.setFileType(FileType::TBD_V2);193  File.addTargets(Targets);194  File.setCurrentVersion(PackedVersion(1, 2, 3));195  File.setTwoLevelNamespace();196  File.setApplicationExtensionSafe();197  File.setSwiftABIVersion(5);198  File.setObjCConstraint(ObjCConstraintType::Retain_Release);199  File.addAllowableClient("clientA", Targets[1]);200  File.addReexportedLibrary("/usr/lib/libfoo.dylib", Targets[1]);201  File.addSymbol(EncodeKind::GlobalSymbol, "_sym1", {Targets[0]});202  File.addSymbol(EncodeKind::GlobalSymbol, "_sym2", {Targets[0]},203                 SymbolFlags::WeakDefined);204  File.addSymbol(EncodeKind::GlobalSymbol, "_sym3", {Targets[0]},205                 SymbolFlags::ThreadLocalValue);206  File.addSymbol(EncodeKind::ObjectiveCClass, "Class1", {Targets[1]});207  File.addSymbol(EncodeKind::ObjectiveCClassEHType, "Class1", {Targets[1]});208  File.addSymbol(EncodeKind::ObjectiveCInstanceVariable, "Class1._ivar1",209                 {Targets[1]});210 211  SmallString<4096> Buffer;212  raw_svector_ostream OS(Buffer);213  Error Result = TextAPIWriter::writeToStream(OS, File);214  EXPECT_FALSE(Result);215  EXPECT_STREQ(TBDv2File3, Buffer.c_str());216}217 218TEST(TBDv2, Platform_macOS) {219  static const char TBDv2PlatformMacOS[] = "--- !tapi-tbd-v2\n"220                                           "archs: [ x86_64 ]\n"221                                           "platform: macosx\n"222                                           "install-name: Test.dylib\n"223                                           "...\n";224 225  Expected<TBDFile> Result =226      TextAPIReader::get(MemoryBufferRef(TBDv2PlatformMacOS, "Test.tbd"));227  EXPECT_TRUE(!!Result);228  TBDFile File = std::move(Result.get());229  auto Platform = PLATFORM_MACOS;230  EXPECT_EQ(FileType::TBD_V2, File->getFileType());231  EXPECT_EQ(File->getPlatforms().size(), 1U);232  EXPECT_EQ(Platform, *File->getPlatforms().begin());233}234 235TEST(TBDv2, Platform_iOS) {236  static const char TBDv2PlatformiOS[] = "--- !tapi-tbd-v2\n"237                                         "archs: [ arm64 ]\n"238                                         "platform: ios\n"239                                         "install-name: Test.dylib\n"240                                         "...\n";241 242  Expected<TBDFile> Result =243      TextAPIReader::get(MemoryBufferRef(TBDv2PlatformiOS, "Test.tbd"));244  EXPECT_TRUE(!!Result);245  auto Platform = PLATFORM_IOS;246  TBDFile File = std::move(Result.get());247  EXPECT_EQ(FileType::TBD_V2, File->getFileType());248  EXPECT_EQ(File->getPlatforms().size(), 1U);249  EXPECT_EQ(Platform, *File->getPlatforms().begin());250}251 252TEST(TBDv2, Platform_watchOS) {253  static const char TBDv2PlatformWatchOS[] = "--- !tapi-tbd-v2\n"254                                             "archs: [ armv7k ]\n"255                                             "platform: watchos\n"256                                             "install-name: Test.dylib\n"257                                             "...\n";258 259  Expected<TBDFile> Result =260      TextAPIReader::get(MemoryBufferRef(TBDv2PlatformWatchOS, "Test.tbd"));261  EXPECT_TRUE(!!Result);262  auto Platform = PLATFORM_WATCHOS;263  TBDFile File = std::move(Result.get());264  EXPECT_EQ(FileType::TBD_V2, File->getFileType());265  EXPECT_EQ(File->getPlatforms().size(), 1U);266  EXPECT_EQ(Platform, *File->getPlatforms().begin());267}268 269TEST(TBDv2, Platform_tvOS) {270  static const char TBDv2PlatformtvOS[] = "--- !tapi-tbd-v2\n"271                                          "archs: [ arm64 ]\n"272                                          "platform: tvos\n"273                                          "install-name: Test.dylib\n"274                                          "...\n";275 276  Expected<TBDFile> Result =277      TextAPIReader::get(MemoryBufferRef(TBDv2PlatformtvOS, "Test.tbd"));278  EXPECT_TRUE(!!Result);279  auto Platform = PLATFORM_TVOS;280  TBDFile File = std::move(Result.get());281  EXPECT_EQ(FileType::TBD_V2, File->getFileType());282  EXPECT_EQ(File->getPlatforms().size(), 1U);283  EXPECT_EQ(Platform, *File->getPlatforms().begin());284}285 286TEST(TBDv2, Platform_bridgeOS) {287  static const char TBDv2BridgeOS[] = "--- !tapi-tbd-v2\n"288                                      "archs: [ armv7k ]\n"289                                      "platform: bridgeos\n"290                                      "install-name: Test.dylib\n"291                                      "...\n";292 293  Expected<TBDFile> Result =294      TextAPIReader::get(MemoryBufferRef(TBDv2BridgeOS, "Test.tbd"));295  EXPECT_TRUE(!!Result);296  auto Platform = PLATFORM_BRIDGEOS;297  TBDFile File = std::move(Result.get());298  EXPECT_EQ(FileType::TBD_V2, File->getFileType());299  EXPECT_EQ(File->getPlatforms().size(), 1U);300  EXPECT_EQ(Platform, *File->getPlatforms().begin());301}302 303TEST(TBDv2, Swift_1_0) {304  static const char TBDv2Swift1[] = "--- !tapi-tbd-v2\n"305                                    "archs: [ arm64 ]\n"306                                    "platform: ios\n"307                                    "install-name: Test.dylib\n"308                                    "swift-version: 1.0\n"309                                    "...\n";310 311  Expected<TBDFile> Result =312      TextAPIReader::get(MemoryBufferRef(TBDv2Swift1, "Test.tbd"));313  EXPECT_TRUE(!!Result);314  TBDFile File = std::move(Result.get());315  EXPECT_EQ(FileType::TBD_V2, File->getFileType());316  EXPECT_EQ(1U, File->getSwiftABIVersion());317}318 319TEST(TBDv2, Swift_1_1) {320  static const char TBDv2Swift1dot[] = "--- !tapi-tbd-v2\n"321                                       "archs: [ arm64 ]\n"322                                       "platform: ios\n"323                                       "install-name: Test.dylib\n"324                                       "swift-version: 1.1\n"325                                       "...\n";326 327  Expected<TBDFile> Result =328      TextAPIReader::get(MemoryBufferRef(TBDv2Swift1dot, "Test.tbd"));329  EXPECT_TRUE(!!Result);330  TBDFile File = std::move(Result.get());331  EXPECT_EQ(FileType::TBD_V2, File->getFileType());332  EXPECT_EQ(2U, File->getSwiftABIVersion());333}334 335TEST(TBDv2, Swift_2_0) {336  static const char tbd_v2_swift_2_0[] = "--- !tapi-tbd-v2\n"337                                         "archs: [ arm64 ]\n"338                                         "platform: ios\n"339                                         "install-name: Test.dylib\n"340                                         "swift-version: 2.0\n"341                                         "...\n";342 343  Expected<TBDFile> Result =344      TextAPIReader::get(MemoryBufferRef(tbd_v2_swift_2_0, "Test.tbd"));345  EXPECT_TRUE(!!Result);346  TBDFile File = std::move(Result.get());347  EXPECT_EQ(FileType::TBD_V2, File->getFileType());348  EXPECT_EQ(3U, File->getSwiftABIVersion());349}350 351TEST(TBDv2, Swift_3_0) {352  static const char TBDv2Swift3[] = "--- !tapi-tbd-v2\n"353                                    "archs: [ arm64 ]\n"354                                    "platform: ios\n"355                                    "install-name: Test.dylib\n"356                                    "swift-version: 3.0\n"357                                    "...\n";358 359  Expected<TBDFile> Result =360      TextAPIReader::get(MemoryBufferRef(TBDv2Swift3, "Test.tbd"));361  EXPECT_TRUE(!!Result);362  TBDFile File = std::move(Result.get());363  EXPECT_EQ(FileType::TBD_V2, File->getFileType());364  EXPECT_EQ(4U, File->getSwiftABIVersion());365}366 367TEST(TBDv2, Swift_4_0) {368  static const char TBDv2Swift4[] = "--- !tapi-tbd-v2\n"369                                    "archs: [ arm64 ]\n"370                                    "platform: ios\n"371                                    "install-name: Test.dylib\n"372                                    "swift-version: 4.0\n"373                                    "...\n";374 375  Expected<TBDFile> Result =376      TextAPIReader::get(MemoryBufferRef(TBDv2Swift4, "Test.tbd"));377  EXPECT_FALSE(!!Result);378  std::string ErrorMessage = toString(Result.takeError());379  EXPECT_EQ("malformed file\nTest.tbd:5:16: error: invalid Swift ABI "380            "version.\nswift-version: 4.0\n               ^~~\n",381            ErrorMessage);382}383 384TEST(TBDv2, Swift_5) {385  static const char TBDv2Swift5[] = "--- !tapi-tbd-v2\n"386                                    "archs: [ arm64 ]\n"387                                    "platform: ios\n"388                                    "install-name: Test.dylib\n"389                                    "swift-version: 5\n"390                                    "...\n";391 392  Expected<TBDFile> Result =393      TextAPIReader::get(MemoryBufferRef(TBDv2Swift5, "Test.tbd"));394  EXPECT_TRUE(!!Result);395  TBDFile File = std::move(Result.get());396  EXPECT_EQ(FileType::TBD_V2, File->getFileType());397  EXPECT_EQ(5U, File->getSwiftABIVersion());398}399 400TEST(TBDv2, Swift_99) {401  static const char TBDv2Swift99[] = "--- !tapi-tbd-v2\n"402                                     "archs: [ arm64 ]\n"403                                     "platform: ios\n"404                                     "install-name: Test.dylib\n"405                                     "swift-version: 99\n"406                                     "...\n";407 408  Expected<TBDFile> Result =409      TextAPIReader::get(MemoryBufferRef(TBDv2Swift99, "Test.tbd"));410  EXPECT_TRUE(!!Result);411  TBDFile File = std::move(Result.get());412  EXPECT_EQ(FileType::TBD_V2, File->getFileType());413  EXPECT_EQ(99U, File->getSwiftABIVersion());414}415 416TEST(TBDv2, UnknownArchitecture) {417  static const char TBDv2FileUnknownArch[] = "--- !tapi-tbd-v2\n"418                                             "archs: [ foo ]\n"419                                             "platform: macosx\n"420                                             "install-name: Test.dylib\n"421                                             "...\n";422  Expected<TBDFile> Result =423      TextAPIReader::get(MemoryBufferRef(TBDv2FileUnknownArch, "Test.tbd"));424  EXPECT_TRUE(!!Result);425}426 427TEST(TBDv2, UnknownPlatform) {428  static const char TBDv2FileUnknownPlatform[] = "--- !tapi-tbd-v2\n"429                                                 "archs: [ i386 ]\n"430                                                 "platform: newOS\n"431                                                 "...\n";432 433  Expected<TBDFile> Result =434      TextAPIReader::get(MemoryBufferRef(TBDv2FileUnknownPlatform, "Test.tbd"));435  EXPECT_FALSE(!!Result);436  std::string ErrorMessage = toString(Result.takeError());437  EXPECT_EQ("malformed file\nTest.tbd:3:11: error: unknown platform\nplatform: "438            "newOS\n          ^~~~~\n",439            ErrorMessage);440}441 442TEST(TBDv2, InvalidPlatform) {443  static const char TBDv2FileInvalidPlatform[] = "--- !tapi-tbd-v2\n"444                                                 "archs: [ i386 ]\n"445                                                 "platform: iosmac\n"446                                                 "install-name: Test.dylib\n"447                                                 "...\n";448 449  Expected<TBDFile> Result =450      TextAPIReader::get(MemoryBufferRef(TBDv2FileInvalidPlatform, "Test.tbd"));451  EXPECT_FALSE(!!Result);452  std::string ErrorMessage = toString(Result.takeError());453  EXPECT_EQ("malformed file\nTest.tbd:3:11: error: invalid platform\nplatform: "454            "iosmac\n          ^~~~~~\n",455            ErrorMessage);456}457 458TEST(TBDv2, MalformedFile1) {459  static const char TBDv2FileMalformed1[] = "--- !tapi-tbd-v2\n"460                                            "archs: [ arm64 ]\n"461                                            "foobar: \"Unsupported key\"\n"462                                            "...\n";463 464  Expected<TBDFile> Result =465      TextAPIReader::get(MemoryBufferRef(TBDv2FileMalformed1, "Test.tbd"));466  EXPECT_FALSE(!!Result);467  std::string ErrorMessage = toString(Result.takeError());468  ASSERT_EQ("malformed file\nTest.tbd:2:1: error: missing required key "469            "'platform'\narchs: [ arm64 ]\n^\n",470            ErrorMessage);471}472 473TEST(TBDv2, MalformedFile2) {474  static const char TBDv2FileMalformed2[] = "--- !tapi-tbd-v2\n"475                                            "archs: [ arm64 ]\n"476                                            "platform: ios\n"477                                            "install-name: Test.dylib\n"478                                            "foobar: \"Unsupported key\"\n"479                                            "...\n";480 481  Expected<TBDFile> Result =482      TextAPIReader::get(MemoryBufferRef(TBDv2FileMalformed2, "Test.tbd"));483  EXPECT_FALSE(!!Result);484  std::string ErrorMessage = toString(Result.takeError());485  ASSERT_EQ(486      "malformed file\nTest.tbd:5:1: error: unknown key 'foobar'\nfoobar: "487      "\"Unsupported key\"\n^~~~~~\n",488      ErrorMessage);489}490 491} // namespace TBDv2492