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