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