xref: /aosp_15_r20/development/vndk/tools/header-checker/src/repr/json/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/json/ir_reader.h"
16 
17 #include "repr/ir_dumper.h"
18 #include "repr/ir_reader.h"
19 #include "repr/ir_representation_internal.h"
20 #include "repr/json/api.h"
21 #include "repr/json/converter.h"
22 
23 #include <json/reader.h>
24 #include <json/writer.h>
25 
26 #include <llvm/Support/raw_ostream.h>
27 
28 #include <cstdlib>
29 #include <fstream>
30 #include <sstream>
31 #include <string>
32 
33 
34 namespace header_checker {
35 namespace repr {
36 
37 
38 static const std::map<std::string, AccessSpecifierIR>
39     access_json_to_ir(CreateInverseMap(access_ir_to_json));
40 
41 static const std::map<std::string, RecordTypeIR::RecordKind>
42     record_kind_json_to_ir(CreateInverseMap(record_kind_ir_to_json));
43 
44 static const std::map<std::string, VTableComponentIR::Kind>
45     vtable_component_kind_json_to_ir(
46         CreateInverseMap(vtable_component_kind_ir_to_json));
47 
48 static const std::map<std::string, ElfSymbolIR::ElfSymbolBinding>
49     elf_symbol_binding_json_to_ir(
50         CreateInverseMap(elf_symbol_binding_ir_to_json));
51 
52 
JsonObjectRef(const Json::Value & json_value,bool & ok)53 JsonObjectRef::JsonObjectRef(const Json::Value &json_value, bool &ok)
54     : object_(json_value.isObject() ? json_value : json_empty_object), ok_(ok) {
55   if (!json_value.isObject()) {
56     ok_ = false;
57   }
58 }
59 
IsMember(const std::string & key) const60 bool JsonObjectRef::IsMember(const std::string &key) const {
61   return object_.isMember(key);
62 }
63 
64 const Json::Value &
Get(const std::string & key,const Json::Value & default_value,IsExpectedJsonType is_expected_type) const65 JsonObjectRef::Get(const std::string &key, const Json::Value &default_value,
66                    IsExpectedJsonType is_expected_type) const {
67   if (!object_.isMember(key)) {
68     return default_value;
69   }
70   const Json::Value &value = object_[key];
71   if (!(value.*is_expected_type)()) {
72     ok_ = false;
73     return default_value;
74   }
75   return value;
76 }
77 
GetBool(const std::string & key) const78 bool JsonObjectRef::GetBool(const std::string &key) const {
79   return Get(key, json_false, &Json::Value::isBool).asBool();
80 }
81 
GetInt(const std::string & key) const82 int64_t JsonObjectRef::GetInt(const std::string &key) const {
83   return Get(key, json_0, &Json::Value::isInt64).asInt64();
84 }
85 
GetUint(const std::string & key) const86 uint64_t JsonObjectRef::GetUint(const std::string &key) const {
87   return Get(key, json_0, &Json::Value::isUInt64).asUInt64();
88 }
89 
GetIntegralValue(const std::string & key) const90 const Json::Value &JsonObjectRef::GetIntegralValue(
91     const std::string &key) const {
92   return Get(key, json_0, &Json::Value::isIntegral);
93 }
94 
GetString(const std::string & key) const95 std::string JsonObjectRef::GetString(const std::string &key) const {
96   return Get(key, json_empty_string, &Json::Value::isString).asString();
97 }
98 
GetString(const std::string & key,const std::string & default_value) const99 std::string JsonObjectRef::GetString(const std::string &key,
100                                      const std::string &default_value) const {
101   return Get(key, Json::Value(default_value), &Json::Value::isString)
102       .asString();
103 }
104 
GetObject(const std::string & key) const105 JsonObjectRef JsonObjectRef::GetObject(const std::string &key) const {
106   return JsonObjectRef(Get(key, json_empty_object, &Json::Value::isObject),
107                        ok_);
108 }
109 
110 JsonArrayRef<JsonObjectRef>
GetObjects(const std::string & key) const111 JsonObjectRef::GetObjects(const std::string &key) const {
112   return JsonArrayRef<JsonObjectRef>(
113       Get(key, json_empty_array, &Json::Value::isArray), ok_);
114 }
115 
116 JsonArrayRef<std::string>
GetStrings(const std::string & key) const117 JsonObjectRef::GetStrings(const std::string &key) const {
118   return JsonArrayRef<std::string>(
119       Get(key, json_empty_array, &Json::Value::isArray), ok_);
120 }
121 
122 template <>
operator *() const123 JsonObjectRef JsonArrayRef<JsonObjectRef>::Iterator::operator*() const {
124   return JsonObjectRef(array_[index_], ok_);
125 }
126 
operator *() const127 template <> std::string JsonArrayRef<std::string>::Iterator::operator*() const {
128   return array_[index_].asString();
129 }
130 
GetAccess(const JsonObjectRef & type_decl)131 static AccessSpecifierIR GetAccess(const JsonObjectRef &type_decl) {
132   std::string access(type_decl.GetString("access"));
133   if (access.empty()) {
134     return default_access_ir;
135   }
136   return FindInMap(access_json_to_ir, access,
137                    "Failed to convert JSON to AccessSpecifierIR");
138 }
139 
140 static RecordTypeIR::RecordKind
GetRecordKind(const JsonObjectRef & record_type)141 GetRecordKind(const JsonObjectRef &record_type) {
142   std::string kind(record_type.GetString("record_kind"));
143   if (kind.empty()) {
144     return default_record_kind_ir;
145   }
146   return FindInMap(record_kind_json_to_ir, kind,
147                    "Failed to convert JSON to RecordKind");
148 }
149 
150 static VTableComponentIR::Kind
GetVTableComponentKind(const JsonObjectRef & vtable_component)151 GetVTableComponentKind(const JsonObjectRef &vtable_component) {
152   std::string kind(vtable_component.GetString("kind"));
153   if (kind.empty()) {
154     return default_vtable_component_kind_ir;
155   }
156   return FindInMap(vtable_component_kind_json_to_ir, kind,
157                    "Failed to convert JSON to VTableComponentIR::Kind");
158 }
159 
160 static ElfSymbolIR::ElfSymbolBinding
GetElfSymbolBinding(const JsonObjectRef & elf_symbol)161 GetElfSymbolBinding(const JsonObjectRef &elf_symbol) {
162   std::string binding(elf_symbol.GetString("binding"));
163   if (binding.empty()) {
164     return default_elf_symbol_binding_ir;
165   }
166   return FindInMap(elf_symbol_binding_json_to_ir, binding,
167                    "Failed to convert JSON to ElfSymbolBinding");
168 }
169 
ReadDumpImpl(const std::string & dump_file)170 bool JsonIRReader::ReadDumpImpl(const std::string &dump_file) {
171   Json::Value tu_json;
172   Json::CharReaderBuilder builder;
173   builder["collectComments"] = false;
174   std::ifstream input(dump_file);
175 
176   std::string errorMessage;
177   if (!Json::parseFromStream(builder, input, &tu_json, &errorMessage)) {
178     llvm::errs() << "Failed to parse JSON: " << errorMessage << "\n";
179     return false;
180   }
181   bool ok = true;
182   JsonObjectRef tu(tu_json, ok);
183   if (!ok) {
184     llvm::errs() << "Translation unit is not an object\n";
185     return false;
186   }
187 
188   ReadFunctions(tu);
189   ReadGlobalVariables(tu);
190   ReadEnumTypes(tu);
191   ReadRecordTypes(tu);
192   ReadFunctionTypes(tu);
193   ReadArrayTypes(tu);
194   ReadPointerTypes(tu);
195   ReadQualifiedTypes(tu);
196   ReadBuiltinTypes(tu);
197   ReadLvalueReferenceTypes(tu);
198   ReadRvalueReferenceTypes(tu);
199   ReadElfFunctions(tu);
200   ReadElfObjects(tu);
201   if (!ok) {
202     llvm::errs() << "Failed to convert JSON to IR\n";
203     return false;
204   }
205   return true;
206 }
207 
ReadTemplateInfo(const JsonObjectRef & type_decl,TemplatedArtifactIR * template_ir)208 void JsonIRReader::ReadTemplateInfo(const JsonObjectRef &type_decl,
209                                     TemplatedArtifactIR *template_ir) {
210   TemplateInfoIR template_info_ir;
211   for (auto &&referenced_type : type_decl.GetStrings("template_args")) {
212     TemplateElementIR template_element_ir(referenced_type);
213     template_info_ir.AddTemplateElement(std::move(template_element_ir));
214   }
215   template_ir->SetTemplateInfo(std::move(template_info_ir));
216 }
217 
ReadTypeInfo(const JsonObjectRef & type_decl,TypeIR * type_ir)218 void JsonIRReader::ReadTypeInfo(const JsonObjectRef &type_decl,
219                                 TypeIR *type_ir) {
220   // LinkableMessageIR
221   type_ir->SetSourceFile(type_decl.GetString("source_file"));
222   type_ir->SetLinkerSetKey(type_decl.GetString("linker_set_key"));
223   // TypeIR
224   type_ir->SetName(type_decl.GetString("name"));
225   type_ir->SetSize(type_decl.GetUint("size"));
226   type_ir->SetAlignment(type_decl.GetUint("alignment"));
227   type_ir->SetSelfType(
228       type_decl.GetString("self_type", type_ir->GetLinkerSetKey()));
229   // ReferencesOtherType
230   type_ir->SetReferencedType(
231       type_decl.GetString("referenced_type", type_ir->GetSelfType()));
232 }
233 
ReadAvailabilityAttrs(const JsonObjectRef & object,HasAvailabilityAttrs * decl_ir)234 static void ReadAvailabilityAttrs(const JsonObjectRef &object,
235                                   HasAvailabilityAttrs *decl_ir) {
236   for (auto &&attr : object.GetObjects("availability_attrs")) {
237     repr::AvailabilityAttrIR attr_ir;
238     if (attr.IsMember("introduced_major")) {
239       attr_ir.SetIntroduced(attr.GetUint("introduced_major"));
240     }
241     if (attr.IsMember("deprecated_major")) {
242       attr_ir.SetDeprecated(attr.GetUint("deprecated_major"));
243     }
244     if (attr.IsMember("obsoleted_major")) {
245       attr_ir.SetObsoleted(attr.GetUint("obsoleted_major"));
246     }
247     attr_ir.SetUnavailable(attr.GetBool("unavailable"));
248     decl_ir->AddAvailabilityAttr(std::move(attr_ir));
249   }
250 }
251 
ReadRecordFields(const JsonObjectRef & record_type,RecordTypeIR * record_ir)252 void JsonIRReader::ReadRecordFields(const JsonObjectRef &record_type,
253                                     RecordTypeIR *record_ir) {
254   for (auto &&field : record_type.GetObjects("fields")) {
255     RecordFieldIR record_field_ir(
256         field.GetString("field_name"), field.GetString("referenced_type"),
257         field.GetUint("field_offset"), GetAccess(field),
258         field.GetBool("is_bit_field"), field.GetUint("bit_width"));
259     ReadAvailabilityAttrs(field, &record_field_ir);
260     record_ir->AddRecordField(std::move(record_field_ir));
261   }
262 }
263 
ReadBaseSpecifiers(const JsonObjectRef & record_type,RecordTypeIR * record_ir)264 void JsonIRReader::ReadBaseSpecifiers(const JsonObjectRef &record_type,
265                                       RecordTypeIR *record_ir) {
266   for (auto &&base_specifier : record_type.GetObjects("base_specifiers")) {
267     CXXBaseSpecifierIR record_base_ir(
268         base_specifier.GetString("referenced_type"),
269         base_specifier.GetBool("is_virtual"), GetAccess(base_specifier));
270     record_ir->AddCXXBaseSpecifier(std::move(record_base_ir));
271   }
272 }
273 
ReadVTableLayout(const JsonObjectRef & record_type,RecordTypeIR * record_ir)274 void JsonIRReader::ReadVTableLayout(const JsonObjectRef &record_type,
275                                     RecordTypeIR *record_ir) {
276   VTableLayoutIR vtable_layout_ir;
277   for (auto &&vtable_component : record_type.GetObjects("vtable_components")) {
278     VTableComponentIR vtable_component_ir(
279         vtable_component.GetString("mangled_component_name"),
280         GetVTableComponentKind(vtable_component),
281         vtable_component.GetInt("component_value"),
282         vtable_component.GetBool("is_pure"));
283     vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir));
284   }
285   record_ir->SetVTableLayout(std::move(vtable_layout_ir));
286 }
287 
ReadEnumFields(const JsonObjectRef & enum_type,EnumTypeIR * enum_ir)288 void JsonIRReader::ReadEnumFields(const JsonObjectRef &enum_type,
289                                   EnumTypeIR *enum_ir) {
290   for (auto &&field : enum_type.GetObjects("enum_fields")) {
291     EnumFieldIR enum_field_ir;
292     enum_field_ir.SetName(field.GetString("name"));
293     const Json::Value &value = field.GetIntegralValue("enum_field_value");
294     if (value.isUInt64()) {
295       enum_field_ir.SetUnsignedValue(value.asUInt64());
296     } else {
297       enum_field_ir.SetSignedValue(value.asInt64());
298     }
299     ReadAvailabilityAttrs(field, &enum_field_ir);
300     enum_ir->AddEnumField(std::move(enum_field_ir));
301   }
302 }
303 
ReadFunctionParametersAndReturnType(const JsonObjectRef & function,CFunctionLikeIR * function_ir)304 void JsonIRReader::ReadFunctionParametersAndReturnType(
305     const JsonObjectRef &function, CFunctionLikeIR *function_ir) {
306   function_ir->SetReturnType(function.GetString("return_type"));
307   for (auto &&parameter : function.GetObjects("parameters")) {
308     ParamIR param_ir(parameter.GetString("referenced_type"),
309                      parameter.GetBool("default_arg"),
310                      parameter.GetBool("is_this_ptr"));
311     function_ir->AddParameter(std::move(param_ir));
312   }
313 }
314 
FunctionJsonToIR(const JsonObjectRef & function)315 FunctionIR JsonIRReader::FunctionJsonToIR(const JsonObjectRef &function) {
316   FunctionIR function_ir;
317   function_ir.SetLinkerSetKey(function.GetString("linker_set_key"));
318   function_ir.SetName(function.GetString("function_name"));
319   function_ir.SetAccess(GetAccess(function));
320   function_ir.SetSourceFile(function.GetString("source_file"));
321   ReadFunctionParametersAndReturnType(function, &function_ir);
322   ReadTemplateInfo(function, &function_ir);
323   ReadAvailabilityAttrs(function, &function_ir);
324   return function_ir;
325 }
326 
327 FunctionTypeIR
FunctionTypeJsonToIR(const JsonObjectRef & function_type)328 JsonIRReader::FunctionTypeJsonToIR(const JsonObjectRef &function_type) {
329   FunctionTypeIR function_type_ir;
330   ReadTypeInfo(function_type, &function_type_ir);
331   ReadFunctionParametersAndReturnType(function_type, &function_type_ir);
332   return function_type_ir;
333 }
334 
335 RecordTypeIR
RecordTypeJsonToIR(const JsonObjectRef & record_type)336 JsonIRReader::RecordTypeJsonToIR(const JsonObjectRef &record_type) {
337   RecordTypeIR record_type_ir;
338   ReadTypeInfo(record_type, &record_type_ir);
339   ReadTemplateInfo(record_type, &record_type_ir);
340   record_type_ir.SetAccess(GetAccess(record_type));
341   ReadVTableLayout(record_type, &record_type_ir);
342   ReadRecordFields(record_type, &record_type_ir);
343   ReadBaseSpecifiers(record_type, &record_type_ir);
344   record_type_ir.SetRecordKind(GetRecordKind(record_type));
345   record_type_ir.SetAnonymity(record_type.GetBool("is_anonymous"));
346   ReadAvailabilityAttrs(record_type, &record_type_ir);
347   return record_type_ir;
348 }
349 
EnumTypeJsonToIR(const JsonObjectRef & enum_type)350 EnumTypeIR JsonIRReader::EnumTypeJsonToIR(const JsonObjectRef &enum_type) {
351   EnumTypeIR enum_type_ir;
352   ReadTypeInfo(enum_type, &enum_type_ir);
353   enum_type_ir.SetUnderlyingType(enum_type.GetString("underlying_type"));
354   enum_type_ir.SetAccess(GetAccess(enum_type));
355   ReadEnumFields(enum_type, &enum_type_ir);
356   ReadAvailabilityAttrs(enum_type, &enum_type_ir);
357   return enum_type_ir;
358 }
359 
ReadGlobalVariables(const JsonObjectRef & tu)360 void JsonIRReader::ReadGlobalVariables(const JsonObjectRef &tu) {
361   for (auto &&global_variable : tu.GetObjects("global_vars")) {
362     GlobalVarIR global_variable_ir;
363     // GlobalVarIR
364     global_variable_ir.SetName(global_variable.GetString("name"));
365     global_variable_ir.SetAccess(GetAccess(global_variable));
366     // LinkableMessageIR
367     global_variable_ir.SetSourceFile(global_variable.GetString("source_file"));
368     global_variable_ir.SetLinkerSetKey(
369         global_variable.GetString("linker_set_key"));
370     // ReferencesOtherType
371     global_variable_ir.SetReferencedType(global_variable.GetString(
372         "referenced_type", global_variable_ir.GetLinkerSetKey()));
373     ReadAvailabilityAttrs(global_variable, &global_variable_ir);
374     module_->AddGlobalVariable(std::move(global_variable_ir));
375   }
376 }
377 
ReadPointerTypes(const JsonObjectRef & tu)378 void JsonIRReader::ReadPointerTypes(const JsonObjectRef &tu) {
379   for (auto &&pointer_type : tu.GetObjects("pointer_types")) {
380     PointerTypeIR pointer_type_ir;
381     ReadTypeInfo(pointer_type, &pointer_type_ir);
382     module_->AddPointerType(std::move(pointer_type_ir));
383   }
384 }
385 
ReadBuiltinTypes(const JsonObjectRef & tu)386 void JsonIRReader::ReadBuiltinTypes(const JsonObjectRef &tu) {
387   for (auto &&builtin_type : tu.GetObjects("builtin_types")) {
388     BuiltinTypeIR builtin_type_ir;
389     ReadTypeInfo(builtin_type, &builtin_type_ir);
390     builtin_type_ir.SetSignedness(builtin_type.GetBool("is_unsigned"));
391     builtin_type_ir.SetIntegralType(builtin_type.GetBool("is_integral"));
392     module_->AddBuiltinType(std::move(builtin_type_ir));
393   }
394 }
395 
ReadQualifiedTypes(const JsonObjectRef & tu)396 void JsonIRReader::ReadQualifiedTypes(const JsonObjectRef &tu) {
397   for (auto &&qualified_type : tu.GetObjects("qualified_types")) {
398     QualifiedTypeIR qualified_type_ir;
399     ReadTypeInfo(qualified_type, &qualified_type_ir);
400     qualified_type_ir.SetConstness(qualified_type.GetBool("is_const"));
401     qualified_type_ir.SetVolatility(qualified_type.GetBool("is_volatile"));
402     qualified_type_ir.SetRestrictedness(
403         qualified_type.GetBool("is_restricted"));
404     module_->AddQualifiedType(std::move(qualified_type_ir));
405   }
406 }
407 
ReadArrayTypes(const JsonObjectRef & tu)408 void JsonIRReader::ReadArrayTypes(const JsonObjectRef &tu) {
409   for (auto &&array_type : tu.GetObjects("array_types")) {
410     ArrayTypeIR array_type_ir;
411     ReadTypeInfo(array_type, &array_type_ir);
412     array_type_ir.SetUnknownBound(array_type.GetBool("is_of_unknown_bound"));
413     module_->AddArrayType(std::move(array_type_ir));
414   }
415 }
416 
ReadLvalueReferenceTypes(const JsonObjectRef & tu)417 void JsonIRReader::ReadLvalueReferenceTypes(const JsonObjectRef &tu) {
418   for (auto &&lvalue_reference_type : tu.GetObjects("lvalue_reference_types")) {
419     LvalueReferenceTypeIR lvalue_reference_type_ir;
420     ReadTypeInfo(lvalue_reference_type, &lvalue_reference_type_ir);
421     module_->AddLvalueReferenceType(std::move(lvalue_reference_type_ir));
422   }
423 }
424 
ReadRvalueReferenceTypes(const JsonObjectRef & tu)425 void JsonIRReader::ReadRvalueReferenceTypes(const JsonObjectRef &tu) {
426   for (auto &&rvalue_reference_type : tu.GetObjects("rvalue_reference_types")) {
427     RvalueReferenceTypeIR rvalue_reference_type_ir;
428     ReadTypeInfo(rvalue_reference_type, &rvalue_reference_type_ir);
429     module_->AddRvalueReferenceType(std::move(rvalue_reference_type_ir));
430   }
431 }
432 
ReadFunctions(const JsonObjectRef & tu)433 void JsonIRReader::ReadFunctions(const JsonObjectRef &tu) {
434   for (auto &&function : tu.GetObjects("functions")) {
435     FunctionIR function_ir = FunctionJsonToIR(function);
436     module_->AddFunction(std::move(function_ir));
437   }
438 }
439 
ReadRecordTypes(const JsonObjectRef & tu)440 void JsonIRReader::ReadRecordTypes(const JsonObjectRef &tu) {
441   for (auto &&record_type : tu.GetObjects("record_types")) {
442     RecordTypeIR record_type_ir = RecordTypeJsonToIR(record_type);
443     module_->AddRecordType(std::move(record_type_ir));
444   }
445 }
446 
ReadFunctionTypes(const JsonObjectRef & tu)447 void JsonIRReader::ReadFunctionTypes(const JsonObjectRef &tu) {
448   for (auto &&function_type : tu.GetObjects("function_types")) {
449     FunctionTypeIR function_type_ir = FunctionTypeJsonToIR(function_type);
450     module_->AddFunctionType(std::move(function_type_ir));
451   }
452 }
453 
ReadEnumTypes(const JsonObjectRef & tu)454 void JsonIRReader::ReadEnumTypes(const JsonObjectRef &tu) {
455   for (auto &&enum_type : tu.GetObjects("enum_types")) {
456     EnumTypeIR enum_type_ir = EnumTypeJsonToIR(enum_type);
457     module_->AddEnumType(std::move(enum_type_ir));
458   }
459 }
460 
ReadElfFunctions(const JsonObjectRef & tu)461 void JsonIRReader::ReadElfFunctions(const JsonObjectRef &tu) {
462   for (auto &&elf_function : tu.GetObjects("elf_functions")) {
463     ElfFunctionIR elf_function_ir(elf_function.GetString("name"),
464                                   GetElfSymbolBinding(elf_function));
465     module_->AddElfFunction(std::move(elf_function_ir));
466   }
467 }
468 
ReadElfObjects(const JsonObjectRef & tu)469 void JsonIRReader::ReadElfObjects(const JsonObjectRef &tu) {
470   for (auto &&elf_object : tu.GetObjects("elf_objects")) {
471     ElfObjectIR elf_object_ir(elf_object.GetString("name"),
472                               GetElfSymbolBinding(elf_object));
473     module_->AddElfObject(std::move(elf_object_ir));
474   }
475 }
476 
CreateJsonIRReader(std::unique_ptr<ModuleIR> module_ir)477 std::unique_ptr<IRReader> CreateJsonIRReader(
478     std::unique_ptr<ModuleIR> module_ir) {
479   return std::make_unique<JsonIRReader>(std::move(module_ir));
480 }
481 
482 
483 }  // namespace repr
484 }  // header_checker
485