[llvm-branch-commits] [llvm] 7f25460 - [text] WIP writerf

Cyndy Ishida via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Feb 16 13:54:21 PST 2023


Author: Cyndy Ishida
Date: 2023-02-16T13:53:38-08:00
New Revision: 7f254605c66e0260f8b169cd62b094e8a56ddb70

URL: https://github.com/llvm/llvm-project/commit/7f254605c66e0260f8b169cd62b094e8a56ddb70
DIFF: https://github.com/llvm/llvm-project/commit/7f254605c66e0260f8b169cd62b094e8a56ddb70.diff

LOG: [text] WIP writerf

Added: 
    

Modified: 
    llvm/lib/TextAPI/TextStub.cpp
    llvm/lib/TextAPI/TextStubCommon.h
    llvm/lib/TextAPI/TextStubV5.cpp
    llvm/unittests/TextAPI/TextStubV5Tests.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/TextAPI/TextStub.cpp b/llvm/lib/TextAPI/TextStub.cpp
index 73cb61472bff..af60bd794e2d 100644
--- a/llvm/lib/TextAPI/TextStub.cpp
+++ b/llvm/lib/TextAPI/TextStub.cpp
@@ -1163,6 +1163,12 @@ Error TextAPIWriter::writeToStream(raw_ostream &OS, const InterfaceFile &File) {
   TextAPIContext Ctx;
   Ctx.Path = std::string(File.getPath());
   Ctx.FileKind = File.getFileType();
+
+  // Write out in JSON format.
+  if (Ctx.FileKind >= FileType::TBD_V5) {
+    return serializeInterfaceFileToJSON(OS, File);
+  }
+
   llvm::yaml::Output YAMLOut(OS, &Ctx, /*WrapColumn=*/80);
 
   std::vector<const InterfaceFile *> Files;

diff  --git a/llvm/lib/TextAPI/TextStubCommon.h b/llvm/lib/TextAPI/TextStubCommon.h
index 51b423137f4e..6ee5b3931831 100644
--- a/llvm/lib/TextAPI/TextStubCommon.h
+++ b/llvm/lib/TextAPI/TextStubCommon.h
@@ -45,6 +45,8 @@ class PackedVersion;
 
 Expected<std::unique_ptr<InterfaceFile>>
 getInterfaceFileFromJSON(StringRef JSON);
+
+Error serializeInterfaceFileToJSON(raw_ostream &OS, const InterfaceFile &File);
 } // namespace MachO
 
 namespace yaml {

diff  --git a/llvm/lib/TextAPI/TextStubV5.cpp b/llvm/lib/TextAPI/TextStubV5.cpp
index d19f7dd457f3..abd3f6030e96 100644
--- a/llvm/lib/TextAPI/TextStubV5.cpp
+++ b/llvm/lib/TextAPI/TextStubV5.cpp
@@ -155,6 +155,10 @@ static llvm::SmallString<128> getParseErrorMsg(TBDKey Key) {
   return {"invalid ", Keys[Key], " section"};
 }
 
+static llvm::SmallString<128> getSerializeErrorMsg(TBDKey Key) {
+  return {"missing ", Keys[Key], " information"};
+}
+
 class JSONStubError : public llvm::ErrorInfo<llvm::json::ParseError> {
 public:
   JSONStubError(Twine ErrMsg) : Message(ErrMsg.str()) {}
@@ -710,3 +714,78 @@ MachO::getInterfaceFileFromJSON(StringRef JSON) {
   }
   return std::move(IF);
 }
+
+namespace {
+
+bool insertNonEmptyArray(Object &Obj, TBDKey Key, Array &&Contents) {
+  if (Contents.empty())
+    return false;
+  Obj[Keys[Key]] = std::move(Contents);
+  return true;
+}
+
+Array serializeTargets(const InterfaceFile *File) {
+  Array Targets;
+  for (const auto Targ : File->targets()) {
+    Object TargetInfo;
+    TargetInfo[Keys[TBDKey::Deployment]] = Targ.MinDeployment.getAsString();
+    TargetInfo[Keys[TBDKey::Target]] =
+        (getArchitectureName(Targ.Arch) + "-" + getPlatformName(Targ.Platform))
+            .str();
+    Targets.emplace_back(std::move(TargetInfo));
+  }
+  return Targets;
+}
+
+Array serializeInstallNames(const InterfaceFile *File) {
+  Array Names;
+  return Names;
+}
+
+Expected<Object> serializeIF(const InterfaceFile *File) {
+  Object Library;
+
+  // Handle required keys.
+  if (!insertNonEmptyArray(Library, TBDKey::TargetInfo, serializeTargets(File)))
+    return make_error<JSONStubError>(getSerializeErrorMsg(TBDKey::TargetInfo));
+
+  // if (!insertNonEmptyArray(Library, TBDKey::InstallName,
+  // serializeInstallNames(File)))
+  //   return
+  //   make_error<JSONStubError>(getSerializeErrorMsg(TBDKey::InstallName));
+
+  return Library;
+}
+
+Expected<Object> getJSON(const InterfaceFile *File) {
+  assert(File->getFileType() == FileType::TBD_V5 &&
+         "unexpected json file format version");
+  Object Root;
+
+  Array Documents;
+  auto MainLibOrErr = serializeIF(File);
+  if (!MainLibOrErr)
+    return MainLibOrErr;
+  Documents.emplace_back(std::move(*MainLibOrErr));
+  for (const auto &Doc : File->documents()) {
+    auto LibOrErr = serializeIF(Doc.get());
+    if (!LibOrErr)
+      return LibOrErr;
+    Documents.emplace_back(std::move(*LibOrErr));
+  }
+
+  Root[Keys[TBDKey::TBDVersion]] = 5;
+  Root[Keys[TBDKey::Document]] = std::move(Documents);
+  return Root;
+}
+
+} // namespace
+
+Error MachO::serializeInterfaceFileToJSON(raw_ostream &OS,
+                                          const InterfaceFile &File) {
+  auto TextFile = getJSON(&File);
+  if (!TextFile)
+    return TextFile.takeError();
+  OS << formatv("{0:2}", Value(std::move(*TextFile))) << "\n";
+  return Error::success();
+}

diff  --git a/llvm/unittests/TextAPI/TextStubV5Tests.cpp b/llvm/unittests/TextAPI/TextStubV5Tests.cpp
index 5b0b596b1cd1..8ccde0c79483 100644
--- a/llvm/unittests/TextAPI/TextStubV5Tests.cpp
+++ b/llvm/unittests/TextAPI/TextStubV5Tests.cpp
@@ -519,4 +519,154 @@ TEST(TBDv5, ReadMultipleDocuments) {
       std::equal(Exports.begin(), Exports.end(), std::begin(ExpectedExports)));
 }
 
+TEST(TBDv5, WriteFile) {
+  static const char TBDv5File[] = R"({ 
+"tapi_tbd_version": 5,
+"files": [
+    {
+        "target_info": [
+            {
+                "target": "x86_64-macos",
+                "min_deployment": "10.14" 
+            },
+            {
+                "target": "arm64-macos",
+                "min_deployment": "10.14"
+            },
+            {
+                "target": "arm64-maccatalyst",
+                "min_deployment": "12.1"
+            }
+        ],
+        "flags":[ 
+            {
+            "attributes": ["flat_namespace"]
+            }
+        ], 
+        "install_names":[
+            {
+                "name":"/S/L/F/Foo.framework/Foo"
+            }
+        ],
+        "current_versions":[ 
+            {
+                "version": "1.2"
+            }
+        ],
+        "compatibility_versions":[
+            {
+                "version": "1.1"
+            }
+         ],
+        "rpaths": [ 
+           {
+            "targets": ["x86_64-macos"],
+            "paths": ["@executable_path/.../Frameworks"]
+           }
+         ],
+        "parent_umbrellas": [
+            {
+                "umbrella": "System"
+            }
+        ],
+        "allowable_clients": [
+            {
+                "clients": [ "ClientA","ClientB" ]
+            }
+        ],
+        "reexported_libraries": [
+            {
+                "names": [
+                    "/u/l/l/libfoo.dylib",
+                    "/u/l/l/libbar.dylib"
+                ]
+            }
+        ],
+        "exported_symbols": [
+            {
+                "targets": [ "x86_64-macos", "arm64-macos" ],
+                "data": { 
+                    "globals": [ "_global" ],
+                    "objc_classes": [ "ClassA" ],
+                    "weaks": [],
+                    "thread-locals": []
+                },
+                "text": { 
+                    "globals": [ "_func" ]
+                }
+            },
+            {
+                "targets": [
+                    "x86_64-macos"
+                ],
+                "data": {
+                    "globals": [ "_globalVar" ],
+                    "objc_classes": [ "ClassData" ], 
+                    "objc_eh_types": [ "ClassA", "ClassB" ], 
+                    "objc_ivars": [ "ClassA.ivar1", "ClassA.ivar2", "ClassC.ivar1" ]
+                },
+                "text": {
+                    "globals": [ "_funcFoo" ]
+                }
+            }
+        ],
+        "reexported_symbols": [
+            {
+                "targets": [ "x86_64-macos", "arm64-macos" ],
+                "data": {
+                    "globals": [ "_globalRe" ],
+                    "objc_classes": [ "ClassRexport" ]
+                },
+                "text": {
+                    "globals": [ "_funcA" ]
+                }
+            }
+        ],
+        "undefined_symbols": [
+            {
+                "targets": [ "x86_64-macos" ],
+                "data": {
+                    "globals": [ "_globalBind" ],
+                    "weaks": [ "referenced_sym" ]
+                }
+            }
+        ]
+    }
+]
+})";
+
+  InterfaceFile File;
+  File.setFileType(FileType::TBD_V5);
+
+  TargetList AllTargets = {
+      Target(AK_x86_64, PLATFORM_MACOS, VersionTuple(10, 14)),
+      Target(AK_arm64, PLATFORM_MACOS, VersionTuple(10, 14)),
+      Target(AK_arm64, PLATFORM_MACCATALYST, VersionTuple(12, 1)),
+  };
+  File.addTargets(AllTargets);
+  File.setInstallName("Umbrella.framework/Umbrella");
+  // File.addUUID(uuids[0].first, uuids[0].second);
+  // File.addUUID(uuids[1].first, uuids[1].second);
+  // File.setCurrentVersion(PackedVersion(1, 2, 3));
+  // File.setTwoLevelNamespace();
+  // File.setInstallAPI(true);
+  // File.setApplicationExtensionSafe(true);
+  // File.setSwiftABIVersion(5);
+  // File.addAllowableClient("ClientA", Targets[0]);
+  // File.addParentUmbrella(Targets[0], "System");
+  // File.addParentUmbrella(Targets[1], "System");
+  // File.addSymbol(SymbolKind::GlobalSymbol, "_symA", {Targets[0]});
+  // File.addSymbol(SymbolKind::GlobalSymbol, "_symB", {Targets[1]});
+  // File.addSymbol(SymbolKind::GlobalSymbol, "_symC", {Targets[0]},
+  //                SymbolFlags::WeakDefined);
+  // File.addSymbol(SymbolKind::ObjectiveCClass, "Class1", {Targets[0]});
+
+  SmallString<4096> Buffer;
+  raw_svector_ostream OS(Buffer);
+  Error Result = TextAPIWriter::writeToStream(OS, File);
+  EXPECT_FALSE(Result);
+  llvm::outs() << Buffer;
+  EXPECT_STREQ(TBDv5File, Buffer.c_str());
+}
+
 } // end namespace TBDv5


        


More information about the llvm-branch-commits mailing list