xref: /aosp_15_r20/development/vndk/tools/header-checker/src/linker/module_merger.h (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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