// Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "repr/ir_representation.h" namespace header_checker { namespace linker { class MergeStatus { public: MergeStatus(bool was_newly_added, const std::string &type_id) : was_newly_added_(was_newly_added), type_id_(type_id) {} MergeStatus() {} // type_id_ always has the global_type_id corresponding to the type this // MergeStatus corresponds to. For // generic reference types (pointers, qual types, l(r)value references etc), // this will be a proactively added type_id, which will be added to the // parent type_graph if the we decide to add the referencing type to the // parent post ODR checking. bool was_newly_added_ = false; std::string type_id_; }; class ModuleMerger { public: ModuleMerger(const std::set *exported_headers) : module_(new repr::ModuleIR(exported_headers)) {} const repr::ModuleIR &GetModule() { return *module_; } void MergeGraphs(const repr::ModuleIR &addend); private: void MergeCFunctionLikeDeps( const repr::ModuleIR &addend, repr::CFunctionLikeIR *cfunction_like_ir, repr::AbiElementMap *local_to_global_type_id_map); MergeStatus MergeFunctionType( const repr::FunctionTypeIR *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); MergeStatus MergeEnumType(const repr::EnumTypeIR *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); void MergeEnumDependencies( const repr::ModuleIR &addend, repr::EnumTypeIR *added_node, repr::AbiElementMap *local_to_global_type_id_map); MergeStatus MergeRecordAndDependencies( const repr::RecordTypeIR *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); void MergeRecordDependencies( const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, repr::AbiElementMap *local_to_global_type_id_map); void MergeRecordFields( const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, repr::AbiElementMap *local_to_global_type_id_map); void MergeRecordCXXBases( const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, repr::AbiElementMap *local_to_global_type_id_map); void MergeRecordTemplateElements( const repr::ModuleIR &addend, repr::RecordTypeIR *added_node, repr::AbiElementMap *local_to_global_type_id_map); void MergeGlobalVariable( const repr::GlobalVarIR *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); void MergeGlobalVariables( const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); void MergeFunctionDeps( repr::FunctionIR *added_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); void MergeFunction(const repr::FunctionIR *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); template MergeStatus MergeReferencingTypeInternalAndUpdateParent( const repr::ModuleIR &addend, const T *addend_node, repr::AbiElementMap *local_to_global_type_id_map, repr::AbiElementMap *parent_map, const std::string &updated_self_type_id); MergeStatus MergeReferencingTypeInternal( const repr::ModuleIR &addend, repr::ReferencesOtherType *references_type, repr::AbiElementMap *local_to_global_type_id_map); MergeStatus MergeReferencingType( const repr::ModuleIR &addend, const repr::TypeIR *addend_node, repr::AbiElementMap *local_to_global_type_id_map); template std::pair::iterator> UpdateUDTypeAccounting( const T *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map, repr::AbiElementMap *specific_type_map); MergeStatus MergeBuiltinType( const repr::BuiltinTypeIR *builtin_type, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); MergeStatus LookupUserDefinedType( const repr::TypeIR *ud_type, const repr::ModuleIR &addend, const std::string &ud_type_unique_id, repr::AbiElementMap *local_to_global_type_id_map_); MergeStatus LookupType(const repr::TypeIR *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); MergeStatus MergeTypeInternal( const repr::TypeIR *addend_node, const repr::ModuleIR &addend, repr::AbiElementMap *local_to_global_type_id_map); MergeStatus MergeType(const repr::TypeIR *addend_type, const repr::ModuleIR &addend, repr::AbiElementMap *merged_types_cache); private: std::unique_ptr module_; }; } // namespace linker } // namespace header_checker