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