15b5ab80eSSam Powell //===-- DiffEngine.h - File comparator --------------------------*- C++ -*-===// 25b5ab80eSSam Powell // 35b5ab80eSSam Powell // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45b5ab80eSSam Powell // See https://llvm.org/LICENSE.txt for license information. 55b5ab80eSSam Powell // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65b5ab80eSSam Powell // 75b5ab80eSSam Powell //===----------------------------------------------------------------------===// 85b5ab80eSSam Powell // 95b5ab80eSSam Powell // This header defines the interface to the llvm-tapi difference engine, 105b5ab80eSSam Powell // which structurally compares two tbd files. 115b5ab80eSSam Powell // 125b5ab80eSSam Powell //===----------------------------------------------------------------------===/ 135b5ab80eSSam Powell #ifndef LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H 145b5ab80eSSam Powell #define LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H 155b5ab80eSSam Powell 165b5ab80eSSam Powell #include "llvm/ADT/Optional.h" 175b5ab80eSSam Powell #include "llvm/Object/TapiUniversal.h" 185b5ab80eSSam Powell #include "llvm/Support/raw_ostream.h" 195b5ab80eSSam Powell #include "llvm/TextAPI/Symbol.h" 205b5ab80eSSam Powell #include "llvm/TextAPI/Target.h" 215b5ab80eSSam Powell 225b5ab80eSSam Powell namespace llvm { 235b5ab80eSSam Powell 245b5ab80eSSam Powell /// InterfaceInputOrder determines from which file the diff attribute belongs 255b5ab80eSSam Powell /// to. 265b5ab80eSSam Powell enum InterfaceInputOrder { lhs, rhs }; 275b5ab80eSSam Powell 285b5ab80eSSam Powell /// DiffAttrKind is the enum that holds the concrete bases for RTTI. 295b5ab80eSSam Powell enum DiffAttrKind { 305b5ab80eSSam Powell AD_Diff_Scalar_PackedVersion, 315b5ab80eSSam Powell AD_Diff_Scalar_Unsigned, 325b5ab80eSSam Powell AD_Diff_Scalar_Bool, 335b5ab80eSSam Powell AD_Diff_Scalar_Str, 345b5ab80eSSam Powell AD_Str_Vec, 355b5ab80eSSam Powell AD_Sym_Vec, 365b5ab80eSSam Powell AD_Inline_Doc, 375b5ab80eSSam Powell }; 385b5ab80eSSam Powell 395b5ab80eSSam Powell /// AttributeDiff is the abstract class for RTTI. 405b5ab80eSSam Powell class AttributeDiff { 415b5ab80eSSam Powell public: AttributeDiff(DiffAttrKind Kind)425b5ab80eSSam Powell AttributeDiff(DiffAttrKind Kind) : Kind(Kind){}; ~AttributeDiff()435b5ab80eSSam Powell virtual ~AttributeDiff(){}; getKind()445b5ab80eSSam Powell DiffAttrKind getKind() const { return Kind; } 455b5ab80eSSam Powell 465b5ab80eSSam Powell private: 475b5ab80eSSam Powell DiffAttrKind Kind; 485b5ab80eSSam Powell }; 495b5ab80eSSam Powell 505b5ab80eSSam Powell /// DiffOutput is the representation of a diff for a single attribute. 515b5ab80eSSam Powell struct DiffOutput { 525b5ab80eSSam Powell /// The name of the attribute. 535b5ab80eSSam Powell std::string Name; 545b5ab80eSSam Powell /// The kind for RTTI 555b5ab80eSSam Powell DiffAttrKind Kind; 565b5ab80eSSam Powell /// Different values for the attribute 575b5ab80eSSam Powell /// from each file where a diff is present. 585b5ab80eSSam Powell std::vector<std::unique_ptr<AttributeDiff>> Values; DiffOutputDiffOutput595b5ab80eSSam Powell DiffOutput(std::string Name) : Name(Name){}; 605b5ab80eSSam Powell }; 615b5ab80eSSam Powell 625b5ab80eSSam Powell /// DiffScalarVal is a template class for the different types of scalar values. 635b5ab80eSSam Powell template <class T, DiffAttrKind U> class DiffScalarVal : public AttributeDiff { 645b5ab80eSSam Powell public: DiffScalarVal(InterfaceInputOrder Order,T Val)655b5ab80eSSam Powell DiffScalarVal(InterfaceInputOrder Order, T Val) 665b5ab80eSSam Powell : AttributeDiff(U), Order(Order), Val(Val){}; 675b5ab80eSSam Powell classof(const AttributeDiff * A)685b5ab80eSSam Powell static bool classof(const AttributeDiff *A) { return A->getKind() == U; } 695b5ab80eSSam Powell 705b5ab80eSSam Powell void print(raw_ostream &, std::string); 715b5ab80eSSam Powell getVal()725b5ab80eSSam Powell T getVal() const { return Val; } getOrder()735b5ab80eSSam Powell InterfaceInputOrder getOrder() const { return Order; } 745b5ab80eSSam Powell 755b5ab80eSSam Powell private: 765b5ab80eSSam Powell /// The order is the file from which the diff is found. 775b5ab80eSSam Powell InterfaceInputOrder Order; 785b5ab80eSSam Powell T Val; 795b5ab80eSSam Powell }; 805b5ab80eSSam Powell 815b5ab80eSSam Powell /// SymScalar is the diff symbol and the order. 825b5ab80eSSam Powell class SymScalar { 835b5ab80eSSam Powell public: SymScalar(InterfaceInputOrder Order,const MachO::Symbol * Sym)845b5ab80eSSam Powell SymScalar(InterfaceInputOrder Order, const MachO::Symbol *Sym) 855b5ab80eSSam Powell : Order(Order), Val(Sym){}; 865b5ab80eSSam Powell getFlagString(MachO::SymbolFlags Flags)875b5ab80eSSam Powell std::string getFlagString(MachO::SymbolFlags Flags) { 885b5ab80eSSam Powell return Flags != MachO::SymbolFlags::None 895b5ab80eSSam Powell ? " - " + stringifySymbolFlag(Flags) 905b5ab80eSSam Powell : stringifySymbolFlag(Flags); 915b5ab80eSSam Powell } 925b5ab80eSSam Powell 935b5ab80eSSam Powell void print(raw_ostream &OS, std::string Indent, MachO::Target Targ); 945b5ab80eSSam Powell getVal()955b5ab80eSSam Powell const MachO::Symbol *getVal() const { return Val; } getOrder()965b5ab80eSSam Powell InterfaceInputOrder getOrder() const { return Order; } 975b5ab80eSSam Powell 985b5ab80eSSam Powell private: 995b5ab80eSSam Powell /// The order is the file from which the diff is found. 1005b5ab80eSSam Powell InterfaceInputOrder Order; 1015b5ab80eSSam Powell const MachO::Symbol *Val; 102*56709b86SCyndy Ishida StringLiteral getSymbolNamePrefix(MachO::SymbolKind Kind); 1035b5ab80eSSam Powell std::string stringifySymbolFlag(MachO::SymbolFlags Flag); 1045b5ab80eSSam Powell }; 1055b5ab80eSSam Powell 1065b5ab80eSSam Powell class DiffStrVec : public AttributeDiff { 1075b5ab80eSSam Powell public: 1085b5ab80eSSam Powell MachO::Target Targ; 1095b5ab80eSSam Powell /// Values is a vector of StringRef values associated with the target. 1105b5ab80eSSam Powell std::vector<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>> TargValues; DiffStrVec(MachO::Target Targ)1115b5ab80eSSam Powell DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){}; 1125b5ab80eSSam Powell classof(const AttributeDiff * A)1135b5ab80eSSam Powell static bool classof(const AttributeDiff *A) { 1145b5ab80eSSam Powell return A->getKind() == AD_Str_Vec; 1155b5ab80eSSam Powell } 1165b5ab80eSSam Powell }; 1175b5ab80eSSam Powell 1185b5ab80eSSam Powell class DiffSymVec : public AttributeDiff { 1195b5ab80eSSam Powell public: 1205b5ab80eSSam Powell MachO::Target Targ; 1215b5ab80eSSam Powell /// Values is a vector of symbol values associated with the target. 1225b5ab80eSSam Powell std::vector<SymScalar> TargValues; DiffSymVec(MachO::Target Targ)1235b5ab80eSSam Powell DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){}; 1245b5ab80eSSam Powell classof(const AttributeDiff * A)1255b5ab80eSSam Powell static bool classof(const AttributeDiff *A) { 1265b5ab80eSSam Powell return A->getKind() == AD_Sym_Vec; 1275b5ab80eSSam Powell } 1285b5ab80eSSam Powell }; 1295b5ab80eSSam Powell 1305b5ab80eSSam Powell /// InlineDoc represents an inlined framework/library in a TBD File. 1315b5ab80eSSam Powell class InlineDoc : public AttributeDiff { 1325b5ab80eSSam Powell public: 1335b5ab80eSSam Powell /// Install name of the framework/library. 1345b5ab80eSSam Powell std::string InstallName; 1355b5ab80eSSam Powell /// Differences found from each file. 1365b5ab80eSSam Powell std::vector<DiffOutput> DocValues; InlineDoc(StringRef InstName,std::vector<DiffOutput> Diff)1375b5ab80eSSam Powell InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff) 1385b5ab80eSSam Powell : AttributeDiff(AD_Inline_Doc), InstallName(InstName), 1395b5ab80eSSam Powell DocValues(std::move(Diff)){}; 1405b5ab80eSSam Powell classof(const AttributeDiff * A)1415b5ab80eSSam Powell static bool classof(const AttributeDiff *A) { 1425b5ab80eSSam Powell return A->getKind() == AD_Inline_Doc; 1435b5ab80eSSam Powell } 1445b5ab80eSSam Powell }; 1455b5ab80eSSam Powell 1465b5ab80eSSam Powell /// DiffEngine contains the methods to compare the input files and print the 1475b5ab80eSSam Powell /// output of the differences found in the files. 1485b5ab80eSSam Powell class DiffEngine { 1495b5ab80eSSam Powell public: DiffEngine(object::TapiUniversal * InputFileNameLHS,object::TapiUniversal * InputFileNameRHS)1505b5ab80eSSam Powell DiffEngine(object::TapiUniversal *InputFileNameLHS, 1515b5ab80eSSam Powell object::TapiUniversal *InputFileNameRHS) 1525b5ab80eSSam Powell : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){}; 1535b5ab80eSSam Powell bool compareFiles(raw_ostream &); 1545b5ab80eSSam Powell 1555b5ab80eSSam Powell private: 1565b5ab80eSSam Powell object::TapiUniversal *FileLHS; 1575b5ab80eSSam Powell object::TapiUniversal *FileRHS; 1585b5ab80eSSam Powell 1595b5ab80eSSam Powell /// Function that prints the differences found in the files. 1605b5ab80eSSam Powell void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int); 1615b5ab80eSSam Powell /// Function that does the comparison of the TBD files and returns the 1625b5ab80eSSam Powell /// differences. 1635b5ab80eSSam Powell std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *, 1645b5ab80eSSam Powell const MachO::InterfaceFile *); 1655b5ab80eSSam Powell }; 1665b5ab80eSSam Powell 1675b5ab80eSSam Powell } // namespace llvm 1685b5ab80eSSam Powell 1695b5ab80eSSam Powell #endif 170