[clang][ssaf] Add MultiArchSharedLibrary data structure (#206854)
This change introduces `MultiArchSharedLibrary` data structure that wraps per-architecture `LUSummaryEncoding` members. This is the SSAF analogue of a fat shared library. The overall design mirrors the existing `MultiArchStaticLibrary` design: each member identifies the same logical library built for a different target triple. Support for constructing and consuming this object will be added in a future PR. rdar://181164537
This commit is contained in:
parent
8aaa28e8d7
commit
e69038f9c2
47 changed files with 1210 additions and 31 deletions
|
|
@ -33,6 +33,7 @@ namespace clang::ssaf {
|
|||
/// entity linker and contains deduplicated and patched entity summaries.
|
||||
class LUSummaryEncoding {
|
||||
friend class EntityLinker;
|
||||
friend class MultiArchSharedLibrary;
|
||||
friend class SerializationFormat;
|
||||
friend class TestFixture;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
//===- MultiArchSharedLibrary.h ---------------------------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the MultiArchSharedLibrary class, which represents a
|
||||
// multi-architecture wrapper around per-architecture LUSummaryEncoding
|
||||
// instances (the SSAF analogue of a Mach-O fat shared library/dylib, e.g.
|
||||
// one produced by `lipo -create` over per-arch `.dylib` files).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_ENTITYLINKER_MULTIARCHSHAREDLIBRARY_H
|
||||
#define LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_ENTITYLINKER_MULTIARCHSHAREDLIBRARY_H
|
||||
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummaryEncoding.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/Model/BuildNamespace.h"
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <tuple>
|
||||
|
||||
namespace clang::ssaf {
|
||||
|
||||
/// Represents a multi-architecture shared library.
|
||||
///
|
||||
/// A MultiArchSharedLibrary bundles per-architecture LUSummaryEncoding
|
||||
/// members, mirroring the role of a Mach-O fat shared library (the result
|
||||
/// of `lipo -create` over per-architecture `.dylib` files). All members
|
||||
/// represent the same logical shared library built for different
|
||||
/// architectures; the wrapper's \c Namespace is the nested build
|
||||
/// namespace identifying that shared library, and every member's
|
||||
/// \c LUNamespace must equal it exactly.
|
||||
class MultiArchSharedLibrary {
|
||||
friend class SerializationFormat;
|
||||
friend class TestFixture;
|
||||
|
||||
/// Orders members by their TargetTriple's canonical enum components.
|
||||
/// llvm::Triple's parser maps alias spellings to the same enum values
|
||||
/// (e.g. "aarch64" and "arm64" both become Triple::aarch64), so a
|
||||
/// tuple-of-enums compare is equivalent to comparing normalized triples
|
||||
/// for identity, but without the per-call string allocation.
|
||||
struct MemberByTargetTriple {
|
||||
static auto key(const llvm::Triple &T) {
|
||||
return std::make_tuple(T.getArch(), T.getSubArch(), T.getVendor(),
|
||||
T.getOS(), T.getEnvironment(),
|
||||
T.getObjectFormat());
|
||||
}
|
||||
bool operator()(const std::unique_ptr<LUSummaryEncoding> &A,
|
||||
const std::unique_ptr<LUSummaryEncoding> &B) const {
|
||||
return key(A->TargetTriple) < key(B->TargetTriple);
|
||||
}
|
||||
};
|
||||
|
||||
// The nested namespace identifying this multi-architecture shared
|
||||
// library. It matches the LUNamespace of every member exactly (same
|
||||
// path, same kinds, same names): the shared library's identity is the
|
||||
// same across all its architecture slices.
|
||||
NestedBuildNamespace Namespace;
|
||||
|
||||
// LUSummaryEncoding objects ordered by TargetTriple enum components.
|
||||
// Two members with the same TargetTriple are not permitted.
|
||||
std::set<std::unique_ptr<LUSummaryEncoding>, MemberByTargetTriple> Members;
|
||||
|
||||
public:
|
||||
explicit MultiArchSharedLibrary(NestedBuildNamespace Namespace)
|
||||
: Namespace(std::move(Namespace)) {}
|
||||
};
|
||||
|
||||
} // namespace clang::ssaf
|
||||
|
||||
#endif // LLVM_CLANG_SCALABLESTATICANALYSIS_CORE_ENTITYLINKER_MULTIARCHSHAREDLIBRARY_H
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
//
|
||||
// This file defines the MultiArchStaticLibrary class, which represents a
|
||||
// multi-architecture wrapper around per-architecture StaticLibrary
|
||||
// instances (the SSAF analogue of a Mach-O fat static library, e.g. one
|
||||
// produced by `lipo -create` over per-arch `.a` files).
|
||||
// instances.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
|
@ -26,21 +25,15 @@ namespace clang::ssaf {
|
|||
|
||||
/// Represents a multi-architecture static library.
|
||||
///
|
||||
/// A MultiArchStaticLibrary bundles per-architecture StaticLibrary
|
||||
/// members, mirroring the role of a Mach-O fat static library (the result
|
||||
/// of `lipo -create` over per-architecture `.a` files). All members
|
||||
/// represent the same logical library built for different architectures;
|
||||
/// the wrapper's \c Namespace identifies that shared library and every
|
||||
/// member's namespace must agree on its name.
|
||||
/// A MultiArchStaticLibrary bundles per-architecture StaticLibrary members. All
|
||||
/// members represent the same logical library built for different
|
||||
/// architectures; the wrapper's \c Namespace identifies that shared library and
|
||||
/// every member's namespace must agree on its name.
|
||||
class MultiArchStaticLibrary {
|
||||
friend class SerializationFormat;
|
||||
friend class TestFixture;
|
||||
|
||||
/// Orders members by their TargetTriple's canonical enum components.
|
||||
/// llvm::Triple's parser maps alias spellings to the same enum values
|
||||
/// (e.g. "aarch64" and "arm64" both become Triple::aarch64), so a
|
||||
/// tuple-of-enums compare is equivalent to comparing normalized triples
|
||||
/// for identity, but without the per-call string allocation.
|
||||
struct MemberByTargetTriple {
|
||||
static auto key(const llvm::Triple &T) {
|
||||
return std::make_tuple(T.getArch(), T.getSubArch(), T.getVendor(),
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ FIELD(LUSummaryEncoding, LinkageTable)
|
|||
FIELD(LUSummaryEncoding, LUNamespace)
|
||||
FIELD(MultiArchStaticLibrary, Members)
|
||||
FIELD(MultiArchStaticLibrary, Namespace)
|
||||
FIELD(MultiArchSharedLibrary, Members)
|
||||
FIELD(MultiArchSharedLibrary, Namespace)
|
||||
FIELD(NestedBuildNamespace, Namespaces)
|
||||
FIELD(StaticLibrary, Members)
|
||||
FIELD(StaticLibrary, Namespace)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ public:
|
|||
llvm::Error writeMultiArchStaticLibrary(const MultiArchStaticLibrary &M,
|
||||
llvm::StringRef Path) override;
|
||||
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
readMultiArchSharedLibrary(llvm::StringRef Path) override;
|
||||
|
||||
llvm::Error writeMultiArchSharedLibrary(const MultiArchSharedLibrary &M,
|
||||
llvm::StringRef Path) override;
|
||||
|
||||
llvm::Expected<WPASuite> readWPASuite(llvm::StringRef Path) override;
|
||||
|
||||
llvm::Error writeWPASuite(const WPASuite &Suite,
|
||||
|
|
@ -143,6 +149,11 @@ private:
|
|||
llvm::Expected<MultiArchStaticLibrary>
|
||||
readMultiArchStaticLibraryFromObject(const Object &Root);
|
||||
|
||||
/// Parses a MultiArchSharedLibrary from an already-validated root JSON
|
||||
/// object. See \c readTUSummaryFromObject for caller responsibilities.
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
readMultiArchSharedLibraryFromObject(const Object &Root);
|
||||
|
||||
/// Serializes a TUSummaryEncoding to a JSON object including its
|
||||
/// self-describing \c type field. Used both by \c writeTUSummaryEncoding
|
||||
/// and by the StaticLibrary writer to emit member entries.
|
||||
|
|
@ -153,6 +164,11 @@ private:
|
|||
/// and by the MultiArchStaticLibrary writer to emit per-arch slices.
|
||||
Object staticLibraryToJSON(const StaticLibrary &S) const;
|
||||
|
||||
/// Serializes an LUSummaryEncoding to a JSON object including its
|
||||
/// self-describing \c type field. Used both by \c writeLUSummaryEncoding
|
||||
/// and by the MultiArchSharedLibrary writer to emit per-arch slices.
|
||||
Object luSummaryEncodingToJSON(const LUSummaryEncoding &E) const;
|
||||
|
||||
/// Parses a WPASuite from an already-validated root JSON object. See
|
||||
/// \c readTUSummaryFromObject for caller responsibilities.
|
||||
llvm::Expected<WPASuite> readWPASuiteFromObject(const Object &Root);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummaryEncoding.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchSharedLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchStaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h"
|
||||
|
|
@ -43,12 +44,13 @@ using Artifact = std::variant<TUSummary, LUSummary, WPASuite>;
|
|||
/// artifacts but with their per-entity summary payloads left as opaque
|
||||
/// format-specific encodings rather than fully resolved analysis results.
|
||||
///
|
||||
/// \c StaticLibrary and \c MultiArchStaticLibrary appear only in this
|
||||
/// variant: the archiver/arch tools and the linker pass member payloads
|
||||
/// through without decoding them, so fully decoded shapes would have no
|
||||
/// consumer.
|
||||
using ArtifactEncoding = std::variant<TUSummaryEncoding, LUSummaryEncoding,
|
||||
StaticLibrary, MultiArchStaticLibrary>;
|
||||
/// \c StaticLibrary, \c MultiArchStaticLibrary, and
|
||||
/// \c MultiArchSharedLibrary appear only in this variant: the
|
||||
/// archiver/arch tools and the linker pass member payloads through
|
||||
/// without decoding them, so fully decoded shapes would have no consumer.
|
||||
using ArtifactEncoding =
|
||||
std::variant<TUSummaryEncoding, LUSummaryEncoding, StaticLibrary,
|
||||
MultiArchStaticLibrary, MultiArchSharedLibrary>;
|
||||
|
||||
/// Abstract base class for serialization formats.
|
||||
class SerializationFormat {
|
||||
|
|
@ -115,6 +117,13 @@ public:
|
|||
writeMultiArchStaticLibrary(const MultiArchStaticLibrary &M,
|
||||
llvm::StringRef Path) = 0;
|
||||
|
||||
virtual llvm::Expected<MultiArchSharedLibrary>
|
||||
readMultiArchSharedLibrary(llvm::StringRef Path) = 0;
|
||||
|
||||
virtual llvm::Error
|
||||
writeMultiArchSharedLibrary(const MultiArchSharedLibrary &M,
|
||||
llvm::StringRef Path) = 0;
|
||||
|
||||
virtual llvm::Expected<WPASuite> readWPASuite(llvm::StringRef Path) = 0;
|
||||
|
||||
virtual llvm::Error writeWPASuite(const WPASuite &Suite,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ add_clang_library(clangScalableStaticAnalysisCore
|
|||
Serialization/JSONFormat/LUSummary.cpp
|
||||
Serialization/JSONFormat/LUSummaryEncoding.cpp
|
||||
Serialization/JSONFormat/MultiArchStaticLibrary.cpp
|
||||
Serialization/JSONFormat/MultiArchSharedLibrary.cpp
|
||||
Serialization/JSONFormat/StaticLibrary.cpp
|
||||
Serialization/JSONFormat/TUSummary.cpp
|
||||
Serialization/JSONFormat/TUSummaryEncoding.cpp
|
||||
|
|
|
|||
|
|
@ -165,11 +165,22 @@ JSONFormat::readArtifactEncoding(llvm::StringRef Path) {
|
|||
return ArtifactEncoding{std::move(*ExpectedM)};
|
||||
}
|
||||
|
||||
if (*ExpectedType == JSONTypeValueMultiArchSharedLibrary) {
|
||||
auto ExpectedM = readMultiArchSharedLibraryFromObject(*RootObjectPtr);
|
||||
if (!ExpectedM) {
|
||||
return ErrorBuilder::wrap(ExpectedM.takeError())
|
||||
.context(ErrorMessages::ReadingFromFile, "ArtifactEncoding", Path)
|
||||
.build();
|
||||
}
|
||||
return ArtifactEncoding{std::move(*ExpectedM)};
|
||||
}
|
||||
|
||||
return ErrorBuilder::create(
|
||||
std::errc::invalid_argument,
|
||||
ErrorMessages::UnknownArtifactEncodingType, *ExpectedType,
|
||||
JSONTypeKey, JSONTypeValueTUSummary, JSONTypeValueLUSummary,
|
||||
JSONTypeValueStaticLibrary, JSONTypeValueMultiArchStaticLibrary)
|
||||
JSONTypeValueStaticLibrary, JSONTypeValueMultiArchStaticLibrary,
|
||||
JSONTypeValueMultiArchSharedLibrary)
|
||||
.context(ErrorMessages::ReadingFromFile, "ArtifactEncoding", Path)
|
||||
.build();
|
||||
}
|
||||
|
|
@ -185,11 +196,13 @@ llvm::Error JSONFormat::writeArtifactEncoding(const ArtifactEncoding &E,
|
|||
return writeLUSummaryEncoding(Enc, Path);
|
||||
} else if constexpr (std::is_same_v<T, StaticLibrary>) {
|
||||
return writeStaticLibrary(Enc, Path);
|
||||
} else if constexpr (std::is_same_v<T, MultiArchStaticLibrary>) {
|
||||
return writeMultiArchStaticLibrary(Enc, Path);
|
||||
} else {
|
||||
static_assert(
|
||||
std::is_same_v<T, MultiArchStaticLibrary>,
|
||||
std::is_same_v<T, MultiArchSharedLibrary>,
|
||||
"ArtifactEncoding visitor must cover all variant alternatives");
|
||||
return writeMultiArchStaticLibrary(Enc, Path);
|
||||
return writeMultiArchSharedLibrary(Enc, Path);
|
||||
}
|
||||
},
|
||||
E);
|
||||
|
|
|
|||
|
|
@ -82,11 +82,13 @@ inline constexpr const char *FailedToReadObjectAtIndex =
|
|||
|
||||
inline constexpr const char *MismatchedSummaryType =
|
||||
"expected '{0}' for field '{1}' but got '{2}'";
|
||||
inline constexpr const char *MismatchedNestedNamespace =
|
||||
"field '{0}' does not equal the enclosing artifact's namespace";
|
||||
inline constexpr const char *UnknownArtifactType =
|
||||
"unknown value '{0}' for field '{1}': expected '{2}', '{3}', or '{4}'";
|
||||
inline constexpr const char *UnknownArtifactEncodingType =
|
||||
"unknown value '{0}' for field '{1}': expected '{2}', '{3}', '{4}', or "
|
||||
"'{5}'";
|
||||
"unknown value '{0}' for field '{1}': expected '{2}', '{3}', '{4}', '{5}', "
|
||||
"or '{6}'";
|
||||
|
||||
inline constexpr const char *FailedToDeserializeEntitySummaryNoFormatInfo =
|
||||
"failed to deserialize EntitySummary: no FormatInfo registered for '{0}'";
|
||||
|
|
@ -158,6 +160,11 @@ inline constexpr const char *JSONTypeValueStaticLibrary = "StaticLibrary";
|
|||
inline constexpr const char *JSONTypeValueMultiArchStaticLibrary =
|
||||
"MultiArchStaticLibrary";
|
||||
|
||||
/// Value written to \c JSONTypeKey for serialized \c MultiArchSharedLibrary
|
||||
/// files.
|
||||
inline constexpr const char *JSONTypeValueMultiArchSharedLibrary =
|
||||
"MultiArchSharedLibrary";
|
||||
|
||||
/// Value written to \c JSONTypeKey for serialized \c WPASuite files.
|
||||
inline constexpr const char *JSONTypeValueWPASuite = "WPASuite";
|
||||
|
||||
|
|
|
|||
|
|
@ -164,6 +164,17 @@ JSONFormat::readLUSummaryEncodingFromObject(const Object &RootObject) {
|
|||
llvm::Error
|
||||
JSONFormat::writeLUSummaryEncoding(const LUSummaryEncoding &SummaryEncoding,
|
||||
llvm::StringRef Path) {
|
||||
if (auto Error = writeJSON(luSummaryEncodingToJSON(SummaryEncoding), Path)) {
|
||||
return ErrorBuilder::wrap(std::move(Error))
|
||||
.context(ErrorMessages::WritingToFile, "LUSummary", Path)
|
||||
.build();
|
||||
}
|
||||
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
Object JSONFormat::luSummaryEncodingToJSON(
|
||||
const LUSummaryEncoding &SummaryEncoding) const {
|
||||
Object RootObject;
|
||||
|
||||
RootObject[JSONTypeKey] = JSONTypeValueLUSummary;
|
||||
|
|
@ -181,13 +192,7 @@ JSONFormat::writeLUSummaryEncoding(const LUSummaryEncoding &SummaryEncoding,
|
|||
|
||||
RootObject["data"] = encodingSummaryDataMapToJSON(getData(SummaryEncoding));
|
||||
|
||||
if (auto Error = writeJSON(std::move(RootObject), Path)) {
|
||||
return ErrorBuilder::wrap(std::move(Error))
|
||||
.context(ErrorMessages::WritingToFile, "LUSummary", Path)
|
||||
.build();
|
||||
}
|
||||
|
||||
return llvm::Error::success();
|
||||
return RootObject;
|
||||
}
|
||||
|
||||
} // namespace clang::ssaf
|
||||
|
|
|
|||
|
|
@ -0,0 +1,163 @@
|
|||
//===- MultiArchSharedLibrary.cpp -----------------------------------------===//
|
||||
//
|
||||
// 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 "JSONFormatImpl.h"
|
||||
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummaryEncoding.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchSharedLibrary.h"
|
||||
#include "llvm/TargetParser/Triple.h"
|
||||
|
||||
namespace clang::ssaf {
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MultiArchSharedLibrary
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
JSONFormat::readMultiArchSharedLibrary(llvm::StringRef Path) {
|
||||
auto ExpectedJSON = readJSON(Path);
|
||||
if (!ExpectedJSON) {
|
||||
return ErrorBuilder::wrap(ExpectedJSON.takeError())
|
||||
.context(ErrorMessages::ReadingFromFile, "MultiArchSharedLibrary", Path)
|
||||
.build();
|
||||
}
|
||||
|
||||
Object *RootObjectPtr = ExpectedJSON->getAsObject();
|
||||
if (!RootObjectPtr) {
|
||||
return ErrorBuilder::create(std::errc::invalid_argument,
|
||||
ErrorMessages::FailedToReadObject,
|
||||
"MultiArchSharedLibrary", "object")
|
||||
.context(ErrorMessages::ReadingFromFile, "MultiArchSharedLibrary", Path)
|
||||
.build();
|
||||
}
|
||||
|
||||
if (auto Err = checkSummaryType(*RootObjectPtr,
|
||||
JSONTypeValueMultiArchSharedLibrary)) {
|
||||
return ErrorBuilder::wrap(std::move(Err))
|
||||
.context(ErrorMessages::ReadingFromFile, "MultiArchSharedLibrary", Path)
|
||||
.build();
|
||||
}
|
||||
|
||||
auto ExpectedM = readMultiArchSharedLibraryFromObject(*RootObjectPtr);
|
||||
if (!ExpectedM) {
|
||||
return ErrorBuilder::wrap(ExpectedM.takeError())
|
||||
.context(ErrorMessages::ReadingFromFile, "MultiArchSharedLibrary", Path)
|
||||
.build();
|
||||
}
|
||||
|
||||
return std::move(*ExpectedM);
|
||||
}
|
||||
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
JSONFormat::readMultiArchSharedLibraryFromObject(const Object &RootObject) {
|
||||
const Array *NamespaceArray = RootObject.getArray("namespace");
|
||||
if (!NamespaceArray) {
|
||||
return ErrorBuilder::create(std::errc::invalid_argument,
|
||||
ErrorMessages::FailedToReadObjectAtField,
|
||||
"NestedBuildNamespace", "namespace", "array")
|
||||
.build();
|
||||
}
|
||||
|
||||
auto ExpectedNamespace = nestedBuildNamespaceFromJSON(*NamespaceArray);
|
||||
if (!ExpectedNamespace) {
|
||||
return ErrorBuilder::wrap(ExpectedNamespace.takeError())
|
||||
.context(ErrorMessages::ReadingFromField, "NestedBuildNamespace",
|
||||
"namespace")
|
||||
.build();
|
||||
}
|
||||
|
||||
const Array *MembersArray = RootObject.getArray("members");
|
||||
if (!MembersArray) {
|
||||
return ErrorBuilder::create(std::errc::invalid_argument,
|
||||
ErrorMessages::FailedToReadObjectAtField,
|
||||
"MultiArchSharedLibrary members", "members",
|
||||
"array")
|
||||
.build();
|
||||
}
|
||||
|
||||
MultiArchSharedLibrary M(std::move(*ExpectedNamespace));
|
||||
auto &Members = getMembers(M);
|
||||
const auto &WrapperNamespace = getNamespace(M);
|
||||
|
||||
for (const auto &[Index, MemberValue] : llvm::enumerate(*MembersArray)) {
|
||||
const Object *MemberObject = MemberValue.getAsObject();
|
||||
if (!MemberObject) {
|
||||
return ErrorBuilder::create(std::errc::invalid_argument,
|
||||
ErrorMessages::FailedToReadObjectAtIndex,
|
||||
"MultiArchSharedLibrary member", Index,
|
||||
"object")
|
||||
.build();
|
||||
}
|
||||
|
||||
if (auto Err = checkSummaryType(*MemberObject, JSONTypeValueLUSummary)) {
|
||||
return ErrorBuilder::wrap(std::move(Err))
|
||||
.context(ErrorMessages::ReadingFromIndex,
|
||||
"MultiArchSharedLibrary member", Index)
|
||||
.build();
|
||||
}
|
||||
|
||||
auto ExpectedMember = readLUSummaryEncodingFromObject(*MemberObject);
|
||||
if (!ExpectedMember) {
|
||||
return ErrorBuilder::wrap(ExpectedMember.takeError())
|
||||
.context(ErrorMessages::ReadingFromIndex,
|
||||
"MultiArchSharedLibrary member", Index)
|
||||
.build();
|
||||
}
|
||||
|
||||
// Every per-arch slice must resolve to the same shared-library identity,
|
||||
// so the member's LUNamespace must equal the wrapper's Namespace.
|
||||
if (WrapperNamespace != getLUNamespace(*ExpectedMember)) {
|
||||
return ErrorBuilder::create(std::errc::invalid_argument,
|
||||
ErrorMessages::MismatchedNestedNamespace,
|
||||
"lu_namespace")
|
||||
.context(ErrorMessages::ReadingFromIndex,
|
||||
"MultiArchSharedLibrary member", Index)
|
||||
.build();
|
||||
}
|
||||
|
||||
auto [It, Inserted] = Members.insert(
|
||||
std::make_unique<LUSummaryEncoding>(std::move(*ExpectedMember)));
|
||||
if (!Inserted) {
|
||||
auto MemberTriple = llvm::Triple::normalize(getTargetTriple(**It).str());
|
||||
return ErrorBuilder::create(std::errc::invalid_argument,
|
||||
ErrorMessages::FailedInsertionOnDuplication,
|
||||
"MultiArchSharedLibrary member", Index,
|
||||
MemberTriple)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(M);
|
||||
}
|
||||
|
||||
llvm::Error
|
||||
JSONFormat::writeMultiArchSharedLibrary(const MultiArchSharedLibrary &M,
|
||||
llvm::StringRef Path) {
|
||||
Object RootObject;
|
||||
|
||||
RootObject[JSONTypeKey] = JSONTypeValueMultiArchSharedLibrary;
|
||||
|
||||
RootObject["namespace"] = nestedBuildNamespaceToJSON(getNamespace(M));
|
||||
|
||||
Array MembersArray;
|
||||
MembersArray.reserve(getMembers(M).size());
|
||||
for (const auto &Member : getMembers(M)) {
|
||||
MembersArray.push_back(luSummaryEncodingToJSON(*Member));
|
||||
}
|
||||
RootObject["members"] = std::move(MembersArray);
|
||||
|
||||
if (auto Error = writeJSON(std::move(RootObject), Path)) {
|
||||
return ErrorBuilder::wrap(std::move(Error))
|
||||
.context(ErrorMessages::WritingToFile, "MultiArchSharedLibrary", Path)
|
||||
.build();
|
||||
}
|
||||
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
} // namespace clang::ssaf
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"members": [],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": {
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"suffix": "",
|
||||
"usr": "c:@F@foo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"linkage_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"linkage": {
|
||||
"type": "External"
|
||||
}
|
||||
}
|
||||
],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": {
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"suffix": "",
|
||||
"usr": "c:@F@foo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"linkage_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"linkage": {
|
||||
"type": "External"
|
||||
}
|
||||
}
|
||||
],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "x86_64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -60,3 +60,16 @@
|
|||
// RUN: diff %S/Inputs/rt-multi-arch-static-library-nonempty.json %t/rt-multi-arch-static-library-nonempty-enc.json
|
||||
// RUN: clang-ssaf-format --type auto --encoding %S/Inputs/rt-multi-arch-static-library-nonempty.json -o %t/rt-multi-arch-static-library-nonempty-enc-explicit.json
|
||||
// RUN: diff %S/Inputs/rt-multi-arch-static-library-nonempty.json %t/rt-multi-arch-static-library-nonempty-enc-explicit.json
|
||||
|
||||
// MultiArchSharedLibrary, like its sibling, appears only in the
|
||||
// ArtifactEncoding variant; round-trip both empty and non-empty fixtures.
|
||||
|
||||
// RUN: clang-ssaf-format --encoding %S/Inputs/rt-multi-arch-shared-library-empty.json -o %t/rt-multi-arch-shared-library-empty-enc.json
|
||||
// RUN: diff %S/Inputs/rt-multi-arch-shared-library-empty.json %t/rt-multi-arch-shared-library-empty-enc.json
|
||||
// RUN: clang-ssaf-format --type auto --encoding %S/Inputs/rt-multi-arch-shared-library-empty.json -o %t/rt-multi-arch-shared-library-empty-enc-explicit.json
|
||||
// RUN: diff %S/Inputs/rt-multi-arch-shared-library-empty.json %t/rt-multi-arch-shared-library-empty-enc-explicit.json
|
||||
|
||||
// RUN: clang-ssaf-format --encoding %S/Inputs/rt-multi-arch-shared-library-nonempty.json -o %t/rt-multi-arch-shared-library-nonempty-enc.json
|
||||
// RUN: diff %S/Inputs/rt-multi-arch-shared-library-nonempty.json %t/rt-multi-arch-shared-library-nonempty-enc.json
|
||||
// RUN: clang-ssaf-format --type auto --encoding %S/Inputs/rt-multi-arch-shared-library-nonempty.json -o %t/rt-multi-arch-shared-library-nonempty-enc-explicit.json
|
||||
// RUN: diff %S/Inputs/rt-multi-arch-shared-library-nonempty.json %t/rt-multi-arch-shared-library-nonempty-enc-explicit.json
|
||||
|
|
|
|||
|
|
@ -40,4 +40,4 @@
|
|||
// RUN: not clang-ssaf-format --type auto --encoding %S/Inputs/unknown-type.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=ENCODING-UNKNOWN-TYPE
|
||||
// ENCODING-UNKNOWN-TYPE: clang-ssaf-format: error: reading ArtifactEncoding from file '{{.*}}unknown-type.json'
|
||||
// ENCODING-UNKNOWN-TYPE-NEXT: unknown value 'Mystery' for field 'type': expected 'TUSummary', 'LUSummary', 'StaticLibrary', or 'MultiArchStaticLibrary'
|
||||
// ENCODING-UNKNOWN-TYPE-NEXT: unknown value 'Mystery' for field 'type': expected 'TUSummary', 'LUSummary', 'StaticLibrary', 'MultiArchStaticLibrary', or 'MultiArchSharedLibrary'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{ broken
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "TUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libbar"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"members": [
|
||||
"not an object"
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"members": {},
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"members": [],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchStaticLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"members": [],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"members": [],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"members": [],
|
||||
"namespace": "libfoo",
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1 @@
|
|||
[]
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"members": [],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "x86_64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": {
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"suffix": "",
|
||||
"usr": "c:@F@foo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"linkage_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"linkage": {
|
||||
"type": "External"
|
||||
}
|
||||
}
|
||||
],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": {
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"suffix": "",
|
||||
"usr": "c:@F@foo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"linkage_table": [
|
||||
{
|
||||
"id": 0,
|
||||
"linkage": {
|
||||
"type": "External"
|
||||
}
|
||||
}
|
||||
],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "x86_64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64_32-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "x86_64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "x86_64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"members": [
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "x86_64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
},
|
||||
{
|
||||
"data": [],
|
||||
"id_table": [],
|
||||
"linkage_table": [],
|
||||
"lu_namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"target_triple": "arm64_32-apple-macosx",
|
||||
"type": "LUSummary"
|
||||
}
|
||||
],
|
||||
"namespace": [
|
||||
{
|
||||
"kind": "LinkUnit",
|
||||
"name": "libfoo"
|
||||
}
|
||||
],
|
||||
"type": "MultiArchSharedLibrary"
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// File-I/O error tests: readJSON() input validation and writeJSON() output
|
||||
// validation for clang-ssaf-format --type multi-arch-shared-library.
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t
|
||||
|
||||
// ============================================================================
|
||||
// readJSON() errors
|
||||
// ============================================================================
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/nonexistent.json 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=NONEXISTENT-FILE
|
||||
// NONEXISTENT-FILE: clang-ssaf-format: error: failed to validate path '{{.*}}nonexistent.json': Path does not exist
|
||||
|
||||
// RUN: mkdir -p %t/test-directory.json
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %t/test-directory.json 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=PATH-IS-DIRECTORY
|
||||
// PATH-IS-DIRECTORY: clang-ssaf-format: error: failed to validate path '{{.*}}test-directory.json': Path is not a file
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/not-json-extension.txt 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=NOT-JSON-EXTENSION
|
||||
// NOT-JSON-EXTENSION: clang-ssaf-format: error: failed to validate path '{{.*}}not-json-extension.txt': No format registered for extension 'txt'
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/invalid-syntax.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=INVALID-SYNTAX
|
||||
// INVALID-SYNTAX: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}invalid-syntax.json'
|
||||
// INVALID-SYNTAX-NEXT: {{.*}}Expected object key
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/not-object.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=NOT-OBJECT
|
||||
// NOT-OBJECT: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}not-object.json'
|
||||
// NOT-OBJECT-NEXT: failed to read MultiArchSharedLibrary: expected JSON object
|
||||
|
||||
// ============================================================================
|
||||
// writeJSON() errors
|
||||
// ============================================================================
|
||||
|
||||
// RUN: echo '{}' > %t/existing.json
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-single-member.json -o %t/existing.json 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=WRITE-FILE-ALREADY-EXISTS
|
||||
// WRITE-FILE-ALREADY-EXISTS: clang-ssaf-format: error: failed to validate path '{{.*}}existing.json': File already exists
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-single-member.json -o %t/nonexistent-dir/test.json 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=WRITE-PARENT-DIRECTORY-NOT-FOUND
|
||||
// WRITE-PARENT-DIRECTORY-NOT-FOUND: clang-ssaf-format: error: failed to validate path '{{.*}}nonexistent-dir{{.}}test.json': Parent directory does not exist
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-single-member.json -o %t/test.txt 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=WRITE-NOT-JSON-EXTENSION
|
||||
// WRITE-NOT-JSON-EXTENSION: clang-ssaf-format: error: failed to validate path '{{.*}}test.txt': No format registered for extension 'txt'
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Tests for clang-ssaf-format --type multi-arch-shared-library that
|
||||
// require filesystem permission support (symlinks, chmod).
|
||||
|
||||
// UNSUPPORTED: system-windows
|
||||
// REQUIRES: non-root-user
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t
|
||||
|
||||
// ============================================================================
|
||||
// Broken symlink
|
||||
// ============================================================================
|
||||
|
||||
// RUN: ln -sf %t/nonexistent-target.json %t/broken-symlink.json
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %t/broken-symlink.json 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=BROKEN-SYMLINK
|
||||
// BROKEN-SYMLINK: clang-ssaf-format: error: failed to validate path '{{.*}}broken-symlink.json': Path does not exist
|
||||
|
||||
// ============================================================================
|
||||
// No read permission
|
||||
// ============================================================================
|
||||
|
||||
// RUN: cp %S/Inputs/rt-single-member.json %t/no-read-permission.json
|
||||
// RUN: chmod -r %t/no-read-permission.json
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %t/no-read-permission.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=NO-READ-PERMISSION
|
||||
// RUN: chmod +r %t/no-read-permission.json
|
||||
// NO-READ-PERMISSION: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}no-read-permission.json'
|
||||
// NO-READ-PERMISSION-NEXT: failed to read file '{{.*}}no-read-permission.json': {{.*}}
|
||||
|
||||
// ============================================================================
|
||||
// Write to directory without write permission
|
||||
// ============================================================================
|
||||
|
||||
// RUN: mkdir -p %t/write-protected-dir
|
||||
// RUN: chmod -w %t/write-protected-dir
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-single-member.json -o %t/write-protected-dir/test.json 2>&1 \
|
||||
// RUN: | FileCheck %s --check-prefix=WRITE-STREAM-OPEN-FAILURE
|
||||
// RUN: chmod +w %t/write-protected-dir
|
||||
// WRITE-STREAM-OPEN-FAILURE: clang-ssaf-format: error: failed to validate path '{{.*}}write-protected-dir{{.}}test.json': Parent directory is not writable
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
// Round-trip tests: read a MultiArchSharedLibrary JSON input, write it
|
||||
// back out, and diff the result against the original.
|
||||
//
|
||||
// MultiArchSharedLibrary has only an encoding representation, so
|
||||
// --encoding is a no-op for --type multi-arch-shared-library and both
|
||||
// invocations must produce the same output.
|
||||
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t
|
||||
|
||||
// An empty members array is a valid (if degenerate) MultiArchSharedLibrary.
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-empty-members.json -o %t/rt-empty-members.json
|
||||
// RUN: diff %S/Inputs/rt-empty-members.json %t/rt-empty-members.json
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library --encoding %S/Inputs/rt-empty-members.json -o %t/rt-empty-members-enc.json
|
||||
// RUN: diff %S/Inputs/rt-empty-members.json %t/rt-empty-members-enc.json
|
||||
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-single-member.json -o %t/rt-single-member.json
|
||||
// RUN: diff %S/Inputs/rt-single-member.json %t/rt-single-member.json
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library --encoding %S/Inputs/rt-single-member.json -o %t/rt-single-member-enc.json
|
||||
// RUN: diff %S/Inputs/rt-single-member.json %t/rt-single-member-enc.json
|
||||
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-multiple-members.json -o %t/rt-multiple-members.json
|
||||
// RUN: diff %S/Inputs/rt-multiple-members.json %t/rt-multiple-members.json
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library --encoding %S/Inputs/rt-multiple-members.json -o %t/rt-multiple-members-enc.json
|
||||
// RUN: diff %S/Inputs/rt-multiple-members.json %t/rt-multiple-members-enc.json
|
||||
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-nonempty-members.json -o %t/rt-nonempty-members.json
|
||||
// RUN: diff %S/Inputs/rt-nonempty-members.json %t/rt-nonempty-members.json
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library --encoding %S/Inputs/rt-nonempty-members.json -o %t/rt-nonempty-members-enc.json
|
||||
// RUN: diff %S/Inputs/rt-nonempty-members.json %t/rt-nonempty-members-enc.json
|
||||
|
||||
// ============================================================================
|
||||
// Member sort order
|
||||
// ============================================================================
|
||||
//
|
||||
// Members are stored in a std::set keyed by TargetTriple enum components,
|
||||
// so the writer emits them in enum-tuple order regardless of input order.
|
||||
// unsorted-members-input.json lists the members as x86_64, then arm64;
|
||||
// the writer must produce the canonical (arm64, x86_64) ordering, byte
|
||||
// identical to rt-multiple-members.json.
|
||||
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library %S/Inputs/unsorted-members-input.json -o %t/unsorted-members-output.json
|
||||
// RUN: diff %S/Inputs/rt-multiple-members.json %t/unsorted-members-output.json
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library --encoding %S/Inputs/unsorted-members-input.json -o %t/unsorted-members-output-enc.json
|
||||
// RUN: diff %S/Inputs/rt-multiple-members.json %t/unsorted-members-output-enc.json
|
||||
|
||||
// 3-member ordering: confirms the sort isn't an accidental two-element
|
||||
// swap. The unsorted input lists x86_64, arm64, arm64_32; the writer
|
||||
// must produce (arm64, arm64_32, x86_64) — byte identical to
|
||||
// rt-three-members.json.
|
||||
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library %S/Inputs/rt-three-members.json -o %t/rt-three-members.json
|
||||
// RUN: diff %S/Inputs/rt-three-members.json %t/rt-three-members.json
|
||||
// RUN: clang-ssaf-format --type multi-arch-shared-library %S/Inputs/unsorted-three-members-input.json -o %t/unsorted-three-members-output.json
|
||||
// RUN: diff %S/Inputs/rt-three-members.json %t/unsorted-three-members-output.json
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
// Top-level MultiArchSharedLibrary structure tests: type discriminator,
|
||||
// namespace identity, members array, and per-member validation including
|
||||
// duplicate-target-triple and namespace-mismatch rejection.
|
||||
|
||||
// ============================================================================
|
||||
// readMultiArchSharedLibrary() / writeMultiArchSharedLibrary() type-field
|
||||
// errors
|
||||
// ============================================================================
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/missing-type.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MISSING-TYPE
|
||||
// MISSING-TYPE: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}missing-type.json'
|
||||
// MISSING-TYPE-NEXT: failed to read summary type from field 'type': expected JSON string
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/mismatched-type.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MISMATCHED-TYPE
|
||||
// MISMATCHED-TYPE: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}mismatched-type.json'
|
||||
// MISMATCHED-TYPE-NEXT: expected 'MultiArchSharedLibrary' for field 'type' but got 'MultiArchStaticLibrary'
|
||||
|
||||
// ============================================================================
|
||||
// namespace field errors
|
||||
// ============================================================================
|
||||
|
||||
// The top-level namespace is required and must be a JSON array of
|
||||
// BuildNamespace steps.
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/missing-namespace.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MISSING-NAMESPACE
|
||||
// MISSING-NAMESPACE: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}missing-namespace.json'
|
||||
// MISSING-NAMESPACE-NEXT: failed to read NestedBuildNamespace from field 'namespace': expected JSON array
|
||||
|
||||
// The namespace field must be a JSON array, not a string.
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/namespace-not-array.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=NAMESPACE-NOT-ARRAY
|
||||
// NAMESPACE-NOT-ARRAY: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}namespace-not-array.json'
|
||||
// NAMESPACE-NOT-ARRAY-NEXT: failed to read NestedBuildNamespace from field 'namespace': expected JSON array
|
||||
|
||||
// ============================================================================
|
||||
// members field errors
|
||||
// ============================================================================
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/missing-members.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MISSING-MEMBERS
|
||||
// MISSING-MEMBERS: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}missing-members.json'
|
||||
// MISSING-MEMBERS-NEXT: failed to read MultiArchSharedLibrary members from field 'members': expected JSON array
|
||||
|
||||
// The members field must be a JSON array, not an object.
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/members-not-array.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MEMBERS-NOT-ARRAY
|
||||
// MEMBERS-NOT-ARRAY: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}members-not-array.json'
|
||||
// MEMBERS-NOT-ARRAY-NEXT: failed to read MultiArchSharedLibrary members from field 'members': expected JSON array
|
||||
|
||||
// ============================================================================
|
||||
// per-member errors
|
||||
// ============================================================================
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/member-not-object.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MEMBER-NOT-OBJECT
|
||||
// MEMBER-NOT-OBJECT: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}member-not-object.json'
|
||||
// MEMBER-NOT-OBJECT-NEXT: failed to read MultiArchSharedLibrary member from index '0': expected JSON object
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/member-missing-type.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MEMBER-MISSING-TYPE
|
||||
// MEMBER-MISSING-TYPE: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}member-missing-type.json'
|
||||
// MEMBER-MISSING-TYPE-NEXT: reading MultiArchSharedLibrary member from index '0'
|
||||
// MEMBER-MISSING-TYPE-NEXT: failed to read summary type from field 'type': expected JSON string
|
||||
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/member-mismatched-type.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MEMBER-MISMATCHED-TYPE
|
||||
// MEMBER-MISMATCHED-TYPE: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}member-mismatched-type.json'
|
||||
// MEMBER-MISMATCHED-TYPE-NEXT: reading MultiArchSharedLibrary member from index '0'
|
||||
// MEMBER-MISMATCHED-TYPE-NEXT: expected 'LUSummary' for field 'type' but got 'TUSummary'
|
||||
|
||||
// Each member is a per-arch slice of the same shared library, so its
|
||||
// lu_namespace must equal the wrapper's namespace exactly. A member
|
||||
// whose leaf-step name differs from the wrapper's is rejected.
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/member-namespace-mismatch.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MEMBER-NAMESPACE-MISMATCH
|
||||
// MEMBER-NAMESPACE-MISMATCH: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}member-namespace-mismatch.json'
|
||||
// MEMBER-NAMESPACE-MISMATCH-NEXT: reading MultiArchSharedLibrary member from index '0'
|
||||
// MEMBER-NAMESPACE-MISMATCH-NEXT: field 'lu_namespace' does not equal the enclosing artifact's namespace
|
||||
|
||||
// A member with an empty lu_namespace array cannot equal the wrapper's
|
||||
// (non-empty) namespace, so the equality check also fires.
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/member-empty-lu-namespace.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MEMBER-EMPTY-LU-NAMESPACE
|
||||
// MEMBER-EMPTY-LU-NAMESPACE: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}member-empty-lu-namespace.json'
|
||||
// MEMBER-EMPTY-LU-NAMESPACE-NEXT: reading MultiArchSharedLibrary member from index '0'
|
||||
// MEMBER-EMPTY-LU-NAMESPACE-NEXT: field 'lu_namespace' does not equal the enclosing artifact's namespace
|
||||
|
||||
// Members are identified by their full target_triple. Two members sharing
|
||||
// the same target_triple are rejected.
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/duplicate-target-triple.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=DUPLICATE-TARGET-TRIPLE
|
||||
// DUPLICATE-TARGET-TRIPLE: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}duplicate-target-triple.json'
|
||||
// DUPLICATE-TARGET-TRIPLE-NEXT: failed to insert MultiArchSharedLibrary member at index '1': encountered duplicate 'arm64-apple-macosx'
|
||||
|
||||
// Verifies that errors raised inside readLUSummaryEncodingFromObject (here, a
|
||||
// missing lu_namespace on the member) are properly wrapped with the
|
||||
// "reading MultiArchSharedLibrary member from index 'N'" context, then
|
||||
// with the outer "reading MultiArchSharedLibrary from file '...'" context.
|
||||
// RUN: not clang-ssaf-format --type multi-arch-shared-library %S/Inputs/member-inner-error.json 2>&1 \
|
||||
// RUN: | FileCheck %s --match-full-lines --check-prefix=MEMBER-INNER-ERROR
|
||||
// MEMBER-INNER-ERROR: clang-ssaf-format: error: reading MultiArchSharedLibrary from file '{{.*}}member-inner-error.json'
|
||||
// MEMBER-INNER-ERROR-NEXT: reading MultiArchSharedLibrary member from index '0'
|
||||
// MEMBER-INNER-ERROR-NEXT: failed to read NestedBuildNamespace from field 'lu_namespace': expected JSON array
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummaryEncoding.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchSharedLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchStaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h"
|
||||
|
|
@ -47,6 +48,7 @@ enum class SummaryType {
|
|||
LU,
|
||||
StaticLibrary,
|
||||
MultiArchStaticLibrary,
|
||||
MultiArchSharedLibrary,
|
||||
WPA
|
||||
};
|
||||
|
||||
|
|
@ -77,6 +79,9 @@ cl::opt<SummaryType> Type(
|
|||
clEnumValN(SummaryType::MultiArchStaticLibrary,
|
||||
"multi-arch-static-library",
|
||||
"Multi-architecture static library"),
|
||||
clEnumValN(SummaryType::MultiArchSharedLibrary,
|
||||
"multi-arch-shared-library",
|
||||
"Multi-architecture shared library"),
|
||||
clEnumValN(SummaryType::WPA, "wpa",
|
||||
"Whole-program analysis suite")),
|
||||
cl::init(SummaryType::Auto), cl::cat(SsafFormatCategory));
|
||||
|
|
@ -322,6 +327,13 @@ void convert(const FormatInput &FI) {
|
|||
run(FI, &SerializationFormat::readMultiArchStaticLibrary,
|
||||
&SerializationFormat::writeMultiArchStaticLibrary);
|
||||
return;
|
||||
case SummaryType::MultiArchSharedLibrary:
|
||||
// MultiArchSharedLibrary has only an encoded representation, so
|
||||
// --encoding is a no-op here: both paths route to
|
||||
// readMultiArchSharedLibrary / writeMultiArchSharedLibrary.
|
||||
run(FI, &SerializationFormat::readMultiArchSharedLibrary,
|
||||
&SerializationFormat::writeMultiArchSharedLibrary);
|
||||
return;
|
||||
case SummaryType::WPA:
|
||||
run(FI, &SerializationFormat::readWPASuite,
|
||||
&SerializationFormat::writeWPASuite);
|
||||
|
|
|
|||
|
|
@ -118,6 +118,16 @@ public:
|
|||
return failing("writeMultiArchStaticLibrary");
|
||||
}
|
||||
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
readMultiArchSharedLibrary(llvm::StringRef Path) override {
|
||||
return failing("readMultiArchSharedLibrary");
|
||||
}
|
||||
|
||||
llvm::Error writeMultiArchSharedLibrary(const MultiArchSharedLibrary &M,
|
||||
llvm::StringRef Path) override {
|
||||
return failing("writeMultiArchSharedLibrary");
|
||||
}
|
||||
|
||||
llvm::Expected<WPASuite> readWPASuite(llvm::StringRef Path) override {
|
||||
return failing("readWPASuite");
|
||||
}
|
||||
|
|
@ -214,6 +224,14 @@ public:
|
|||
llvm::StringRef) override {
|
||||
return llvm::Error::success();
|
||||
}
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
readMultiArchSharedLibrary(llvm::StringRef) override {
|
||||
return llvm::createStringError("not implemented");
|
||||
}
|
||||
llvm::Error writeMultiArchSharedLibrary(const MultiArchSharedLibrary &,
|
||||
llvm::StringRef) override {
|
||||
return llvm::Error::success();
|
||||
}
|
||||
llvm::Expected<WPASuite> readWPASuite(llvm::StringRef) override {
|
||||
return llvm::createStringError("not implemented");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "Registries/MockSerializationFormat.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummaryEncoding.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchSharedLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchStaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h"
|
||||
|
|
@ -222,6 +223,18 @@ llvm::Error MockSerializationFormat::writeMultiArchStaticLibrary(
|
|||
"MockSerializationFormat does not support MultiArchStaticLibrary");
|
||||
}
|
||||
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
MockSerializationFormat::readMultiArchSharedLibrary(llvm::StringRef Path) {
|
||||
llvm_unreachable(
|
||||
"MockSerializationFormat does not support MultiArchSharedLibrary");
|
||||
}
|
||||
|
||||
llvm::Error MockSerializationFormat::writeMultiArchSharedLibrary(
|
||||
const MultiArchSharedLibrary &M, llvm::StringRef Path) {
|
||||
llvm_unreachable(
|
||||
"MockSerializationFormat does not support MultiArchSharedLibrary");
|
||||
}
|
||||
|
||||
llvm::Expected<WPASuite>
|
||||
MockSerializationFormat::readWPASuite(llvm::StringRef Path) {
|
||||
llvm_unreachable("MockSerializationFormat does not support WPASuite");
|
||||
|
|
|
|||
|
|
@ -56,6 +56,12 @@ public:
|
|||
llvm::Error writeMultiArchStaticLibrary(const MultiArchStaticLibrary &M,
|
||||
llvm::StringRef Path) override;
|
||||
|
||||
llvm::Expected<MultiArchSharedLibrary>
|
||||
readMultiArchSharedLibrary(llvm::StringRef Path) override;
|
||||
|
||||
llvm::Error writeMultiArchSharedLibrary(const MultiArchSharedLibrary &M,
|
||||
llvm::StringRef Path) override;
|
||||
|
||||
llvm::Expected<Artifact> readArtifact(llvm::StringRef Path) override;
|
||||
|
||||
llvm::Error writeArtifact(const Artifact &A, llvm::StringRef Path) override;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/LUSummaryEncoding.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchSharedLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/MultiArchStaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/StaticLibrary.h"
|
||||
#include "clang/ScalableStaticAnalysis/Core/EntityLinker/TUSummaryEncoding.h"
|
||||
|
|
|
|||
Loading…
Reference in a new issue