1 //===-- DiffEngine.h - File comparator --------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This header defines the interface to the llvm-tapi difference engine, 10 // which structurally compares two tbd files. 11 // 12 //===----------------------------------------------------------------------===/ 13 #ifndef LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H 14 #define LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H 15 16 #include "llvm/Object/TapiUniversal.h" 17 #include "llvm/Support/raw_ostream.h" 18 #include "llvm/TextAPI/Symbol.h" 19 #include "llvm/TextAPI/Target.h" 20 21 namespace llvm { 22 23 /// InterfaceInputOrder determines from which file the diff attribute belongs 24 /// to. 25 enum InterfaceInputOrder { lhs, rhs }; 26 27 /// DiffAttrKind is the enum that holds the concrete bases for RTTI. 28 enum DiffAttrKind { 29 AD_Diff_Scalar_PackedVersion, 30 AD_Diff_Scalar_Unsigned, 31 AD_Diff_Scalar_Bool, 32 AD_Diff_Scalar_Str, 33 AD_Str_Vec, 34 AD_Sym_Vec, 35 AD_Inline_Doc, 36 }; 37 38 /// AttributeDiff is the abstract class for RTTI. 39 class AttributeDiff { 40 public: AttributeDiff(DiffAttrKind Kind)41 AttributeDiff(DiffAttrKind Kind) : Kind(Kind){}; ~AttributeDiff()42 virtual ~AttributeDiff(){}; getKind()43 DiffAttrKind getKind() const { return Kind; } 44 45 private: 46 DiffAttrKind Kind; 47 }; 48 49 /// DiffOutput is the representation of a diff for a single attribute. 50 struct DiffOutput { 51 /// The name of the attribute. 52 std::string Name; 53 /// The kind for RTTI 54 DiffAttrKind Kind; 55 /// Different values for the attribute 56 /// from each file where a diff is present. 57 std::vector<std::unique_ptr<AttributeDiff>> Values; DiffOutputDiffOutput58 DiffOutput(std::string Name) : Name(Name){}; 59 }; 60 61 /// DiffScalarVal is a template class for the different types of scalar values. 62 template <class T, DiffAttrKind U> class DiffScalarVal : public AttributeDiff { 63 public: DiffScalarVal(InterfaceInputOrder Order,T Val)64 DiffScalarVal(InterfaceInputOrder Order, T Val) 65 : AttributeDiff(U), Order(Order), Val(Val){}; 66 classof(const AttributeDiff * A)67 static bool classof(const AttributeDiff *A) { return A->getKind() == U; } 68 69 void print(raw_ostream &, std::string); 70 getVal()71 T getVal() const { return Val; } getOrder()72 InterfaceInputOrder getOrder() const { return Order; } 73 74 private: 75 /// The order is the file from which the diff is found. 76 InterfaceInputOrder Order; 77 T Val; 78 }; 79 80 /// SymScalar is the diff symbol and the order. 81 class SymScalar { 82 public: SymScalar(InterfaceInputOrder Order,const MachO::Symbol * Sym)83 SymScalar(InterfaceInputOrder Order, const MachO::Symbol *Sym) 84 : Order(Order), Val(Sym){}; 85 86 std::string getFlagString(const MachO::Symbol *Sym); 87 88 void print(raw_ostream &OS, std::string Indent, MachO::Target Targ); 89 getVal()90 const MachO::Symbol *getVal() const { return Val; } getOrder()91 InterfaceInputOrder getOrder() const { return Order; } 92 93 private: 94 /// The order is the file from which the diff is found. 95 InterfaceInputOrder Order; 96 const MachO::Symbol *Val; 97 StringLiteral getSymbolNamePrefix(MachO::EncodeKind Kind); 98 }; 99 100 class DiffStrVec : public AttributeDiff { 101 public: 102 MachO::Target Targ; 103 /// Values is a vector of StringRef values associated with the target. 104 std::vector<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>> TargValues; DiffStrVec(MachO::Target Targ)105 DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){}; 106 classof(const AttributeDiff * A)107 static bool classof(const AttributeDiff *A) { 108 return A->getKind() == AD_Str_Vec; 109 } 110 }; 111 112 class DiffSymVec : public AttributeDiff { 113 public: 114 MachO::Target Targ; 115 /// Values is a vector of symbol values associated with the target. 116 std::vector<SymScalar> TargValues; DiffSymVec(MachO::Target Targ)117 DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){}; 118 classof(const AttributeDiff * A)119 static bool classof(const AttributeDiff *A) { 120 return A->getKind() == AD_Sym_Vec; 121 } 122 }; 123 124 /// InlineDoc represents an inlined framework/library in a TBD File. 125 class InlineDoc : public AttributeDiff { 126 public: 127 /// Install name of the framework/library. 128 std::string InstallName; 129 /// Differences found from each file. 130 std::vector<DiffOutput> DocValues; InlineDoc(StringRef InstName,std::vector<DiffOutput> Diff)131 InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff) 132 : AttributeDiff(AD_Inline_Doc), InstallName(InstName), 133 DocValues(std::move(Diff)){}; 134 classof(const AttributeDiff * A)135 static bool classof(const AttributeDiff *A) { 136 return A->getKind() == AD_Inline_Doc; 137 } 138 }; 139 140 /// DiffEngine contains the methods to compare the input files and print the 141 /// output of the differences found in the files. 142 class DiffEngine { 143 public: DiffEngine(MachO::InterfaceFile * InputFileNameLHS,MachO::InterfaceFile * InputFileNameRHS)144 DiffEngine(MachO::InterfaceFile *InputFileNameLHS, 145 MachO::InterfaceFile *InputFileNameRHS) 146 : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){}; 147 bool compareFiles(raw_ostream &); 148 149 private: 150 MachO::InterfaceFile *FileLHS; 151 MachO::InterfaceFile *FileRHS; 152 153 /// Function that prints the differences found in the files. 154 void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int); 155 /// Function that does the comparison of the TBD files and returns the 156 /// differences. 157 std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *, 158 const MachO::InterfaceFile *); 159 }; 160 161 } // namespace llvm 162 163 #endif 164