Home | History | Annotate | Download | only in include
      1 #ifndef ABI_DIFF_HELPERS
      2 #define ABI_DIFF_HELPERS
      3 
      4 #include <ir_representation.h>
      5 
      6 #include <deque>
      7 
      8 // Classes which act as middle-men between clang AST parsing routines and
      9 // message format specific dumpers.
     10 namespace abi_util {
     11 
     12 using MergeStatus = TextFormatToIRReader::MergeStatus;
     13 
     14 enum DiffStatus {
     15   // There was no diff found while comparing types.
     16   no_diff = 0,
     17   // There was a diff found and it should be added as a part of a diff message.
     18   direct_diff = 1,
     19   // There was a diff found, however it need not be added as a part of a diff
     20   // message, since it would have already been noted elsewhere.
     21   indirect_diff = 2,
     22 };
     23 
     24 static inline DiffStatus operator| (DiffStatus f,DiffStatus s) {
     25   return static_cast<DiffStatus>(
     26       static_cast<std::underlying_type<DiffStatus>::type>(f) |
     27       static_cast<std::underlying_type<DiffStatus>::type>(s));
     28 }
     29 
     30 static inline DiffStatus operator& (DiffStatus f, DiffStatus s) {
     31   return static_cast<DiffStatus>(
     32       static_cast<std::underlying_type<DiffStatus>::type>(f) &
     33       static_cast<std::underlying_type<DiffStatus>::type>(s));
     34 }
     35 
     36 template <typename T>
     37 using DiffStatusPair = std::pair<DiffStatus, T>;
     38 
     39 template <typename GenericField, typename GenericFieldDiff>
     40 struct GenericFieldDiffInfo {
     41   DiffStatus diff_status_;
     42   std::vector<GenericFieldDiff> diffed_fields_;
     43   std::vector<const GenericField *> removed_fields_;
     44   std::vector<const GenericField *> added_fields_;
     45 };
     46 
     47 std::string Unwind(const std::deque<std::string> *type_queue);
     48 
     49 class AbiDiffHelper {
     50  public:
     51   AbiDiffHelper(
     52       const AbiElementMap<const abi_util::TypeIR *> &old_types,
     53       const AbiElementMap<const abi_util::TypeIR *> &new_types,
     54       std::set<std::string> *type_cache,
     55       abi_util::IRDiffDumper *ir_diff_dumper = nullptr,
     56       AbiElementMap<MergeStatus> *local_to_global_type_id_map = nullptr)
     57       : old_types_(old_types), new_types_(new_types),
     58         type_cache_(type_cache), ir_diff_dumper_(ir_diff_dumper),
     59         local_to_global_type_id_map_(local_to_global_type_id_map) { }
     60 
     61   DiffStatus CompareAndDumpTypeDiff(
     62       const std::string &old_type_str, const std::string &new_type_str,
     63       std::deque<std::string> *type_queue = nullptr,
     64       abi_util::IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced);
     65 
     66   DiffStatus CompareAndDumpTypeDiff(
     67       const abi_util::TypeIR *old_type, const abi_util::TypeIR *new_type,
     68       abi_util::LinkableMessageKind kind,
     69       std::deque<std::string> *type_queue = nullptr,
     70       abi_util::IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced);
     71 
     72 
     73   DiffStatus CompareRecordTypes(const abi_util::RecordTypeIR *old_type,
     74                                 const abi_util::RecordTypeIR *new_type,
     75                                 std::deque<std::string> *type_queue,
     76                                 abi_util::IRDiffDumper::DiffKind diff_kind);
     77 
     78   DiffStatus CompareQualifiedTypes(const abi_util::QualifiedTypeIR *old_type,
     79                                    const abi_util::QualifiedTypeIR *new_type,
     80                                    std::deque<std::string> *type_queue,
     81                                    abi_util::IRDiffDumper::DiffKind diff_kind);
     82 
     83   DiffStatus ComparePointerTypes(const abi_util::PointerTypeIR *old_type,
     84                                  const abi_util::PointerTypeIR *new_type,
     85                                  std::deque<std::string> *type_queue,
     86                                  abi_util::IRDiffDumper::DiffKind diff_kind);
     87 
     88   DiffStatus CompareLvalueReferenceTypes(
     89       const abi_util::LvalueReferenceTypeIR *old_type,
     90       const abi_util::LvalueReferenceTypeIR *new_type,
     91       std::deque<std::string> *type_queue,
     92       abi_util::IRDiffDumper::DiffKind diff_kind);
     93 
     94   DiffStatus CompareRvalueReferenceTypes(
     95       const abi_util::RvalueReferenceTypeIR *old_type,
     96       const abi_util::RvalueReferenceTypeIR *new_type,
     97       std::deque<std::string> *type_queue,
     98       abi_util::IRDiffDumper::DiffKind diff_kind);
     99 
    100 
    101   DiffStatus CompareBuiltinTypes(const abi_util::BuiltinTypeIR *old_type,
    102                                  const abi_util::BuiltinTypeIR *new_type);
    103   static void CompareEnumFields(
    104     const std::vector<abi_util::EnumFieldIR> &old_fields,
    105     const std::vector<abi_util::EnumFieldIR> &new_fields,
    106     abi_util::EnumTypeDiffIR *enum_type_diff_ir);
    107 
    108   DiffStatus CompareEnumTypes(const abi_util::EnumTypeIR *old_type,
    109                               const abi_util::EnumTypeIR *new_type,
    110                               std::deque<std::string> *type_queue,
    111                               abi_util::IRDiffDumper::DiffKind diff_kind);
    112 
    113   DiffStatus CompareFunctionTypes(const abi_util::FunctionTypeIR *old_type,
    114                                   const abi_util::FunctionTypeIR *new_type,
    115                                   std::deque<std::string> *type_queue,
    116                                   abi_util::DiffMessageIR::DiffKind diff_kind);
    117 
    118   void ReplaceRemovedFieldTypeIdsWithTypeNames(
    119     std::vector<abi_util::RecordFieldIR *> *removed_fields);
    120 
    121   void ReplaceDiffedFieldTypeIdsWithTypeNames(
    122       abi_util::RecordFieldDiffIR *diffed_field);
    123 
    124   std::vector<std::pair<abi_util::RecordFieldIR, abi_util::RecordFieldIR>>
    125   FixupDiffedFieldTypeIds(
    126       const std::vector<abi_util::RecordFieldDiffIR> &field_diffs);
    127 
    128   DiffStatusPair<std::unique_ptr<abi_util::RecordFieldDiffIR>>
    129   CompareCommonRecordFields(
    130     const abi_util::RecordFieldIR *old_field,
    131     const abi_util::RecordFieldIR *new_field,
    132     std::deque<std::string> *type_queue,
    133     abi_util::IRDiffDumper::DiffKind diff_kind);
    134 
    135   GenericFieldDiffInfo<abi_util::RecordFieldIR, abi_util::RecordFieldDiffIR>
    136       CompareRecordFields(
    137       const std::vector<abi_util::RecordFieldIR> &old_fields,
    138       const std::vector<abi_util::RecordFieldIR> &new_fields,
    139       std::deque<std::string> *type_queue,
    140       abi_util::IRDiffDumper::DiffKind diff_kind);
    141 
    142   DiffStatus CompareFunctionParameters(
    143       const std::vector<abi_util::ParamIR> &old_parameters,
    144       const std::vector<abi_util::ParamIR> &new_parameters,
    145       std::deque<std::string> *type_queue,
    146       abi_util::IRDiffDumper::DiffKind diff_kind);
    147 
    148   bool CompareBaseSpecifiers(
    149       const std::vector<abi_util::CXXBaseSpecifierIR> &old_base_specifiers,
    150       const std::vector<abi_util::CXXBaseSpecifierIR> &new_base_specifiers,
    151       std::deque<std::string> *type_queue,
    152       abi_util::IRDiffDumper::DiffKind diff_kind);
    153 
    154   bool CompareVTables(const abi_util::RecordTypeIR *old_record,
    155                       const abi_util::RecordTypeIR *new_record);
    156 
    157   bool CompareVTableComponents(
    158       const abi_util::VTableComponentIR &old_component,
    159       const abi_util::VTableComponentIR &new_component);
    160 
    161   DiffStatus CompareTemplateInfo(
    162       const std::vector<abi_util::TemplateElementIR> &old_template_elements,
    163       const std::vector<abi_util::TemplateElementIR> &new_template_elements,
    164       std::deque<std::string> *type_queue,
    165       abi_util::IRDiffDumper::DiffKind diff_kind);
    166 
    167 
    168   bool CompareSizeAndAlignment(const abi_util::TypeIR *old_ti,
    169                                const abi_util::TypeIR *new_ti);
    170 
    171   template <typename DiffType, typename DiffElement>
    172   bool AddToDiff(DiffType *mutable_diff, const DiffElement *oldp,
    173                  const DiffElement *newp,
    174                  std::deque<std::string> *type_queue = nullptr);
    175  protected:
    176   const AbiElementMap<const abi_util::TypeIR *> &old_types_;
    177   const AbiElementMap<const abi_util::TypeIR *> &new_types_;
    178   std::set<std::string> *type_cache_ = nullptr;
    179   abi_util::IRDiffDumper *ir_diff_dumper_ = nullptr;
    180   AbiElementMap<MergeStatus> *local_to_global_type_id_map_ = nullptr;
    181 };
    182 
    183 void ReplaceTypeIdsWithTypeNames(
    184     const AbiElementMap<const TypeIR *> &type_graph, LinkableMessageIR *lm);
    185 
    186 } // namespace abi_util
    187 #endif
    188