• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
old_types_(old_types)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