xref: /llvm-project/llvm/tools/llvm-readtapi/DiffEngine.h (revision d9a9872ec4760762fdc467ef283cea302a3742e5)
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