xref: /openbsd-src/gnu/llvm/llvm/tools/llvm-tapi-diff/DiffEngine.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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 
getFlagString(MachO::SymbolFlags Flags)86   std::string getFlagString(MachO::SymbolFlags Flags) {
87     return Flags != MachO::SymbolFlags::None
88                ? " - " + stringifySymbolFlag(Flags)
89                : stringifySymbolFlag(Flags);
90   }
91 
92   void print(raw_ostream &OS, std::string Indent, MachO::Target Targ);
93 
getVal()94   const MachO::Symbol *getVal() const { return Val; }
getOrder()95   InterfaceInputOrder getOrder() const { return Order; }
96 
97 private:
98   /// The order is the file from which the diff is found.
99   InterfaceInputOrder Order;
100   const MachO::Symbol *Val;
101   StringLiteral getSymbolNamePrefix(MachO::SymbolKind Kind);
102   std::string stringifySymbolFlag(MachO::SymbolFlags Flag);
103 };
104 
105 class DiffStrVec : public AttributeDiff {
106 public:
107   MachO::Target Targ;
108   /// Values is a vector of StringRef values associated with the target.
109   std::vector<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>> TargValues;
DiffStrVec(MachO::Target Targ)110   DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){};
111 
classof(const AttributeDiff * A)112   static bool classof(const AttributeDiff *A) {
113     return A->getKind() == AD_Str_Vec;
114   }
115 };
116 
117 class DiffSymVec : public AttributeDiff {
118 public:
119   MachO::Target Targ;
120   /// Values is a vector of symbol values associated with the target.
121   std::vector<SymScalar> TargValues;
DiffSymVec(MachO::Target Targ)122   DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){};
123 
classof(const AttributeDiff * A)124   static bool classof(const AttributeDiff *A) {
125     return A->getKind() == AD_Sym_Vec;
126   }
127 };
128 
129 /// InlineDoc represents an inlined framework/library in a TBD File.
130 class InlineDoc : public AttributeDiff {
131 public:
132   /// Install name of the framework/library.
133   std::string InstallName;
134   /// Differences found from each file.
135   std::vector<DiffOutput> DocValues;
InlineDoc(StringRef InstName,std::vector<DiffOutput> Diff)136   InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff)
137       : AttributeDiff(AD_Inline_Doc), InstallName(InstName),
138         DocValues(std::move(Diff)){};
139 
classof(const AttributeDiff * A)140   static bool classof(const AttributeDiff *A) {
141     return A->getKind() == AD_Inline_Doc;
142   }
143 };
144 
145 /// DiffEngine contains the methods to compare the input files and print the
146 /// output of the differences found in the files.
147 class DiffEngine {
148 public:
DiffEngine(object::TapiUniversal * InputFileNameLHS,object::TapiUniversal * InputFileNameRHS)149   DiffEngine(object::TapiUniversal *InputFileNameLHS,
150              object::TapiUniversal *InputFileNameRHS)
151       : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){};
152   bool compareFiles(raw_ostream &);
153 
154 private:
155   object::TapiUniversal *FileLHS;
156   object::TapiUniversal *FileRHS;
157 
158   /// Function that prints the differences found in the files.
159   void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int);
160   /// Function that does the comparison of the TBD files and returns the
161   /// differences.
162   std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *,
163                                           const MachO::InterfaceFile *);
164 };
165 
166 } // namespace llvm
167 
168 #endif
169