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_PROTOBUF_CONVERTER_H_
16 #define HEADER_CHECKER_PROTOBUF_CONVERTER_H_
17
18 #include "repr/ir_diff_representation.h"
19 #include "repr/ir_representation.h"
20 #include "repr/protobuf/abi_diff.h"
21 #include "repr/protobuf/abi_dump.h"
22
23
24 namespace header_checker {
25 namespace repr {
26
27
CompatibilityStatusIRToProtobuf(CompatibilityStatusIR status)28 inline abi_diff::CompatibilityStatus CompatibilityStatusIRToProtobuf(
29 CompatibilityStatusIR status) {
30 switch (status) {
31 case CompatibilityStatusIR::Incompatible:
32 return abi_diff::CompatibilityStatus::INCOMPATIBLE;
33 case CompatibilityStatusIR::Extension:
34 return abi_diff::CompatibilityStatus::EXTENSION;
35 default:
36 break;
37 }
38 return abi_diff::CompatibilityStatus::COMPATIBLE;
39 }
40
ElfSymbolBindingIRToProtobuf(ElfSymbolIR::ElfSymbolBinding binding)41 inline abi_dump::ElfSymbolBinding ElfSymbolBindingIRToProtobuf(
42 ElfSymbolIR::ElfSymbolBinding binding) {
43 switch (binding) {
44 case ElfSymbolIR::ElfSymbolBinding::Global:
45 return abi_dump::ElfSymbolBinding::Global;
46 case ElfSymbolIR::ElfSymbolBinding::Weak:
47 return abi_dump::ElfSymbolBinding::Weak;
48 }
49 // We skip symbols of all other Bindings
50 // TODO: Add all bindings, don't leave out info
51 assert(0);
52 }
53
ElfSymbolBindingProtobufToIR(abi_dump::ElfSymbolBinding binding)54 inline ElfSymbolIR::ElfSymbolBinding ElfSymbolBindingProtobufToIR(
55 abi_dump::ElfSymbolBinding binding) {
56 switch (binding) {
57 case abi_dump::ElfSymbolBinding::Global:
58 return ElfSymbolIR::ElfSymbolBinding::Global;
59 case abi_dump::ElfSymbolBinding::Weak:
60 return ElfSymbolIR::ElfSymbolBinding::Weak;
61 }
62 // We skip symbols of all other Bindings
63 assert(0);
64 }
65
AccessIRToProtobuf(AccessSpecifierIR access)66 inline abi_dump::AccessSpecifier AccessIRToProtobuf(AccessSpecifierIR access) {
67 switch (access) {
68 case AccessSpecifierIR::ProtectedAccess:
69 return abi_dump::AccessSpecifier::protected_access;
70 case AccessSpecifierIR::PrivateAccess:
71 return abi_dump::AccessSpecifier::private_access;
72 default:
73 return abi_dump::AccessSpecifier::public_access;
74 }
75 return abi_dump::AccessSpecifier::public_access;
76 }
77
AccessProtobufToIR(abi_dump::AccessSpecifier access)78 inline AccessSpecifierIR AccessProtobufToIR(
79 abi_dump::AccessSpecifier access) {
80 switch (access) {
81 case abi_dump::AccessSpecifier::protected_access:
82 return AccessSpecifierIR::ProtectedAccess;
83 case abi_dump::AccessSpecifier::private_access:
84 return AccessSpecifierIR::PrivateAccess;
85 default:
86 return AccessSpecifierIR::PublicAccess;
87 }
88 return AccessSpecifierIR::PublicAccess;
89 }
90
RecordKindIRToProtobuf(RecordTypeIR::RecordKind kind)91 inline abi_dump::RecordKind RecordKindIRToProtobuf(
92 RecordTypeIR::RecordKind kind) {
93 switch (kind) {
94 case RecordTypeIR::RecordKind::struct_kind:
95 return abi_dump::RecordKind::struct_kind;
96
97 case RecordTypeIR::RecordKind::class_kind:
98 return abi_dump::RecordKind::class_kind;
99
100 case RecordTypeIR::RecordKind::union_kind:
101 return abi_dump::RecordKind::union_kind;
102
103 default:
104 return abi_dump::RecordKind::struct_kind;
105 }
106 // Should not be reached
107 assert(false);
108 }
109
RecordKindProtobufToIR(abi_dump::RecordKind kind)110 inline RecordTypeIR::RecordKind RecordKindProtobufToIR(
111 abi_dump::RecordKind kind) {
112 switch (kind) {
113 case abi_dump::RecordKind::struct_kind:
114 return RecordTypeIR::struct_kind;
115
116 case abi_dump::RecordKind::class_kind:
117 return RecordTypeIR::class_kind;
118
119 case abi_dump::RecordKind::union_kind:
120 return RecordTypeIR::union_kind;
121
122 default:
123 return RecordTypeIR::struct_kind;
124 }
125 // Should not be reached
126 assert(false);
127 }
128
VTableComponentKindIRToProtobuf(VTableComponentIR::Kind kind)129 inline abi_dump::VTableComponent::Kind VTableComponentKindIRToProtobuf(
130 VTableComponentIR::Kind kind) {
131 switch (kind) {
132 case VTableComponentIR::Kind::VCallOffset:
133 return abi_dump::VTableComponent_Kind_VCallOffset;
134
135 case VTableComponentIR::Kind::VBaseOffset:
136 return abi_dump::VTableComponent_Kind_VBaseOffset;
137
138 case VTableComponentIR::Kind::OffsetToTop:
139 return abi_dump::VTableComponent_Kind_OffsetToTop;
140
141 case VTableComponentIR::Kind::RTTI:
142 return abi_dump::VTableComponent_Kind_RTTI;
143
144 case VTableComponentIR::Kind::FunctionPointer:
145 return abi_dump::VTableComponent_Kind_FunctionPointer;
146
147 case VTableComponentIR::Kind::CompleteDtorPointer:
148 return abi_dump::VTableComponent_Kind_CompleteDtorPointer;
149
150 case VTableComponentIR::Kind::DeletingDtorPointer:
151 return abi_dump::VTableComponent_Kind_DeletingDtorPointer;
152
153 default:
154 return abi_dump::VTableComponent_Kind_UnusedFunctionPointer;
155 }
156 // Should not be reached
157 assert(false);
158 }
159
VTableComponentKindProtobufToIR(abi_dump::VTableComponent_Kind kind)160 inline VTableComponentIR::Kind VTableComponentKindProtobufToIR(
161 abi_dump::VTableComponent_Kind kind) {
162 switch (kind) {
163 case abi_dump::VTableComponent_Kind_VCallOffset:
164 return VTableComponentIR::Kind::VCallOffset;
165
166 case abi_dump::VTableComponent_Kind_VBaseOffset:
167 return VTableComponentIR::Kind::VBaseOffset;
168
169 case abi_dump::VTableComponent_Kind_OffsetToTop:
170 return VTableComponentIR::Kind::OffsetToTop;
171
172 case abi_dump::VTableComponent_Kind_RTTI:
173 return VTableComponentIR::Kind::RTTI;
174
175 case abi_dump::VTableComponent_Kind_FunctionPointer:
176 return VTableComponentIR::Kind::FunctionPointer;
177
178 case abi_dump::VTableComponent_Kind_CompleteDtorPointer:
179 return VTableComponentIR::Kind::CompleteDtorPointer;
180
181 case abi_dump::VTableComponent_Kind_DeletingDtorPointer:
182 return VTableComponentIR::Kind::DeletingDtorPointer;
183
184 default:
185 return VTableComponentIR::Kind::UnusedFunctionPointer;
186 }
187 // Should not be reached
188 assert(false);
189 }
190
191 // Convert IR to the messages defined in abi_dump.proto.
192 class IRToProtobufConverter {
193 private:
194 static bool AddTemplateInformation(
195 abi_dump::TemplateInfo *ti, const TemplatedArtifactIR *ta);
196
197 static bool AddTypeInfo(
198 abi_dump::BasicNamedAndTypedDecl *type_info, const TypeIR *typep);
199
200 static bool AddRecordFields(
201 abi_dump::RecordType *record_protobuf, const RecordTypeIR *record_ir);
202
203 static bool AddBaseSpecifiers(
204 abi_dump::RecordType *record_protobuf, const RecordTypeIR *record_ir);
205
206 static bool AddVTableLayout(
207 abi_dump::RecordType *record_protobuf, const RecordTypeIR *record_ir);
208
209 static bool AddEnumFields(abi_dump::EnumType *enum_protobuf,
210 const EnumTypeIR *enum_ir);
211
212 public:
213 static bool ConvertRecordFieldIR(
214 abi_dump::RecordFieldDecl *record_field_protobuf,
215 const RecordFieldIR *record_field_ir);
216
217 static bool ConvertCXXBaseSpecifierIR(
218 abi_dump::CXXBaseSpecifier *base_specifier_protobuf,
219 const CXXBaseSpecifierIR &base_specifier_ir);
220
221 static bool ConvertVTableLayoutIR(
222 abi_dump::VTableLayout *vtable_layout_protobuf,
223 const VTableLayoutIR &vtable_layout_ir);
224
225 static bool ConvertEnumFieldIR(abi_dump::EnumFieldDecl *enum_field_protobuf,
226 const EnumFieldIR *enum_field_ir);
227
228 static abi_dump::EnumType ConvertEnumTypeIR(const EnumTypeIR *enump);
229
230 static abi_dump::RecordType ConvertRecordTypeIR(const RecordTypeIR *recordp);
231
232 static abi_dump::FunctionType ConvertFunctionTypeIR (
233 const FunctionTypeIR *function_typep);
234
235 template <typename CFunctionLikeMessage>
236 static bool AddFunctionParametersAndSetReturnType(
237 CFunctionLikeMessage *function_like_protobuf,
238 const CFunctionLikeIR *cfunction_like_ir);
239
240 template <typename CFunctionLikeMessage>
241 static bool AddFunctionParameters(CFunctionLikeMessage *function_protobuf,
242 const CFunctionLikeIR *cfunction_like_ir);
243
244 static abi_dump::FunctionDecl ConvertFunctionIR(const FunctionIR *functionp);
245
246 static abi_dump::GlobalVarDecl ConvertGlobalVarIR(
247 const GlobalVarIR *global_varp);
248
249 static abi_dump::PointerType ConvertPointerTypeIR(
250 const PointerTypeIR *pointerp);
251
252 static abi_dump::QualifiedType ConvertQualifiedTypeIR(
253 const QualifiedTypeIR *qualtypep);
254
255 static abi_dump::BuiltinType ConvertBuiltinTypeIR(
256 const BuiltinTypeIR *builtin_typep);
257
258 static abi_dump::ArrayType ConvertArrayTypeIR(
259 const ArrayTypeIR *array_typep);
260
261 static abi_dump::LvalueReferenceType ConvertLvalueReferenceTypeIR(
262 const LvalueReferenceTypeIR *lvalue_reference_typep);
263
264 static abi_dump::RvalueReferenceType ConvertRvalueReferenceTypeIR(
265 const RvalueReferenceTypeIR *rvalue_reference_typep);
266
267 static abi_dump::ElfFunction ConvertElfFunctionIR(
268 const ElfFunctionIR *elf_function_ir);
269
270 static abi_dump::ElfObject ConvertElfObjectIR(
271 const ElfObjectIR *elf_object_ir);
272 };
273
274 // Convert IR to the messages defined in abi_diff.proto.
275 class IRDiffToProtobufConverter {
276 private:
277 static bool AddTypeInfoDiff(
278 abi_diff::TypeInfoDiff *type_info_diff_protobuf,
279 const TypeDiffIR *type_diff_ir);
280
281 static bool AddVTableLayoutDiff(
282 abi_diff::VTableLayoutDiff *vtable_layout_diff_protobuf,
283 const VTableLayoutDiffIR *vtable_layout_diff_ir);
284
285 static bool AddBaseSpecifierDiffs(
286 abi_diff::CXXBaseSpecifierDiff *base_specifier_diff_protobuf,
287 const CXXBaseSpecifierDiffIR *base_specifier_diff_ir);
288
289 static bool AddRecordFields(
290 abi_diff::RecordTypeDiff *record_diff_protobuf,
291 const std::vector<const RecordFieldIR *> &record_fields_removed_ir,
292 bool removed);
293
294 static bool AddRecordFieldDiffs(
295 abi_diff::RecordTypeDiff *record_diff_protobuf,
296 const std::vector<RecordFieldDiffIR> &record_field_diff_ir);
297
298 static bool AddEnumUnderlyingTypeDiff(
299 abi_diff::UnderlyingTypeDiff *underlying_type_diff_protobuf,
300 const std::pair<std::string, std::string> *underlying_type_diff_ir);
301
302 public:
303 static abi_diff::RecordTypeDiff ConvertRecordTypeDiffIR(
304 const RecordTypeDiffIR *record_type_diffp);
305
306 static abi_diff::EnumTypeDiff ConvertEnumTypeDiffIR(
307 const EnumTypeDiffIR *enum_type_diffp);
308
309 static abi_diff::FunctionDeclDiff ConvertFunctionDiffIR(
310 const FunctionDiffIR *function_diffp);
311
312 static abi_diff::GlobalVarDeclDiff ConvertGlobalVarDiffIR(
313 const GlobalVarDiffIR *global_var_diffp);
314 };
315
316
317 } // namespace repr
318 } // namespace header_checker
319
320
321 #endif // HEADER_CHECKER_PROTOBUF_CONVERTER_H_
322