• Home
  • History
  • Annotate
  • 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