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(const std::set<std::string> * exported_headers)43 ModuleMerger(const std::set<std::string> *exported_headers) 44 : module_(new repr::ModuleIR(exported_headers)) {} 45 GetModule()46 const repr::ModuleIR &GetModule() { 47 return *module_; 48 } 49 50 void MergeGraphs(const repr::ModuleIR &addend); 51 52 private: 53 void MergeCFunctionLikeDeps( 54 const repr::ModuleIR &addend, repr::CFunctionLikeIR *cfunction_like_ir, 55 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 56 57 MergeStatus MergeFunctionType( 58 const repr::FunctionTypeIR *addend_node, const repr::ModuleIR &addend, 59 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 60 61 MergeStatus 62 MergeEnumType(const repr::EnumTypeIR *addend_node, 63 const repr::ModuleIR &addend, 64 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 65 66 void MergeEnumDependencies( 67 const repr::ModuleIR &addend, repr::EnumTypeIR *added_node, 68 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 69 70 MergeStatus MergeRecordAndDependencies( 71 const repr::RecordTypeIR *addend_node, const repr::ModuleIR &addend, 72 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 73 74 void MergeRecordDependencies( 75 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 76 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 77 78 void MergeRecordFields( 79 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 80 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 81 82 void MergeRecordCXXBases( 83 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 84 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 85 86 void MergeRecordTemplateElements( 87 const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, 88 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 89 90 void MergeGlobalVariable( 91 const repr::GlobalVarIR *addend_node, const repr::ModuleIR &addend, 92 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 93 94 void MergeGlobalVariables( 95 const repr::ModuleIR &addend, 96 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 97 98 void MergeFunctionDeps( 99 repr::FunctionIR *added_node, const repr::ModuleIR &addend, 100 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 101 102 void 103 MergeFunction(const repr::FunctionIR *addend_node, 104 const repr::ModuleIR &addend, 105 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 106 107 template <typename T> 108 MergeStatus MergeReferencingTypeInternalAndUpdateParent( 109 const repr::ModuleIR &addend, const T *addend_node, 110 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map, 111 repr::AbiElementMap<T> *parent_map, 112 const std::string &updated_self_type_id); 113 114 MergeStatus MergeReferencingTypeInternal( 115 const repr::ModuleIR &addend, repr::ReferencesOtherType *references_type, 116 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 117 118 MergeStatus MergeReferencingType( 119 const repr::ModuleIR &addend, const repr::TypeIR *addend_node, 120 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 121 122 template <typename T> 123 std::pair<MergeStatus, typename repr::AbiElementMap<T>::iterator> 124 UpdateUDTypeAccounting( 125 const T *addend_node, const repr::ModuleIR &addend, 126 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map, 127 repr::AbiElementMap<T> *specific_type_map); 128 129 MergeStatus MergeBuiltinType( 130 const repr::BuiltinTypeIR *builtin_type, const repr::ModuleIR &addend, 131 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 132 133 MergeStatus LookupUserDefinedType( 134 const repr::TypeIR *ud_type, const repr::ModuleIR &addend, 135 const std::string &ud_type_unique_id, 136 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map_); 137 138 MergeStatus 139 LookupType(const repr::TypeIR *addend_node, const repr::ModuleIR &addend, 140 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 141 142 MergeStatus MergeTypeInternal( 143 const repr::TypeIR *addend_node, const repr::ModuleIR &addend, 144 repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map); 145 146 MergeStatus MergeType(const repr::TypeIR *addend_type, 147 const repr::ModuleIR &addend, 148 repr::AbiElementMap<MergeStatus> *merged_types_cache); 149 150 private: 151 std::unique_ptr<repr::ModuleIR> module_; 152 }; 153 154 155 } // namespace linker 156 } // namespace header_checker 157