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:
52   static std::unique_ptr<IRReader> CreateIRReader(
53       TextFormatIR text_format,
54       const std::set<std::string> *exported_headers = nullptr);
55 
IRReader(const std::set<std::string> * exported_headers)56   IRReader(const std::set<std::string> *exported_headers)
57       : module_(new ModuleIR(exported_headers)) {}
58 
~IRReader()59   virtual ~IRReader() {}
60 
61   bool ReadDump(const std::string &dump_file);
62 
GetModule()63   ModuleIR &GetModule() {
64     return *module_;
65   }
66 
TakeModule()67   std::unique_ptr<ModuleIR> TakeModule() {
68     return std::move(module_);
69   }
70 
71   void MergeGraphs(const IRReader &addend);
72 
73  private:
74   virtual bool ReadDumpImpl(const std::string &dump_file) = 0;
75 
76   void MergeCFunctionLikeDeps(
77       const IRReader &addend, CFunctionLikeIR *cfunction_like_ir,
78       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
79 
80   MergeStatus MergeFunctionType(
81       const FunctionTypeIR *addend_node, const IRReader &addend,
82       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
83 
84   MergeStatus MergeEnumType(
85       const EnumTypeIR *addend_node, const IRReader &addend,
86       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
87 
88   void MergeEnumDependencies(
89       const IRReader &addend, EnumTypeIR *added_node,
90       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
91 
92   MergeStatus MergeRecordAndDependencies(
93       const RecordTypeIR *addend_node, const IRReader &addend,
94       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
95 
96   void MergeRecordDependencies(
97       const IRReader &addend, RecordTypeIR *added_node,
98       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
99 
100   void MergeRecordFields(
101       const IRReader &addend, RecordTypeIR *added_node,
102       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
103 
104   void MergeRecordCXXBases(
105       const IRReader &addend, RecordTypeIR *added_node,
106       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
107 
108   void MergeRecordTemplateElements(
109       const IRReader &addend, RecordTypeIR *added_node,
110       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
111 
112   void MergeGlobalVariable(
113       const GlobalVarIR *addend_node, const IRReader &addend,
114       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
115 
116   void MergeGlobalVariables(
117       const IRReader &addend,
118       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
119 
120   void MergeFunctionDeps(
121       FunctionIR *added_node, const IRReader &addend,
122       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
123 
124   void MergeFunction(
125       const FunctionIR *addend_node, const IRReader &addend,
126       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
127 
128   template <typename T>
129   MergeStatus MergeReferencingTypeInternalAndUpdateParent(
130       const IRReader &addend, const T *addend_node,
131       AbiElementMap<MergeStatus> *local_to_global_type_id_map,
132       AbiElementMap<T> *parent_map, const std::string &updated_self_type_id);
133 
134   MergeStatus MergeReferencingTypeInternal(
135       const IRReader &addend, ReferencesOtherType *references_type,
136       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
137 
138   MergeStatus MergeReferencingType(
139       const IRReader &addend, const TypeIR *addend_node,
140       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
141 
142   template <typename T>
143   std::pair<MergeStatus, typename AbiElementMap<T>::iterator>
144   UpdateUDTypeAccounting(
145       const T *addend_node, const IRReader &addend,
146       AbiElementMap<MergeStatus> *local_to_global_type_id_map,
147       AbiElementMap<T> *specific_type_map);
148 
149   MergeStatus MergeBuiltinType(
150       const BuiltinTypeIR *builtin_type, const IRReader &addend,
151       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
152 
153   MergeStatus LookupUserDefinedType(
154       const TypeIR *ud_type, const IRReader &addend,
155       const std::string &ud_type_unique_id,
156       AbiElementMap<MergeStatus> *local_to_global_type_id_map_);
157 
158   MergeStatus LookupType(
159       const TypeIR *addend_node, const IRReader &addend,
160       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
161 
162   MergeStatus MergeTypeInternal(
163       const TypeIR *addend_node, const IRReader &addend,
164       AbiElementMap<MergeStatus> *local_to_global_type_id_map);
165 
166   MergeStatus MergeType(
167       const TypeIR *addend_type, const IRReader &addend,
168       AbiElementMap<MergeStatus> *merged_types_cache);
169 
170   std::string AllocateNewTypeId(const std::string &addend_type_id,
171                                 const ModuleIR &addend_module);
172 
173  protected:
174   std::unique_ptr<ModuleIR> module_;
175 
176   uint64_t max_type_id_ = 0;
177 };
178 
179 
180 }  // namespace repr
181 }  // namespace header_checker
182 
183 
184 #endif  // HEADER_CHECKER_REPR_IR_READER_H_
185