• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef ABI_DIFF_HELPERS_H_
16 #define ABI_DIFF_HELPERS_H_
17 
18 #include "repr/ir_diff_dumper.h"
19 #include "repr/ir_diff_representation.h"
20 #include "repr/ir_reader.h"
21 #include "repr/ir_representation.h"
22 
23 #include <deque>
24 
25 
26 namespace header_checker {
27 namespace repr {
28 
29 
30 // Classes which act as middle-men between clang AST parsing routines and
31 // message format specific dumpers.
32 
33 using MergeStatus = IRReader::MergeStatus;
34 
35 enum DiffStatus {
36   // There was no diff found while comparing types.
37   no_diff = 0,
38   // There was a diff found and it should be added as a part of a diff message.
39   direct_diff = 1,
40   // There was a diff found, however it need not be added as a part of a diff
41   // message, since it would have already been noted elsewhere.
42   indirect_diff = 2,
43 
44   opaque_diff = 3,
45 };
46 
47 static inline DiffStatus operator|(DiffStatus f, DiffStatus s) {
48   return static_cast<DiffStatus>(
49       static_cast<std::underlying_type<DiffStatus>::type>(f) |
50       static_cast<std::underlying_type<DiffStatus>::type>(s));
51 }
52 
53 static inline DiffStatus operator&(DiffStatus f, DiffStatus s) {
54   return static_cast<DiffStatus>(
55       static_cast<std::underlying_type<DiffStatus>::type>(f) &
56       static_cast<std::underlying_type<DiffStatus>::type>(s));
57 }
58 
59 template <typename T>
60 using DiffStatusPair = std::pair<DiffStatus, T>;
61 
62 template <typename GenericField, typename GenericFieldDiff>
63 struct GenericFieldDiffInfo {
64   DiffStatus diff_status_;
65   std::vector<GenericFieldDiff> diffed_fields_;
66   std::vector<const GenericField *> removed_fields_;
67   std::vector<const GenericField *> added_fields_;
68 };
69 
70 std::string Unwind(const std::deque<std::string> *type_queue);
71 
72 struct DiffPolicyOptions {
DiffPolicyOptionsDiffPolicyOptions73   DiffPolicyOptions(bool consider_opaque_types_different)
74       : consider_opaque_types_different_(consider_opaque_types_different) {}
75 
76   bool consider_opaque_types_different_;
77 };
78 
79 class AbiDiffHelper {
80  public:
81   AbiDiffHelper(
82       const AbiElementMap<const TypeIR *> &old_types,
83       const AbiElementMap<const TypeIR *> &new_types,
84       const DiffPolicyOptions &diff_policy_options,
85       std::set<std::string> *type_cache,
86       IRDiffDumper *ir_diff_dumper = nullptr,
87       AbiElementMap<MergeStatus> *local_to_global_type_id_map = nullptr)
old_types_(old_types)88       : old_types_(old_types), new_types_(new_types),
89         diff_policy_options_(diff_policy_options), type_cache_(type_cache),
90         ir_diff_dumper_(ir_diff_dumper),
91         local_to_global_type_id_map_(local_to_global_type_id_map) {}
92 
93   DiffStatus CompareAndDumpTypeDiff(
94       const std::string &old_type_str, const std::string &new_type_str,
95       std::deque<std::string> *type_queue = nullptr,
96       IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced);
97 
98   DiffStatus CompareAndDumpTypeDiff(
99       const TypeIR *old_type, const TypeIR *new_type,
100       LinkableMessageKind kind,
101       std::deque<std::string> *type_queue = nullptr,
102       IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced);
103 
104 
105   DiffStatus CompareRecordTypes(const RecordTypeIR *old_type,
106                                 const RecordTypeIR *new_type,
107                                 std::deque<std::string> *type_queue,
108                                 IRDiffDumper::DiffKind diff_kind);
109 
110   DiffStatus CompareQualifiedTypes(const QualifiedTypeIR *old_type,
111                                    const QualifiedTypeIR *new_type,
112                                    std::deque<std::string> *type_queue,
113                                    IRDiffDumper::DiffKind diff_kind);
114 
115   DiffStatus ComparePointerTypes(const PointerTypeIR *old_type,
116                                  const PointerTypeIR *new_type,
117                                  std::deque<std::string> *type_queue,
118                                  IRDiffDumper::DiffKind diff_kind);
119 
120   DiffStatus CompareLvalueReferenceTypes(
121       const LvalueReferenceTypeIR *old_type,
122       const LvalueReferenceTypeIR *new_type,
123       std::deque<std::string> *type_queue,
124       IRDiffDumper::DiffKind diff_kind);
125 
126   DiffStatus CompareRvalueReferenceTypes(
127       const RvalueReferenceTypeIR *old_type,
128       const RvalueReferenceTypeIR *new_type,
129       std::deque<std::string> *type_queue,
130       IRDiffDumper::DiffKind diff_kind);
131 
132 
133   DiffStatus CompareBuiltinTypes(const BuiltinTypeIR *old_type,
134                                  const BuiltinTypeIR *new_type);
135 
136   static void CompareEnumFields(
137       const std::vector<EnumFieldIR> &old_fields,
138       const std::vector<EnumFieldIR> &new_fields,
139       EnumTypeDiffIR *enum_type_diff_ir);
140 
141   DiffStatus CompareEnumTypes(const EnumTypeIR *old_type,
142                               const EnumTypeIR *new_type,
143                               std::deque<std::string> *type_queue,
144                               IRDiffDumper::DiffKind diff_kind);
145 
146   DiffStatus CompareFunctionTypes(const FunctionTypeIR *old_type,
147                                   const FunctionTypeIR *new_type,
148                                   std::deque<std::string> *type_queue,
149                                   DiffMessageIR::DiffKind diff_kind);
150 
151   void ReplaceRemovedFieldTypeIdsWithTypeNames(
152       std::vector<RecordFieldIR *> *removed_fields);
153 
154   void ReplaceDiffedFieldTypeIdsWithTypeNames(
155       RecordFieldDiffIR *diffed_field);
156 
157   std::vector<std::pair<RecordFieldIR, RecordFieldIR>>
158   FixupDiffedFieldTypeIds(
159       const std::vector<RecordFieldDiffIR> &field_diffs);
160 
161   DiffStatusPair<std::unique_ptr<RecordFieldDiffIR>>
162   CompareCommonRecordFields(
163       const RecordFieldIR *old_field,
164       const RecordFieldIR *new_field,
165       std::deque<std::string> *type_queue,
166       IRDiffDumper::DiffKind diff_kind);
167 
168   GenericFieldDiffInfo<RecordFieldIR, RecordFieldDiffIR>
169       CompareRecordFields(
170       const std::vector<RecordFieldIR> &old_fields,
171       const std::vector<RecordFieldIR> &new_fields,
172       std::deque<std::string> *type_queue,
173       IRDiffDumper::DiffKind diff_kind);
174 
175   DiffStatus CompareFunctionParameters(
176       const std::vector<ParamIR> &old_parameters,
177       const std::vector<ParamIR> &new_parameters,
178       std::deque<std::string> *type_queue,
179       IRDiffDumper::DiffKind diff_kind);
180 
181   bool CompareBaseSpecifiers(
182       const std::vector<CXXBaseSpecifierIR> &old_base_specifiers,
183       const std::vector<CXXBaseSpecifierIR> &new_base_specifiers,
184       std::deque<std::string> *type_queue,
185       IRDiffDumper::DiffKind diff_kind);
186 
187   bool CompareVTables(const RecordTypeIR *old_record,
188                       const RecordTypeIR *new_record);
189 
190   bool CompareVTableComponents(
191       const VTableComponentIR &old_component,
192       const VTableComponentIR &new_component);
193 
194   DiffStatus CompareTemplateInfo(
195       const std::vector<TemplateElementIR> &old_template_elements,
196       const std::vector<TemplateElementIR> &new_template_elements,
197       std::deque<std::string> *type_queue,
198       IRDiffDumper::DiffKind diff_kind);
199 
200 
201   bool CompareSizeAndAlignment(const TypeIR *old_ti,
202                                const TypeIR *new_ti);
203 
204   template <typename DiffType, typename DiffElement>
205   bool AddToDiff(DiffType *mutable_diff, const DiffElement *oldp,
206                  const DiffElement *newp,
207                  std::deque<std::string> *type_queue = nullptr);
208 
209  protected:
210   const AbiElementMap<const TypeIR *> &old_types_;
211   const AbiElementMap<const TypeIR *> &new_types_;
212   const DiffPolicyOptions &diff_policy_options_;
213   std::set<std::string> *type_cache_;
214   IRDiffDumper *ir_diff_dumper_;
215   AbiElementMap<MergeStatus> *local_to_global_type_id_map_;
216 };
217 
218 void ReplaceTypeIdsWithTypeNames(
219     const AbiElementMap<const TypeIR *> &type_graph, LinkableMessageIR *lm);
220 
221 
222 }  // namespace repr
223 }  // namespace header_checker
224 
225 
226 #endif  // ABI_DIFF_HELPERS_H_
227