[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