1 // Copyright (C) 2020 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 #include "repr/ir_representation.h" 16 17 18 namespace header_checker { 19 namespace linker { 20 21 22 class MergeStatus { 23 public: MergeStatus(bool was_newly_added,const std::string & type_id)24 MergeStatus(bool was_newly_added, const std::string &type_id) 25 : was_newly_added_(was_newly_added), type_id_(type_id) {} 26 MergeStatus()27 MergeStatus() {} 28 29 // type_id_ always has the global_type_id corresponding to the type this 30 // MergeStatus corresponds to. For 31 // generic reference types (pointers, qual types, l(r)value references etc), 32 // this will be a proactively added type_id, which will be added to the 33 // parent type_graph if the we decide to add the referencing type to the 34 // parent post ODR checking. 35 bool was_newly_added_ = false; 36 37 std::string type_id_; 38 }; 39 40 41 class ModuleMerger { 42 public: ModuleMerger()43 ModuleMerger() : module_(std::make_unique<repr::ModuleIR>()) {} 44 GetModule()45 const repr::ModuleIR &GetModule() { return *module_; } 46 47 void MergeGraphs(const repr::ModuleIR &addend); 48 49 private: 50 void MergeCFunctionLikeDeps( 51 const repr::ModuleIR &addend, repr::CFunctionLikeIR *cfunction_like_ir, 52 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 53 54 MergeStatus MergeFunctionType( 55 const repr::FunctionTypeIR *addend_node, const repr::ModuleIR &addend, 56 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 57 58 MergeStatus 59 MergeEnumType(const repr::EnumTypeIR *addend_node, 60 const repr::ModuleIR &addend, 61 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 62 63 void MergeEnumDependencies( 64 const repr::ModuleIR &addend, repr::EnumTypeIR *added_node, 65 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 66 67 MergeStatus MergeRecordAndDependencies( 68 const repr::RecordTypeIR *addend_node, const repr::ModuleIR &addend, 69 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 70 71 void MergeRecordDependencies( 72 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 73 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 74 75 void MergeRecordFields( 76 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 77 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 78 79 void MergeRecordCXXBases( 80 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 81 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 82 83 void MergeRecordTemplateElements( 84 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 85 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 86 87 void MergeGlobalVariable( 88 const repr::GlobalVarIR *addend_node, const repr::ModuleIR &addend, 89 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 90 91 void MergeGlobalVariables( 92 const repr::ModuleIR &addend, 93 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 94 95 void MergeFunctionDeps( 96 repr::FunctionIR *added_node, const repr::ModuleIR &addend, 97 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 98 99 void 100 MergeFunction(const repr::FunctionIR *addend_node, 101 const repr::ModuleIR &addend, 102 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 103 104 template <typename T> 105 MergeStatus MergeReferencingTypeInternalAndUpdateParent( 106 const repr::ModuleIR &addend, const T *addend_node, 107 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map, 108 repr::AbiElementMap<T> *parent_map, 109 const std::string &updated_self_type_id); 110 111 MergeStatus MergeReferencingTypeInternal( 112 const repr::ModuleIR &addend, repr::ReferencesOtherType *references_type, 113 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 114 115 MergeStatus MergeReferencingType( 116 const repr::ModuleIR &addend, const repr::TypeIR *addend_node, 117 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 118 119 template <typename T> 120 std::pair<MergeStatus, typename repr::AbiElementMap<T>::iterator> 121 UpdateUDTypeAccounting( 122 const T *addend_node, const repr::ModuleIR &addend, 123 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map, 124 repr::AbiElementMap<T> *specific_type_map); 125 126 MergeStatus MergeBuiltinType( 127 const repr::BuiltinTypeIR *builtin_type, const repr::ModuleIR &addend, 128 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 129 130 MergeStatus LookupUserDefinedType( 131 const repr::TypeIR *ud_type, const repr::ModuleIR &addend, 132 const std::string &ud_type_unique_id, 133 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map_); 134 135 MergeStatus 136 LookupType(const repr::TypeIR *addend_node, const repr::ModuleIR &addend, 137 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 138 139 MergeStatus MergeTypeInternal( 140 const repr::TypeIR *addend_node, const repr::ModuleIR &addend, 141 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 142 143 MergeStatus MergeType(const repr::TypeIR *addend_type, 144 const repr::ModuleIR &addend, 145 repr::AbiElementMap<MergeStatus> *merged_types_cache); 146 147 private: 148 std::unique_ptr<repr::ModuleIR> module_; 149 }; 150 151 152 } // namespace linker 153 } // namespace header_checker 154