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