blob: 252fbd87c637498594485fcb4bd1faea984da7b2 [file] [log] [blame]
Sam Powell5b5ab802021-06-09 21:13:31 -07001//===-- 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/ADT/Optional.h"
17#include "llvm/Object/TapiUniversal.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/TextAPI/Symbol.h"
20#include "llvm/TextAPI/Target.h"
21
22namespace llvm {
23
24/// InterfaceInputOrder determines from which file the diff attribute belongs
25/// to.
26enum InterfaceInputOrder { lhs, rhs };
27
28/// DiffAttrKind is the enum that holds the concrete bases for RTTI.
29enum DiffAttrKind {
30 AD_Diff_Scalar_PackedVersion,
31 AD_Diff_Scalar_Unsigned,
32 AD_Diff_Scalar_Bool,
33 AD_Diff_Scalar_Str,
34 AD_Str_Vec,
35 AD_Sym_Vec,
36 AD_Inline_Doc,
37};
38
39/// AttributeDiff is the abstract class for RTTI.
40class AttributeDiff {
41public:
42 AttributeDiff(DiffAttrKind Kind) : Kind(Kind){};
43 virtual ~AttributeDiff(){};
44 DiffAttrKind getKind() const { return Kind; }
45
46private:
47 DiffAttrKind Kind;
48};
49
50/// DiffOutput is the representation of a diff for a single attribute.
51struct DiffOutput {
52 /// The name of the attribute.
53 std::string Name;
54 /// The kind for RTTI
55 DiffAttrKind Kind;
56 /// Different values for the attribute
57 /// from each file where a diff is present.
58 std::vector<std::unique_ptr<AttributeDiff>> Values;
59 DiffOutput(std::string Name) : Name(Name){};
60};
61
62/// DiffScalarVal is a template class for the different types of scalar values.
63template <class T, DiffAttrKind U> class DiffScalarVal : public AttributeDiff {
64public:
65 DiffScalarVal(InterfaceInputOrder Order, T Val)
66 : AttributeDiff(U), Order(Order), Val(Val){};
67
68 static bool classof(const AttributeDiff *A) { return A->getKind() == U; }
69
70 void print(raw_ostream &, std::string);
71
72 T getVal() const { return Val; }
73 InterfaceInputOrder getOrder() const { return Order; }
74
75private:
76 /// The order is the file from which the diff is found.
77 InterfaceInputOrder Order;
78 T Val;
79};
80
81/// SymScalar is the diff symbol and the order.
82class SymScalar {
83public:
84 SymScalar(InterfaceInputOrder Order, const MachO::Symbol *Sym)
85 : Order(Order), Val(Sym){};
86
87 std::string getFlagString(MachO::SymbolFlags Flags) {
88 return Flags != MachO::SymbolFlags::None
89 ? " - " + stringifySymbolFlag(Flags)
90 : stringifySymbolFlag(Flags);
91 }
92
93 void print(raw_ostream &OS, std::string Indent, MachO::Target Targ);
94
95 const MachO::Symbol *getVal() const { return Val; }
96 InterfaceInputOrder getOrder() const { return Order; }
97
98private:
99 /// The order is the file from which the diff is found.
100 InterfaceInputOrder Order;
101 const MachO::Symbol *Val;
Cyndy Ishida56709b82021-06-23 08:55:39 -0700102 StringLiteral getSymbolNamePrefix(MachO::SymbolKind Kind);
Sam Powell5b5ab802021-06-09 21:13:31 -0700103 std::string stringifySymbolFlag(MachO::SymbolFlags Flag);
104};
105
106class DiffStrVec : public AttributeDiff {
107public:
108 MachO::Target Targ;
109 /// Values is a vector of StringRef values associated with the target.
110 std::vector<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>> TargValues;
111 DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){};
112
113 static bool classof(const AttributeDiff *A) {
114 return A->getKind() == AD_Str_Vec;
115 }
116};
117
118class DiffSymVec : public AttributeDiff {
119public:
120 MachO::Target Targ;
121 /// Values is a vector of symbol values associated with the target.
122 std::vector<SymScalar> TargValues;
123 DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){};
124
125 static bool classof(const AttributeDiff *A) {
126 return A->getKind() == AD_Sym_Vec;
127 }
128};
129
130/// InlineDoc represents an inlined framework/library in a TBD File.
131class InlineDoc : public AttributeDiff {
132public:
133 /// Install name of the framework/library.
134 std::string InstallName;
135 /// Differences found from each file.
136 std::vector<DiffOutput> DocValues;
137 InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff)
138 : AttributeDiff(AD_Inline_Doc), InstallName(InstName),
139 DocValues(std::move(Diff)){};
140
141 static bool classof(const AttributeDiff *A) {
142 return A->getKind() == AD_Inline_Doc;
143 }
144};
145
146/// DiffEngine contains the methods to compare the input files and print the
147/// output of the differences found in the files.
148class DiffEngine {
149public:
150 DiffEngine(object::TapiUniversal *InputFileNameLHS,
151 object::TapiUniversal *InputFileNameRHS)
152 : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){};
153 bool compareFiles(raw_ostream &);
154
155private:
156 object::TapiUniversal *FileLHS;
157 object::TapiUniversal *FileRHS;
158
159 /// Function that prints the differences found in the files.
160 void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int);
161 /// Function that does the comparison of the TBD files and returns the
162 /// differences.
163 std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *,
164 const MachO::InterfaceFile *);
165};
166
167} // namespace llvm
168
169#endif