15b5ab80eSSam Powell //===-- DiffEngine.h - File comparator --------------------------*- C++ -*-===//
25b5ab80eSSam Powell //
35b5ab80eSSam Powell // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45b5ab80eSSam Powell // See https://llvm.org/LICENSE.txt for license information.
55b5ab80eSSam Powell // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65b5ab80eSSam Powell //
75b5ab80eSSam Powell //===----------------------------------------------------------------------===//
85b5ab80eSSam Powell //
95b5ab80eSSam Powell // This header defines the interface to the llvm-tapi difference engine,
105b5ab80eSSam Powell // which structurally compares two tbd files.
115b5ab80eSSam Powell //
125b5ab80eSSam Powell //===----------------------------------------------------------------------===/
135b5ab80eSSam Powell #ifndef LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H
145b5ab80eSSam Powell #define LLVM_TOOLS_LLVM_TAPI_DIFF_DIFFENGINE_H
155b5ab80eSSam Powell 
165b5ab80eSSam Powell #include "llvm/ADT/Optional.h"
175b5ab80eSSam Powell #include "llvm/Object/TapiUniversal.h"
185b5ab80eSSam Powell #include "llvm/Support/raw_ostream.h"
195b5ab80eSSam Powell #include "llvm/TextAPI/Symbol.h"
205b5ab80eSSam Powell #include "llvm/TextAPI/Target.h"
215b5ab80eSSam Powell 
225b5ab80eSSam Powell namespace llvm {
235b5ab80eSSam Powell 
245b5ab80eSSam Powell /// InterfaceInputOrder determines from which file the diff attribute belongs
255b5ab80eSSam Powell /// to.
265b5ab80eSSam Powell enum InterfaceInputOrder { lhs, rhs };
275b5ab80eSSam Powell 
285b5ab80eSSam Powell /// DiffAttrKind is the enum that holds the concrete bases for RTTI.
295b5ab80eSSam Powell enum DiffAttrKind {
305b5ab80eSSam Powell   AD_Diff_Scalar_PackedVersion,
315b5ab80eSSam Powell   AD_Diff_Scalar_Unsigned,
325b5ab80eSSam Powell   AD_Diff_Scalar_Bool,
335b5ab80eSSam Powell   AD_Diff_Scalar_Str,
345b5ab80eSSam Powell   AD_Str_Vec,
355b5ab80eSSam Powell   AD_Sym_Vec,
365b5ab80eSSam Powell   AD_Inline_Doc,
375b5ab80eSSam Powell };
385b5ab80eSSam Powell 
395b5ab80eSSam Powell /// AttributeDiff is the abstract class for RTTI.
405b5ab80eSSam Powell class AttributeDiff {
415b5ab80eSSam Powell public:
AttributeDiff(DiffAttrKind Kind)425b5ab80eSSam Powell   AttributeDiff(DiffAttrKind Kind) : Kind(Kind){};
~AttributeDiff()435b5ab80eSSam Powell   virtual ~AttributeDiff(){};
getKind()445b5ab80eSSam Powell   DiffAttrKind getKind() const { return Kind; }
455b5ab80eSSam Powell 
465b5ab80eSSam Powell private:
475b5ab80eSSam Powell   DiffAttrKind Kind;
485b5ab80eSSam Powell };
495b5ab80eSSam Powell 
505b5ab80eSSam Powell /// DiffOutput is the representation of a diff for a single attribute.
515b5ab80eSSam Powell struct DiffOutput {
525b5ab80eSSam Powell   /// The name of the attribute.
535b5ab80eSSam Powell   std::string Name;
545b5ab80eSSam Powell   /// The kind for RTTI
555b5ab80eSSam Powell   DiffAttrKind Kind;
565b5ab80eSSam Powell   /// Different values for the attribute
575b5ab80eSSam Powell   /// from each file where a diff is present.
585b5ab80eSSam Powell   std::vector<std::unique_ptr<AttributeDiff>> Values;
DiffOutputDiffOutput595b5ab80eSSam Powell   DiffOutput(std::string Name) : Name(Name){};
605b5ab80eSSam Powell };
615b5ab80eSSam Powell 
625b5ab80eSSam Powell /// DiffScalarVal is a template class for the different types of scalar values.
635b5ab80eSSam Powell template <class T, DiffAttrKind U> class DiffScalarVal : public AttributeDiff {
645b5ab80eSSam Powell public:
DiffScalarVal(InterfaceInputOrder Order,T Val)655b5ab80eSSam Powell   DiffScalarVal(InterfaceInputOrder Order, T Val)
665b5ab80eSSam Powell       : AttributeDiff(U), Order(Order), Val(Val){};
675b5ab80eSSam Powell 
classof(const AttributeDiff * A)685b5ab80eSSam Powell   static bool classof(const AttributeDiff *A) { return A->getKind() == U; }
695b5ab80eSSam Powell 
705b5ab80eSSam Powell   void print(raw_ostream &, std::string);
715b5ab80eSSam Powell 
getVal()725b5ab80eSSam Powell   T getVal() const { return Val; }
getOrder()735b5ab80eSSam Powell   InterfaceInputOrder getOrder() const { return Order; }
745b5ab80eSSam Powell 
755b5ab80eSSam Powell private:
765b5ab80eSSam Powell   /// The order is the file from which the diff is found.
775b5ab80eSSam Powell   InterfaceInputOrder Order;
785b5ab80eSSam Powell   T Val;
795b5ab80eSSam Powell };
805b5ab80eSSam Powell 
815b5ab80eSSam Powell /// SymScalar is the diff symbol and the order.
825b5ab80eSSam Powell class SymScalar {
835b5ab80eSSam Powell public:
SymScalar(InterfaceInputOrder Order,const MachO::Symbol * Sym)845b5ab80eSSam Powell   SymScalar(InterfaceInputOrder Order, const MachO::Symbol *Sym)
855b5ab80eSSam Powell       : Order(Order), Val(Sym){};
865b5ab80eSSam Powell 
getFlagString(MachO::SymbolFlags Flags)875b5ab80eSSam Powell   std::string getFlagString(MachO::SymbolFlags Flags) {
885b5ab80eSSam Powell     return Flags != MachO::SymbolFlags::None
895b5ab80eSSam Powell                ? " - " + stringifySymbolFlag(Flags)
905b5ab80eSSam Powell                : stringifySymbolFlag(Flags);
915b5ab80eSSam Powell   }
925b5ab80eSSam Powell 
935b5ab80eSSam Powell   void print(raw_ostream &OS, std::string Indent, MachO::Target Targ);
945b5ab80eSSam Powell 
getVal()955b5ab80eSSam Powell   const MachO::Symbol *getVal() const { return Val; }
getOrder()965b5ab80eSSam Powell   InterfaceInputOrder getOrder() const { return Order; }
975b5ab80eSSam Powell 
985b5ab80eSSam Powell private:
995b5ab80eSSam Powell   /// The order is the file from which the diff is found.
1005b5ab80eSSam Powell   InterfaceInputOrder Order;
1015b5ab80eSSam Powell   const MachO::Symbol *Val;
102*56709b86SCyndy Ishida   StringLiteral getSymbolNamePrefix(MachO::SymbolKind Kind);
1035b5ab80eSSam Powell   std::string stringifySymbolFlag(MachO::SymbolFlags Flag);
1045b5ab80eSSam Powell };
1055b5ab80eSSam Powell 
1065b5ab80eSSam Powell class DiffStrVec : public AttributeDiff {
1075b5ab80eSSam Powell public:
1085b5ab80eSSam Powell   MachO::Target Targ;
1095b5ab80eSSam Powell   /// Values is a vector of StringRef values associated with the target.
1105b5ab80eSSam Powell   std::vector<DiffScalarVal<StringRef, AD_Diff_Scalar_Str>> TargValues;
DiffStrVec(MachO::Target Targ)1115b5ab80eSSam Powell   DiffStrVec(MachO::Target Targ) : AttributeDiff(AD_Str_Vec), Targ(Targ){};
1125b5ab80eSSam Powell 
classof(const AttributeDiff * A)1135b5ab80eSSam Powell   static bool classof(const AttributeDiff *A) {
1145b5ab80eSSam Powell     return A->getKind() == AD_Str_Vec;
1155b5ab80eSSam Powell   }
1165b5ab80eSSam Powell };
1175b5ab80eSSam Powell 
1185b5ab80eSSam Powell class DiffSymVec : public AttributeDiff {
1195b5ab80eSSam Powell public:
1205b5ab80eSSam Powell   MachO::Target Targ;
1215b5ab80eSSam Powell   /// Values is a vector of symbol values associated with the target.
1225b5ab80eSSam Powell   std::vector<SymScalar> TargValues;
DiffSymVec(MachO::Target Targ)1235b5ab80eSSam Powell   DiffSymVec(MachO::Target Targ) : AttributeDiff(AD_Sym_Vec), Targ(Targ){};
1245b5ab80eSSam Powell 
classof(const AttributeDiff * A)1255b5ab80eSSam Powell   static bool classof(const AttributeDiff *A) {
1265b5ab80eSSam Powell     return A->getKind() == AD_Sym_Vec;
1275b5ab80eSSam Powell   }
1285b5ab80eSSam Powell };
1295b5ab80eSSam Powell 
1305b5ab80eSSam Powell /// InlineDoc represents an inlined framework/library in a TBD File.
1315b5ab80eSSam Powell class InlineDoc : public AttributeDiff {
1325b5ab80eSSam Powell public:
1335b5ab80eSSam Powell   /// Install name of the framework/library.
1345b5ab80eSSam Powell   std::string InstallName;
1355b5ab80eSSam Powell   /// Differences found from each file.
1365b5ab80eSSam Powell   std::vector<DiffOutput> DocValues;
InlineDoc(StringRef InstName,std::vector<DiffOutput> Diff)1375b5ab80eSSam Powell   InlineDoc(StringRef InstName, std::vector<DiffOutput> Diff)
1385b5ab80eSSam Powell       : AttributeDiff(AD_Inline_Doc), InstallName(InstName),
1395b5ab80eSSam Powell         DocValues(std::move(Diff)){};
1405b5ab80eSSam Powell 
classof(const AttributeDiff * A)1415b5ab80eSSam Powell   static bool classof(const AttributeDiff *A) {
1425b5ab80eSSam Powell     return A->getKind() == AD_Inline_Doc;
1435b5ab80eSSam Powell   }
1445b5ab80eSSam Powell };
1455b5ab80eSSam Powell 
1465b5ab80eSSam Powell /// DiffEngine contains the methods to compare the input files and print the
1475b5ab80eSSam Powell /// output of the differences found in the files.
1485b5ab80eSSam Powell class DiffEngine {
1495b5ab80eSSam Powell public:
DiffEngine(object::TapiUniversal * InputFileNameLHS,object::TapiUniversal * InputFileNameRHS)1505b5ab80eSSam Powell   DiffEngine(object::TapiUniversal *InputFileNameLHS,
1515b5ab80eSSam Powell              object::TapiUniversal *InputFileNameRHS)
1525b5ab80eSSam Powell       : FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){};
1535b5ab80eSSam Powell   bool compareFiles(raw_ostream &);
1545b5ab80eSSam Powell 
1555b5ab80eSSam Powell private:
1565b5ab80eSSam Powell   object::TapiUniversal *FileLHS;
1575b5ab80eSSam Powell   object::TapiUniversal *FileRHS;
1585b5ab80eSSam Powell 
1595b5ab80eSSam Powell   /// Function that prints the differences found in the files.
1605b5ab80eSSam Powell   void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int);
1615b5ab80eSSam Powell   /// Function that does the comparison of the TBD files and returns the
1625b5ab80eSSam Powell   /// differences.
1635b5ab80eSSam Powell   std::vector<DiffOutput> findDifferences(const MachO::InterfaceFile *,
1645b5ab80eSSam Powell                                           const MachO::InterfaceFile *);
1655b5ab80eSSam Powell };
1665b5ab80eSSam Powell 
1675b5ab80eSSam Powell } // namespace llvm
1685b5ab80eSSam Powell 
1695b5ab80eSSam Powell #endif
170