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