167 lines · c
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-exception6//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_H14#define LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H15 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 21namespace llvm {22 23/// InterfaceInputOrder determines from which file the diff attribute belongs24/// to.25enum InterfaceInputOrder { lhs, rhs };26 27/// DiffAttrKind is the enum that holds the concrete bases for RTTI.28enum 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.39class AttributeDiff {40public:41 AttributeDiff(DiffAttrKind Kind) : Kind(Kind){};42 virtual ~AttributeDiff() = default;43 DiffAttrKind getKind() const { return Kind; }44 45private:46 DiffAttrKind Kind;47};48 49/// DiffOutput is the representation of a diff for a single attribute.50struct DiffOutput {51 /// The name of the attribute.52 std::string Name;53 /// The kind for RTTI54 DiffAttrKind Kind;55 /// Different values for the attribute56 /// from each file where a diff is present.57 std::vector<std::unique_ptr<AttributeDiff>> Values;58 DiffOutput(std::string Name) : Name(Name){};59};60 61/// DiffScalarVal is a template class for the different types of scalar values.62template <class T, DiffAttrKind U> class DiffScalarVal : public AttributeDiff {63public:64 DiffScalarVal(InterfaceInputOrder Order, T Val)65 : AttributeDiff(U), Order(Order), Val(Val){};66 67 static bool classof(const AttributeDiff *A) { return A->getKind() == U; }68 69 void print(raw_ostream &, std::string);70 71 T getVal() const { return Val; }72 InterfaceInputOrder getOrder() const { return Order; }73 74private: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.81class SymScalar {82public: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 90 const MachO::Symbol *getVal() const { return Val; }91 InterfaceInputOrder getOrder() const { return Order; }92 93private: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 100class DiffStrVec : public AttributeDiff {101public: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;105 DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){};106 107 static bool classof(const AttributeDiff *A) {108 return A->getKind() == AD_Str_Vec;109 }110};111 112class DiffSymVec : public AttributeDiff {113public:114 MachO::Target Targ;115 /// Values is a vector of symbol values associated with the target.116 std::vector<SymScalar> TargValues;117 DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){};118 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.125class InlineDoc : public AttributeDiff {126public:127 /// Install name of the framework/library.128 std::string InstallName;129 /// Differences found from each file.130 std::vector<DiffOutput> DocValues;131 /// Whether document only exists for one input.132 bool IsMissingDoc;133 InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff,134 bool IsMissingDoc = false)135 : AttributeDiff(AD_Inline_Doc), InstallName(InstName),136 DocValues(std::move(Diff)), IsMissingDoc(IsMissingDoc) {};137 138 static bool classof(const AttributeDiff *A) {139 return A->getKind() == AD_Inline_Doc;140 }141};142 143/// DiffEngine contains the methods to compare the input files and print the144/// output of the differences found in the files.145class DiffEngine {146public:147 DiffEngine(MachO::InterfaceFile *InputFileNameLHS,148 MachO::InterfaceFile *InputFileNameRHS)149 : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){};150 bool compareFiles(raw_ostream &);151 152private:153 MachO::InterfaceFile *FileLHS;154 MachO::InterfaceFile *FileRHS;155 156 /// Function that prints the differences found in the files.157 void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int);158 /// Function that does the comparison of the TBD files and returns the159 /// differences.160 std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *,161 const MachO::InterfaceFile *);162};163 164} // namespace llvm165 166#endif167