• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 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 HEADER_CHECKER_REPR_IR_DIFF_REPRESENTATION_H_
16 #define HEADER_CHECKER_REPR_IR_DIFF_REPRESENTATION_H_
17 
18 #include "repr/ir_representation.h"
19 
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 
27 namespace header_checker {
28 namespace repr {
29 
30 
31 class DiffMessageIR {
32  public:
33   enum DiffKind {
34     Added,
35     Removed,
36     Referenced,
37     Unreferenced
38   };
39 
40  public:
~DiffMessageIR()41   virtual ~DiffMessageIR() {}
42 
43   virtual LinkableMessageKind Kind() const = 0;
44 
SetName(const std::string & name)45   void SetName(const std::string &name) {
46     name_ = name;
47   }
48 
GetName()49   const std::string &GetName() const {
50     return name_;
51   }
52 
53  protected:
54   std::string name_;
55 };
56 
57 class AccessSpecifierDiffIR {
58  public:
AccessSpecifierDiffIR(AccessSpecifierIR old_access,AccessSpecifierIR new_access)59   AccessSpecifierDiffIR(AccessSpecifierIR old_access,
60                         AccessSpecifierIR new_access)
61       : old_access_(old_access), new_access_(new_access) {}
62 
GetOldAccess()63   AccessSpecifierIR GetOldAccess() const { return old_access_; }
64 
GetNewAccess()65   AccessSpecifierIR GetNewAccess() const { return new_access_; }
66 
67  protected:
68   AccessSpecifierIR old_access_;
69   AccessSpecifierIR new_access_;
70 };
71 
72 class TypeDiffIR {
73  public:
TypeDiffIR(std::pair<uint64_t,uint64_t> && sizes,std::pair<uint32_t,uint32_t> && alignment)74   TypeDiffIR(std::pair<uint64_t, uint64_t> &&sizes,
75              std::pair<uint32_t, uint32_t> &&alignment)
76       : sizes_(std::move(sizes)), alignments_(std::move(alignment)) {}
77 
GetSizes()78   const std::pair<uint64_t, uint64_t> &GetSizes() const {
79     return sizes_;
80   }
81 
GetAlignments()82   const std::pair<uint32_t, uint32_t> &GetAlignments() const {
83     return alignments_;
84   }
85 
86  protected:
87   std::pair<uint64_t, uint64_t> sizes_;
88   std::pair<uint32_t, uint32_t> alignments_;
89 };
90 
91 class VTableLayoutDiffIR {
92  public:
VTableLayoutDiffIR(const VTableLayoutIR & old_layout,const VTableLayoutIR & new_layout)93   VTableLayoutDiffIR(const VTableLayoutIR &old_layout,
94                      const VTableLayoutIR &new_layout)
95       : old_layout_(old_layout), new_layout_(new_layout) {}
96 
GetOldVTable()97   const VTableLayoutIR &GetOldVTable() const {
98     return old_layout_;
99   }
100 
GetNewVTable()101   const VTableLayoutIR &GetNewVTable() const {
102     return new_layout_;
103   }
104 
105  protected:
106   const VTableLayoutIR &old_layout_;
107   const VTableLayoutIR &new_layout_;
108 };
109 
110 class RecordFieldDiffIR {
111  public:
RecordFieldDiffIR(const RecordFieldIR * old_field,const RecordFieldIR * new_field)112   RecordFieldDiffIR(const RecordFieldIR *old_field,
113                     const RecordFieldIR *new_field)
114       : old_field_(old_field), new_field_(new_field) {}
115 
GetOldField()116   const RecordFieldIR *GetOldField() const {
117     return old_field_;
118   }
119 
GetNewField()120   const RecordFieldIR *GetNewField() const {
121     return new_field_;
122   }
123 
124   const RecordFieldIR *old_field_;
125   const RecordFieldIR *new_field_;
126 };
127 
128 class CXXBaseSpecifierDiffIR {
129  public:
CXXBaseSpecifierDiffIR(const std::vector<CXXBaseSpecifierIR> & old_base_specifiers,const std::vector<CXXBaseSpecifierIR> & new_base_specifiers)130   CXXBaseSpecifierDiffIR(
131       const std::vector<CXXBaseSpecifierIR> &old_base_specifiers,
132       const std::vector<CXXBaseSpecifierIR> &new_base_specifiers)
133       : old_base_specifiers_(old_base_specifiers),
134         new_base_specifiers_(new_base_specifiers) {}
135 
GetOldBases()136   const std::vector<CXXBaseSpecifierIR> &GetOldBases() const {
137     return old_base_specifiers_;
138   }
139 
GetNewBases()140   const std::vector<CXXBaseSpecifierIR> &GetNewBases() const {
141     return new_base_specifiers_;
142   }
143 
144  protected:
145   const std::vector<CXXBaseSpecifierIR> &old_base_specifiers_;
146   const std::vector<CXXBaseSpecifierIR> &new_base_specifiers_;
147 };
148 
149 class RecordTypeDiffIR : public DiffMessageIR {
150  public:
Kind()151   LinkableMessageKind Kind() const override {
152     return LinkableMessageKind::RecordTypeKind;
153   }
154 
SetFieldDiffs(std::vector<RecordFieldDiffIR> && field_diffs)155   void SetFieldDiffs(std::vector<RecordFieldDiffIR> &&field_diffs) {
156     field_diffs_ = std::move(field_diffs);
157   }
158 
GetFieldDiffs()159   const std::vector<RecordFieldDiffIR> &GetFieldDiffs() const {
160     return field_diffs_;
161   }
162 
SetFieldsRemoved(std::vector<const RecordFieldIR * > && fields_removed)163   void SetFieldsRemoved(std::vector<const RecordFieldIR *> &&fields_removed) {
164     fields_removed_ = std::move(fields_removed);
165   }
166 
SetFieldsAdded(std::vector<const RecordFieldIR * > && fields_added)167   void SetFieldsAdded(std::vector<const RecordFieldIR *> &&fields_added) {
168     fields_added_ = std::move(fields_added);
169   }
170 
GetFieldsRemoved()171   const std::vector<const RecordFieldIR *> &GetFieldsRemoved() const {
172     return fields_removed_;
173   }
174 
GetFieldsAdded()175   const std::vector<const RecordFieldIR *> &GetFieldsAdded() const {
176     return fields_added_;
177   }
178 
SetVTableLayoutDiff(std::unique_ptr<VTableLayoutDiffIR> && vtable_diffs)179   void SetVTableLayoutDiff(std::unique_ptr<VTableLayoutDiffIR> &&vtable_diffs) {
180     vtable_diffs_ = std::move(vtable_diffs);
181   }
182 
SetTypeDiff(std::unique_ptr<TypeDiffIR> && type_diff)183   void SetTypeDiff(std::unique_ptr<TypeDiffIR> &&type_diff) {
184     type_diff_ = std::move(type_diff);
185   }
186 
SetAccessDiff(std::unique_ptr<AccessSpecifierDiffIR> && access_diff)187   void SetAccessDiff(std::unique_ptr<AccessSpecifierDiffIR> &&access_diff) {
188     access_diff_ = std::move(access_diff);
189   }
190 
SetBaseSpecifierDiffs(std::unique_ptr<CXXBaseSpecifierDiffIR> && base_diffs)191   void SetBaseSpecifierDiffs(
192       std::unique_ptr<CXXBaseSpecifierDiffIR> &&base_diffs) {
193     base_specifier_diffs_ = std::move(base_diffs);
194   }
195 
SetLinkerSetKey(std::string linker_set_key)196   void SetLinkerSetKey(std::string linker_set_key) {
197     linker_set_key_ = std::move(linker_set_key);
198   }
199 
SetExtended(bool is_extended)200   void SetExtended(bool is_extended) { is_extended_ = is_extended; }
201 
GetTypeDiff()202   const TypeDiffIR *GetTypeDiff() const {
203     return type_diff_.get();
204   }
205 
GetVTableLayoutDiff()206   const VTableLayoutDiffIR *GetVTableLayoutDiff() const {
207     return vtable_diffs_.get();
208   }
209 
GetBaseSpecifiers()210   const CXXBaseSpecifierDiffIR *GetBaseSpecifiers() const {
211     return base_specifier_diffs_.get();
212   }
213 
GetLinkerSetKey()214   const std::string &GetLinkerSetKey() const { return linker_set_key_; }
215 
IsExtended()216   bool IsExtended() const { return is_extended_; }
217 
218  protected:
219   // optional implemented with vector / std::unique_ptr.
220   std::unique_ptr<TypeDiffIR> type_diff_;
221   std::unique_ptr<VTableLayoutDiffIR> vtable_diffs_;
222   std::vector<RecordFieldDiffIR> field_diffs_;
223   std::vector<const RecordFieldIR *> fields_removed_;
224   std::vector<const RecordFieldIR *> fields_added_;
225   std::unique_ptr<AccessSpecifierDiffIR> access_diff_;
226   std::unique_ptr<CXXBaseSpecifierDiffIR> base_specifier_diffs_;
227   std::string linker_set_key_;
228   bool is_extended_ = false;
229 };
230 
231 class EnumFieldDiffIR {
232  public:
EnumFieldDiffIR(const EnumFieldIR * old_field,const EnumFieldIR * new_field)233   EnumFieldDiffIR(const EnumFieldIR *old_field, const EnumFieldIR *new_field)
234       : old_field_(old_field), new_field_(new_field) {}
235 
GetOldField()236   const EnumFieldIR *GetOldField() const {
237     return old_field_;
238   }
239 
GetNewField()240   const EnumFieldIR *GetNewField() const {
241     return new_field_;
242   }
243 
244  protected:
245   const EnumFieldIR *old_field_;
246   const EnumFieldIR *new_field_;
247 };
248 
249 class EnumTypeDiffIR : public DiffMessageIR {
250  public:
SetFieldsRemoved(std::vector<const EnumFieldIR * > && fields_removed)251   void SetFieldsRemoved(std::vector<const EnumFieldIR *> &&fields_removed) {
252     fields_removed_ = std::move(fields_removed);
253   }
254 
GetFieldsRemoved()255   const std::vector<const EnumFieldIR *> &GetFieldsRemoved() const {
256     return fields_removed_;
257   }
258 
SetFieldsAdded(std::vector<const EnumFieldIR * > && fields_added)259   void SetFieldsAdded(std::vector<const EnumFieldIR *> &&fields_added) {
260     fields_added_ = std::move(fields_added);
261   }
262 
GetFieldsAdded()263   const std::vector<const EnumFieldIR *> &GetFieldsAdded() const {
264     return fields_added_;
265   }
266 
SetFieldsDiff(std::vector<EnumFieldDiffIR> && fields_diff)267   void SetFieldsDiff(std::vector<EnumFieldDiffIR> &&fields_diff) {
268     fields_diff_ = std::move(fields_diff);
269   }
270 
GetFieldsDiff()271   const std::vector<EnumFieldDiffIR> &GetFieldsDiff() const {
272     return fields_diff_;
273   }
274 
SetUnderlyingTypeDiff(std::unique_ptr<std::pair<std::string,std::string>> && utype_diff)275   void SetUnderlyingTypeDiff(
276       std::unique_ptr<std::pair<std::string, std::string>> &&utype_diff) {
277     underlying_type_diff_ = std::move(utype_diff);
278   }
279 
GetUnderlyingTypeDiff()280   const std::pair<std::string, std::string> *GetUnderlyingTypeDiff() const {
281     return underlying_type_diff_.get();
282   }
283 
SetLinkerSetKey(std::string linker_set_key)284   void SetLinkerSetKey(std::string linker_set_key) {
285     linker_set_key_ = std::move(linker_set_key);
286   }
287 
GetLinkerSetKey()288   const std::string &GetLinkerSetKey() const { return linker_set_key_; }
289 
IsExtended()290   bool IsExtended() const {
291     if (fields_removed_.size() == 0 && fields_diff_.size() == 0 &&
292         fields_added_.size() != 0) {
293         return true;
294     }
295     return false;
296   }
297 
IsIncompatible()298   bool IsIncompatible() const {
299     if (fields_removed_.size() != 0 || fields_diff_.size() != 0) {
300         return true;
301     }
302     return false;
303   }
304 
Kind()305   LinkableMessageKind Kind() const override {
306     return LinkableMessageKind::EnumTypeKind;
307   }
308 
309  protected:
310   // The underlying type can only be integral, so we just need to check for
311   // referenced type.
312   std::unique_ptr<std::pair<std::string, std::string>> underlying_type_diff_;
313   std::vector<const EnumFieldIR *> fields_removed_;
314   std::vector<const EnumFieldIR *> fields_added_;
315   std::vector<EnumFieldDiffIR> fields_diff_;
316   std::string linker_set_key_;
317 };
318 
319 class GlobalVarDiffIR : public DiffMessageIR {
320  public:
Kind()321   LinkableMessageKind Kind() const override {
322     return LinkableMessageKind::GlobalVarKind;
323   }
324 
GlobalVarDiffIR(const GlobalVarIR * old_global_var,const GlobalVarIR * new_global_var)325   GlobalVarDiffIR(const GlobalVarIR *old_global_var,
326                   const GlobalVarIR *new_global_var)
327       : old_global_var_(old_global_var), new_global_var_(new_global_var) {}
328 
GetOldGlobalVar()329   const GlobalVarIR *GetOldGlobalVar() const {
330     return old_global_var_;
331   }
332 
GetNewGlobalVar()333   const GlobalVarIR *GetNewGlobalVar() const {
334     return new_global_var_;
335   }
336 
337  protected:
338   const GlobalVarIR *old_global_var_;
339   const GlobalVarIR *new_global_var_;
340 };
341 
342 class FunctionDiffIR : public DiffMessageIR {
343  public:
FunctionDiffIR(const FunctionIR * old_function,const FunctionIR * new_function,bool is_extended)344   FunctionDiffIR(const FunctionIR *old_function, const FunctionIR *new_function,
345                  bool is_extended)
346       : old_function_(old_function),
347         new_function_(new_function),
348         is_extended_(is_extended) {}
349 
Kind()350   LinkableMessageKind Kind() const override {
351     return LinkableMessageKind::FunctionKind;
352   }
353 
GetOldFunction()354   const FunctionIR *GetOldFunction() const {
355     return old_function_;
356   }
357 
GetNewFunction()358   const FunctionIR *GetNewFunction() const {
359     return new_function_;
360   }
361 
IsExtended()362   bool IsExtended() const { return is_extended_; }
363 
364  protected:
365   const FunctionIR *old_function_;
366   const FunctionIR *new_function_;
367   const bool is_extended_;
368 };
369 
370 
371 }  // namespace repr
372 }  // namespace header_checker
373 
374 
375 #endif  // HEADER_CHECKER_REPR_IR_DIFF_REPRESENTATION_H_
376