xref: /aosp_15_r20/development/vndk/tools/header-checker/src/repr/protobuf/ir_reader.cpp (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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 #include "repr/protobuf/ir_reader.h"
16 
17 #include "repr/ir_representation_internal.h"
18 #include "repr/protobuf/api.h"
19 #include "repr/protobuf/converter.h"
20 
21 #include <fstream>
22 #include <memory>
23 
24 #include <google/protobuf/text_format.h>
25 #include <llvm/Support/raw_ostream.h>
26 
27 
28 namespace header_checker {
29 namespace repr {
30 
31 
ReadTypeInfo(const abi_dump::BasicNamedAndTypedDecl & type_info,TypeIR * typep)32 void ProtobufIRReader::ReadTypeInfo(
33     const abi_dump::BasicNamedAndTypedDecl &type_info, TypeIR *typep) {
34   typep->SetLinkerSetKey(type_info.linker_set_key());
35   typep->SetName(type_info.name());
36   typep->SetSourceFile(type_info.source_file());
37   typep->SetReferencedType(type_info.referenced_type());
38   typep->SetSelfType(type_info.self_type());
39   typep->SetSize(type_info.size());
40   typep->SetAlignment(type_info.alignment());
41 }
42 
ReadAvailabilityAttrs(const google::protobuf::RepeatedPtrField<abi_dump::AvailabilityAttr> & attrs_protobuf,HasAvailabilityAttrs * decl_ir)43 static void ReadAvailabilityAttrs(
44     const google::protobuf::RepeatedPtrField<abi_dump::AvailabilityAttr>
45         &attrs_protobuf,
46     HasAvailabilityAttrs *decl_ir) {
47   for (const abi_dump::AvailabilityAttr &attr_protobuf : attrs_protobuf) {
48     AvailabilityAttrIR attr;
49     if (attr_protobuf.has_introduced_major()) {
50       attr.SetIntroduced(attr_protobuf.introduced_major());
51     }
52     if (attr_protobuf.has_deprecated_major()) {
53       attr.SetDeprecated(attr_protobuf.deprecated_major());
54     }
55     if (attr_protobuf.has_obsoleted_major()) {
56       attr.SetObsoleted(attr_protobuf.obsoleted_major());
57     }
58     attr.SetUnavailable(attr_protobuf.unavailable());
59     decl_ir->AddAvailabilityAttr(std::move(attr));
60   }
61 }
62 
ReadDumpImpl(const std::string & dump_file)63 bool ProtobufIRReader::ReadDumpImpl(const std::string &dump_file) {
64   abi_dump::TranslationUnit tu;
65   std::ifstream input(dump_file);
66   google::protobuf::io::IstreamInputStream text_is(&input);
67 
68   if (!google::protobuf::TextFormat::Parse(&text_is, &tu)) {
69     llvm::errs() << "Failed to parse protobuf TextFormat file\n";
70     return false;
71   }
72   ReadFunctions(tu);
73   ReadGlobalVariables(tu);
74 
75   ReadEnumTypes(tu);
76   ReadRecordTypes(tu);
77   ReadFunctionTypes(tu);
78   ReadArrayTypes(tu);
79   ReadPointerTypes(tu);
80   ReadQualifiedTypes(tu);
81   ReadBuiltinTypes(tu);
82   ReadLvalueReferenceTypes(tu);
83   ReadRvalueReferenceTypes(tu);
84 
85   ReadElfFunctions(tu);
86   ReadElfObjects(tu);
87   return true;
88 }
89 
TemplateInfoProtobufToIR(const abi_dump::TemplateInfo & template_info_protobuf)90 TemplateInfoIR ProtobufIRReader::TemplateInfoProtobufToIR(
91     const abi_dump::TemplateInfo &template_info_protobuf) {
92   TemplateInfoIR template_info_ir;
93   for (auto &&template_element : template_info_protobuf.elements()) {
94     TemplateElementIR template_element_ir(template_element.referenced_type());
95     template_info_ir.AddTemplateElement(std::move(template_element_ir));
96   }
97   return template_info_ir;
98 }
99 
100 template <typename T>
SetupCFunctionLikeIR(const T & cfunction_like_protobuf,CFunctionLikeIR * cfunction_like_ir)101 static void SetupCFunctionLikeIR(const T &cfunction_like_protobuf,
102                                  CFunctionLikeIR *cfunction_like_ir) {
103   cfunction_like_ir->SetReturnType(cfunction_like_protobuf.return_type());
104   for (auto &&parameter: cfunction_like_protobuf.parameters()) {
105     ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(),
106                      false);
107     cfunction_like_ir->AddParameter(std::move(param_ir));
108   }
109 }
110 
FunctionProtobufToIR(const abi_dump::FunctionDecl & function_protobuf)111 FunctionIR ProtobufIRReader::FunctionProtobufToIR(
112     const abi_dump::FunctionDecl &function_protobuf) {
113   FunctionIR function_ir;
114   function_ir.SetReturnType(function_protobuf.return_type());
115   function_ir.SetLinkerSetKey(function_protobuf.linker_set_key());
116   function_ir.SetName(function_protobuf.function_name());
117   function_ir.SetAccess(AccessProtobufToIR(function_protobuf.access()));
118   function_ir.SetSourceFile(function_protobuf.source_file());
119   // Set parameters
120   for (auto &&parameter: function_protobuf.parameters()) {
121     ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(),
122                      parameter.is_this_ptr());
123     function_ir.AddParameter(std::move(param_ir));
124   }
125   // Set Template info
126   function_ir.SetTemplateInfo(
127       TemplateInfoProtobufToIR(function_protobuf.template_info()));
128   ReadAvailabilityAttrs(function_protobuf.availability_attrs(), &function_ir);
129   return function_ir;
130 }
131 
FunctionTypeProtobufToIR(const abi_dump::FunctionType & function_type_protobuf)132 FunctionTypeIR ProtobufIRReader::FunctionTypeProtobufToIR(
133     const abi_dump::FunctionType &function_type_protobuf) {
134   FunctionTypeIR function_type_ir;
135   ReadTypeInfo(function_type_protobuf.type_info(), &function_type_ir);
136   SetupCFunctionLikeIR(function_type_protobuf, &function_type_ir);
137   return function_type_ir;
138 }
139 
VTableLayoutProtobufToIR(const abi_dump::VTableLayout & vtable_layout_protobuf)140 VTableLayoutIR ProtobufIRReader::VTableLayoutProtobufToIR(
141     const abi_dump::VTableLayout &vtable_layout_protobuf) {
142   VTableLayoutIR vtable_layout_ir;
143   for (auto &&vtable_component : vtable_layout_protobuf.vtable_components()) {
144     VTableComponentIR vtable_component_ir(
145         vtable_component.mangled_component_name(),
146         VTableComponentKindProtobufToIR(vtable_component.kind()),
147         vtable_component.component_value(),
148         vtable_component.is_pure());
149     vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir));
150   }
151   return vtable_layout_ir;
152 }
153 
RecordFieldsProtobufToIR(const google::protobuf::RepeatedPtrField<abi_dump::RecordFieldDecl> & rfp)154 std::vector<RecordFieldIR> ProtobufIRReader::RecordFieldsProtobufToIR(
155     const google::protobuf::RepeatedPtrField<abi_dump::RecordFieldDecl> &rfp) {
156   std::vector<RecordFieldIR> record_type_fields_ir;
157   for (auto &&field : rfp) {
158     RecordFieldIR record_field_ir(
159         field.field_name(), field.referenced_type(), field.field_offset(),
160         AccessProtobufToIR(field.access()), field.is_bit_field(),
161         field.bit_width());
162     ReadAvailabilityAttrs(field.availability_attrs(), &record_field_ir);
163     record_type_fields_ir.emplace_back(std::move(record_field_ir));
164   }
165   return record_type_fields_ir;
166 }
167 
168 std::vector<CXXBaseSpecifierIR>
RecordCXXBaseSpecifiersProtobufToIR(const google::protobuf::RepeatedPtrField<abi_dump::CXXBaseSpecifier> & rbs)169 ProtobufIRReader::RecordCXXBaseSpecifiersProtobufToIR(
170     const google::protobuf::RepeatedPtrField<abi_dump::CXXBaseSpecifier> &rbs) {
171   std::vector<CXXBaseSpecifierIR> record_type_bases_ir;
172   for (auto &&base : rbs) {
173     CXXBaseSpecifierIR record_base_ir(
174         base.referenced_type(), base.is_virtual(),
175         AccessProtobufToIR(base.access()));
176     record_type_bases_ir.emplace_back(std::move(record_base_ir));
177   }
178   return record_type_bases_ir;
179 }
180 
RecordTypeProtobufToIR(const abi_dump::RecordType & record_type_protobuf)181 RecordTypeIR ProtobufIRReader::RecordTypeProtobufToIR(
182     const abi_dump::RecordType &record_type_protobuf) {
183   RecordTypeIR record_type_ir;
184   ReadTypeInfo(record_type_protobuf.type_info(), &record_type_ir);
185   record_type_ir.SetTemplateInfo(
186       TemplateInfoProtobufToIR(record_type_protobuf.template_info()));
187   record_type_ir.SetAccess(AccessProtobufToIR(record_type_protobuf.access()));
188   record_type_ir.SetVTableLayout(
189       VTableLayoutProtobufToIR(record_type_protobuf.vtable_layout()));
190   // Get fields
191   record_type_ir.SetRecordFields(RecordFieldsProtobufToIR(
192       record_type_protobuf.fields()));
193   // Base Specifiers
194   record_type_ir.SetCXXBaseSpecifiers(RecordCXXBaseSpecifiersProtobufToIR(
195       record_type_protobuf.base_specifiers()));
196   record_type_ir.SetRecordKind(
197       RecordKindProtobufToIR(record_type_protobuf.record_kind()));
198   record_type_ir.SetAnonymity(record_type_protobuf.is_anonymous());
199   ReadAvailabilityAttrs(record_type_protobuf.availability_attrs(),
200                         &record_type_ir);
201   return record_type_ir;
202 }
203 
EnumFieldsProtobufToIR(const google::protobuf::RepeatedPtrField<abi_dump::EnumFieldDecl> & efp)204 std::vector<EnumFieldIR> ProtobufIRReader::EnumFieldsProtobufToIR(
205     const google::protobuf::RepeatedPtrField<abi_dump::EnumFieldDecl> &efp) {
206   std::vector<EnumFieldIR> enum_type_fields_ir;
207   for (auto &&field : efp) {
208     EnumFieldIR enum_field_ir;
209     enum_field_ir.SetName(field.name());
210     // enum_field_value is declared as int64.
211     enum_field_ir.SetSignedValue(field.enum_field_value());
212     ReadAvailabilityAttrs(field.availability_attrs(), &enum_field_ir);
213     enum_type_fields_ir.emplace_back(std::move(enum_field_ir));
214   }
215   return enum_type_fields_ir;
216 }
217 
EnumTypeProtobufToIR(const abi_dump::EnumType & enum_type_protobuf)218 EnumTypeIR ProtobufIRReader::EnumTypeProtobufToIR(
219     const abi_dump::EnumType &enum_type_protobuf) {
220   EnumTypeIR enum_type_ir;
221   ReadTypeInfo(enum_type_protobuf.type_info(), &enum_type_ir);
222   enum_type_ir.SetUnderlyingType(enum_type_protobuf.underlying_type());
223   enum_type_ir.SetAccess(AccessProtobufToIR(enum_type_protobuf.access()));
224   enum_type_ir.SetFields(
225       EnumFieldsProtobufToIR(enum_type_protobuf.enum_fields()));
226   ReadAvailabilityAttrs(enum_type_protobuf.availability_attrs(), &enum_type_ir);
227   return enum_type_ir;
228 }
229 
ReadGlobalVariables(const abi_dump::TranslationUnit & tu)230 void ProtobufIRReader::ReadGlobalVariables(
231     const abi_dump::TranslationUnit &tu) {
232   for (auto &&global_variable_protobuf : tu.global_vars()) {
233     GlobalVarIR global_variable_ir;
234     global_variable_ir.SetName(global_variable_protobuf.name());
235     global_variable_ir.SetAccess(AccessProtobufToIR(global_variable_protobuf.access()));
236     global_variable_ir.SetSourceFile(global_variable_protobuf.source_file());
237     global_variable_ir.SetReferencedType(
238         global_variable_protobuf.referenced_type());
239     global_variable_ir.SetLinkerSetKey(
240         global_variable_protobuf.linker_set_key());
241     ReadAvailabilityAttrs(global_variable_protobuf.availability_attrs(),
242                           &global_variable_ir);
243     module_->AddGlobalVariable(std::move(global_variable_ir));
244   }
245 }
246 
ReadPointerTypes(const abi_dump::TranslationUnit & tu)247 void ProtobufIRReader::ReadPointerTypes(const abi_dump::TranslationUnit &tu) {
248   for (auto &&pointer_type_protobuf : tu.pointer_types()) {
249     PointerTypeIR pointer_type_ir;
250     ReadTypeInfo(pointer_type_protobuf.type_info(), &pointer_type_ir);
251     module_->AddPointerType(std::move(pointer_type_ir));
252   }
253 }
254 
ReadBuiltinTypes(const abi_dump::TranslationUnit & tu)255 void ProtobufIRReader::ReadBuiltinTypes(const abi_dump::TranslationUnit &tu) {
256   for (auto &&builtin_type_protobuf : tu.builtin_types()) {
257     BuiltinTypeIR builtin_type_ir;
258     ReadTypeInfo(builtin_type_protobuf.type_info(), &builtin_type_ir);
259     builtin_type_ir.SetSignedness(builtin_type_protobuf.is_unsigned());
260     builtin_type_ir.SetIntegralType(builtin_type_protobuf.is_integral());
261     module_->AddBuiltinType(std::move(builtin_type_ir));
262   }
263 }
264 
ReadQualifiedTypes(const abi_dump::TranslationUnit & tu)265 void ProtobufIRReader::ReadQualifiedTypes(const abi_dump::TranslationUnit &tu) {
266   for (auto &&qualified_type_protobuf : tu.qualified_types()) {
267     QualifiedTypeIR qualified_type_ir;
268     ReadTypeInfo(qualified_type_protobuf.type_info(), &qualified_type_ir);
269     qualified_type_ir.SetConstness(qualified_type_protobuf.is_const());
270     qualified_type_ir.SetVolatility(qualified_type_protobuf.is_volatile());
271     qualified_type_ir.SetRestrictedness(
272         qualified_type_protobuf.is_restricted());
273     module_->AddQualifiedType(std::move(qualified_type_ir));
274   }
275 }
276 
ReadArrayTypes(const abi_dump::TranslationUnit & tu)277 void ProtobufIRReader::ReadArrayTypes(const abi_dump::TranslationUnit &tu) {
278   for (auto &&array_type_protobuf : tu.array_types()) {
279     ArrayTypeIR array_type_ir;
280     ReadTypeInfo(array_type_protobuf.type_info(), &array_type_ir);
281     array_type_ir.SetUnknownBound(array_type_protobuf.is_of_unknown_bound());
282     module_->AddArrayType(std::move(array_type_ir));
283   }
284 }
285 
ReadLvalueReferenceTypes(const abi_dump::TranslationUnit & tu)286 void ProtobufIRReader::ReadLvalueReferenceTypes(
287     const abi_dump::TranslationUnit &tu) {
288   for (auto &&lvalue_reference_type_protobuf : tu.lvalue_reference_types()) {
289     LvalueReferenceTypeIR lvalue_reference_type_ir;
290     ReadTypeInfo(lvalue_reference_type_protobuf.type_info(),
291                  &lvalue_reference_type_ir);
292     module_->AddLvalueReferenceType(std::move(lvalue_reference_type_ir));
293   }
294 }
295 
ReadRvalueReferenceTypes(const abi_dump::TranslationUnit & tu)296 void ProtobufIRReader::ReadRvalueReferenceTypes(
297     const abi_dump::TranslationUnit &tu) {
298   for (auto &&rvalue_reference_type_protobuf : tu.rvalue_reference_types()) {
299     RvalueReferenceTypeIR rvalue_reference_type_ir;
300     ReadTypeInfo(rvalue_reference_type_protobuf.type_info(),
301                  &rvalue_reference_type_ir);
302     module_->AddRvalueReferenceType(std::move(rvalue_reference_type_ir));
303   }
304 }
305 
ReadFunctions(const abi_dump::TranslationUnit & tu)306 void ProtobufIRReader::ReadFunctions(const abi_dump::TranslationUnit &tu) {
307   for (auto &&function_protobuf : tu.functions()) {
308     FunctionIR function_ir = FunctionProtobufToIR(function_protobuf);
309     module_->AddFunction(std::move(function_ir));
310   }
311 }
312 
ReadRecordTypes(const abi_dump::TranslationUnit & tu)313 void ProtobufIRReader::ReadRecordTypes(const abi_dump::TranslationUnit &tu) {
314   for (auto &&record_type_protobuf : tu.record_types()) {
315     RecordTypeIR record_type_ir = RecordTypeProtobufToIR(record_type_protobuf);
316     module_->AddRecordType(std::move(record_type_ir));
317   }
318 }
319 
ReadFunctionTypes(const abi_dump::TranslationUnit & tu)320 void ProtobufIRReader::ReadFunctionTypes(const abi_dump::TranslationUnit &tu) {
321   for (auto &&function_type_protobuf : tu.function_types()) {
322     FunctionTypeIR function_type_ir =
323         FunctionTypeProtobufToIR(function_type_protobuf);
324     module_->AddFunctionType(std::move(function_type_ir));
325   }
326 }
327 
ReadEnumTypes(const abi_dump::TranslationUnit & tu)328 void ProtobufIRReader::ReadEnumTypes(const abi_dump::TranslationUnit &tu) {
329   for (auto &&enum_type_protobuf : tu.enum_types()) {
330     EnumTypeIR enum_type_ir = EnumTypeProtobufToIR(enum_type_protobuf);
331     module_->AddEnumType(std::move(enum_type_ir));
332   }
333 }
334 
ReadElfFunctions(const abi_dump::TranslationUnit & tu)335 void ProtobufIRReader::ReadElfFunctions(const abi_dump::TranslationUnit &tu) {
336   for (auto &&elf_function : tu.elf_functions()) {
337     ElfFunctionIR elf_function_ir(
338         elf_function.name(),
339         ElfSymbolBindingProtobufToIR(elf_function.binding()));
340     module_->AddElfFunction(std::move(elf_function_ir));
341   }
342 }
343 
ReadElfObjects(const abi_dump::TranslationUnit & tu)344 void ProtobufIRReader::ReadElfObjects(const abi_dump::TranslationUnit &tu) {
345   for (auto &&elf_object : tu.elf_objects()) {
346     ElfObjectIR elf_object_ir(
347         elf_object.name(), ElfSymbolBindingProtobufToIR(elf_object.binding()));
348     module_->AddElfObject(std::move(elf_object_ir));
349   }
350 }
351 
CreateProtobufIRReader(std::unique_ptr<ModuleIR> module_ir)352 std::unique_ptr<IRReader> CreateProtobufIRReader(
353     std::unique_ptr<ModuleIR> module_ir) {
354   return std::make_unique<ProtobufIRReader>(std::move(module_ir));
355 }
356 
357 
358 }  // namespace repr
359 }  // namespace header_checker
360