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: |
41 | AttributeDiff(DiffAttrKind Kind) : Kind(Kind){}; |
42 | virtual ~AttributeDiff(){}; |
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; |
58 | 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: |
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 | |
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: |
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 | |
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; |
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 | |
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; |
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. |
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; |
131 | InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff) |
132 | : AttributeDiff(AD_Inline_Doc), InstallName(InstName), |
133 | DocValues(std::move(Diff)){}; |
134 | |
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: |
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 | |