//===-- DiffEngine.h - File comparator --------------------------*- 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 header defines the interface to the llvm-tapi difference engine, // which structurally compares two tbd files. // //===----------------------------------------------------------------------===/ #ifndef LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H #define LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H #include "llvm/ADT/Optional.h" #include "llvm/Object/TapiUniversal.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TextAPI/Symbol.h" #include "llvm/TextAPI/Target.h" namespace llvm { /// InterfaceInputOrder determines from which file the diff attribute belongs /// to. enum InterfaceInputOrder { lhs, rhs }; /// DiffAttrKind is the enum that holds the concrete bases for RTTI. enum DiffAttrKind { AD_Diff_Scalar_PackedVersion, AD_Diff_Scalar_Unsigned, AD_Diff_Scalar_Bool, AD_Diff_Scalar_Str, AD_Str_Vec, AD_Sym_Vec, AD_Inline_Doc, }; /// AttributeDiff is the abstract class for RTTI. class AttributeDiff { public: AttributeDiff(DiffAttrKind Kind) : Kind(Kind){}; virtual ~AttributeDiff(){}; DiffAttrKind getKind() const { return Kind; } private: DiffAttrKind Kind; }; /// DiffOutput is the representation of a diff for a single attribute. struct DiffOutput { /// The name of the attribute. std::string Name; /// The kind for RTTI DiffAttrKind Kind; /// Different values for the attribute /// from each file where a diff is present. std::vector> Values; DiffOutput(std::string Name) : Name(Name){}; }; /// DiffScalarVal is a template class for the different types of scalar values. template class DiffScalarVal : public AttributeDiff { public: DiffScalarVal(InterfaceInputOrder Order, T Val) : AttributeDiff(U), Order(Order), Val(Val){}; static bool classof(const AttributeDiff *A) { return A->getKind() == U; } void print(raw_ostream &, std::string); T getVal() const { return Val; } InterfaceInputOrder getOrder() const { return Order; } private: /// The order is the file from which the diff is found. InterfaceInputOrder Order; T Val; }; /// SymScalar is the diff symbol and the order. class SymScalar { public: SymScalar(InterfaceInputOrder Order, const MachO::Symbol *Sym) : Order(Order), Val(Sym){}; std::string getFlagString(MachO::SymbolFlags Flags) { return Flags != MachO::SymbolFlags::None ? " - " + stringifySymbolFlag(Flags) : stringifySymbolFlag(Flags); } void print(raw_ostream &OS, std::string Indent, MachO::Target Targ); const MachO::Symbol *getVal() const { return Val; } InterfaceInputOrder getOrder() const { return Order; } private: /// The order is the file from which the diff is found. InterfaceInputOrder Order; const MachO::Symbol *Val; StringLiteral getSymbolNamePrefix(MachO::SymbolKind Kind); std::string stringifySymbolFlag(MachO::SymbolFlags Flag); }; class DiffStrVec : public AttributeDiff { public: MachO::Target Targ; /// Values is a vector of StringRef values associated with the target. std::vector> TargValues; DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){}; static bool classof(const AttributeDiff *A) { return A->getKind() == AD_Str_Vec; } }; class DiffSymVec : public AttributeDiff { public: MachO::Target Targ; /// Values is a vector of symbol values associated with the target. std::vector TargValues; DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){}; static bool classof(const AttributeDiff *A) { return A->getKind() == AD_Sym_Vec; } }; /// InlineDoc represents an inlined framework/library in a TBD File. class InlineDoc : public AttributeDiff { public: /// Install name of the framework/library. std::string InstallName; /// Differences found from each file. std::vector DocValues; InlineDoc(StringRef InstName, std::vector Diff) : AttributeDiff(AD_Inline_Doc), InstallName(InstName), DocValues(std::move(Diff)){}; static bool classof(const AttributeDiff *A) { return A->getKind() == AD_Inline_Doc; } }; /// DiffEngine contains the methods to compare the input files and print the /// output of the differences found in the files. class DiffEngine { public: DiffEngine(object::TapiUniversal *InputFileNameLHS, object::TapiUniversal *InputFileNameRHS) : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){}; bool compareFiles(raw_ostream &); private: object::TapiUniversal *FileLHS; object::TapiUniversal *FileRHS; /// Function that prints the differences found in the files. void printDifferences(raw_ostream &, const std::vector &, int); /// Function that does the comparison of the TBD files and returns the /// differences. std::vector findDifferences(const MachO::InterfaceFile *, const MachO::InterfaceFile *); }; } // namespace llvm #endif