Home | History | Annotate | Download | only in json
      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 &&parameter : 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