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