• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 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 #ifndef HEADER_CHECKER_REPR_IR_READER_H_
16 #define HEADER_CHECKER_REPR_IR_READER_H_
17 
18 #include "repr/ir_representation.h"
19 
20 #include <cstdint>
21 #include <list>
22 #include <memory>
23 #include <set>
24 #include <string>
25 #include <utility>
26 
27 
28 namespace header_checker {
29 namespace repr {
30 
31 
32 class IRReader {
33  public:
34   struct MergeStatus {
MergeStatusMergeStatus35     MergeStatus(bool was_newly_added, const std::string &type_id)
36         : was_newly_added_(was_newly_added), type_id_(type_id) {}
37 
MergeStatusMergeStatus38     MergeStatus() {}
39 
40     // type_id_ always has the global_type_id corresponding to the type this
41     // MergeStatus corresponds to. For
42     // generic reference types (pointers, qual types, l(r)value references etc),
43     // this will be a proactively added type_id, which will be added to the
44     // parent  type_graph if the we decide to add the referencing type to the
45     // parent post ODR checking.
46     bool was_newly_added_ = false;
47 
48     std::string type_id_;
49   };
50 
51  public:
IRReader(const std::set<std::string> * exported_headers)52   IRReader(const std::set<std::string> *exported_headers)
53       : module_(new ModuleIR(exported_headers)) {}
54 
~IRReader()55   virtual ~IRReader() {}
56 
57   virtual bool ReadDump(const std::string &dump_file) = 0;
58 
GetModule()59   ModuleIR &GetModule() {
60     return *module_;
61   }
62 
TakeModule()63   std::unique_ptr<ModuleIR> TakeModule() {
64     return std::move(module_);
65   }
66 
Merge(IRReader && addend)67   void Merge(IRReader &&addend) {
68     MergeElements(&module_->functions_, std::move(addend.module_->functions_));
69     MergeElements(&module_->global_variables_,
70                   std::move(addend.module_->global_variables_));
71     MergeElements(&module_->record_types_,
72                   std::move(addend.module_->record_types_));
73     MergeElements(&module_->enum_types_,
74                   std::move(addend.module_->enum_types_));
75     MergeElements(&module_->pointer_types_,
76                   std::move(addend.module_->pointer_types_));
77     MergeElements(&module_->lvalue_reference_types_,
78                   std::move(addend.module_->lvalue_reference_types_));
79     MergeElements(&module_->rvalue_reference_types_,
80                   std::move(addend.module_->rvalue_reference_types_));
81     MergeElements(&module_->array_types_,
82                   std::move(addend.module_->array_types_));
83     MergeElements(&module_->builtin_types_,
84                   std::move(addend.module_->builtin_types_));
85     MergeElements(&module_->qualified_types_,
86                   std::move(addend.module_->qualified_types_));
87   }
88 
89   template <typename T>
90   MergeStatus MergeReferencingTypeInternalAndUpdateParent(
91       const IRReader &addend, const T *addend_node,
92       AbiElementMap<MergeStatus> *local_to_global_type_id_map,
93       AbiElementMap<T> *parent_map, const std::string &updated_self_type_id);
94 
95   MergeStatus DoesUDTypeODRViolationExist(
96       const TypeIR *ud_type, const IRReader &addend,
97       const std::string &ud_type_unique_id,
98       AbiElementMap<MergeStatus> *local_to_global_type_id_map_);
99 
100   MergeStatus MergeReferencingTypeInternal(
101       const IRReader &addend, ReferencesOtherType *references_type,
102       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
103 
104   MergeStatus MergeReferencingType(
105       const IRReader &addend, const TypeIR *addend_node,
106       AbiElementMap<MergeStatus> *local_to_global_type_id_map,
107       const std::string &updated_self_type_id);
108 
109   MergeStatus MergeGenericReferringType(
110       const IRReader &addend, const TypeIR *addend_node,
111       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
112 
113   template <typename T>
114   std::pair<MergeStatus, typename AbiElementMap<T>::iterator>
115   UpdateUDTypeAccounting(
116       const T *addend_node, const IRReader &addend,
117       AbiElementMap<MergeStatus> *local_to_global_type_id_map,
118       AbiElementMap<T> *specific_type_map);
119 
120   MergeStatus MergeTypeInternal(
121       const TypeIR *addend_node, const IRReader &addend,
122       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
123 
124   void MergeCFunctionLikeDeps(
125       const IRReader &addend, CFunctionLikeIR *cfunction_like_ir,
126       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
127 
128   MergeStatus MergeFunctionType(
129       const FunctionTypeIR *addend_node, const IRReader &addend,
130       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
131 
132   MergeStatus MergeEnumType(
133       const EnumTypeIR *addend_node, const IRReader &addend,
134       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
135 
136   void MergeEnumDependencies(
137       const IRReader &addend, EnumTypeIR *added_node,
138       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
139 
140   MergeStatus MergeRecordAndDependencies(
141       const RecordTypeIR *addend_node, const IRReader &addend,
142       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
143 
144   void MergeRecordDependencies(
145       const IRReader &addend, RecordTypeIR *added_node,
146       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
147 
148   void MergeRecordFields(
149       const IRReader &addend, RecordTypeIR *added_node,
150       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
151 
152   void MergeRecordCXXBases(
153       const IRReader &addend, RecordTypeIR *added_node,
154       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
155 
156   void MergeRecordTemplateElements(
157       const IRReader &addend, RecordTypeIR *added_node,
158       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
159 
160   MergeStatus IsBuiltinTypeNodePresent(
161       const BuiltinTypeIR *builtin_type, const IRReader &addend,
162       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
163 
164   void MergeGlobalVariable(
165       const GlobalVarIR *addend_node, const IRReader &addend,
166       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
167 
168   void MergeGlobalVariables(
169       const IRReader &addend,
170       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
171 
172   void MergeFunctionDeps(
173       FunctionIR *added_node, const IRReader &addend,
174       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
175 
176   void MergeFunction(
177       const FunctionIR *addend_node, const IRReader &addend,
178       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
179 
180   void MergeGraphs(const IRReader &addend);
181 
182   void UpdateIRReaderTypeGraph(
183       const TypeIR *addend_node, const std::string &added_type_id,
184       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
185 
186   MergeStatus IsTypeNodePresent(
187       const TypeIR *addend_node, const IRReader &addend,
188       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
189 
190   MergeStatus MergeType(
191       const TypeIR *addend_type, const IRReader &addend,
192       AbiElementMap<MergeStatus> *merged_types_cache);
193 
194   std::string AllocateNewTypeId();
195 
196   static std::unique_ptr<IRReader> CreateIRReader(
197       TextFormatIR text_format,
198       const std::set<std::string> *exported_headers = nullptr);
199 
200  protected:
201   template <typename Augend, typename Addend>
MergeElements(Augend * augend,Addend && addend)202   inline void MergeElements(Augend *augend, Addend &&addend) {
203     augend->insert(std::make_move_iterator(addend.begin()),
204                    std::make_move_iterator(addend.end()));
205   }
206 
207   std::unique_ptr<ModuleIR> module_;
208 
209   uint64_t max_type_id_ = 0;
210 };
211 
212 
213 }  // namespace repr
214 }  // namespace header_checker
215 
216 
217 #endif  // HEADER_CHECKER_REPR_IR_READER_H_
218