diff options
| author | Logan Chien <loganchien@google.com> | 2019-03-20 09:30:55 -0700 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2019-03-20 09:30:55 -0700 |
| commit | c6d3c5d6096d6bb3c7c16a833a629fd890f69d4a (patch) | |
| tree | d0eb987ef619ca967c34484f6dfe6bc012d29077 /vndk | |
| parent | a4a93774f68c028e855d30726b3caf6f6753918f (diff) | |
| parent | 8984268c22188180de23bda067004249a5d07bfc (diff) | |
| download | android_development-c6d3c5d6096d6bb3c7c16a833a629fd890f69d4a.tar.gz android_development-c6d3c5d6096d6bb3c7c16a833a629fd890f69d4a.tar.bz2 android_development-c6d3c5d6096d6bb3c7c16a833a629fd890f69d4a.zip | |
Merge changes Ibc7a9a94,I4e8a0683,I4f741262,Ib19c9666,Ib55dc8bd, ... am: fd08ad980e am: 4881a4af11
am: 8984268c22
Change-Id: Ibeb24838055d5ea474f2f3cce9829dcb34408472
Diffstat (limited to 'vndk')
94 files changed, 7448 insertions, 6151 deletions
diff --git a/vndk/tools/header-checker/Android.bp b/vndk/tools/header-checker/Android.bp index 8edebdda1..d83bd477f 100644 --- a/vndk/tools/header-checker/Android.bp +++ b/vndk/tools/header-checker/Android.bp @@ -41,6 +41,10 @@ cc_defaults { }, }, + local_include_dirs: [ + "src", + ], + compile_multilib: "64", stl: "none", } @@ -53,18 +57,18 @@ cc_binary_host { ], srcs: [ - "header-abi-dumper/src/abi_wrappers.cpp", - "header-abi-dumper/src/ast_processing.cpp", - "header-abi-dumper/src/diagnostic_consumer.cpp", - "header-abi-dumper/src/fake_decl_source.cpp", - "header-abi-dumper/src/fixed_argv.cpp", - "header-abi-dumper/src/frontend_action.cpp", - "header-abi-dumper/src/frontend_action_factory.cpp", - "header-abi-dumper/src/header_checker.cpp", + "src/dumper/abi_wrappers.cpp", + "src/dumper/ast_processing.cpp", + "src/dumper/diagnostic_consumer.cpp", + "src/dumper/fake_decl_source.cpp", + "src/dumper/fixed_argv.cpp", + "src/dumper/frontend_action.cpp", + "src/dumper/frontend_action_factory.cpp", + "src/dumper/header_checker.cpp", ], static_libs: [ - "libheader-abi-util", + "libheader-checker", "libheader-checker-proto", "libjsoncpp", ], @@ -83,7 +87,7 @@ cc_defaults { defaults: ["header-checker-defaults"], static_libs: [ - "libheader-abi-util", + "libheader-checker", "libheader-checker-proto", "libjsoncpp", ], @@ -105,7 +109,7 @@ cc_binary_host { ], srcs: [ - "header-abi-linker/src/header_abi_linker.cpp", + "src/linker/header_abi_linker.cpp", ], } @@ -118,9 +122,9 @@ cc_binary_host { ], srcs: [ - "header-abi-diff/src/abi_diff.cpp", - "header-abi-diff/src/abi_diff_wrappers.cpp", - "header-abi-diff/src/header_abi_diff.cpp", + "src/diff/abi_diff.cpp", + "src/diff/abi_diff_wrappers.cpp", + "src/diff/header_abi_diff.cpp", ], } @@ -133,28 +137,36 @@ cc_binary_host { ], srcs: [ - "merge-abi-diff/src/merge_abi_diff.cpp", + "src/diff_merge/merge_abi_diff.cpp", ], } cc_library_host_static { - name: "libheader-abi-util", + name: "libheader-checker", defaults: [ "header-checker-defaults", ], srcs: [ - "header-abi-util/src/abi_diff_helpers.cpp", - "header-abi-util/src/api_level.cpp", - "header-abi-util/src/collect_exported_headers.cpp", - "header-abi-util/src/exported_symbol_set.cpp", - "header-abi-util/src/ir_representation.cpp", - "header-abi-util/src/ir_representation_json.cpp", - "header-abi-util/src/ir_representation_protobuf.cpp", - "header-abi-util/src/so_file_parser.cpp", - "header-abi-util/src/string_utils.cpp", - "header-abi-util/src/version_script_parser.cpp", + "src/repr/abi_diff_helpers.cpp", + "src/repr/ir_diff_dumper.cpp", + "src/repr/ir_dumper.cpp", + "src/repr/ir_reader.cpp", + "src/repr/ir_representation.cpp", + "src/repr/json/converter.cpp", + "src/repr/json/ir_dumper.cpp", + "src/repr/json/ir_reader.cpp", + "src/repr/protobuf/converter.cpp", + "src/repr/protobuf/ir_diff_dumper.cpp", + "src/repr/protobuf/ir_dumper.cpp", + "src/repr/protobuf/ir_reader.cpp", + "src/repr/symbol/exported_symbol_set.cpp", + "src/repr/symbol/so_file_parser.cpp", + "src/repr/symbol/version_script_parser.cpp", + "src/utils/api_level.cpp", + "src/utils/collect_exported_headers.cpp", + "src/utils/string_utils.cpp", ], static_libs: [ @@ -173,32 +185,26 @@ cc_library_host_static { "-Wno-long-long", "-Wno-unused-parameter", ], - - export_include_dirs: ["header-abi-util/include"], } cc_test_host { - name: "libheader-abi-util_test", + name: "header-checker-unittests", defaults: [ "header-checker-defaults", ], srcs: [ - "header-abi-util/src/api_level_test.cpp", - "header-abi-util/src/exported_symbol_set_test.cpp", - "header-abi-util/src/string_utils_test.cpp", - "header-abi-util/src/version_script_parser_test.cpp", - ], - - local_include_dirs: [ - "header-abi-util/include", + "src/repr/symbol/exported_symbol_set_test.cpp", + "src/repr/symbol/version_script_parser_test.cpp", + "src/utils/api_level_test.cpp", + "src/utils/string_utils_test.cpp", ], static_libs: [ "libgtest", "libgtest_main", - "libheader-abi-util", + "libheader-checker", ], shared_libs: [ diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h deleted file mode 100644 index 4604b0fcc..000000000 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (C) 2016 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef ABI_DIFF_H_ -#define ABI_DIFF_H_ - -#include "abi_diff_wrappers.h" -#include "ir_representation.h" - -#include <string> -#include <vector> - -using abi_util::AbiElementMap; -using abi_util::DiffPolicyOptions; - -class HeaderAbiDiff { - public: - HeaderAbiDiff(const std::string &lib_name, const std::string &arch, - const std::string &old_dump, const std::string &new_dump, - const std::string &compatibility_report, - const std::set<std::string> &ignored_symbols, - const DiffPolicyOptions &diff_policy_options, - bool check_all_apis, abi_util::TextFormatIR text_format_old, - abi_util::TextFormatIR text_format_new, - abi_util::TextFormatIR text_format_diff) - : lib_name_(lib_name), arch_(arch), old_dump_(old_dump), - new_dump_(new_dump), cr_(compatibility_report), - ignored_symbols_(ignored_symbols), - diff_policy_options_(diff_policy_options), - check_all_apis_(check_all_apis), - text_format_old_(text_format_old), text_format_new_(text_format_new), - text_format_diff_(text_format_diff) {} - - abi_util::CompatibilityStatusIR GenerateCompatibilityReport(); - - private: - abi_util::CompatibilityStatusIR CompareTUs( - const abi_util::TextFormatToIRReader *old_tu, - const abi_util::TextFormatToIRReader *new_tu, - abi_util::IRDiffDumper *ir_diff_dumper); - - template <typename T, typename ElfSymbolType> - bool CollectDynsymExportables( - const AbiElementMap<T> &old_exportables, - const AbiElementMap<T> &new_exportables, - const AbiElementMap<ElfSymbolType> &old_elf_symbols, - const AbiElementMap<ElfSymbolType> &new_elf_symbols, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map, - abi_util::IRDiffDumper *ir_diff_dumper); - - template <typename T> - bool Collect( - const AbiElementMap<const T *> &old_elements_map, - const AbiElementMap<const T *> &new_elements_map, - const AbiElementMap<const abi_util::ElfSymbolIR *> *old_elf_map, - const AbiElementMap<const abi_util::ElfSymbolIR *> *new_elf_map, - abi_util::IRDiffDumper *ir_diff_dumper, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map); - - bool CollectElfSymbols( - const AbiElementMap<const abi_util::ElfSymbolIR *> &old_symbols, - const AbiElementMap<const abi_util::ElfSymbolIR *> &new_symbols, - abi_util::IRDiffDumper *ir_diff_dumper); - - bool PopulateElfElements( - std::vector<const abi_util::ElfSymbolIR *> &elf_elements, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind); - - template <typename T> - bool PopulateRemovedElements( - const AbiElementMap<const T *> &old_elements_map, - const AbiElementMap<const T *> &new_elements_map, - const AbiElementMap<const abi_util::ElfSymbolIR *> *elf_map, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind, - const AbiElementMap<const abi_util::TypeIR *> &types_map); - - template <typename T> - bool PopulateCommonElements( - const AbiElementMap<const T *> &old_elements_map, - const AbiElementMap<const T *> &new_elements_map, - const AbiElementMap<const abi_util::TypeIR *> &old_types, - const AbiElementMap<const abi_util::TypeIR *> &new_types, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind); - - template <typename T> - bool DumpDiffElements( - std::vector<std::pair<const T *, const T *>> &pairs, - const AbiElementMap<const abi_util::TypeIR *> &old_types, - const AbiElementMap<const abi_util::TypeIR *> &new_types, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind); - - template <typename T> - bool DumpLoneElements( - std::vector<const T *> &elements, - const AbiElementMap<const abi_util::ElfSymbolIR *> *elf_map, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map); - - std::pair<AbiElementMap<const abi_util::EnumTypeIR *>, - AbiElementMap<const abi_util::RecordTypeIR *>> - ExtractUserDefinedTypes(const abi_util::TextFormatToIRReader *tu); - - bool CollectUserDefinedTypes( - const abi_util::TextFormatToIRReader *old_tu, - const abi_util::TextFormatToIRReader *new_tu, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map, - abi_util::IRDiffDumper *ir_diff_dumper); - - template <typename T> - bool CollectUserDefinedTypesInternal( - const AbiElementMap<const T*> &old_ud_types_map, - const AbiElementMap<const T*> &new_ud_types_map, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map, - abi_util::IRDiffDumper *ir_diff_dumper); - - private: - const std::string &lib_name_; - const std::string &arch_; - const std::string &old_dump_; - const std::string &new_dump_; - const std::string &cr_; - const std::set<std::string> &ignored_symbols_; - const DiffPolicyOptions &diff_policy_options_; - bool check_all_apis_; - std::set<std::string> type_cache_; - abi_util::TextFormatIR text_format_old_; - abi_util::TextFormatIR text_format_new_; - abi_util::TextFormatIR text_format_diff_; -}; - -#endif // ABI_DIFF_H_ diff --git a/vndk/tools/header-checker/header-abi-util/src/ir_representation_json.cpp b/vndk/tools/header-checker/header-abi-util/src/ir_representation_json.cpp deleted file mode 100644 index c04b33e0b..000000000 --- a/vndk/tools/header-checker/header-abi-util/src/ir_representation_json.cpp +++ /dev/null @@ -1,939 +0,0 @@ -// Copyright (C) 2018 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "ir_representation_json.h" - -#include <json/reader.h> -#include <json/writer.h> - -#include <llvm/Support/raw_ostream.h> - -#include <cstdlib> -#include <fstream> -#include <sstream> -#include <string> - -namespace abi_util { - -// Conversion between IR enums and JSON strings. -static const std::map<AccessSpecifierIR, std::string> access_ir_to_json{ - {AccessSpecifierIR::PublicAccess, "public"}, - {AccessSpecifierIR::ProtectedAccess, "protected"}, - {AccessSpecifierIR::PrivateAccess, "private"}, -}; - -static const std::map<std::string, AccessSpecifierIR> - access_json_to_ir(CreateInverseMap(access_ir_to_json)); - -static const AccessSpecifierIR default_access_ir = - AccessSpecifierIR::PublicAccess; - -static const std::map<RecordTypeIR::RecordKind, std::string> - record_kind_ir_to_json{ - {RecordTypeIR::RecordKind::struct_kind, "struct"}, - {RecordTypeIR::RecordKind::class_kind, "class"}, - {RecordTypeIR::RecordKind::union_kind, "union"}, -}; - -static const std::map<std::string, RecordTypeIR::RecordKind> - record_kind_json_to_ir(CreateInverseMap(record_kind_ir_to_json)); - -static const RecordTypeIR::RecordKind default_record_kind_ir = - RecordTypeIR::RecordKind::struct_kind; - -static const std::map<VTableComponentIR::Kind, std::string> - vtable_component_kind_ir_to_json{ - {VTableComponentIR::Kind::VCallOffset, "vcall_offset"}, - {VTableComponentIR::Kind::VBaseOffset, "vbase_offset"}, - {VTableComponentIR::Kind::OffsetToTop, "offset_to_top"}, - {VTableComponentIR::Kind::RTTI, "rtti"}, - {VTableComponentIR::Kind::FunctionPointer, "function_pointer"}, - {VTableComponentIR::Kind::CompleteDtorPointer, "complete_dtor_pointer"}, - {VTableComponentIR::Kind::DeletingDtorPointer, "deleting_dtor_pointer"}, - {VTableComponentIR::Kind::UnusedFunctionPointer, "unused_function_pointer"}, -}; - -static const std::map<std::string, VTableComponentIR::Kind> - vtable_component_kind_json_to_ir( - CreateInverseMap(vtable_component_kind_ir_to_json)); - -static const VTableComponentIR::Kind default_vtable_component_kind_ir = - VTableComponentIR::Kind::FunctionPointer; - -static const std::map<ElfSymbolIR::ElfSymbolBinding, std::string> - elf_symbol_binding_ir_to_json{ - {ElfSymbolIR::ElfSymbolBinding::Weak, "weak"}, - {ElfSymbolIR::ElfSymbolBinding::Global, "global"}, -}; - -static const std::map<std::string, ElfSymbolIR::ElfSymbolBinding> - elf_symbol_binding_json_to_ir( - CreateInverseMap(elf_symbol_binding_ir_to_json)); - -static const ElfSymbolIR::ElfSymbolBinding default_elf_symbol_binding_ir = - ElfSymbolIR::ElfSymbolBinding::Global; - -// If m contains k, this function returns the value. -// Otherwise, it prints error_msg and exits. -template <typename K, typename V> -static inline const V &FindInMap(const std::map<K, V> &m, const K &k, - const std::string &error_msg) { - auto it = m.find(k); - if (it == m.end()) { - llvm::errs() << error_msg << "\n"; - ::exit(1); - } - return it->second; -} - -static const JsonObject json_empty_object; -static const JsonArray json_empty_array; -static const Json::Value json_0(0); -static const Json::Value json_false(false); -static const Json::Value json_empty_string(""); - -void JsonObject::Set(const std::string &key, bool value) { - SetOmissible(key, value, false); -} - -void JsonObject::Set(const std::string &key, uint64_t value) { - SetOmissible<Json::UInt64>(key, value, 0); -} - -void JsonObject::Set(const std::string &key, int64_t value) { - SetOmissible<Json::Int64>(key, value, 0); -} - -void JsonObject::Set(const std::string &key, const std::string &value) { - SetOmissible<const std::string &>(key, value, ""); -} - -void JsonObject::Set(const std::string &key, const JsonArray &value) { - SetOmissible(key, value, json_empty_array); -} - -static void AddAccess(JsonObject &type_decl, AccessSpecifierIR value) { - if (value != default_access_ir) { - type_decl.Set("access", - FindInMap(access_ir_to_json, value, - "Failed to convert AccessSpecifierIR to JSON")); - } -} - -static void AddRecordKind(JsonObject &record_type, - RecordTypeIR::RecordKind value) { - if (value != default_record_kind_ir) { - record_type.Set("record_kind", - FindInMap(record_kind_ir_to_json, value, - "Failed to convert RecordKind to JSON")); - } -} - -static void AddVtableComponentKind(JsonObject &vtable_component, - VTableComponentIR::Kind value) { - if (value != default_vtable_component_kind_ir) { - vtable_component.Set( - "kind", FindInMap(vtable_component_kind_ir_to_json, value, - "Failed to convert VTableComponentIR::Kind to JSON")); - } -} - -static void AddElfSymbolBinding(JsonObject &elf_symbol, - ElfSymbolIR::ElfSymbolBinding value) { - if (value != default_elf_symbol_binding_ir) { - elf_symbol.Set("binding", - FindInMap(elf_symbol_binding_ir_to_json, value, - "Failed to convert ElfSymbolBinding to JSON")); - } -} - -void IRToJsonConverter::AddTemplateInfo( - JsonObject &type_decl, const TemplatedArtifactIR *template_ir) { - JsonArray args; - for (auto &&template_element_ir : template_ir->GetTemplateElements()) { - args.append(template_element_ir.GetReferencedType()); - } - type_decl.Set("template_args", args); -} - -void IRToJsonConverter::AddTypeInfo(JsonObject &type_decl, - const TypeIR *type_ir) { - type_decl.Set("linker_set_key", type_ir->GetLinkerSetKey()); - type_decl.Set("source_file", type_ir->GetSourceFile()); - type_decl.Set("name", type_ir->GetName()); - type_decl.Set("size", (uint64_t)type_ir->GetSize()); - type_decl.Set("alignment", (uint64_t)type_ir->GetAlignment()); - type_decl.Set("referenced_type", type_ir->GetReferencedType()); - type_decl.Set("self_type", type_ir->GetSelfType()); -} - -static JsonObject ConvertRecordFieldIR(const RecordFieldIR *record_field_ir) { - JsonObject record_field; - record_field.Set("field_name", record_field_ir->GetName()); - record_field.Set("referenced_type", record_field_ir->GetReferencedType()); - AddAccess(record_field, record_field_ir->GetAccess()); - record_field.Set("field_offset", (uint64_t)record_field_ir->GetOffset()); - return record_field; -} - -void IRToJsonConverter::AddRecordFields(JsonObject &record_type, - const RecordTypeIR *record_ir) { - JsonArray fields; - for (auto &&field_ir : record_ir->GetFields()) { - fields.append(ConvertRecordFieldIR(&field_ir)); - } - record_type.Set("fields", fields); -} - -static JsonObject -ConvertBaseSpecifierIR(const CXXBaseSpecifierIR &base_specifier_ir) { - JsonObject base_specifier; - base_specifier.Set("referenced_type", base_specifier_ir.GetReferencedType()); - base_specifier.Set("is_virtual", base_specifier_ir.IsVirtual()); - AddAccess(base_specifier, base_specifier_ir.GetAccess()); - return base_specifier; -} - -void IRToJsonConverter::AddBaseSpecifiers(JsonObject &record_type, - const RecordTypeIR *record_ir) { - JsonArray base_specifiers; - for (auto &&base_ir : record_ir->GetBases()) { - base_specifiers.append(ConvertBaseSpecifierIR(base_ir)); - } - record_type.Set("base_specifiers", base_specifiers); -} - -static JsonObject -ConvertVTableComponentIR(const VTableComponentIR &vtable_component_ir) { - JsonObject vtable_component; - AddVtableComponentKind(vtable_component, vtable_component_ir.GetKind()); - vtable_component.Set("component_value", - (int64_t)vtable_component_ir.GetValue()); - vtable_component.Set("mangled_component_name", vtable_component_ir.GetName()); - vtable_component.Set("is_pure", vtable_component_ir.GetIsPure()); - return vtable_component; -} - -void IRToJsonConverter::AddVTableLayout(JsonObject &record_type, - const RecordTypeIR *record_ir) { - JsonArray vtable_components; - for (auto &&vtable_component_ir : - record_ir->GetVTableLayout().GetVTableComponents()) { - vtable_components.append(ConvertVTableComponentIR(vtable_component_ir)); - } - record_type.Set("vtable_components", vtable_components); -} - -void IRToJsonConverter::AddTagTypeInfo(JsonObject &type_decl, - const TagTypeIR *tag_type_ir) { - type_decl.Set("unique_id", tag_type_ir->GetUniqueId()); -} - -JsonObject IRToJsonConverter::ConvertRecordTypeIR(const RecordTypeIR *recordp) { - JsonObject record_type; - - AddAccess(record_type, recordp->GetAccess()); - AddRecordKind(record_type, recordp->GetRecordKind()); - record_type.Set("is_anonymous", recordp->IsAnonymous()); - AddTypeInfo(record_type, recordp); - AddRecordFields(record_type, recordp); - AddBaseSpecifiers(record_type, recordp); - AddVTableLayout(record_type, recordp); - AddTagTypeInfo(record_type, recordp); - AddTemplateInfo(record_type, recordp); - return record_type; -} - -void IRToJsonConverter::AddFunctionParametersAndSetReturnType( - JsonObject &function, const CFunctionLikeIR *cfunction_like_ir) { - function.Set("return_type", cfunction_like_ir->GetReturnType()); - AddFunctionParameters(function, cfunction_like_ir); -} - -void IRToJsonConverter::AddFunctionParameters( - JsonObject &function, const CFunctionLikeIR *cfunction_like_ir) { - JsonArray parameters; - for (auto &¶meter_ir : cfunction_like_ir->GetParameters()) { - JsonObject parameter; - parameter.Set("referenced_type", parameter_ir.GetReferencedType()); - parameter.Set("default_arg", parameter_ir.GetIsDefault()); - parameter.Set("is_this_ptr", parameter_ir.GetIsThisPtr()); - parameters.append(parameter); - } - function.Set("parameters", parameters); -} - -JsonObject -IRToJsonConverter::ConvertFunctionTypeIR(const FunctionTypeIR *function_typep) { - JsonObject function_type; - AddTypeInfo(function_type, function_typep); - AddFunctionParametersAndSetReturnType(function_type, function_typep); - return function_type; -} - -JsonObject IRToJsonConverter::ConvertFunctionIR(const FunctionIR *functionp) { - JsonObject function; - AddAccess(function, functionp->GetAccess()); - function.Set("linker_set_key", functionp->GetLinkerSetKey()); - function.Set("source_file", functionp->GetSourceFile()); - function.Set("function_name", functionp->GetName()); - AddFunctionParametersAndSetReturnType(function, functionp); - AddTemplateInfo(function, functionp); - return function; -} - -static JsonObject ConvertEnumFieldIR(const EnumFieldIR *enum_field_ir) { - JsonObject enum_field; - enum_field.Set("name", enum_field_ir->GetName()); - // Never omit enum values. - enum_field["enum_field_value"] = Json::Int64(enum_field_ir->GetValue()); - return enum_field; -} - -void IRToJsonConverter::AddEnumFields(JsonObject &enum_type, - const EnumTypeIR *enum_ir) { - JsonArray enum_fields; - for (auto &&field : enum_ir->GetFields()) { - enum_fields.append(ConvertEnumFieldIR(&field)); - } - enum_type.Set("enum_fields", enum_fields); -} - -JsonObject IRToJsonConverter::ConvertEnumTypeIR(const EnumTypeIR *enump) { - JsonObject enum_type; - AddAccess(enum_type, enump->GetAccess()); - enum_type.Set("underlying_type", enump->GetUnderlyingType()); - AddTypeInfo(enum_type, enump); - AddEnumFields(enum_type, enump); - AddTagTypeInfo(enum_type, enump); - return enum_type; -} - -JsonObject -IRToJsonConverter::ConvertGlobalVarIR(const GlobalVarIR *global_varp) { - JsonObject global_var; - global_var.Set("referenced_type", global_varp->GetReferencedType()); - global_var.Set("source_file", global_varp->GetSourceFile()); - global_var.Set("name", global_varp->GetName()); - global_var.Set("linker_set_key", global_varp->GetLinkerSetKey()); - AddAccess(global_var, global_varp->GetAccess()); - return global_var; -} - -JsonObject -IRToJsonConverter::ConvertPointerTypeIR(const PointerTypeIR *pointerp) { - JsonObject pointer_type; - AddTypeInfo(pointer_type, pointerp); - return pointer_type; -} - -JsonObject -IRToJsonConverter::ConvertQualifiedTypeIR(const QualifiedTypeIR *qualtypep) { - JsonObject qualified_type; - AddTypeInfo(qualified_type, qualtypep); - qualified_type.Set("is_const", qualtypep->IsConst()); - qualified_type.Set("is_volatile", qualtypep->IsVolatile()); - qualified_type.Set("is_restricted", qualtypep->IsRestricted()); - return qualified_type; -} - -JsonObject -IRToJsonConverter::ConvertBuiltinTypeIR(const BuiltinTypeIR *builtin_typep) { - JsonObject builtin_type; - builtin_type.Set("is_unsigned", builtin_typep->IsUnsigned()); - builtin_type.Set("is_integral", builtin_typep->IsIntegralType()); - AddTypeInfo(builtin_type, builtin_typep); - return builtin_type; -} - -JsonObject -IRToJsonConverter::ConvertArrayTypeIR(const ArrayTypeIR *array_typep) { - JsonObject array_type; - AddTypeInfo(array_type, array_typep); - return array_type; -} - -JsonObject IRToJsonConverter::ConvertLvalueReferenceTypeIR( - const LvalueReferenceTypeIR *lvalue_reference_typep) { - JsonObject lvalue_reference_type; - AddTypeInfo(lvalue_reference_type, lvalue_reference_typep); - return lvalue_reference_type; -} - -JsonObject IRToJsonConverter::ConvertRvalueReferenceTypeIR( - const RvalueReferenceTypeIR *rvalue_reference_typep) { - JsonObject rvalue_reference_type; - AddTypeInfo(rvalue_reference_type, rvalue_reference_typep); - return rvalue_reference_type; -} - -bool JsonIRDumper::AddLinkableMessageIR(const LinkableMessageIR *lm) { - std::string key; - JsonObject converted; - // No RTTI - switch (lm->GetKind()) { - case RecordTypeKind: - key = "record_types"; - converted = ConvertRecordTypeIR(static_cast<const RecordTypeIR *>(lm)); - break; - case EnumTypeKind: - key = "enum_types"; - converted = ConvertEnumTypeIR(static_cast<const EnumTypeIR *>(lm)); - break; - case PointerTypeKind: - key = "pointer_types"; - converted = ConvertPointerTypeIR(static_cast<const PointerTypeIR *>(lm)); - break; - case QualifiedTypeKind: - key = "qualified_types"; - converted = - ConvertQualifiedTypeIR(static_cast<const QualifiedTypeIR *>(lm)); - break; - case ArrayTypeKind: - key = "array_types"; - converted = ConvertArrayTypeIR(static_cast<const ArrayTypeIR *>(lm)); - break; - case LvalueReferenceTypeKind: - key = "lvalue_reference_types"; - converted = ConvertLvalueReferenceTypeIR( - static_cast<const LvalueReferenceTypeIR *>(lm)); - break; - case RvalueReferenceTypeKind: - key = "rvalue_reference_types"; - converted = ConvertRvalueReferenceTypeIR( - static_cast<const RvalueReferenceTypeIR *>(lm)); - break; - case BuiltinTypeKind: - key = "builtin_types"; - converted = ConvertBuiltinTypeIR(static_cast<const BuiltinTypeIR *>(lm)); - break; - case FunctionTypeKind: - key = "function_types"; - converted = ConvertFunctionTypeIR(static_cast<const FunctionTypeIR *>(lm)); - break; - case GlobalVarKind: - key = "global_vars"; - converted = ConvertGlobalVarIR(static_cast<const GlobalVarIR *>(lm)); - break; - case FunctionKind: - key = "functions"; - converted = ConvertFunctionIR(static_cast<const FunctionIR *>(lm)); - break; - default: - return false; - } - translation_unit_[key].append(converted); - return true; -} - -bool JsonIRDumper::AddElfSymbolMessageIR(const ElfSymbolIR *elf_symbol_ir) { - std::string key; - switch (elf_symbol_ir->GetKind()) { - case ElfSymbolIR::ElfFunctionKind: - key = "elf_functions"; - break; - case ElfSymbolIR::ElfObjectKind: - key = "elf_objects"; - break; - default: - return false; - } - JsonObject elf_symbol; - elf_symbol.Set("name", elf_symbol_ir->GetName()); - AddElfSymbolBinding(elf_symbol, elf_symbol_ir->GetBinding()); - translation_unit_[key].append(elf_symbol); - return true; -} - -static std::string DumpJson(const JsonObject &obj) { - std::ostringstream output_stream; - Json::StyledStreamWriter writer(/* indentation */ " "); - writer.write(output_stream, obj); - return output_stream.str(); -} - -static void WriteTailTrimmedLinesToFile(const std::string &path, - const std::string &output_string) { - std::ofstream output_file(path); - size_t line_start = 0; - while (line_start < output_string.size()) { - size_t trailing_space_start = line_start; - size_t index; - for (index = line_start; - index < output_string.size() && output_string[index] != '\n'; - index++) { - if (output_string[index] != ' ') { - trailing_space_start = index + 1; - } - } - // Only write this line if this line contains non-whitespace characters. - if (trailing_space_start != line_start) { - output_file.write(output_string.data() + line_start, - trailing_space_start - line_start); - output_file.write("\n", 1); - } - line_start = index + 1; - } -} - -bool JsonIRDumper::Dump() { - std::string output_string = DumpJson(translation_unit_); - WriteTailTrimmedLinesToFile(dump_path_, output_string); - return true; -} - -JsonIRDumper::JsonIRDumper(const std::string &dump_path) - : IRDumper(dump_path), translation_unit_() { - const std::string keys[] = { - "record_types", - "enum_types", - "pointer_types", - "lvalue_reference_types", - "rvalue_reference_types", - "builtin_types", - "qualified_types", - "array_types", - "function_types", - "functions", - "global_vars", - "elf_functions", - "elf_objects", - }; - for (auto key : keys) { - translation_unit_[key] = JsonArray(); - } -} - -JsonObjectRef::JsonObjectRef(const Json::Value &json_value, bool &ok) - : object_(json_value.isObject() ? json_value : json_empty_object), ok_(ok) { - if (!json_value.isObject()) { - ok_ = false; - } -} - -const Json::Value & -JsonObjectRef::Get(const std::string &key, const Json::Value &default_value, - IsExpectedJsonType is_expected_type) const { - if (!object_.isMember(key)) { - return default_value; - } - const Json::Value &value = object_[key]; - if (!(value.*is_expected_type)()) { - ok_ = false; - return default_value; - } - return value; -} - -bool JsonObjectRef::GetBool(const std::string &key) const { - return Get(key, json_false, &Json::Value::isBool).asBool(); -} - -int64_t JsonObjectRef::GetInt(const std::string &key) const { - return Get(key, json_0, &Json::Value::isIntegral).asInt64(); -} - -uint64_t JsonObjectRef::GetUint(const std::string &key) const { - return Get(key, json_0, &Json::Value::isIntegral).asUInt64(); -} - -std::string JsonObjectRef::GetString(const std::string &key) const { - return Get(key, json_empty_string, &Json::Value::isString).asString(); -} - -JsonObjectRef JsonObjectRef::GetObject(const std::string &key) const { - return JsonObjectRef(Get(key, json_empty_object, &Json::Value::isObject), - ok_); -} - -JsonArrayRef<JsonObjectRef> -JsonObjectRef::GetObjects(const std::string &key) const { - return JsonArrayRef<JsonObjectRef>( - Get(key, json_empty_array, &Json::Value::isArray), ok_); -} - -JsonArrayRef<std::string> -JsonObjectRef::GetStrings(const std::string &key) const { - return JsonArrayRef<std::string>( - Get(key, json_empty_array, &Json::Value::isArray), ok_); -} - -template <> -JsonObjectRef JsonArrayRef<JsonObjectRef>::Iterator::operator*() const { - return JsonObjectRef(array_[index_], ok_); -} - -template <> std::string JsonArrayRef<std::string>::Iterator::operator*() const { - return array_[index_].asString(); -} - -static AccessSpecifierIR GetAccess(const JsonObjectRef &type_decl) { - std::string access(type_decl.GetString("access")); - if (access.empty()) { - return default_access_ir; - } - return FindInMap(access_json_to_ir, access, - "Failed to convert JSON to AccessSpecifierIR"); -} - -static RecordTypeIR::RecordKind -GetRecordKind(const JsonObjectRef &record_type) { - std::string kind(record_type.GetString("record_kind")); - if (kind.empty()) { - return default_record_kind_ir; - } - return FindInMap(record_kind_json_to_ir, kind, - "Failed to convert JSON to RecordKind"); -} - -static VTableComponentIR::Kind -GetVTableComponentKind(const JsonObjectRef &vtable_component) { - std::string kind(vtable_component.GetString("kind")); - if (kind.empty()) { - return default_vtable_component_kind_ir; - } - return FindInMap(vtable_component_kind_json_to_ir, kind, - "Failed to convert JSON to VTableComponentIR::Kind"); -} - -static ElfSymbolIR::ElfSymbolBinding -GetElfSymbolBinding(const JsonObjectRef &elf_symbol) { - std::string binding(elf_symbol.GetString("binding")); - if (binding.empty()) { - return default_elf_symbol_binding_ir; - } - return FindInMap(elf_symbol_binding_json_to_ir, binding, - "Failed to convert JSON to ElfSymbolBinding"); -} - -bool JsonToIRReader::ReadDump(const std::string &dump_file) { - Json::Value tu_json; - Json::Reader reader; - std::ifstream input(dump_file); - - if (!reader.parse(input, tu_json, /* collectComments */ false)) { - llvm::errs() << "Failed to parse JSON: " - << reader.getFormattedErrorMessages() << "\n"; - return false; - } - bool ok = true; - JsonObjectRef tu(tu_json, ok); - if (!ok) { - llvm::errs() << "Translation unit is not an object\n"; - return false; - } - - ReadFunctions(tu); - ReadGlobalVariables(tu); - ReadEnumTypes(tu); - ReadRecordTypes(tu); - ReadFunctionTypes(tu); - ReadArrayTypes(tu); - ReadPointerTypes(tu); - ReadQualifiedTypes(tu); - ReadBuiltinTypes(tu); - ReadLvalueReferenceTypes(tu); - ReadRvalueReferenceTypes(tu); - ReadElfFunctions(tu); - ReadElfObjects(tu); - if (!ok) { - llvm::errs() << "Failed to convert JSON to IR\n"; - return false; - } - return true; -} - -void JsonToIRReader::ReadTagTypeInfo(const JsonObjectRef &type_decl, - TagTypeIR *tag_type_ir) { - tag_type_ir->SetUniqueId(type_decl.GetString("unique_id")); -} - -void JsonToIRReader::ReadTemplateInfo(const JsonObjectRef &type_decl, - TemplatedArtifactIR *template_ir) { - TemplateInfoIR template_info_ir; - for (auto &&referenced_type : type_decl.GetStrings("template_args")) { - TemplateElementIR template_element_ir(referenced_type); - template_info_ir.AddTemplateElement(std::move(template_element_ir)); - } - template_ir->SetTemplateInfo(std::move(template_info_ir)); -} - -void JsonToIRReader::ReadTypeInfo(const JsonObjectRef &type_decl, - TypeIR *type_ir) { - type_ir->SetLinkerSetKey(type_decl.GetString("linker_set_key")); - type_ir->SetSourceFile(type_decl.GetString("source_file")); - type_ir->SetName(type_decl.GetString("name")); - type_ir->SetReferencedType(type_decl.GetString("referenced_type")); - type_ir->SetSelfType(type_decl.GetString("self_type")); - type_ir->SetSize(type_decl.GetUint("size")); - type_ir->SetAlignment(type_decl.GetUint("alignment")); -} - -void JsonToIRReader::ReadRecordFields(const JsonObjectRef &record_type, - RecordTypeIR *record_ir) { - for (auto &&field : record_type.GetObjects("fields")) { - RecordFieldIR record_field_ir( - field.GetString("field_name"), field.GetString("referenced_type"), - field.GetUint("field_offset"), GetAccess(field)); - record_ir->AddRecordField(std::move(record_field_ir)); - } -} - -void JsonToIRReader::ReadBaseSpecifiers(const JsonObjectRef &record_type, - RecordTypeIR *record_ir) { - for (auto &&base_specifier : record_type.GetObjects("base_specifiers")) { - CXXBaseSpecifierIR record_base_ir( - base_specifier.GetString("referenced_type"), - base_specifier.GetBool("is_virtual"), GetAccess(base_specifier)); - record_ir->AddCXXBaseSpecifier(std::move(record_base_ir)); - } -} - -void JsonToIRReader::ReadVTableLayout(const JsonObjectRef &record_type, - RecordTypeIR *record_ir) { - VTableLayoutIR vtable_layout_ir; - for (auto &&vtable_component : record_type.GetObjects("vtable_components")) { - VTableComponentIR vtable_component_ir( - vtable_component.GetString("mangled_component_name"), - GetVTableComponentKind(vtable_component), - vtable_component.GetInt("component_value"), - vtable_component.GetBool("is_pure")); - vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir)); - } - record_ir->SetVTableLayout(std::move(vtable_layout_ir)); -} - -void JsonToIRReader::ReadEnumFields(const JsonObjectRef &enum_type, - EnumTypeIR *enum_ir) { - for (auto &&field : enum_type.GetObjects("enum_fields")) { - EnumFieldIR enum_field_ir(field.GetString("name"), - field.GetInt("enum_field_value")); - enum_ir->AddEnumField(std::move(enum_field_ir)); - } -} - -void JsonToIRReader::ReadFunctionParametersAndReturnType( - const JsonObjectRef &function, CFunctionLikeIR *function_ir) { - function_ir->SetReturnType(function.GetString("return_type")); - for (auto &¶meter : function.GetObjects("parameters")) { - ParamIR param_ir(parameter.GetString("referenced_type"), - parameter.GetBool("default_arg"), - parameter.GetBool("is_this_ptr")); - function_ir->AddParameter(std::move(param_ir)); - } -} - -FunctionIR JsonToIRReader::FunctionJsonToIR(const JsonObjectRef &function) { - FunctionIR function_ir; - function_ir.SetLinkerSetKey(function.GetString("linker_set_key")); - function_ir.SetName(function.GetString("function_name")); - function_ir.SetAccess(GetAccess(function)); - function_ir.SetSourceFile(function.GetString("source_file")); - ReadFunctionParametersAndReturnType(function, &function_ir); - ReadTemplateInfo(function, &function_ir); - return function_ir; -} - -FunctionTypeIR -JsonToIRReader::FunctionTypeJsonToIR(const JsonObjectRef &function_type) { - FunctionTypeIR function_type_ir; - ReadTypeInfo(function_type, &function_type_ir); - ReadFunctionParametersAndReturnType(function_type, &function_type_ir); - return function_type_ir; -} - -RecordTypeIR -JsonToIRReader::RecordTypeJsonToIR(const JsonObjectRef &record_type) { - RecordTypeIR record_type_ir; - ReadTypeInfo(record_type, &record_type_ir); - ReadTemplateInfo(record_type, &record_type_ir); - record_type_ir.SetAccess(GetAccess(record_type)); - ReadVTableLayout(record_type, &record_type_ir); - ReadRecordFields(record_type, &record_type_ir); - ReadBaseSpecifiers(record_type, &record_type_ir); - record_type_ir.SetRecordKind(GetRecordKind(record_type)); - record_type_ir.SetAnonymity(record_type.GetBool("is_anonymous")); - ReadTagTypeInfo(record_type, &record_type_ir); - return record_type_ir; -} - -EnumTypeIR JsonToIRReader::EnumTypeJsonToIR(const JsonObjectRef &enum_type) { - EnumTypeIR enum_type_ir; - ReadTypeInfo(enum_type, &enum_type_ir); - enum_type_ir.SetUnderlyingType(enum_type.GetString("underlying_type")); - enum_type_ir.SetAccess(GetAccess(enum_type)); - ReadEnumFields(enum_type, &enum_type_ir); - ReadTagTypeInfo(enum_type, &enum_type_ir); - return enum_type_ir; -} - -void JsonToIRReader::ReadGlobalVariables(const JsonObjectRef &tu) { - for (auto &&global_variable : tu.GetObjects("global_vars")) { - GlobalVarIR global_variable_ir; - global_variable_ir.SetName(global_variable.GetString("name")); - global_variable_ir.SetAccess(GetAccess(global_variable)); - global_variable_ir.SetSourceFile(global_variable.GetString("source_file")); - global_variable_ir.SetReferencedType( - global_variable.GetString("referenced_type")); - global_variable_ir.SetLinkerSetKey( - global_variable.GetString("linker_set_key")); - if (!IsLinkableMessageInExportedHeaders(&global_variable_ir)) { - continue; - } - global_variables_.insert( - {global_variable_ir.GetLinkerSetKey(), std::move(global_variable_ir)}); - } -} - -void JsonToIRReader::ReadPointerTypes(const JsonObjectRef &tu) { - for (auto &&pointer_type : tu.GetObjects("pointer_types")) { - PointerTypeIR pointer_type_ir; - ReadTypeInfo(pointer_type, &pointer_type_ir); - if (!IsLinkableMessageInExportedHeaders(&pointer_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(pointer_type_ir), &pointer_types_, - &type_graph_); - } -} - -void JsonToIRReader::ReadBuiltinTypes(const JsonObjectRef &tu) { - for (auto &&builtin_type : tu.GetObjects("builtin_types")) { - BuiltinTypeIR builtin_type_ir; - ReadTypeInfo(builtin_type, &builtin_type_ir); - builtin_type_ir.SetSignedness(builtin_type.GetBool("is_unsigned")); - builtin_type_ir.SetIntegralType(builtin_type.GetBool("is_integral")); - AddToMapAndTypeGraph(std::move(builtin_type_ir), &builtin_types_, - &type_graph_); - } -} - -void JsonToIRReader::ReadQualifiedTypes(const JsonObjectRef &tu) { - for (auto &&qualified_type : tu.GetObjects("qualified_types")) { - QualifiedTypeIR qualified_type_ir; - ReadTypeInfo(qualified_type, &qualified_type_ir); - qualified_type_ir.SetConstness(qualified_type.GetBool("is_const")); - qualified_type_ir.SetVolatility(qualified_type.GetBool("is_volatile")); - qualified_type_ir.SetRestrictedness( - qualified_type.GetBool("is_restricted")); - if (!IsLinkableMessageInExportedHeaders(&qualified_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(qualified_type_ir), &qualified_types_, - &type_graph_); - } -} - -void JsonToIRReader::ReadArrayTypes(const JsonObjectRef &tu) { - for (auto &&array_type : tu.GetObjects("array_types")) { - ArrayTypeIR array_type_ir; - ReadTypeInfo(array_type, &array_type_ir); - if (!IsLinkableMessageInExportedHeaders(&array_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(array_type_ir), &array_types_, &type_graph_); - } -} - -void JsonToIRReader::ReadLvalueReferenceTypes(const JsonObjectRef &tu) { - for (auto &&lvalue_reference_type : tu.GetObjects("lvalue_reference_types")) { - LvalueReferenceTypeIR lvalue_reference_type_ir; - ReadTypeInfo(lvalue_reference_type, &lvalue_reference_type_ir); - if (!IsLinkableMessageInExportedHeaders(&lvalue_reference_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(lvalue_reference_type_ir), - &lvalue_reference_types_, &type_graph_); - } -} - -void JsonToIRReader::ReadRvalueReferenceTypes(const JsonObjectRef &tu) { - for (auto &&rvalue_reference_type : tu.GetObjects("rvalue_reference_types")) { - RvalueReferenceTypeIR rvalue_reference_type_ir; - ReadTypeInfo(rvalue_reference_type, &rvalue_reference_type_ir); - if (!IsLinkableMessageInExportedHeaders(&rvalue_reference_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(rvalue_reference_type_ir), - &rvalue_reference_types_, &type_graph_); - } -} - -void JsonToIRReader::ReadFunctions(const JsonObjectRef &tu) { - for (auto &&function : tu.GetObjects("functions")) { - FunctionIR function_ir = FunctionJsonToIR(function); - if (!IsLinkableMessageInExportedHeaders(&function_ir)) { - continue; - } - functions_.insert({function_ir.GetLinkerSetKey(), std::move(function_ir)}); - } -} - -void JsonToIRReader::ReadRecordTypes(const JsonObjectRef &tu) { - for (auto &&record_type : tu.GetObjects("record_types")) { - RecordTypeIR record_type_ir = RecordTypeJsonToIR(record_type); - if (!IsLinkableMessageInExportedHeaders(&record_type_ir)) { - continue; - } - auto it = AddToMapAndTypeGraph(std::move(record_type_ir), &record_types_, - &type_graph_); - const std::string &key = GetODRListMapKey(&(it->second)); - AddToODRListMap(key, &(it->second)); - } -} - -void JsonToIRReader::ReadFunctionTypes(const JsonObjectRef &tu) { - for (auto &&function_type : tu.GetObjects("function_types")) { - FunctionTypeIR function_type_ir = FunctionTypeJsonToIR(function_type); - if (!IsLinkableMessageInExportedHeaders(&function_type_ir)) { - continue; - } - auto it = AddToMapAndTypeGraph(std::move(function_type_ir), - &function_types_, &type_graph_); - const std::string &key = GetODRListMapKey(&(it->second)); - AddToODRListMap(key, &(it->second)); - } -} - -void JsonToIRReader::ReadEnumTypes(const JsonObjectRef &tu) { - for (auto &&enum_type : tu.GetObjects("enum_types")) { - EnumTypeIR enum_type_ir = EnumTypeJsonToIR(enum_type); - if (!IsLinkableMessageInExportedHeaders(&enum_type_ir)) { - continue; - } - auto it = AddToMapAndTypeGraph(std::move(enum_type_ir), &enum_types_, - &type_graph_); - AddToODRListMap(it->second.GetUniqueId() + it->second.GetSourceFile(), - (&it->second)); - } -} - -void JsonToIRReader::ReadElfFunctions(const JsonObjectRef &tu) { - for (auto &&elf_function : tu.GetObjects("elf_functions")) { - ElfFunctionIR elf_function_ir(elf_function.GetString("name"), - GetElfSymbolBinding(elf_function)); - elf_functions_.insert( - {elf_function_ir.GetName(), std::move(elf_function_ir)}); - } -} - -void JsonToIRReader::ReadElfObjects(const JsonObjectRef &tu) { - for (auto &&elf_object : tu.GetObjects("elf_objects")) { - ElfObjectIR elf_object_ir(elf_object.GetString("name"), - GetElfSymbolBinding(elf_object)); - elf_objects_.insert({elf_object_ir.GetName(), std::move(elf_object_ir)}); - } -} - -} // namespace abi_util diff --git a/vndk/tools/header-checker/header-abi-util/src/ir_representation_protobuf.cpp b/vndk/tools/header-checker/header-abi-util/src/ir_representation_protobuf.cpp deleted file mode 100644 index 5951555f8..000000000 --- a/vndk/tools/header-checker/header-abi-util/src/ir_representation_protobuf.cpp +++ /dev/null @@ -1,1493 +0,0 @@ -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "ir_representation_protobuf.h" - -#include <llvm/Support/raw_ostream.h> - -#include <fstream> -#include <iostream> -#include <memory> -#include <string> - -namespace abi_util { - -void ProtobufTextFormatToIRReader::ReadTypeInfo( - const abi_dump::BasicNamedAndTypedDecl &type_info, TypeIR *typep) { - typep->SetLinkerSetKey(type_info.linker_set_key()); - typep->SetName(type_info.name()); - typep->SetSourceFile(type_info.source_file()); - typep->SetReferencedType(type_info.referenced_type()); - typep->SetSelfType(type_info.self_type()); - typep->SetSize(type_info.size()); - typep->SetAlignment(type_info.alignment()); -} - -bool ProtobufTextFormatToIRReader::ReadDump(const std::string &dump_file) { - abi_dump::TranslationUnit tu; - std::ifstream input(dump_file); - google::protobuf::io::IstreamInputStream text_is(&input); - - if (!google::protobuf::TextFormat::Parse(&text_is, &tu)) { - llvm::errs() << "Failed to parse protobuf TextFormat file\n"; - return false; - } - ReadFunctions(tu); - ReadGlobalVariables(tu); - - ReadEnumTypes(tu); - ReadRecordTypes(tu); - ReadFunctionTypes(tu); - ReadArrayTypes(tu); - ReadPointerTypes(tu); - ReadQualifiedTypes(tu); - ReadBuiltinTypes(tu); - ReadLvalueReferenceTypes(tu); - ReadRvalueReferenceTypes(tu); - - ReadElfFunctions(tu); - ReadElfObjects(tu); - return true; -} - -TemplateInfoIR ProtobufTextFormatToIRReader::TemplateInfoProtobufToIR( - const abi_dump::TemplateInfo &template_info_protobuf) { - TemplateInfoIR template_info_ir; - for (auto &&template_element : template_info_protobuf.elements()) { - TemplateElementIR template_element_ir(template_element.referenced_type()); - template_info_ir.AddTemplateElement(std::move(template_element_ir)); - } - return template_info_ir; -} - -template <typename T> -static void SetupCFunctionLikeIR(const T &cfunction_like_protobuf, - CFunctionLikeIR *cfunction_like_ir) { - cfunction_like_ir->SetReturnType(cfunction_like_protobuf.return_type()); - for (auto &¶meter: cfunction_like_protobuf.parameters()) { - ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(), - false); - cfunction_like_ir->AddParameter(std::move(param_ir)); - } -} - -FunctionIR ProtobufTextFormatToIRReader::FunctionProtobufToIR( - const abi_dump::FunctionDecl &function_protobuf) { - FunctionIR function_ir; - function_ir.SetReturnType(function_protobuf.return_type()); - function_ir.SetLinkerSetKey(function_protobuf.linker_set_key()); - function_ir.SetName(function_protobuf.function_name()); - function_ir.SetAccess(AccessProtobufToIR(function_protobuf.access())); - function_ir.SetSourceFile(function_protobuf.source_file()); - // Set parameters - for (auto &¶meter: function_protobuf.parameters()) { - ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(), - parameter.is_this_ptr()); - function_ir.AddParameter(std::move(param_ir)); - } - // Set Template info - function_ir.SetTemplateInfo( - TemplateInfoProtobufToIR(function_protobuf.template_info())); - return function_ir; -} - -FunctionTypeIR ProtobufTextFormatToIRReader::FunctionTypeProtobufToIR( - const abi_dump::FunctionType &function_type_protobuf) { - FunctionTypeIR function_type_ir; - ReadTypeInfo(function_type_protobuf.type_info(), &function_type_ir); - SetupCFunctionLikeIR(function_type_protobuf, &function_type_ir); - return function_type_ir; -} - -VTableLayoutIR ProtobufTextFormatToIRReader::VTableLayoutProtobufToIR( - const abi_dump::VTableLayout &vtable_layout_protobuf) { - VTableLayoutIR vtable_layout_ir; - for (auto &&vtable_component : vtable_layout_protobuf.vtable_components()) { - VTableComponentIR vtable_component_ir( - vtable_component.mangled_component_name(), - VTableComponentKindProtobufToIR(vtable_component.kind()), - vtable_component.component_value(), - vtable_component.is_pure()); - vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir)); - } - return vtable_layout_ir; -} - -std::vector<RecordFieldIR> -ProtobufTextFormatToIRReader::RecordFieldsProtobufToIR( - const google::protobuf::RepeatedPtrField<abi_dump::RecordFieldDecl> &rfp) { - std::vector<RecordFieldIR> record_type_fields_ir; - for (auto &&field : rfp) { - RecordFieldIR record_field_ir(field.field_name(), field.referenced_type(), - field.field_offset(), - AccessProtobufToIR(field.access())); - record_type_fields_ir.emplace_back(std::move(record_field_ir)); - } - return record_type_fields_ir; -} - -std::vector<CXXBaseSpecifierIR> -ProtobufTextFormatToIRReader::RecordCXXBaseSpecifiersProtobufToIR( - const google::protobuf::RepeatedPtrField<abi_dump::CXXBaseSpecifier> &rbs) { - std::vector<CXXBaseSpecifierIR> record_type_bases_ir; - for (auto &&base : rbs) { - CXXBaseSpecifierIR record_base_ir( - base.referenced_type(), base.is_virtual(), - AccessProtobufToIR(base.access())); - record_type_bases_ir.emplace_back(std::move(record_base_ir)); - } - return record_type_bases_ir; -} - -RecordTypeIR ProtobufTextFormatToIRReader::RecordTypeProtobufToIR( - const abi_dump::RecordType &record_type_protobuf) { - RecordTypeIR record_type_ir; - ReadTypeInfo(record_type_protobuf.type_info(), &record_type_ir); - record_type_ir.SetTemplateInfo( - TemplateInfoProtobufToIR(record_type_protobuf.template_info())); - record_type_ir.SetAccess(AccessProtobufToIR(record_type_protobuf.access())); - record_type_ir.SetVTableLayout( - VTableLayoutProtobufToIR(record_type_protobuf.vtable_layout())); - // Get fields - record_type_ir.SetRecordFields(RecordFieldsProtobufToIR( - record_type_protobuf.fields())); - // Base Specifiers - record_type_ir.SetCXXBaseSpecifiers(RecordCXXBaseSpecifiersProtobufToIR( - record_type_protobuf.base_specifiers())); - record_type_ir.SetRecordKind( - RecordKindProtobufToIR(record_type_protobuf.record_kind())); - record_type_ir.SetAnonymity(record_type_protobuf.is_anonymous()); - record_type_ir.SetUniqueId(record_type_protobuf.tag_info().unique_id()); - return record_type_ir; -} - -std::vector<EnumFieldIR> -ProtobufTextFormatToIRReader::EnumFieldsProtobufToIR( - const google::protobuf::RepeatedPtrField<abi_dump::EnumFieldDecl> &efp) { - std::vector<EnumFieldIR> enum_type_fields_ir; - for (auto &&field : efp) { - EnumFieldIR enum_field_ir(field.name(), field.enum_field_value()); - enum_type_fields_ir.emplace_back(std::move(enum_field_ir)); - } - return enum_type_fields_ir; -} - -EnumTypeIR ProtobufTextFormatToIRReader::EnumTypeProtobufToIR( - const abi_dump::EnumType &enum_type_protobuf) { - EnumTypeIR enum_type_ir; - ReadTypeInfo(enum_type_protobuf.type_info(), &enum_type_ir); - enum_type_ir.SetUnderlyingType(enum_type_protobuf.underlying_type()); - enum_type_ir.SetAccess(AccessProtobufToIR(enum_type_protobuf.access())); - enum_type_ir.SetFields( - EnumFieldsProtobufToIR(enum_type_protobuf.enum_fields())); - enum_type_ir.SetUniqueId(enum_type_protobuf.tag_info().unique_id()); - return enum_type_ir; -} - -void ProtobufTextFormatToIRReader::ReadGlobalVariables( - const abi_dump::TranslationUnit &tu) { - for (auto &&global_variable_protobuf : tu.global_vars()) { - GlobalVarIR global_variable_ir; - global_variable_ir.SetName(global_variable_protobuf.name()); - global_variable_ir.SetAccess(AccessProtobufToIR(global_variable_protobuf.access())); - global_variable_ir.SetSourceFile(global_variable_protobuf.source_file()); - global_variable_ir.SetReferencedType( - global_variable_protobuf.referenced_type()); - global_variable_ir.SetLinkerSetKey( - global_variable_protobuf.linker_set_key()); - if (!IsLinkableMessageInExportedHeaders(&global_variable_ir)) { - continue; - } - global_variables_.insert( - {global_variable_ir.GetLinkerSetKey(), std::move(global_variable_ir)}); - } -} - -void ProtobufTextFormatToIRReader::ReadPointerTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&pointer_type_protobuf : tu.pointer_types()) { - PointerTypeIR pointer_type_ir; - ReadTypeInfo(pointer_type_protobuf.type_info(), &pointer_type_ir); - if (!IsLinkableMessageInExportedHeaders(&pointer_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(pointer_type_ir), &pointer_types_, - &type_graph_); - } -} - -void ProtobufTextFormatToIRReader::ReadBuiltinTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&builtin_type_protobuf : tu.builtin_types()) { - BuiltinTypeIR builtin_type_ir; - ReadTypeInfo(builtin_type_protobuf.type_info(), &builtin_type_ir); - builtin_type_ir.SetSignedness(builtin_type_protobuf.is_unsigned()); - builtin_type_ir.SetIntegralType(builtin_type_protobuf.is_integral()); - AddToMapAndTypeGraph(std::move(builtin_type_ir), &builtin_types_, - &type_graph_); - } -} - -void ProtobufTextFormatToIRReader::ReadQualifiedTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&qualified_type_protobuf : tu.qualified_types()) { - QualifiedTypeIR qualified_type_ir; - ReadTypeInfo(qualified_type_protobuf.type_info(), &qualified_type_ir); - qualified_type_ir.SetConstness(qualified_type_protobuf.is_const()); - qualified_type_ir.SetVolatility(qualified_type_protobuf.is_volatile()); - qualified_type_ir.SetRestrictedness( - qualified_type_protobuf.is_restricted()); - if (!IsLinkableMessageInExportedHeaders(&qualified_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(qualified_type_ir), &qualified_types_, - &type_graph_); - } -} - -void ProtobufTextFormatToIRReader::ReadArrayTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&array_type_protobuf : tu.array_types()) { - ArrayTypeIR array_type_ir; - ReadTypeInfo(array_type_protobuf.type_info(), &array_type_ir); - if (!IsLinkableMessageInExportedHeaders(&array_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(array_type_ir), &array_types_, - &type_graph_); - } -} - -void ProtobufTextFormatToIRReader::ReadLvalueReferenceTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&lvalue_reference_type_protobuf : tu.lvalue_reference_types()) { - LvalueReferenceTypeIR lvalue_reference_type_ir; - ReadTypeInfo(lvalue_reference_type_protobuf.type_info(), - &lvalue_reference_type_ir); - if (!IsLinkableMessageInExportedHeaders(&lvalue_reference_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(lvalue_reference_type_ir), - &lvalue_reference_types_, &type_graph_); - } -} - -void ProtobufTextFormatToIRReader::ReadRvalueReferenceTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&rvalue_reference_type_protobuf : tu.rvalue_reference_types()) { - RvalueReferenceTypeIR rvalue_reference_type_ir; - ReadTypeInfo(rvalue_reference_type_protobuf.type_info(), - &rvalue_reference_type_ir); - if (!IsLinkableMessageInExportedHeaders(&rvalue_reference_type_ir)) { - continue; - } - AddToMapAndTypeGraph(std::move(rvalue_reference_type_ir), - &rvalue_reference_types_, &type_graph_); - } -} - -void ProtobufTextFormatToIRReader::ReadFunctions( - const abi_dump::TranslationUnit &tu) { - for (auto &&function_protobuf : tu.functions()) { - FunctionIR function_ir = FunctionProtobufToIR(function_protobuf); - if (!IsLinkableMessageInExportedHeaders(&function_ir)) { - continue; - } - functions_.insert({function_ir.GetLinkerSetKey(), std::move(function_ir)}); - } -} - -void ProtobufTextFormatToIRReader::ReadRecordTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&record_type_protobuf : tu.record_types()) { - RecordTypeIR record_type_ir = RecordTypeProtobufToIR(record_type_protobuf); - if (!IsLinkableMessageInExportedHeaders(&record_type_ir)) { - continue; - } - auto it = AddToMapAndTypeGraph(std::move(record_type_ir), &record_types_, - &type_graph_); - const std::string &key = GetODRListMapKey(&(it->second)); - AddToODRListMap(key, &(it->second)); - } -} - -void ProtobufTextFormatToIRReader::ReadFunctionTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&function_type_protobuf : tu.function_types()) { - FunctionTypeIR function_type_ir = - FunctionTypeProtobufToIR(function_type_protobuf); - if (!IsLinkableMessageInExportedHeaders(&function_type_ir)) { - continue; - } - auto it = AddToMapAndTypeGraph(std::move(function_type_ir), - &function_types_, &type_graph_); - const std::string &key = GetODRListMapKey(&(it->second)); - AddToODRListMap(key, &(it->second)); - } -} - -void ProtobufTextFormatToIRReader::ReadEnumTypes( - const abi_dump::TranslationUnit &tu) { - for (auto &&enum_type_protobuf : tu.enum_types()) { - EnumTypeIR enum_type_ir = EnumTypeProtobufToIR(enum_type_protobuf); - if (!IsLinkableMessageInExportedHeaders(&enum_type_ir)) { - continue; - } - auto it = AddToMapAndTypeGraph(std::move(enum_type_ir), &enum_types_, - &type_graph_); - AddToODRListMap(it->second.GetUniqueId() + it->second.GetSourceFile(), - (&it->second)); - } -} - -void ProtobufTextFormatToIRReader::ReadElfFunctions( - const abi_dump::TranslationUnit &tu) { - for (auto &&elf_function : tu.elf_functions()) { - ElfFunctionIR elf_function_ir( - elf_function.name(), - ElfSymbolBindingProtobufToIR(elf_function.binding())); - elf_functions_.insert( - {elf_function_ir.GetName(), std::move(elf_function_ir)}); - } -} - -void ProtobufTextFormatToIRReader::ReadElfObjects( - const abi_dump::TranslationUnit &tu) { - for (auto &&elf_object : tu.elf_objects()) { - ElfObjectIR elf_object_ir( - elf_object.name(), ElfSymbolBindingProtobufToIR(elf_object.binding())); - elf_objects_.insert( - {elf_object_ir.GetName(), std::move(elf_object_ir)}); - } -} - -bool IRToProtobufConverter::AddTemplateInformation( - abi_dump::TemplateInfo *ti, const abi_util::TemplatedArtifactIR *ta) { - for (auto &&template_element : ta->GetTemplateElements()) { - abi_dump::TemplateElement *added_element = ti->add_elements(); - if (!added_element) { - llvm::errs() << "Failed to add template element\n"; - return false; - } - added_element->set_referenced_type(template_element.GetReferencedType()); - } - return true; -} - -bool IRToProtobufConverter::AddTypeInfo( - abi_dump::BasicNamedAndTypedDecl *type_info, const TypeIR *typep) { - if (!type_info || !typep) { - llvm::errs() << "Typeinfo not valid\n"; - return false; - } - type_info->set_linker_set_key(typep->GetLinkerSetKey()); - type_info->set_source_file(typep->GetSourceFile()); - type_info->set_name(typep->GetName()); - type_info->set_size(typep->GetSize()); - type_info->set_alignment(typep->GetAlignment()); - type_info->set_referenced_type(typep->GetReferencedType()); - type_info->set_self_type(typep->GetSelfType()); - return true; -} - -static void SetIRToProtobufRecordField( - abi_dump::RecordFieldDecl *record_field_protobuf, - const RecordFieldIR *record_field_ir) { - record_field_protobuf->set_field_name(record_field_ir->GetName()); - record_field_protobuf->set_referenced_type( - record_field_ir->GetReferencedType()); - record_field_protobuf->set_access( - AccessIRToProtobuf(record_field_ir->GetAccess())); - record_field_protobuf->set_field_offset(record_field_ir->GetOffset()); -} - -bool IRToProtobufConverter::AddRecordFields( - abi_dump::RecordType *record_protobuf, - const RecordTypeIR *record_ir) { - // Iterate through the fields and create corresponding ones for the protobuf - // record - for (auto &&field_ir : record_ir->GetFields()) { - abi_dump::RecordFieldDecl *added_field = record_protobuf->add_fields(); - if (!added_field) { - llvm::errs() << "Couldn't add record field\n"; - } - SetIRToProtobufRecordField(added_field, &field_ir); - } - return true; -} - -static bool SetIRToProtobufBaseSpecifier( - abi_dump::CXXBaseSpecifier *base_specifier_protobuf, - const CXXBaseSpecifierIR &base_specifier_ir) { - if (!base_specifier_protobuf) { - llvm::errs() << "Protobuf base specifier not valid\n"; - return false; - } - base_specifier_protobuf->set_referenced_type( - base_specifier_ir.GetReferencedType()); - base_specifier_protobuf->set_is_virtual( - base_specifier_ir.IsVirtual()); - base_specifier_protobuf->set_access( - AccessIRToProtobuf(base_specifier_ir.GetAccess())); - return true; -} - -bool IRToProtobufConverter::AddBaseSpecifiers( - abi_dump::RecordType *record_protobuf, const RecordTypeIR *record_ir) { - for (auto &&base_ir : record_ir->GetBases()) { - abi_dump::CXXBaseSpecifier *added_base = - record_protobuf->add_base_specifiers(); - if (!SetIRToProtobufBaseSpecifier(added_base, base_ir)) { - return false; - } - } - return true; -} - -static bool SetIRToProtobufVTableLayout( - abi_dump::VTableLayout *vtable_layout_protobuf, - const VTableLayoutIR &vtable_layout_ir) { - if (vtable_layout_protobuf == nullptr) { - llvm::errs() << "vtable layout protobuf not valid\n"; - return false; - } - for (auto &&vtable_component_ir : vtable_layout_ir.GetVTableComponents()) { - abi_dump::VTableComponent *added_vtable_component = - vtable_layout_protobuf->add_vtable_components(); - if (!added_vtable_component) { - llvm::errs() << "Couldn't add vtable component\n"; - return false; - } - added_vtable_component->set_kind( - VTableComponentKindIRToProtobuf(vtable_component_ir.GetKind())); - added_vtable_component->set_component_value(vtable_component_ir.GetValue()); - added_vtable_component->set_mangled_component_name( - vtable_component_ir.GetName()); - added_vtable_component->set_is_pure(vtable_component_ir.GetIsPure()); - } - return true; -} - -bool IRToProtobufConverter::AddVTableLayout( - abi_dump::RecordType *record_protobuf, - const RecordTypeIR *record_ir) { - // If there are no entries in the vtable, just return. - if (record_ir->GetVTableNumEntries() == 0) { - return true; - } - const VTableLayoutIR &vtable_layout_ir = record_ir->GetVTableLayout(); - abi_dump::VTableLayout *vtable_layout_protobuf = - record_protobuf->mutable_vtable_layout(); - if (!SetIRToProtobufVTableLayout(vtable_layout_protobuf, vtable_layout_ir)) { - return false; - } - return true; -} - -bool IRToProtobufConverter::AddTagTypeInfo( - abi_dump::TagType *tag_type_protobuf, - const abi_util::TagTypeIR *tag_type_ir) { - if (!tag_type_protobuf || !tag_type_ir) { - return false; - } - tag_type_protobuf->set_unique_id(tag_type_ir->GetUniqueId()); - return true; -} - -abi_dump::RecordType IRToProtobufConverter::ConvertRecordTypeIR( - const RecordTypeIR *recordp) { - abi_dump::RecordType added_record_type; - added_record_type.set_access(AccessIRToProtobuf(recordp->GetAccess())); - added_record_type.set_record_kind( - RecordKindIRToProtobuf(recordp->GetRecordKind())); - if (recordp->IsAnonymous()) { - added_record_type.set_is_anonymous(true); - } - if (!AddTypeInfo(added_record_type.mutable_type_info(), recordp) || - !AddRecordFields(&added_record_type, recordp) || - !AddBaseSpecifiers(&added_record_type, recordp) || - !AddVTableLayout(&added_record_type, recordp) || - !AddTagTypeInfo(added_record_type.mutable_tag_info(), recordp) || - !(recordp->GetTemplateElements().size() ? - AddTemplateInformation(added_record_type.mutable_template_info(), - recordp) : true)) { - llvm::errs() << "Template information could not be added\n"; - ::exit(1); - } - return added_record_type; -} - - -abi_dump::ElfObject IRToProtobufConverter::ConvertElfObjectIR( - const ElfObjectIR *elf_object_ir) { - abi_dump::ElfObject elf_object_protobuf; - elf_object_protobuf.set_name(elf_object_ir->GetName()); - return elf_object_protobuf; -} - -abi_dump::ElfFunction IRToProtobufConverter::ConvertElfFunctionIR( - const ElfFunctionIR *elf_function_ir) { - abi_dump::ElfFunction elf_function_protobuf; - elf_function_protobuf.set_name(elf_function_ir->GetName()); - return elf_function_protobuf; -} - -template <typename CFunctionLikeMessage> -bool IRToProtobufConverter::AddFunctionParametersAndSetReturnType( - CFunctionLikeMessage *function_like_protobuf, - const CFunctionLikeIR *cfunction_like_ir) { - function_like_protobuf->set_return_type(cfunction_like_ir->GetReturnType()); - return AddFunctionParameters(function_like_protobuf, cfunction_like_ir); -} - -template <typename CFunctionLikeMessage> -bool IRToProtobufConverter::AddFunctionParameters( - CFunctionLikeMessage *function_like_protobuf, - const CFunctionLikeIR *cfunction_like_ir) { - for (auto &¶meter : cfunction_like_ir->GetParameters()) { - abi_dump::ParamDecl *added_parameter = - function_like_protobuf->add_parameters(); - if (!added_parameter) { - return false; - } - added_parameter->set_referenced_type( - parameter.GetReferencedType()); - added_parameter->set_default_arg(parameter.GetIsDefault()); - added_parameter->set_is_this_ptr(parameter.GetIsThisPtr()); - } - return true; -} - -abi_dump::FunctionType IRToProtobufConverter::ConvertFunctionTypeIR ( - const FunctionTypeIR *function_typep) { - abi_dump::FunctionType added_function_type; - if (!AddTypeInfo(added_function_type.mutable_type_info(), function_typep) || - !AddFunctionParametersAndSetReturnType(&added_function_type, - function_typep)) { - llvm::errs() << "Could not convert FunctionTypeIR to protobuf\n"; - ::exit(1); - } - return added_function_type; -} - -abi_dump::FunctionDecl IRToProtobufConverter::ConvertFunctionIR( - const FunctionIR *functionp) { - abi_dump::FunctionDecl added_function; - added_function.set_access(AccessIRToProtobuf(functionp->GetAccess())); - added_function.set_linker_set_key(functionp->GetLinkerSetKey()); - added_function.set_source_file(functionp->GetSourceFile()); - added_function.set_function_name(functionp->GetName()); - if (!AddFunctionParametersAndSetReturnType(&added_function, functionp) || - !(functionp->GetTemplateElements().size() ? - AddTemplateInformation(added_function.mutable_template_info(), functionp) - : true)) { - llvm::errs() << "Template information could not be added\n"; - ::exit(1); - } - return added_function; -} - -static bool SetIRToProtobufEnumField( - abi_dump::EnumFieldDecl *enum_field_protobuf, - const EnumFieldIR *enum_field_ir) { - if (enum_field_protobuf == nullptr) { - return true; - } - enum_field_protobuf->set_name(enum_field_ir->GetName()); - enum_field_protobuf->set_enum_field_value(enum_field_ir->GetValue()); - return true; -} - -bool IRToProtobufConverter::AddEnumFields(abi_dump::EnumType *enum_protobuf, - const EnumTypeIR *enum_ir) { - for (auto &&field : enum_ir->GetFields()) { - abi_dump::EnumFieldDecl *enum_fieldp = enum_protobuf->add_enum_fields(); - if (!SetIRToProtobufEnumField(enum_fieldp, &field)) { - return false; - } - } - return true; -} - - -abi_dump::EnumType IRToProtobufConverter::ConvertEnumTypeIR( - const EnumTypeIR *enump) { - abi_dump::EnumType added_enum_type; - added_enum_type.set_access(AccessIRToProtobuf(enump->GetAccess())); - added_enum_type.set_underlying_type(enump->GetUnderlyingType()); - if (!AddTypeInfo(added_enum_type.mutable_type_info(), enump) || - !AddEnumFields(&added_enum_type, enump) || - !AddTagTypeInfo(added_enum_type.mutable_tag_info(), enump)) { - llvm::errs() << "EnumTypeIR could not be converted\n"; - ::exit(1); - } - return added_enum_type; -} - -abi_dump::GlobalVarDecl IRToProtobufConverter::ConvertGlobalVarIR( - const GlobalVarIR *global_varp) { - abi_dump::GlobalVarDecl added_global_var; - added_global_var.set_referenced_type(global_varp->GetReferencedType()); - added_global_var.set_source_file(global_varp->GetSourceFile()); - added_global_var.set_name(global_varp->GetName()); - added_global_var.set_linker_set_key(global_varp->GetLinkerSetKey()); - added_global_var.set_access( - AccessIRToProtobuf(global_varp->GetAccess())); - return added_global_var; -} - -abi_dump::PointerType IRToProtobufConverter::ConvertPointerTypeIR( - const PointerTypeIR *pointerp) { - abi_dump::PointerType added_pointer_type; - if (!AddTypeInfo(added_pointer_type.mutable_type_info(), pointerp)) { - llvm::errs() << "PointerTypeIR could not be converted\n"; - ::exit(1); - } - return added_pointer_type; -} - -abi_dump::QualifiedType IRToProtobufConverter::ConvertQualifiedTypeIR( - const QualifiedTypeIR *qualtypep) { - abi_dump::QualifiedType added_qualified_type; - if (!AddTypeInfo(added_qualified_type.mutable_type_info(), qualtypep)) { - llvm::errs() << "QualifiedTypeIR could not be converted\n"; - ::exit(1); - } - added_qualified_type.set_is_const(qualtypep->IsConst()); - added_qualified_type.set_is_volatile(qualtypep->IsVolatile()); - added_qualified_type.set_is_restricted(qualtypep->IsRestricted()); - return added_qualified_type; -} - -abi_dump::BuiltinType IRToProtobufConverter::ConvertBuiltinTypeIR( - const BuiltinTypeIR *builtin_typep) { - abi_dump::BuiltinType added_builtin_type; - added_builtin_type.set_is_unsigned(builtin_typep->IsUnsigned()); - added_builtin_type.set_is_integral(builtin_typep->IsIntegralType()); - if (!AddTypeInfo(added_builtin_type.mutable_type_info(), builtin_typep)) { - llvm::errs() << "BuiltinTypeIR could not be converted\n"; - ::exit(1); - } - return added_builtin_type; -} - -abi_dump::ArrayType IRToProtobufConverter::ConvertArrayTypeIR( - const ArrayTypeIR *array_typep) { - abi_dump::ArrayType added_array_type; - if (!AddTypeInfo(added_array_type.mutable_type_info(), array_typep)) { - llvm::errs() << "ArrayTypeIR could not be converted\n"; - ::exit(1); - } - return added_array_type; -} - -abi_dump::LvalueReferenceType -IRToProtobufConverter::ConvertLvalueReferenceTypeIR( - const LvalueReferenceTypeIR *lvalue_reference_typep) { - abi_dump::LvalueReferenceType added_lvalue_reference_type; - if (!AddTypeInfo(added_lvalue_reference_type.mutable_type_info(), - lvalue_reference_typep)) { - llvm::errs() << "LvalueReferenceTypeIR could not be converted\n"; - ::exit(1); - } - return added_lvalue_reference_type; -} - -abi_dump::RvalueReferenceType -IRToProtobufConverter::ConvertRvalueReferenceTypeIR( - const RvalueReferenceTypeIR *rvalue_reference_typep) { - abi_dump::RvalueReferenceType added_rvalue_reference_type; - if (!AddTypeInfo(added_rvalue_reference_type.mutable_type_info(), - rvalue_reference_typep)) { - llvm::errs() << "RvalueReferenceTypeIR could not be converted\n"; - ::exit(1); - } - return added_rvalue_reference_type; -} - - -bool IRDiffToProtobufConverter::AddTypeInfoDiff( - abi_diff::TypeInfoDiff *type_info_diff_protobuf, - const TypeDiffIR *type_diff_ir) { - abi_diff::TypeInfo *old_type_info_protobuf = - type_info_diff_protobuf->mutable_old_type_info(); - abi_diff::TypeInfo *new_type_info_protobuf = - type_info_diff_protobuf->mutable_new_type_info(); - if (old_type_info_protobuf == nullptr || new_type_info_protobuf == nullptr) { - return false; - } - const std::pair<uint64_t, uint64_t> &sizes = type_diff_ir->GetSizes(); - const std::pair<uint32_t, uint32_t> &alignments = - type_diff_ir->GetAlignments(); - old_type_info_protobuf->set_size(sizes.first); - new_type_info_protobuf->set_size(sizes.second); - - old_type_info_protobuf->set_alignment(alignments.first); - new_type_info_protobuf->set_alignment(alignments.second); - return true; -} - -bool IRDiffToProtobufConverter::AddVTableLayoutDiff( - abi_diff::VTableLayoutDiff *vtable_layout_diff_protobuf, - const VTableLayoutDiffIR *vtable_layout_diff_ir) { - abi_dump:: VTableLayout *old_vtable = - vtable_layout_diff_protobuf->mutable_old_vtable(); - abi_dump:: VTableLayout *new_vtable = - vtable_layout_diff_protobuf->mutable_new_vtable(); - if (old_vtable == nullptr || new_vtable == nullptr || - !SetIRToProtobufVTableLayout(old_vtable, - vtable_layout_diff_ir->GetOldVTable()) || - !SetIRToProtobufVTableLayout(new_vtable, - vtable_layout_diff_ir->GetNewVTable())) { - return false; - } - return true; -} - -template <typename T> -static bool CopyBaseSpecifiersDiffIRToProtobuf( - google::protobuf::RepeatedPtrField<T> *dst, - const std::vector<CXXBaseSpecifierIR> &bases_ir) { - for (auto &&base_ir : bases_ir) { - T *added_base = dst->Add(); - if (!SetIRToProtobufBaseSpecifier(added_base, base_ir)) { - return false; - } - } - return true; -} - -bool IRDiffToProtobufConverter::AddBaseSpecifierDiffs( - abi_diff::CXXBaseSpecifierDiff *base_specifiers_diff_protobuf, - const CXXBaseSpecifierDiffIR *base_specifiers_diff_ir) { - if (!CopyBaseSpecifiersDiffIRToProtobuf( - base_specifiers_diff_protobuf->mutable_old_bases(), - base_specifiers_diff_ir->GetOldBases()) || - !CopyBaseSpecifiersDiffIRToProtobuf( - base_specifiers_diff_protobuf->mutable_new_bases(), - base_specifiers_diff_ir->GetNewBases())) { - return false; - } - return true; -} - -bool IRDiffToProtobufConverter::AddRecordFields( - abi_diff::RecordTypeDiff *record_diff_protobuf, - const std::vector<const RecordFieldIR *> &record_fields_ir, - bool field_removed) { - for (auto &&record_field_ir : record_fields_ir) { - abi_dump::RecordFieldDecl *field = nullptr; - if (field_removed) { - field = record_diff_protobuf->add_fields_removed(); - } else { - field = record_diff_protobuf->add_fields_added(); - } - if (field == nullptr) { - return false; - } - SetIRToProtobufRecordField(field, record_field_ir); - } - return true; -} - -bool IRDiffToProtobufConverter::AddRecordFieldDiffs( - abi_diff::RecordTypeDiff *record_diff_protobuf, - const std::vector<RecordFieldDiffIR> &record_field_diffs_ir) { - for (auto &&record_field_diff_ir : record_field_diffs_ir) { - abi_diff::RecordFieldDeclDiff *record_field_diff = - record_diff_protobuf->add_fields_diff(); - if (record_field_diff == nullptr) { - return false; - } - abi_dump::RecordFieldDecl *old_field = - record_field_diff->mutable_old_field(); - abi_dump::RecordFieldDecl *new_field = - record_field_diff->mutable_new_field(); - if (old_field == nullptr || new_field == nullptr) { - return false; - } - SetIRToProtobufRecordField(old_field, - record_field_diff_ir.GetOldField()); - SetIRToProtobufRecordField(new_field, - record_field_diff_ir.GetNewField()); - } - return true; -} - -abi_diff::RecordTypeDiff IRDiffToProtobufConverter::ConvertRecordTypeDiffIR( - const RecordTypeDiffIR *record_type_diff_ir) { - abi_diff::RecordTypeDiff record_type_diff_protobuf; - record_type_diff_protobuf.set_name(record_type_diff_ir->GetName()); - const TypeDiffIR *type_diff_ir = record_type_diff_ir->GetTypeDiff(); - // If a type_info diff exists - if (type_diff_ir != nullptr) { - abi_diff::TypeInfoDiff *type_info_diff = - record_type_diff_protobuf.mutable_type_info_diff(); - if (!AddTypeInfoDiff(type_info_diff, type_diff_ir)) { - llvm::errs() << "RecordType could not be converted\n"; - ::exit(1); - } - } - // If vtables differ. - const VTableLayoutDiffIR *vtable_layout_diff_ir = - record_type_diff_ir->GetVTableLayoutDiff(); - if (vtable_layout_diff_ir != nullptr) { - abi_diff::VTableLayoutDiff *vtable_layout_diff_protobuf = - record_type_diff_protobuf.mutable_vtable_layout_diff(); - if (!AddVTableLayoutDiff(vtable_layout_diff_protobuf, - vtable_layout_diff_ir)) { - llvm::errs() << "VTable layout diff could not be added\n"; - ::exit(1); - } - } - // If base specifiers differ. - const CXXBaseSpecifierDiffIR *base_specifier_diff_ir = - record_type_diff_ir->GetBaseSpecifiers(); - if (base_specifier_diff_ir != nullptr) { - abi_diff::CXXBaseSpecifierDiff *base_specifier_diff_protobuf = - record_type_diff_protobuf.mutable_bases_diff(); - if (!AddBaseSpecifierDiffs(base_specifier_diff_protobuf, - base_specifier_diff_ir)) { - llvm::errs() << "Base Specifier diff could not be added\n"; - ::exit(1); - } - } - // Field diffs - if (!AddRecordFields(&record_type_diff_protobuf, - record_type_diff_ir->GetFieldsRemoved(), true) || - !AddRecordFields(&record_type_diff_protobuf, - record_type_diff_ir->GetFieldsAdded(), false) || - !AddRecordFieldDiffs(&record_type_diff_protobuf, - record_type_diff_ir->GetFieldDiffs())) { - llvm::errs() << "Record Field diff could not be added\n"; - ::exit(1); - } - return record_type_diff_protobuf; -} - -bool IRDiffToProtobufConverter::AddEnumUnderlyingTypeDiff( - abi_diff::UnderlyingTypeDiff *underlying_type_diff_protobuf, - const std::pair<std::string, std::string> *underlying_type_diff_ir) { - if (underlying_type_diff_protobuf == nullptr) { - return false; - } - underlying_type_diff_protobuf->set_old_type(underlying_type_diff_ir->first); - underlying_type_diff_protobuf->set_new_type(underlying_type_diff_ir->second); - return true; -} - -static bool AddEnumFields( - google::protobuf::RepeatedPtrField<abi_dump::EnumFieldDecl> *dst, - const std::vector<const EnumFieldIR *> &enum_fields) { - for (auto &&enum_field : enum_fields) { - abi_dump::EnumFieldDecl *added_enum_field = dst->Add(); - if (!SetIRToProtobufEnumField(added_enum_field, enum_field)) { - return false; - } - } - return true; -} - -static bool AddEnumFieldDiffs( - google::protobuf::RepeatedPtrField<abi_diff::EnumFieldDeclDiff> *dst, - const std::vector<EnumFieldDiffIR> &fields_diff_ir) { - for (auto &&field_diff_ir : fields_diff_ir) { - abi_diff::EnumFieldDeclDiff *field_diff_protobuf = dst->Add(); - if (field_diff_protobuf == nullptr) { - return false; - } - if (!SetIRToProtobufEnumField(field_diff_protobuf->mutable_old_field(), - field_diff_ir.GetOldField()) || - !SetIRToProtobufEnumField(field_diff_protobuf->mutable_new_field(), - field_diff_ir.GetNewField())) { - return false; - } - } - return true; -} - -abi_diff::EnumTypeDiff IRDiffToProtobufConverter::ConvertEnumTypeDiffIR( - const EnumTypeDiffIR *enum_type_diff_ir) { - abi_diff::EnumTypeDiff enum_type_diff_protobuf; - enum_type_diff_protobuf.set_name(enum_type_diff_ir->GetName()); - const std::pair<std::string, std::string> *underlying_type_diff = - enum_type_diff_ir->GetUnderlyingTypeDiff(); - if ((underlying_type_diff != nullptr && - !AddEnumUnderlyingTypeDiff( - enum_type_diff_protobuf.mutable_underlying_type_diff(), - underlying_type_diff)) || - !AddEnumFields(enum_type_diff_protobuf.mutable_fields_removed(), - enum_type_diff_ir->GetFieldsRemoved()) || - !AddEnumFields(enum_type_diff_protobuf.mutable_fields_added(), - enum_type_diff_ir->GetFieldsAdded()) || - !AddEnumFieldDiffs(enum_type_diff_protobuf.mutable_fields_diff(), - enum_type_diff_ir->GetFieldsDiff())) { - llvm::errs() << "Enum field diff could not be added\n"; - ::exit(1); - } - return enum_type_diff_protobuf; -} - -abi_diff::GlobalVarDeclDiff IRDiffToProtobufConverter::ConvertGlobalVarDiffIR( - const GlobalVarDiffIR *global_var_diff_ir) { - abi_diff::GlobalVarDeclDiff global_var_diff; - global_var_diff.set_name(global_var_diff_ir->GetName()); - abi_dump::GlobalVarDecl *old_global_var = global_var_diff.mutable_old(); - abi_dump::GlobalVarDecl *new_global_var = global_var_diff.mutable_new_(); - if (old_global_var == nullptr || new_global_var == nullptr) { - llvm::errs() << "Globar Var diff could not be added\n"; - ::exit(1); - } - *old_global_var = - IRToProtobufConverter::ConvertGlobalVarIR( - global_var_diff_ir->GetOldGlobalVar()); - *new_global_var = - IRToProtobufConverter::ConvertGlobalVarIR( - global_var_diff_ir->GetNewGlobalVar()); - return global_var_diff; -} - -abi_diff::FunctionDeclDiff IRDiffToProtobufConverter::ConvertFunctionDiffIR( - const FunctionDiffIR *function_diff_ir) { - abi_diff::FunctionDeclDiff function_diff; - function_diff.set_name(function_diff_ir->GetName()); - abi_dump::FunctionDecl *old_function = function_diff.mutable_old(); - abi_dump::FunctionDecl *new_function = function_diff.mutable_new_(); - if (old_function == nullptr || new_function == nullptr) { - llvm::errs() << "Function diff could not be added\n"; - ::exit(1); - } - *old_function = IRToProtobufConverter::ConvertFunctionIR( - function_diff_ir->GetOldFunction()); - *new_function = IRToProtobufConverter::ConvertFunctionIR( - function_diff_ir->GetNewFunction()); - return function_diff; -} - -bool ProtobufIRDumper::AddLinkableMessageIR (const LinkableMessageIR *lm) { - // No RTTI - switch (lm->GetKind()) { - case RecordTypeKind: - return AddRecordTypeIR(static_cast<const RecordTypeIR *>(lm)); - case EnumTypeKind: - return AddEnumTypeIR(static_cast<const EnumTypeIR *>(lm)); - case PointerTypeKind: - return AddPointerTypeIR(static_cast<const PointerTypeIR *>(lm)); - case QualifiedTypeKind: - return AddQualifiedTypeIR(static_cast<const QualifiedTypeIR *>(lm)); - case ArrayTypeKind: - return AddArrayTypeIR(static_cast<const ArrayTypeIR *>(lm)); - case LvalueReferenceTypeKind: - return AddLvalueReferenceTypeIR( - static_cast<const LvalueReferenceTypeIR *>(lm)); - case RvalueReferenceTypeKind: - return AddRvalueReferenceTypeIR( - static_cast<const RvalueReferenceTypeIR*>(lm)); - case BuiltinTypeKind: - return AddBuiltinTypeIR(static_cast<const BuiltinTypeIR*>(lm)); - case FunctionTypeKind: - return AddFunctionTypeIR(static_cast<const FunctionTypeIR*>(lm)); - case GlobalVarKind: - return AddGlobalVarIR(static_cast<const GlobalVarIR*>(lm)); - case FunctionKind: - return AddFunctionIR(static_cast<const FunctionIR*>(lm)); - } - return false; -} - -bool ProtobufIRDumper::AddElfFunctionIR(const ElfFunctionIR *elf_function) { - abi_dump::ElfFunction *added_elf_function = tu_ptr_->add_elf_functions(); - if (!added_elf_function) { - return false; - } - added_elf_function->set_name(elf_function->GetName()); - added_elf_function->set_binding( - ElfSymbolBindingIRToProtobuf(elf_function->GetBinding())); - return true; -} - -bool ProtobufIRDumper::AddElfObjectIR(const ElfObjectIR *elf_object) { - abi_dump::ElfObject *added_elf_object = tu_ptr_->add_elf_objects(); - if (!added_elf_object) { - return false; - } - added_elf_object->set_name(elf_object->GetName()); - added_elf_object->set_binding( - ElfSymbolBindingIRToProtobuf(elf_object->GetBinding())); - return true; -} - -bool ProtobufIRDumper::AddElfSymbolMessageIR(const ElfSymbolIR *em) { - switch (em->GetKind()) { - case ElfSymbolIR::ElfFunctionKind: - return AddElfFunctionIR(static_cast<const ElfFunctionIR *>(em)); - case ElfSymbolIR::ElfObjectKind: - return AddElfObjectIR(static_cast<const ElfObjectIR *>(em)); - } - return false; -} - -bool ProtobufIRDumper::AddRecordTypeIR(const RecordTypeIR *recordp) { - abi_dump::RecordType *added_record_type = tu_ptr_->add_record_types(); - if (!added_record_type) { - return false; - } - *added_record_type = ConvertRecordTypeIR(recordp); - return true; -} - -bool ProtobufIRDumper::AddFunctionTypeIR(const FunctionTypeIR *function_typep) { - abi_dump::FunctionType *added_function_type = tu_ptr_->add_function_types(); - if (!added_function_type) { - return false; - } - *added_function_type = ConvertFunctionTypeIR(function_typep); - return true; -} - -bool ProtobufIRDumper::AddFunctionIR(const FunctionIR *functionp) { - abi_dump::FunctionDecl *added_function = tu_ptr_->add_functions(); - if (!added_function) { - return false; - } - *added_function = ConvertFunctionIR(functionp); - return true; -} - -bool ProtobufIRDumper::AddEnumTypeIR(const EnumTypeIR *enump) { - abi_dump::EnumType *added_enum_type = tu_ptr_->add_enum_types(); - if (!added_enum_type) { - return false; - } - *added_enum_type = ConvertEnumTypeIR(enump); - return true; -} - -bool ProtobufIRDumper::AddGlobalVarIR(const GlobalVarIR *global_varp) { - abi_dump::GlobalVarDecl *added_global_var = tu_ptr_->add_global_vars(); - if (!added_global_var) { - return false; - } - *added_global_var = ConvertGlobalVarIR(global_varp); - return true; -} - -bool ProtobufIRDumper::AddPointerTypeIR(const PointerTypeIR *pointerp) { - abi_dump::PointerType *added_pointer_type = tu_ptr_->add_pointer_types(); - if (!added_pointer_type) { - return false; - } - *added_pointer_type = ConvertPointerTypeIR(pointerp); - return true; -} - -bool ProtobufIRDumper::AddQualifiedTypeIR(const QualifiedTypeIR *qualtypep) { - abi_dump::QualifiedType *added_qualified_type = - tu_ptr_->add_qualified_types(); - if (!added_qualified_type) { - return false; - } - *added_qualified_type = ConvertQualifiedTypeIR(qualtypep); - return true; -} - -bool ProtobufIRDumper::AddBuiltinTypeIR(const BuiltinTypeIR *builtin_typep) { - abi_dump::BuiltinType *added_builtin_type = - tu_ptr_->add_builtin_types(); - if (!added_builtin_type) { - return false; - } - *added_builtin_type = ConvertBuiltinTypeIR(builtin_typep); - return true; -} - -bool ProtobufIRDumper::AddArrayTypeIR(const ArrayTypeIR *array_typep) { - abi_dump::ArrayType *added_array_type = - tu_ptr_->add_array_types(); - if (!added_array_type) { - return false; - } - *added_array_type = ConvertArrayTypeIR(array_typep); - return true; -} - -bool ProtobufIRDumper::AddLvalueReferenceTypeIR( - const LvalueReferenceTypeIR *lvalue_reference_typep) { - abi_dump::LvalueReferenceType *added_lvalue_reference_type = - tu_ptr_->add_lvalue_reference_types(); - if (!added_lvalue_reference_type) { - return false; - } - *added_lvalue_reference_type = - ConvertLvalueReferenceTypeIR(lvalue_reference_typep); - return true; -} - -bool ProtobufIRDumper::AddRvalueReferenceTypeIR( - const RvalueReferenceTypeIR *rvalue_reference_typep) { - abi_dump::RvalueReferenceType *added_rvalue_reference_type = - tu_ptr_->add_rvalue_reference_types(); - if (!added_rvalue_reference_type) { - return false; - } - *added_rvalue_reference_type = - ConvertRvalueReferenceTypeIR(rvalue_reference_typep); - return true; -} - -bool ProtobufIRDumper::Dump() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - assert( tu_ptr_.get() != nullptr); - std::ofstream text_output(dump_path_); - google::protobuf::io::OstreamOutputStream text_os(&text_output); - return google::protobuf::TextFormat::Print(*tu_ptr_.get(), &text_os); -} - -void ProtobufIRDiffDumper::AddLibNameIR(const std::string &name) { - diff_tu_->set_lib_name(name); -} - -void ProtobufIRDiffDumper::AddArchIR(const std::string &arch) { - diff_tu_->set_arch(arch); -} - -CompatibilityStatusIR ProtobufIRDiffDumper::GetCompatibilityStatusIR() { - if (diff_tu_->functions_removed().size() != 0 || - diff_tu_->global_vars_removed().size() != 0 || - diff_tu_->function_diffs().size() != 0 || - diff_tu_->global_var_diffs().size() != 0 || - diff_tu_->enum_type_diffs().size() != 0 || - diff_tu_->record_type_diffs().size() != 0) { - return CompatibilityStatusIR::Incompatible; - } - - CompatibilityStatusIR combined_status = CompatibilityStatusIR::Compatible; - - if (diff_tu_->enum_type_extension_diffs().size() != 0 || - diff_tu_->functions_added().size() != 0 || - diff_tu_->global_vars_added().size() != 0) { - combined_status = combined_status | CompatibilityStatusIR::Extension; - } - - if (diff_tu_->unreferenced_enum_type_diffs().size() != 0 || - diff_tu_->unreferenced_enum_types_removed().size() != 0 || - diff_tu_->unreferenced_record_types_removed().size() != 0 || - diff_tu_->unreferenced_record_type_diffs().size() != 0 || - diff_tu_->unreferenced_enum_type_extension_diffs().size() != 0 || - diff_tu_->unreferenced_record_types_added().size() != 0 || - diff_tu_->unreferenced_enum_types_added().size()) { - combined_status = - combined_status | CompatibilityStatusIR::UnreferencedChanges; - } - - if (diff_tu_->removed_elf_functions().size() != 0 || - diff_tu_->removed_elf_objects().size() != 0) { - combined_status = combined_status | CompatibilityStatusIR::ElfIncompatible; - } - - return combined_status; -} - -void ProtobufIRDiffDumper::AddCompatibilityStatusIR( - CompatibilityStatusIR status) { - diff_tu_->set_compatibility_status(CompatibilityStatusIRToProtobuf(status)); -} - -bool ProtobufIRDiffDumper::AddDiffMessageIR(const DiffMessageIR *message, - const std::string &type_stack, - DiffKind diff_kind) { - switch (message->Kind()) { - case RecordTypeKind: - return AddRecordTypeDiffIR( - static_cast<const RecordTypeDiffIR *>(message), type_stack, - diff_kind); - case EnumTypeKind: - return AddEnumTypeDiffIR( - static_cast<const EnumTypeDiffIR *>(message), type_stack, diff_kind); - case GlobalVarKind: - return AddGlobalVarDiffIR( - static_cast<const GlobalVarDiffIR*>(message), type_stack, diff_kind); - case FunctionKind: - return AddFunctionDiffIR( - static_cast<const FunctionDiffIR*>(message), type_stack, diff_kind); - default: - break; - } - llvm::errs() << "Dump Diff attempted on something not a user defined type / " - << "function / global variable\n"; - return false; -} - -bool ProtobufIRDiffDumper::AddLinkableMessageIR( - const LinkableMessageIR *message, DiffKind diff_kind) { - switch (message->GetKind()) { - case RecordTypeKind: - return AddLoneRecordTypeDiffIR( - static_cast<const RecordTypeIR *>(message), diff_kind); - case EnumTypeKind: - return AddLoneEnumTypeDiffIR( - static_cast<const EnumTypeIR *>(message), diff_kind); - case GlobalVarKind: - return AddLoneGlobalVarDiffIR( - static_cast<const GlobalVarIR*>(message), diff_kind); - case FunctionKind: - return AddLoneFunctionDiffIR( - static_cast<const FunctionIR*>(message), diff_kind); - default: - break; - } - llvm::errs() << "Dump Diff attempted on something not a user defined type / " - << "function / global variable\n"; - return false; -} - -bool ProtobufIRDiffDumper::AddElfSymbolMessageIR(const ElfSymbolIR *elf_symbol, - DiffKind diff_kind) { - switch (elf_symbol->GetKind()) { - case ElfSymbolIR::ElfFunctionKind: - return AddElfFunctionIR(static_cast<const ElfFunctionIR *>(elf_symbol), - diff_kind); - break; - case ElfSymbolIR::ElfObjectKind: - return AddElfObjectIR(static_cast<const ElfObjectIR *>(elf_symbol), - diff_kind); - break; - } - // Any other kind is invalid - return false; -} - -bool ProtobufIRDiffDumper::AddElfFunctionIR( - const ElfFunctionIR *elf_function_ir, DiffKind diff_kind) { - abi_dump::ElfFunction *added_elf_function = nullptr; - switch (diff_kind) { - case DiffKind::Removed: - added_elf_function = diff_tu_->add_removed_elf_functions(); - break; - case DiffKind::Added: - added_elf_function = diff_tu_->add_added_elf_functions(); - break; - default: - llvm::errs() << "Invalid call to AddElfFunctionIR\n"; - return false; - } - if (added_elf_function == nullptr) { - return false; - } - *added_elf_function = - IRToProtobufConverter::ConvertElfFunctionIR(elf_function_ir); - return true; -} - -bool ProtobufIRDiffDumper::AddElfObjectIR( - const ElfObjectIR *elf_object_ir, DiffKind diff_kind) { - abi_dump::ElfObject *added_elf_object = nullptr; - switch (diff_kind) { - case DiffKind::Removed: - added_elf_object = diff_tu_->add_removed_elf_objects(); - break; - case DiffKind::Added: - added_elf_object = diff_tu_->add_added_elf_objects(); - break; - default: - llvm::errs() << "Invalid call to AddElfObjectIR\n"; - return false; - } - if (added_elf_object == nullptr) { - return false; - } - *added_elf_object = - IRToProtobufConverter::ConvertElfObjectIR(elf_object_ir); - return true; -} - -bool ProtobufIRDiffDumper::AddLoneRecordTypeDiffIR( - const RecordTypeIR *record_type_ir, DiffKind diff_kind) { - abi_dump::RecordType *added_record_type = nullptr; - switch (diff_kind) { - case DiffKind::Removed: - // Referenced record types do not get reported as added / removed, - // the diff shows up in the parent type / function/ global variable - // referencing the record. - added_record_type = diff_tu_->add_unreferenced_record_types_removed(); - break; - case DiffKind::Added: - added_record_type = diff_tu_->add_unreferenced_record_types_added(); - break; - default: - llvm::errs() << "Invalid call to AddLoneRecordTypeDiffIR\n"; - return false; - } - if (added_record_type == nullptr) { - return false; - } - *added_record_type = - IRToProtobufConverter::ConvertRecordTypeIR(record_type_ir); - return true; -} - -bool ProtobufIRDiffDumper::AddLoneFunctionDiffIR( - const FunctionIR *function_ir, DiffKind diff_kind) { - abi_dump::FunctionDecl *added_function = nullptr; - switch (diff_kind) { - case DiffKind::Removed: - added_function = diff_tu_->add_functions_removed(); - break; - case DiffKind::Added: - added_function = diff_tu_->add_functions_added(); - break; - default: - llvm::errs() << "Invalid call to AddLoneFunctionDiffIR\n"; - return false; - } - *added_function = IRToProtobufConverter::ConvertFunctionIR(function_ir); - return true; -} - -bool ProtobufIRDiffDumper::AddLoneEnumTypeDiffIR( - const EnumTypeIR *enum_type_ir, DiffKind diff_kind) { - abi_dump::EnumType *added_enum_type = nullptr; - switch (diff_kind) { - case DiffKind::Removed: - // Referenced enum types do not get reported as added / removed, - // the diff shows up in the parent type / function/ global variable - // referencing the enum. - added_enum_type = diff_tu_->add_unreferenced_enum_types_removed(); - break; - case DiffKind::Added: - added_enum_type = diff_tu_->add_unreferenced_enum_types_added(); - break; - default: - llvm::errs() << "Invalid call to AddLoneRecordTypeDiffIR\n"; - return false; - } - if (added_enum_type == nullptr) { - return false; - } - *added_enum_type = IRToProtobufConverter::ConvertEnumTypeIR(enum_type_ir); - return true; -} - -bool ProtobufIRDiffDumper::AddLoneGlobalVarDiffIR( - const GlobalVarIR *global_var_ir, DiffKind diff_kind) { - abi_dump::GlobalVarDecl *added_global_var = nullptr; - switch (diff_kind) { - case DiffKind::Removed: - added_global_var = diff_tu_->add_global_vars_removed(); - break; - case DiffKind::Added: - added_global_var = diff_tu_->add_global_vars_added(); - break; - default: - llvm::errs() << "Invalid call to AddLoneFunctionDiffIR\n"; - return false; - } - *added_global_var = IRToProtobufConverter::ConvertGlobalVarIR(global_var_ir); - return true; -} - -bool ProtobufIRDiffDumper::AddRecordTypeDiffIR( - const RecordTypeDiffIR *record_diff_ir, const std::string &type_stack, - DiffKind diff_kind) { - abi_diff::RecordTypeDiff *added_record_type_diff = nullptr; - switch (diff_kind) { - case DiffKind::Unreferenced: - added_record_type_diff = diff_tu_->add_unreferenced_record_type_diffs(); - break; - case DiffKind::Referenced: - added_record_type_diff = diff_tu_->add_record_type_diffs(); - break; - default: - break; - } - if (!added_record_type_diff) { - return false; - } - - *added_record_type_diff = - IRDiffToProtobufConverter::ConvertRecordTypeDiffIR(record_diff_ir); - added_record_type_diff->set_type_stack(type_stack); - return true; -} - -bool ProtobufIRDiffDumper::AddFunctionDiffIR( - const FunctionDiffIR *function_diff_ir, const std::string &type_stack, - DiffKind diff_kind) { - abi_diff::FunctionDeclDiff *added_function_diff = - diff_tu_->add_function_diffs(); - if (!added_function_diff) { - return false; - } - *added_function_diff = - IRDiffToProtobufConverter::ConvertFunctionDiffIR(function_diff_ir); - return true; -} - -bool ProtobufIRDiffDumper::AddEnumTypeDiffIR(const EnumTypeDiffIR *enum_diff_ir, - const std::string &type_stack, - DiffKind diff_kind) { - abi_diff::EnumTypeDiff *added_enum_type_diff = nullptr; - switch (diff_kind) { - case DiffKind::Unreferenced: - if (enum_diff_ir->IsExtended()) { - added_enum_type_diff = - diff_tu_->add_unreferenced_enum_type_extension_diffs(); - } else { - added_enum_type_diff = - diff_tu_->add_unreferenced_enum_type_diffs(); - } - break; - case DiffKind::Referenced: - if (enum_diff_ir->IsExtended()) { - added_enum_type_diff = - diff_tu_->add_enum_type_extension_diffs(); - } else { - added_enum_type_diff = - diff_tu_->add_enum_type_diffs(); - } - break; - default: - break; - } - if (!added_enum_type_diff) { - return false; - } - *added_enum_type_diff = - IRDiffToProtobufConverter::ConvertEnumTypeDiffIR(enum_diff_ir); - added_enum_type_diff->set_type_stack(type_stack); - return true; -} - -bool ProtobufIRDiffDumper::AddGlobalVarDiffIR( - const GlobalVarDiffIR *global_var_diff_ir, const std::string &type_stack, - DiffKind diff_kind) { - abi_diff::GlobalVarDeclDiff *added_global_var_diff = - diff_tu_->add_global_var_diffs(); - if (!added_global_var_diff) { - return false; - } - *added_global_var_diff = - IRDiffToProtobufConverter::ConvertGlobalVarDiffIR(global_var_diff_ir); - return true; -} - -bool ProtobufIRDiffDumper::Dump() { - GOOGLE_PROTOBUF_VERIFY_VERSION; - assert(diff_tu_.get() != nullptr); - std::ofstream text_output(dump_path_); - google::protobuf::io::OstreamOutputStream text_os(&text_output); - return google::protobuf::TextFormat::Print(*diff_tu_.get(), &text_os); -} - -} // namespace abi_util diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp b/vndk/tools/header-checker/src/diff/abi_diff.cpp index a72636abf..0d2d759dc 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp +++ b/vndk/tools/header-checker/src/diff/abi_diff.cpp @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "abi_diff.h" +#include "diff/abi_diff.h" -#include "header_abi_util.h" +#include "utils/header_abi_util.h" #include <llvm/Support/raw_ostream.h> @@ -24,21 +24,26 @@ #include <stdlib.h> -abi_util::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() { - using abi_util::TextFormatToIRReader; - std::unique_ptr<abi_util::TextFormatToIRReader> old_reader = - TextFormatToIRReader::CreateTextFormatToIRReader(text_format_old_); - std::unique_ptr<abi_util::TextFormatToIRReader> new_reader = - TextFormatToIRReader::CreateTextFormatToIRReader(text_format_new_); + +namespace header_checker { +namespace diff { + + +repr::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() { + std::unique_ptr<repr::IRReader> old_reader = + repr::IRReader::CreateIRReader(text_format_old_); + std::unique_ptr<repr::IRReader> new_reader = + repr::IRReader::CreateIRReader(text_format_new_); if (!old_reader || !new_reader || !old_reader->ReadDump(old_dump_) || !new_reader->ReadDump(new_dump_)) { llvm::errs() << "Could not create Text Format readers\n"; ::exit(1); } - std::unique_ptr<abi_util::IRDiffDumper> ir_diff_dumper = - abi_util::IRDiffDumper::CreateIRDiffDumper(text_format_diff_, cr_); - abi_util::CompatibilityStatusIR status = - CompareTUs(old_reader.get(), new_reader.get(), ir_diff_dumper.get()); + std::unique_ptr<repr::IRDiffDumper> ir_diff_dumper = + repr::IRDiffDumper::CreateIRDiffDumper(text_format_diff_, cr_); + repr::CompatibilityStatusIR status = + CompareTUs(old_reader->GetModule(), new_reader->GetModule(), + ir_diff_dumper.get()); if (!ir_diff_dumper->Dump()) { llvm::errs() << "Could not dump diff report\n"; ::exit(1); @@ -46,27 +51,26 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() { return status; } -abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( - const abi_util::TextFormatToIRReader *old_tu, - const abi_util::TextFormatToIRReader *new_tu, - abi_util::IRDiffDumper *ir_diff_dumper) { +repr::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( + const repr::ModuleIR &old_tu, const repr::ModuleIR &new_tu, + repr::IRDiffDumper *ir_diff_dumper) { // Collect all old and new types in maps, so that we can refer to them by // type name / linker_set_key later. - const AbiElementMap<const abi_util::TypeIR *> old_types = - old_tu->GetTypeGraph(); - const AbiElementMap<const abi_util::TypeIR *> new_types = - new_tu->GetTypeGraph(); + const AbiElementMap<const repr::TypeIR *> old_types = + old_tu.GetTypeGraph(); + const AbiElementMap<const repr::TypeIR *> new_types = + new_tu.GetTypeGraph(); // Collect fills in added, removed ,unsafe and safe function diffs. - if (!CollectDynsymExportables(old_tu->GetFunctions(), new_tu->GetFunctions(), - old_tu->GetElfFunctions(), - new_tu->GetElfFunctions(), + if (!CollectDynsymExportables(old_tu.GetFunctions(), new_tu.GetFunctions(), + old_tu.GetElfFunctions(), + new_tu.GetElfFunctions(), old_types, new_types, ir_diff_dumper) || - !CollectDynsymExportables(old_tu->GetGlobalVariables(), - new_tu->GetGlobalVariables(), - old_tu->GetElfObjects(), - new_tu->GetElfObjects(), + !CollectDynsymExportables(old_tu.GetGlobalVariables(), + new_tu.GetGlobalVariables(), + old_tu.GetElfObjects(), + new_tu.GetElfObjects(), old_types, new_types, ir_diff_dumper)) { llvm::errs() << "Unable to collect dynsym exportables\n"; @@ -81,7 +85,7 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( ::exit(1); } - abi_util::CompatibilityStatusIR combined_status = + repr::CompatibilityStatusIR combined_status = ir_diff_dumper->GetCompatibilityStatusIR(); ir_diff_dumper->AddLibNameIR(lib_name_); @@ -90,37 +94,36 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( return combined_status; } -std::pair<AbiElementMap<const abi_util::EnumTypeIR *>, - AbiElementMap<const abi_util::RecordTypeIR *>> -HeaderAbiDiff::ExtractUserDefinedTypes( - const abi_util::TextFormatToIRReader *tu) { - AbiElementMap<const abi_util::EnumTypeIR *> enum_types; - AbiElementMap<const abi_util::RecordTypeIR *> record_types; +std::pair<AbiElementMap<const repr::EnumTypeIR *>, + AbiElementMap<const repr::RecordTypeIR *>> +HeaderAbiDiff::ExtractUserDefinedTypes(const repr::ModuleIR &tu) { + AbiElementMap<const repr::EnumTypeIR *> enum_types; + AbiElementMap<const repr::RecordTypeIR *> record_types; // Iterate through the ODRListMap, if there is more than 1 element in the // list, we cannot really unique the type by name, so skip it. If not, add a // map entry UniqueId -> const Record(Enum)TypeIR *. - for (auto &it : tu->GetODRListMap()) { + for (auto &it : tu.GetODRListMap()) { auto &odr_list = it.second; if (odr_list.size() != 1) { continue; } - const abi_util::TypeIR *type = *(odr_list.begin()); - const abi_util::RecordTypeIR *record_type = nullptr; + const repr::TypeIR *type = *(odr_list.begin()); + const repr::RecordTypeIR *record_type = nullptr; switch (type->GetKind()) { - case abi_util::RecordTypeKind: - record_type = static_cast<const abi_util::RecordTypeIR *>(type); + case repr::RecordTypeKind: + record_type = static_cast<const repr::RecordTypeIR *>(type); if (record_type->IsAnonymous()) { continue; } record_types.emplace( record_type->GetUniqueId(), record_type); break; - case abi_util::EnumTypeKind: + case repr::EnumTypeKind: enum_types.emplace( - static_cast<const abi_util::EnumTypeIR *>(type)->GetUniqueId(), - static_cast<const abi_util::EnumTypeIR *>(type)); + static_cast<const repr::EnumTypeIR *>(type)->GetUniqueId(), + static_cast<const repr::EnumTypeIR *>(type)); break; - case abi_util::FunctionTypeKind: + case repr::FunctionTypeKind: continue; default: // Only user defined types should have ODR list entries. @@ -131,11 +134,10 @@ HeaderAbiDiff::ExtractUserDefinedTypes( } bool HeaderAbiDiff::CollectUserDefinedTypes( - const abi_util::TextFormatToIRReader *old_tu, - const abi_util::TextFormatToIRReader *new_tu, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map, - abi_util::IRDiffDumper *ir_diff_dumper) { + const repr::ModuleIR &old_tu, const repr::ModuleIR &new_tu, + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map, + repr::IRDiffDumper *ir_diff_dumper) { auto old_enums_and_records_extracted = ExtractUserDefinedTypes(old_tu); auto new_enums_and_records_extracted = ExtractUserDefinedTypes(new_tu); @@ -154,15 +156,15 @@ template <typename T> bool HeaderAbiDiff::CollectUserDefinedTypesInternal( const AbiElementMap<const T*> &old_ud_types_map, const AbiElementMap<const T*> &new_ud_types_map, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map, - abi_util::IRDiffDumper *ir_diff_dumper) { + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map, + repr::IRDiffDumper *ir_diff_dumper) { return (Collect(old_ud_types_map, new_ud_types_map, nullptr, nullptr, ir_diff_dumper, old_types_map, new_types_map) && PopulateCommonElements(old_ud_types_map, new_ud_types_map, old_types_map, new_types_map, ir_diff_dumper, - abi_util::DiffMessageIR::Unreferenced)); + repr::DiffMessageIR::Unreferenced)); } template <typename T, typename ElfSymbolType> @@ -171,30 +173,27 @@ bool HeaderAbiDiff::CollectDynsymExportables( const AbiElementMap<T> &new_exportables, const AbiElementMap<ElfSymbolType> &old_elf_symbols, const AbiElementMap<ElfSymbolType> &new_elf_symbols, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map, - abi_util::IRDiffDumper *ir_diff_dumper) { + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map, + repr::IRDiffDumper *ir_diff_dumper) { AbiElementMap<const T *> old_exportables_map; AbiElementMap<const T *> new_exportables_map; - AbiElementMap<const abi_util::ElfSymbolIR *> old_elf_symbol_map; - AbiElementMap<const abi_util::ElfSymbolIR *> new_elf_symbol_map; - - abi_util::AddToMap(&old_exportables_map, old_exportables, - [](auto e) { return e->first;}, - [](auto e) {return &(e->second);}); - abi_util::AddToMap(&new_exportables_map, new_exportables, - [](auto e) { return e->first;}, - [](auto e) { return &(e->second);}); - - abi_util::AddToMap( - &old_elf_symbol_map, old_elf_symbols, - [](auto e) { return e->first;}, - [](auto e) {return &(e->second);}); - - abi_util::AddToMap( - &new_elf_symbol_map, new_elf_symbols, - [](auto e) { return e->first;}, - [](auto e) {return &(e->second);}); + AbiElementMap<const repr::ElfSymbolIR *> old_elf_symbol_map; + AbiElementMap<const repr::ElfSymbolIR *> new_elf_symbol_map; + + utils::AddToMap(&old_exportables_map, old_exportables, + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); + utils::AddToMap(&new_exportables_map, new_exportables, + [](auto e) { return e->first;}, + [](auto e) { return &(e->second);}); + + utils::AddToMap(&old_elf_symbol_map, old_elf_symbols, + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); + utils::AddToMap(&new_elf_symbol_map, new_elf_symbols, + [](auto e) { return e->first;}, + [](auto e) {return &(e->second);}); if (!Collect(old_exportables_map, new_exportables_map, &old_elf_symbol_map, &new_elf_symbol_map, @@ -203,7 +202,7 @@ bool HeaderAbiDiff::CollectDynsymExportables( ir_diff_dumper) || !PopulateCommonElements(old_exportables_map, new_exportables_map, old_types_map, new_types_map, ir_diff_dumper, - abi_util::DiffMessageIR::Referenced)) { + repr::DiffMessageIR::Referenced)) { llvm::errs() << "Diffing dynsym exportables failed\n"; return false; } @@ -220,17 +219,17 @@ template <typename T> bool HeaderAbiDiff::Collect( const AbiElementMap<const T*> &old_elements_map, const AbiElementMap<const T*> &new_elements_map, - const AbiElementMap<const abi_util::ElfSymbolIR *> *old_elf_map, - const AbiElementMap<const abi_util::ElfSymbolIR *> *new_elf_map, - abi_util::IRDiffDumper *ir_diff_dumper, - const AbiElementMap<const abi_util::TypeIR *> &old_types_map, - const AbiElementMap<const abi_util::TypeIR *> &new_types_map) { + const AbiElementMap<const repr::ElfSymbolIR *> *old_elf_map, + const AbiElementMap<const repr::ElfSymbolIR *> *new_elf_map, + repr::IRDiffDumper *ir_diff_dumper, + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map) { if (!PopulateRemovedElements( old_elements_map, new_elements_map, new_elf_map, ir_diff_dumper, - abi_util::DiffMessageIR::Removed, old_types_map) || + repr::DiffMessageIR::Removed, old_types_map) || !PopulateRemovedElements( new_elements_map, old_elements_map, old_elf_map, ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind::Added, new_types_map)) { + repr::IRDiffDumper::DiffKind::Added, new_types_map)) { llvm::errs() << "Populating functions in report failed\n"; return false; } @@ -238,25 +237,25 @@ bool HeaderAbiDiff::Collect( } bool HeaderAbiDiff::CollectElfSymbols( - const AbiElementMap<const abi_util::ElfSymbolIR *> &old_symbols, - const AbiElementMap<const abi_util::ElfSymbolIR *> &new_symbols, - abi_util::IRDiffDumper *ir_diff_dumper) { - std::vector<const abi_util::ElfSymbolIR *> removed_elements = - abi_util::FindRemovedElements(old_symbols, new_symbols); + const AbiElementMap<const repr::ElfSymbolIR *> &old_symbols, + const AbiElementMap<const repr::ElfSymbolIR *> &new_symbols, + repr::IRDiffDumper *ir_diff_dumper) { + std::vector<const repr::ElfSymbolIR *> removed_elements = + utils::FindRemovedElements(old_symbols, new_symbols); - std::vector<const abi_util::ElfSymbolIR *> added_elements = - abi_util::FindRemovedElements(new_symbols, old_symbols); + std::vector<const repr::ElfSymbolIR *> added_elements = + utils::FindRemovedElements(new_symbols, old_symbols); return (PopulateElfElements(removed_elements, ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind::Removed) && + repr::IRDiffDumper::DiffKind::Removed) && PopulateElfElements(added_elements, ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind::Added)); + repr::IRDiffDumper::DiffKind::Added)); } bool HeaderAbiDiff::PopulateElfElements( - std::vector<const abi_util::ElfSymbolIR *> &elf_elements, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind) { + std::vector<const repr::ElfSymbolIR *> &elf_elements, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind) { for (auto &&elf_element : elf_elements) { if (!ir_diff_dumper->AddElfSymbolMessageIR(elf_element, diff_kind)) { return false; @@ -269,12 +268,12 @@ template <typename T> bool HeaderAbiDiff::PopulateRemovedElements( const AbiElementMap<const T*> &old_elements_map, const AbiElementMap<const T*> &new_elements_map, - const AbiElementMap<const abi_util::ElfSymbolIR *> *elf_map, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind, - const AbiElementMap<const abi_util::TypeIR *> &removed_types_map) { + const AbiElementMap<const repr::ElfSymbolIR *> *elf_map, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap<const repr::TypeIR *> &removed_types_map) { std::vector<const T *> removed_elements = - abi_util::FindRemovedElements(old_elements_map, new_elements_map); + utils::FindRemovedElements(old_elements_map, new_elements_map); if (!DumpLoneElements(removed_elements, elf_map, ir_diff_dumper, diff_kind, removed_types_map)) { llvm::errs() << "Dumping added / removed element to report failed\n"; @@ -290,12 +289,12 @@ template <typename T> bool HeaderAbiDiff::PopulateCommonElements( const AbiElementMap<const T *> &old_elements_map, const AbiElementMap<const T *> &new_elements_map, - const AbiElementMap<const abi_util::TypeIR *> &old_types, - const AbiElementMap<const abi_util::TypeIR *> &new_types, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind) { + const AbiElementMap<const repr::TypeIR *> &old_types, + const AbiElementMap<const repr::TypeIR *> &new_types, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind) { std::vector<std::pair<const T *, const T *>> common_elements = - abi_util::FindCommonElements(old_elements_map, new_elements_map); + utils::FindCommonElements(old_elements_map, new_elements_map); if (!DumpDiffElements(common_elements, old_types, new_types, ir_diff_dumper, diff_kind)) { llvm::errs() << "Dumping difference in common element to report failed\n"; @@ -307,17 +306,16 @@ bool HeaderAbiDiff::PopulateCommonElements( template <typename T> bool HeaderAbiDiff::DumpLoneElements( std::vector<const T *> &elements, - const AbiElementMap<const abi_util::ElfSymbolIR *> *elf_map, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind, - const AbiElementMap<const abi_util::TypeIR *> &types_map) { + const AbiElementMap<const repr::ElfSymbolIR *> *elf_map, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap<const repr::TypeIR *> &types_map) { // If the record / enum has source file information, skip it. std::smatch source_file_match; std::regex source_file_regex(" at "); for (auto &&element : elements) { - if (abi_diff_wrappers::IgnoreSymbol<T>( - element, ignored_symbols_, - [](const T *e) {return e->GetLinkerSetKey();})) { + if (IgnoreSymbol<T>(element, ignored_symbols_, + [](const T *e) {return e->GetLinkerSetKey();})) { continue; } // The element does exist in the .dynsym table, we do not have meta-data @@ -344,21 +342,20 @@ bool HeaderAbiDiff::DumpLoneElements( template <typename T> bool HeaderAbiDiff::DumpDiffElements( std::vector<std::pair<const T *,const T *>> &pairs, - const AbiElementMap<const abi_util::TypeIR *> &old_types, - const AbiElementMap<const abi_util::TypeIR *> &new_types, - abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind) { + const AbiElementMap<const repr::TypeIR *> &old_types, + const AbiElementMap<const repr::TypeIR *> &new_types, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind) { for (auto &&pair : pairs) { const T *old_element = pair.first; const T *new_element = pair.second; - if (abi_diff_wrappers::IgnoreSymbol<T>( - old_element, ignored_symbols_, - [](const T *e) {return e->GetLinkerSetKey();})) { + if (IgnoreSymbol<T>(old_element, ignored_symbols_, + [](const T *e) {return e->GetLinkerSetKey();})) { continue; } - abi_diff_wrappers::DiffWrapper<T> diff_wrapper( + DiffWrapper<T> diff_wrapper( old_element, new_element, ir_diff_dumper, old_types, new_types, diff_policy_options_, &type_cache_); if (!diff_wrapper.DumpDiff(diff_kind)) { @@ -368,3 +365,7 @@ bool HeaderAbiDiff::DumpDiffElements( } return true; } + + +} // namespace diff +} // namespace header_checker diff --git a/vndk/tools/header-checker/src/diff/abi_diff.h b/vndk/tools/header-checker/src/diff/abi_diff.h new file mode 100644 index 000000000..cbda960c1 --- /dev/null +++ b/vndk/tools/header-checker/src/diff/abi_diff.h @@ -0,0 +1,162 @@ +// Copyright (C) 2016 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABI_DIFF_H_ +#define ABI_DIFF_H_ + +#include "diff/abi_diff_wrappers.h" +#include "repr/ir_representation.h" + +#include <string> +#include <vector> + + +namespace header_checker { +namespace diff { + + +using repr::AbiElementMap; +using repr::DiffPolicyOptions; + + +class HeaderAbiDiff { + public: + HeaderAbiDiff(const std::string &lib_name, const std::string &arch, + const std::string &old_dump, const std::string &new_dump, + const std::string &compatibility_report, + const std::set<std::string> &ignored_symbols, + const DiffPolicyOptions &diff_policy_options, + bool check_all_apis, repr::TextFormatIR text_format_old, + repr::TextFormatIR text_format_new, + repr::TextFormatIR text_format_diff) + : lib_name_(lib_name), arch_(arch), old_dump_(old_dump), + new_dump_(new_dump), cr_(compatibility_report), + ignored_symbols_(ignored_symbols), + diff_policy_options_(diff_policy_options), + check_all_apis_(check_all_apis), + text_format_old_(text_format_old), text_format_new_(text_format_new), + text_format_diff_(text_format_diff) {} + + repr::CompatibilityStatusIR GenerateCompatibilityReport(); + + private: + repr::CompatibilityStatusIR CompareTUs( + const repr::ModuleIR &old_tu, + const repr::ModuleIR &new_tu, + repr::IRDiffDumper *ir_diff_dumper); + + template <typename T, typename ElfSymbolType> + bool CollectDynsymExportables( + const AbiElementMap<T> &old_exportables, + const AbiElementMap<T> &new_exportables, + const AbiElementMap<ElfSymbolType> &old_elf_symbols, + const AbiElementMap<ElfSymbolType> &new_elf_symbols, + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map, + repr::IRDiffDumper *ir_diff_dumper); + + template <typename T> + bool Collect( + const AbiElementMap<const T *> &old_elements_map, + const AbiElementMap<const T *> &new_elements_map, + const AbiElementMap<const repr::ElfSymbolIR *> *old_elf_map, + const AbiElementMap<const repr::ElfSymbolIR *> *new_elf_map, + repr::IRDiffDumper *ir_diff_dumper, + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map); + + bool CollectElfSymbols( + const AbiElementMap<const repr::ElfSymbolIR *> &old_symbols, + const AbiElementMap<const repr::ElfSymbolIR *> &new_symbols, + repr::IRDiffDumper *ir_diff_dumper); + + bool PopulateElfElements( + std::vector<const repr::ElfSymbolIR *> &elf_elements, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind); + + template <typename T> + bool PopulateRemovedElements( + const AbiElementMap<const T *> &old_elements_map, + const AbiElementMap<const T *> &new_elements_map, + const AbiElementMap<const repr::ElfSymbolIR *> *elf_map, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap<const repr::TypeIR *> &types_map); + + template <typename T> + bool PopulateCommonElements( + const AbiElementMap<const T *> &old_elements_map, + const AbiElementMap<const T *> &new_elements_map, + const AbiElementMap<const repr::TypeIR *> &old_types, + const AbiElementMap<const repr::TypeIR *> &new_types, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind); + + template <typename T> + bool DumpDiffElements( + std::vector<std::pair<const T *, const T *>> &pairs, + const AbiElementMap<const repr::TypeIR *> &old_types, + const AbiElementMap<const repr::TypeIR *> &new_types, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind); + + template <typename T> + bool DumpLoneElements( + std::vector<const T *> &elements, + const AbiElementMap<const repr::ElfSymbolIR *> *elf_map, + repr::IRDiffDumper *ir_diff_dumper, + repr::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap<const repr::TypeIR *> &old_types_map); + + std::pair<AbiElementMap<const repr::EnumTypeIR *>, + AbiElementMap<const repr::RecordTypeIR *>> + ExtractUserDefinedTypes(const repr::ModuleIR &tu); + + bool CollectUserDefinedTypes( + const repr::ModuleIR &old_tu, + const repr::ModuleIR &new_tu, + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map, + repr::IRDiffDumper *ir_diff_dumper); + + template <typename T> + bool CollectUserDefinedTypesInternal( + const AbiElementMap<const T*> &old_ud_types_map, + const AbiElementMap<const T*> &new_ud_types_map, + const AbiElementMap<const repr::TypeIR *> &old_types_map, + const AbiElementMap<const repr::TypeIR *> &new_types_map, + repr::IRDiffDumper *ir_diff_dumper); + + private: + const std::string &lib_name_; + const std::string &arch_; + const std::string &old_dump_; + const std::string &new_dump_; + const std::string &cr_; + const std::set<std::string> &ignored_symbols_; + const DiffPolicyOptions &diff_policy_options_; + bool check_all_apis_; + std::set<std::string> type_cache_; + repr::TextFormatIR text_format_old_; + repr::TextFormatIR text_format_new_; + repr::TextFormatIR text_format_diff_; +}; + + +} // namespace diff +} // namespace header_checker + + +#endif // ABI_DIFF_H_ diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp b/vndk/tools/header-checker/src/diff/abi_diff_wrappers.cpp index 4614bea6c..3722c46bd 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp +++ b/vndk/tools/header-checker/src/diff/abi_diff_wrappers.cpp @@ -12,21 +12,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "abi_diff_wrappers.h" +#include "diff/abi_diff_wrappers.h" -#include "header_abi_util.h" +#include "utils/header_abi_util.h" #include <llvm/Support/raw_ostream.h> -namespace abi_diff_wrappers { -using abi_util::AbiElementMap; -using abi_util::DiffStatus; -using abi_util::Unwind; +namespace header_checker { +namespace diff { + + +using repr::AbiElementMap; +using repr::DiffStatus; +using repr::Unwind; + template <> -bool DiffWrapper<abi_util::RecordTypeIR>::DumpDiff( - abi_util::DiffMessageIR::DiffKind diff_kind) { +bool DiffWrapper<repr::RecordTypeIR>::DumpDiff( + repr::DiffMessageIR::DiffKind diff_kind) { std::deque<std::string> type_queue; if (oldp_->GetUniqueId() != newp_->GetUniqueId()) { llvm::errs() << "Comparing two different unreferenced records\n"; @@ -41,8 +45,8 @@ bool DiffWrapper<abi_util::RecordTypeIR>::DumpDiff( } template <> -bool DiffWrapper<abi_util::EnumTypeIR>::DumpDiff( - abi_util::DiffMessageIR::DiffKind diff_kind) { +bool DiffWrapper<repr::EnumTypeIR>::DumpDiff( + repr::DiffMessageIR::DiffKind diff_kind) { std::deque<std::string> type_queue; if (oldp_->GetUniqueId() != newp_->GetUniqueId()) { llvm::errs() << "Comparing two different unreferenced enums\n"; @@ -57,8 +61,8 @@ bool DiffWrapper<abi_util::EnumTypeIR>::DumpDiff( } template <> -bool DiffWrapper<abi_util::GlobalVarIR>::DumpDiff( - abi_util::DiffMessageIR::DiffKind diff_kind) { +bool DiffWrapper<repr::GlobalVarIR>::DumpDiff( + repr::DiffMessageIR::DiffKind diff_kind) { std::deque<std::string> type_queue; type_queue.push_back(oldp_->GetName()); DiffStatus type_diff = CompareAndDumpTypeDiff(oldp_->GetReferencedType(), @@ -67,11 +71,11 @@ bool DiffWrapper<abi_util::GlobalVarIR>::DumpDiff( DiffStatus access_diff = (oldp_->GetAccess() == newp_->GetAccess()) ? DiffStatus::no_diff : DiffStatus::direct_diff; if ((type_diff | access_diff) & DiffStatus::direct_diff) { - abi_util::GlobalVarIR old_global_var = *oldp_; - abi_util::GlobalVarIR new_global_var = *newp_; + repr::GlobalVarIR old_global_var = *oldp_; + repr::GlobalVarIR new_global_var = *newp_; ReplaceTypeIdsWithTypeNames(old_types_, &old_global_var); ReplaceTypeIdsWithTypeNames(new_types_, &new_global_var); - abi_util::GlobalVarDiffIR global_var_diff_ir(&old_global_var, + repr::GlobalVarDiffIR global_var_diff_ir(&old_global_var, &new_global_var); global_var_diff_ir.SetName(oldp_->GetName()); return ir_diff_dumper_->AddDiffMessageIR(&global_var_diff_ir, @@ -81,8 +85,8 @@ bool DiffWrapper<abi_util::GlobalVarIR>::DumpDiff( } template <> -bool DiffWrapper<abi_util::FunctionIR>::DumpDiff( - abi_util::DiffMessageIR::DiffKind diff_kind) { +bool DiffWrapper<repr::FunctionIR>::DumpDiff( + repr::DiffMessageIR::DiffKind diff_kind) { std::deque<std::string> type_queue; type_queue.push_back(oldp_->GetName()); @@ -99,11 +103,11 @@ bool DiffWrapper<abi_util::FunctionIR>::DumpDiff( if ((param_diffs == DiffStatus::direct_diff || return_type_diff == DiffStatus::direct_diff) || (oldp_->GetAccess() != newp_->GetAccess())) { - abi_util::FunctionIR old_function = *oldp_; - abi_util::FunctionIR new_function = *newp_; + repr::FunctionIR old_function = *oldp_; + repr::FunctionIR new_function = *newp_; ReplaceTypeIdsWithTypeNames(old_types_, &old_function); ReplaceTypeIdsWithTypeNames(new_types_, &new_function); - abi_util::FunctionDiffIR function_diff_ir(&old_function, &new_function); + repr::FunctionDiffIR function_diff_ir(&old_function, &new_function); function_diff_ir.SetName(oldp_->GetName()); return ir_diff_dumper_->AddDiffMessageIR(&function_diff_ir, Unwind(&type_queue), diff_kind); @@ -111,4 +115,6 @@ bool DiffWrapper<abi_util::FunctionIR>::DumpDiff( return true; } -} // namespace abi_diff_wrappers + +} // namespace diff +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h b/vndk/tools/header-checker/src/diff/abi_diff_wrappers.h index 8a4845254..baa4a5f19 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h +++ b/vndk/tools/header-checker/src/diff/abi_diff_wrappers.h @@ -15,16 +15,18 @@ #ifndef ABI_DIFF_WRAPPERS_H_ #define ABI_DIFF_WRAPPERS_H_ -#include "abi_diff_helpers.h" -#include "ir_representation.h" +#include "repr/abi_diff_helpers.h" +#include "repr/ir_representation.h" -#include <deque> -namespace abi_diff_wrappers { +namespace header_checker { +namespace diff { + + +using repr::AbiDiffHelper; +using repr::AbiElementMap; +using repr::DiffStatus; -using abi_util::AbiElementMap; -using abi_util::AbiDiffHelper; -using abi_util::DiffStatus; template <typename T, typename F> static bool IgnoreSymbol(const T *element, @@ -37,22 +39,25 @@ template <typename T> class DiffWrapper : public AbiDiffHelper { public: DiffWrapper(const T *oldp, const T *newp, - abi_util::IRDiffDumper *ir_diff_dumper, - const AbiElementMap<const abi_util::TypeIR *> &old_types, - const AbiElementMap<const abi_util::TypeIR *> &new_types, - const abi_util::DiffPolicyOptions &diff_policy_options, + repr::IRDiffDumper *ir_diff_dumper, + const AbiElementMap<const repr::TypeIR *> &old_types, + const AbiElementMap<const repr::TypeIR *> &new_types, + const repr::DiffPolicyOptions &diff_policy_options, std::set<std::string> *type_cache) : AbiDiffHelper(old_types, new_types, diff_policy_options, type_cache, ir_diff_dumper), oldp_(oldp), newp_(newp) {} - bool DumpDiff(abi_util::IRDiffDumper::DiffKind diff_kind); + bool DumpDiff(repr::IRDiffDumper::DiffKind diff_kind); private: const T *oldp_; const T *newp_; }; -} // namespace abi_diff_wrappers + +} // namespace diff +} // namespace header_checker + #endif // ABI_DIFF_WRAPPERS_H_ diff --git a/vndk/tools/header-checker/header-abi-diff/src/header_abi_diff.cpp b/vndk/tools/header-checker/src/diff/header_abi_diff.cpp index a3a3ab295..ac13b535f 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/header_abi_diff.cpp +++ b/vndk/tools/header-checker/src/diff/header_abi_diff.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "abi_diff.h" +#include "diff/abi_diff.h" #include <llvm/Support/CommandLine.h> #include <llvm/Support/FileSystem.h> @@ -20,6 +20,13 @@ #include <fstream> + +using header_checker::diff::HeaderAbiDiff; +using header_checker::repr::CompatibilityStatusIR; +using header_checker::repr::DiffPolicyOptions; +using header_checker::repr::TextFormatIR; + + static llvm::cl::OptionCategory header_checker_category( "header-abi-diff options"); @@ -91,27 +98,27 @@ static llvm::cl::opt<bool> consider_opaque_types_different( "This should not be used while comparing C++ library ABIs"), llvm::cl::Optional, llvm::cl::cat(header_checker_category)); -static llvm::cl::opt<abi_util::TextFormatIR> text_format_old( +static llvm::cl::opt<TextFormatIR> text_format_old( "input-format-old", llvm::cl::desc("Specify input format of old abi dump"), - llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + llvm::cl::values(clEnumValN(TextFormatIR::ProtobufTextFormat, "ProtobufTextFormat", "ProtobufTextFormat"), - clEnumValN(abi_util::TextFormatIR::Json, "Json", "JSON")), - llvm::cl::init(abi_util::TextFormatIR::Json), + clEnumValN(TextFormatIR::Json, "Json", "JSON")), + llvm::cl::init(TextFormatIR::Json), llvm::cl::cat(header_checker_category)); -static llvm::cl::opt<abi_util::TextFormatIR> text_format_new( +static llvm::cl::opt<TextFormatIR> text_format_new( "input-format-new", llvm::cl::desc("Specify input format of new abi dump"), - llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + llvm::cl::values(clEnumValN(TextFormatIR::ProtobufTextFormat, "ProtobufTextFormat", "ProtobufTextFormat"), - clEnumValN(abi_util::TextFormatIR::Json, "Json", "JSON")), - llvm::cl::init(abi_util::TextFormatIR::Json), + clEnumValN(TextFormatIR::Json, "Json", "JSON")), + llvm::cl::init(TextFormatIR::Json), llvm::cl::cat(header_checker_category)); -static llvm::cl::opt<abi_util::TextFormatIR> text_format_diff( +static llvm::cl::opt<TextFormatIR> text_format_diff( "text-format-diff", llvm::cl::desc("Specify text format of abi-diff"), - llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + llvm::cl::values(clEnumValN(TextFormatIR::ProtobufTextFormat, "ProtobufTextFormat", "ProtobufTextFormat")), - llvm::cl::init(abi_util::TextFormatIR::ProtobufTextFormat), + llvm::cl::init(TextFormatIR::ProtobufTextFormat), llvm::cl::cat(header_checker_category)); static std::set<std::string> LoadIgnoredSymbols(std::string &symbol_list_path) { @@ -131,14 +138,14 @@ static std::set<std::string> LoadIgnoredSymbols(std::string &symbol_list_path) { static const char kWarn[] = "\033[36;1mwarning: \033[0m"; static const char kError[] = "\033[31;1merror: \033[0m"; -bool ShouldEmitWarningMessage(abi_util::CompatibilityStatusIR status) { +bool ShouldEmitWarningMessage(CompatibilityStatusIR status) { return ((!allow_extensions && - (status & abi_util::CompatibilityStatusIR::Extension)) || + (status & CompatibilityStatusIR::Extension)) || (!allow_unreferenced_changes && - (status & abi_util::CompatibilityStatusIR::UnreferencedChanges)) || + (status & CompatibilityStatusIR::UnreferencedChanges)) || (!allow_unreferenced_elf_symbol_changes && - (status & abi_util::CompatibilityStatusIR::ElfIncompatible)) || - (status & abi_util::CompatibilityStatusIR::Incompatible)); + (status & CompatibilityStatusIR::ElfIncompatible)) || + (status & CompatibilityStatusIR::Incompatible)); } int main(int argc, const char **argv) { @@ -147,24 +154,24 @@ int main(int argc, const char **argv) { if (llvm::sys::fs::exists(ignore_symbol_list)) { ignored_symbols = LoadIgnoredSymbols(ignore_symbol_list); } - abi_util::DiffPolicyOptions diff_policy_options( + DiffPolicyOptions diff_policy_options( consider_opaque_types_different); HeaderAbiDiff judge(lib_name, arch, old_dump, new_dump, compatibility_report, ignored_symbols, diff_policy_options, check_all_apis, text_format_old, text_format_new, text_format_diff); - abi_util::CompatibilityStatusIR status = judge.GenerateCompatibilityReport(); + CompatibilityStatusIR status = judge.GenerateCompatibilityReport(); std::string status_str = ""; std::string unreferenced_change_str = ""; std::string error_or_warning_str = kWarn; switch (status) { - case abi_util::CompatibilityStatusIR::Incompatible: + case CompatibilityStatusIR::Incompatible: error_or_warning_str = kError; status_str = "INCOMPATIBLE CHANGES"; break; - case abi_util::CompatibilityStatusIR::ElfIncompatible: + case CompatibilityStatusIR::ElfIncompatible: if (elf_unreferenced_symbol_errors) { error_or_warning_str = kError; } @@ -173,13 +180,13 @@ int main(int argc, const char **argv) { default: break; } - if (status & abi_util::CompatibilityStatusIR::Extension) { + if (status & CompatibilityStatusIR::Extension) { if (!allow_extensions) { error_or_warning_str = kError; } status_str = "EXTENDING CHANGES"; } - if (status & abi_util::CompatibilityStatusIR::UnreferencedChanges) { + if (status & CompatibilityStatusIR::UnreferencedChanges) { unreferenced_change_str = ", changes in exported headers, which are"; unreferenced_change_str += " not directly referenced by exported symbols."; unreferenced_change_str += " This MIGHT be an ABI breaking change due to"; @@ -205,5 +212,5 @@ int main(int argc, const char **argv) { return status; } - return abi_util::CompatibilityStatusIR::Compatible; + return CompatibilityStatusIR::Compatible; } diff --git a/vndk/tools/header-checker/merge-abi-diff/src/merge_abi_diff.cpp b/vndk/tools/header-checker/src/diff_merge/merge_abi_diff.cpp index 7844261e9..dd582eafe 100644 --- a/vndk/tools/header-checker/merge-abi-diff/src/merge_abi_diff.cpp +++ b/vndk/tools/header-checker/src/diff_merge/merge_abi_diff.cpp @@ -12,14 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "header_abi_util.h" - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#pragma clang diagnostic ignored "-Wnested-anon-types" -#include "abi_dump.pb.h" -#include "abi_diff.pb.h" -#pragma clang diagnostic pop +#include "repr/protobuf/abi_diff.h" +#include "repr/protobuf/abi_dump.h" #include <google/protobuf/text_format.h> #include <google/protobuf/io/zero_copy_stream_impl.h> @@ -35,39 +29,39 @@ #include <stdlib.h> -static llvm::cl::OptionCategory merge_abi_diff_category( + +static llvm::cl::OptionCategory merge_diff_category( "merge-abi-diff options"); static llvm::cl::list<std::string> diff_report_list( llvm::cl::Positional, llvm::cl::desc("<diff-reports>"), llvm::cl::Required, - llvm::cl::cat(merge_abi_diff_category), llvm::cl::OneOrMore); + llvm::cl::cat(merge_diff_category), llvm::cl::OneOrMore); static llvm::cl::opt<std::string> merged_diff_report( "o", llvm::cl::desc("<merged-diff-report>"), llvm::cl::Required, - llvm::cl::cat(merge_abi_diff_category)); + llvm::cl::cat(merge_diff_category)); static llvm::cl::opt<bool> advice_only( "advice-only", llvm::cl::desc("Advisory mode only"), llvm::cl::Optional, - llvm::cl::cat(merge_abi_diff_category)); + llvm::cl::cat(merge_diff_category)); static llvm::cl::opt<bool> do_not_break_on_extensions( "allow-extensions", llvm::cl::desc("Do not return a non zero status on extensions"), - llvm::cl::Optional, llvm::cl::cat(merge_abi_diff_category)); + llvm::cl::Optional, llvm::cl::cat(merge_diff_category)); -typedef abi_diff::CompatibilityStatus CompatibilityStatus; - -static bool IsStatusDowngraded(const CompatibilityStatus &old_status, - const CompatibilityStatus &new_status) { +static bool IsStatusDowngraded( + const abi_diff::CompatibilityStatus &old_status, + const abi_diff::CompatibilityStatus &new_status) { bool status_downgraded = false; switch (old_status) { - case CompatibilityStatus::EXTENSION: - if (new_status == CompatibilityStatus::INCOMPATIBLE) { + case abi_diff::CompatibilityStatus::EXTENSION: + if (new_status == abi_diff::CompatibilityStatus::INCOMPATIBLE) { status_downgraded = true; } break; - case CompatibilityStatus::COMPATIBLE: - if (new_status != CompatibilityStatus::COMPATIBLE) { + case abi_diff::CompatibilityStatus::COMPATIBLE: + if (new_status != abi_diff::CompatibilityStatus::COMPATIBLE) { status_downgraded = true; } break; @@ -77,14 +71,14 @@ static bool IsStatusDowngraded(const CompatibilityStatus &old_status, return status_downgraded; } -static CompatibilityStatus MergeDiffReports( +static abi_diff::CompatibilityStatus MergeDiffReports( const std::vector<std::string> &diff_reports, const std::string &merged_diff_report) { - abi_diff::MergedTranslationUnitDiff merged_tu_diff; std::ofstream text_output(merged_diff_report); google::protobuf::io::OstreamOutputStream text_os(&text_output); - CompatibilityStatus status = CompatibilityStatus::COMPATIBLE; + abi_diff::CompatibilityStatus status = + abi_diff::CompatibilityStatus::COMPATIBLE; for (auto &&i : diff_reports) { abi_diff::TranslationUnitDiff diff_tu; @@ -100,7 +94,7 @@ static CompatibilityStatus MergeDiffReports( llvm::errs() << "Failed to add diff report to merged report\n"; ::exit(1); } - CompatibilityStatus new_status = diff_tu.compatibility_status(); + abi_diff::CompatibilityStatus new_status = diff_tu.compatibility_status(); added_tu_diff->set_lib_name(diff_tu.lib_name()); added_tu_diff->set_arch(diff_tu.arch()); added_tu_diff->set_diff_report_path(i); @@ -121,14 +115,14 @@ static CompatibilityStatus MergeDiffReports( int main(int argc, const char **argv) { GOOGLE_PROTOBUF_VERIFY_VERSION; llvm::cl::ParseCommandLineOptions(argc, argv, "merge-abi-diff"); - CompatibilityStatus extension_or_incompatible = + abi_diff::CompatibilityStatus extension_or_incompatible = MergeDiffReports(diff_report_list, merged_diff_report); std::string status_str = ""; switch (extension_or_incompatible) { - case CompatibilityStatus::INCOMPATIBLE: + case abi_diff::CompatibilityStatus::INCOMPATIBLE: status_str = "broken"; break; - case CompatibilityStatus::EXTENSION: + case abi_diff::CompatibilityStatus::EXTENSION: status_str = "extended"; break; default: @@ -145,12 +139,12 @@ int main(int argc, const char **argv) { } if (do_not_break_on_extensions && - extension_or_incompatible == CompatibilityStatus::EXTENSION) { - extension_or_incompatible = CompatibilityStatus::COMPATIBLE; + extension_or_incompatible == abi_diff::CompatibilityStatus::EXTENSION) { + extension_or_incompatible = abi_diff::CompatibilityStatus::COMPATIBLE; } if (!advice_only) { return extension_or_incompatible; } - return CompatibilityStatus::COMPATIBLE; + return abi_diff::CompatibilityStatus::COMPATIBLE; } diff --git a/vndk/tools/header-checker/header-abi-dumper/src/abi_wrappers.cpp b/vndk/tools/header-checker/src/dumper/abi_wrappers.cpp index d5773caad..b17a7fc22 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/abi_wrappers.cpp +++ b/vndk/tools/header-checker/src/dumper/abi_wrappers.cpp @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "abi_wrappers.h" +#include "dumper/abi_wrappers.h" -#include "header_abi_util.h" +#include "repr/ir_reader.h" +#include "utils/header_abi_util.h" #include <clang/AST/QualTypeNames.h> #include <clang/Index/CodegenNameGenerator.h> @@ -25,18 +26,21 @@ #include <limits.h> #include <stdlib.h> -using namespace abi_wrapper; + +namespace header_checker { +namespace dumper { + ABIWrapper::ABIWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *cip, - abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches) + repr::ModuleIR *module, + ASTCaches *ast_caches) : cip_(cip), mangle_contextp_(mangle_contextp), ast_contextp_(ast_contextp), - ir_dumper_(ir_dumper), + module_(module), ast_caches_(ast_caches) {} std::string ABIWrapper::GetCachedDeclSourceFile( @@ -149,22 +153,22 @@ std::string ABIWrapper::GetDeclSourceFile(const clang::Decl *decl, // belonging to the library. clang::SourceLocation expansion_location = sm.getExpansionLoc(location); llvm::StringRef file_name = sm.getFilename(expansion_location); - return abi_util::RealPath(file_name.str()); + return utils::RealPath(file_name.str()); } -static abi_util::AccessSpecifierIR AccessClangToIR( +static repr::AccessSpecifierIR AccessClangToIR( const clang::AccessSpecifier sp) { switch (sp) { case clang::AS_private: { - return abi_util::AccessSpecifierIR::PrivateAccess; + return repr::AccessSpecifierIR::PrivateAccess; break; } case clang::AS_protected: { - return abi_util::AccessSpecifierIR::ProtectedAccess; + return repr::AccessSpecifierIR::ProtectedAccess; break; } default: { - return abi_util::AccessSpecifierIR::PublicAccess; + return repr::AccessSpecifierIR::PublicAccess; break; } } @@ -172,7 +176,7 @@ static abi_util::AccessSpecifierIR AccessClangToIR( bool ABIWrapper::CreateAnonymousRecord(const clang::RecordDecl *record_decl) { RecordDeclWrapper record_decl_wrapper(mangle_contextp_, ast_contextp_, cip_, - record_decl, ir_dumper_, ast_caches_); + record_decl, module_, ast_caches_); return record_decl_wrapper.GetRecordDecl(); } @@ -197,7 +201,7 @@ static clang::QualType GetReferencedType(const clang::QualType qual_type) { } bool ABIWrapper::CreateExtendedType(clang::QualType qual_type, - abi_util::TypeIR *typep) { + repr::TypeIR *typep) { const clang::QualType canonical_type = qual_type.getCanonicalType(); // The source file is going to be set later anyway. return CreateBasicNamedAndTypedDecl(canonical_type, typep, ""); @@ -223,7 +227,7 @@ bool ABIWrapper::CreateBasicNamedAndTypedDecl(clang::QualType qual_type, // extending Type and return a pointer to that and pass it to CreateBasic... // CreateBasic...(qualtype, Type *) fills in size, alignemnt etc. auto type_and_status = SetTypeKind(canonical_type, source_file); - std::unique_ptr<abi_util::TypeIR> typep = std::move(type_and_status.typep_); + std::unique_ptr<repr::TypeIR> typep = std::move(type_and_status.typep_); if (!base_type->isVoidType() && type_and_status.should_create_type_ && !typep) { llvm::errs() << "nullptr with valid type while creating basic type\n"; @@ -234,7 +238,7 @@ bool ABIWrapper::CreateBasicNamedAndTypedDecl(clang::QualType qual_type, } return (CreateBasicNamedAndTypedDecl( canonical_type, typep.get(), source_file) && - ir_dumper_->AddLinkableMessageIR(typep.get())); + module_->AddLinkableMessage(*typep)); } std::string RecordDeclWrapper::GetMangledRTTI( @@ -266,7 +270,7 @@ std::string ABIWrapper::GetTypeUniqueId(const clang::TagDecl *tag_decl) { // include all the generic information of a basic type. Other methods will // create more specific information, e.g. RecordDecl, EnumDecl. bool ABIWrapper::CreateBasicNamedAndTypedDecl( - clang::QualType canonical_type, abi_util::TypeIR *typep, + clang::QualType canonical_type, repr::TypeIR *typep, const std::string &source_file) { // Cannot determine the size and alignment for template parameter dependent // types as well as incomplete types. @@ -312,7 +316,7 @@ TypeAndCreationStatus ABIWrapper::SetTypeKind( const clang::QualType canonical_type, const std::string &source_file) { if (canonical_type.hasLocalQualifiers()) { auto qual_type_ir = - std::make_unique<abi_util::QualifiedTypeIR>(); + std::make_unique<repr::QualifiedTypeIR>(); qual_type_ir->SetConstness(canonical_type.isConstQualified()); qual_type_ir->SetRestrictedness(canonical_type.isRestrictQualified()); qual_type_ir->SetVolatility(canonical_type.isVolatileQualified()); @@ -321,32 +325,32 @@ TypeAndCreationStatus ABIWrapper::SetTypeKind( } const clang::Type *type_ptr = canonical_type.getTypePtr(); if (type_ptr->isPointerType()) { - auto pointer_type_ir = std::make_unique<abi_util::PointerTypeIR>(); + auto pointer_type_ir = std::make_unique<repr::PointerTypeIR>(); pointer_type_ir->SetSourceFile(source_file); return TypeAndCreationStatus(std::move(pointer_type_ir)); } if (type_ptr->isLValueReferenceType()) { auto lvalue_reference_type_ir = - std::make_unique<abi_util::LvalueReferenceTypeIR>(); + std::make_unique<repr::LvalueReferenceTypeIR>(); lvalue_reference_type_ir->SetSourceFile(source_file); return TypeAndCreationStatus(std::move(lvalue_reference_type_ir)); } if (type_ptr->isRValueReferenceType()) { auto rvalue_reference_type_ir = - std::make_unique<abi_util::RvalueReferenceTypeIR>(); + std::make_unique<repr::RvalueReferenceTypeIR>(); rvalue_reference_type_ir->SetSourceFile(source_file); return TypeAndCreationStatus(std::move(rvalue_reference_type_ir)); } if (type_ptr->isArrayType()) { - auto array_type_ir = std::make_unique<abi_util::ArrayTypeIR>(); + auto array_type_ir = std::make_unique<repr::ArrayTypeIR>(); array_type_ir->SetSourceFile(source_file); return TypeAndCreationStatus(std::move(array_type_ir)); } if (type_ptr->isEnumeralType()) { - return TypeAndCreationStatus(std::make_unique<abi_util::EnumTypeIR>()); + return TypeAndCreationStatus(std::make_unique<repr::EnumTypeIR>()); } if (type_ptr->isBuiltinType()) { - auto builtin_type_ir = std::make_unique<abi_util::BuiltinTypeIR>(); + auto builtin_type_ir = std::make_unique<repr::BuiltinTypeIR>(); builtin_type_ir->SetSignedness(type_ptr->isUnsignedIntegerType()); builtin_type_ir->SetIntegralType(type_ptr->isIntegralType(*ast_contextp_)); return TypeAndCreationStatus(std::move(builtin_type_ir)); @@ -354,7 +358,7 @@ TypeAndCreationStatus ABIWrapper::SetTypeKind( if (auto &&func_type_ptr = llvm::dyn_cast<const clang::FunctionType>(type_ptr)) { FunctionTypeWrapper function_type_wrapper(mangle_contextp_, ast_contextp_, - cip_, func_type_ptr, ir_dumper_, + cip_, func_type_ptr, module_, ast_caches_, source_file); if (!function_type_wrapper.GetFunctionType()) { llvm::errs() << "FunctionType could not be created\n"; @@ -396,9 +400,9 @@ std::string ABIWrapper::GetTagDeclQualifiedName(const clang::TagDecl *decl) { } bool ABIWrapper::SetupTemplateArguments(const clang::TemplateArgumentList *tl, - abi_util::TemplatedArtifactIR *ta, + repr::TemplatedArtifactIR *ta, const std::string &source_file) { - abi_util::TemplateInfoIR template_info; + repr::TemplateInfoIR template_info; for (int i = 0; i < tl->size(); i++) { const clang::TemplateArgument &arg = (*tl)[i]; // TODO: More comprehensive checking needed. @@ -407,7 +411,7 @@ bool ABIWrapper::SetupTemplateArguments(const clang::TemplateArgumentList *tl, } clang::QualType type = arg.getAsType(); template_info.AddTemplateElement( - abi_util::TemplateElementIR( + repr::TemplateElementIR( ast_caches_->GetTypeId(GetKeyForTypeId(type)))); if (!CreateBasicNamedAndTypedDecl(type, source_file)) { llvm::errs() << "Setting up template arguments failed\n"; @@ -432,15 +436,15 @@ std::string ABIWrapper::QualTypeToString(const clang::QualType &sweet_qt) { FunctionTypeWrapper::FunctionTypeWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::FunctionType *function_type, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches, const std::string &source_file) - : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper, + const clang::FunctionType *function_type, repr::ModuleIR *module, + ASTCaches *ast_caches, const std::string &source_file) + : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, module, ast_caches), function_type_(function_type), source_file_(source_file) {} bool FunctionTypeWrapper::SetupFunctionType( - abi_util::FunctionTypeIR *function_type_ir) { + repr::FunctionTypeIR *function_type_ir) { // Add ReturnType function_type_ir->SetReturnType( ast_caches_->GetTypeId(GetKeyForTypeId(function_type_->getReturnType()))); @@ -461,14 +465,14 @@ bool FunctionTypeWrapper::SetupFunctionType( } bool FunctionTypeWrapper::GetFunctionType() { - auto abi_decl = std::make_unique<abi_util::FunctionTypeIR>(); + auto abi_decl = std::make_unique<repr::FunctionTypeIR>(); clang::QualType canonical_type = function_type_->getCanonicalTypeInternal(); if (!CreateBasicNamedAndTypedDecl(canonical_type, abi_decl.get(), "")) { llvm::errs() << "Couldn't create (function type) extended type\n"; return false; } return SetupFunctionType(abi_decl.get()) && - ir_dumper_->AddLinkableMessageIR(abi_decl.get()); + module_->AddLinkableMessage(*abi_decl); } FunctionDeclWrapper::FunctionDeclWrapper( @@ -476,13 +480,13 @@ FunctionDeclWrapper::FunctionDeclWrapper( clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, const clang::FunctionDecl *decl, - abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches) - : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper, + repr::ModuleIR *module, + ASTCaches *ast_caches) + : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, module, ast_caches), function_decl_(decl) {} -bool FunctionDeclWrapper::SetupThisParameter(abi_util::FunctionIR *functionp, +bool FunctionDeclWrapper::SetupThisParameter(repr::FunctionIR *functionp, const std::string &source_file) { const clang::CXXMethodDecl *cxx_method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(function_decl_); @@ -495,20 +499,20 @@ bool FunctionDeclWrapper::SetupThisParameter(abi_util::FunctionIR *functionp, } bool ABIWrapper::SetupFunctionParameter( - abi_util::CFunctionLikeIR *functionp, const clang::QualType qual_type, + repr::CFunctionLikeIR *functionp, const clang::QualType qual_type, bool has_default_arg, const std::string &source_file, bool is_this_ptr) { if (!CreateBasicNamedAndTypedDecl(qual_type, source_file)) { llvm::errs() << "Setting up function parameter failed\n"; return false; } - functionp->AddParameter(abi_util::ParamIR( + functionp->AddParameter(repr::ParamIR( ast_caches_->GetTypeId(GetKeyForTypeId(qual_type)), has_default_arg, is_this_ptr)); return true; } bool FunctionDeclWrapper::SetupFunctionParameters( - abi_util::FunctionIR *functionp, + repr::FunctionIR *functionp, const std::string &source_file) { clang::FunctionDecl::param_const_iterator param_it = function_decl_->param_begin(); @@ -531,7 +535,7 @@ bool FunctionDeclWrapper::SetupFunctionParameters( return true; } -bool FunctionDeclWrapper::SetupFunction(abi_util::FunctionIR *functionp, +bool FunctionDeclWrapper::SetupFunction(repr::FunctionIR *functionp, const std::string &source_file) { // Go through all the parameters in the method and add them to the fields. // Also get the fully qualfied name. @@ -548,7 +552,7 @@ bool FunctionDeclWrapper::SetupFunction(abi_util::FunctionIR *functionp, SetupTemplateInfo(functionp, source_file); } -bool FunctionDeclWrapper::SetupTemplateInfo(abi_util::FunctionIR *functionp, +bool FunctionDeclWrapper::SetupTemplateInfo(repr::FunctionIR *functionp, const std::string &source_file) { switch (function_decl_->getTemplatedKind()) { case clang::FunctionDecl::TK_FunctionTemplateSpecialization: { @@ -567,8 +571,8 @@ bool FunctionDeclWrapper::SetupTemplateInfo(abi_util::FunctionIR *functionp, return true; } -std::unique_ptr<abi_util::FunctionIR> FunctionDeclWrapper::GetFunctionDecl() { - auto abi_decl = std::make_unique<abi_util::FunctionIR>(); +std::unique_ptr<repr::FunctionIR> FunctionDeclWrapper::GetFunctionDecl() { + auto abi_decl = std::make_unique<repr::FunctionIR>(); std::string source_file = GetCachedDeclSourceFile(function_decl_, cip_); if (!SetupFunction(abi_decl.get(), source_file)) { return nullptr; @@ -580,13 +584,13 @@ RecordDeclWrapper::RecordDeclWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::RecordDecl *decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches) - : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper, + const clang::RecordDecl *decl, repr::ModuleIR *module, + ASTCaches *ast_caches) + : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, module, ast_caches), record_decl_(decl) {} -bool RecordDeclWrapper::SetupRecordFields(abi_util::RecordTypeIR *recordp, +bool RecordDeclWrapper::SetupRecordFields(repr::RecordTypeIR *recordp, const std::string &source_file) { clang::RecordDecl::field_iterator field = record_decl_->field_begin(); uint32_t field_index = 0; @@ -606,7 +610,7 @@ bool RecordDeclWrapper::SetupRecordFields(abi_util::RecordTypeIR *recordp, } std::string field_name = field->getName(); uint64_t field_offset = record_layout.getFieldOffset(field_index); - recordp->AddRecordField(abi_util::RecordFieldIR( + recordp->AddRecordField(repr::RecordFieldIR( field_name, ast_caches_->GetTypeId(key_for_type_id), field_offset, AccessClangToIR(field->getAccess()))); field++; @@ -616,7 +620,7 @@ bool RecordDeclWrapper::SetupRecordFields(abi_util::RecordTypeIR *recordp, } bool RecordDeclWrapper::SetupCXXBases( - abi_util::RecordTypeIR *cxxp, const clang::CXXRecordDecl *cxx_record_decl) { + repr::RecordTypeIR *cxxp, const clang::CXXRecordDecl *cxx_record_decl) { if (!cxx_record_decl || !cxxp) { return false; } @@ -625,10 +629,10 @@ bool RecordDeclWrapper::SetupCXXBases( while (base_class != cxx_record_decl->bases_end()) { std::string name = QualTypeToString(base_class->getType()); bool is_virtual = base_class->isVirtual(); - abi_util::AccessSpecifierIR access = + repr::AccessSpecifierIR access = AccessClangToIR(base_class->getAccessSpecifier()); cxxp->AddCXXBaseSpecifier( - abi_util::CXXBaseSpecifierIR( + repr::CXXBaseSpecifierIR( ast_caches_->GetTypeId(GetKeyForTypeId(base_class->getType())), is_virtual, access)); base_class++; @@ -639,7 +643,7 @@ bool RecordDeclWrapper::SetupCXXBases( typedef std::map<uint64_t, clang::ThunkInfo> ThunkMap; bool RecordDeclWrapper::SetupRecordVTable( - abi_util::RecordTypeIR *record_declp, + repr::RecordTypeIR *record_declp, const clang::CXXRecordDecl *cxx_record_decl) { if (!cxx_record_decl || !record_declp) { return false; @@ -662,7 +666,7 @@ bool RecordDeclWrapper::SetupRecordVTable( llvm::ArrayRef<clang::VTableLayout::VTableThunkTy> thunks = vtable_layout.vtable_thunks(); ThunkMap thunk_map(thunks.begin(), thunks.end()); - abi_util::VTableLayoutIR vtable_ir_layout; + repr::VTableLayoutIR vtable_ir_layout; uint64_t index = 0; for (auto vtable_component : vtable_layout.vtable_components()) { @@ -671,7 +675,7 @@ bool RecordDeclWrapper::SetupRecordVTable( if (it != thunk_map.end()) { thunk_info = it->second; } - abi_util::VTableComponentIR added_component = + repr::VTableComponentIR added_component = SetupRecordVTableComponent(vtable_component, thunk_info); vtable_ir_layout.AddVTableComponent(std::move(added_component)); index++; @@ -680,11 +684,11 @@ bool RecordDeclWrapper::SetupRecordVTable( return true; } -abi_util::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent( +repr::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent( const clang::VTableComponent &vtable_component, const clang::ThunkInfo &thunk_info) { - abi_util::VTableComponentIR::Kind kind = - abi_util::VTableComponentIR::Kind::RTTI; + repr::VTableComponentIR::Kind kind = + repr::VTableComponentIR::Kind::RTTI; std::string mangled_component_name = ""; llvm::raw_string_ostream ostream(mangled_component_name); int64_t value = 0; @@ -694,20 +698,20 @@ abi_util::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent( switch (clang_component_kind) { case clang::VTableComponent::CK_VCallOffset: - kind = abi_util::VTableComponentIR::Kind::VCallOffset; + kind = repr::VTableComponentIR::Kind::VCallOffset; value = vtable_component.getVCallOffset().getQuantity(); break; case clang::VTableComponent::CK_VBaseOffset: - kind = abi_util::VTableComponentIR::Kind::VBaseOffset; + kind = repr::VTableComponentIR::Kind::VBaseOffset; value = vtable_component.getVBaseOffset().getQuantity(); break; case clang::VTableComponent::CK_OffsetToTop: - kind = abi_util::VTableComponentIR::Kind::OffsetToTop; + kind = repr::VTableComponentIR::Kind::OffsetToTop; value = vtable_component.getOffsetToTop().getQuantity(); break; case clang::VTableComponent::CK_RTTI: { - kind = abi_util::VTableComponentIR::Kind::RTTI; + kind = repr::VTableComponentIR::Kind::RTTI; const clang::CXXRecordDecl *rtti_decl = vtable_component.getRTTIDecl(); assert(rtti_decl != nullptr); @@ -725,7 +729,7 @@ abi_util::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent( is_pure = method_decl->isPure(); switch (clang_component_kind) { case clang::VTableComponent::CK_FunctionPointer: - kind = abi_util::VTableComponentIR::Kind::FunctionPointer; + kind = repr::VTableComponentIR::Kind::FunctionPointer; if (thunk_info.isEmpty()) { mangle_contextp_->mangleName(method_decl, ostream); } else { @@ -740,10 +744,10 @@ abi_util::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent( if (clang_component_kind == clang::VTableComponent::CK_CompleteDtorPointer) { dtor_type = clang::CXXDtorType::Dtor_Complete; - kind = abi_util::VTableComponentIR::Kind::CompleteDtorPointer; + kind = repr::VTableComponentIR::Kind::CompleteDtorPointer; } else { dtor_type = clang::CXXDtorType::Dtor_Deleting; - kind = abi_util::VTableComponentIR::Kind::DeletingDtorPointer; + kind = repr::VTableComponentIR::Kind::DeletingDtorPointer; } if (thunk_info.isEmpty()) { @@ -758,7 +762,7 @@ abi_util::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent( } break; case clang::VTableComponent::CK_UnusedFunctionPointer: - kind = abi_util::VTableComponentIR::Kind::UnusedFunctionPointer; + kind = repr::VTableComponentIR::Kind::UnusedFunctionPointer; break; default: break; @@ -768,12 +772,12 @@ abi_util::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent( default: break; } - return abi_util::VTableComponentIR(mangled_component_name, kind, value, + return repr::VTableComponentIR(mangled_component_name, kind, value, is_pure); } bool RecordDeclWrapper::SetupTemplateInfo( - abi_util::RecordTypeIR *record_declp, + repr::RecordTypeIR *record_declp, const clang::CXXRecordDecl *cxx_record_decl, const std::string &source_file) { assert(cxx_record_decl != nullptr); @@ -790,20 +794,20 @@ bool RecordDeclWrapper::SetupTemplateInfo( return true; } -bool RecordDeclWrapper::SetupRecordInfo(abi_util::RecordTypeIR *record_declp, +bool RecordDeclWrapper::SetupRecordInfo(repr::RecordTypeIR *record_declp, const std::string &source_file) { if (!record_declp) { return false; } if (record_decl_->isStruct()) { record_declp->SetRecordKind( - abi_util::RecordTypeIR::RecordKind::struct_kind); + repr::RecordTypeIR::RecordKind::struct_kind); } else if (record_decl_->isClass()) { record_declp->SetRecordKind( - abi_util::RecordTypeIR::RecordKind::class_kind); + repr::RecordTypeIR::RecordKind::class_kind); } else { record_declp->SetRecordKind( - abi_util::RecordTypeIR::RecordKind::union_kind); + repr::RecordTypeIR::RecordKind::union_kind); } const clang::Type *basic_type = nullptr; @@ -825,7 +829,7 @@ bool RecordDeclWrapper::SetupRecordInfo(abi_util::RecordTypeIR *record_declp, SetupCXXRecordInfo(record_declp, source_file); } -bool RecordDeclWrapper::SetupCXXRecordInfo(abi_util::RecordTypeIR *record_declp, +bool RecordDeclWrapper::SetupCXXRecordInfo(repr::RecordTypeIR *record_declp, const std::string &source_file) { const clang::CXXRecordDecl *cxx_record_decl = clang::dyn_cast<clang::CXXRecordDecl>(record_decl_); @@ -839,7 +843,7 @@ bool RecordDeclWrapper::SetupCXXRecordInfo(abi_util::RecordTypeIR *record_declp, // TODO: Can we use clang's ODR hash to do faster ODR checking? bool RecordDeclWrapper::GetRecordDecl() { - auto abi_decl = std::make_unique<abi_util::RecordTypeIR>(); + auto abi_decl = std::make_unique<repr::RecordTypeIR>(); std::string source_file = GetCachedDeclSourceFile(record_decl_, cip_); if (!SetupRecordInfo(abi_decl.get(), source_file)) { llvm::errs() << "Setting up CXX Bases / Template Info failed\n"; @@ -851,20 +855,20 @@ bool RecordDeclWrapper::GetRecordDecl() { // cached, don't add the record. return true; } - return ir_dumper_->AddLinkableMessageIR(abi_decl.get()); + return module_->AddLinkableMessage(*abi_decl); } EnumDeclWrapper::EnumDeclWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::EnumDecl *decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches) - : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper, + const clang::EnumDecl *decl, repr::ModuleIR *module, + ASTCaches *ast_caches) + : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, module, ast_caches), enum_decl_(decl) {} -bool EnumDeclWrapper::SetupEnumFields(abi_util::EnumTypeIR *enump) { +bool EnumDeclWrapper::SetupEnumFields(repr::EnumTypeIR *enump) { if (!enump) { return false; } @@ -872,13 +876,13 @@ bool EnumDeclWrapper::SetupEnumFields(abi_util::EnumTypeIR *enump) { while (enum_it != enum_decl_->enumerator_end()) { std::string name = enum_it->getQualifiedNameAsString(); uint64_t field_value = enum_it->getInitVal().getExtValue(); - enump->AddEnumField(abi_util::EnumFieldIR(name, field_value)); + enump->AddEnumField(repr::EnumFieldIR(name, field_value)); enum_it++; } return true; } -bool EnumDeclWrapper::SetupEnum(abi_util::EnumTypeIR *enum_type, +bool EnumDeclWrapper::SetupEnum(repr::EnumTypeIR *enum_type, const std::string &source_file) { std::string enum_name = GetTagDeclQualifiedName(enum_decl_); clang::QualType enum_qual_type = @@ -896,27 +900,27 @@ bool EnumDeclWrapper::SetupEnum(abi_util::EnumTypeIR *enum_type, } bool EnumDeclWrapper::GetEnumDecl() { - auto abi_decl = std::make_unique<abi_util::EnumTypeIR>(); + auto abi_decl = std::make_unique<repr::EnumTypeIR>(); std::string source_file = GetCachedDeclSourceFile(enum_decl_, cip_); if (!SetupEnum(abi_decl.get(), source_file)) { llvm::errs() << "Setting up Enum failed\n"; return false; } - return ir_dumper_->AddLinkableMessageIR(abi_decl.get()); + return module_->AddLinkableMessage(*abi_decl); } GlobalVarDeclWrapper::GlobalVarDeclWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::VarDecl *decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches) - : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper, + const clang::VarDecl *decl, repr::ModuleIR *module, + ASTCaches *ast_caches) + : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, module, ast_caches), global_var_decl_(decl) {} -bool GlobalVarDeclWrapper::SetupGlobalVar(abi_util::GlobalVarIR *global_varp, +bool GlobalVarDeclWrapper::SetupGlobalVar(repr::GlobalVarIR *global_varp, const std::string &source_file) { // Temporary fix: clang segfaults on trying to mangle global variable which // is a dependent sized array type. @@ -935,8 +939,12 @@ bool GlobalVarDeclWrapper::SetupGlobalVar(abi_util::GlobalVarIR *global_varp, } bool GlobalVarDeclWrapper::GetGlobalVarDecl() { - auto abi_decl = std::make_unique<abi_util::GlobalVarIR>(); + auto abi_decl = std::make_unique<repr::GlobalVarIR>(); std::string source_file = GetCachedDeclSourceFile(global_var_decl_, cip_); return SetupGlobalVar(abi_decl.get(), source_file) && - ir_dumper_->AddLinkableMessageIR(abi_decl.get()); + module_->AddLinkableMessage(*abi_decl); } + + +} // dumper +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-dumper/src/abi_wrappers.h b/vndk/tools/header-checker/src/dumper/abi_wrappers.h index 3505020b7..d7c22449d 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/abi_wrappers.h +++ b/vndk/tools/header-checker/src/dumper/abi_wrappers.h @@ -15,8 +15,8 @@ #ifndef ABI_WRAPPERS_H_ #define ABI_WRAPPERS_H_ -#include "ast_util.h" -#include "ir_representation.h" +#include "dumper/ast_util.h" +#include "repr/ir_representation.h" #include <clang/AST/AST.h> #include <clang/AST/ASTConsumer.h> @@ -24,23 +24,27 @@ #include <clang/AST/VTableBuilder.h> #include <clang/Frontend/CompilerInstance.h> -namespace abi_wrapper { + +namespace header_checker { +namespace dumper { + struct TypeAndCreationStatus { - std::unique_ptr<abi_util::TypeIR> typep_; + std::unique_ptr<repr::TypeIR> typep_; bool should_create_type_; // Whether the type is to be created. - TypeAndCreationStatus(std::unique_ptr<abi_util::TypeIR> &&typep, + TypeAndCreationStatus(std::unique_ptr<repr::TypeIR> &&typep, bool should_create_type = true) : typep_(std::move(typep)), should_create_type_(should_create_type) {} }; + class ABIWrapper { public: ABIWrapper(clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *cip, - abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches); + repr::ModuleIR *module, + ASTCaches *ast_caches); static std::string GetDeclSourceFile(const clang::Decl *decl, const clang::CompilerInstance *cip); @@ -57,10 +61,10 @@ class ABIWrapper { std::string TypeNameWithFinalDestination(clang::QualType qual_type); bool SetupTemplateArguments(const clang::TemplateArgumentList *tl, - abi_util::TemplatedArtifactIR *ta, + repr::TemplatedArtifactIR *ta, const std::string &source_file); - bool SetupFunctionParameter(abi_util::CFunctionLikeIR *functionp, + bool SetupFunctionParameter(repr::CFunctionLikeIR *functionp, const clang::QualType qual_type, bool has_default_arg, const std::string &source_file, @@ -74,11 +78,11 @@ class ABIWrapper { const std::string &source_file); bool CreateBasicNamedAndTypedDecl(clang::QualType canonical_type, - abi_util::TypeIR *typep, + repr::TypeIR *typep, const std::string &source_file); bool CreateExtendedType(clang::QualType canonical_type, - abi_util::TypeIR *typep); + repr::TypeIR *typep); bool CreateAnonymousRecord(const clang::RecordDecl *decl); @@ -93,17 +97,18 @@ class ABIWrapper { const clang::CompilerInstance *cip_; clang::MangleContext *mangle_contextp_; clang::ASTContext *ast_contextp_; - abi_util::IRDumper *ir_dumper_; - ast_util::ASTCaches *ast_caches_; + repr::ModuleIR *module_; + ASTCaches *ast_caches_; }; + class RecordDeclWrapper : public ABIWrapper { public: RecordDeclWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::RecordDecl *record_decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches); + const clang::RecordDecl *record_decl, repr::ModuleIR *module, + ASTCaches *ast_caches); bool GetRecordDecl(); @@ -111,69 +116,71 @@ class RecordDeclWrapper : public ABIWrapper { const clang::RecordDecl *record_decl_; private: - bool SetupRecordInfo(abi_util::RecordTypeIR *type, + bool SetupRecordInfo(repr::RecordTypeIR *type, const std::string &source_file); - bool SetupRecordFields(abi_util::RecordTypeIR *record_declp, + bool SetupRecordFields(repr::RecordTypeIR *record_declp, const std::string &source_file); - bool SetupCXXBases(abi_util::RecordTypeIR *cxxp, + bool SetupCXXBases(repr::RecordTypeIR *cxxp, const clang::CXXRecordDecl *cxx_record_decl); - bool SetupTemplateInfo(abi_util::RecordTypeIR *record_declp, + bool SetupTemplateInfo(repr::RecordTypeIR *record_declp, const clang::CXXRecordDecl *cxx_record_decl, const std::string &source_file); - bool SetupRecordVTable(abi_util::RecordTypeIR *record_declp, + bool SetupRecordVTable(repr::RecordTypeIR *record_declp, const clang::CXXRecordDecl *cxx_record_decl); std::string GetMangledRTTI(const clang::CXXRecordDecl *cxx_record_decl); - abi_util::VTableComponentIR + repr::VTableComponentIR SetupRecordVTableComponent(const clang::VTableComponent &vtable_component, const clang::ThunkInfo &thunk_info); - bool SetupCXXRecordInfo(abi_util::RecordTypeIR *record_declp, + bool SetupCXXRecordInfo(repr::RecordTypeIR *record_declp, const std::string &source_file); }; + class FunctionDeclWrapper : public ABIWrapper { public: FunctionDeclWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::FunctionDecl *decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches); + const clang::FunctionDecl *decl, repr::ModuleIR *module, + ASTCaches *ast_caches); - std::unique_ptr<abi_util::FunctionIR> GetFunctionDecl(); + std::unique_ptr<repr::FunctionIR> GetFunctionDecl(); private: const clang::FunctionDecl *function_decl_; private: - bool SetupFunction(abi_util::FunctionIR *methodp, + bool SetupFunction(repr::FunctionIR *methodp, const std::string &source_file); - bool SetupTemplateInfo(abi_util::FunctionIR *functionp, + bool SetupTemplateInfo(repr::FunctionIR *functionp, const std::string &source_file); - bool SetupFunctionParameters(abi_util::FunctionIR *functionp, + bool SetupFunctionParameters(repr::FunctionIR *functionp, const std::string &source_file); - bool SetupThisParameter(abi_util::FunctionIR *functionp, + bool SetupThisParameter(repr::FunctionIR *functionp, const std::string &source_file); }; + class FunctionTypeWrapper : public ABIWrapper { private: - bool SetupFunctionType(abi_util::FunctionTypeIR *function_type_ir); + bool SetupFunctionType(repr::FunctionTypeIR *function_type_ir); public: FunctionTypeWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::FunctionType *function_type, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches, const std::string &source_file); + const clang::FunctionType *function_type, repr::ModuleIR *module, + ASTCaches *ast_caches, const std::string &source_file); bool GetFunctionType(); @@ -182,13 +189,14 @@ class FunctionTypeWrapper : public ABIWrapper { const std::string &source_file_; }; + class EnumDeclWrapper : public ABIWrapper { public: EnumDeclWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::EnumDecl *decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches); + const clang::EnumDecl *decl, repr::ModuleIR *module, + ASTCaches *ast_caches); bool GetEnumDecl(); @@ -196,19 +204,20 @@ class EnumDeclWrapper : public ABIWrapper { const clang::EnumDecl *enum_decl_; private: - bool SetupEnum(abi_util::EnumTypeIR *type, + bool SetupEnum(repr::EnumTypeIR *type, const std::string &source_file); - bool SetupEnumFields(abi_util::EnumTypeIR *enump); + bool SetupEnumFields(repr::EnumTypeIR *enump); }; + class GlobalVarDeclWrapper : public ABIWrapper { public: GlobalVarDeclWrapper( clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::VarDecl *decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches); + const clang::VarDecl *decl, repr::ModuleIR *module, + ASTCaches *ast_caches); bool GetGlobalVarDecl(); @@ -216,10 +225,13 @@ class GlobalVarDeclWrapper : public ABIWrapper { const clang::VarDecl *global_var_decl_; private: - bool SetupGlobalVar(abi_util::GlobalVarIR *global_varp, + bool SetupGlobalVar(repr::GlobalVarIR *global_varp, const std::string &source_file); }; -} // namespace abi_wrapper + +} // namespace dumper +} // namespace header_checker + #endif // ABI_WRAPPERS_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp b/vndk/tools/header-checker/src/dumper/ast_processing.cpp index 0aac0e332..3df360cca 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.cpp +++ b/vndk/tools/header-checker/src/dumper/ast_processing.cpp @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "ast_processing.h" +#include "dumper/ast_processing.h" -#include "abi_wrappers.h" +#include "dumper/abi_wrappers.h" +#include "repr/ir_dumper.h" #include <clang/Lex/Token.h> #include <clang/AST/QualTypeNames.h> @@ -24,21 +25,20 @@ #include <iostream> #include <string> -using abi_wrapper::ABIWrapper; -using abi_wrapper::FunctionDeclWrapper; -using abi_wrapper::RecordDeclWrapper; -using abi_wrapper::EnumDeclWrapper; -using abi_wrapper::GlobalVarDeclWrapper; + +namespace header_checker { +namespace dumper { + HeaderASTVisitor::HeaderASTVisitor( const HeaderCheckerOptions &options, clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, - const clang::Decl *tu_decl, abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches) + const clang::Decl *tu_decl, repr::ModuleIR *module, + ASTCaches *ast_caches) : options_(options), mangle_contextp_(mangle_contextp), ast_contextp_(ast_contextp), cip_(compiler_instance_p), tu_decl_(tu_decl), - ir_dumper_(ir_dumper), ast_caches_(ast_caches) {} + module_(module), ast_caches_(ast_caches) {} bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) { // Avoid segmentation fault in getASTRecordLayout. @@ -55,7 +55,7 @@ bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) { return true; } RecordDeclWrapper record_decl_wrapper( - mangle_contextp_, ast_contextp_, cip_, decl, ir_dumper_, ast_caches_); + mangle_contextp_, ast_contextp_, cip_, decl, module_, ast_caches_); return record_decl_wrapper.GetRecordDecl(); } @@ -66,24 +66,24 @@ bool HeaderASTVisitor::VisitEnumDecl(const clang::EnumDecl *decl) { return true; } EnumDeclWrapper enum_decl_wrapper( - mangle_contextp_, ast_contextp_, cip_, decl, ir_dumper_, ast_caches_); + mangle_contextp_, ast_contextp_, cip_, decl, module_, ast_caches_); return enum_decl_wrapper.GetEnumDecl(); } -static bool MutateFunctionWithLinkageName(const abi_util::FunctionIR *function, - abi_util::IRDumper *ir_dumper, +static bool MutateFunctionWithLinkageName(const repr::FunctionIR *function, + repr::ModuleIR *module, std::string &linkage_name) { - auto added_function = std::make_unique<abi_util::FunctionIR>(); + auto added_function = std::make_unique<repr::FunctionIR>(); *added_function = *function; added_function->SetLinkerSetKey(linkage_name); - return ir_dumper->AddLinkableMessageIR(added_function.get()); + return module->AddLinkableMessage(*added_function); } -static bool AddMangledFunctions(const abi_util::FunctionIR *function, - abi_util:: IRDumper *ir_dumper, +static bool AddMangledFunctions(const repr::FunctionIR *function, + repr:: ModuleIR *module, std::vector<std::string> &manglings) { for (auto &&mangling : manglings) { - if (!MutateFunctionWithLinkageName(function, ir_dumper, mangling)) { + if (!MutateFunctionWithLinkageName(function, module, mangling)) { return false; } } @@ -132,18 +132,18 @@ bool HeaderASTVisitor::VisitFunctionDecl(const clang::FunctionDecl *decl) { return true; } FunctionDeclWrapper function_decl_wrapper( - mangle_contextp_, ast_contextp_, cip_, decl, ir_dumper_, ast_caches_); + mangle_contextp_, ast_contextp_, cip_, decl, module_, ast_caches_); auto function_wrapper = function_decl_wrapper.GetFunctionDecl(); // Destructors and Constructors can have more than 1 symbol generated from the // same Decl. clang::index::CodegenNameGenerator cg(*ast_contextp_); std::vector<std::string> manglings = cg.getAllManglings(decl); if (!manglings.empty()) { - return AddMangledFunctions(function_wrapper.get(), ir_dumper_, manglings); + return AddMangledFunctions(function_wrapper.get(), module_, manglings); } std::string linkage_name = ABIWrapper::GetMangledNameDecl(decl, mangle_contextp_); - return MutateFunctionWithLinkageName(function_wrapper.get(), ir_dumper_, + return MutateFunctionWithLinkageName(function_wrapper.get(), module_, linkage_name); } @@ -154,7 +154,7 @@ bool HeaderASTVisitor::VisitVarDecl(const clang::VarDecl *decl) { return true; } GlobalVarDeclWrapper global_var_decl_wrapper( - mangle_contextp_, ast_contextp_, cip_, decl, ir_dumper_, ast_caches_); + mangle_contextp_, ast_contextp_, cip_, decl, module_, ast_caches_); return global_var_decl_wrapper.GetGlobalVarDecl(); } @@ -202,18 +202,30 @@ void HeaderASTConsumer::HandleTranslationUnit(clang::ASTContext &ctx) { ctx.createMangleContext()); const std::string &translation_unit_source = ABIWrapper::GetDeclSourceFile(translation_unit, cip_); - ast_util::ASTCaches ast_caches(translation_unit_source); + ASTCaches ast_caches(translation_unit_source); if (!options_.exported_headers_.empty()) { options_.exported_headers_.insert(translation_unit_source); } - std::unique_ptr<abi_util::IRDumper> ir_dumper = - abi_util::IRDumper::CreateIRDumper(options_.text_format_, - options_.dump_name_); + + std::unique_ptr<repr::ModuleIR> module( + new repr::ModuleIR(nullptr /*FIXME*/)); + HeaderASTVisitor v(options_, mangle_contextp.get(), &ctx, cip_, - translation_unit, ir_dumper.get(), &ast_caches); + translation_unit, module.get(), &ast_caches); + if (!v.TraverseDecl(translation_unit)) { + llvm::errs() << "ABI extraction failed\n"; + ::exit(1); + } - if (!v.TraverseDecl(translation_unit) || !ir_dumper->Dump()) { - llvm::errs() << "Serialization to ostream failed\n"; + std::unique_ptr<repr::IRDumper> ir_dumper = + repr::IRDumper::CreateIRDumper(options_.text_format_, + options_.dump_name_); + if (!ir_dumper->Dump(*module)) { + llvm::errs() << "Serialization failed\n"; ::exit(1); } } + + +} // dumper +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h b/vndk/tools/header-checker/src/dumper/ast_processing.h index 4e8cd5969..90443abc4 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/ast_processing.h +++ b/vndk/tools/header-checker/src/dumper/ast_processing.h @@ -15,8 +15,8 @@ #ifndef AST_PROCESSING_H_ #define AST_PROCESSING_H_ -#include "ast_util.h" -#include "header_checker.h" +#include "dumper/ast_util.h" +#include "dumper/header_checker.h" #include <clang/AST/AST.h> #include <clang/AST/ASTConsumer.h> @@ -27,6 +27,11 @@ #include <set> + +namespace header_checker { +namespace dumper { + + class HeaderASTVisitor : public clang::RecursiveASTVisitor<HeaderASTVisitor> { public: @@ -35,8 +40,8 @@ class HeaderASTVisitor clang::ASTContext *ast_contextp, const clang::CompilerInstance *compiler_instance_p, const clang::Decl *tu_decl, - abi_util::IRDumper *ir_dumper, - ast_util::ASTCaches *ast_caches); + repr::ModuleIR *module, + ASTCaches *ast_caches); bool VisitRecordDecl(const clang::RecordDecl *decl); @@ -60,12 +65,13 @@ class HeaderASTVisitor const clang::CompilerInstance *cip_; // To optimize recursion into only exported abi. const clang::Decl *tu_decl_; - abi_util::IRDumper *ir_dumper_; + repr::ModuleIR *module_; // We cache the source file an AST node corresponds to, to avoid repeated // calls to "realpath". - ast_util::ASTCaches *ast_caches_; + ASTCaches *ast_caches_; }; + class HeaderASTConsumer : public clang::ASTConsumer { public: HeaderASTConsumer(clang::CompilerInstance *compiler_instancep, @@ -78,4 +84,9 @@ class HeaderASTConsumer : public clang::ASTConsumer { HeaderCheckerOptions &options_; }; + +} // namespace dumper +} // namespace header_checker + + #endif // AST_PROCESSING_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/ast_util.h b/vndk/tools/header-checker/src/dumper/ast_util.h index 74057c592..b68c4ba79 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/ast_util.h +++ b/vndk/tools/header-checker/src/dumper/ast_util.h @@ -20,7 +20,10 @@ #include <map> #include <string> -namespace ast_util { + +namespace header_checker { +namespace dumper { + constexpr static char type_id_prefix[] = "type-"; @@ -45,6 +48,9 @@ struct ASTCaches { uint64_t max_type_id_ = 0; }; -} // namespace ast_util + +} // namespace dumper +} // namespace header_checker + #endif // AST_UTIL_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/diagnostic_consumer.cpp b/vndk/tools/header-checker/src/dumper/diagnostic_consumer.cpp index e99e9b0ce..212609db7 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/diagnostic_consumer.cpp +++ b/vndk/tools/header-checker/src/dumper/diagnostic_consumer.cpp @@ -12,12 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "diagnostic_consumer.h" +#include "dumper/diagnostic_consumer.h" #include <clang/Basic/DiagnosticCategories.h> #include <clang/Basic/DiagnosticIDs.h> #include <clang/Lex/LexDiagnostic.h> + +namespace header_checker { +namespace dumper { + + HeaderCheckerDiagnosticConsumer::HeaderCheckerDiagnosticConsumer( std::unique_ptr<clang::DiagnosticConsumer> wrapped) : wrapped_(std::move(wrapped)) {} @@ -62,3 +67,7 @@ void HeaderCheckerDiagnosticConsumer::HandleDiagnostic( DiagnosticConsumer::HandleDiagnostic(level, info); wrapped_->HandleDiagnostic(level, info); } + + +} // dumper +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-dumper/src/diagnostic_consumer.h b/vndk/tools/header-checker/src/dumper/diagnostic_consumer.h index 927c8caf8..f4738ee8d 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/diagnostic_consumer.h +++ b/vndk/tools/header-checker/src/dumper/diagnostic_consumer.h @@ -17,6 +17,11 @@ #include <clang/Basic/Diagnostic.h> + +namespace header_checker { +namespace dumper { + + class HeaderCheckerDiagnosticConsumer : public clang::DiagnosticConsumer { private: std::unique_ptr<clang::DiagnosticConsumer> wrapped_; @@ -34,4 +39,9 @@ class HeaderCheckerDiagnosticConsumer : public clang::DiagnosticConsumer { const clang::Diagnostic &info) override; }; + +} // namespace dumper +} // namespace header_checker + + #endif // DIAGNOSTIC_CONSUMER_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/fake_decl_source.cpp b/vndk/tools/header-checker/src/dumper/fake_decl_source.cpp index 417433cdf..4930a39c9 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/fake_decl_source.cpp +++ b/vndk/tools/header-checker/src/dumper/fake_decl_source.cpp @@ -12,11 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "fake_decl_source.h" +#include "dumper/fake_decl_source.h" #include <clang/Lex/Preprocessor.h> #include <clang/Sema/Lookup.h> + +namespace header_checker { +namespace dumper { + + FakeDeclSource::FakeDeclSource(const clang::CompilerInstance &ci) : ci_(ci) {} clang::CXXRecordDecl * @@ -198,3 +203,7 @@ bool FakeDeclSource::LookupUnqualified(clang::LookupResult &result, result.resolveKind(); return true; } + + +} // dumper +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-dumper/src/fake_decl_source.h b/vndk/tools/header-checker/src/dumper/fake_decl_source.h index 7d9cc7950..42c855267 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/fake_decl_source.h +++ b/vndk/tools/header-checker/src/dumper/fake_decl_source.h @@ -12,10 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +#ifndef HEADER_CHECKER_ABI_DUMPER_FAKE_DECL_SOURCE_H_ +#define HEADER_CHECKER_ABI_DUMPER_FAKE_DECL_SOURCE_H_ + #include <clang/Frontend/CompilerInstance.h> #include <clang/Sema/ExternalSemaSource.h> #include <clang/Sema/Sema.h> + +namespace header_checker { +namespace dumper { + + // This class creates fake declarations when the compiler queries for unknown // types. class FakeDeclSource : public clang::ExternalSemaSource { @@ -57,3 +65,10 @@ class FakeDeclSource : public clang::ExternalSemaSource { bool LookupUnqualified(clang::LookupResult &result, clang::Scope *scope) override; }; + + +} // namespace dumper +} // namespace header_checker + + +#endif // HEADER_CHECKER_ABI_DUMPER_FAKE_DECL_SOURCE_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/fixed_argv.cpp b/vndk/tools/header-checker/src/dumper/fixed_argv.cpp index 3ab28c9de..57f402b0d 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/fixed_argv.cpp +++ b/vndk/tools/header-checker/src/dumper/fixed_argv.cpp @@ -12,6 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "fixed_argv.h" +#include "dumper/fixed_argv.h" + + +namespace header_checker { +namespace dumper { + FixedArgvRegistry *FixedArgvRegistry::head_ = nullptr; + + +} // dumper +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-dumper/src/fixed_argv.h b/vndk/tools/header-checker/src/dumper/fixed_argv.h index 61d590dcf..1ae947edd 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/fixed_argv.h +++ b/vndk/tools/header-checker/src/dumper/fixed_argv.h @@ -24,6 +24,10 @@ #include <string.h> +namespace header_checker { +namespace dumper { + + class FixedArgvAccess; @@ -131,4 +135,8 @@ class FixedArgvRegistry { }; +} // namespace dumper +} // namespace header_checker + + #endif // FIXED_ARGV_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp b/vndk/tools/header-checker/src/dumper/frontend_action.cpp index 6662fce87..6b773267b 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.cpp +++ b/vndk/tools/header-checker/src/dumper/frontend_action.cpp @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "frontend_action.h" +#include "dumper/frontend_action.h" -#include "ast_processing.h" -#include "diagnostic_consumer.h" -#include "fake_decl_source.h" -#include "header_abi_util.h" -#include "ir_representation.h" +#include "dumper/ast_processing.h" +#include "dumper/diagnostic_consumer.h" +#include "dumper/fake_decl_source.h" +#include "repr/ir_representation.h" +#include "utils/header_abi_util.h" #include <clang/AST/ASTConsumer.h> #include <clang/Frontend/CompilerInstance.h> @@ -26,6 +26,11 @@ #include <llvm/ADT/STLExtras.h> + +namespace header_checker { +namespace dumper { + + HeaderCheckerFrontendAction::HeaderCheckerFrontendAction( HeaderCheckerOptions &options) : options_(options) {} @@ -56,3 +61,7 @@ bool HeaderCheckerFrontendAction::BeginSourceFileAction( } return true; } + + +} // dumper +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h b/vndk/tools/header-checker/src/dumper/frontend_action.h index 166e3b637..ad82850eb 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action.h +++ b/vndk/tools/header-checker/src/dumper/frontend_action.h @@ -15,7 +15,7 @@ #ifndef FRONTEND_ACTION_H_ #define FRONTEND_ACTION_H_ -#include "header_checker.h" +#include "dumper/header_checker.h" #include <clang/Frontend/FrontendAction.h> #include <llvm/ADT/StringRef.h> @@ -25,11 +25,17 @@ #include <string> #include <vector> + namespace clang { class ASTConsumer; class CompilerInstance; } // namespace clang + +namespace header_checker { +namespace dumper { + + class HeaderCheckerFrontendAction : public clang::ASTFrontendAction { private: HeaderCheckerOptions &options_; @@ -45,4 +51,9 @@ class HeaderCheckerFrontendAction : public clang::ASTFrontendAction { bool BeginSourceFileAction(clang::CompilerInstance &ci) override; }; + +} // namespace dumper +} // namespace header_checker + + #endif // FRONTEND_ACTION_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp b/vndk/tools/header-checker/src/dumper/frontend_action_factory.cpp index bf1448a4e..307b9160d 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.cpp +++ b/vndk/tools/header-checker/src/dumper/frontend_action_factory.cpp @@ -12,12 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "frontend_action_factory.h" +#include "dumper/frontend_action_factory.h" -#include "frontend_action.h" +#include "dumper/frontend_action.h" #include <clang/Frontend/FrontendActions.h> + +namespace header_checker { +namespace dumper { + + HeaderCheckerFrontendActionFactory::HeaderCheckerFrontendActionFactory( HeaderCheckerOptions &options) : options_(options) {} @@ -25,3 +30,7 @@ HeaderCheckerFrontendActionFactory::HeaderCheckerFrontendActionFactory( clang::FrontendAction *HeaderCheckerFrontendActionFactory::create() { return new HeaderCheckerFrontendAction(options_); } + + +} // dumper +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h b/vndk/tools/header-checker/src/dumper/frontend_action_factory.h index 1f470c950..0a7d4094c 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/frontend_action_factory.h +++ b/vndk/tools/header-checker/src/dumper/frontend_action_factory.h @@ -15,13 +15,18 @@ #ifndef FRONTEND_ACTION_FACTORY_H_ #define FRONTEND_ACTION_FACTORY_H_ -#include "frontend_action.h" -#include "ir_representation.h" +#include "dumper/frontend_action.h" +#include "repr/ir_representation.h" #include <clang/Tooling/Tooling.h> #include <vector> + +namespace header_checker { +namespace dumper { + + class HeaderCheckerFrontendActionFactory : public clang::tooling::FrontendActionFactory { private: @@ -33,4 +38,9 @@ class HeaderCheckerFrontendActionFactory clang::FrontendAction *create() override; }; + +} // namespace dumper +} // namespace header_checker + + #endif // FRONTEND_ACTION_FACTORY_H_ diff --git a/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp b/vndk/tools/header-checker/src/dumper/header_checker.cpp index 25f352b95..25d87fe8c 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/header_checker.cpp +++ b/vndk/tools/header-checker/src/dumper/header_checker.cpp @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "header_checker.h" +#include "dumper/header_checker.h" -#include "fixed_argv.h" -#include "frontend_action_factory.h" -#include "header_abi_util.h" +#include "dumper/fixed_argv.h" +#include "dumper/frontend_action_factory.h" +#include "utils/header_abi_util.h" #include <clang/Frontend/FrontendActions.h> #include <clang/Tooling/CommonOptionsParser.h> @@ -32,6 +32,18 @@ #include <stdlib.h> + +using header_checker::dumper::FixedArgv; +using header_checker::dumper::FixedArgvAccess; +using header_checker::dumper::FixedArgvRegistry; +using header_checker::dumper::HeaderCheckerFrontendActionFactory; +using header_checker::dumper::HeaderCheckerOptions; +using header_checker::repr::TextFormatIR; +using header_checker::utils::CollectAllExportedHeaders; +using header_checker::utils::RealPath; + + + static llvm::cl::OptionCategory header_checker_category( "header-checker options"); @@ -63,12 +75,12 @@ static llvm::cl::opt<bool> dump_function_declarations( "file"), llvm::cl::Optional, llvm::cl::cat(header_checker_category)); -static llvm::cl::opt<abi_util::TextFormatIR> output_format( +static llvm::cl::opt<TextFormatIR> output_format( "output-format", llvm::cl::desc("Specify format of output dump file"), - llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + llvm::cl::values(clEnumValN(TextFormatIR::ProtobufTextFormat, "ProtobufTextFormat", "ProtobufTextFormat"), - clEnumValN(abi_util::TextFormatIR::Json, "Json", "JSON")), - llvm::cl::init(abi_util::TextFormatIR::Json), + clEnumValN(TextFormatIR::Json, "Json", "JSON")), + llvm::cl::init(TextFormatIR::Json), llvm::cl::cat(header_checker_category)); // Hide irrelevant command line options defined in LLVM libraries. @@ -130,13 +142,12 @@ int main(int argc, const char **argv) { std::set<std::string> exported_headers; if (!no_filter) { - exported_headers = - abi_util::CollectAllExportedHeaders(exported_header_dirs); + exported_headers = CollectAllExportedHeaders(exported_header_dirs); } // Initialize clang tools and run front-end action. std::vector<std::string> header_files{ header_file }; - HeaderCheckerOptions options(abi_util::RealPath(header_file), out_dump, + HeaderCheckerOptions options(RealPath(header_file), out_dump, std::move(exported_headers), output_format, dump_function_declarations, suppress_errors); diff --git a/vndk/tools/header-checker/header-abi-dumper/src/header_checker.h b/vndk/tools/header-checker/src/dumper/header_checker.h index 8fe4ebbc7..6acd59628 100644 --- a/vndk/tools/header-checker/header-abi-dumper/src/header_checker.h +++ b/vndk/tools/header-checker/src/dumper/header_checker.h @@ -15,24 +15,29 @@ #ifndef HEADER_CHECKER_H_ #define HEADER_CHECKER_H_ -#include "ir_representation.h" +#include "repr/ir_representation.h" #include <set> #include <string> + +namespace header_checker { +namespace dumper { + + class HeaderCheckerOptions { public: std::string source_file_; std::string dump_name_; std::set<std::string> exported_headers_; - abi_util::TextFormatIR text_format_; + repr::TextFormatIR text_format_; bool dump_function_declarations_; bool suppress_errors_; public: HeaderCheckerOptions(std::string source_file, std::string dump_name, std::set<std::string> exported_headers, - abi_util::TextFormatIR text_format, + repr::TextFormatIR text_format, bool dump_function_declarations, bool suppress_errors) : source_file_(std::move(source_file)), dump_name_(std::move(dump_name)), exported_headers_(std::move(exported_headers)), @@ -41,4 +46,9 @@ class HeaderCheckerOptions { suppress_errors_(suppress_errors) {} }; + +} // namespace dumper +} // namespace header_checker + + #endif // HEADER_CHECKER_H_ diff --git a/vndk/tools/header-checker/header-abi-linker/src/header_abi_linker.cpp b/vndk/tools/header-checker/src/linker/header_abi_linker.cpp index 3da1ac1e4..e9890c16e 100644 --- a/vndk/tools/header-checker/header-abi-linker/src/header_abi_linker.cpp +++ b/vndk/tools/header-checker/src/linker/header_abi_linker.cpp @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "header_abi_util.h" -#include "ir_representation.h" -#include "so_file_parser.h" -#include "version_script_parser.h" +#include "repr/ir_representation.h" +#include "repr/ir_dumper.h" +#include "repr/ir_reader.h" +#include "repr/symbol/so_file_parser.h" +#include "repr/symbol/version_script_parser.h" +#include "utils/header_abi_util.h" #include <llvm/Support/CommandLine.h> #include <llvm/Support/raw_ostream.h> @@ -31,6 +33,12 @@ #include <stdlib.h> + +using namespace header_checker; +using header_checker::repr::TextFormatIR; +using header_checker::utils::CollectAllExportedHeaders; + + static constexpr std::size_t kSourcesPerBatchThread = 7; static llvm::cl::OptionCategory header_linker_category( @@ -77,20 +85,20 @@ static llvm::cl::opt<std::string> so_file( "so", llvm::cl::desc("<path to so file>"), llvm::cl::Optional, llvm::cl::cat(header_linker_category)); -static llvm::cl::opt<abi_util::TextFormatIR> input_format( +static llvm::cl::opt<TextFormatIR> input_format( "input-format", llvm::cl::desc("Specify format of input dump files"), - llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + llvm::cl::values(clEnumValN(TextFormatIR::ProtobufTextFormat, "ProtobufTextFormat", "ProtobufTextFormat"), - clEnumValN(abi_util::TextFormatIR::Json, "Json", "JSON")), - llvm::cl::init(abi_util::TextFormatIR::Json), + clEnumValN(TextFormatIR::Json, "Json", "JSON")), + llvm::cl::init(TextFormatIR::Json), llvm::cl::cat(header_linker_category)); -static llvm::cl::opt<abi_util::TextFormatIR> output_format( +static llvm::cl::opt<TextFormatIR> output_format( "output-format", llvm::cl::desc("Specify format of output dump file"), - llvm::cl::values(clEnumValN(abi_util::TextFormatIR::ProtobufTextFormat, + llvm::cl::values(clEnumValN(TextFormatIR::ProtobufTextFormat, "ProtobufTextFormat", "ProtobufTextFormat"), - clEnumValN(abi_util::TextFormatIR::Json, "Json", "JSON")), - llvm::cl::init(abi_util::TextFormatIR::Json), + clEnumValN(TextFormatIR::Json, "Json", "JSON")), + llvm::cl::init(TextFormatIR::Json), llvm::cl::cat(header_linker_category)); class HeaderAbiLinker { @@ -115,11 +123,11 @@ class HeaderAbiLinker { private: template <typename T> - bool LinkDecl(abi_util::IRDumper *dst, - const abi_util::AbiElementMap<T> &src, + bool LinkDecl(repr::ModuleIR *dst, + const repr::AbiElementMap<T> &src, const std::function<bool(const std::string &)> &symbol_filter); - std::unique_ptr<abi_util::TextFormatToIRReader> ReadInputDumpFiles(); + std::unique_ptr<repr::IRReader> ReadInputDumpFiles(); bool ReadExportedSymbols(); @@ -127,22 +135,19 @@ class HeaderAbiLinker { bool ReadExportedSymbolsFromSharedObjectFile(); - bool LinkTypes(const abi_util::TextFormatToIRReader *ir_reader, - abi_util::IRDumper *ir_dumper); + bool LinkTypes(repr::ModuleIR &module, repr::ModuleIR *linked_module); - bool LinkFunctions(const abi_util::TextFormatToIRReader *ir_reader, - abi_util::IRDumper *ir_dumper); + bool LinkFunctions(repr::ModuleIR &module, repr::ModuleIR *linked_module); - bool LinkGlobalVars(const abi_util::TextFormatToIRReader *ir_reader, - abi_util::IRDumper *ir_dumper); + bool LinkGlobalVars(repr::ModuleIR &module, repr::ModuleIR *linked_module); - bool LinkExportedSymbols(abi_util::IRDumper *ir_dumper); + bool LinkExportedSymbols(repr::ModuleIR *linked_module); - bool LinkExportedSymbols(abi_util::IRDumper *ir_dumper, - const abi_util::ExportedSymbolSet &exported_symbols); + bool LinkExportedSymbols(repr::ModuleIR *linked_module, + const repr::ExportedSymbolSet &exported_symbols); template <typename SymbolMap> - bool LinkExportedSymbols(abi_util::IRDumper *ir_dumper, + bool LinkExportedSymbols(repr::ModuleIR *linked_module, const SymbolMap &symbols); // Check whether a symbol name is considered as exported. If both @@ -164,18 +169,18 @@ class HeaderAbiLinker { std::set<std::string> exported_headers_; // Exported symbols - std::unique_ptr<abi_util::ExportedSymbolSet> shared_object_symbols_; - std::unique_ptr<abi_util::ExportedSymbolSet> version_script_symbols_; + std::unique_ptr<repr::ExportedSymbolSet> shared_object_symbols_; + + std::unique_ptr<repr::ExportedSymbolSet> version_script_symbols_; }; static void DeDuplicateAbiElementsThread( const std::vector<std::string> &dump_files, const std::set<std::string> *exported_headers, - abi_util::TextFormatToIRReader *greader, std::mutex *greader_lock, + repr::IRReader *greader, std::mutex *greader_lock, std::atomic<std::size_t> *cnt) { - std::unique_ptr<abi_util::TextFormatToIRReader> local_reader = - abi_util::TextFormatToIRReader::CreateTextFormatToIRReader( - input_format, exported_headers); + std::unique_ptr<repr::IRReader> local_reader = + repr::IRReader::CreateIRReader(input_format, exported_headers); auto begin_it = dump_files.begin(); std::size_t num_sources = dump_files.size(); @@ -186,9 +191,8 @@ static void DeDuplicateAbiElementsThread( } std::size_t end = std::min(i + kSourcesPerBatchThread, num_sources); for (auto it = begin_it; it != begin_it + end; it++) { - std::unique_ptr<abi_util::TextFormatToIRReader> reader = - abi_util::TextFormatToIRReader::CreateTextFormatToIRReader( - input_format, exported_headers); + std::unique_ptr<repr::IRReader> reader = + repr::IRReader::CreateIRReader(input_format, exported_headers); assert(reader != nullptr); if (!reader->ReadDump(*it)) { llvm::errs() << "ReadDump failed\n"; @@ -203,11 +207,10 @@ static void DeDuplicateAbiElementsThread( greader->MergeGraphs(*local_reader); } -std::unique_ptr<abi_util::TextFormatToIRReader> +std::unique_ptr<repr::IRReader> HeaderAbiLinker::ReadInputDumpFiles() { - std::unique_ptr<abi_util::TextFormatToIRReader> greader = - abi_util::TextFormatToIRReader::CreateTextFormatToIRReader( - input_format, &exported_headers_); + std::unique_ptr<repr::IRReader> greader = + repr::IRReader::CreateIRReader(input_format, &exported_headers_); std::size_t max_threads = std::thread::hardware_concurrency(); std::size_t num_threads = kSourcesPerBatchThread < dump_files_.size() ? @@ -237,29 +240,33 @@ bool HeaderAbiLinker::LinkAndDump() { } // Construct the list of exported headers for source location filtering. - exported_headers_ = - abi_util::CollectAllExportedHeaders(exported_header_dirs_); + exported_headers_ = CollectAllExportedHeaders(exported_header_dirs_); // Read all input ABI dumps. auto greader = ReadInputDumpFiles(); + repr::ModuleIR &module = greader->GetModule(); + // Link input ABI dumps. - std::unique_ptr<abi_util::IRDumper> ir_dumper = - abi_util::IRDumper::CreateIRDumper(output_format, out_dump_name_); - assert(ir_dumper != nullptr); + std::unique_ptr<repr::ModuleIR> linked_module( + new repr::ModuleIR(&exported_headers_)); - if (!LinkExportedSymbols(ir_dumper.get())) { + if (!LinkExportedSymbols(linked_module.get())) { return false; } - if (!LinkTypes(greader.get(), ir_dumper.get()) || - !LinkFunctions(greader.get(), ir_dumper.get()) || - !LinkGlobalVars(greader.get(), ir_dumper.get())) { + if (!LinkTypes(module, linked_module.get()) || + !LinkFunctions(module, linked_module.get()) || + !LinkGlobalVars(module, linked_module.get())) { llvm::errs() << "Failed to link elements\n"; return false; } - if (!ir_dumper->Dump()) { + // Dump the linked module. + std::unique_ptr<repr::IRDumper> ir_dumper = + repr::IRDumper::CreateIRDumper(output_format, out_dump_name_); + assert(ir_dumper != nullptr); + if (!ir_dumper->Dump(*linked_module)) { llvm::errs() << "Failed to serialize the linked output to ostream\n"; return false; } @@ -269,7 +276,7 @@ bool HeaderAbiLinker::LinkAndDump() { template <typename T> bool HeaderAbiLinker::LinkDecl( - abi_util::IRDumper *dst, const abi_util::AbiElementMap<T> &src, + repr::ModuleIR *dst, const repr::AbiElementMap<T> &src, const std::function<bool(const std::string &)> &symbol_filter) { assert(dst != nullptr); for (auto &&element : src) { @@ -285,7 +292,7 @@ bool HeaderAbiLinker::LinkDecl( if (!symbol_filter(element.first)) { continue; } - if (!dst->AddLinkableMessageIR(&(element.second))) { + if (!dst->AddLinkableMessage(element.second)) { llvm::errs() << "Failed to add element to linked dump\n"; return false; } @@ -293,19 +300,18 @@ bool HeaderAbiLinker::LinkDecl( return true; } -bool HeaderAbiLinker::LinkTypes(const abi_util::TextFormatToIRReader *reader, - abi_util::IRDumper *ir_dumper) { - assert(reader != nullptr); +bool HeaderAbiLinker::LinkTypes(repr::ModuleIR &module, + repr::ModuleIR *linked_module) { auto no_filter = [](const std::string &symbol) { return true; }; - return LinkDecl(ir_dumper, reader->GetRecordTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetEnumTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetFunctionTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetBuiltinTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetPointerTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetRvalueReferenceTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetLvalueReferenceTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetArrayTypes(), no_filter) && - LinkDecl(ir_dumper, reader->GetQualifiedTypes(), no_filter); + return LinkDecl(linked_module, module.GetRecordTypes(), no_filter) && + LinkDecl(linked_module, module.GetEnumTypes(), no_filter) && + LinkDecl(linked_module, module.GetFunctionTypes(), no_filter) && + LinkDecl(linked_module, module.GetBuiltinTypes(), no_filter) && + LinkDecl(linked_module, module.GetPointerTypes(), no_filter) && + LinkDecl(linked_module, module.GetRvalueReferenceTypes(), no_filter) && + LinkDecl(linked_module, module.GetLvalueReferenceTypes(), no_filter) && + LinkDecl(linked_module, module.GetArrayTypes(), no_filter) && + LinkDecl(linked_module, module.GetQualifiedTypes(), no_filter); } bool HeaderAbiLinker::IsSymbolExported(const std::string &name) const { @@ -318,34 +324,30 @@ bool HeaderAbiLinker::IsSymbolExported(const std::string &name) const { return true; } -bool HeaderAbiLinker::LinkFunctions( - const abi_util::TextFormatToIRReader *reader, - abi_util::IRDumper *ir_dumper) { - assert(reader != nullptr); +bool HeaderAbiLinker::LinkFunctions(repr::ModuleIR &module, + repr::ModuleIR *linked_module) { auto symbol_filter = [this](const std::string &linker_set_key) { return IsSymbolExported(linker_set_key); }; - return LinkDecl(ir_dumper, reader->GetFunctions(), symbol_filter); + return LinkDecl(linked_module, module.GetFunctions(), symbol_filter); } -bool HeaderAbiLinker::LinkGlobalVars( - const abi_util::TextFormatToIRReader *reader, - abi_util::IRDumper *ir_dumper) { - assert(reader != nullptr); +bool HeaderAbiLinker::LinkGlobalVars(repr::ModuleIR &module, + repr::ModuleIR *linked_module) { auto symbol_filter = [this](const std::string &linker_set_key) { return IsSymbolExported(linker_set_key); }; - return LinkDecl(ir_dumper, reader->GetGlobalVariables(), symbol_filter); + return LinkDecl(linked_module, module.GetGlobalVariables(), symbol_filter); } template <typename SymbolMap> -bool HeaderAbiLinker::LinkExportedSymbols(abi_util::IRDumper *dst, +bool HeaderAbiLinker::LinkExportedSymbols(repr::ModuleIR *dst, const SymbolMap &symbols) { for (auto &&symbol : symbols) { if (!IsSymbolExported(symbol.first)) { continue; } - if (!dst->AddElfSymbolMessageIR(&(symbol.second))) { + if (!dst->AddElfSymbol(symbol.second)) { return false; } } @@ -353,19 +355,19 @@ bool HeaderAbiLinker::LinkExportedSymbols(abi_util::IRDumper *dst, } bool HeaderAbiLinker::LinkExportedSymbols( - abi_util::IRDumper *ir_dumper, - const abi_util::ExportedSymbolSet &exported_symbols) { - return (LinkExportedSymbols(ir_dumper, exported_symbols.GetFunctions()) && - LinkExportedSymbols(ir_dumper, exported_symbols.GetVars())); + repr::ModuleIR *linked_module, + const repr::ExportedSymbolSet &exported_symbols) { + return (LinkExportedSymbols(linked_module, exported_symbols.GetFunctions()) && + LinkExportedSymbols(linked_module, exported_symbols.GetVars())); } -bool HeaderAbiLinker::LinkExportedSymbols(abi_util::IRDumper *ir_dumper) { +bool HeaderAbiLinker::LinkExportedSymbols(repr::ModuleIR *linked_module) { if (shared_object_symbols_) { - return LinkExportedSymbols(ir_dumper, *shared_object_symbols_); + return LinkExportedSymbols(linked_module, *shared_object_symbols_); } if (version_script_symbols_) { - return LinkExportedSymbols(ir_dumper, *version_script_symbols_); + return LinkExportedSymbols(linked_module, *version_script_symbols_); } return false; @@ -397,7 +399,7 @@ bool HeaderAbiLinker::ReadExportedSymbols() { } bool HeaderAbiLinker::ReadExportedSymbolsFromVersionScript() { - std::optional<abi_util::ApiLevel> api_level = abi_util::ParseApiLevel(api_); + std::optional<utils::ApiLevel> api_level = utils::ParseApiLevel(api_); if (!api_level) { llvm::errs() << "-api must be either \"current\" or an integer (e.g. 21)\n"; return false; @@ -409,7 +411,7 @@ bool HeaderAbiLinker::ReadExportedSymbolsFromVersionScript() { return false; } - abi_util::VersionScriptParser parser; + repr::VersionScriptParser parser; parser.SetArch(arch_); parser.SetApiLevel(api_level.value()); for (auto &&version : excluded_symbol_versions_) { @@ -429,8 +431,8 @@ bool HeaderAbiLinker::ReadExportedSymbolsFromVersionScript() { } bool HeaderAbiLinker::ReadExportedSymbolsFromSharedObjectFile() { - std::unique_ptr<abi_util::SoFileParser> so_parser = - abi_util::SoFileParser::Create(so_file_); + std::unique_ptr<repr::SoFileParser> so_parser = + repr::SoFileParser::Create(so_file_); if (!so_parser) { return false; } diff --git a/vndk/tools/header-checker/header-abi-util/src/abi_diff_helpers.cpp b/vndk/tools/header-checker/src/repr/abi_diff_helpers.cpp index 251882576..604186961 100644 --- a/vndk/tools/header-checker/header-abi-util/src/abi_diff_helpers.cpp +++ b/vndk/tools/header-checker/src/repr/abi_diff_helpers.cpp @@ -12,12 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "abi_diff_helpers.h" -#include "header_abi_util.h" +#include "repr/abi_diff_helpers.h" + +#include "utils/header_abi_util.h" #include <llvm/Support/raw_ostream.h> -namespace abi_util { + +namespace header_checker { +namespace repr { + std::string Unwind(const std::deque<std::string> *type_queue) { if (!type_queue) { @@ -45,17 +49,17 @@ static void TypeQueueCheckAndPop(std::deque<std::string> *type_queue) { } } -static bool IsAccessDownGraded(abi_util::AccessSpecifierIR old_access, - abi_util::AccessSpecifierIR new_access) { +static bool IsAccessDownGraded(AccessSpecifierIR old_access, + AccessSpecifierIR new_access) { bool access_downgraded = false; switch (old_access) { - case abi_util::AccessSpecifierIR::ProtectedAccess: - if (new_access == abi_util::AccessSpecifierIR::PrivateAccess) { + case AccessSpecifierIR::ProtectedAccess: + if (new_access == AccessSpecifierIR::PrivateAccess) { access_downgraded = true; } break; - case abi_util::AccessSpecifierIR::PublicAccess: - if (new_access != abi_util::AccessSpecifierIR::PublicAccess) { + case AccessSpecifierIR::PublicAccess: + if (new_access != AccessSpecifierIR::PublicAccess) { access_downgraded = true; } break; @@ -154,36 +158,36 @@ void ReplaceTypeIdsWithTypeNames( } void AbiDiffHelper::CompareEnumFields( - const std::vector<abi_util::EnumFieldIR> &old_fields, - const std::vector<abi_util::EnumFieldIR> &new_fields, - abi_util::EnumTypeDiffIR *enum_type_diff_ir) { - AbiElementMap<const abi_util::EnumFieldIR *> old_fields_map; - AbiElementMap<const abi_util::EnumFieldIR *> new_fields_map; - abi_util::AddToMap(&old_fields_map, old_fields, - [](const abi_util::EnumFieldIR *f) {return f->GetName();}, - [](const abi_util::EnumFieldIR *f) {return f;}); + const std::vector<EnumFieldIR> &old_fields, + const std::vector<EnumFieldIR> &new_fields, + EnumTypeDiffIR *enum_type_diff_ir) { + AbiElementMap<const EnumFieldIR *> old_fields_map; + AbiElementMap<const EnumFieldIR *> new_fields_map; + utils::AddToMap(&old_fields_map, old_fields, + [](const EnumFieldIR *f) {return f->GetName();}, + [](const EnumFieldIR *f) {return f;}); - abi_util::AddToMap(&new_fields_map, new_fields, - [](const abi_util::EnumFieldIR *f) {return f->GetName();}, - [](const abi_util::EnumFieldIR *f) {return f;}); + utils::AddToMap(&new_fields_map, new_fields, + [](const EnumFieldIR *f) {return f->GetName();}, + [](const EnumFieldIR *f) {return f;}); - std::vector<const abi_util::EnumFieldIR *> removed_fields = - abi_util::FindRemovedElements(old_fields_map, new_fields_map); + std::vector<const EnumFieldIR *> removed_fields = + utils::FindRemovedElements(old_fields_map, new_fields_map); - std::vector<const abi_util::EnumFieldIR *> added_fields = - abi_util::FindRemovedElements(new_fields_map, old_fields_map); + std::vector<const EnumFieldIR *> added_fields = + utils::FindRemovedElements(new_fields_map, old_fields_map); enum_type_diff_ir->SetFieldsAdded(std::move(added_fields)); enum_type_diff_ir->SetFieldsRemoved(std::move(removed_fields)); - std::vector<std::pair<const abi_util::EnumFieldIR *, - const abi_util::EnumFieldIR *>> cf = - abi_util::FindCommonElements(old_fields_map, new_fields_map); - std::vector<abi_util::EnumFieldDiffIR> enum_field_diffs; + std::vector<std::pair<const EnumFieldIR *, + const EnumFieldIR *>> cf = + utils::FindCommonElements(old_fields_map, new_fields_map); + std::vector<EnumFieldDiffIR> enum_field_diffs; for (auto &&common_fields : cf) { if (common_fields.first->GetValue() != common_fields.second->GetValue()) { - abi_util::EnumFieldDiffIR enum_field_diff_ir(common_fields.first, + EnumFieldDiffIR enum_field_diff_ir(common_fields.first, common_fields.second); enum_field_diffs.emplace_back(std::move(enum_field_diff_ir)); } @@ -192,13 +196,13 @@ void AbiDiffHelper::CompareEnumFields( } DiffStatus AbiDiffHelper::CompareEnumTypes( - const abi_util::EnumTypeIR *old_type, const abi_util::EnumTypeIR *new_type, + const EnumTypeIR *old_type, const EnumTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { if (old_type->GetUniqueId() != new_type->GetUniqueId()) { return DiffStatus::direct_diff; } - auto enum_type_diff_ir = std::make_unique<abi_util::EnumTypeDiffIR>(); + auto enum_type_diff_ir = std::make_unique<EnumTypeDiffIR>(); enum_type_diff_ir->SetName(old_type->GetName()); const std::string &old_underlying_type = ConvertTypeIdToString(old_types_, old_type->GetUnderlyingType()); @@ -234,8 +238,8 @@ static std::string RemoveThunkInfoFromMangledName(const std::string &name) { } bool AbiDiffHelper::CompareVTableComponents( - const abi_util::VTableComponentIR &old_component, - const abi_util::VTableComponentIR &new_component) { + const VTableComponentIR &old_component, + const VTableComponentIR &new_component) { // Vtable components in prebuilts/abi-dumps/vndk/28 don't have thunk info. if (old_component.GetName() != new_component.GetName()) { if (RemoveThunkInfoFromMangledName(old_component.GetName()) == @@ -252,12 +256,12 @@ bool AbiDiffHelper::CompareVTableComponents( } bool AbiDiffHelper::CompareVTables( - const abi_util::RecordTypeIR *old_record, - const abi_util::RecordTypeIR *new_record) { + const RecordTypeIR *old_record, + const RecordTypeIR *new_record) { - const std::vector<abi_util::VTableComponentIR> &old_components = + const std::vector<VTableComponentIR> &old_components = old_record->GetVTableLayout().GetVTableComponents(); - const std::vector<abi_util::VTableComponentIR> &new_components = + const std::vector<VTableComponentIR> &new_components = new_record->GetVTableLayout().GetVTableComponents(); if (old_components.size() > new_components.size()) { // Something in the vtable got deleted. @@ -276,18 +280,18 @@ bool AbiDiffHelper::CompareVTables( } bool AbiDiffHelper::CompareSizeAndAlignment( - const abi_util::TypeIR *old_type, - const abi_util::TypeIR *new_type) { + const TypeIR *old_type, + const TypeIR *new_type) { return old_type->GetSize() == new_type->GetSize() && old_type->GetAlignment() == new_type->GetAlignment(); } -DiffStatusPair<std::unique_ptr<abi_util::RecordFieldDiffIR>> +DiffStatusPair<std::unique_ptr<RecordFieldDiffIR>> AbiDiffHelper::CompareCommonRecordFields( - const abi_util::RecordFieldIR *old_field, - const abi_util::RecordFieldIR *new_field, + const RecordFieldIR *old_field, + const RecordFieldIR *new_field, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { DiffStatus field_diff_status = CompareAndDumpTypeDiff(old_field->GetReferencedType(), @@ -301,7 +305,7 @@ AbiDiffHelper::CompareCommonRecordFields( (field_diff_status == DiffStatus::direct_diff)) { return std::make_pair( DiffStatus::direct_diff, - std::make_unique<abi_util::RecordFieldDiffIR>(old_field, new_field) + std::make_unique<RecordFieldDiffIR>(old_field, new_field) ); } return std::make_pair(field_diff_status, nullptr); @@ -310,46 +314,46 @@ AbiDiffHelper::CompareCommonRecordFields( GenericFieldDiffInfo<RecordFieldIR, RecordFieldDiffIR> AbiDiffHelper::CompareRecordFields( - const std::vector<abi_util::RecordFieldIR> &old_fields, - const std::vector<abi_util::RecordFieldIR> &new_fields, + const std::vector<RecordFieldIR> &old_fields, + const std::vector<RecordFieldIR> &new_fields, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { GenericFieldDiffInfo<RecordFieldIR, RecordFieldDiffIR> diffed_removed_added_fields; - AbiElementMap<const abi_util::RecordFieldIR *> old_fields_map; - AbiElementMap<const abi_util::RecordFieldIR *> new_fields_map; - std::map<uint64_t, const abi_util::RecordFieldIR *> old_fields_offset_map; - std::map<uint64_t, const abi_util::RecordFieldIR *> new_fields_offset_map; + AbiElementMap<const RecordFieldIR *> old_fields_map; + AbiElementMap<const RecordFieldIR *> new_fields_map; + std::map<uint64_t, const RecordFieldIR *> old_fields_offset_map; + std::map<uint64_t, const RecordFieldIR *> new_fields_offset_map; - abi_util::AddToMap( + utils::AddToMap( &old_fields_map, old_fields, - [](const abi_util::RecordFieldIR *f) {return f->GetName();}, - [](const abi_util::RecordFieldIR *f) {return f;}); - abi_util::AddToMap( + [](const RecordFieldIR *f) {return f->GetName();}, + [](const RecordFieldIR *f) {return f;}); + utils::AddToMap( &new_fields_map, new_fields, - [](const abi_util::RecordFieldIR *f) {return f->GetName();}, - [](const abi_util::RecordFieldIR *f) {return f;}); - abi_util::AddToMap( + [](const RecordFieldIR *f) {return f->GetName();}, + [](const RecordFieldIR *f) {return f;}); + utils::AddToMap( &old_fields_offset_map, old_fields, - [](const abi_util::RecordFieldIR *f) {return f->GetOffset();}, - [](const abi_util::RecordFieldIR *f) {return f;}); - abi_util::AddToMap( + [](const RecordFieldIR *f) {return f->GetOffset();}, + [](const RecordFieldIR *f) {return f;}); + utils::AddToMap( &new_fields_offset_map, new_fields, - [](const abi_util::RecordFieldIR *f) {return f->GetOffset();}, - [](const abi_util::RecordFieldIR *f) {return f;}); + [](const RecordFieldIR *f) {return f->GetOffset();}, + [](const RecordFieldIR *f) {return f;}); // If a field is removed from the map field_name -> offset see if another // field is present at the same offset and compare the size and type etc, // remove it from the removed fields if they're compatible. DiffStatus final_diff_status = DiffStatus::no_diff; - std::vector<const abi_util::RecordFieldIR *> removed_fields = - abi_util::FindRemovedElements(old_fields_map, new_fields_map); + std::vector<const RecordFieldIR *> removed_fields = + utils::FindRemovedElements(old_fields_map, new_fields_map); - std::vector<const abi_util::RecordFieldIR *> added_fields = - abi_util::FindRemovedElements(new_fields_map, old_fields_map); + std::vector<const RecordFieldIR *> added_fields = + utils::FindRemovedElements(new_fields_map, old_fields_map); auto predicate = - [&](const abi_util::RecordFieldIR *removed_field, - std::map<uint64_t, const abi_util::RecordFieldIR *> &field_off_map) { + [&](const RecordFieldIR *removed_field, + std::map<uint64_t, const RecordFieldIR *> &field_off_map) { uint64_t old_field_offset = removed_field->GetOffset(); auto corresponding_field_at_same_offset = field_off_map.find(old_field_offset); @@ -380,8 +384,8 @@ AbiDiffHelper::CompareRecordFields( diffed_removed_added_fields.added_fields_ = std::move(added_fields); std::vector<std::pair< - const abi_util::RecordFieldIR *, const abi_util::RecordFieldIR *>> cf = - abi_util::FindCommonElements(old_fields_map, new_fields_map); + const RecordFieldIR *, const RecordFieldIR *>> cf = + utils::FindCommonElements(old_fields_map, new_fields_map); bool common_field_diff_exists = false; for (auto &&common_fields : cf) { auto diffed_field_ptr = CompareCommonRecordFields( @@ -407,10 +411,10 @@ AbiDiffHelper::CompareRecordFields( } bool AbiDiffHelper::CompareBaseSpecifiers( - const std::vector<abi_util::CXXBaseSpecifierIR> &old_base_specifiers, - const std::vector<abi_util::CXXBaseSpecifierIR> &new_base_specifiers, + const std::vector<CXXBaseSpecifierIR> &old_base_specifiers, + const std::vector<CXXBaseSpecifierIR> &new_base_specifiers, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { if (old_base_specifiers.size() != new_base_specifiers.size()) { return false; } @@ -430,10 +434,10 @@ bool AbiDiffHelper::CompareBaseSpecifiers( } DiffStatus AbiDiffHelper::CompareTemplateInfo( - const std::vector<abi_util::TemplateElementIR> &old_template_elements, - const std::vector<abi_util::TemplateElementIR> &new_template_elements, + const std::vector<TemplateElementIR> &old_template_elements, + const std::vector<TemplateElementIR> &new_template_elements, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { uint32_t old_template_size = old_template_elements.size(); uint32_t i = 0; if (old_template_size != new_template_elements.size()) { @@ -441,9 +445,9 @@ DiffStatus AbiDiffHelper::CompareTemplateInfo( } DiffStatus final_diff_status = DiffStatus::no_diff; while (i < old_template_size) { - const abi_util::TemplateElementIR &old_template_element = + const TemplateElementIR &old_template_element = old_template_elements[i]; - const abi_util::TemplateElementIR &new_template_element = + const TemplateElementIR &new_template_element = new_template_elements[i]; auto template_element_diff = CompareAndDumpTypeDiff(old_template_element.GetReferencedType(), @@ -478,10 +482,10 @@ static std::vector<const T*> ConvertToConstPtrVector( return cptr_vec; } -static std::vector<abi_util::RecordFieldIR> FixupRemovedFieldTypeIds( - const std::vector<const abi_util::RecordFieldIR *> &removed_fields, - const AbiElementMap<const abi_util::TypeIR *> &old_types) { - std::vector<abi_util::RecordFieldIR> removed_fields_dup; +static std::vector<RecordFieldIR> FixupRemovedFieldTypeIds( + const std::vector<const RecordFieldIR *> &removed_fields, + const AbiElementMap<const TypeIR *> &old_types) { + std::vector<RecordFieldIR> removed_fields_dup; for (auto &removed_field : removed_fields) { removed_fields_dup.emplace_back(*removed_field); RecordFieldIR &it = removed_fields_dup[removed_fields_dup.size() -1]; @@ -491,17 +495,17 @@ static std::vector<abi_util::RecordFieldIR> FixupRemovedFieldTypeIds( return removed_fields_dup; } -std::vector<std::pair<abi_util::RecordFieldIR, abi_util::RecordFieldIR>> +std::vector<std::pair<RecordFieldIR, RecordFieldIR>> AbiDiffHelper::FixupDiffedFieldTypeIds( - const std::vector<abi_util::RecordFieldDiffIR> &field_diffs) { - std::vector<std::pair<abi_util::RecordFieldIR, abi_util::RecordFieldIR>> + const std::vector<RecordFieldDiffIR> &field_diffs) { + std::vector<std::pair<RecordFieldIR, RecordFieldIR>> diffed_fields_dup; for (auto &field_diff : field_diffs) { diffed_fields_dup.emplace_back(*(field_diff.old_field_), *(field_diff.new_field_)); auto &it = diffed_fields_dup[diffed_fields_dup.size() - 1]; - abi_util::RecordFieldIR &old_field = it.first; - abi_util::RecordFieldIR &new_field = it.second; + RecordFieldIR &old_field = it.first; + RecordFieldIR &new_field = it.second; old_field.SetReferencedType( ConvertTypeIdToString(old_types_, old_field.GetReferencedType())); new_field.SetReferencedType( @@ -511,10 +515,10 @@ AbiDiffHelper::FixupDiffedFieldTypeIds( } DiffStatus AbiDiffHelper::CompareFunctionTypes( - const abi_util::FunctionTypeIR *old_type, - const abi_util::FunctionTypeIR *new_type, + const FunctionTypeIR *old_type, + const FunctionTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { DiffStatus param_diffs = CompareFunctionParameters(old_type->GetParameters(), new_type->GetParameters(), type_queue, diff_kind); @@ -537,11 +541,11 @@ DiffStatus AbiDiffHelper::CompareFunctionTypes( } DiffStatus AbiDiffHelper::CompareRecordTypes( - const abi_util::RecordTypeIR *old_type, - const abi_util::RecordTypeIR *new_type, + const RecordTypeIR *old_type, + const RecordTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { - auto record_type_diff_ir = std::make_unique<abi_util::RecordTypeDiffIR>(); + DiffMessageIR::DiffKind diff_kind) { + auto record_type_diff_ir = std::make_unique<RecordTypeDiffIR>(); // Compare names. if (!old_type->IsAnonymous() && !new_type->IsAnonymous() && old_type->GetUniqueId() != new_type->GetUniqueId()) { @@ -554,14 +558,14 @@ DiffStatus AbiDiffHelper::CompareRecordTypes( if (IsAccessDownGraded(old_type->GetAccess(), new_type->GetAccess())) { final_diff_status = DiffStatus::indirect_diff; record_type_diff_ir->SetAccessDiff( - std::make_unique<abi_util::AccessSpecifierDiffIR>( + std::make_unique<AccessSpecifierDiffIR>( old_type->GetAccess(), new_type->GetAccess())); } if (!CompareSizeAndAlignment(old_type, new_type)) { final_diff_status = DiffStatus::indirect_diff; record_type_diff_ir->SetTypeDiff( - std::make_unique<abi_util::TypeDiffIR>( + std::make_unique<TypeDiffIR>( std::make_pair(old_type->GetSize(), new_type->GetSize()), std::make_pair(old_type->GetAlignment(), new_type->GetAlignment()))); @@ -569,7 +573,7 @@ DiffStatus AbiDiffHelper::CompareRecordTypes( if (!CompareVTables(old_type, new_type)) { final_diff_status = DiffStatus::indirect_diff; record_type_diff_ir->SetVTableLayoutDiff( - std::make_unique<abi_util::VTableLayoutDiffIR>( + std::make_unique<VTableLayoutDiffIR>( old_type->GetVTableLayout(), new_type->GetVTableLayout())); } auto &old_fields_dup = old_type->GetFields(); @@ -579,15 +583,15 @@ DiffStatus AbiDiffHelper::CompareRecordTypes( // TODO: Combine this with base class diffs as well. final_diff_status = final_diff_status | field_status_and_diffs.diff_status_; - std::vector<abi_util::CXXBaseSpecifierIR> old_bases = old_type->GetBases(); - std::vector<abi_util::CXXBaseSpecifierIR> new_bases = new_type->GetBases(); + std::vector<CXXBaseSpecifierIR> old_bases = old_type->GetBases(); + std::vector<CXXBaseSpecifierIR> new_bases = new_type->GetBases(); if (!CompareBaseSpecifiers(old_bases, new_bases, type_queue, diff_kind) && ir_diff_dumper_) { ReplaceReferencesOtherTypeIdWithName(old_types_, old_bases); ReplaceReferencesOtherTypeIdWithName(new_types_, new_bases); record_type_diff_ir->SetBaseSpecifierDiffs ( - std::make_unique<abi_util::CXXBaseSpecifierDiffIR>(old_bases, + std::make_unique<CXXBaseSpecifierDiffIR>(old_bases, new_bases)); } if (ir_diff_dumper_) { @@ -595,20 +599,20 @@ DiffStatus AbiDiffHelper::CompareRecordTypes( // type ids -> type strings. std::vector<std::pair<RecordFieldIR, RecordFieldIR>> field_diff_dups = FixupDiffedFieldTypeIds(field_status_and_diffs.diffed_fields_); - std::vector<abi_util::RecordFieldDiffIR> field_diffs_fixed = - ConvertToDiffContainerVector<abi_util::RecordFieldDiffIR, - abi_util::RecordFieldIR>(field_diff_dups); + std::vector<RecordFieldDiffIR> field_diffs_fixed = + ConvertToDiffContainerVector<RecordFieldDiffIR, + RecordFieldIR>(field_diff_dups); - std::vector<abi_util::RecordFieldIR> field_removed_dups = + std::vector<RecordFieldIR> field_removed_dups = FixupRemovedFieldTypeIds(field_status_and_diffs.removed_fields_, old_types_); - std::vector<const abi_util::RecordFieldIR *> fields_removed_fixed = + std::vector<const RecordFieldIR *> fields_removed_fixed = ConvertToConstPtrVector(field_removed_dups); - std::vector<abi_util::RecordFieldIR> field_added_dups = + std::vector<RecordFieldIR> field_added_dups = FixupRemovedFieldTypeIds(field_status_and_diffs.added_fields_, new_types_); - std::vector<const abi_util::RecordFieldIR *> fields_added_fixed = + std::vector<const RecordFieldIR *> fields_added_fixed = ConvertToConstPtrVector(field_added_dups); record_type_diff_ir->SetFieldDiffs(std::move(field_diffs_fixed)); @@ -635,30 +639,30 @@ DiffStatus AbiDiffHelper::CompareRecordTypes( } DiffStatus AbiDiffHelper::CompareLvalueReferenceTypes( - const abi_util::LvalueReferenceTypeIR *old_type, - const abi_util::LvalueReferenceTypeIR *new_type, + const LvalueReferenceTypeIR *old_type, + const LvalueReferenceTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { return CompareAndDumpTypeDiff(old_type->GetReferencedType(), new_type->GetReferencedType(), type_queue, diff_kind); } DiffStatus AbiDiffHelper::CompareRvalueReferenceTypes( - const abi_util::RvalueReferenceTypeIR *old_type, - const abi_util::RvalueReferenceTypeIR *new_type, + const RvalueReferenceTypeIR *old_type, + const RvalueReferenceTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { return CompareAndDumpTypeDiff(old_type->GetReferencedType(), new_type->GetReferencedType(), type_queue, diff_kind); } DiffStatus AbiDiffHelper::CompareQualifiedTypes( - const abi_util::QualifiedTypeIR *old_type, - const abi_util::QualifiedTypeIR *new_type, + const QualifiedTypeIR *old_type, + const QualifiedTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { // If all the qualifiers are not the same, return direct_diff, else // recursively compare the unqualified types. if (old_type->IsConst() != new_type->IsConst() || @@ -672,10 +676,10 @@ DiffStatus AbiDiffHelper::CompareQualifiedTypes( } DiffStatus AbiDiffHelper::ComparePointerTypes( - const abi_util::PointerTypeIR *old_type, - const abi_util::PointerTypeIR *new_type, + const PointerTypeIR *old_type, + const PointerTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { // The following need to be the same for two pointer types to be considered // equivalent: // 1) Number of pointer indirections are the same. @@ -687,8 +691,8 @@ DiffStatus AbiDiffHelper::ComparePointerTypes( } DiffStatus AbiDiffHelper::CompareBuiltinTypes( - const abi_util::BuiltinTypeIR *old_type, - const abi_util::BuiltinTypeIR *new_type) { + const BuiltinTypeIR *old_type, + const BuiltinTypeIR *new_type) { // If the size, alignment and is_unsigned are the same, return no_diff // else return direct_diff. if (!CompareSizeAndAlignment(old_type, new_type) || @@ -700,18 +704,18 @@ DiffStatus AbiDiffHelper::CompareBuiltinTypes( } DiffStatus AbiDiffHelper::CompareFunctionParameters( - const std::vector<abi_util::ParamIR> &old_parameters, - const std::vector<abi_util::ParamIR> &new_parameters, + const std::vector<ParamIR> &old_parameters, + const std::vector<ParamIR> &new_parameters, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { size_t old_parameters_size = old_parameters.size(); if (old_parameters_size != new_parameters.size()) { return DiffStatus::direct_diff; } uint64_t i = 0; while (i < old_parameters_size) { - const abi_util::ParamIR &old_parameter = old_parameters.at(i); - const abi_util::ParamIR &new_parameter = new_parameters.at(i); + const ParamIR &old_parameter = old_parameters.at(i); + const ParamIR &new_parameter = new_parameters.at(i); if ((CompareAndDumpTypeDiff(old_parameter.GetReferencedType(), new_parameter.GetReferencedType(), type_queue, diff_kind) == @@ -725,68 +729,68 @@ DiffStatus AbiDiffHelper::CompareFunctionParameters( } DiffStatus AbiDiffHelper::CompareAndDumpTypeDiff( - const abi_util::TypeIR *old_type, const abi_util::TypeIR *new_type, - abi_util::LinkableMessageKind kind, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { - if (kind == abi_util::LinkableMessageKind::BuiltinTypeKind) { + const TypeIR *old_type, const TypeIR *new_type, + LinkableMessageKind kind, std::deque<std::string> *type_queue, + DiffMessageIR::DiffKind diff_kind) { + if (kind == LinkableMessageKind::BuiltinTypeKind) { return CompareBuiltinTypes( - static_cast<const abi_util::BuiltinTypeIR *>(old_type), - static_cast<const abi_util::BuiltinTypeIR *>(new_type)); + static_cast<const BuiltinTypeIR *>(old_type), + static_cast<const BuiltinTypeIR *>(new_type)); } - if (kind == abi_util::LinkableMessageKind::QualifiedTypeKind) { + if (kind == LinkableMessageKind::QualifiedTypeKind) { return CompareQualifiedTypes( - static_cast<const abi_util::QualifiedTypeIR *>(old_type), - static_cast<const abi_util::QualifiedTypeIR *>(new_type), + static_cast<const QualifiedTypeIR *>(old_type), + static_cast<const QualifiedTypeIR *>(new_type), type_queue, diff_kind); } - if (kind == abi_util::LinkableMessageKind::EnumTypeKind) { + if (kind == LinkableMessageKind::EnumTypeKind) { return CompareEnumTypes( - static_cast<const abi_util::EnumTypeIR *>(old_type), - static_cast<const abi_util::EnumTypeIR *>(new_type), + static_cast<const EnumTypeIR *>(old_type), + static_cast<const EnumTypeIR *>(new_type), type_queue, diff_kind); } - if (kind == abi_util::LinkableMessageKind::LvalueReferenceTypeKind) { + if (kind == LinkableMessageKind::LvalueReferenceTypeKind) { return CompareLvalueReferenceTypes( - static_cast<const abi_util::LvalueReferenceTypeIR *>(old_type), - static_cast<const abi_util::LvalueReferenceTypeIR *>(new_type), + static_cast<const LvalueReferenceTypeIR *>(old_type), + static_cast<const LvalueReferenceTypeIR *>(new_type), type_queue, diff_kind); } - if (kind == abi_util::LinkableMessageKind::RvalueReferenceTypeKind) { + if (kind == LinkableMessageKind::RvalueReferenceTypeKind) { return CompareRvalueReferenceTypes( - static_cast<const abi_util::RvalueReferenceTypeIR *>(old_type), - static_cast<const abi_util::RvalueReferenceTypeIR *>(new_type), + static_cast<const RvalueReferenceTypeIR *>(old_type), + static_cast<const RvalueReferenceTypeIR *>(new_type), type_queue, diff_kind); } - if (kind == abi_util::LinkableMessageKind::PointerTypeKind) { + if (kind == LinkableMessageKind::PointerTypeKind) { return ComparePointerTypes( - static_cast<const abi_util::PointerTypeIR *>(old_type), - static_cast<const abi_util::PointerTypeIR *>(new_type), + static_cast<const PointerTypeIR *>(old_type), + static_cast<const PointerTypeIR *>(new_type), type_queue, diff_kind); } - if (kind == abi_util::LinkableMessageKind::RecordTypeKind) { + if (kind == LinkableMessageKind::RecordTypeKind) { return CompareRecordTypes( - static_cast<const abi_util::RecordTypeIR *>(old_type), - static_cast<const abi_util::RecordTypeIR *>(new_type), + static_cast<const RecordTypeIR *>(old_type), + static_cast<const RecordTypeIR *>(new_type), type_queue, diff_kind); } - if (kind == abi_util::LinkableMessageKind::FunctionTypeKind) { + if (kind == LinkableMessageKind::FunctionTypeKind) { return CompareFunctionTypes( - static_cast<const abi_util::FunctionTypeIR *>(old_type), - static_cast<const abi_util::FunctionTypeIR *>(new_type), + static_cast<const FunctionTypeIR *>(old_type), + static_cast<const FunctionTypeIR *>(new_type), type_queue, diff_kind); } return DiffStatus::no_diff; } static DiffStatus CompareDistinctKindMessages( - const abi_util::TypeIR *old_type, const abi_util::TypeIR *new_type) { + const TypeIR *old_type, const TypeIR *new_type) { // For these types to be considered ABI compatible, the very least requirement // is that their sizes and alignments should be equal. // TODO: Fill in @@ -796,7 +800,7 @@ static DiffStatus CompareDistinctKindMessages( DiffStatus AbiDiffHelper::CompareAndDumpTypeDiff( const std::string &old_type_id, const std::string &new_type_id, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind) { + DiffMessageIR::DiffKind diff_kind) { // Check the map for type ids which have already been compared // These types have already been diffed, return without further comparison. if (!type_cache_->insert(old_type_id + new_type_id).second) { @@ -806,9 +810,9 @@ DiffStatus AbiDiffHelper::CompareAndDumpTypeDiff( TypeQueueCheckAndPushBack( type_queue, ConvertTypeIdToString(old_types_,old_type_id)); - AbiElementMap<const abi_util::TypeIR *>::const_iterator old_it = + AbiElementMap<const TypeIR *>::const_iterator old_it = old_types_.find(old_type_id); - AbiElementMap<const abi_util::TypeIR *>::const_iterator new_it = + AbiElementMap<const TypeIR *>::const_iterator new_it = new_types_.find(new_type_id); if (old_it == old_types_.end() || new_it == new_types_.end()) { @@ -820,8 +824,8 @@ DiffStatus AbiDiffHelper::CompareAndDumpTypeDiff( return DiffStatus::no_diff; } - abi_util::LinkableMessageKind old_kind = old_it->second->GetKind(); - abi_util::LinkableMessageKind new_kind = new_it->second->GetKind(); + LinkableMessageKind old_kind = old_it->second->GetKind(); + LinkableMessageKind new_kind = new_it->second->GetKind(); DiffStatus diff_status = DiffStatus::no_diff; if (old_kind != new_kind) { diff_status = CompareDistinctKindMessages(old_it->second, new_it->second); @@ -844,4 +848,6 @@ DiffStatus AbiDiffHelper::CompareAndDumpTypeDiff( return diff_status; } -} // namespace abi_util + +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/abi_diff_helpers.h b/vndk/tools/header-checker/src/repr/abi_diff_helpers.h index 3fda32663..40febf4c6 100644 --- a/vndk/tools/header-checker/header-abi-util/include/abi_diff_helpers.h +++ b/vndk/tools/header-checker/src/repr/abi_diff_helpers.h @@ -15,15 +15,22 @@ #ifndef ABI_DIFF_HELPERS_H_ #define ABI_DIFF_HELPERS_H_ -#include "ir_representation.h" +#include "repr/ir_diff_dumper.h" +#include "repr/ir_diff_representation.h" +#include "repr/ir_reader.h" +#include "repr/ir_representation.h" #include <deque> + +namespace header_checker { +namespace repr { + + // Classes which act as middle-men between clang AST parsing routines and // message format specific dumpers. -namespace abi_util { -using MergeStatus = TextFormatToIRReader::MergeStatus; +using MergeStatus = IRReader::MergeStatus; enum DiffStatus { // There was no diff found while comparing types. @@ -37,7 +44,7 @@ enum DiffStatus { opaque_diff = 3, }; -static inline DiffStatus operator|(DiffStatus f,DiffStatus s) { +static inline DiffStatus operator|(DiffStatus f, DiffStatus s) { return static_cast<DiffStatus>( static_cast<std::underlying_type<DiffStatus>::type>(f) | static_cast<std::underlying_type<DiffStatus>::type>(s)); @@ -72,11 +79,11 @@ struct DiffPolicyOptions { class AbiDiffHelper { public: AbiDiffHelper( - const AbiElementMap<const abi_util::TypeIR *> &old_types, - const AbiElementMap<const abi_util::TypeIR *> &new_types, + const AbiElementMap<const TypeIR *> &old_types, + const AbiElementMap<const TypeIR *> &new_types, const DiffPolicyOptions &diff_policy_options, std::set<std::string> *type_cache, - abi_util::IRDiffDumper *ir_diff_dumper = nullptr, + IRDiffDumper *ir_diff_dumper = nullptr, AbiElementMap<MergeStatus> *local_to_global_type_id_map = nullptr) : old_types_(old_types), new_types_(new_types), diff_policy_options_(diff_policy_options), type_cache_(type_cache), @@ -86,113 +93,113 @@ class AbiDiffHelper { DiffStatus CompareAndDumpTypeDiff( const std::string &old_type_str, const std::string &new_type_str, std::deque<std::string> *type_queue = nullptr, - abi_util::IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced); + IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced); DiffStatus CompareAndDumpTypeDiff( - const abi_util::TypeIR *old_type, const abi_util::TypeIR *new_type, - abi_util::LinkableMessageKind kind, + const TypeIR *old_type, const TypeIR *new_type, + LinkableMessageKind kind, std::deque<std::string> *type_queue = nullptr, - abi_util::IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced); + IRDiffDumper::DiffKind diff_kind = DiffMessageIR::Unreferenced); - DiffStatus CompareRecordTypes(const abi_util::RecordTypeIR *old_type, - const abi_util::RecordTypeIR *new_type, + DiffStatus CompareRecordTypes(const RecordTypeIR *old_type, + const RecordTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); - DiffStatus CompareQualifiedTypes(const abi_util::QualifiedTypeIR *old_type, - const abi_util::QualifiedTypeIR *new_type, + DiffStatus CompareQualifiedTypes(const QualifiedTypeIR *old_type, + const QualifiedTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); - DiffStatus ComparePointerTypes(const abi_util::PointerTypeIR *old_type, - const abi_util::PointerTypeIR *new_type, + DiffStatus ComparePointerTypes(const PointerTypeIR *old_type, + const PointerTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); DiffStatus CompareLvalueReferenceTypes( - const abi_util::LvalueReferenceTypeIR *old_type, - const abi_util::LvalueReferenceTypeIR *new_type, + const LvalueReferenceTypeIR *old_type, + const LvalueReferenceTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); DiffStatus CompareRvalueReferenceTypes( - const abi_util::RvalueReferenceTypeIR *old_type, - const abi_util::RvalueReferenceTypeIR *new_type, + const RvalueReferenceTypeIR *old_type, + const RvalueReferenceTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); - DiffStatus CompareBuiltinTypes(const abi_util::BuiltinTypeIR *old_type, - const abi_util::BuiltinTypeIR *new_type); + DiffStatus CompareBuiltinTypes(const BuiltinTypeIR *old_type, + const BuiltinTypeIR *new_type); static void CompareEnumFields( - const std::vector<abi_util::EnumFieldIR> &old_fields, - const std::vector<abi_util::EnumFieldIR> &new_fields, - abi_util::EnumTypeDiffIR *enum_type_diff_ir); + const std::vector<EnumFieldIR> &old_fields, + const std::vector<EnumFieldIR> &new_fields, + EnumTypeDiffIR *enum_type_diff_ir); - DiffStatus CompareEnumTypes(const abi_util::EnumTypeIR *old_type, - const abi_util::EnumTypeIR *new_type, + DiffStatus CompareEnumTypes(const EnumTypeIR *old_type, + const EnumTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); - DiffStatus CompareFunctionTypes(const abi_util::FunctionTypeIR *old_type, - const abi_util::FunctionTypeIR *new_type, + DiffStatus CompareFunctionTypes(const FunctionTypeIR *old_type, + const FunctionTypeIR *new_type, std::deque<std::string> *type_queue, - abi_util::DiffMessageIR::DiffKind diff_kind); + DiffMessageIR::DiffKind diff_kind); void ReplaceRemovedFieldTypeIdsWithTypeNames( - std::vector<abi_util::RecordFieldIR *> *removed_fields); + std::vector<RecordFieldIR *> *removed_fields); void ReplaceDiffedFieldTypeIdsWithTypeNames( - abi_util::RecordFieldDiffIR *diffed_field); + RecordFieldDiffIR *diffed_field); - std::vector<std::pair<abi_util::RecordFieldIR, abi_util::RecordFieldIR>> + std::vector<std::pair<RecordFieldIR, RecordFieldIR>> FixupDiffedFieldTypeIds( - const std::vector<abi_util::RecordFieldDiffIR> &field_diffs); + const std::vector<RecordFieldDiffIR> &field_diffs); - DiffStatusPair<std::unique_ptr<abi_util::RecordFieldDiffIR>> + DiffStatusPair<std::unique_ptr<RecordFieldDiffIR>> CompareCommonRecordFields( - const abi_util::RecordFieldIR *old_field, - const abi_util::RecordFieldIR *new_field, + const RecordFieldIR *old_field, + const RecordFieldIR *new_field, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); - GenericFieldDiffInfo<abi_util::RecordFieldIR, abi_util::RecordFieldDiffIR> + GenericFieldDiffInfo<RecordFieldIR, RecordFieldDiffIR> CompareRecordFields( - const std::vector<abi_util::RecordFieldIR> &old_fields, - const std::vector<abi_util::RecordFieldIR> &new_fields, + const std::vector<RecordFieldIR> &old_fields, + const std::vector<RecordFieldIR> &new_fields, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); DiffStatus CompareFunctionParameters( - const std::vector<abi_util::ParamIR> &old_parameters, - const std::vector<abi_util::ParamIR> &new_parameters, + const std::vector<ParamIR> &old_parameters, + const std::vector<ParamIR> &new_parameters, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); bool CompareBaseSpecifiers( - const std::vector<abi_util::CXXBaseSpecifierIR> &old_base_specifiers, - const std::vector<abi_util::CXXBaseSpecifierIR> &new_base_specifiers, + const std::vector<CXXBaseSpecifierIR> &old_base_specifiers, + const std::vector<CXXBaseSpecifierIR> &new_base_specifiers, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); - bool CompareVTables(const abi_util::RecordTypeIR *old_record, - const abi_util::RecordTypeIR *new_record); + bool CompareVTables(const RecordTypeIR *old_record, + const RecordTypeIR *new_record); bool CompareVTableComponents( - const abi_util::VTableComponentIR &old_component, - const abi_util::VTableComponentIR &new_component); + const VTableComponentIR &old_component, + const VTableComponentIR &new_component); DiffStatus CompareTemplateInfo( - const std::vector<abi_util::TemplateElementIR> &old_template_elements, - const std::vector<abi_util::TemplateElementIR> &new_template_elements, + const std::vector<TemplateElementIR> &old_template_elements, + const std::vector<TemplateElementIR> &new_template_elements, std::deque<std::string> *type_queue, - abi_util::IRDiffDumper::DiffKind diff_kind); + IRDiffDumper::DiffKind diff_kind); - bool CompareSizeAndAlignment(const abi_util::TypeIR *old_ti, - const abi_util::TypeIR *new_ti); + bool CompareSizeAndAlignment(const TypeIR *old_ti, + const TypeIR *new_ti); template <typename DiffType, typename DiffElement> bool AddToDiff(DiffType *mutable_diff, const DiffElement *oldp, @@ -200,17 +207,20 @@ class AbiDiffHelper { std::deque<std::string> *type_queue = nullptr); protected: - const AbiElementMap<const abi_util::TypeIR *> &old_types_; - const AbiElementMap<const abi_util::TypeIR *> &new_types_; + const AbiElementMap<const TypeIR *> &old_types_; + const AbiElementMap<const TypeIR *> &new_types_; const DiffPolicyOptions &diff_policy_options_; std::set<std::string> *type_cache_; - abi_util::IRDiffDumper *ir_diff_dumper_; + IRDiffDumper *ir_diff_dumper_; AbiElementMap<MergeStatus> *local_to_global_type_id_map_; }; void ReplaceTypeIdsWithTypeNames( const AbiElementMap<const TypeIR *> &type_graph, LinkableMessageIR *lm); -} // namespace abi_util + +} // namespace repr +} // namespace header_checker + #endif // ABI_DIFF_HELPERS_H_ diff --git a/vndk/tools/header-checker/src/repr/ir_diff_dumper.cpp b/vndk/tools/header-checker/src/repr/ir_diff_dumper.cpp new file mode 100644 index 000000000..d0b0eab9a --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_diff_dumper.cpp @@ -0,0 +1,44 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/ir_diff_dumper.h" + +#include "repr/ir_representation.h" +#include "repr/protobuf/api.h" + +#include <memory> +#include <string> + +#include <llvm/Support/raw_ostream.h> + + +namespace header_checker { +namespace repr { + + +std::unique_ptr<IRDiffDumper> IRDiffDumper::CreateIRDiffDumper( + TextFormatIR text_format, const std::string &dump_path) { + switch (text_format) { + case TextFormatIR::ProtobufTextFormat: + return CreateProtobufIRDiffDumper(dump_path); + default: + // Nothing else is supported yet. + llvm::errs() << "Text format not supported yet\n"; + return nullptr; + } +} + + +} // namespace repr +} // header_checker diff --git a/vndk/tools/header-checker/src/repr/ir_diff_dumper.h b/vndk/tools/header-checker/src/repr/ir_diff_dumper.h new file mode 100644 index 000000000..bb7a2eb2a --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_diff_dumper.h @@ -0,0 +1,68 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_IR_DIFF_DUMPER_H_ +#define HEADER_CHECKER_REPR_IR_DIFF_DUMPER_H_ + +#include "repr/ir_diff_representation.h" + +#include <string> + + +namespace header_checker { +namespace repr { + + +class IRDiffDumper { + public: + typedef DiffMessageIR::DiffKind DiffKind; + + public: + IRDiffDumper(const std::string &dump_path) : dump_path_(dump_path) {} + + virtual ~IRDiffDumper() {} + + virtual bool AddDiffMessageIR(const DiffMessageIR *, + const std::string &type_stack, + DiffKind diff_kind) = 0; + + virtual bool AddLinkableMessageIR(const LinkableMessageIR *, + DiffKind diff_kind) = 0; + + virtual bool AddElfSymbolMessageIR(const ElfSymbolIR *, + DiffKind diff_kind) = 0; + + virtual void AddLibNameIR(const std::string &name) = 0; + + virtual void AddArchIR(const std::string &arch) = 0; + + virtual void AddCompatibilityStatusIR(CompatibilityStatusIR status) = 0; + + virtual bool Dump() = 0; + + virtual CompatibilityStatusIR GetCompatibilityStatusIR() = 0; + + static std::unique_ptr<IRDiffDumper> CreateIRDiffDumper( + TextFormatIR, const std::string &dump_path); + + protected: + const std::string &dump_path_; +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_IR_DIFF_DUMPER_H_ diff --git a/vndk/tools/header-checker/src/repr/ir_diff_representation.h b/vndk/tools/header-checker/src/repr/ir_diff_representation.h new file mode 100644 index 000000000..2ec4c0def --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_diff_representation.h @@ -0,0 +1,358 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_IR_DIFF_REPRESENTATION_H_ +#define HEADER_CHECKER_REPR_IR_DIFF_REPRESENTATION_H_ + +#include "repr/ir_representation.h" + +#include <cstdint> +#include <memory> +#include <string> +#include <utility> +#include <vector> + + +namespace header_checker { +namespace repr { + + +class DiffMessageIR { + public: + enum DiffKind { + Extension, // Applicable for enums. + Added, + Removed, + Referenced, + Unreferenced + }; + + public: + virtual ~DiffMessageIR() {} + + virtual LinkableMessageKind Kind() const = 0; + + void SetName(const std::string &name) { + name_ = name; + } + + const std::string &GetName() const { + return name_; + } + + protected: + std::string name_; +}; + +class AccessSpecifierDiffIR { + public: + AccessSpecifierDiffIR(AccessSpecifierIR old_access, + AccessSpecifierIR new_access) + : old_access_(old_access), new_access_(new_access) {} + + protected: + AccessSpecifierIR old_access_; + AccessSpecifierIR new_access_; +}; + +class TypeDiffIR { + public: + TypeDiffIR(std::pair<uint64_t, uint64_t> &&sizes, + std::pair<uint32_t, uint32_t> &&alignment) + : sizes_(std::move(sizes)), alignments_(std::move(alignment)) {} + + const std::pair<uint64_t, uint64_t> &GetSizes() const { + return sizes_; + } + + const std::pair<uint32_t, uint32_t> &GetAlignments() const { + return alignments_; + } + + protected: + std::pair<uint64_t, uint64_t> sizes_; + std::pair<uint32_t, uint32_t> alignments_; +}; + +class VTableLayoutDiffIR { + public: + VTableLayoutDiffIR(const VTableLayoutIR &old_layout, + const VTableLayoutIR &new_layout) + : old_layout_(old_layout), new_layout_(new_layout) {} + + const VTableLayoutIR &GetOldVTable() const { + return old_layout_; + } + + const VTableLayoutIR &GetNewVTable() const { + return new_layout_; + } + + protected: + const VTableLayoutIR &old_layout_; + const VTableLayoutIR &new_layout_; +}; + +class RecordFieldDiffIR { + public: + RecordFieldDiffIR(const RecordFieldIR *old_field, + const RecordFieldIR *new_field) + : old_field_(old_field), new_field_(new_field) {} + + const RecordFieldIR *GetOldField() const { + return old_field_; + } + + const RecordFieldIR *GetNewField() const { + return new_field_; + } + + const RecordFieldIR *old_field_; + const RecordFieldIR *new_field_; +}; + +class CXXBaseSpecifierDiffIR { + public: + CXXBaseSpecifierDiffIR( + const std::vector<CXXBaseSpecifierIR> &old_base_specifiers, + const std::vector<CXXBaseSpecifierIR> &new_base_specifiers) + : old_base_specifiers_(old_base_specifiers), + new_base_specifiers_(new_base_specifiers) {} + + const std::vector<CXXBaseSpecifierIR> &GetOldBases() const { + return old_base_specifiers_; + } + + const std::vector<CXXBaseSpecifierIR> &GetNewBases() const { + return new_base_specifiers_; + } + + protected: + const std::vector<CXXBaseSpecifierIR> &old_base_specifiers_; + const std::vector<CXXBaseSpecifierIR> &new_base_specifiers_; +}; + +class RecordTypeDiffIR : public DiffMessageIR { + public: + LinkableMessageKind Kind() const override { + return LinkableMessageKind::RecordTypeKind; + } + + void SetFieldDiffs(std::vector<RecordFieldDiffIR> &&field_diffs) { + field_diffs_ = std::move(field_diffs); + } + + const std::vector<RecordFieldDiffIR> &GetFieldDiffs() const { + return field_diffs_; + } + + void SetFieldsRemoved(std::vector<const RecordFieldIR *> &&fields_removed) { + fields_removed_ = std::move(fields_removed); + } + + void SetFieldsAdded(std::vector<const RecordFieldIR *> &&fields_added) { + fields_added_ = std::move(fields_added); + } + + const std::vector<const RecordFieldIR *> &GetFieldsRemoved() const { + return fields_removed_; + } + + const std::vector<const RecordFieldIR *> &GetFieldsAdded() const { + return fields_added_; + } + + void SetVTableLayoutDiff(std::unique_ptr<VTableLayoutDiffIR> &&vtable_diffs) { + vtable_diffs_ = std::move(vtable_diffs); + } + + void SetTypeDiff(std::unique_ptr<TypeDiffIR> &&type_diff) { + type_diff_ = std::move(type_diff); + } + + void SetAccessDiff(std::unique_ptr<AccessSpecifierDiffIR> &&access_diff) { + access_diff_ = std::move(access_diff); + } + + void SetBaseSpecifierDiffs( + std::unique_ptr<CXXBaseSpecifierDiffIR> &&base_diffs) { + base_specifier_diffs_ = std::move(base_diffs); + } + + bool DiffExists() const { + return (type_diff_ != nullptr) || (vtable_diffs_ != nullptr) || + (fields_removed_.size() != 0) || (field_diffs_.size() != 0) || + (access_diff_ != nullptr) || (base_specifier_diffs_ != nullptr); + } + + const TypeDiffIR *GetTypeDiff() const { + return type_diff_.get(); + } + + const VTableLayoutDiffIR *GetVTableLayoutDiff() const { + return vtable_diffs_.get(); + } + + const CXXBaseSpecifierDiffIR *GetBaseSpecifiers() const { + return base_specifier_diffs_.get(); + } + + protected: + // optional implemented with vector / std::unique_ptr. + std::unique_ptr<TypeDiffIR> type_diff_; + std::unique_ptr<VTableLayoutDiffIR> vtable_diffs_; + std::vector<RecordFieldDiffIR> field_diffs_; + std::vector<const RecordFieldIR *> fields_removed_; + std::vector<const RecordFieldIR *> fields_added_; + std::unique_ptr<AccessSpecifierDiffIR> access_diff_; + std::unique_ptr<CXXBaseSpecifierDiffIR> base_specifier_diffs_; + // Template Diffs are not needed since they will show up in the linker set + // key. +}; + +class EnumFieldDiffIR { + public: + EnumFieldDiffIR(const EnumFieldIR *old_field, const EnumFieldIR *new_field) + : old_field_(old_field), new_field_(new_field) {} + + const EnumFieldIR *GetOldField() const { + return old_field_; + } + + const EnumFieldIR *GetNewField() const { + return new_field_; + } + + protected: + const EnumFieldIR *old_field_; + const EnumFieldIR *new_field_; +}; + +class EnumTypeDiffIR : public DiffMessageIR { + public: + void SetFieldsRemoved(std::vector<const EnumFieldIR *> &&fields_removed) { + fields_removed_ = std::move(fields_removed); + } + + const std::vector<const EnumFieldIR *> &GetFieldsRemoved() const { + return fields_removed_; + } + + void SetFieldsAdded(std::vector<const EnumFieldIR *> &&fields_added) { + fields_added_ = std::move(fields_added); + } + + const std::vector<const EnumFieldIR *> &GetFieldsAdded() const { + return fields_added_; + } + + void SetFieldsDiff(std::vector<EnumFieldDiffIR> &&fields_diff) { + fields_diff_ = std::move(fields_diff); + } + + const std::vector<EnumFieldDiffIR> &GetFieldsDiff() const { + return fields_diff_; + } + + void SetUnderlyingTypeDiff( + std::unique_ptr<std::pair<std::string, std::string>> &&utype_diff) { + underlying_type_diff_ = std::move(utype_diff); + } + + const std::pair<std::string, std::string> *GetUnderlyingTypeDiff() const { + return underlying_type_diff_.get(); + } + + bool IsExtended() const { + if (fields_removed_.size() == 0 && fields_diff_.size() == 0 && + fields_added_.size() != 0) { + return true; + } + return false; + } + + bool IsIncompatible() const { + if (fields_removed_.size() != 0 || fields_diff_.size() != 0) { + return true; + } + return false; + } + + LinkableMessageKind Kind() const override { + return LinkableMessageKind::EnumTypeKind; + } + + protected: + // The underlying type can only be integral, so we just need to check for + // referenced type. + std::unique_ptr<std::pair<std::string, std::string>> underlying_type_diff_; + std::vector<const EnumFieldIR *> fields_removed_; + std::vector<const EnumFieldIR *> fields_added_; + std::vector<EnumFieldDiffIR> fields_diff_; + // Modifiable to allow implicit construction. + std::string name_; +}; + +class GlobalVarDiffIR : public DiffMessageIR { + public: + LinkableMessageKind Kind() const override { + return LinkableMessageKind::GlobalVarKind; + } + + GlobalVarDiffIR(const GlobalVarIR *old_global_var, + const GlobalVarIR *new_global_var) + : old_global_var_(old_global_var), new_global_var_(new_global_var) {} + + const GlobalVarIR *GetOldGlobalVar() const { + return old_global_var_; + } + + const GlobalVarIR *GetNewGlobalVar() const { + return new_global_var_; + } + + protected: + const GlobalVarIR *old_global_var_; + const GlobalVarIR *new_global_var_; +}; + +class FunctionDiffIR : public DiffMessageIR { + public: + FunctionDiffIR(const FunctionIR *old_function, + const FunctionIR *new_function) + : old_function_(old_function), new_function_(new_function) {} + + LinkableMessageKind Kind() const override { + return LinkableMessageKind::FunctionKind; + } + + const FunctionIR *GetOldFunction() const { + return old_function_; + } + + const FunctionIR *GetNewFunction() const { + return new_function_; + } + + protected: + const FunctionIR *old_function_; + const FunctionIR *new_function_; +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_IR_DIFF_REPRESENTATION_H_ diff --git a/vndk/tools/header-checker/src/repr/ir_dumper.cpp b/vndk/tools/header-checker/src/repr/ir_dumper.cpp new file mode 100644 index 000000000..b195eaf15 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_dumper.cpp @@ -0,0 +1,111 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/ir_dumper.h" + +#include "repr/json/api.h" +#include "repr/protobuf/api.h" + +#include <algorithm> +#include <memory> +#include <string> +#include <vector> + +#include <llvm/Support/raw_ostream.h> + + +namespace header_checker { +namespace repr { + + +std::unique_ptr<IRDumper> IRDumper::CreateIRDumper( + TextFormatIR text_format, const std::string &dump_path) { + switch (text_format) { + case TextFormatIR::ProtobufTextFormat: + return CreateProtobufIRDumper(dump_path); + case TextFormatIR::Json: + return CreateJsonIRDumper(dump_path); + default: + llvm::errs() << "Text format not supported yet\n"; + return nullptr; + } +} + + +// TODO: Replace AbiElementMap key with linker_set_key and use the natural +// ordering. +template <typename T> +static std::vector<const T *> SortAbiElements(const AbiElementMap<T> &m) { + std::vector<const T *> xs; + + xs.reserve(m.size()); + for (auto &&item : m) { + xs.push_back(&item.second); + } + + auto &&compare = [](const T *lhs, const T *rhs) { + return lhs->GetLinkerSetKey() < rhs->GetLinkerSetKey(); + }; + std::stable_sort(xs.begin(), xs.end(), compare); + + return xs; +} + + +bool IRDumper::DumpModule(const ModuleIR &module) { + for (auto &&item : SortAbiElements(module.GetFunctions())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetGlobalVariables())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetRecordTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetFunctionTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetEnumTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetLvalueReferenceTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetRvalueReferenceTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetQualifiedTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetArrayTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetPointerTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : SortAbiElements(module.GetBuiltinTypes())) { + AddLinkableMessageIR(item); + } + for (auto &&item : module.GetElfFunctions()) { + AddElfSymbolMessageIR(&item.second); + } + for (auto &&item : module.GetElfObjects()) { + AddElfSymbolMessageIR(&item.second); + } + return true; +} + + +} // namespace repr +} // header_checker diff --git a/vndk/tools/header-checker/src/repr/ir_dumper.h b/vndk/tools/header-checker/src/repr/ir_dumper.h new file mode 100644 index 000000000..e8e30f909 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_dumper.h @@ -0,0 +1,54 @@ +// Copyright (C) 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_IR_DUMPER_H_ +#define HEADER_CHECKER_REPR_IR_DUMPER_H_ + +#include "repr/ir_representation.h" + +#include <string> + + +namespace header_checker { +namespace repr { + + +class IRDumper { + public: + IRDumper(const std::string &dump_path) : dump_path_(dump_path) {} + + virtual ~IRDumper() {} + + static std::unique_ptr<IRDumper> CreateIRDumper( + TextFormatIR text_format, const std::string &dump_path); + + virtual bool Dump(const ModuleIR &module) = 0; + + protected: + bool DumpModule(const ModuleIR &module); + + virtual bool AddLinkableMessageIR(const LinkableMessageIR *) = 0; + + virtual bool AddElfSymbolMessageIR(const ElfSymbolIR *) = 0; + + protected: + const std::string &dump_path_; +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_IR_DUMPER_H_ diff --git a/vndk/tools/header-checker/header-abi-util/src/ir_representation.cpp b/vndk/tools/header-checker/src/repr/ir_reader.cpp index 26dc22e31..3e4e928af 100644 --- a/vndk/tools/header-checker/header-abi-util/src/ir_representation.cpp +++ b/vndk/tools/header-checker/src/repr/ir_reader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 The Android Open Source Project +// Copyright (C) 2019 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,112 +12,78 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "ir_representation.h" +#include "repr/ir_reader.h" -#include "abi_diff_helpers.h" -#include "ir_representation_json.h" -#include "ir_representation_protobuf.h" +#include "repr/abi_diff_helpers.h" +#include "repr/ir_representation.h" +#include "repr/ir_representation_internal.h" +#include "repr/json/api.h" +#include "repr/protobuf/api.h" -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#pragma clang diagnostic ignored "-Wnested-anon-types" -#include "abi_dump.pb.h" -#pragma clang diagnostic pop - -#include <google/protobuf/text_format.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <list> +#include <memory> +#include <set> +#include <string> #include <llvm/Support/raw_ostream.h> -#include <string> -#include <memory> -namespace abi_util { +namespace header_checker { +namespace repr { -using MergeStatus = TextFormatToIRReader::MergeStatus; -std::unique_ptr<IRDumper> IRDumper::CreateIRDumper( - TextFormatIR text_format, const std::string &dump_path) { - switch (text_format) { - case TextFormatIR::ProtobufTextFormat: - return std::make_unique<ProtobufIRDumper>(dump_path); - case TextFormatIR::Json: - return std::make_unique<JsonIRDumper>(dump_path); - default: - llvm::errs() << "Text format not supported yet\n"; - return nullptr; - } -} +using MergeStatus = IRReader::MergeStatus; -std::unique_ptr<IRDiffDumper> IRDiffDumper::CreateIRDiffDumper( - TextFormatIR text_format, const std::string &dump_path) { - switch (text_format) { - case TextFormatIR::ProtobufTextFormat: - return std::make_unique<ProtobufIRDiffDumper>(dump_path); - default: - // Nothing else is supported yet. - llvm::errs() << "Text format not supported yet\n"; - return nullptr; - } -} -std::unique_ptr<TextFormatToIRReader> -TextFormatToIRReader::CreateTextFormatToIRReader( +std::unique_ptr<IRReader> +IRReader::CreateIRReader( TextFormatIR text_format, const std::set<std::string> *exported_headers) { switch (text_format) { case TextFormatIR::ProtobufTextFormat: - return std::make_unique<ProtobufTextFormatToIRReader>(exported_headers); + return CreateProtobufIRReader(exported_headers); case TextFormatIR::Json: - return std::make_unique<JsonToIRReader>(exported_headers); + return CreateJsonIRReader(exported_headers); default: llvm::errs() << "Text format not supported yet\n"; return nullptr; } } -void TextFormatToIRReader::AddToODRListMap(const std::string &key, - const TypeIR *value) { - auto map_it = odr_list_map_.find(key); - if (map_it == odr_list_map_.end()) { - odr_list_map_.emplace(key, std::list<const TypeIR *>({value})); - return; - } - odr_list_map_[key].emplace_back(value); -} -MergeStatus TextFormatToIRReader::IsBuiltinTypeNodePresent( - const BuiltinTypeIR *builtin_type, const TextFormatToIRReader &addend, +MergeStatus IRReader::IsBuiltinTypeNodePresent( + const BuiltinTypeIR *builtin_type, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { - std::string builtin_linker_set_key = builtin_type->GetLinkerSetKey(); - auto builtin_it = builtin_types_.find(builtin_linker_set_key); - if (builtin_it != builtin_types_.end()) { + auto builtin_it = module_->builtin_types_.find(builtin_linker_set_key); + if (builtin_it != module_->builtin_types_.end()) { return MergeStatus(false, builtin_it->second.GetSelfType()); } // Add this builtin type to the parent graph's builtin_types_ map. // Before that, correct the type id of the builtin-type. const std::string &local_type_id = builtin_type->GetSelfType(); std::string builtin_global_type_id = AllocateNewTypeId(); - auto it = builtin_types_.emplace(builtin_linker_set_key, *builtin_type); + auto it = module_->builtin_types_.emplace( + builtin_linker_set_key, *builtin_type); it.first->second.SetSelfType(builtin_global_type_id); it.first->second.SetReferencedType(builtin_global_type_id); - type_graph_.emplace(builtin_global_type_id, &((it.first)->second)); + module_->type_graph_.emplace(builtin_global_type_id, &((it.first)->second)); MergeStatus merge_status(true, builtin_global_type_id); local_to_global_type_id_map->emplace(local_type_id, merge_status); return merge_status; } -MergeStatus TextFormatToIRReader::DoesUDTypeODRViolationExist( - const TypeIR *ud_type, const TextFormatToIRReader &addend, - const std::string ud_type_unique_id_and_source, + +MergeStatus IRReader::DoesUDTypeODRViolationExist( + const TypeIR *ud_type, const IRReader &addend, + const std::string &ud_type_unique_id_and_source, AbiElementMap<MergeStatus> *local_to_global_type_id_map_) { // Per entry in the map: // /-----------------------------------------------------------------------\ // | UDType->UniqueTagId + UdType->source File => list(const UDTypeIR *) | // \-----------------------------------------------------------------------/ - auto it = odr_list_map_.find(ud_type_unique_id_and_source); - if (it == odr_list_map_.end()) { + auto it = module_->odr_list_map_.find(ud_type_unique_id_and_source); + if (it == module_->odr_list_map_.end()) { // Calling this an ODR violation even though it means no UD with the same // name + source combination was seen in the parent graph. The type-id // passed does not matter since was_newly_added_ is true, the type will get @@ -126,7 +92,7 @@ MergeStatus TextFormatToIRReader::DoesUDTypeODRViolationExist( } std::set<std::string> type_cache; DiffPolicyOptions diff_policy_options(false) ; - AbiDiffHelper diff_helper(type_graph_, addend.type_graph_, + AbiDiffHelper diff_helper(module_->type_graph_, addend.module_->type_graph_, diff_policy_options, &type_cache, nullptr, local_to_global_type_id_map_); for (auto &contender_ud : it->second) { @@ -145,8 +111,9 @@ MergeStatus TextFormatToIRReader::DoesUDTypeODRViolationExist( return MergeStatus(true, (*(it->second.begin()))->GetSelfType()); } -MergeStatus TextFormatToIRReader::IsTypeNodePresent( - const TypeIR *addend_node, const TextFormatToIRReader &addend, + +MergeStatus IRReader::IsTypeNodePresent( + const TypeIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { std::string unique_type_id; switch (addend_node->GetKind()) { @@ -172,11 +139,12 @@ MergeStatus TextFormatToIRReader::IsTypeNodePresent( addend_node, addend, unique_type_id, local_to_global_type_id_map); } + // This method merges the type referenced by 'references_type' into the parent // graph. It also corrects the referenced_type field in the references_type // object passed and returns the merge status of the *referenced type*. -MergeStatus TextFormatToIRReader::MergeReferencingTypeInternal( - const TextFormatToIRReader &addend, +MergeStatus IRReader::MergeReferencingTypeInternal( + const IRReader &addend, ReferencesOtherType *references_type, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { // First look in the local_to_global_type_id_map for the referenced type's @@ -194,8 +162,8 @@ MergeStatus TextFormatToIRReader::MergeReferencingTypeInternal( // If that did not go through, look at the addend's type_map_ and get the // TypeIR* and call MergeType on it. - auto local_type_it = addend.type_graph_.find(referenced_type_id); - if (local_type_it != addend.type_graph_.end()) { + auto local_type_it = addend.module_->type_graph_.find(referenced_type_id); + if (local_type_it != addend.module_->type_graph_.end()) { // We don't care about merge_status.was_newly_added since we wouldn't have // gotten this far if we weren't adding this. MergeStatus merge_status = @@ -211,24 +179,27 @@ MergeStatus TextFormatToIRReader::MergeReferencingTypeInternal( return MergeStatus(true, hidden_type_id); } -void TextFormatToIRReader::MergeRecordFields( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, + +void IRReader::MergeRecordFields( + const IRReader &addend, RecordTypeIR *added_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { for (auto &field : added_node->GetFields()) { MergeReferencingTypeInternal(addend, &field, local_to_global_type_id_map); } } -void TextFormatToIRReader::MergeRecordCXXBases( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, + +void IRReader::MergeRecordCXXBases( + const IRReader &addend, RecordTypeIR *added_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { for (auto &base : added_node->GetBases()) { MergeReferencingTypeInternal(addend, &base, local_to_global_type_id_map); } } -void TextFormatToIRReader::MergeRecordTemplateElements( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, + +void IRReader::MergeRecordTemplateElements( + const IRReader &addend, RecordTypeIR *added_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { for (auto &template_element : added_node->GetTemplateElements()) { MergeReferencingTypeInternal( @@ -236,8 +207,9 @@ void TextFormatToIRReader::MergeRecordTemplateElements( } } -void TextFormatToIRReader::MergeRecordDependencies( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, + +void IRReader::MergeRecordDependencies( + const IRReader &addend, RecordTypeIR *added_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { // First call MergeType on all its fields. MergeRecordFields(addend, added_node, local_to_global_type_id_map); @@ -248,10 +220,11 @@ void TextFormatToIRReader::MergeRecordDependencies( MergeRecordTemplateElements(addend, added_node, local_to_global_type_id_map); } + template <typename T> std::pair<MergeStatus, typename AbiElementMap<T>::iterator> -TextFormatToIRReader::UpdateUDTypeAccounting( - const T *addend_node, const TextFormatToIRReader &addend, +IRReader::UpdateUDTypeAccounting( + const T *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map, AbiElementMap<T> *specific_type_map) { std::string added_type_id = AllocateNewTypeId(); @@ -263,37 +236,40 @@ TextFormatToIRReader::UpdateUDTypeAccounting( added_type_ir.SetSelfType(added_type_id); added_type_ir.SetReferencedType(added_type_id); auto it = AddToMapAndTypeGraph(std::move(added_type_ir), specific_type_map, - &type_graph_); + &module_->type_graph_); // Add to faciliate ODR checking. const std::string &key = GetODRListMapKey(&(it->second)); MergeStatus type_merge_status = MergeStatus(true, added_type_id); - AddToODRListMap(key, &(it->second)); + module_->AddToODRListMap(key, &(it->second)); local_to_global_type_id_map->emplace(addend_node->GetSelfType(), type_merge_status); return {type_merge_status, it}; } + + // This method is necessarily going to have a was_newly_merged_ = true in its // MergeStatus return. So it necessarily merges a new RecordType. -MergeStatus TextFormatToIRReader::MergeRecordAndDependencies( - const RecordTypeIR *addend_node, const TextFormatToIRReader &addend, +MergeStatus IRReader::MergeRecordAndDependencies( + const RecordTypeIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { auto merge_status_and_it = UpdateUDTypeAccounting(addend_node, addend, local_to_global_type_id_map, - &record_types_); + &module_->record_types_); auto it = merge_status_and_it.second; MergeRecordDependencies(addend, &(it->second), local_to_global_type_id_map); return merge_status_and_it.first; } -void TextFormatToIRReader::MergeEnumDependencies( - const TextFormatToIRReader &addend, EnumTypeIR *added_node, + +void IRReader::MergeEnumDependencies( + const IRReader &addend, EnumTypeIR *added_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { const std::string underlying_type_id = added_node->GetUnderlyingType(); // Get the underlying type, it nessarily has to be present in the addend's // type graph since builtin types can't be hidden. Call MergeType on it and // change the underlying type to that. - auto it = addend.type_graph_.find(underlying_type_id); - if (it == addend.type_graph_.end()) { + auto it = addend.module_->type_graph_.find(underlying_type_id); + if (it == addend.module_->type_graph_.end()) { llvm::errs() << "Enum underlying types should not be hidden\n"; ::exit(1); } @@ -302,33 +278,36 @@ void TextFormatToIRReader::MergeEnumDependencies( added_node->SetUnderlyingType(merge_status.type_id_); } + // This method is necessarily going to have a was_newly_merged_ = true in its // MergeStatus return. So it necessarily merges a new EnumType. -MergeStatus TextFormatToIRReader::MergeEnumType( - const EnumTypeIR *addend_node, const TextFormatToIRReader &addend, +MergeStatus IRReader::MergeEnumType( + const EnumTypeIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { auto merge_status_and_it = UpdateUDTypeAccounting(addend_node, addend, local_to_global_type_id_map, - &enum_types_); + &module_->enum_types_); auto it = merge_status_and_it.second; MergeEnumDependencies(addend, &(it->second), local_to_global_type_id_map); return merge_status_and_it.first; } -MergeStatus TextFormatToIRReader::MergeFunctionType( - const FunctionTypeIR *addend_node, const TextFormatToIRReader &addend, + +MergeStatus IRReader::MergeFunctionType( + const FunctionTypeIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { auto merge_status_and_it = UpdateUDTypeAccounting(addend_node, addend, local_to_global_type_id_map, - &function_types_); + &module_->function_types_); auto it = merge_status_and_it.second; MergeCFunctionLikeDeps(addend, &(it->second), local_to_global_type_id_map); return merge_status_and_it.first; } + template <typename T> -MergeStatus TextFormatToIRReader::MergeReferencingTypeInternalAndUpdateParent( - const TextFormatToIRReader &addend, const T *addend_node, +MergeStatus IRReader::MergeReferencingTypeInternalAndUpdateParent( + const IRReader &addend, const T *addend_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map, AbiElementMap<T> *parent_map, const std::string &updated_self_type_id) { MergeStatus merge_status; @@ -341,7 +320,8 @@ MergeStatus TextFormatToIRReader::MergeReferencingTypeInternalAndUpdateParent( local_to_global_type_id_map); if (merge_status.was_newly_added_) { // Emplace to map (type-referenced -> Referencing type) - AddToMapAndTypeGraph(std::move(added_node), parent_map, &type_graph_); + AddToMapAndTypeGraph(std::move(added_node), parent_map, + &module_->type_graph_); return MergeStatus(true, updated_self_type_id); } @@ -368,7 +348,7 @@ MergeStatus TextFormatToIRReader::MergeReferencingTypeInternalAndUpdateParent( // the referenced type, so we added it to the parent and also updated the // local_to_global_type_id_map's global_id value. AddToMapAndTypeGraph(std::move(added_node), parent_map, - &type_graph_); + &module_->type_graph_); merge_status = MergeStatus(true, updated_self_type_id); return merge_status; @@ -387,32 +367,36 @@ MergeStatus TextFormatToIRReader::MergeReferencingTypeInternalAndUpdateParent( return merge_status; } -MergeStatus TextFormatToIRReader::MergeReferencingType( - const TextFormatToIRReader &addend, const TypeIR *addend_node, + +MergeStatus IRReader::MergeReferencingType( + const IRReader &addend, const TypeIR *addend_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map, const std::string &updated_self_type_id) { switch (addend_node->GetKind()) { case PointerTypeKind: return MergeReferencingTypeInternalAndUpdateParent( addend, static_cast<const PointerTypeIR *>(addend_node), - local_to_global_type_id_map, &pointer_types_, updated_self_type_id); + local_to_global_type_id_map, &module_->pointer_types_, + updated_self_type_id); case QualifiedTypeKind: return MergeReferencingTypeInternalAndUpdateParent( addend, static_cast<const QualifiedTypeIR *>(addend_node), - local_to_global_type_id_map, &qualified_types_, updated_self_type_id); + local_to_global_type_id_map, &module_->qualified_types_, + updated_self_type_id); case ArrayTypeKind: return MergeReferencingTypeInternalAndUpdateParent( addend, static_cast<const ArrayTypeIR *>(addend_node), - local_to_global_type_id_map, &array_types_, updated_self_type_id); + local_to_global_type_id_map, &module_->array_types_, + updated_self_type_id); case LvalueReferenceTypeKind: return MergeReferencingTypeInternalAndUpdateParent( addend, static_cast<const LvalueReferenceTypeIR *>(addend_node), - local_to_global_type_id_map, &lvalue_reference_types_, + local_to_global_type_id_map, &module_->lvalue_reference_types_, updated_self_type_id); case RvalueReferenceTypeKind: return MergeReferencingTypeInternalAndUpdateParent( addend, static_cast<const RvalueReferenceTypeIR *>(addend_node), - local_to_global_type_id_map, &rvalue_reference_types_, + local_to_global_type_id_map, &module_->rvalue_reference_types_, updated_self_type_id); default: // Only referencing types @@ -420,10 +404,11 @@ MergeStatus TextFormatToIRReader::MergeReferencingType( } } + // This method creates a new node for the addend node in the graph if MergeType // on the reference returned a MergeStatus with was_newly_added_ = true. -MergeStatus TextFormatToIRReader::MergeGenericReferringType( - const TextFormatToIRReader &addend, const TypeIR *addend_node, +MergeStatus IRReader::MergeGenericReferringType( + const IRReader &addend, const TypeIR *addend_node, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { // First add the type 'pro-actively'. We need to do this since we'll need to // fill in 'referenced-type' fields in all this type's descendants and @@ -436,8 +421,9 @@ MergeStatus TextFormatToIRReader::MergeGenericReferringType( added_type_id); } -MergeStatus TextFormatToIRReader::MergeTypeInternal( - const TypeIR *addend_node, const TextFormatToIRReader &addend, + +MergeStatus IRReader::MergeTypeInternal( + const TypeIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { switch (addend_node->GetKind()) { case BuiltinTypeKind: @@ -462,9 +448,9 @@ MergeStatus TextFormatToIRReader::MergeTypeInternal( assert(0); } -MergeStatus TextFormatToIRReader::MergeType( - const TypeIR *addend_node, - const TextFormatToIRReader &addend, + +MergeStatus IRReader::MergeType( + const TypeIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { // Check if the addend type is already in the parent graph. Since we're // going to traverse all the dependencies add whichever ones are not in the @@ -484,13 +470,14 @@ MergeStatus TextFormatToIRReader::MergeType( return merge_status; } -void TextFormatToIRReader::MergeCFunctionLikeDeps( - const TextFormatToIRReader &addend, CFunctionLikeIR *cfunction_like_ir, + +void IRReader::MergeCFunctionLikeDeps( + const IRReader &addend, CFunctionLikeIR *cfunction_like_ir, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { // Merge the return type first. auto ret_type_it = - addend.type_graph_.find(cfunction_like_ir->GetReturnType()); - if (ret_type_it == addend.type_graph_.end()) { + addend.module_->type_graph_.find(cfunction_like_ir->GetReturnType()); + if (ret_type_it == addend.module_->type_graph_.end()) { // Hidden types aren't officially added to the parent since there is // nothing actually backing it. We assign a type-id. cfunction_like_ir->SetReturnType(AllocateNewTypeId()); @@ -505,8 +492,9 @@ void TextFormatToIRReader::MergeCFunctionLikeDeps( } } -void TextFormatToIRReader::MergeFunctionDeps( - FunctionIR *added_node, const TextFormatToIRReader &addend, + +void IRReader::MergeFunctionDeps( + FunctionIR *added_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { MergeCFunctionLikeDeps(addend, added_node, local_to_global_type_id_map); // Merge and fix template parameters @@ -516,17 +504,19 @@ void TextFormatToIRReader::MergeFunctionDeps( } } + template <typename T> static bool IsLinkableMessagePresent(const LinkableMessageIR *lm, const AbiElementMap<T> &message_map) { return (message_map.find(lm->GetLinkerSetKey()) != message_map.end()); } -void TextFormatToIRReader::MergeFunction( - const FunctionIR *addend_node, const TextFormatToIRReader &addend, + +void IRReader::MergeFunction( + const FunctionIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { const std::string &function_linkage_name = addend_node->GetLinkerSetKey(); - if (IsLinkableMessagePresent(addend_node, functions_)) { + if (IsLinkableMessagePresent(addend_node, module_->functions_)) { // The functions and all of its dependencies have already been added. // No two globally visible functions can have the same symbol name. return; @@ -534,55 +524,51 @@ void TextFormatToIRReader::MergeFunction( FunctionIR function_ir = *addend_node; MergeFunctionDeps(&function_ir, addend, local_to_global_type_id_map); // Add it to the parent's function map. - functions_.emplace(function_linkage_name, std::move(function_ir)); + module_->functions_.emplace(function_linkage_name, std::move(function_ir)); } -std::string TextFormatToIRReader::AllocateNewTypeId() { + +std::string IRReader::AllocateNewTypeId() { return "type-" + std::to_string(++max_type_id_); } -void TextFormatToIRReader::MergeGlobalVariable( - const GlobalVarIR *addend_node, const TextFormatToIRReader &addend, + +void IRReader::MergeGlobalVariable( + const GlobalVarIR *addend_node, const IRReader &addend, AbiElementMap<MergeStatus> *local_to_global_type_id_map) { const std::string &global_variable_linkage_name = addend_node->GetLinkerSetKey(); - if (IsLinkableMessagePresent(addend_node, global_variables_)) { + if (IsLinkableMessagePresent(addend_node, module_->global_variables_)) { // The global variable and all of its dependencies have already been added. return; } GlobalVarIR global_variable_ir = *addend_node; MergeReferencingTypeInternal(addend, &global_variable_ir, local_to_global_type_id_map); - global_variables_.emplace(global_variable_linkage_name, - std::move(global_variable_ir)); + module_->global_variables_.emplace( + global_variable_linkage_name, std::move(global_variable_ir)); } -void TextFormatToIRReader::MergeGraphs(const TextFormatToIRReader &addend) { + +void IRReader::MergeGraphs(const IRReader &addend) { // Iterate through nodes of addend reader and merge them. // Keep a merged types cache since if a type is merged, so will all of its // dependencies which weren't already merged. AbiElementMap<MergeStatus> merged_types_cache; - for (auto &&type_ir : addend.type_graph_) { + for (auto &&type_ir : addend.module_->type_graph_) { MergeType(type_ir.second, addend, &merged_types_cache); } - for (auto &&function_ir : addend.functions_) { + for (auto &&function_ir : addend.module_->functions_) { MergeFunction(&function_ir.second, addend, &merged_types_cache); } - for (auto &&global_var_ir : addend.global_variables_) { + for (auto &&global_var_ir : addend.module_->global_variables_) { MergeGlobalVariable(&global_var_ir.second, addend, &merged_types_cache); } } -bool TextFormatToIRReader::IsLinkableMessageInExportedHeaders( - const LinkableMessageIR *linkable_message) const { - if (exported_headers_ == nullptr || exported_headers_->empty()) { - return true; - } - return exported_headers_->find(linkable_message->GetSourceFile()) != - exported_headers_->end(); -} -} // namespace abi_util +} // namespace repr +} // header_checker diff --git a/vndk/tools/header-checker/src/repr/ir_reader.h b/vndk/tools/header-checker/src/repr/ir_reader.h new file mode 100644 index 000000000..21a8f6951 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_reader.h @@ -0,0 +1,217 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_IR_READER_H_ +#define HEADER_CHECKER_REPR_IR_READER_H_ + +#include "repr/ir_representation.h" + +#include <cstdint> +#include <list> +#include <memory> +#include <set> +#include <string> +#include <utility> + + +namespace header_checker { +namespace repr { + + +class IRReader { + public: + struct MergeStatus { + MergeStatus(bool was_newly_added, const std::string &type_id) + : was_newly_added_(was_newly_added), type_id_(type_id) {} + + MergeStatus() {} + + // type_id_ always has the global_type_id corresponding to the type this + // MergeStatus corresponds to. For + // generic reference types (pointers, qual types, l(r)value references etc), + // this will be a proactively added type_id, which will be added to the + // parent type_graph if the we decide to add the referencing type to the + // parent post ODR checking. + bool was_newly_added_ = false; + + std::string type_id_; + }; + + public: + IRReader(const std::set<std::string> *exported_headers) + : module_(new ModuleIR(exported_headers)) {} + + virtual ~IRReader() {} + + virtual bool ReadDump(const std::string &dump_file) = 0; + + ModuleIR &GetModule() { + return *module_; + } + + std::unique_ptr<ModuleIR> TakeModule() { + return std::move(module_); + } + + void Merge(IRReader &&addend) { + MergeElements(&module_->functions_, std::move(addend.module_->functions_)); + MergeElements(&module_->global_variables_, + std::move(addend.module_->global_variables_)); + MergeElements(&module_->record_types_, + std::move(addend.module_->record_types_)); + MergeElements(&module_->enum_types_, + std::move(addend.module_->enum_types_)); + MergeElements(&module_->pointer_types_, + std::move(addend.module_->pointer_types_)); + MergeElements(&module_->lvalue_reference_types_, + std::move(addend.module_->lvalue_reference_types_)); + MergeElements(&module_->rvalue_reference_types_, + std::move(addend.module_->rvalue_reference_types_)); + MergeElements(&module_->array_types_, + std::move(addend.module_->array_types_)); + MergeElements(&module_->builtin_types_, + std::move(addend.module_->builtin_types_)); + MergeElements(&module_->qualified_types_, + std::move(addend.module_->qualified_types_)); + } + + template <typename T> + MergeStatus MergeReferencingTypeInternalAndUpdateParent( + const IRReader &addend, const T *addend_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map, + AbiElementMap<T> *parent_map, const std::string &updated_self_type_id); + + MergeStatus DoesUDTypeODRViolationExist( + const TypeIR *ud_type, const IRReader &addend, + const std::string &ud_type_unique_id, + AbiElementMap<MergeStatus> *local_to_global_type_id_map_); + + MergeStatus MergeReferencingTypeInternal( + const IRReader &addend, ReferencesOtherType *references_type, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + MergeStatus MergeReferencingType( + const IRReader &addend, const TypeIR *addend_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map, + const std::string &updated_self_type_id); + + MergeStatus MergeGenericReferringType( + const IRReader &addend, const TypeIR *addend_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + template <typename T> + std::pair<MergeStatus, typename AbiElementMap<T>::iterator> + UpdateUDTypeAccounting( + const T *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map, + AbiElementMap<T> *specific_type_map); + + MergeStatus MergeTypeInternal( + const TypeIR *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeCFunctionLikeDeps( + const IRReader &addend, CFunctionLikeIR *cfunction_like_ir, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + MergeStatus MergeFunctionType( + const FunctionTypeIR *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + MergeStatus MergeEnumType( + const EnumTypeIR *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeEnumDependencies( + const IRReader &addend, EnumTypeIR *added_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + MergeStatus MergeRecordAndDependencies( + const RecordTypeIR *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeRecordDependencies( + const IRReader &addend, RecordTypeIR *added_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeRecordFields( + const IRReader &addend, RecordTypeIR *added_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeRecordCXXBases( + const IRReader &addend, RecordTypeIR *added_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeRecordTemplateElements( + const IRReader &addend, RecordTypeIR *added_node, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + MergeStatus IsBuiltinTypeNodePresent( + const BuiltinTypeIR *builtin_type, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeGlobalVariable( + const GlobalVarIR *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeGlobalVariables( + const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeFunctionDeps( + FunctionIR *added_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeFunction( + const FunctionIR *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + void MergeGraphs(const IRReader &addend); + + void UpdateIRReaderTypeGraph( + const TypeIR *addend_node, const std::string &added_type_id, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + MergeStatus IsTypeNodePresent( + const TypeIR *addend_node, const IRReader &addend, + AbiElementMap<MergeStatus> *local_to_global_type_id_map); + + MergeStatus MergeType( + const TypeIR *addend_type, const IRReader &addend, + AbiElementMap<MergeStatus> *merged_types_cache); + + std::string AllocateNewTypeId(); + + static std::unique_ptr<IRReader> CreateIRReader( + TextFormatIR text_format, + const std::set<std::string> *exported_headers = nullptr); + + protected: + template <typename Augend, typename Addend> + inline void MergeElements(Augend *augend, Addend &&addend) { + augend->insert(std::make_move_iterator(addend.begin()), + std::make_move_iterator(addend.end())); + } + + std::unique_ptr<ModuleIR> module_; + + uint64_t max_type_id_ = 0; +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_IR_READER_H_ diff --git a/vndk/tools/header-checker/src/repr/ir_representation.cpp b/vndk/tools/header-checker/src/repr/ir_representation.cpp new file mode 100644 index 000000000..e755002de --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_representation.cpp @@ -0,0 +1,211 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/ir_representation.h" + +#include "repr/ir_reader.h" +#include "repr/ir_representation_internal.h" + +#include <utility> + + +namespace header_checker { +namespace repr { + + +template <typename T, typename U> +static inline T CreateTemp(const U &lm) { + // Cast source const reference to destination const reference and then create + // a temporary copy. + return static_cast<const T &>(lm); +} + + +bool ModuleIR::AddLinkableMessage(const LinkableMessageIR &lm) { + switch (lm.GetKind()) { + case RecordTypeKind: + AddRecordType(CreateTemp<RecordTypeIR>(lm)); + return true; + case EnumTypeKind: + AddEnumType(CreateTemp<EnumTypeIR>(lm)); + return true; + case PointerTypeKind: + AddPointerType(CreateTemp<PointerTypeIR>(lm)); + return true; + case QualifiedTypeKind: + AddQualifiedType(CreateTemp<QualifiedTypeIR>(lm)); + return true; + case ArrayTypeKind: + AddArrayType(CreateTemp<ArrayTypeIR>(lm)); + return true; + case LvalueReferenceTypeKind: + AddLvalueReferenceType(CreateTemp<LvalueReferenceTypeIR>(lm)); + return true; + case RvalueReferenceTypeKind: + AddRvalueReferenceType(CreateTemp<RvalueReferenceTypeIR>(lm)); + return true; + case BuiltinTypeKind: + AddBuiltinType(CreateTemp<BuiltinTypeIR>(lm)); + return true; + case FunctionTypeKind: + AddFunctionType(CreateTemp<FunctionTypeIR>(lm)); + return true; + case GlobalVarKind: + AddGlobalVariable(CreateTemp<GlobalVarIR>(lm)); + return true; + case FunctionKind: + AddFunction(CreateTemp<FunctionIR>(lm)); + return true; + } + return false; +} + + +bool ModuleIR::AddElfSymbol(const ElfSymbolIR &elf_symbol) { + switch (elf_symbol.GetKind()) { + case ElfSymbolIR::ElfFunctionKind: + AddElfFunction(CreateTemp<ElfFunctionIR>(elf_symbol)); + return true; + case ElfSymbolIR::ElfObjectKind: + AddElfObject(CreateTemp<ElfObjectIR>(elf_symbol)); + return true; + } + return false; +} + + +void ModuleIR::AddFunction(FunctionIR &&function) { + if (!IsLinkableMessageInExportedHeaders(&function)) { + return; + } + functions_.insert({function.GetLinkerSetKey(), std::move(function)}); +} + + +void ModuleIR::AddGlobalVariable(GlobalVarIR &&global_var) { + if (!IsLinkableMessageInExportedHeaders(&global_var)) { + return; + } + global_variables_.insert( + {global_var.GetLinkerSetKey(), std::move(global_var)}); +} + + +void ModuleIR::AddRecordType(RecordTypeIR &&record_type) { + if (!IsLinkableMessageInExportedHeaders(&record_type)) { + return; + } + auto it = AddToMapAndTypeGraph( + std::move(record_type), &record_types_, &type_graph_); + const std::string &key = GetODRListMapKey(&(it->second)); + AddToODRListMap(key, &(it->second)); +} + + +void ModuleIR::AddFunctionType(FunctionTypeIR &&function_type) { + if (!IsLinkableMessageInExportedHeaders(&function_type)) { + return; + } + auto it = AddToMapAndTypeGraph( + std::move(function_type), &function_types_, &type_graph_); + const std::string &key = GetODRListMapKey(&(it->second)); + AddToODRListMap(key, &(it->second)); +} + + +void ModuleIR::AddEnumType(EnumTypeIR &&enum_type) { + if (!IsLinkableMessageInExportedHeaders(&enum_type)) { + return; + } + auto it = AddToMapAndTypeGraph( + std::move(enum_type), &enum_types_, &type_graph_); + AddToODRListMap(it->second.GetUniqueId() + it->second.GetSourceFile(), + (&it->second)); +} + + +void ModuleIR::AddLvalueReferenceType( + LvalueReferenceTypeIR &&lvalue_reference_type) { + if (!IsLinkableMessageInExportedHeaders(&lvalue_reference_type)) { + return; + } + AddToMapAndTypeGraph(std::move(lvalue_reference_type), + &lvalue_reference_types_, &type_graph_); +} + + +void ModuleIR::AddRvalueReferenceType( + RvalueReferenceTypeIR &&rvalue_reference_type) { + if (!IsLinkableMessageInExportedHeaders(&rvalue_reference_type)) { + return; + } + AddToMapAndTypeGraph(std::move(rvalue_reference_type), + &rvalue_reference_types_, &type_graph_); +} + + +void ModuleIR::AddQualifiedType(QualifiedTypeIR &&qualified_type) { + if (!IsLinkableMessageInExportedHeaders(&qualified_type)) { + return; + } + AddToMapAndTypeGraph(std::move(qualified_type), &qualified_types_, + &type_graph_); +} + + +void ModuleIR::AddArrayType(ArrayTypeIR &&array_type) { + if (!IsLinkableMessageInExportedHeaders(&array_type)) { + return; + } + AddToMapAndTypeGraph(std::move(array_type), &array_types_, &type_graph_); +} + + +void ModuleIR::AddPointerType(PointerTypeIR &&pointer_type) { + if (!IsLinkableMessageInExportedHeaders(&pointer_type)) { + return; + } + AddToMapAndTypeGraph(std::move(pointer_type), &pointer_types_, &type_graph_); +} + + +void ModuleIR::AddBuiltinType(BuiltinTypeIR &&builtin_type) { + AddToMapAndTypeGraph(std::move(builtin_type), &builtin_types_, &type_graph_); +} + + +void ModuleIR::AddElfFunction(ElfFunctionIR &&elf_function) { + elf_functions_.insert( + {elf_function.GetName(), std::move(elf_function)}); +} + + +void ModuleIR::AddElfObject(ElfObjectIR &&elf_object) { + elf_objects_.insert( + {elf_object.GetName(), std::move(elf_object)}); +} + + +bool ModuleIR::IsLinkableMessageInExportedHeaders( + const LinkableMessageIR *linkable_message) const { + if (exported_headers_ == nullptr || exported_headers_->empty()) { + return true; + } + return exported_headers_->find(linkable_message->GetSourceFile()) != + exported_headers_->end(); +} + + +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/ir_representation.h b/vndk/tools/header-checker/src/repr/ir_representation.h index 886c39e85..60fe0d01a 100644 --- a/vndk/tools/header-checker/header-abi-util/include/ir_representation.h +++ b/vndk/tools/header-checker/src/repr/ir_representation.h @@ -15,19 +15,21 @@ #ifndef IR_REPRESENTATION_H_ #define IR_REPRESENTATION_H_ -#include <cassert> #include <list> #include <map> #include <memory> -#include <regex> #include <set> #include <string> #include <unordered_map> #include <vector> + +namespace header_checker { +namespace repr { + + // Classes which act as middle-men between clang AST parsing routines and // message format specific dumpers. -namespace abi_util { template <typename T> using AbiElementMap = std::map<std::string, T>; @@ -772,104 +774,11 @@ class ElfObjectIR : public ElfSymbolIR { } }; -class IRDumper { +class ModuleIR { public: - IRDumper(const std::string &dump_path) : dump_path_(dump_path) {} - - virtual ~IRDumper() {} - - static std::unique_ptr<IRDumper> CreateIRDumper( - TextFormatIR text_format, const std::string &dump_path); - - virtual bool AddLinkableMessageIR(const LinkableMessageIR *) = 0; - - virtual bool AddElfSymbolMessageIR(const ElfSymbolIR *) = 0; - - virtual bool Dump() = 0; - - protected: - const std::string &dump_path_; -}; - -template <typename T> -inline std::string GetReferencedTypeMapKey(T &element) { - return element.GetReferencedType(); -} - -template <> -inline std::string GetReferencedTypeMapKey<ArrayTypeIR>(ArrayTypeIR &element) { - return element.GetReferencedType() + ":" + std::to_string(element.GetSize()); -} - -template <> -inline std::string GetReferencedTypeMapKey<BuiltinTypeIR>( - BuiltinTypeIR &element) { - return element.GetLinkerSetKey(); -} - -inline static std::string BoolToString(bool val) { - return val ? "true" : "false"; -} - -template <> -inline std::string GetReferencedTypeMapKey<QualifiedTypeIR>( - QualifiedTypeIR &element) { - return element.GetReferencedType() + BoolToString(element.IsRestricted()) + - BoolToString(element.IsVolatile()) + BoolToString(element.IsConst()); -} - -inline std::string GetODRListMapKey(const RecordTypeIR *record_type_ir) { - if (record_type_ir->IsAnonymous()) { - return record_type_ir->GetLinkerSetKey() + record_type_ir->GetUniqueId(); - } - return record_type_ir->GetUniqueId() + record_type_ir->GetSourceFile(); -} - -inline std::string GetODRListMapKey(const EnumTypeIR *enum_type_ir) { - return enum_type_ir->GetUniqueId() + enum_type_ir->GetSourceFile(); -} - -inline std::string GetODRListMapKey(const FunctionTypeIR *function_type_ir) { - return function_type_ir->GetLinkerSetKey(); -} - -// The map that is being updated maps special_key -> Type / Function/ GlobVar -// This special key is needed to distinguish what is being referenced. -template <typename T> -typename AbiElementMap<T>::iterator AddToMapAndTypeGraph( - T &&element, AbiElementMap<T> *map_to_update, - AbiElementMap<const TypeIR *> *type_graph) { - auto it = map_to_update->emplace(GetReferencedTypeMapKey(element), - std::move(element)); - type_graph->emplace(it.first->second.GetSelfType(), &(it.first->second)); - return it.first; -} - -class TextFormatToIRReader { - public: - struct MergeStatus { - MergeStatus(bool was_newly_added, const std::string &type_id) - : was_newly_added_(was_newly_added), type_id_(type_id) {} - - MergeStatus() {} - - // type_id_ always has the global_type_id corresponding to the type this - // MergeStatus corresponds to. For - // generic reference types (pointers, qual types, l(r)value references etc), - // this will be a proactively added type_id, which will be added to the - // parent type_graph if the we decide to add the referencing type to the - // parent post ODR checking. - bool was_newly_added_ = false; - - std::string type_id_; - }; - - public: - TextFormatToIRReader(const std::set<std::string> *exported_headers) + ModuleIR(const std::set<std::string> *exported_headers) : exported_headers_(exported_headers) {} - virtual ~TextFormatToIRReader() {} - const AbiElementMap<FunctionIR> &GetFunctions() const { return functions_; } @@ -931,146 +840,53 @@ class TextFormatToIRReader { return odr_list_map_; } - virtual bool ReadDump(const std::string &dump_file) = 0; - - void Merge(TextFormatToIRReader &&addend) { - MergeElements(&functions_, std::move(addend.functions_)); - MergeElements(&global_variables_, std::move(addend.global_variables_)); - MergeElements(&record_types_, std::move(addend.record_types_)); - MergeElements(&enum_types_, std::move(addend.enum_types_)); - MergeElements(&pointer_types_, std::move(addend.pointer_types_)); - MergeElements(&lvalue_reference_types_, - std::move(addend.lvalue_reference_types_)); - MergeElements(&rvalue_reference_types_, - std::move(addend.rvalue_reference_types_)); - MergeElements(&array_types_, std::move(addend.array_types_)); - MergeElements(&builtin_types_, std::move(addend.builtin_types_)); - MergeElements(&qualified_types_, std::move(addend.qualified_types_)); - } - - void AddToODRListMap(const std::string &key, const TypeIR *value); - - template <typename T> - MergeStatus MergeReferencingTypeInternalAndUpdateParent( - const TextFormatToIRReader &addend, const T *addend_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map, - AbiElementMap<T> *parent_map, const std::string &updated_self_type_id); - MergeStatus DoesUDTypeODRViolationExist( - const TypeIR *ud_type, const TextFormatToIRReader &addend, - const std::string ud_type_unique_id, - AbiElementMap<MergeStatus> *local_to_global_type_id_map_); + bool AddLinkableMessage(const LinkableMessageIR &); - MergeStatus MergeReferencingTypeInternal( - const TextFormatToIRReader &addend, ReferencesOtherType *references_type, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddFunction(FunctionIR &&function); - MergeStatus MergeReferencingType( - const TextFormatToIRReader &addend, const TypeIR *addend_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map, - const std::string &updated_self_type_id); + void AddGlobalVariable(GlobalVarIR &&global_var); - MergeStatus MergeGenericReferringType( - const TextFormatToIRReader &addend, const TypeIR *addend_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddRecordType(RecordTypeIR &&record_type); - template <typename T> - std::pair<MergeStatus, typename AbiElementMap<T>::iterator> - UpdateUDTypeAccounting( - const T *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map, - AbiElementMap<T> *specific_type_map); + void AddFunctionType(FunctionTypeIR &&function_type); - MergeStatus MergeTypeInternal( - const TypeIR *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddEnumType(EnumTypeIR &&enum_type); - void MergeCFunctionLikeDeps( - const TextFormatToIRReader &addend, CFunctionLikeIR *cfunction_like_ir, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddLvalueReferenceType(LvalueReferenceTypeIR &&lvalue_reference_type); - MergeStatus MergeFunctionType( - const FunctionTypeIR *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddRvalueReferenceType(RvalueReferenceTypeIR &&rvalue_reference_type); - MergeStatus MergeEnumType( - const EnumTypeIR *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddQualifiedType(QualifiedTypeIR &&qualified_type); - void MergeEnumDependencies( - const TextFormatToIRReader &addend, EnumTypeIR *added_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddArrayType(ArrayTypeIR &&array_type); - MergeStatus MergeRecordAndDependencies( - const RecordTypeIR *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddPointerType(PointerTypeIR &&pointer_type); - void MergeRecordDependencies( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddBuiltinType(BuiltinTypeIR &&builtin_type); - void MergeRecordFields( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + bool AddElfSymbol(const ElfSymbolIR &); - void MergeRecordCXXBases( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddElfFunction(ElfFunctionIR &&elf_function); - void MergeRecordTemplateElements( - const TextFormatToIRReader &addend, RecordTypeIR *added_node, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); + void AddElfObject(ElfObjectIR &&elf_object); - MergeStatus IsBuiltinTypeNodePresent( - const BuiltinTypeIR *builtin_type, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); - - void MergeGlobalVariable( - const GlobalVarIR *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); - - void MergeGlobalVariables( - const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); - - void MergeFunctionDeps( - FunctionIR *added_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); - - void MergeFunction( - const FunctionIR *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); - - void MergeGraphs(const TextFormatToIRReader &addend); - - void UpdateTextFormatToIRReaderTypeGraph( - const TypeIR *addend_node, const std::string &added_type_id, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); - - MergeStatus IsTypeNodePresent( - const TypeIR *addend_node, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *local_to_global_type_id_map); - - MergeStatus MergeType( - const TypeIR *addend_type, const TextFormatToIRReader &addend, - AbiElementMap<MergeStatus> *merged_types_cache); - - std::string AllocateNewTypeId(); - - static std::unique_ptr<TextFormatToIRReader> CreateTextFormatToIRReader( - TextFormatIR text_format, - const std::set<std::string> *exported_headers = nullptr); - - protected: - template <typename Augend, typename Addend> - inline void MergeElements(Augend *augend, Addend &&addend) { - augend->insert(std::make_move_iterator(addend.begin()), - std::make_move_iterator(addend.end())); + void AddToODRListMap(const std::string &key, const TypeIR *value) { + auto map_it = odr_list_map_.find(key); + if (map_it == odr_list_map_.end()) { + odr_list_map_.emplace(key, std::list<const TypeIR *>({value})); + return; + } + odr_list_map_[key].emplace_back(value); } + + private: bool IsLinkableMessageInExportedHeaders( const LinkableMessageIR *linkable_message) const; + + public: AbiElementList<RecordTypeIR> record_types_list_; AbiElementMap<FunctionIR> functions_; AbiElementMap<GlobalVarIR> global_variables_; @@ -1078,7 +894,7 @@ class TextFormatToIRReader { AbiElementMap<FunctionTypeIR> function_types_; AbiElementMap<EnumTypeIR> enum_types_; // These maps which contain generic referring types as values are used while - // looking up whether in the parent graph, a particular reffering type refers + // looking up whether in the parent graph, a particular referring type refers // to a certain type id. The mechanism is useful while trying to determine // whether a generic referring type needs to be newly added to the parent // graph or not. @@ -1095,367 +911,11 @@ class TextFormatToIRReader { // maps unique_id + source_file -> const TypeIR * AbiElementUnorderedMap<std::list<const TypeIR *>> odr_list_map_; const std::set<std::string> *exported_headers_; - uint64_t max_type_id_ = 0; -}; - -class DiffMessageIR { - public: - enum DiffKind { - Extension, // Applicable for enums. - Added, - Removed, - Referenced, - Unreferenced - }; - - public: - virtual ~DiffMessageIR() {} - - virtual LinkableMessageKind Kind() const = 0; - - void SetName(const std::string &name) { - name_ = name; - } - - const std::string &GetName() const { - return name_; - } - - protected: - std::string name_; -}; - -class AccessSpecifierDiffIR { - public: - AccessSpecifierDiffIR(AccessSpecifierIR old_access, - AccessSpecifierIR new_access) - : old_access_(old_access), new_access_(new_access) {} - - protected: - AccessSpecifierIR old_access_; - AccessSpecifierIR new_access_; -}; - -class TypeDiffIR { - public: - TypeDiffIR(std::pair<uint64_t, uint64_t> &&sizes, - std::pair<uint32_t, uint32_t> &&alignment) - : sizes_(std::move(sizes)), alignments_(std::move(alignment)) {} - - const std::pair<uint64_t, uint64_t> &GetSizes() const { - return sizes_; - } - - const std::pair<uint32_t, uint32_t> &GetAlignments() const { - return alignments_; - } - - protected: - std::pair<uint64_t, uint64_t> sizes_; - std::pair<uint32_t, uint32_t> alignments_; -}; - -class VTableLayoutDiffIR { - public: - VTableLayoutDiffIR(const VTableLayoutIR &old_layout, - const VTableLayoutIR &new_layout) - : old_layout_(old_layout), new_layout_(new_layout) {} - - const VTableLayoutIR &GetOldVTable() const { - return old_layout_; - } - - const VTableLayoutIR &GetNewVTable() const { - return new_layout_; - } - - protected: - const VTableLayoutIR &old_layout_; - const VTableLayoutIR &new_layout_; -}; - -class RecordFieldDiffIR { - public: - RecordFieldDiffIR(const RecordFieldIR *old_field, - const RecordFieldIR *new_field) - : old_field_(old_field), new_field_(new_field) {} - - const RecordFieldIR *GetOldField() const { - return old_field_; - } - - const RecordFieldIR *GetNewField() const { - return new_field_; - } - - const RecordFieldIR *old_field_; - const RecordFieldIR *new_field_; -}; - -class CXXBaseSpecifierDiffIR { - public: - CXXBaseSpecifierDiffIR( - const std::vector<CXXBaseSpecifierIR> &old_base_specifiers, - const std::vector<CXXBaseSpecifierIR> &new_base_specifiers) - : old_base_specifiers_(old_base_specifiers), - new_base_specifiers_(new_base_specifiers) {} - - const std::vector<CXXBaseSpecifierIR> &GetOldBases() const { - return old_base_specifiers_; - } - - const std::vector<CXXBaseSpecifierIR> &GetNewBases() const { - return new_base_specifiers_; - } - - protected: - const std::vector<CXXBaseSpecifierIR> &old_base_specifiers_; - const std::vector<CXXBaseSpecifierIR> &new_base_specifiers_; -}; - -class RecordTypeDiffIR : public DiffMessageIR { - public: - LinkableMessageKind Kind() const override { - return LinkableMessageKind::RecordTypeKind; - } - - void SetFieldDiffs(std::vector<RecordFieldDiffIR> &&field_diffs) { - field_diffs_ = std::move(field_diffs); - } - - const std::vector<RecordFieldDiffIR> &GetFieldDiffs() const { - return field_diffs_; - } - - void SetFieldsRemoved(std::vector<const RecordFieldIR *> &&fields_removed) { - fields_removed_ = std::move(fields_removed); - } - - void SetFieldsAdded(std::vector<const RecordFieldIR *> &&fields_added) { - fields_added_ = std::move(fields_added); - } - - const std::vector<const RecordFieldIR *> &GetFieldsRemoved() const { - return fields_removed_; - } - - const std::vector<const RecordFieldIR *> &GetFieldsAdded() const { - return fields_added_; - } - - void SetVTableLayoutDiff(std::unique_ptr<VTableLayoutDiffIR> &&vtable_diffs) { - vtable_diffs_ = std::move(vtable_diffs); - } - - void SetTypeDiff(std::unique_ptr<TypeDiffIR> &&type_diff) { - type_diff_ = std::move(type_diff); - } - - void SetAccessDiff(std::unique_ptr<AccessSpecifierDiffIR> &&access_diff) { - access_diff_ = std::move(access_diff); - } - - void SetBaseSpecifierDiffs( - std::unique_ptr<CXXBaseSpecifierDiffIR> &&base_diffs) { - base_specifier_diffs_ = std::move(base_diffs); - } - - bool DiffExists() const { - return (type_diff_ != nullptr) || (vtable_diffs_ != nullptr) || - (fields_removed_.size() != 0) || (field_diffs_.size() != 0) || - (access_diff_ != nullptr) || (base_specifier_diffs_ != nullptr); - } - - const TypeDiffIR *GetTypeDiff() const { - return type_diff_.get(); - } - - const VTableLayoutDiffIR *GetVTableLayoutDiff() const { - return vtable_diffs_.get(); - } - - const CXXBaseSpecifierDiffIR *GetBaseSpecifiers() const { - return base_specifier_diffs_.get(); - } - - protected: - // optional implemented with vector / std::unique_ptr. - std::unique_ptr<TypeDiffIR> type_diff_; - std::unique_ptr<VTableLayoutDiffIR> vtable_diffs_; - std::vector<RecordFieldDiffIR> field_diffs_; - std::vector<const RecordFieldIR *> fields_removed_; - std::vector<const RecordFieldIR *> fields_added_; - std::unique_ptr<AccessSpecifierDiffIR> access_diff_; - std::unique_ptr<CXXBaseSpecifierDiffIR> base_specifier_diffs_; - // Template Diffs are not needed since they will show up in the linker set - // key. -}; - -class EnumFieldDiffIR { - public: - EnumFieldDiffIR(const EnumFieldIR *old_field, const EnumFieldIR *new_field) - : old_field_(old_field), new_field_(new_field) {} - - const EnumFieldIR *GetOldField() const { - return old_field_; - } - - const EnumFieldIR *GetNewField() const { - return new_field_; - } - - protected: - const EnumFieldIR *old_field_; - const EnumFieldIR *new_field_; -}; - -class EnumTypeDiffIR : public DiffMessageIR { - public: - void SetFieldsRemoved(std::vector<const EnumFieldIR *> &&fields_removed) { - fields_removed_ = std::move(fields_removed); - } - - const std::vector<const EnumFieldIR *> &GetFieldsRemoved() const { - return fields_removed_; - } - - void SetFieldsAdded(std::vector<const EnumFieldIR *> &&fields_added) { - fields_added_ = std::move(fields_added); - } - - const std::vector<const EnumFieldIR *> &GetFieldsAdded() const { - return fields_added_; - } - - void SetFieldsDiff(std::vector<EnumFieldDiffIR> &&fields_diff) { - fields_diff_ = std::move(fields_diff); - } - - const std::vector<EnumFieldDiffIR> &GetFieldsDiff() const { - return fields_diff_; - } - - void SetUnderlyingTypeDiff( - std::unique_ptr<std::pair<std::string, std::string>> &&utype_diff) { - underlying_type_diff_ = std::move(utype_diff); - } - - const std::pair<std::string, std::string> *GetUnderlyingTypeDiff() const { - return underlying_type_diff_.get(); - } - - bool IsExtended() const { - if (fields_removed_.size() == 0 && fields_diff_.size() == 0 && - fields_added_.size() != 0) { - return true; - } - return false; - } - - bool IsIncompatible() const { - if (fields_removed_.size() != 0 || fields_diff_.size() != 0) { - return true; - } - return false; - } - - LinkableMessageKind Kind() const override { - return LinkableMessageKind::EnumTypeKind; - } - - protected: - // The underlying type can only be integral, so we just need to check for - // referenced type. - std::unique_ptr<std::pair<std::string, std::string>> underlying_type_diff_; - std::vector<const EnumFieldIR *> fields_removed_; - std::vector<const EnumFieldIR *> fields_added_; - std::vector<EnumFieldDiffIR> fields_diff_; - // Modifiable to allow implicit construction. - std::string name_; }; -class GlobalVarDiffIR : public DiffMessageIR { - public: - LinkableMessageKind Kind() const override { - return LinkableMessageKind::GlobalVarKind; - } - - GlobalVarDiffIR(const GlobalVarIR *old_global_var, - const GlobalVarIR *new_global_var) - : old_global_var_(old_global_var), new_global_var_(new_global_var) {} - - const GlobalVarIR *GetOldGlobalVar() const { - return old_global_var_; - } - - const GlobalVarIR *GetNewGlobalVar() const { - return new_global_var_; - } - - protected: - const GlobalVarIR *old_global_var_; - const GlobalVarIR *new_global_var_; -}; -class FunctionDiffIR : public DiffMessageIR { - public: - FunctionDiffIR(const FunctionIR *old_function, - const FunctionIR *new_function) - : old_function_(old_function), new_function_(new_function) {} - - LinkableMessageKind Kind() const override { - return LinkableMessageKind::FunctionKind; - } - - const FunctionIR *GetOldFunction() const { - return old_function_; - } - - const FunctionIR *GetNewFunction() const { - return new_function_; - } - - protected: - const FunctionIR *old_function_; - const FunctionIR *new_function_; -}; - -class IRDiffDumper { - public: - typedef DiffMessageIR::DiffKind DiffKind; - - public: - IRDiffDumper(const std::string &dump_path) : dump_path_(dump_path) {} - - virtual ~IRDiffDumper() {} - - virtual bool AddDiffMessageIR(const DiffMessageIR *, - const std::string &type_stack, - DiffKind diff_kind) = 0; - - virtual bool AddLinkableMessageIR(const LinkableMessageIR *, - DiffKind diff_kind) = 0; - - virtual bool AddElfSymbolMessageIR(const ElfSymbolIR *, - DiffKind diff_kind) = 0; - - virtual void AddLibNameIR(const std::string &name) = 0; - - virtual void AddArchIR(const std::string &arch) = 0; - - virtual void AddCompatibilityStatusIR(CompatibilityStatusIR status) = 0; - - virtual bool Dump() = 0; - - virtual CompatibilityStatusIR GetCompatibilityStatusIR() = 0; - - static std::unique_ptr<IRDiffDumper> CreateIRDiffDumper( - TextFormatIR, const std::string &dump_path); - - protected: - const std::string &dump_path_; -}; +} // namespace repr +} // namespace header_checker -} // namespace abi_util #endif // IR_REPRESENTATION_H_ diff --git a/vndk/tools/header-checker/src/repr/ir_representation_internal.h b/vndk/tools/header-checker/src/repr/ir_representation_internal.h new file mode 100644 index 000000000..c5df1bb86 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/ir_representation_internal.h @@ -0,0 +1,86 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_IR_REPRESENTATION_INTERNAL_H_ +#define HEADER_CHECKER_REPR_IR_REPRESENTATION_INTERNAL_H_ + +#include "repr/ir_representation.h" + +#include <string> + + +namespace header_checker { +namespace repr { + + +template <typename T> +inline std::string GetReferencedTypeMapKey(T &element) { + return element.GetReferencedType(); +} + +template <> +inline std::string GetReferencedTypeMapKey<ArrayTypeIR>(ArrayTypeIR &element) { + return element.GetReferencedType() + ":" + std::to_string(element.GetSize()); +} + +template <> +inline std::string GetReferencedTypeMapKey<BuiltinTypeIR>( + BuiltinTypeIR &element) { + return element.GetLinkerSetKey(); +} + +inline static std::string BoolToString(bool val) { + return val ? "true" : "false"; +} + +template <> +inline std::string GetReferencedTypeMapKey<QualifiedTypeIR>( + QualifiedTypeIR &element) { + return element.GetReferencedType() + BoolToString(element.IsRestricted()) + + BoolToString(element.IsVolatile()) + BoolToString(element.IsConst()); +} + +inline std::string GetODRListMapKey(const RecordTypeIR *record_type_ir) { + if (record_type_ir->IsAnonymous()) { + return record_type_ir->GetLinkerSetKey() + record_type_ir->GetUniqueId(); + } + return record_type_ir->GetUniqueId() + record_type_ir->GetSourceFile(); +} + +inline std::string GetODRListMapKey(const EnumTypeIR *enum_type_ir) { + return enum_type_ir->GetUniqueId() + enum_type_ir->GetSourceFile(); +} + +inline std::string GetODRListMapKey(const FunctionTypeIR *function_type_ir) { + return function_type_ir->GetLinkerSetKey(); +} + +// The map that is being updated maps special_key -> Type / Function/ GlobVar +// This special key is needed to distinguish what is being referenced. +template <typename T> +typename AbiElementMap<T>::iterator AddToMapAndTypeGraph( + T &&element, AbiElementMap<T> *map_to_update, + AbiElementMap<const TypeIR *> *type_graph) { + auto it = map_to_update->emplace(GetReferencedTypeMapKey(element), + std::move(element)); + type_graph->emplace(it.first->second.GetSelfType(), &(it.first->second)); + return it.first; +} + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_IR_REPRESENTATION_INTERNAL_H_ diff --git a/vndk/tools/header-checker/src/repr/json/api.h b/vndk/tools/header-checker/src/repr/json/api.h new file mode 100644 index 000000000..95c1c37c1 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/json/api.h @@ -0,0 +1,41 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_JSON_API_H_ +#define HEADER_CHECKER_REPR_JSON_API_H_ + +#include <memory> +#include <set> +#include <string> + + +namespace header_checker { +namespace repr { + + +class IRDumper; +class IRReader; + + +std::unique_ptr<IRDumper> CreateJsonIRDumper(const std::string &dump_path); + +std::unique_ptr<IRReader> CreateJsonIRReader( + const std::set<std::string> *exported_headers); + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_JSON_API_H_ diff --git a/vndk/tools/header-checker/src/repr/json/converter.cpp b/vndk/tools/header-checker/src/repr/json/converter.cpp new file mode 100644 index 000000000..1cdaeddb8 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/json/converter.cpp @@ -0,0 +1,67 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/json/converter.h" + + +namespace header_checker { +namespace repr { + + +const JsonArray json_empty_array; +const JsonObject json_empty_object; +const Json::Value json_0(0); +const Json::Value json_false(false); +const Json::Value json_empty_string(""); + + +const AccessSpecifierIR default_access_ir = AccessSpecifierIR::PublicAccess; + +const RecordTypeIR::RecordKind default_record_kind_ir = + RecordTypeIR::RecordKind::struct_kind; + +const VTableComponentIR::Kind default_vtable_component_kind_ir = + VTableComponentIR::Kind::FunctionPointer; + +const ElfSymbolIR::ElfSymbolBinding default_elf_symbol_binding_ir = + ElfSymbolIR::ElfSymbolBinding::Global; + + +void JsonObject::Set(const std::string &key, bool value) { + SetOmissible(key, value, false); +} + + +void JsonObject::Set(const std::string &key, uint64_t value) { + SetOmissible<Json::UInt64>(key, value, 0); +} + + +void JsonObject::Set(const std::string &key, int64_t value) { + SetOmissible<Json::Int64>(key, value, 0); +} + + +void JsonObject::Set(const std::string &key, const std::string &value) { + SetOmissible<const std::string &>(key, value, ""); +} + + +void JsonObject::Set(const std::string &key, const JsonArray &value) { + SetOmissible(key, value, json_empty_array); +} + + +} // namespace repr +} // header_checker diff --git a/vndk/tools/header-checker/src/repr/json/converter.h b/vndk/tools/header-checker/src/repr/json/converter.h new file mode 100644 index 000000000..a6c82b980 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/json/converter.h @@ -0,0 +1,134 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_JSON_CONVERTER_H_ +#define HEADER_CHECKER_REPR_JSON_CONVERTER_H_ + +#include "repr/ir_representation.h" + +#include <json/value.h> + +#include <map> +#include <string> + +#include <llvm/Support/raw_ostream.h> + + +namespace header_checker { +namespace repr { + + +// These classes wrap constructors of Json::Value. +class JsonArray : public Json::Value { + public: + JsonArray() : Json::Value(Json::ValueType::arrayValue) {} +}; + + +class JsonObject : public Json::Value { + public: + JsonObject() : Json::Value(Json::ValueType::objectValue) {} + + // This method inserts the key-value pair if the value is not equal to the + // omissible value. + // Omit false. + void Set(const std::string &key, bool value); + + // Omit 0. + void Set(const std::string &key, uint64_t value); + + // Omit 0. + void Set(const std::string &key, int64_t value); + + // Omit "". + void Set(const std::string &key, const std::string &value); + + // Omit []. + void Set(const std::string &key, const JsonArray &value); + + private: + template <typename T> + inline void SetOmissible(const std::string &key, T value, T omissible_value) { + if (value != omissible_value) { + (*this)[key] = value; + } else { + removeMember(key); + } + } +}; + + +extern const JsonArray json_empty_array; +extern const JsonObject json_empty_object; +extern const Json::Value json_0; +extern const Json::Value json_false; +extern const Json::Value json_empty_string; + +extern const AccessSpecifierIR default_access_ir; +extern const RecordTypeIR::RecordKind default_record_kind_ir; +extern const VTableComponentIR::Kind default_vtable_component_kind_ir; +extern const ElfSymbolIR::ElfSymbolBinding default_elf_symbol_binding_ir; + + +// Conversion between IR enums and JSON strings. +static const std::map<AccessSpecifierIR, std::string> access_ir_to_json{ + {AccessSpecifierIR::PublicAccess, "public"}, + {AccessSpecifierIR::ProtectedAccess, "protected"}, + {AccessSpecifierIR::PrivateAccess, "private"}, +}; + +static const std::map<RecordTypeIR::RecordKind, std::string> + record_kind_ir_to_json{ + {RecordTypeIR::RecordKind::struct_kind, "struct"}, + {RecordTypeIR::RecordKind::class_kind, "class"}, + {RecordTypeIR::RecordKind::union_kind, "union"}, +}; + +static const std::map<VTableComponentIR::Kind, std::string> + vtable_component_kind_ir_to_json{ + {VTableComponentIR::Kind::VCallOffset, "vcall_offset"}, + {VTableComponentIR::Kind::VBaseOffset, "vbase_offset"}, + {VTableComponentIR::Kind::OffsetToTop, "offset_to_top"}, + {VTableComponentIR::Kind::RTTI, "rtti"}, + {VTableComponentIR::Kind::FunctionPointer, "function_pointer"}, + {VTableComponentIR::Kind::CompleteDtorPointer, "complete_dtor_pointer"}, + {VTableComponentIR::Kind::DeletingDtorPointer, "deleting_dtor_pointer"}, + {VTableComponentIR::Kind::UnusedFunctionPointer, "unused_function_pointer"}, +}; + +static const std::map<ElfSymbolIR::ElfSymbolBinding, std::string> + elf_symbol_binding_ir_to_json{ + {ElfSymbolIR::ElfSymbolBinding::Weak, "weak"}, + {ElfSymbolIR::ElfSymbolBinding::Global, "global"}, +}; + +// If m contains k, this function returns the value. +// Otherwise, it prints error_msg and exits. +template <typename K, typename V> +static inline const V &FindInMap(const std::map<K, V> &m, const K &k, + const std::string &error_msg) { + auto it = m.find(k); + if (it == m.end()) { + llvm::errs() << error_msg << "\n"; + ::exit(1); + } + return it->second; +} + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_JSON_CONVERTER_H_ diff --git a/vndk/tools/header-checker/src/repr/json/ir_dumper.cpp b/vndk/tools/header-checker/src/repr/json/ir_dumper.cpp new file mode 100644 index 000000000..c3341bea7 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/json/ir_dumper.cpp @@ -0,0 +1,437 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/json/ir_dumper.h" + +#include "repr/ir_dumper.h" +#include "repr/ir_reader.h" +#include "repr/ir_representation_internal.h" +#include "repr/json/api.h" +#include "repr/json/converter.h" + +#include <json/reader.h> +#include <json/writer.h> + +#include <llvm/Support/raw_ostream.h> + +#include <cstdlib> +#include <fstream> +#include <sstream> +#include <string> + + +namespace header_checker { +namespace repr { + + +static void AddAccess(JsonObject &type_decl, AccessSpecifierIR value) { + if (value != default_access_ir) { + type_decl.Set("access", + FindInMap(access_ir_to_json, value, + "Failed to convert AccessSpecifierIR to JSON")); + } +} + +static void AddRecordKind(JsonObject &record_type, + RecordTypeIR::RecordKind value) { + if (value != default_record_kind_ir) { + record_type.Set("record_kind", + FindInMap(record_kind_ir_to_json, value, + "Failed to convert RecordKind to JSON")); + } +} + +static void AddVtableComponentKind(JsonObject &vtable_component, + VTableComponentIR::Kind value) { + if (value != default_vtable_component_kind_ir) { + vtable_component.Set( + "kind", FindInMap(vtable_component_kind_ir_to_json, value, + "Failed to convert VTableComponentIR::Kind to JSON")); + } +} + +static void AddElfSymbolBinding(JsonObject &elf_symbol, + ElfSymbolIR::ElfSymbolBinding value) { + if (value != default_elf_symbol_binding_ir) { + elf_symbol.Set("binding", + FindInMap(elf_symbol_binding_ir_to_json, value, + "Failed to convert ElfSymbolBinding to JSON")); + } +} + +void IRToJsonConverter::AddTemplateInfo( + JsonObject &type_decl, const TemplatedArtifactIR *template_ir) { + JsonArray args; + for (auto &&template_element_ir : template_ir->GetTemplateElements()) { + args.append(template_element_ir.GetReferencedType()); + } + type_decl.Set("template_args", args); +} + +void IRToJsonConverter::AddTypeInfo(JsonObject &type_decl, + const TypeIR *type_ir) { + type_decl.Set("linker_set_key", type_ir->GetLinkerSetKey()); + type_decl.Set("source_file", type_ir->GetSourceFile()); + type_decl.Set("name", type_ir->GetName()); + type_decl.Set("size", (uint64_t)type_ir->GetSize()); + type_decl.Set("alignment", (uint64_t)type_ir->GetAlignment()); + type_decl.Set("referenced_type", type_ir->GetReferencedType()); + type_decl.Set("self_type", type_ir->GetSelfType()); +} + +static JsonObject ConvertRecordFieldIR(const RecordFieldIR *record_field_ir) { + JsonObject record_field; + record_field.Set("field_name", record_field_ir->GetName()); + record_field.Set("referenced_type", record_field_ir->GetReferencedType()); + AddAccess(record_field, record_field_ir->GetAccess()); + record_field.Set("field_offset", (uint64_t)record_field_ir->GetOffset()); + return record_field; +} + +void IRToJsonConverter::AddRecordFields(JsonObject &record_type, + const RecordTypeIR *record_ir) { + JsonArray fields; + for (auto &&field_ir : record_ir->GetFields()) { + fields.append(ConvertRecordFieldIR(&field_ir)); + } + record_type.Set("fields", fields); +} + +static JsonObject +ConvertBaseSpecifierIR(const CXXBaseSpecifierIR &base_specifier_ir) { + JsonObject base_specifier; + base_specifier.Set("referenced_type", base_specifier_ir.GetReferencedType()); + base_specifier.Set("is_virtual", base_specifier_ir.IsVirtual()); + AddAccess(base_specifier, base_specifier_ir.GetAccess()); + return base_specifier; +} + +void IRToJsonConverter::AddBaseSpecifiers(JsonObject &record_type, + const RecordTypeIR *record_ir) { + JsonArray base_specifiers; + for (auto &&base_ir : record_ir->GetBases()) { + base_specifiers.append(ConvertBaseSpecifierIR(base_ir)); + } + record_type.Set("base_specifiers", base_specifiers); +} + +static JsonObject +ConvertVTableComponentIR(const VTableComponentIR &vtable_component_ir) { + JsonObject vtable_component; + AddVtableComponentKind(vtable_component, vtable_component_ir.GetKind()); + vtable_component.Set("component_value", + (int64_t)vtable_component_ir.GetValue()); + vtable_component.Set("mangled_component_name", vtable_component_ir.GetName()); + vtable_component.Set("is_pure", vtable_component_ir.GetIsPure()); + return vtable_component; +} + +void IRToJsonConverter::AddVTableLayout(JsonObject &record_type, + const RecordTypeIR *record_ir) { + JsonArray vtable_components; + for (auto &&vtable_component_ir : + record_ir->GetVTableLayout().GetVTableComponents()) { + vtable_components.append(ConvertVTableComponentIR(vtable_component_ir)); + } + record_type.Set("vtable_components", vtable_components); +} + +void IRToJsonConverter::AddTagTypeInfo(JsonObject &type_decl, + const TagTypeIR *tag_type_ir) { + type_decl.Set("unique_id", tag_type_ir->GetUniqueId()); +} + +JsonObject IRToJsonConverter::ConvertRecordTypeIR(const RecordTypeIR *recordp) { + JsonObject record_type; + + AddAccess(record_type, recordp->GetAccess()); + AddRecordKind(record_type, recordp->GetRecordKind()); + record_type.Set("is_anonymous", recordp->IsAnonymous()); + AddTypeInfo(record_type, recordp); + AddRecordFields(record_type, recordp); + AddBaseSpecifiers(record_type, recordp); + AddVTableLayout(record_type, recordp); + AddTagTypeInfo(record_type, recordp); + AddTemplateInfo(record_type, recordp); + return record_type; +} + +void IRToJsonConverter::AddFunctionParametersAndSetReturnType( + JsonObject &function, const CFunctionLikeIR *cfunction_like_ir) { + function.Set("return_type", cfunction_like_ir->GetReturnType()); + AddFunctionParameters(function, cfunction_like_ir); +} + +void IRToJsonConverter::AddFunctionParameters( + JsonObject &function, const CFunctionLikeIR *cfunction_like_ir) { + JsonArray parameters; + for (auto &¶meter_ir : cfunction_like_ir->GetParameters()) { + JsonObject parameter; + parameter.Set("referenced_type", parameter_ir.GetReferencedType()); + parameter.Set("default_arg", parameter_ir.GetIsDefault()); + parameter.Set("is_this_ptr", parameter_ir.GetIsThisPtr()); + parameters.append(parameter); + } + function.Set("parameters", parameters); +} + +JsonObject +IRToJsonConverter::ConvertFunctionTypeIR(const FunctionTypeIR *function_typep) { + JsonObject function_type; + AddTypeInfo(function_type, function_typep); + AddFunctionParametersAndSetReturnType(function_type, function_typep); + return function_type; +} + +JsonObject IRToJsonConverter::ConvertFunctionIR(const FunctionIR *functionp) { + JsonObject function; + AddAccess(function, functionp->GetAccess()); + function.Set("linker_set_key", functionp->GetLinkerSetKey()); + function.Set("source_file", functionp->GetSourceFile()); + function.Set("function_name", functionp->GetName()); + AddFunctionParametersAndSetReturnType(function, functionp); + AddTemplateInfo(function, functionp); + return function; +} + +static JsonObject ConvertEnumFieldIR(const EnumFieldIR *enum_field_ir) { + JsonObject enum_field; + enum_field.Set("name", enum_field_ir->GetName()); + // Never omit enum values. + enum_field["enum_field_value"] = Json::Int64(enum_field_ir->GetValue()); + return enum_field; +} + +void IRToJsonConverter::AddEnumFields(JsonObject &enum_type, + const EnumTypeIR *enum_ir) { + JsonArray enum_fields; + for (auto &&field : enum_ir->GetFields()) { + enum_fields.append(ConvertEnumFieldIR(&field)); + } + enum_type.Set("enum_fields", enum_fields); +} + +JsonObject IRToJsonConverter::ConvertEnumTypeIR(const EnumTypeIR *enump) { + JsonObject enum_type; + AddAccess(enum_type, enump->GetAccess()); + enum_type.Set("underlying_type", enump->GetUnderlyingType()); + AddTypeInfo(enum_type, enump); + AddEnumFields(enum_type, enump); + AddTagTypeInfo(enum_type, enump); + return enum_type; +} + +JsonObject +IRToJsonConverter::ConvertGlobalVarIR(const GlobalVarIR *global_varp) { + JsonObject global_var; + global_var.Set("referenced_type", global_varp->GetReferencedType()); + global_var.Set("source_file", global_varp->GetSourceFile()); + global_var.Set("name", global_varp->GetName()); + global_var.Set("linker_set_key", global_varp->GetLinkerSetKey()); + AddAccess(global_var, global_varp->GetAccess()); + return global_var; +} + +JsonObject +IRToJsonConverter::ConvertPointerTypeIR(const PointerTypeIR *pointerp) { + JsonObject pointer_type; + AddTypeInfo(pointer_type, pointerp); + return pointer_type; +} + +JsonObject +IRToJsonConverter::ConvertQualifiedTypeIR(const QualifiedTypeIR *qualtypep) { + JsonObject qualified_type; + AddTypeInfo(qualified_type, qualtypep); + qualified_type.Set("is_const", qualtypep->IsConst()); + qualified_type.Set("is_volatile", qualtypep->IsVolatile()); + qualified_type.Set("is_restricted", qualtypep->IsRestricted()); + return qualified_type; +} + +JsonObject +IRToJsonConverter::ConvertBuiltinTypeIR(const BuiltinTypeIR *builtin_typep) { + JsonObject builtin_type; + builtin_type.Set("is_unsigned", builtin_typep->IsUnsigned()); + builtin_type.Set("is_integral", builtin_typep->IsIntegralType()); + AddTypeInfo(builtin_type, builtin_typep); + return builtin_type; +} + +JsonObject +IRToJsonConverter::ConvertArrayTypeIR(const ArrayTypeIR *array_typep) { + JsonObject array_type; + AddTypeInfo(array_type, array_typep); + return array_type; +} + +JsonObject IRToJsonConverter::ConvertLvalueReferenceTypeIR( + const LvalueReferenceTypeIR *lvalue_reference_typep) { + JsonObject lvalue_reference_type; + AddTypeInfo(lvalue_reference_type, lvalue_reference_typep); + return lvalue_reference_type; +} + +JsonObject IRToJsonConverter::ConvertRvalueReferenceTypeIR( + const RvalueReferenceTypeIR *rvalue_reference_typep) { + JsonObject rvalue_reference_type; + AddTypeInfo(rvalue_reference_type, rvalue_reference_typep); + return rvalue_reference_type; +} + +bool JsonIRDumper::AddLinkableMessageIR(const LinkableMessageIR *lm) { + std::string key; + JsonObject converted; + // No RTTI + switch (lm->GetKind()) { + case RecordTypeKind: + key = "record_types"; + converted = ConvertRecordTypeIR(static_cast<const RecordTypeIR *>(lm)); + break; + case EnumTypeKind: + key = "enum_types"; + converted = ConvertEnumTypeIR(static_cast<const EnumTypeIR *>(lm)); + break; + case PointerTypeKind: + key = "pointer_types"; + converted = ConvertPointerTypeIR(static_cast<const PointerTypeIR *>(lm)); + break; + case QualifiedTypeKind: + key = "qualified_types"; + converted = + ConvertQualifiedTypeIR(static_cast<const QualifiedTypeIR *>(lm)); + break; + case ArrayTypeKind: + key = "array_types"; + converted = ConvertArrayTypeIR(static_cast<const ArrayTypeIR *>(lm)); + break; + case LvalueReferenceTypeKind: + key = "lvalue_reference_types"; + converted = ConvertLvalueReferenceTypeIR( + static_cast<const LvalueReferenceTypeIR *>(lm)); + break; + case RvalueReferenceTypeKind: + key = "rvalue_reference_types"; + converted = ConvertRvalueReferenceTypeIR( + static_cast<const RvalueReferenceTypeIR *>(lm)); + break; + case BuiltinTypeKind: + key = "builtin_types"; + converted = ConvertBuiltinTypeIR(static_cast<const BuiltinTypeIR *>(lm)); + break; + case FunctionTypeKind: + key = "function_types"; + converted = ConvertFunctionTypeIR(static_cast<const FunctionTypeIR *>(lm)); + break; + case GlobalVarKind: + key = "global_vars"; + converted = ConvertGlobalVarIR(static_cast<const GlobalVarIR *>(lm)); + break; + case FunctionKind: + key = "functions"; + converted = ConvertFunctionIR(static_cast<const FunctionIR *>(lm)); + break; + default: + return false; + } + translation_unit_[key].append(converted); + return true; +} + +bool JsonIRDumper::AddElfSymbolMessageIR(const ElfSymbolIR *elf_symbol_ir) { + std::string key; + switch (elf_symbol_ir->GetKind()) { + case ElfSymbolIR::ElfFunctionKind: + key = "elf_functions"; + break; + case ElfSymbolIR::ElfObjectKind: + key = "elf_objects"; + break; + default: + return false; + } + JsonObject elf_symbol; + elf_symbol.Set("name", elf_symbol_ir->GetName()); + AddElfSymbolBinding(elf_symbol, elf_symbol_ir->GetBinding()); + translation_unit_[key].append(elf_symbol); + return true; +} + +static std::string DumpJson(const JsonObject &obj) { + std::ostringstream output_stream; + Json::StyledStreamWriter writer(/* indentation */ " "); + writer.write(output_stream, obj); + return output_stream.str(); +} + +static void WriteTailTrimmedLinesToFile(const std::string &path, + const std::string &output_string) { + std::ofstream output_file(path); + size_t line_start = 0; + while (line_start < output_string.size()) { + size_t trailing_space_start = line_start; + size_t index; + for (index = line_start; + index < output_string.size() && output_string[index] != '\n'; + index++) { + if (output_string[index] != ' ') { + trailing_space_start = index + 1; + } + } + // Only write this line if this line contains non-whitespace characters. + if (trailing_space_start != line_start) { + output_file.write(output_string.data() + line_start, + trailing_space_start - line_start); + output_file.write("\n", 1); + } + line_start = index + 1; + } +} + +bool JsonIRDumper::Dump(const ModuleIR &module) { + DumpModule(module); + std::string output_string = DumpJson(translation_unit_); + WriteTailTrimmedLinesToFile(dump_path_, output_string); + return true; +} + +JsonIRDumper::JsonIRDumper(const std::string &dump_path) + : IRDumper(dump_path), translation_unit_() { + const std::string keys[] = { + "record_types", + "enum_types", + "pointer_types", + "lvalue_reference_types", + "rvalue_reference_types", + "builtin_types", + "qualified_types", + "array_types", + "function_types", + "functions", + "global_vars", + "elf_functions", + "elf_objects", + }; + for (auto key : keys) { + translation_unit_[key] = JsonArray(); + } +} + +std::unique_ptr<IRDumper> CreateJsonIRDumper(const std::string &dump_path) { + return std::make_unique<JsonIRDumper>(dump_path); +} + + +} // namespace repr +} // header_checker diff --git a/vndk/tools/header-checker/src/repr/json/ir_dumper.h b/vndk/tools/header-checker/src/repr/json/ir_dumper.h new file mode 100644 index 000000000..0b2871f2c --- /dev/null +++ b/vndk/tools/header-checker/src/repr/json/ir_dumper.h @@ -0,0 +1,104 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_JSON_IR_DUMPER_H_ +#define HEADER_CHECKER_REPR_JSON_IR_DUMPER_H_ + +#include "repr/ir_dumper.h" +#include "repr/ir_reader.h" +#include "repr/ir_representation.h" +#include "repr/json/converter.h" + + +namespace header_checker { +namespace repr { + + +class IRToJsonConverter { + private: + static void AddTemplateInfo(JsonObject &type_decl, + const TemplatedArtifactIR *template_ir); + + // BasicNamedAndTypedDecl + static void AddTypeInfo(JsonObject &type_decl, const TypeIR *type_ir); + + static void AddRecordFields(JsonObject &record_type, + const RecordTypeIR *record_ir); + + static void AddBaseSpecifiers(JsonObject &record_type, + const RecordTypeIR *record_ir); + + static void AddVTableLayout(JsonObject &record_type, + const RecordTypeIR *record_ir); + + static void AddTagTypeInfo(JsonObject &type_decl, + const TagTypeIR *tag_type_ir); + + static void AddEnumFields(JsonObject &enum_type, const EnumTypeIR *enum_ir); + + public: + static JsonObject ConvertEnumTypeIR(const EnumTypeIR *enump); + + static JsonObject ConvertRecordTypeIR(const RecordTypeIR *recordp); + + static JsonObject ConvertFunctionTypeIR(const FunctionTypeIR *function_typep); + + static void AddFunctionParametersAndSetReturnType( + JsonObject &function, const CFunctionLikeIR *cfunction_like_ir); + + static void AddFunctionParameters(JsonObject &function, + const CFunctionLikeIR *cfunction_like_ir); + + static JsonObject ConvertFunctionIR(const FunctionIR *functionp); + + static JsonObject ConvertGlobalVarIR(const GlobalVarIR *global_varp); + + static JsonObject ConvertPointerTypeIR(const PointerTypeIR *pointerp); + + static JsonObject ConvertQualifiedTypeIR(const QualifiedTypeIR *qualtypep); + + static JsonObject ConvertBuiltinTypeIR(const BuiltinTypeIR *builtin_typep); + + static JsonObject ConvertArrayTypeIR(const ArrayTypeIR *array_typep); + + static JsonObject ConvertLvalueReferenceTypeIR( + const LvalueReferenceTypeIR *lvalue_reference_typep); + + static JsonObject ConvertRvalueReferenceTypeIR( + const RvalueReferenceTypeIR *rvalue_reference_typep); +}; + +class JsonIRDumper : public IRDumper, public IRToJsonConverter { + public: + JsonIRDumper(const std::string &dump_path); + + ~JsonIRDumper() override {} + + bool Dump(const ModuleIR &module) override; + + private: + bool AddLinkableMessageIR(const LinkableMessageIR *) override; + + bool AddElfSymbolMessageIR(const ElfSymbolIR *) override; + + private: + JsonObject translation_unit_; +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_JSON_IR_DUMPER_H_ diff --git a/vndk/tools/header-checker/src/repr/json/ir_reader.cpp b/vndk/tools/header-checker/src/repr/json/ir_reader.cpp new file mode 100644 index 000000000..a1d2df793 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/json/ir_reader.cpp @@ -0,0 +1,435 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/json/ir_reader.h" + +#include "repr/ir_dumper.h" +#include "repr/ir_reader.h" +#include "repr/ir_representation_internal.h" +#include "repr/json/api.h" +#include "repr/json/converter.h" + +#include <json/reader.h> +#include <json/writer.h> + +#include <llvm/Support/raw_ostream.h> + +#include <cstdlib> +#include <fstream> +#include <sstream> +#include <string> + + +namespace header_checker { +namespace repr { + + +static const std::map<std::string, AccessSpecifierIR> + access_json_to_ir(CreateInverseMap(access_ir_to_json)); + +static const std::map<std::string, RecordTypeIR::RecordKind> + record_kind_json_to_ir(CreateInverseMap(record_kind_ir_to_json)); + +static const std::map<std::string, VTableComponentIR::Kind> + vtable_component_kind_json_to_ir( + CreateInverseMap(vtable_component_kind_ir_to_json)); + +static const std::map<std::string, ElfSymbolIR::ElfSymbolBinding> + elf_symbol_binding_json_to_ir( + CreateInverseMap(elf_symbol_binding_ir_to_json)); + + +JsonObjectRef::JsonObjectRef(const Json::Value &json_value, bool &ok) + : object_(json_value.isObject() ? json_value : json_empty_object), ok_(ok) { + if (!json_value.isObject()) { + ok_ = false; + } +} + +const Json::Value & +JsonObjectRef::Get(const std::string &key, const Json::Value &default_value, + IsExpectedJsonType is_expected_type) const { + if (!object_.isMember(key)) { + return default_value; + } + const Json::Value &value = object_[key]; + if (!(value.*is_expected_type)()) { + ok_ = false; + return default_value; + } + return value; +} + +bool JsonObjectRef::GetBool(const std::string &key) const { + return Get(key, json_false, &Json::Value::isBool).asBool(); +} + +int64_t JsonObjectRef::GetInt(const std::string &key) const { + return Get(key, json_0, &Json::Value::isIntegral).asInt64(); +} + +uint64_t JsonObjectRef::GetUint(const std::string &key) const { + return Get(key, json_0, &Json::Value::isIntegral).asUInt64(); +} + +std::string JsonObjectRef::GetString(const std::string &key) const { + return Get(key, json_empty_string, &Json::Value::isString).asString(); +} + +JsonObjectRef JsonObjectRef::GetObject(const std::string &key) const { + return JsonObjectRef(Get(key, json_empty_object, &Json::Value::isObject), + ok_); +} + +JsonArrayRef<JsonObjectRef> +JsonObjectRef::GetObjects(const std::string &key) const { + return JsonArrayRef<JsonObjectRef>( + Get(key, json_empty_array, &Json::Value::isArray), ok_); +} + +JsonArrayRef<std::string> +JsonObjectRef::GetStrings(const std::string &key) const { + return JsonArrayRef<std::string>( + Get(key, json_empty_array, &Json::Value::isArray), ok_); +} + +template <> +JsonObjectRef JsonArrayRef<JsonObjectRef>::Iterator::operator*() const { + return JsonObjectRef(array_[index_], ok_); +} + +template <> std::string JsonArrayRef<std::string>::Iterator::operator*() const { + return array_[index_].asString(); +} + +static AccessSpecifierIR GetAccess(const JsonObjectRef &type_decl) { + std::string access(type_decl.GetString("access")); + if (access.empty()) { + return default_access_ir; + } + return FindInMap(access_json_to_ir, access, + "Failed to convert JSON to AccessSpecifierIR"); +} + +static RecordTypeIR::RecordKind +GetRecordKind(const JsonObjectRef &record_type) { + std::string kind(record_type.GetString("record_kind")); + if (kind.empty()) { + return default_record_kind_ir; + } + return FindInMap(record_kind_json_to_ir, kind, + "Failed to convert JSON to RecordKind"); +} + +static VTableComponentIR::Kind +GetVTableComponentKind(const JsonObjectRef &vtable_component) { + std::string kind(vtable_component.GetString("kind")); + if (kind.empty()) { + return default_vtable_component_kind_ir; + } + return FindInMap(vtable_component_kind_json_to_ir, kind, + "Failed to convert JSON to VTableComponentIR::Kind"); +} + +static ElfSymbolIR::ElfSymbolBinding +GetElfSymbolBinding(const JsonObjectRef &elf_symbol) { + std::string binding(elf_symbol.GetString("binding")); + if (binding.empty()) { + return default_elf_symbol_binding_ir; + } + return FindInMap(elf_symbol_binding_json_to_ir, binding, + "Failed to convert JSON to ElfSymbolBinding"); +} + +bool JsonIRReader::ReadDump(const std::string &dump_file) { + Json::Value tu_json; + Json::Reader reader; + std::ifstream input(dump_file); + + if (!reader.parse(input, tu_json, /* collectComments */ false)) { + llvm::errs() << "Failed to parse JSON: " + << reader.getFormattedErrorMessages() << "\n"; + return false; + } + bool ok = true; + JsonObjectRef tu(tu_json, ok); + if (!ok) { + llvm::errs() << "Translation unit is not an object\n"; + return false; + } + + ReadFunctions(tu); + ReadGlobalVariables(tu); + ReadEnumTypes(tu); + ReadRecordTypes(tu); + ReadFunctionTypes(tu); + ReadArrayTypes(tu); + ReadPointerTypes(tu); + ReadQualifiedTypes(tu); + ReadBuiltinTypes(tu); + ReadLvalueReferenceTypes(tu); + ReadRvalueReferenceTypes(tu); + ReadElfFunctions(tu); + ReadElfObjects(tu); + if (!ok) { + llvm::errs() << "Failed to convert JSON to IR\n"; + return false; + } + return true; +} + +void JsonIRReader::ReadTagTypeInfo(const JsonObjectRef &type_decl, + TagTypeIR *tag_type_ir) { + tag_type_ir->SetUniqueId(type_decl.GetString("unique_id")); +} + +void JsonIRReader::ReadTemplateInfo(const JsonObjectRef &type_decl, + TemplatedArtifactIR *template_ir) { + TemplateInfoIR template_info_ir; + for (auto &&referenced_type : type_decl.GetStrings("template_args")) { + TemplateElementIR template_element_ir(referenced_type); + template_info_ir.AddTemplateElement(std::move(template_element_ir)); + } + template_ir->SetTemplateInfo(std::move(template_info_ir)); +} + +void JsonIRReader::ReadTypeInfo(const JsonObjectRef &type_decl, + TypeIR *type_ir) { + type_ir->SetLinkerSetKey(type_decl.GetString("linker_set_key")); + type_ir->SetSourceFile(type_decl.GetString("source_file")); + type_ir->SetName(type_decl.GetString("name")); + type_ir->SetReferencedType(type_decl.GetString("referenced_type")); + type_ir->SetSelfType(type_decl.GetString("self_type")); + type_ir->SetSize(type_decl.GetUint("size")); + type_ir->SetAlignment(type_decl.GetUint("alignment")); +} + +void JsonIRReader::ReadRecordFields(const JsonObjectRef &record_type, + RecordTypeIR *record_ir) { + for (auto &&field : record_type.GetObjects("fields")) { + RecordFieldIR record_field_ir( + field.GetString("field_name"), field.GetString("referenced_type"), + field.GetUint("field_offset"), GetAccess(field)); + record_ir->AddRecordField(std::move(record_field_ir)); + } +} + +void JsonIRReader::ReadBaseSpecifiers(const JsonObjectRef &record_type, + RecordTypeIR *record_ir) { + for (auto &&base_specifier : record_type.GetObjects("base_specifiers")) { + CXXBaseSpecifierIR record_base_ir( + base_specifier.GetString("referenced_type"), + base_specifier.GetBool("is_virtual"), GetAccess(base_specifier)); + record_ir->AddCXXBaseSpecifier(std::move(record_base_ir)); + } +} + +void JsonIRReader::ReadVTableLayout(const JsonObjectRef &record_type, + RecordTypeIR *record_ir) { + VTableLayoutIR vtable_layout_ir; + for (auto &&vtable_component : record_type.GetObjects("vtable_components")) { + VTableComponentIR vtable_component_ir( + vtable_component.GetString("mangled_component_name"), + GetVTableComponentKind(vtable_component), + vtable_component.GetInt("component_value"), + vtable_component.GetBool("is_pure")); + vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir)); + } + record_ir->SetVTableLayout(std::move(vtable_layout_ir)); +} + +void JsonIRReader::ReadEnumFields(const JsonObjectRef &enum_type, + EnumTypeIR *enum_ir) { + for (auto &&field : enum_type.GetObjects("enum_fields")) { + EnumFieldIR enum_field_ir(field.GetString("name"), + field.GetInt("enum_field_value")); + enum_ir->AddEnumField(std::move(enum_field_ir)); + } +} + +void JsonIRReader::ReadFunctionParametersAndReturnType( + const JsonObjectRef &function, CFunctionLikeIR *function_ir) { + function_ir->SetReturnType(function.GetString("return_type")); + for (auto &¶meter : function.GetObjects("parameters")) { + ParamIR param_ir(parameter.GetString("referenced_type"), + parameter.GetBool("default_arg"), + parameter.GetBool("is_this_ptr")); + function_ir->AddParameter(std::move(param_ir)); + } +} + +FunctionIR JsonIRReader::FunctionJsonToIR(const JsonObjectRef &function) { + FunctionIR function_ir; + function_ir.SetLinkerSetKey(function.GetString("linker_set_key")); + function_ir.SetName(function.GetString("function_name")); + function_ir.SetAccess(GetAccess(function)); + function_ir.SetSourceFile(function.GetString("source_file")); + ReadFunctionParametersAndReturnType(function, &function_ir); + ReadTemplateInfo(function, &function_ir); + return function_ir; +} + +FunctionTypeIR +JsonIRReader::FunctionTypeJsonToIR(const JsonObjectRef &function_type) { + FunctionTypeIR function_type_ir; + ReadTypeInfo(function_type, &function_type_ir); + ReadFunctionParametersAndReturnType(function_type, &function_type_ir); + return function_type_ir; +} + +RecordTypeIR +JsonIRReader::RecordTypeJsonToIR(const JsonObjectRef &record_type) { + RecordTypeIR record_type_ir; + ReadTypeInfo(record_type, &record_type_ir); + ReadTemplateInfo(record_type, &record_type_ir); + record_type_ir.SetAccess(GetAccess(record_type)); + ReadVTableLayout(record_type, &record_type_ir); + ReadRecordFields(record_type, &record_type_ir); + ReadBaseSpecifiers(record_type, &record_type_ir); + record_type_ir.SetRecordKind(GetRecordKind(record_type)); + record_type_ir.SetAnonymity(record_type.GetBool("is_anonymous")); + ReadTagTypeInfo(record_type, &record_type_ir); + return record_type_ir; +} + +EnumTypeIR JsonIRReader::EnumTypeJsonToIR(const JsonObjectRef &enum_type) { + EnumTypeIR enum_type_ir; + ReadTypeInfo(enum_type, &enum_type_ir); + enum_type_ir.SetUnderlyingType(enum_type.GetString("underlying_type")); + enum_type_ir.SetAccess(GetAccess(enum_type)); + ReadEnumFields(enum_type, &enum_type_ir); + ReadTagTypeInfo(enum_type, &enum_type_ir); + return enum_type_ir; +} + +void JsonIRReader::ReadGlobalVariables(const JsonObjectRef &tu) { + for (auto &&global_variable : tu.GetObjects("global_vars")) { + GlobalVarIR global_variable_ir; + global_variable_ir.SetName(global_variable.GetString("name")); + global_variable_ir.SetAccess(GetAccess(global_variable)); + global_variable_ir.SetSourceFile(global_variable.GetString("source_file")); + global_variable_ir.SetReferencedType( + global_variable.GetString("referenced_type")); + global_variable_ir.SetLinkerSetKey( + global_variable.GetString("linker_set_key")); + module_->AddGlobalVariable(std::move(global_variable_ir)); + } +} + +void JsonIRReader::ReadPointerTypes(const JsonObjectRef &tu) { + for (auto &&pointer_type : tu.GetObjects("pointer_types")) { + PointerTypeIR pointer_type_ir; + ReadTypeInfo(pointer_type, &pointer_type_ir); + module_->AddPointerType(std::move(pointer_type_ir)); + } +} + +void JsonIRReader::ReadBuiltinTypes(const JsonObjectRef &tu) { + for (auto &&builtin_type : tu.GetObjects("builtin_types")) { + BuiltinTypeIR builtin_type_ir; + ReadTypeInfo(builtin_type, &builtin_type_ir); + builtin_type_ir.SetSignedness(builtin_type.GetBool("is_unsigned")); + builtin_type_ir.SetIntegralType(builtin_type.GetBool("is_integral")); + module_->AddBuiltinType(std::move(builtin_type_ir)); + } +} + +void JsonIRReader::ReadQualifiedTypes(const JsonObjectRef &tu) { + for (auto &&qualified_type : tu.GetObjects("qualified_types")) { + QualifiedTypeIR qualified_type_ir; + ReadTypeInfo(qualified_type, &qualified_type_ir); + qualified_type_ir.SetConstness(qualified_type.GetBool("is_const")); + qualified_type_ir.SetVolatility(qualified_type.GetBool("is_volatile")); + qualified_type_ir.SetRestrictedness( + qualified_type.GetBool("is_restricted")); + module_->AddQualifiedType(std::move(qualified_type_ir)); + } +} + +void JsonIRReader::ReadArrayTypes(const JsonObjectRef &tu) { + for (auto &&array_type : tu.GetObjects("array_types")) { + ArrayTypeIR array_type_ir; + ReadTypeInfo(array_type, &array_type_ir); + module_->AddArrayType(std::move(array_type_ir)); + } +} + +void JsonIRReader::ReadLvalueReferenceTypes(const JsonObjectRef &tu) { + for (auto &&lvalue_reference_type : tu.GetObjects("lvalue_reference_types")) { + LvalueReferenceTypeIR lvalue_reference_type_ir; + ReadTypeInfo(lvalue_reference_type, &lvalue_reference_type_ir); + module_->AddLvalueReferenceType(std::move(lvalue_reference_type_ir)); + } +} + +void JsonIRReader::ReadRvalueReferenceTypes(const JsonObjectRef &tu) { + for (auto &&rvalue_reference_type : tu.GetObjects("rvalue_reference_types")) { + RvalueReferenceTypeIR rvalue_reference_type_ir; + ReadTypeInfo(rvalue_reference_type, &rvalue_reference_type_ir); + module_->AddRvalueReferenceType(std::move(rvalue_reference_type_ir)); + } +} + +void JsonIRReader::ReadFunctions(const JsonObjectRef &tu) { + for (auto &&function : tu.GetObjects("functions")) { + FunctionIR function_ir = FunctionJsonToIR(function); + module_->AddFunction(std::move(function_ir)); + } +} + +void JsonIRReader::ReadRecordTypes(const JsonObjectRef &tu) { + for (auto &&record_type : tu.GetObjects("record_types")) { + RecordTypeIR record_type_ir = RecordTypeJsonToIR(record_type); + module_->AddRecordType(std::move(record_type_ir)); + } +} + +void JsonIRReader::ReadFunctionTypes(const JsonObjectRef &tu) { + for (auto &&function_type : tu.GetObjects("function_types")) { + FunctionTypeIR function_type_ir = FunctionTypeJsonToIR(function_type); + module_->AddFunctionType(std::move(function_type_ir)); + } +} + +void JsonIRReader::ReadEnumTypes(const JsonObjectRef &tu) { + for (auto &&enum_type : tu.GetObjects("enum_types")) { + EnumTypeIR enum_type_ir = EnumTypeJsonToIR(enum_type); + module_->AddEnumType(std::move(enum_type_ir)); + } +} + +void JsonIRReader::ReadElfFunctions(const JsonObjectRef &tu) { + for (auto &&elf_function : tu.GetObjects("elf_functions")) { + ElfFunctionIR elf_function_ir(elf_function.GetString("name"), + GetElfSymbolBinding(elf_function)); + module_->AddElfFunction(std::move(elf_function_ir)); + } +} + +void JsonIRReader::ReadElfObjects(const JsonObjectRef &tu) { + for (auto &&elf_object : tu.GetObjects("elf_objects")) { + ElfObjectIR elf_object_ir(elf_object.GetString("name"), + GetElfSymbolBinding(elf_object)); + module_->AddElfObject(std::move(elf_object_ir)); + } +} + +std::unique_ptr<IRReader> CreateJsonIRReader( + const std::set<std::string> *exported_headers) { + return std::make_unique<JsonIRReader>(exported_headers); +} + + +} // namespace repr +} // header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/ir_representation_json.h b/vndk/tools/header-checker/src/repr/json/ir_reader.h index 9b4c36f3b..cdaac6c9e 100644 --- a/vndk/tools/header-checker/header-abi-util/include/ir_representation_json.h +++ b/vndk/tools/header-checker/src/repr/json/ir_reader.h @@ -1,4 +1,4 @@ -// Copyright (C) 2018 The Android Open Source Project +// Copyright (C) 2019 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,124 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef IR_REPRESENTATION_JSON_H_ -#define IR_REPRESENTATION_JSON_H_ +#ifndef HEADER_CHECKER_REPR_JSON_IR_READER_H_ +#define HEADER_CHECKER_REPR_JSON_IR_READER_H_ -#include "ir_representation.h" +#include "repr/ir_dumper.h" +#include "repr/ir_reader.h" +#include "repr/ir_representation.h" #include <json/value.h> -// Classes which act as middle-men between clang AST parsing routines and -// message format specific dumpers. -namespace abi_util { -// These classes wrap constructors of Json::Value. -class JsonArray : public Json::Value { - public: - JsonArray() : Json::Value(Json::ValueType::arrayValue) {} -}; - -class JsonObject : public Json::Value { - public: - JsonObject() : Json::Value(Json::ValueType::objectValue) {} - - // This method inserts the key-value pair if the value is not equal to the - // omissible value. - // Omit false. - void Set(const std::string &key, bool value); - - // Omit 0. - void Set(const std::string &key, uint64_t value); - - // Omit 0. - void Set(const std::string &key, int64_t value); - - // Omit "". - void Set(const std::string &key, const std::string &value); - - // Omit []. - void Set(const std::string &key, const JsonArray &value); - - private: - template <typename T> - inline void SetOmissible(const std::string &key, T value, T omissible_value) { - if (value != omissible_value) { - (*this)[key] = value; - } else { - removeMember(key); - } - } -}; - -class IRToJsonConverter { - private: - static void AddTemplateInfo(JsonObject &type_decl, - const TemplatedArtifactIR *template_ir); - - // BasicNamedAndTypedDecl - static void AddTypeInfo(JsonObject &type_decl, const TypeIR *type_ir); - - static void AddRecordFields(JsonObject &record_type, - const RecordTypeIR *record_ir); - - static void AddBaseSpecifiers(JsonObject &record_type, - const RecordTypeIR *record_ir); - - static void AddVTableLayout(JsonObject &record_type, - const RecordTypeIR *record_ir); - - static void AddTagTypeInfo(JsonObject &type_decl, - const TagTypeIR *tag_type_ir); - - static void AddEnumFields(JsonObject &enum_type, const EnumTypeIR *enum_ir); - - public: - static JsonObject ConvertEnumTypeIR(const EnumTypeIR *enump); +namespace header_checker { +namespace repr { - static JsonObject ConvertRecordTypeIR(const RecordTypeIR *recordp); - - static JsonObject ConvertFunctionTypeIR(const FunctionTypeIR *function_typep); - - static void AddFunctionParametersAndSetReturnType( - JsonObject &function, const CFunctionLikeIR *cfunction_like_ir); - - static void AddFunctionParameters(JsonObject &function, - const CFunctionLikeIR *cfunction_like_ir); - - static JsonObject ConvertFunctionIR(const FunctionIR *functionp); - - static JsonObject ConvertGlobalVarIR(const GlobalVarIR *global_varp); - - static JsonObject ConvertPointerTypeIR(const PointerTypeIR *pointerp); - - static JsonObject ConvertQualifiedTypeIR(const QualifiedTypeIR *qualtypep); - - static JsonObject ConvertBuiltinTypeIR(const BuiltinTypeIR *builtin_typep); - - static JsonObject ConvertArrayTypeIR(const ArrayTypeIR *array_typep); - - static JsonObject ConvertLvalueReferenceTypeIR( - const LvalueReferenceTypeIR *lvalue_reference_typep); - - static JsonObject ConvertRvalueReferenceTypeIR( - const RvalueReferenceTypeIR *rvalue_reference_typep); -}; - -class JsonIRDumper : public IRDumper, public IRToJsonConverter { - public: - JsonIRDumper(const std::string &dump_path); - - ~JsonIRDumper() override {} - - bool AddLinkableMessageIR(const LinkableMessageIR *) override; - - bool AddElfSymbolMessageIR(const ElfSymbolIR *) override; - - bool Dump() override; - - private: - JsonObject translation_unit_; -}; template <typename T> class JsonArrayRef; @@ -216,10 +111,10 @@ JsonObjectRef JsonArrayRef<JsonObjectRef>::Iterator::operator*() const; template <> std::string JsonArrayRef<std::string>::Iterator::operator*() const; -class JsonToIRReader : public TextFormatToIRReader { +class JsonIRReader : public IRReader { public: - JsonToIRReader(const std::set<std::string> *exported_headers) - : TextFormatToIRReader(exported_headers) {} + JsonIRReader(const std::set<std::string> *exported_headers) + : IRReader(exported_headers) {} bool ReadDump(const std::string &dump_file) override; @@ -283,6 +178,9 @@ class JsonToIRReader : public TextFormatToIRReader { static EnumTypeIR EnumTypeJsonToIR(const JsonObjectRef &enum_type); }; -} // namespace abi_util -#endif // IR_REPRESENTATION_JSON_H_ +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_JSON_IR_READER_H_ diff --git a/vndk/tools/header-checker/src/repr/protobuf/abi_diff.h b/vndk/tools/header-checker/src/repr/protobuf/abi_diff.h new file mode 100644 index 000000000..d697e7557 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/abi_diff.h @@ -0,0 +1,26 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_PROTOBUF_ABI_DIFF_H_ +#define HEADER_CHECKER_REPR_PROTOBUF_ABI_DIFF_H_ + + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wnested-anon-types" +#include "abi_diff.pb.h" +#pragma clang diagnostic pop + + +#endif // HEADER_CHECKER_REPR_PROTOBUF_ABI_DIFF_H_ diff --git a/vndk/tools/header-checker/src/repr/protobuf/abi_dump.h b/vndk/tools/header-checker/src/repr/protobuf/abi_dump.h new file mode 100644 index 000000000..52d0904c2 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/abi_dump.h @@ -0,0 +1,26 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_PROTOBUF_ABI_DUMP_H_ +#define HEADER_CHECKER_REPR_PROTOBUF_ABI_DUMP_H_ + + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wnested-anon-types" +#include "abi_dump.pb.h" +#pragma clang diagnostic pop + + +#endif // HEADER_CHECKER_REPR_PROTOBUF_ABI_DUMP_H_ diff --git a/vndk/tools/header-checker/src/repr/protobuf/api.h b/vndk/tools/header-checker/src/repr/protobuf/api.h new file mode 100644 index 000000000..22a03ee50 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/api.h @@ -0,0 +1,45 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_PROTOBUF_API_H_ +#define HEADER_CHECKER_REPR_PROTOBUF_API_H_ + +#include <memory> +#include <set> +#include <string> + + +namespace header_checker { +namespace repr { + + +class IRDiffDumper; +class IRDumper; +class IRReader; + + +std::unique_ptr<IRDumper> CreateProtobufIRDumper(const std::string &dump_path); + +std::unique_ptr<IRReader> CreateProtobufIRReader( + const std::set<std::string> *exported_headers); + +std::unique_ptr<IRDiffDumper> CreateProtobufIRDiffDumper( + const std::string &dump_path); + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_PROTOBUF_API_H_ diff --git a/vndk/tools/header-checker/src/repr/protobuf/converter.cpp b/vndk/tools/header-checker/src/repr/protobuf/converter.cpp new file mode 100644 index 000000000..0ec9ab729 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/converter.cpp @@ -0,0 +1,289 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/protobuf/converter.h" + +#include <llvm/Support/raw_ostream.h> + +#include <fstream> +#include <iostream> +#include <memory> +#include <string> + + +namespace header_checker { +namespace repr { + + +bool IRDiffToProtobufConverter::AddTypeInfoDiff( + abi_diff::TypeInfoDiff *type_info_diff_protobuf, + const TypeDiffIR *type_diff_ir) { + abi_diff::TypeInfo *old_type_info_protobuf = + type_info_diff_protobuf->mutable_old_type_info(); + abi_diff::TypeInfo *new_type_info_protobuf = + type_info_diff_protobuf->mutable_new_type_info(); + if (old_type_info_protobuf == nullptr || new_type_info_protobuf == nullptr) { + return false; + } + const std::pair<uint64_t, uint64_t> &sizes = type_diff_ir->GetSizes(); + const std::pair<uint32_t, uint32_t> &alignments = + type_diff_ir->GetAlignments(); + old_type_info_protobuf->set_size(sizes.first); + new_type_info_protobuf->set_size(sizes.second); + + old_type_info_protobuf->set_alignment(alignments.first); + new_type_info_protobuf->set_alignment(alignments.second); + return true; +} + +bool IRDiffToProtobufConverter::AddVTableLayoutDiff( + abi_diff::VTableLayoutDiff *vtable_layout_diff_protobuf, + const VTableLayoutDiffIR *vtable_layout_diff_ir) { + abi_dump:: VTableLayout *old_vtable = + vtable_layout_diff_protobuf->mutable_old_vtable(); + abi_dump:: VTableLayout *new_vtable = + vtable_layout_diff_protobuf->mutable_new_vtable(); + if (old_vtable == nullptr || new_vtable == nullptr || + !SetIRToProtobufVTableLayout(old_vtable, + vtable_layout_diff_ir->GetOldVTable()) || + !SetIRToProtobufVTableLayout(new_vtable, + vtable_layout_diff_ir->GetNewVTable())) { + return false; + } + return true; +} + +template <typename T> +static bool CopyBaseSpecifiersDiffIRToProtobuf( + google::protobuf::RepeatedPtrField<T> *dst, + const std::vector<CXXBaseSpecifierIR> &bases_ir) { + for (auto &&base_ir : bases_ir) { + T *added_base = dst->Add(); + if (!SetIRToProtobufBaseSpecifier(added_base, base_ir)) { + return false; + } + } + return true; +} + +bool IRDiffToProtobufConverter::AddBaseSpecifierDiffs( + abi_diff::CXXBaseSpecifierDiff *base_specifiers_diff_protobuf, + const CXXBaseSpecifierDiffIR *base_specifiers_diff_ir) { + if (!CopyBaseSpecifiersDiffIRToProtobuf( + base_specifiers_diff_protobuf->mutable_old_bases(), + base_specifiers_diff_ir->GetOldBases()) || + !CopyBaseSpecifiersDiffIRToProtobuf( + base_specifiers_diff_protobuf->mutable_new_bases(), + base_specifiers_diff_ir->GetNewBases())) { + return false; + } + return true; +} + +bool IRDiffToProtobufConverter::AddRecordFields( + abi_diff::RecordTypeDiff *record_diff_protobuf, + const std::vector<const RecordFieldIR *> &record_fields_ir, + bool field_removed) { + for (auto &&record_field_ir : record_fields_ir) { + abi_dump::RecordFieldDecl *field = nullptr; + if (field_removed) { + field = record_diff_protobuf->add_fields_removed(); + } else { + field = record_diff_protobuf->add_fields_added(); + } + if (field == nullptr) { + return false; + } + SetIRToProtobufRecordField(field, record_field_ir); + } + return true; +} + +bool IRDiffToProtobufConverter::AddRecordFieldDiffs( + abi_diff::RecordTypeDiff *record_diff_protobuf, + const std::vector<RecordFieldDiffIR> &record_field_diffs_ir) { + for (auto &&record_field_diff_ir : record_field_diffs_ir) { + abi_diff::RecordFieldDeclDiff *record_field_diff = + record_diff_protobuf->add_fields_diff(); + if (record_field_diff == nullptr) { + return false; + } + abi_dump::RecordFieldDecl *old_field = + record_field_diff->mutable_old_field(); + abi_dump::RecordFieldDecl *new_field = + record_field_diff->mutable_new_field(); + if (old_field == nullptr || new_field == nullptr) { + return false; + } + SetIRToProtobufRecordField(old_field, + record_field_diff_ir.GetOldField()); + SetIRToProtobufRecordField(new_field, + record_field_diff_ir.GetNewField()); + } + return true; +} + +abi_diff::RecordTypeDiff IRDiffToProtobufConverter::ConvertRecordTypeDiffIR( + const RecordTypeDiffIR *record_type_diff_ir) { + abi_diff::RecordTypeDiff record_type_diff_protobuf; + record_type_diff_protobuf.set_name(record_type_diff_ir->GetName()); + const TypeDiffIR *type_diff_ir = record_type_diff_ir->GetTypeDiff(); + // If a type_info diff exists + if (type_diff_ir != nullptr) { + abi_diff::TypeInfoDiff *type_info_diff = + record_type_diff_protobuf.mutable_type_info_diff(); + if (!AddTypeInfoDiff(type_info_diff, type_diff_ir)) { + llvm::errs() << "RecordType could not be converted\n"; + ::exit(1); + } + } + // If vtables differ. + const VTableLayoutDiffIR *vtable_layout_diff_ir = + record_type_diff_ir->GetVTableLayoutDiff(); + if (vtable_layout_diff_ir != nullptr) { + abi_diff::VTableLayoutDiff *vtable_layout_diff_protobuf = + record_type_diff_protobuf.mutable_vtable_layout_diff(); + if (!AddVTableLayoutDiff(vtable_layout_diff_protobuf, + vtable_layout_diff_ir)) { + llvm::errs() << "VTable layout diff could not be added\n"; + ::exit(1); + } + } + // If base specifiers differ. + const CXXBaseSpecifierDiffIR *base_specifier_diff_ir = + record_type_diff_ir->GetBaseSpecifiers(); + if (base_specifier_diff_ir != nullptr) { + abi_diff::CXXBaseSpecifierDiff *base_specifier_diff_protobuf = + record_type_diff_protobuf.mutable_bases_diff(); + if (!AddBaseSpecifierDiffs(base_specifier_diff_protobuf, + base_specifier_diff_ir)) { + llvm::errs() << "Base Specifier diff could not be added\n"; + ::exit(1); + } + } + // Field diffs + if (!AddRecordFields(&record_type_diff_protobuf, + record_type_diff_ir->GetFieldsRemoved(), true) || + !AddRecordFields(&record_type_diff_protobuf, + record_type_diff_ir->GetFieldsAdded(), false) || + !AddRecordFieldDiffs(&record_type_diff_protobuf, + record_type_diff_ir->GetFieldDiffs())) { + llvm::errs() << "Record Field diff could not be added\n"; + ::exit(1); + } + return record_type_diff_protobuf; +} + +bool IRDiffToProtobufConverter::AddEnumUnderlyingTypeDiff( + abi_diff::UnderlyingTypeDiff *underlying_type_diff_protobuf, + const std::pair<std::string, std::string> *underlying_type_diff_ir) { + if (underlying_type_diff_protobuf == nullptr) { + return false; + } + underlying_type_diff_protobuf->set_old_type(underlying_type_diff_ir->first); + underlying_type_diff_protobuf->set_new_type(underlying_type_diff_ir->second); + return true; +} + +static bool AddEnumFields( + google::protobuf::RepeatedPtrField<abi_dump::EnumFieldDecl> *dst, + const std::vector<const EnumFieldIR *> &enum_fields) { + for (auto &&enum_field : enum_fields) { + abi_dump::EnumFieldDecl *added_enum_field = dst->Add(); + if (!SetIRToProtobufEnumField(added_enum_field, enum_field)) { + return false; + } + } + return true; +} + +static bool AddEnumFieldDiffs( + google::protobuf::RepeatedPtrField<abi_diff::EnumFieldDeclDiff> *dst, + const std::vector<EnumFieldDiffIR> &fields_diff_ir) { + for (auto &&field_diff_ir : fields_diff_ir) { + abi_diff::EnumFieldDeclDiff *field_diff_protobuf = dst->Add(); + if (field_diff_protobuf == nullptr) { + return false; + } + if (!SetIRToProtobufEnumField(field_diff_protobuf->mutable_old_field(), + field_diff_ir.GetOldField()) || + !SetIRToProtobufEnumField(field_diff_protobuf->mutable_new_field(), + field_diff_ir.GetNewField())) { + return false; + } + } + return true; +} + +abi_diff::EnumTypeDiff IRDiffToProtobufConverter::ConvertEnumTypeDiffIR( + const EnumTypeDiffIR *enum_type_diff_ir) { + abi_diff::EnumTypeDiff enum_type_diff_protobuf; + enum_type_diff_protobuf.set_name(enum_type_diff_ir->GetName()); + const std::pair<std::string, std::string> *underlying_type_diff = + enum_type_diff_ir->GetUnderlyingTypeDiff(); + if ((underlying_type_diff != nullptr && + !AddEnumUnderlyingTypeDiff( + enum_type_diff_protobuf.mutable_underlying_type_diff(), + underlying_type_diff)) || + !AddEnumFields(enum_type_diff_protobuf.mutable_fields_removed(), + enum_type_diff_ir->GetFieldsRemoved()) || + !AddEnumFields(enum_type_diff_protobuf.mutable_fields_added(), + enum_type_diff_ir->GetFieldsAdded()) || + !AddEnumFieldDiffs(enum_type_diff_protobuf.mutable_fields_diff(), + enum_type_diff_ir->GetFieldsDiff())) { + llvm::errs() << "Enum field diff could not be added\n"; + ::exit(1); + } + return enum_type_diff_protobuf; +} + +abi_diff::GlobalVarDeclDiff IRDiffToProtobufConverter::ConvertGlobalVarDiffIR( + const GlobalVarDiffIR *global_var_diff_ir) { + abi_diff::GlobalVarDeclDiff global_var_diff; + global_var_diff.set_name(global_var_diff_ir->GetName()); + abi_dump::GlobalVarDecl *old_global_var = global_var_diff.mutable_old(); + abi_dump::GlobalVarDecl *new_global_var = global_var_diff.mutable_new_(); + if (old_global_var == nullptr || new_global_var == nullptr) { + llvm::errs() << "Globar Var diff could not be added\n"; + ::exit(1); + } + *old_global_var = + IRToProtobufConverter::ConvertGlobalVarIR( + global_var_diff_ir->GetOldGlobalVar()); + *new_global_var = + IRToProtobufConverter::ConvertGlobalVarIR( + global_var_diff_ir->GetNewGlobalVar()); + return global_var_diff; +} + +abi_diff::FunctionDeclDiff IRDiffToProtobufConverter::ConvertFunctionDiffIR( + const FunctionDiffIR *function_diff_ir) { + abi_diff::FunctionDeclDiff function_diff; + function_diff.set_name(function_diff_ir->GetName()); + abi_dump::FunctionDecl *old_function = function_diff.mutable_old(); + abi_dump::FunctionDecl *new_function = function_diff.mutable_new_(); + if (old_function == nullptr || new_function == nullptr) { + llvm::errs() << "Function diff could not be added\n"; + ::exit(1); + } + *old_function = IRToProtobufConverter::ConvertFunctionIR( + function_diff_ir->GetOldFunction()); + *new_function = IRToProtobufConverter::ConvertFunctionIR( + function_diff_ir->GetNewFunction()); + return function_diff; +} + + +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/ir_representation_protobuf.h b/vndk/tools/header-checker/src/repr/protobuf/converter.h index bacd1c965..8f4829a76 100644 --- a/vndk/tools/header-checker/header-abi-util/include/ir_representation_protobuf.h +++ b/vndk/tools/header-checker/src/repr/protobuf/converter.h @@ -1,4 +1,4 @@ -// Copyright (C) 2017 The Android Open Source Project +// Copyright (C) 2019 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,25 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef IR_REPRESENTATION_PROTOBUF_H_ -#define IR_REPRESENTATION_PROTOBUF_H_ +#ifndef HEADER_CHECKER_PROTOBUF_CONVERTER_H_ +#define HEADER_CHECKER_PROTOBUF_CONVERTER_H_ -#include "ir_representation.h" +#include "repr/ir_diff_representation.h" +#include "repr/ir_representation.h" +#include "repr/protobuf/abi_diff.h" +#include "repr/protobuf/abi_dump.h" -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-parameter" -#pragma clang diagnostic ignored "-Wnested-anon-types" -#include "abi_dump.pb.h" -#include "abi_diff.pb.h" -#pragma clang diagnostic pop +#include <llvm/Support/raw_ostream.h> -#include <google/protobuf/text_format.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> +namespace header_checker { +namespace repr { -// Classes which act as middle-men between clang AST parsing routines and -// message format specific dumpers. -namespace abi_util { inline abi_diff::CompatibilityStatus CompatibilityStatusIRToProtobuf( CompatibilityStatusIR status) { @@ -198,7 +193,7 @@ inline VTableComponentIR::Kind VTableComponentKindProtobufToIR( class IRToProtobufConverter { private: static bool AddTemplateInformation( - abi_dump::TemplateInfo *ti, const abi_util::TemplatedArtifactIR *ta); + abi_dump::TemplateInfo *ti, const TemplatedArtifactIR *ta); static bool AddTypeInfo( abi_dump::BasicNamedAndTypedDecl *type_info, const TypeIR *typep); @@ -306,180 +301,71 @@ class IRDiffToProtobufConverter { const GlobalVarDiffIR *global_var_diffp); }; -class ProtobufIRDumper : public IRDumper, public IRToProtobufConverter { - private: - // Types - bool AddRecordTypeIR(const RecordTypeIR *); - - bool AddEnumTypeIR(const EnumTypeIR *); - - bool AddPointerTypeIR(const PointerTypeIR *); - - bool AddQualifiedTypeIR(const QualifiedTypeIR *); - - bool AddLvalueReferenceTypeIR(const LvalueReferenceTypeIR *); - - bool AddRvalueReferenceTypeIR(const RvalueReferenceTypeIR *); - - bool AddArrayTypeIR(const ArrayTypeIR *); - - bool AddBuiltinTypeIR(const BuiltinTypeIR *); - - bool AddFunctionTypeIR(const FunctionTypeIR *function_typep); - - // Functions and global variables. - bool AddFunctionIR(const FunctionIR *); - - bool AddGlobalVarIR(const GlobalVarIR *); - - bool AddElfFunctionIR(const ElfFunctionIR *); - - bool AddElfObjectIR(const ElfObjectIR *); - - public: - ProtobufIRDumper(const std::string &dump_path) - : IRDumper(dump_path), tu_ptr_(new abi_dump::TranslationUnit()) {} - - ~ProtobufIRDumper() override {} - - bool AddLinkableMessageIR(const LinkableMessageIR *) override; - - bool AddElfSymbolMessageIR(const ElfSymbolIR *) override; - - bool Dump() override; - - private: - std::unique_ptr<abi_dump::TranslationUnit> tu_ptr_; -}; - - -class ProtobufTextFormatToIRReader : public TextFormatToIRReader { - private: - template <typename T> - using RepeatedPtrField = google::protobuf::RepeatedPtrField<T>; - - public: - ProtobufTextFormatToIRReader(const std::set<std::string> *exported_headers) - : TextFormatToIRReader(exported_headers) {} - - bool ReadDump(const std::string &dump_file) override; - - private: - void ReadFunctions(const abi_dump::TranslationUnit &tu); - - void ReadGlobalVariables(const abi_dump::TranslationUnit &tu); - - void ReadEnumTypes(const abi_dump::TranslationUnit &tu); - - void ReadRecordTypes(const abi_dump::TranslationUnit &tu); - - void ReadFunctionTypes(const abi_dump::TranslationUnit &tu); - - void ReadPointerTypes(const abi_dump::TranslationUnit &tu); - - void ReadBuiltinTypes(const abi_dump::TranslationUnit &tu); - - void ReadQualifiedTypes(const abi_dump::TranslationUnit &tu); - - void ReadArrayTypes(const abi_dump::TranslationUnit &tu); - - void ReadLvalueReferenceTypes(const abi_dump::TranslationUnit &tu); - - void ReadRvalueReferenceTypes(const abi_dump::TranslationUnit &tu); - - void ReadElfFunctions(const abi_dump::TranslationUnit &tu); - - void ReadElfObjects(const abi_dump::TranslationUnit &tu); - - void ReadTypeInfo(const abi_dump::BasicNamedAndTypedDecl &type_info, - TypeIR *typep); - - FunctionIR FunctionProtobufToIR(const abi_dump::FunctionDecl &); - - FunctionTypeIR FunctionTypeProtobufToIR( - const abi_dump::FunctionType &function_type_protobuf); - - RecordTypeIR RecordTypeProtobufToIR( - const abi_dump::RecordType &record_type_protobuf); - - std::vector<RecordFieldIR> RecordFieldsProtobufToIR( - const RepeatedPtrField<abi_dump::RecordFieldDecl> &rfp); - - std::vector<CXXBaseSpecifierIR> RecordCXXBaseSpecifiersProtobufToIR( - const RepeatedPtrField<abi_dump::CXXBaseSpecifier> &rbs); - - std::vector<EnumFieldIR> EnumFieldsProtobufToIR( - const RepeatedPtrField<abi_dump::EnumFieldDecl> &efp); - - EnumTypeIR EnumTypeProtobufToIR( - const abi_dump::EnumType &enum_type_protobuf); - - VTableLayoutIR VTableLayoutProtobufToIR( - const abi_dump::VTableLayout &vtable_layout_protobuf); - - TemplateInfoIR TemplateInfoProtobufToIR( - const abi_dump::TemplateInfo &template_info_protobuf); -}; - -class ProtobufIRDiffDumper : public IRDiffDumper { - public: - ProtobufIRDiffDumper(const std::string &dump_path) - : IRDiffDumper(dump_path), - diff_tu_(new abi_diff::TranslationUnitDiff()) {} - - ~ProtobufIRDiffDumper() override {} - - bool AddDiffMessageIR(const DiffMessageIR *, const std::string &type_stack, - DiffKind diff_kind) override; - - bool AddLinkableMessageIR(const LinkableMessageIR *, - DiffKind diff_kind) override; - - bool AddElfSymbolMessageIR(const ElfSymbolIR *, DiffKind diff_kind) override; - - void AddLibNameIR(const std::string &name) override; - - void AddArchIR(const std::string &arch) override; - - void AddCompatibilityStatusIR(CompatibilityStatusIR status) override; - - bool Dump() override; - - CompatibilityStatusIR GetCompatibilityStatusIR() override; - - private: - // User defined types. - bool AddRecordTypeDiffIR(const RecordTypeDiffIR *, - const std::string &type_stack, DiffKind diff_kind); - - bool AddEnumTypeDiffIR(const EnumTypeDiffIR *, - const std::string &type_stack, DiffKind diff_kind); - - // Functions and global variables. - bool AddFunctionDiffIR(const FunctionDiffIR *, - const std::string &type_stack, DiffKind diff_kind); - - bool AddGlobalVarDiffIR(const GlobalVarDiffIR *, - const std::string &type_stack, DiffKind diff_kind); - - bool AddLoneRecordTypeDiffIR(const RecordTypeIR *, DiffKind diff_kind); - - bool AddLoneEnumTypeDiffIR(const EnumTypeIR *, DiffKind diff_kind); +inline void SetIRToProtobufRecordField( + abi_dump::RecordFieldDecl *record_field_protobuf, + const RecordFieldIR *record_field_ir) { + record_field_protobuf->set_field_name(record_field_ir->GetName()); + record_field_protobuf->set_referenced_type( + record_field_ir->GetReferencedType()); + record_field_protobuf->set_access( + AccessIRToProtobuf(record_field_ir->GetAccess())); + record_field_protobuf->set_field_offset(record_field_ir->GetOffset()); +} - // Functions and global variables. - bool AddLoneFunctionDiffIR(const FunctionIR *, DiffKind diff_kind); +inline bool SetIRToProtobufBaseSpecifier( + abi_dump::CXXBaseSpecifier *base_specifier_protobuf, + const CXXBaseSpecifierIR &base_specifier_ir) { + if (!base_specifier_protobuf) { + llvm::errs() << "Protobuf base specifier not valid\n"; + return false; + } + base_specifier_protobuf->set_referenced_type( + base_specifier_ir.GetReferencedType()); + base_specifier_protobuf->set_is_virtual( + base_specifier_ir.IsVirtual()); + base_specifier_protobuf->set_access( + AccessIRToProtobuf(base_specifier_ir.GetAccess())); + return true; +} - bool AddLoneGlobalVarDiffIR(const GlobalVarIR *, DiffKind diff_kind); +inline bool SetIRToProtobufVTableLayout( + abi_dump::VTableLayout *vtable_layout_protobuf, + const VTableLayoutIR &vtable_layout_ir) { + if (vtable_layout_protobuf == nullptr) { + llvm::errs() << "vtable layout protobuf not valid\n"; + return false; + } + for (auto &&vtable_component_ir : vtable_layout_ir.GetVTableComponents()) { + abi_dump::VTableComponent *added_vtable_component = + vtable_layout_protobuf->add_vtable_components(); + if (!added_vtable_component) { + llvm::errs() << "Couldn't add vtable component\n"; + return false; + } + added_vtable_component->set_kind( + VTableComponentKindIRToProtobuf(vtable_component_ir.GetKind())); + added_vtable_component->set_component_value(vtable_component_ir.GetValue()); + added_vtable_component->set_mangled_component_name( + vtable_component_ir.GetName()); + added_vtable_component->set_is_pure(vtable_component_ir.GetIsPure()); + } + return true; +} - bool AddElfObjectIR(const ElfObjectIR *elf_object_ir, DiffKind diff_kind); +inline bool SetIRToProtobufEnumField( + abi_dump::EnumFieldDecl *enum_field_protobuf, + const EnumFieldIR *enum_field_ir) { + if (enum_field_protobuf == nullptr) { + return true; + } + enum_field_protobuf->set_name(enum_field_ir->GetName()); + enum_field_protobuf->set_enum_field_value(enum_field_ir->GetValue()); + return true; +} - bool AddElfFunctionIR(const ElfFunctionIR *elf_function_ir, - DiffKind diff_kind); - protected: - std::unique_ptr<abi_diff::TranslationUnitDiff> diff_tu_; -}; +} // namespace repr +} // namespace header_checker -} // namespace abi_util -#endif // IR_REPRESENTATION_PROTOBUF_H_ +#endif // HEADER_CHECKER_PROTOBUF_CONVERTER_H_ diff --git a/vndk/tools/header-checker/src/repr/protobuf/ir_diff_dumper.cpp b/vndk/tools/header-checker/src/repr/protobuf/ir_diff_dumper.cpp new file mode 100644 index 000000000..12d7dedea --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/ir_diff_dumper.cpp @@ -0,0 +1,378 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/protobuf/ir_diff_dumper.h" + +#include "repr/ir_diff_representation.h" +#include "repr/protobuf/api.h" +#include "repr/protobuf/converter.h" + +#include <fstream> +#include <memory> +#include <string> + +#include <llvm/Support/raw_ostream.h> + +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + + +namespace header_checker { +namespace repr { + + +void ProtobufIRDiffDumper::AddLibNameIR(const std::string &name) { + diff_tu_->set_lib_name(name); +} + +void ProtobufIRDiffDumper::AddArchIR(const std::string &arch) { + diff_tu_->set_arch(arch); +} + +CompatibilityStatusIR ProtobufIRDiffDumper::GetCompatibilityStatusIR() { + if (diff_tu_->functions_removed().size() != 0 || + diff_tu_->global_vars_removed().size() != 0 || + diff_tu_->function_diffs().size() != 0 || + diff_tu_->global_var_diffs().size() != 0 || + diff_tu_->enum_type_diffs().size() != 0 || + diff_tu_->record_type_diffs().size() != 0) { + return CompatibilityStatusIR::Incompatible; + } + + CompatibilityStatusIR combined_status = CompatibilityStatusIR::Compatible; + + if (diff_tu_->enum_type_extension_diffs().size() != 0 || + diff_tu_->functions_added().size() != 0 || + diff_tu_->global_vars_added().size() != 0) { + combined_status = combined_status | CompatibilityStatusIR::Extension; + } + + if (diff_tu_->unreferenced_enum_type_diffs().size() != 0 || + diff_tu_->unreferenced_enum_types_removed().size() != 0 || + diff_tu_->unreferenced_record_types_removed().size() != 0 || + diff_tu_->unreferenced_record_type_diffs().size() != 0 || + diff_tu_->unreferenced_enum_type_extension_diffs().size() != 0 || + diff_tu_->unreferenced_record_types_added().size() != 0 || + diff_tu_->unreferenced_enum_types_added().size()) { + combined_status = + combined_status | CompatibilityStatusIR::UnreferencedChanges; + } + + if (diff_tu_->removed_elf_functions().size() != 0 || + diff_tu_->removed_elf_objects().size() != 0) { + combined_status = combined_status | CompatibilityStatusIR::ElfIncompatible; + } + + return combined_status; +} + +void ProtobufIRDiffDumper::AddCompatibilityStatusIR( + CompatibilityStatusIR status) { + diff_tu_->set_compatibility_status(CompatibilityStatusIRToProtobuf(status)); +} + +bool ProtobufIRDiffDumper::AddDiffMessageIR(const DiffMessageIR *message, + const std::string &type_stack, + DiffKind diff_kind) { + switch (message->Kind()) { + case RecordTypeKind: + return AddRecordTypeDiffIR( + static_cast<const RecordTypeDiffIR *>(message), type_stack, + diff_kind); + case EnumTypeKind: + return AddEnumTypeDiffIR( + static_cast<const EnumTypeDiffIR *>(message), type_stack, diff_kind); + case GlobalVarKind: + return AddGlobalVarDiffIR( + static_cast<const GlobalVarDiffIR*>(message), type_stack, diff_kind); + case FunctionKind: + return AddFunctionDiffIR( + static_cast<const FunctionDiffIR*>(message), type_stack, diff_kind); + default: + break; + } + llvm::errs() << "Dump Diff attempted on something not a user defined type / " + << "function / global variable\n"; + return false; +} + +bool ProtobufIRDiffDumper::AddLinkableMessageIR( + const LinkableMessageIR *message, DiffKind diff_kind) { + switch (message->GetKind()) { + case RecordTypeKind: + return AddLoneRecordTypeDiffIR( + static_cast<const RecordTypeIR *>(message), diff_kind); + case EnumTypeKind: + return AddLoneEnumTypeDiffIR( + static_cast<const EnumTypeIR *>(message), diff_kind); + case GlobalVarKind: + return AddLoneGlobalVarDiffIR( + static_cast<const GlobalVarIR*>(message), diff_kind); + case FunctionKind: + return AddLoneFunctionDiffIR( + static_cast<const FunctionIR*>(message), diff_kind); + default: + break; + } + llvm::errs() << "Dump Diff attempted on something not a user defined type / " + << "function / global variable\n"; + return false; +} + +bool ProtobufIRDiffDumper::AddElfSymbolMessageIR(const ElfSymbolIR *elf_symbol, + DiffKind diff_kind) { + switch (elf_symbol->GetKind()) { + case ElfSymbolIR::ElfFunctionKind: + return AddElfFunctionIR(static_cast<const ElfFunctionIR *>(elf_symbol), + diff_kind); + break; + case ElfSymbolIR::ElfObjectKind: + return AddElfObjectIR(static_cast<const ElfObjectIR *>(elf_symbol), + diff_kind); + break; + } + // Any other kind is invalid + return false; +} + +bool ProtobufIRDiffDumper::AddElfFunctionIR( + const ElfFunctionIR *elf_function_ir, DiffKind diff_kind) { + abi_dump::ElfFunction *added_elf_function = nullptr; + switch (diff_kind) { + case DiffKind::Removed: + added_elf_function = diff_tu_->add_removed_elf_functions(); + break; + case DiffKind::Added: + added_elf_function = diff_tu_->add_added_elf_functions(); + break; + default: + llvm::errs() << "Invalid call to AddElfFunctionIR\n"; + return false; + } + if (added_elf_function == nullptr) { + return false; + } + *added_elf_function = + IRToProtobufConverter::ConvertElfFunctionIR(elf_function_ir); + return true; +} + +bool ProtobufIRDiffDumper::AddElfObjectIR( + const ElfObjectIR *elf_object_ir, DiffKind diff_kind) { + abi_dump::ElfObject *added_elf_object = nullptr; + switch (diff_kind) { + case DiffKind::Removed: + added_elf_object = diff_tu_->add_removed_elf_objects(); + break; + case DiffKind::Added: + added_elf_object = diff_tu_->add_added_elf_objects(); + break; + default: + llvm::errs() << "Invalid call to AddElfObjectIR\n"; + return false; + } + if (added_elf_object == nullptr) { + return false; + } + *added_elf_object = + IRToProtobufConverter::ConvertElfObjectIR(elf_object_ir); + return true; +} + +bool ProtobufIRDiffDumper::AddLoneRecordTypeDiffIR( + const RecordTypeIR *record_type_ir, DiffKind diff_kind) { + abi_dump::RecordType *added_record_type = nullptr; + switch (diff_kind) { + case DiffKind::Removed: + // Referenced record types do not get reported as added / removed, + // the diff shows up in the parent type / function/ global variable + // referencing the record. + added_record_type = diff_tu_->add_unreferenced_record_types_removed(); + break; + case DiffKind::Added: + added_record_type = diff_tu_->add_unreferenced_record_types_added(); + break; + default: + llvm::errs() << "Invalid call to AddLoneRecordTypeDiffIR\n"; + return false; + } + if (added_record_type == nullptr) { + return false; + } + *added_record_type = + IRToProtobufConverter::ConvertRecordTypeIR(record_type_ir); + return true; +} + +bool ProtobufIRDiffDumper::AddLoneFunctionDiffIR( + const FunctionIR *function_ir, DiffKind diff_kind) { + abi_dump::FunctionDecl *added_function = nullptr; + switch (diff_kind) { + case DiffKind::Removed: + added_function = diff_tu_->add_functions_removed(); + break; + case DiffKind::Added: + added_function = diff_tu_->add_functions_added(); + break; + default: + llvm::errs() << "Invalid call to AddLoneFunctionDiffIR\n"; + return false; + } + *added_function = IRToProtobufConverter::ConvertFunctionIR(function_ir); + return true; +} + +bool ProtobufIRDiffDumper::AddLoneEnumTypeDiffIR( + const EnumTypeIR *enum_type_ir, DiffKind diff_kind) { + abi_dump::EnumType *added_enum_type = nullptr; + switch (diff_kind) { + case DiffKind::Removed: + // Referenced enum types do not get reported as added / removed, + // the diff shows up in the parent type / function/ global variable + // referencing the enum. + added_enum_type = diff_tu_->add_unreferenced_enum_types_removed(); + break; + case DiffKind::Added: + added_enum_type = diff_tu_->add_unreferenced_enum_types_added(); + break; + default: + llvm::errs() << "Invalid call to AddLoneRecordTypeDiffIR\n"; + return false; + } + if (added_enum_type == nullptr) { + return false; + } + *added_enum_type = IRToProtobufConverter::ConvertEnumTypeIR(enum_type_ir); + return true; +} + +bool ProtobufIRDiffDumper::AddLoneGlobalVarDiffIR( + const GlobalVarIR *global_var_ir, DiffKind diff_kind) { + abi_dump::GlobalVarDecl *added_global_var = nullptr; + switch (diff_kind) { + case DiffKind::Removed: + added_global_var = diff_tu_->add_global_vars_removed(); + break; + case DiffKind::Added: + added_global_var = diff_tu_->add_global_vars_added(); + break; + default: + llvm::errs() << "Invalid call to AddLoneFunctionDiffIR\n"; + return false; + } + *added_global_var = IRToProtobufConverter::ConvertGlobalVarIR(global_var_ir); + return true; +} + +bool ProtobufIRDiffDumper::AddRecordTypeDiffIR( + const RecordTypeDiffIR *record_diff_ir, const std::string &type_stack, + DiffKind diff_kind) { + abi_diff::RecordTypeDiff *added_record_type_diff = nullptr; + switch (diff_kind) { + case DiffKind::Unreferenced: + added_record_type_diff = diff_tu_->add_unreferenced_record_type_diffs(); + break; + case DiffKind::Referenced: + added_record_type_diff = diff_tu_->add_record_type_diffs(); + break; + default: + break; + } + if (!added_record_type_diff) { + return false; + } + + *added_record_type_diff = + IRDiffToProtobufConverter::ConvertRecordTypeDiffIR(record_diff_ir); + added_record_type_diff->set_type_stack(type_stack); + return true; +} + +bool ProtobufIRDiffDumper::AddFunctionDiffIR( + const FunctionDiffIR *function_diff_ir, const std::string &type_stack, + DiffKind diff_kind) { + abi_diff::FunctionDeclDiff *added_function_diff = + diff_tu_->add_function_diffs(); + if (!added_function_diff) { + return false; + } + *added_function_diff = + IRDiffToProtobufConverter::ConvertFunctionDiffIR(function_diff_ir); + return true; +} + +bool ProtobufIRDiffDumper::AddEnumTypeDiffIR(const EnumTypeDiffIR *enum_diff_ir, + const std::string &type_stack, + DiffKind diff_kind) { + abi_diff::EnumTypeDiff *added_enum_type_diff = nullptr; + switch (diff_kind) { + case DiffKind::Unreferenced: + if (enum_diff_ir->IsExtended()) { + added_enum_type_diff = + diff_tu_->add_unreferenced_enum_type_extension_diffs(); + } else { + added_enum_type_diff = + diff_tu_->add_unreferenced_enum_type_diffs(); + } + break; + case DiffKind::Referenced: + if (enum_diff_ir->IsExtended()) { + added_enum_type_diff = + diff_tu_->add_enum_type_extension_diffs(); + } else { + added_enum_type_diff = + diff_tu_->add_enum_type_diffs(); + } + break; + default: + break; + } + if (!added_enum_type_diff) { + return false; + } + *added_enum_type_diff = + IRDiffToProtobufConverter::ConvertEnumTypeDiffIR(enum_diff_ir); + added_enum_type_diff->set_type_stack(type_stack); + return true; +} + +bool ProtobufIRDiffDumper::AddGlobalVarDiffIR( + const GlobalVarDiffIR *global_var_diff_ir, const std::string &type_stack, + DiffKind diff_kind) { + abi_diff::GlobalVarDeclDiff *added_global_var_diff = + diff_tu_->add_global_var_diffs(); + if (!added_global_var_diff) { + return false; + } + *added_global_var_diff = + IRDiffToProtobufConverter::ConvertGlobalVarDiffIR(global_var_diff_ir); + return true; +} + +bool ProtobufIRDiffDumper::Dump() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + assert(diff_tu_.get() != nullptr); + std::ofstream text_output(dump_path_); + google::protobuf::io::OstreamOutputStream text_os(&text_output); + return google::protobuf::TextFormat::Print(*diff_tu_.get(), &text_os); +} + +std::unique_ptr<IRDiffDumper> CreateProtobufIRDiffDumper( + const std::string &dump_path) { + return std::make_unique<ProtobufIRDiffDumper>(dump_path); +} + + +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/src/repr/protobuf/ir_diff_dumper.h b/vndk/tools/header-checker/src/repr/protobuf/ir_diff_dumper.h new file mode 100644 index 000000000..c36bcab65 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/ir_diff_dumper.h @@ -0,0 +1,95 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_PROTOBUF_IR_DIFF_DUMPER_H_ +#define HEADER_CHECKER_REPR_PROTOBUF_IR_DIFF_DUMPER_H_ + +#include "repr/ir_diff_dumper.h" +#include "repr/ir_diff_representation.h" +#include "repr/ir_representation.h" +#include "repr/protobuf/abi_diff.h" + +#include <string> + + +namespace header_checker { +namespace repr { + + +class ProtobufIRDiffDumper : public IRDiffDumper { + public: + ProtobufIRDiffDumper(const std::string &dump_path) + : IRDiffDumper(dump_path), + diff_tu_(new abi_diff::TranslationUnitDiff()) {} + + ~ProtobufIRDiffDumper() override {} + + bool AddDiffMessageIR(const DiffMessageIR *, const std::string &type_stack, + DiffKind diff_kind) override; + + bool AddLinkableMessageIR(const LinkableMessageIR *, + DiffKind diff_kind) override; + + bool AddElfSymbolMessageIR(const ElfSymbolIR *, DiffKind diff_kind) override; + + void AddLibNameIR(const std::string &name) override; + + void AddArchIR(const std::string &arch) override; + + void AddCompatibilityStatusIR(CompatibilityStatusIR status) override; + + bool Dump() override; + + CompatibilityStatusIR GetCompatibilityStatusIR() override; + + + private: + bool AddRecordTypeDiffIR(const RecordTypeDiffIR *, + const std::string &type_stack, DiffKind diff_kind); + + bool AddEnumTypeDiffIR(const EnumTypeDiffIR *, + const std::string &type_stack, DiffKind diff_kind); + + bool AddFunctionDiffIR(const FunctionDiffIR *, + const std::string &type_stack, DiffKind diff_kind); + + bool AddGlobalVarDiffIR(const GlobalVarDiffIR *, + const std::string &type_stack, DiffKind diff_kind); + + + bool AddLoneRecordTypeDiffIR(const RecordTypeIR *, DiffKind diff_kind); + + bool AddLoneEnumTypeDiffIR(const EnumTypeIR *, DiffKind diff_kind); + + bool AddLoneFunctionDiffIR(const FunctionIR *, DiffKind diff_kind); + + bool AddLoneGlobalVarDiffIR(const GlobalVarIR *, DiffKind diff_kind); + + + bool AddElfObjectIR(const ElfObjectIR *elf_object_ir, DiffKind diff_kind); + + bool AddElfFunctionIR(const ElfFunctionIR *elf_function_ir, + DiffKind diff_kind); + + + protected: + std::unique_ptr<abi_diff::TranslationUnitDiff> diff_tu_; +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_PROTOBUF_PROTOBUF_IR_DIFF_DUMPER_H_ diff --git a/vndk/tools/header-checker/src/repr/protobuf/ir_dumper.cpp b/vndk/tools/header-checker/src/repr/protobuf/ir_dumper.cpp new file mode 100644 index 000000000..6bf20b79d --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/ir_dumper.cpp @@ -0,0 +1,501 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/protobuf/ir_dumper.h" + +#include "repr/protobuf/abi_dump.h" +#include "repr/protobuf/api.h" + +#include <fstream> +#include <memory> + +#include <llvm/Support/raw_ostream.h> + +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + + +namespace header_checker { +namespace repr { + + +bool IRToProtobufConverter::AddTemplateInformation( + abi_dump::TemplateInfo *ti, const TemplatedArtifactIR *ta) { + for (auto &&template_element : ta->GetTemplateElements()) { + abi_dump::TemplateElement *added_element = ti->add_elements(); + if (!added_element) { + llvm::errs() << "Failed to add template element\n"; + return false; + } + added_element->set_referenced_type(template_element.GetReferencedType()); + } + return true; +} + +bool IRToProtobufConverter::AddTypeInfo( + abi_dump::BasicNamedAndTypedDecl *type_info, const TypeIR *typep) { + if (!type_info || !typep) { + llvm::errs() << "Typeinfo not valid\n"; + return false; + } + type_info->set_linker_set_key(typep->GetLinkerSetKey()); + type_info->set_source_file(typep->GetSourceFile()); + type_info->set_name(typep->GetName()); + type_info->set_size(typep->GetSize()); + type_info->set_alignment(typep->GetAlignment()); + type_info->set_referenced_type(typep->GetReferencedType()); + type_info->set_self_type(typep->GetSelfType()); + return true; +} + +bool IRToProtobufConverter::AddRecordFields( + abi_dump::RecordType *record_protobuf, + const RecordTypeIR *record_ir) { + // Iterate through the fields and create corresponding ones for the protobuf + // record + for (auto &&field_ir : record_ir->GetFields()) { + abi_dump::RecordFieldDecl *added_field = record_protobuf->add_fields(); + if (!added_field) { + llvm::errs() << "Couldn't add record field\n"; + } + SetIRToProtobufRecordField(added_field, &field_ir); + } + return true; +} + +bool IRToProtobufConverter::AddBaseSpecifiers( + abi_dump::RecordType *record_protobuf, const RecordTypeIR *record_ir) { + for (auto &&base_ir : record_ir->GetBases()) { + abi_dump::CXXBaseSpecifier *added_base = + record_protobuf->add_base_specifiers(); + if (!SetIRToProtobufBaseSpecifier(added_base, base_ir)) { + return false; + } + } + return true; +} + +bool IRToProtobufConverter::AddVTableLayout( + abi_dump::RecordType *record_protobuf, + const RecordTypeIR *record_ir) { + // If there are no entries in the vtable, just return. + if (record_ir->GetVTableNumEntries() == 0) { + return true; + } + const VTableLayoutIR &vtable_layout_ir = record_ir->GetVTableLayout(); + abi_dump::VTableLayout *vtable_layout_protobuf = + record_protobuf->mutable_vtable_layout(); + if (!SetIRToProtobufVTableLayout(vtable_layout_protobuf, vtable_layout_ir)) { + return false; + } + return true; +} + +bool IRToProtobufConverter::AddTagTypeInfo( + abi_dump::TagType *tag_type_protobuf, + const TagTypeIR *tag_type_ir) { + if (!tag_type_protobuf || !tag_type_ir) { + return false; + } + tag_type_protobuf->set_unique_id(tag_type_ir->GetUniqueId()); + return true; +} + +abi_dump::RecordType IRToProtobufConverter::ConvertRecordTypeIR( + const RecordTypeIR *recordp) { + abi_dump::RecordType added_record_type; + added_record_type.set_access(AccessIRToProtobuf(recordp->GetAccess())); + added_record_type.set_record_kind( + RecordKindIRToProtobuf(recordp->GetRecordKind())); + if (recordp->IsAnonymous()) { + added_record_type.set_is_anonymous(true); + } + if (!AddTypeInfo(added_record_type.mutable_type_info(), recordp) || + !AddRecordFields(&added_record_type, recordp) || + !AddBaseSpecifiers(&added_record_type, recordp) || + !AddVTableLayout(&added_record_type, recordp) || + !AddTagTypeInfo(added_record_type.mutable_tag_info(), recordp) || + !(recordp->GetTemplateElements().size() ? + AddTemplateInformation(added_record_type.mutable_template_info(), + recordp) : true)) { + llvm::errs() << "Template information could not be added\n"; + ::exit(1); + } + return added_record_type; +} + + +abi_dump::ElfObject IRToProtobufConverter::ConvertElfObjectIR( + const ElfObjectIR *elf_object_ir) { + abi_dump::ElfObject elf_object_protobuf; + elf_object_protobuf.set_name(elf_object_ir->GetName()); + return elf_object_protobuf; +} + +abi_dump::ElfFunction IRToProtobufConverter::ConvertElfFunctionIR( + const ElfFunctionIR *elf_function_ir) { + abi_dump::ElfFunction elf_function_protobuf; + elf_function_protobuf.set_name(elf_function_ir->GetName()); + return elf_function_protobuf; +} + +template <typename CFunctionLikeMessage> +bool IRToProtobufConverter::AddFunctionParametersAndSetReturnType( + CFunctionLikeMessage *function_like_protobuf, + const CFunctionLikeIR *cfunction_like_ir) { + function_like_protobuf->set_return_type(cfunction_like_ir->GetReturnType()); + return AddFunctionParameters(function_like_protobuf, cfunction_like_ir); +} + +template <typename CFunctionLikeMessage> +bool IRToProtobufConverter::AddFunctionParameters( + CFunctionLikeMessage *function_like_protobuf, + const CFunctionLikeIR *cfunction_like_ir) { + for (auto &¶meter : cfunction_like_ir->GetParameters()) { + abi_dump::ParamDecl *added_parameter = + function_like_protobuf->add_parameters(); + if (!added_parameter) { + return false; + } + added_parameter->set_referenced_type( + parameter.GetReferencedType()); + added_parameter->set_default_arg(parameter.GetIsDefault()); + added_parameter->set_is_this_ptr(parameter.GetIsThisPtr()); + } + return true; +} + +abi_dump::FunctionType IRToProtobufConverter::ConvertFunctionTypeIR ( + const FunctionTypeIR *function_typep) { + abi_dump::FunctionType added_function_type; + if (!AddTypeInfo(added_function_type.mutable_type_info(), function_typep) || + !AddFunctionParametersAndSetReturnType(&added_function_type, + function_typep)) { + llvm::errs() << "Could not convert FunctionTypeIR to protobuf\n"; + ::exit(1); + } + return added_function_type; +} + +abi_dump::FunctionDecl IRToProtobufConverter::ConvertFunctionIR( + const FunctionIR *functionp) { + abi_dump::FunctionDecl added_function; + added_function.set_access(AccessIRToProtobuf(functionp->GetAccess())); + added_function.set_linker_set_key(functionp->GetLinkerSetKey()); + added_function.set_source_file(functionp->GetSourceFile()); + added_function.set_function_name(functionp->GetName()); + if (!AddFunctionParametersAndSetReturnType(&added_function, functionp) || + !(functionp->GetTemplateElements().size() ? + AddTemplateInformation(added_function.mutable_template_info(), functionp) + : true)) { + llvm::errs() << "Template information could not be added\n"; + ::exit(1); + } + return added_function; +} + +bool IRToProtobufConverter::AddEnumFields(abi_dump::EnumType *enum_protobuf, + const EnumTypeIR *enum_ir) { + for (auto &&field : enum_ir->GetFields()) { + abi_dump::EnumFieldDecl *enum_fieldp = enum_protobuf->add_enum_fields(); + if (!SetIRToProtobufEnumField(enum_fieldp, &field)) { + return false; + } + } + return true; +} + + +abi_dump::EnumType IRToProtobufConverter::ConvertEnumTypeIR( + const EnumTypeIR *enump) { + abi_dump::EnumType added_enum_type; + added_enum_type.set_access(AccessIRToProtobuf(enump->GetAccess())); + added_enum_type.set_underlying_type(enump->GetUnderlyingType()); + if (!AddTypeInfo(added_enum_type.mutable_type_info(), enump) || + !AddEnumFields(&added_enum_type, enump) || + !AddTagTypeInfo(added_enum_type.mutable_tag_info(), enump)) { + llvm::errs() << "EnumTypeIR could not be converted\n"; + ::exit(1); + } + return added_enum_type; +} + +abi_dump::GlobalVarDecl IRToProtobufConverter::ConvertGlobalVarIR( + const GlobalVarIR *global_varp) { + abi_dump::GlobalVarDecl added_global_var; + added_global_var.set_referenced_type(global_varp->GetReferencedType()); + added_global_var.set_source_file(global_varp->GetSourceFile()); + added_global_var.set_name(global_varp->GetName()); + added_global_var.set_linker_set_key(global_varp->GetLinkerSetKey()); + added_global_var.set_access( + AccessIRToProtobuf(global_varp->GetAccess())); + return added_global_var; +} + +abi_dump::PointerType IRToProtobufConverter::ConvertPointerTypeIR( + const PointerTypeIR *pointerp) { + abi_dump::PointerType added_pointer_type; + if (!AddTypeInfo(added_pointer_type.mutable_type_info(), pointerp)) { + llvm::errs() << "PointerTypeIR could not be converted\n"; + ::exit(1); + } + return added_pointer_type; +} + +abi_dump::QualifiedType IRToProtobufConverter::ConvertQualifiedTypeIR( + const QualifiedTypeIR *qualtypep) { + abi_dump::QualifiedType added_qualified_type; + if (!AddTypeInfo(added_qualified_type.mutable_type_info(), qualtypep)) { + llvm::errs() << "QualifiedTypeIR could not be converted\n"; + ::exit(1); + } + added_qualified_type.set_is_const(qualtypep->IsConst()); + added_qualified_type.set_is_volatile(qualtypep->IsVolatile()); + added_qualified_type.set_is_restricted(qualtypep->IsRestricted()); + return added_qualified_type; +} + +abi_dump::BuiltinType IRToProtobufConverter::ConvertBuiltinTypeIR( + const BuiltinTypeIR *builtin_typep) { + abi_dump::BuiltinType added_builtin_type; + added_builtin_type.set_is_unsigned(builtin_typep->IsUnsigned()); + added_builtin_type.set_is_integral(builtin_typep->IsIntegralType()); + if (!AddTypeInfo(added_builtin_type.mutable_type_info(), builtin_typep)) { + llvm::errs() << "BuiltinTypeIR could not be converted\n"; + ::exit(1); + } + return added_builtin_type; +} + +abi_dump::ArrayType IRToProtobufConverter::ConvertArrayTypeIR( + const ArrayTypeIR *array_typep) { + abi_dump::ArrayType added_array_type; + if (!AddTypeInfo(added_array_type.mutable_type_info(), array_typep)) { + llvm::errs() << "ArrayTypeIR could not be converted\n"; + ::exit(1); + } + return added_array_type; +} + +abi_dump::LvalueReferenceType +IRToProtobufConverter::ConvertLvalueReferenceTypeIR( + const LvalueReferenceTypeIR *lvalue_reference_typep) { + abi_dump::LvalueReferenceType added_lvalue_reference_type; + if (!AddTypeInfo(added_lvalue_reference_type.mutable_type_info(), + lvalue_reference_typep)) { + llvm::errs() << "LvalueReferenceTypeIR could not be converted\n"; + ::exit(1); + } + return added_lvalue_reference_type; +} + +abi_dump::RvalueReferenceType +IRToProtobufConverter::ConvertRvalueReferenceTypeIR( + const RvalueReferenceTypeIR *rvalue_reference_typep) { + abi_dump::RvalueReferenceType added_rvalue_reference_type; + if (!AddTypeInfo(added_rvalue_reference_type.mutable_type_info(), + rvalue_reference_typep)) { + llvm::errs() << "RvalueReferenceTypeIR could not be converted\n"; + ::exit(1); + } + return added_rvalue_reference_type; +} + +bool ProtobufIRDumper::AddLinkableMessageIR (const LinkableMessageIR *lm) { + // No RTTI + switch (lm->GetKind()) { + case RecordTypeKind: + return AddRecordTypeIR(static_cast<const RecordTypeIR *>(lm)); + case EnumTypeKind: + return AddEnumTypeIR(static_cast<const EnumTypeIR *>(lm)); + case PointerTypeKind: + return AddPointerTypeIR(static_cast<const PointerTypeIR *>(lm)); + case QualifiedTypeKind: + return AddQualifiedTypeIR(static_cast<const QualifiedTypeIR *>(lm)); + case ArrayTypeKind: + return AddArrayTypeIR(static_cast<const ArrayTypeIR *>(lm)); + case LvalueReferenceTypeKind: + return AddLvalueReferenceTypeIR( + static_cast<const LvalueReferenceTypeIR *>(lm)); + case RvalueReferenceTypeKind: + return AddRvalueReferenceTypeIR( + static_cast<const RvalueReferenceTypeIR*>(lm)); + case BuiltinTypeKind: + return AddBuiltinTypeIR(static_cast<const BuiltinTypeIR*>(lm)); + case FunctionTypeKind: + return AddFunctionTypeIR(static_cast<const FunctionTypeIR*>(lm)); + case GlobalVarKind: + return AddGlobalVarIR(static_cast<const GlobalVarIR*>(lm)); + case FunctionKind: + return AddFunctionIR(static_cast<const FunctionIR*>(lm)); + } + return false; +} + +bool ProtobufIRDumper::AddElfFunctionIR(const ElfFunctionIR *elf_function) { + abi_dump::ElfFunction *added_elf_function = tu_ptr_->add_elf_functions(); + if (!added_elf_function) { + return false; + } + added_elf_function->set_name(elf_function->GetName()); + added_elf_function->set_binding( + ElfSymbolBindingIRToProtobuf(elf_function->GetBinding())); + return true; +} + +bool ProtobufIRDumper::AddElfObjectIR(const ElfObjectIR *elf_object) { + abi_dump::ElfObject *added_elf_object = tu_ptr_->add_elf_objects(); + if (!added_elf_object) { + return false; + } + added_elf_object->set_name(elf_object->GetName()); + added_elf_object->set_binding( + ElfSymbolBindingIRToProtobuf(elf_object->GetBinding())); + return true; +} + +bool ProtobufIRDumper::AddElfSymbolMessageIR(const ElfSymbolIR *em) { + switch (em->GetKind()) { + case ElfSymbolIR::ElfFunctionKind: + return AddElfFunctionIR(static_cast<const ElfFunctionIR *>(em)); + case ElfSymbolIR::ElfObjectKind: + return AddElfObjectIR(static_cast<const ElfObjectIR *>(em)); + } + return false; +} + +bool ProtobufIRDumper::AddRecordTypeIR(const RecordTypeIR *recordp) { + abi_dump::RecordType *added_record_type = tu_ptr_->add_record_types(); + if (!added_record_type) { + return false; + } + *added_record_type = ConvertRecordTypeIR(recordp); + return true; +} + +bool ProtobufIRDumper::AddFunctionTypeIR(const FunctionTypeIR *function_typep) { + abi_dump::FunctionType *added_function_type = tu_ptr_->add_function_types(); + if (!added_function_type) { + return false; + } + *added_function_type = ConvertFunctionTypeIR(function_typep); + return true; +} + +bool ProtobufIRDumper::AddFunctionIR(const FunctionIR *functionp) { + abi_dump::FunctionDecl *added_function = tu_ptr_->add_functions(); + if (!added_function) { + return false; + } + *added_function = ConvertFunctionIR(functionp); + return true; +} + +bool ProtobufIRDumper::AddEnumTypeIR(const EnumTypeIR *enump) { + abi_dump::EnumType *added_enum_type = tu_ptr_->add_enum_types(); + if (!added_enum_type) { + return false; + } + *added_enum_type = ConvertEnumTypeIR(enump); + return true; +} + +bool ProtobufIRDumper::AddGlobalVarIR(const GlobalVarIR *global_varp) { + abi_dump::GlobalVarDecl *added_global_var = tu_ptr_->add_global_vars(); + if (!added_global_var) { + return false; + } + *added_global_var = ConvertGlobalVarIR(global_varp); + return true; +} + +bool ProtobufIRDumper::AddPointerTypeIR(const PointerTypeIR *pointerp) { + abi_dump::PointerType *added_pointer_type = tu_ptr_->add_pointer_types(); + if (!added_pointer_type) { + return false; + } + *added_pointer_type = ConvertPointerTypeIR(pointerp); + return true; +} + +bool ProtobufIRDumper::AddQualifiedTypeIR(const QualifiedTypeIR *qualtypep) { + abi_dump::QualifiedType *added_qualified_type = + tu_ptr_->add_qualified_types(); + if (!added_qualified_type) { + return false; + } + *added_qualified_type = ConvertQualifiedTypeIR(qualtypep); + return true; +} + +bool ProtobufIRDumper::AddBuiltinTypeIR(const BuiltinTypeIR *builtin_typep) { + abi_dump::BuiltinType *added_builtin_type = + tu_ptr_->add_builtin_types(); + if (!added_builtin_type) { + return false; + } + *added_builtin_type = ConvertBuiltinTypeIR(builtin_typep); + return true; +} + +bool ProtobufIRDumper::AddArrayTypeIR(const ArrayTypeIR *array_typep) { + abi_dump::ArrayType *added_array_type = + tu_ptr_->add_array_types(); + if (!added_array_type) { + return false; + } + *added_array_type = ConvertArrayTypeIR(array_typep); + return true; +} + +bool ProtobufIRDumper::AddLvalueReferenceTypeIR( + const LvalueReferenceTypeIR *lvalue_reference_typep) { + abi_dump::LvalueReferenceType *added_lvalue_reference_type = + tu_ptr_->add_lvalue_reference_types(); + if (!added_lvalue_reference_type) { + return false; + } + *added_lvalue_reference_type = + ConvertLvalueReferenceTypeIR(lvalue_reference_typep); + return true; +} + +bool ProtobufIRDumper::AddRvalueReferenceTypeIR( + const RvalueReferenceTypeIR *rvalue_reference_typep) { + abi_dump::RvalueReferenceType *added_rvalue_reference_type = + tu_ptr_->add_rvalue_reference_types(); + if (!added_rvalue_reference_type) { + return false; + } + *added_rvalue_reference_type = + ConvertRvalueReferenceTypeIR(rvalue_reference_typep); + return true; +} + +bool ProtobufIRDumper::Dump(const ModuleIR &module) { + GOOGLE_PROTOBUF_VERIFY_VERSION; + DumpModule(module); + assert( tu_ptr_.get() != nullptr); + std::ofstream text_output(dump_path_); + google::protobuf::io::OstreamOutputStream text_os(&text_output); + return google::protobuf::TextFormat::Print(*tu_ptr_.get(), &text_os); +} + +std::unique_ptr<IRDumper> CreateProtobufIRDumper(const std::string &dump_path) { + return std::make_unique<ProtobufIRDumper>(dump_path); +} + + +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/src/repr/protobuf/ir_dumper.h b/vndk/tools/header-checker/src/repr/protobuf/ir_dumper.h new file mode 100644 index 000000000..e5ed27882 --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/ir_dumper.h @@ -0,0 +1,83 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_PROTOBUF_IR_DUMPER_H_ +#define HEADER_CHECKER_REPR_PROTOBUF_IR_DUMPER_H_ + +#include "repr/ir_dumper.h" +#include "repr/protobuf/abi_dump.h" +#include "repr/protobuf/converter.h" +#include "repr/protobuf/ir_dumper.h" + + +namespace header_checker { +namespace repr { + + +class ProtobufIRDumper : public IRDumper, public IRToProtobufConverter { + private: + // Types + bool AddRecordTypeIR(const RecordTypeIR *); + + bool AddEnumTypeIR(const EnumTypeIR *); + + bool AddPointerTypeIR(const PointerTypeIR *); + + bool AddQualifiedTypeIR(const QualifiedTypeIR *); + + bool AddLvalueReferenceTypeIR(const LvalueReferenceTypeIR *); + + bool AddRvalueReferenceTypeIR(const RvalueReferenceTypeIR *); + + bool AddArrayTypeIR(const ArrayTypeIR *); + + bool AddBuiltinTypeIR(const BuiltinTypeIR *); + + bool AddFunctionTypeIR(const FunctionTypeIR *function_typep); + + // Functions and global variables. + bool AddFunctionIR(const FunctionIR *); + + bool AddGlobalVarIR(const GlobalVarIR *); + + bool AddElfFunctionIR(const ElfFunctionIR *); + + bool AddElfObjectIR(const ElfObjectIR *); + + + public: + ProtobufIRDumper(const std::string &dump_path) + : IRDumper(dump_path), tu_ptr_(new abi_dump::TranslationUnit()) {} + + ~ProtobufIRDumper() override {} + + bool Dump(const ModuleIR &module) override; + + + private: + bool AddLinkableMessageIR(const LinkableMessageIR *) override; + + bool AddElfSymbolMessageIR(const ElfSymbolIR *) override; + + + private: + std::unique_ptr<abi_dump::TranslationUnit> tu_ptr_; +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_PROTOBUF_IR_DUMPER_H_ diff --git a/vndk/tools/header-checker/src/repr/protobuf/ir_reader.cpp b/vndk/tools/header-checker/src/repr/protobuf/ir_reader.cpp new file mode 100644 index 000000000..23b250d3e --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/ir_reader.cpp @@ -0,0 +1,327 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "repr/protobuf/ir_reader.h" + +#include "repr/ir_representation_internal.h" +#include "repr/protobuf/api.h" +#include "repr/protobuf/converter.h" + +#include <fstream> +#include <memory> + +#include <google/protobuf/text_format.h> + + +namespace header_checker { +namespace repr { + + +void ProtobufIRReader::ReadTypeInfo( + const abi_dump::BasicNamedAndTypedDecl &type_info, TypeIR *typep) { + typep->SetLinkerSetKey(type_info.linker_set_key()); + typep->SetName(type_info.name()); + typep->SetSourceFile(type_info.source_file()); + typep->SetReferencedType(type_info.referenced_type()); + typep->SetSelfType(type_info.self_type()); + typep->SetSize(type_info.size()); + typep->SetAlignment(type_info.alignment()); +} + +bool ProtobufIRReader::ReadDump(const std::string &dump_file) { + abi_dump::TranslationUnit tu; + std::ifstream input(dump_file); + google::protobuf::io::IstreamInputStream text_is(&input); + + if (!google::protobuf::TextFormat::Parse(&text_is, &tu)) { + llvm::errs() << "Failed to parse protobuf TextFormat file\n"; + return false; + } + ReadFunctions(tu); + ReadGlobalVariables(tu); + + ReadEnumTypes(tu); + ReadRecordTypes(tu); + ReadFunctionTypes(tu); + ReadArrayTypes(tu); + ReadPointerTypes(tu); + ReadQualifiedTypes(tu); + ReadBuiltinTypes(tu); + ReadLvalueReferenceTypes(tu); + ReadRvalueReferenceTypes(tu); + + ReadElfFunctions(tu); + ReadElfObjects(tu); + return true; +} + +TemplateInfoIR ProtobufIRReader::TemplateInfoProtobufToIR( + const abi_dump::TemplateInfo &template_info_protobuf) { + TemplateInfoIR template_info_ir; + for (auto &&template_element : template_info_protobuf.elements()) { + TemplateElementIR template_element_ir(template_element.referenced_type()); + template_info_ir.AddTemplateElement(std::move(template_element_ir)); + } + return template_info_ir; +} + +template <typename T> +static void SetupCFunctionLikeIR(const T &cfunction_like_protobuf, + CFunctionLikeIR *cfunction_like_ir) { + cfunction_like_ir->SetReturnType(cfunction_like_protobuf.return_type()); + for (auto &¶meter: cfunction_like_protobuf.parameters()) { + ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(), + false); + cfunction_like_ir->AddParameter(std::move(param_ir)); + } +} + +FunctionIR ProtobufIRReader::FunctionProtobufToIR( + const abi_dump::FunctionDecl &function_protobuf) { + FunctionIR function_ir; + function_ir.SetReturnType(function_protobuf.return_type()); + function_ir.SetLinkerSetKey(function_protobuf.linker_set_key()); + function_ir.SetName(function_protobuf.function_name()); + function_ir.SetAccess(AccessProtobufToIR(function_protobuf.access())); + function_ir.SetSourceFile(function_protobuf.source_file()); + // Set parameters + for (auto &¶meter: function_protobuf.parameters()) { + ParamIR param_ir(parameter.referenced_type(), parameter.default_arg(), + parameter.is_this_ptr()); + function_ir.AddParameter(std::move(param_ir)); + } + // Set Template info + function_ir.SetTemplateInfo( + TemplateInfoProtobufToIR(function_protobuf.template_info())); + return function_ir; +} + +FunctionTypeIR ProtobufIRReader::FunctionTypeProtobufToIR( + const abi_dump::FunctionType &function_type_protobuf) { + FunctionTypeIR function_type_ir; + ReadTypeInfo(function_type_protobuf.type_info(), &function_type_ir); + SetupCFunctionLikeIR(function_type_protobuf, &function_type_ir); + return function_type_ir; +} + +VTableLayoutIR ProtobufIRReader::VTableLayoutProtobufToIR( + const abi_dump::VTableLayout &vtable_layout_protobuf) { + VTableLayoutIR vtable_layout_ir; + for (auto &&vtable_component : vtable_layout_protobuf.vtable_components()) { + VTableComponentIR vtable_component_ir( + vtable_component.mangled_component_name(), + VTableComponentKindProtobufToIR(vtable_component.kind()), + vtable_component.component_value(), + vtable_component.is_pure()); + vtable_layout_ir.AddVTableComponent(std::move(vtable_component_ir)); + } + return vtable_layout_ir; +} + +std::vector<RecordFieldIR> ProtobufIRReader::RecordFieldsProtobufToIR( + const google::protobuf::RepeatedPtrField<abi_dump::RecordFieldDecl> &rfp) { + std::vector<RecordFieldIR> record_type_fields_ir; + for (auto &&field : rfp) { + RecordFieldIR record_field_ir(field.field_name(), field.referenced_type(), + field.field_offset(), + AccessProtobufToIR(field.access())); + record_type_fields_ir.emplace_back(std::move(record_field_ir)); + } + return record_type_fields_ir; +} + +std::vector<CXXBaseSpecifierIR> +ProtobufIRReader::RecordCXXBaseSpecifiersProtobufToIR( + const google::protobuf::RepeatedPtrField<abi_dump::CXXBaseSpecifier> &rbs) { + std::vector<CXXBaseSpecifierIR> record_type_bases_ir; + for (auto &&base : rbs) { + CXXBaseSpecifierIR record_base_ir( + base.referenced_type(), base.is_virtual(), + AccessProtobufToIR(base.access())); + record_type_bases_ir.emplace_back(std::move(record_base_ir)); + } + return record_type_bases_ir; +} + +RecordTypeIR ProtobufIRReader::RecordTypeProtobufToIR( + const abi_dump::RecordType &record_type_protobuf) { + RecordTypeIR record_type_ir; + ReadTypeInfo(record_type_protobuf.type_info(), &record_type_ir); + record_type_ir.SetTemplateInfo( + TemplateInfoProtobufToIR(record_type_protobuf.template_info())); + record_type_ir.SetAccess(AccessProtobufToIR(record_type_protobuf.access())); + record_type_ir.SetVTableLayout( + VTableLayoutProtobufToIR(record_type_protobuf.vtable_layout())); + // Get fields + record_type_ir.SetRecordFields(RecordFieldsProtobufToIR( + record_type_protobuf.fields())); + // Base Specifiers + record_type_ir.SetCXXBaseSpecifiers(RecordCXXBaseSpecifiersProtobufToIR( + record_type_protobuf.base_specifiers())); + record_type_ir.SetRecordKind( + RecordKindProtobufToIR(record_type_protobuf.record_kind())); + record_type_ir.SetAnonymity(record_type_protobuf.is_anonymous()); + record_type_ir.SetUniqueId(record_type_protobuf.tag_info().unique_id()); + return record_type_ir; +} + +std::vector<EnumFieldIR> ProtobufIRReader::EnumFieldsProtobufToIR( + const google::protobuf::RepeatedPtrField<abi_dump::EnumFieldDecl> &efp) { + std::vector<EnumFieldIR> enum_type_fields_ir; + for (auto &&field : efp) { + EnumFieldIR enum_field_ir(field.name(), field.enum_field_value()); + enum_type_fields_ir.emplace_back(std::move(enum_field_ir)); + } + return enum_type_fields_ir; +} + +EnumTypeIR ProtobufIRReader::EnumTypeProtobufToIR( + const abi_dump::EnumType &enum_type_protobuf) { + EnumTypeIR enum_type_ir; + ReadTypeInfo(enum_type_protobuf.type_info(), &enum_type_ir); + enum_type_ir.SetUnderlyingType(enum_type_protobuf.underlying_type()); + enum_type_ir.SetAccess(AccessProtobufToIR(enum_type_protobuf.access())); + enum_type_ir.SetFields( + EnumFieldsProtobufToIR(enum_type_protobuf.enum_fields())); + enum_type_ir.SetUniqueId(enum_type_protobuf.tag_info().unique_id()); + return enum_type_ir; +} + +void ProtobufIRReader::ReadGlobalVariables( + const abi_dump::TranslationUnit &tu) { + for (auto &&global_variable_protobuf : tu.global_vars()) { + GlobalVarIR global_variable_ir; + global_variable_ir.SetName(global_variable_protobuf.name()); + global_variable_ir.SetAccess(AccessProtobufToIR(global_variable_protobuf.access())); + global_variable_ir.SetSourceFile(global_variable_protobuf.source_file()); + global_variable_ir.SetReferencedType( + global_variable_protobuf.referenced_type()); + global_variable_ir.SetLinkerSetKey( + global_variable_protobuf.linker_set_key()); + module_->AddGlobalVariable(std::move(global_variable_ir)); + } +} + +void ProtobufIRReader::ReadPointerTypes(const abi_dump::TranslationUnit &tu) { + for (auto &&pointer_type_protobuf : tu.pointer_types()) { + PointerTypeIR pointer_type_ir; + ReadTypeInfo(pointer_type_protobuf.type_info(), &pointer_type_ir); + module_->AddPointerType(std::move(pointer_type_ir)); + } +} + +void ProtobufIRReader::ReadBuiltinTypes(const abi_dump::TranslationUnit &tu) { + for (auto &&builtin_type_protobuf : tu.builtin_types()) { + BuiltinTypeIR builtin_type_ir; + ReadTypeInfo(builtin_type_protobuf.type_info(), &builtin_type_ir); + builtin_type_ir.SetSignedness(builtin_type_protobuf.is_unsigned()); + builtin_type_ir.SetIntegralType(builtin_type_protobuf.is_integral()); + module_->AddBuiltinType(std::move(builtin_type_ir)); + } +} + +void ProtobufIRReader::ReadQualifiedTypes(const abi_dump::TranslationUnit &tu) { + for (auto &&qualified_type_protobuf : tu.qualified_types()) { + QualifiedTypeIR qualified_type_ir; + ReadTypeInfo(qualified_type_protobuf.type_info(), &qualified_type_ir); + qualified_type_ir.SetConstness(qualified_type_protobuf.is_const()); + qualified_type_ir.SetVolatility(qualified_type_protobuf.is_volatile()); + qualified_type_ir.SetRestrictedness( + qualified_type_protobuf.is_restricted()); + module_->AddQualifiedType(std::move(qualified_type_ir)); + } +} + +void ProtobufIRReader::ReadArrayTypes(const abi_dump::TranslationUnit &tu) { + for (auto &&array_type_protobuf : tu.array_types()) { + ArrayTypeIR array_type_ir; + ReadTypeInfo(array_type_protobuf.type_info(), &array_type_ir); + module_->AddArrayType(std::move(array_type_ir)); + } +} + +void ProtobufIRReader::ReadLvalueReferenceTypes( + const abi_dump::TranslationUnit &tu) { + for (auto &&lvalue_reference_type_protobuf : tu.lvalue_reference_types()) { + LvalueReferenceTypeIR lvalue_reference_type_ir; + ReadTypeInfo(lvalue_reference_type_protobuf.type_info(), + &lvalue_reference_type_ir); + module_->AddLvalueReferenceType(std::move(lvalue_reference_type_ir)); + } +} + +void ProtobufIRReader::ReadRvalueReferenceTypes( + const abi_dump::TranslationUnit &tu) { + for (auto &&rvalue_reference_type_protobuf : tu.rvalue_reference_types()) { + RvalueReferenceTypeIR rvalue_reference_type_ir; + ReadTypeInfo(rvalue_reference_type_protobuf.type_info(), + &rvalue_reference_type_ir); + module_->AddRvalueReferenceType(std::move(rvalue_reference_type_ir)); + } +} + +void ProtobufIRReader::ReadFunctions(const abi_dump::TranslationUnit &tu) { + for (auto &&function_protobuf : tu.functions()) { + FunctionIR function_ir = FunctionProtobufToIR(function_protobuf); + module_->AddFunction(std::move(function_ir)); + } +} + +void ProtobufIRReader::ReadRecordTypes(const abi_dump::TranslationUnit &tu) { + for (auto &&record_type_protobuf : tu.record_types()) { + RecordTypeIR record_type_ir = RecordTypeProtobufToIR(record_type_protobuf); + module_->AddRecordType(std::move(record_type_ir)); + } +} + +void ProtobufIRReader::ReadFunctionTypes(const abi_dump::TranslationUnit &tu) { + for (auto &&function_type_protobuf : tu.function_types()) { + FunctionTypeIR function_type_ir = + FunctionTypeProtobufToIR(function_type_protobuf); + module_->AddFunctionType(std::move(function_type_ir)); + } +} + +void ProtobufIRReader::ReadEnumTypes(const abi_dump::TranslationUnit &tu) { + for (auto &&enum_type_protobuf : tu.enum_types()) { + EnumTypeIR enum_type_ir = EnumTypeProtobufToIR(enum_type_protobuf); + module_->AddEnumType(std::move(enum_type_ir)); + } +} + +void ProtobufIRReader::ReadElfFunctions(const abi_dump::TranslationUnit &tu) { + for (auto &&elf_function : tu.elf_functions()) { + ElfFunctionIR elf_function_ir( + elf_function.name(), + ElfSymbolBindingProtobufToIR(elf_function.binding())); + module_->AddElfFunction(std::move(elf_function_ir)); + } +} + +void ProtobufIRReader::ReadElfObjects(const abi_dump::TranslationUnit &tu) { + for (auto &&elf_object : tu.elf_objects()) { + ElfObjectIR elf_object_ir( + elf_object.name(), ElfSymbolBindingProtobufToIR(elf_object.binding())); + module_->AddElfObject(std::move(elf_object_ir)); + } +} + +std::unique_ptr<IRReader> CreateProtobufIRReader( + const std::set<std::string> *exported_headers) { + return std::make_unique<ProtobufIRReader>(exported_headers); +} + + +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/src/repr/protobuf/ir_reader.h b/vndk/tools/header-checker/src/repr/protobuf/ir_reader.h new file mode 100644 index 000000000..c943e685a --- /dev/null +++ b/vndk/tools/header-checker/src/repr/protobuf/ir_reader.h @@ -0,0 +1,110 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef HEADER_CHECKER_REPR_PROTOBUF_IR_READER_H_ +#define HEADER_CHECKER_REPR_PROTOBUF_IR_READER_H_ + +#include "repr/ir_reader.h" +#include "repr/protobuf/abi_diff.h" +#include "repr/protobuf/abi_dump.h" + +#include <set> +#include <string> +#include <vector> + +#include <google/protobuf/text_format.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> + + +namespace header_checker { +namespace repr { + + +class ProtobufIRReader : public IRReader { + private: + template <typename T> + using RepeatedPtrField = google::protobuf::RepeatedPtrField<T>; + + + public: + ProtobufIRReader(const std::set<std::string> *exported_headers) + : IRReader(exported_headers) {} + + + bool ReadDump(const std::string &dump_file) override; + + + private: + void ReadFunctions(const abi_dump::TranslationUnit &tu); + + void ReadGlobalVariables(const abi_dump::TranslationUnit &tu); + + void ReadEnumTypes(const abi_dump::TranslationUnit &tu); + + void ReadRecordTypes(const abi_dump::TranslationUnit &tu); + + void ReadFunctionTypes(const abi_dump::TranslationUnit &tu); + + void ReadPointerTypes(const abi_dump::TranslationUnit &tu); + + void ReadBuiltinTypes(const abi_dump::TranslationUnit &tu); + + void ReadQualifiedTypes(const abi_dump::TranslationUnit &tu); + + void ReadArrayTypes(const abi_dump::TranslationUnit &tu); + + void ReadLvalueReferenceTypes(const abi_dump::TranslationUnit &tu); + + void ReadRvalueReferenceTypes(const abi_dump::TranslationUnit &tu); + + void ReadElfFunctions(const abi_dump::TranslationUnit &tu); + + void ReadElfObjects(const abi_dump::TranslationUnit &tu); + + void ReadTypeInfo(const abi_dump::BasicNamedAndTypedDecl &type_info, + TypeIR *typep); + + FunctionIR FunctionProtobufToIR(const abi_dump::FunctionDecl &); + + FunctionTypeIR FunctionTypeProtobufToIR( + const abi_dump::FunctionType &function_type_protobuf); + + RecordTypeIR RecordTypeProtobufToIR( + const abi_dump::RecordType &record_type_protobuf); + + std::vector<RecordFieldIR> RecordFieldsProtobufToIR( + const RepeatedPtrField<abi_dump::RecordFieldDecl> &rfp); + + std::vector<CXXBaseSpecifierIR> RecordCXXBaseSpecifiersProtobufToIR( + const RepeatedPtrField<abi_dump::CXXBaseSpecifier> &rbs); + + std::vector<EnumFieldIR> EnumFieldsProtobufToIR( + const RepeatedPtrField<abi_dump::EnumFieldDecl> &efp); + + EnumTypeIR EnumTypeProtobufToIR( + const abi_dump::EnumType &enum_type_protobuf); + + VTableLayoutIR VTableLayoutProtobufToIR( + const abi_dump::VTableLayout &vtable_layout_protobuf); + + TemplateInfoIR TemplateInfoProtobufToIR( + const abi_dump::TemplateInfo &template_info_protobuf); +}; + + +} // namespace repr +} // namespace header_checker + + +#endif // HEADER_CHECKER_REPR_PROTOBUF_IR_READER_H_ diff --git a/vndk/tools/header-checker/proto/Android.bp b/vndk/tools/header-checker/src/repr/protobuf/proto/Android.bp index b63254a8a..b63254a8a 100644 --- a/vndk/tools/header-checker/proto/Android.bp +++ b/vndk/tools/header-checker/src/repr/protobuf/proto/Android.bp diff --git a/vndk/tools/header-checker/proto/abi_diff.proto b/vndk/tools/header-checker/src/repr/protobuf/proto/abi_diff.proto index 03f8ebe4b..03f8ebe4b 100644 --- a/vndk/tools/header-checker/proto/abi_diff.proto +++ b/vndk/tools/header-checker/src/repr/protobuf/proto/abi_diff.proto diff --git a/vndk/tools/header-checker/proto/abi_dump.proto b/vndk/tools/header-checker/src/repr/protobuf/proto/abi_dump.proto index 68ec0cc70..68ec0cc70 100644 --- a/vndk/tools/header-checker/proto/abi_dump.proto +++ b/vndk/tools/header-checker/src/repr/protobuf/proto/abi_dump.proto diff --git a/vndk/tools/header-checker/header-abi-util/src/exported_symbol_set.cpp b/vndk/tools/header-checker/src/repr/symbol/exported_symbol_set.cpp index 13958eb7b..873be2dff 100644 --- a/vndk/tools/header-checker/header-abi-util/src/exported_symbol_set.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/exported_symbol_set.cpp @@ -12,21 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "exported_symbol_set.h" +#include "repr/symbol/exported_symbol_set.h" -#include "ir_representation.h" -#include "stl_utils.h" -#include "string_utils.h" +#include "repr/ir_representation.h" +#include "utils/stl_utils.h" +#include "utils/string_utils.h" #include <fnmatch.h> #include <cxxabi.h> -namespace abi_util { +namespace header_checker { +namespace repr { static inline bool IsCppSymbol(const std::string &name) { - return StartsWith(name, "_Z"); + return utils::StartsWith(name, "_Z"); } @@ -74,7 +75,7 @@ bool ExportedSymbolSet::HasSymbol(const std::string &name) const { } if (IsCppSymbol(name) && HasDemangledCppSymbolsOrPatterns()) { - std::unique_ptr<char, FreeDeleter> demangled_name_c_str( + std::unique_ptr<char, utils::FreeDeleter> demangled_name_c_str( abi::__cxa_demangle(name.c_str(), nullptr, nullptr, nullptr)); if (demangled_name_c_str) { @@ -96,4 +97,5 @@ bool ExportedSymbolSet::HasSymbol(const std::string &name) const { } -} // namespace abi_util +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/exported_symbol_set.h b/vndk/tools/header-checker/src/repr/symbol/exported_symbol_set.h index 886cb5435..a5ca03def 100644 --- a/vndk/tools/header-checker/header-abi-util/include/exported_symbol_set.h +++ b/vndk/tools/header-checker/src/repr/symbol/exported_symbol_set.h @@ -15,7 +15,7 @@ #ifndef EXPORTED_SYMBOL_SET_ #define EXPORTED_SYMBOL_SET_ -#include "ir_representation.h" +#include "repr/ir_representation.h" #include <functional> #include <map> @@ -23,7 +23,8 @@ #include <string> -namespace abi_util { +namespace header_checker { +namespace repr { class ExportedSymbolSet { @@ -94,7 +95,8 @@ class ExportedSymbolSet { }; -} // namespace abi_util +} // namespace repr +} // namespace header_checker #endif // EXPORTED_SYMBOL_SET_ diff --git a/vndk/tools/header-checker/header-abi-util/src/exported_symbol_set_test.cpp b/vndk/tools/header-checker/src/repr/symbol/exported_symbol_set_test.cpp index f292996df..ad5cbd46f 100644 --- a/vndk/tools/header-checker/header-abi-util/src/exported_symbol_set_test.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/exported_symbol_set_test.cpp @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "exported_symbol_set.h" +#include "repr/symbol/exported_symbol_set.h" -#include "ir_representation.h" +#include "repr/ir_representation.h" #include <gtest/gtest.h> -namespace abi_util { +namespace header_checker { +namespace repr { TEST(ExportedSymbolSetTest, AddFunction) { @@ -129,4 +130,5 @@ TEST(ExportedSymbolSetTest, HasSymbol) { } -} // namespace abi_util +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/src/so_file_parser.cpp b/vndk/tools/header-checker/src/repr/symbol/so_file_parser.cpp index 001f9b912..451c139f1 100644 --- a/vndk/tools/header-checker/header-abi-util/src/so_file_parser.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/so_file_parser.cpp @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "so_file_parser.h" +#include "repr/symbol/so_file_parser.h" -#include "ir_representation.h" +#include "repr/ir_representation.h" #include <llvm/Object/Binary.h> #include <llvm/Object/ELFObjectFile.h> @@ -22,7 +22,8 @@ #include <llvm/Object/SymbolSize.h> -namespace abi_util { +namespace header_checker { +namespace repr { template <typename T> @@ -37,13 +38,13 @@ static inline T UnWrap(llvm::Expected<T> value_or_error) { } -static abi_util::ElfSymbolIR::ElfSymbolBinding +static ElfSymbolIR::ElfSymbolBinding LLVMToIRSymbolBinding(unsigned char binding) { switch (binding) { case llvm::ELF::STB_GLOBAL: - return abi_util::ElfSymbolIR::ElfSymbolBinding::Global; + return ElfSymbolIR::ElfSymbolBinding::Global; case llvm::ELF::STB_WEAK: - return abi_util::ElfSymbolIR::ElfSymbolBinding::Weak; + return ElfSymbolIR::ElfSymbolBinding::Weak; } assert(0); } @@ -94,7 +95,7 @@ ELFSoFileParser<T>::ELFSoFileParser(const llvm::object::ELFObjectFile<T> *obj) { continue; } - abi_util::ElfSymbolIR::ElfSymbolBinding symbol_binding = + ElfSymbolIR::ElfSymbolBinding symbol_binding = LLVMToIRSymbolBinding(elf_sym->getBinding()); std::string symbol_name = UnWrap(symbol_it.getName()); @@ -156,4 +157,5 @@ std::unique_ptr<SoFileParser> SoFileParser::Create( } -} // namespace abi_util +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/so_file_parser.h b/vndk/tools/header-checker/src/repr/symbol/so_file_parser.h index 3f5eeca49..89612c2c0 100644 --- a/vndk/tools/header-checker/header-abi-util/include/so_file_parser.h +++ b/vndk/tools/header-checker/src/repr/symbol/so_file_parser.h @@ -15,15 +15,15 @@ #ifndef SO_FILE_PARSER_H_ #define SO_FILE_PARSER_H_ -#include "exported_symbol_set.h" -#include "ir_representation.h" +#include "repr/ir_representation.h" +#include "repr/symbol/exported_symbol_set.h" #include <memory> -#include <map> #include <string> -namespace abi_util { +namespace header_checker { +namespace repr { class SoFileParser { @@ -36,7 +36,8 @@ class SoFileParser { }; -} // namespace abi_util +} // namespace repr +} // namespace header_checker #endif // SO_FILE_PARSER_H_ diff --git a/vndk/tools/header-checker/header-abi-util/src/version_script_parser.cpp b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp index d9a717c0a..98ecea3f3 100644 --- a/vndk/tools/header-checker/header-abi-util/src/version_script_parser.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "version_script_parser.h" +#include "repr/symbol/version_script_parser.h" -#include "exported_symbol_set.h" -#include "string_utils.h" +#include "repr/symbol/exported_symbol_set.h" +#include "utils/string_utils.h" #include <iostream> #include <memory> @@ -25,7 +25,8 @@ #include <vector> -namespace abi_util { +namespace header_checker { +namespace repr { static constexpr char DEFAULT_ARCH[] = "arm64"; @@ -38,7 +39,7 @@ inline std::string GetIntroducedArchTag(const std::string &arch) { VersionScriptParser::VersionScriptParser() : arch_(DEFAULT_ARCH), introduced_arch_tag_(GetIntroducedArchTag(arch_)), - api_level_(FUTURE_API_LEVEL), stream_(nullptr), line_no_(0) {} + api_level_(utils::FUTURE_API_LEVEL), stream_(nullptr), line_no_(0) {} void VersionScriptParser::SetArch(const std::string &arch) { @@ -61,7 +62,7 @@ VersionScriptParser::ParsedTags VersionScriptParser::ParseSymbolTags( } std::string_view comment_line = line_view.substr(comment_pos + 1); - std::vector<std::string_view> tags = Split(comment_line, " \t"); + std::vector<std::string_view> tags = utils::Split(comment_line, " \t"); bool has_introduced_arch_tags = false; @@ -92,8 +93,8 @@ VersionScriptParser::ParsedTags VersionScriptParser::ParseSymbolTags( } // Check introduced tags. - if (StartsWith(tag, "introduced=")) { - std::optional<ApiLevel> intro = ParseApiLevel( + if (utils::StartsWith(tag, "introduced=")) { + std::optional<utils::ApiLevel> intro = utils::ParseApiLevel( std::string(tag.substr(sizeof("introduced=") - 1))); if (!intro) { ReportError("Bad introduced tag: " + std::string(tag)); @@ -106,8 +107,8 @@ VersionScriptParser::ParsedTags VersionScriptParser::ParseSymbolTags( continue; } - if (StartsWith(tag, introduced_arch_tag_)) { - std::optional<ApiLevel> intro = ParseApiLevel( + if (utils::StartsWith(tag, introduced_arch_tag_)) { + std::optional<utils::ApiLevel> intro = utils::ParseApiLevel( std::string(tag.substr(introduced_arch_tag_.size()))); if (!intro) { ReportError("Bad introduced tag " + std::string(tag)); @@ -141,7 +142,7 @@ bool VersionScriptParser::IsSymbolExported( } if (tags.has_future_tag_) { - return api_level_ == FUTURE_API_LEVEL; + return api_level_ == utils::FUTURE_API_LEVEL; } if (tags.has_introduced_tags_) { @@ -161,7 +162,7 @@ bool VersionScriptParser::ParseSymbolLine(const std::string &line, return false; } - std::string symbol(Trim(line.substr(0, pos))); + std::string symbol(utils::Trim(line.substr(0, pos))); ParsedTags tags = ParseSymbolTags(line); if (!IsSymbolExported(tags)) { @@ -169,7 +170,7 @@ bool VersionScriptParser::ParseSymbolLine(const std::string &line, } if (is_in_extern_cpp) { - if (IsGlobPattern(symbol)) { + if (utils::IsGlobPattern(symbol)) { exported_symbols_->AddDemangledCppGlobPattern(symbol); } else { exported_symbols_->AddDemangledCppSymbol(symbol); @@ -177,7 +178,7 @@ bool VersionScriptParser::ParseSymbolLine(const std::string &line, return true; } - if (IsGlobPattern(symbol)) { + if (utils::IsGlobPattern(symbol)) { exported_symbols_->AddGlobPattern(symbol); return true; } @@ -219,11 +220,11 @@ bool VersionScriptParser::ParseVersionBlock(bool ignore_symbols) { } // Check symbol visibility label - if (StartsWith(line, "local:")) { + if (utils::StartsWith(line, "local:")) { scope = LineScope::LOCAL; continue; } - if (StartsWith(line, "global:")) { + if (utils::StartsWith(line, "global:")) { scope = LineScope::GLOBAL; continue; } @@ -264,7 +265,7 @@ std::unique_ptr<ExportedSymbolSet> VersionScriptParser::Parse( return nullptr; } - std::string version(Trim(line.substr(0, lparen_pos - 1))); + std::string version(utils::Trim(line.substr(0, lparen_pos - 1))); bool exclude_symbol_version = (excluded_symbol_versions_.find(version) != excluded_symbol_versions_.end()); @@ -280,7 +281,7 @@ std::unique_ptr<ExportedSymbolSet> VersionScriptParser::Parse( bool VersionScriptParser::ReadLine(std::string &line) { while (std::getline(*stream_, line)) { ++line_no_; - line = std::string(Trim(line)); + line = std::string(utils::Trim(line)); if (line.empty() || line[0] == '#') { continue; } @@ -293,4 +294,5 @@ bool VersionScriptParser::ReadLine(std::string &line) { VersionScriptParser::ErrorHandler::~ErrorHandler() {} -} // namespace abi_util +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/version_script_parser.h b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.h index 7becddf01..7a047a299 100644 --- a/vndk/tools/header-checker/header-abi-util/include/version_script_parser.h +++ b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.h @@ -15,17 +15,17 @@ #ifndef VERSION_SCRIPT_PARSER_H_ #define VERSION_SCRIPT_PARSER_H_ -#include "api_level.h" -#include "exported_symbol_set.h" -#include "ir_representation.h" +#include "repr/ir_representation.h" +#include "repr/symbol/exported_symbol_set.h" +#include "utils/api_level.h" #include <functional> -#include <map> #include <set> #include <string> -namespace abi_util { +namespace header_checker { +namespace repr { class VersionScriptParser { @@ -44,7 +44,7 @@ class VersionScriptParser { unsigned has_excluded_tags_ : 1; unsigned has_future_tag_ : 1; unsigned has_var_tag_ : 1; - ApiLevel introduced_; + utils::ApiLevel introduced_; public: @@ -69,7 +69,7 @@ class VersionScriptParser { void SetArch(const std::string &arch); - void SetApiLevel(ApiLevel api_level) { + void SetApiLevel(utils::ApiLevel api_level) { api_level_ = api_level; } @@ -113,7 +113,7 @@ class VersionScriptParser { std::string arch_; std::string introduced_arch_tag_; - ApiLevel api_level_; + utils::ApiLevel api_level_; std::set<std::string, std::less<>> excluded_symbol_versions_; std::set<std::string, std::less<>> excluded_symbol_tags_; @@ -125,7 +125,8 @@ class VersionScriptParser { }; -} // namespace abi_util +} // namespace repr +} // namespace header_checker #endif // VERSION_SCRIPT_PARSER_H_ diff --git a/vndk/tools/header-checker/header-abi-util/src/version_script_parser_test.cpp b/vndk/tools/header-checker/src/repr/symbol/version_script_parser_test.cpp index c84f19db2..7984f580e 100644 --- a/vndk/tools/header-checker/header-abi-util/src/version_script_parser_test.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/version_script_parser_test.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "version_script_parser.h" +#include "repr/symbol/version_script_parser.h" #include <gtest/gtest.h> @@ -21,7 +21,8 @@ #include <string> -namespace abi_util { +namespace header_checker { +namespace repr { TEST(VersionScriptParserTest, SmokeTest) { @@ -245,7 +246,7 @@ TEST(VersionScriptParserTest, ParseSymbolTagsIntroduced) { { VersionScriptParser parser; parser.SetArch("arm64"); - parser.SetApiLevel(FUTURE_API_LEVEL); + parser.SetApiLevel(utils::FUTURE_API_LEVEL); std::istringstream stream(testdata); std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream)); @@ -427,4 +428,5 @@ TEST(VersionScriptParserTest, ParseGlobPattern) { } -} // namespace abi_util +} // namespace repr +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/src/api_level.cpp b/vndk/tools/header-checker/src/utils/api_level.cpp index dc0b21683..a04b9b42b 100644 --- a/vndk/tools/header-checker/header-abi-util/src/api_level.cpp +++ b/vndk/tools/header-checker/src/utils/api_level.cpp @@ -12,15 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "api_level.h" +#include "utils/api_level.h" -#include "string_utils.h" +#include "utils/string_utils.h" #include <cassert> #include <string> -namespace abi_util { +namespace header_checker { +namespace utils { std::optional<ApiLevel> ParseApiLevel(const std::string &api_level_str) { @@ -31,4 +32,5 @@ std::optional<ApiLevel> ParseApiLevel(const std::string &api_level_str) { } -} // namespace abi_util +} // namespace utils +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/api_level.h b/vndk/tools/header-checker/src/utils/api_level.h index 11bcb66dc..45e86e47c 100644 --- a/vndk/tools/header-checker/header-abi-util/include/api_level.h +++ b/vndk/tools/header-checker/src/utils/api_level.h @@ -19,7 +19,8 @@ #include <string> -namespace abi_util { +namespace header_checker { +namespace utils { using ApiLevel = int; @@ -31,7 +32,8 @@ constexpr ApiLevel FUTURE_API_LEVEL = 10000; std::optional<ApiLevel> ParseApiLevel(const std::string &api); -} // namespace abi_util +} // namespace utils +} // namespace header_checker #endif // API_LEVEL_H_ diff --git a/vndk/tools/header-checker/header-abi-util/src/api_level_test.cpp b/vndk/tools/header-checker/src/utils/api_level_test.cpp index 3f6008cfe..74f06675b 100644 --- a/vndk/tools/header-checker/header-abi-util/src/api_level_test.cpp +++ b/vndk/tools/header-checker/src/utils/api_level_test.cpp @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "api_level.h" +#include "utils/api_level.h" #include <gtest/gtest.h> -namespace abi_util { +namespace header_checker { +namespace utils { TEST(ApiLevelTest, ParseApiLevel) { @@ -32,5 +33,5 @@ TEST(ApiLevelTest, ParseApiLevel) { } -} // namespace abi_util - +} // namespace utils +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/src/collect_exported_headers.cpp b/vndk/tools/header-checker/src/utils/collect_exported_headers.cpp index 0b6b07978..0729e60e1 100644 --- a/vndk/tools/header-checker/header-abi-util/src/collect_exported_headers.cpp +++ b/vndk/tools/header-checker/src/utils/collect_exported_headers.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "header_abi_util.h" +#include "utils/header_abi_util.h" #include <llvm/Support/FileSystem.h> #include <llvm/Support/Path.h> @@ -22,7 +22,10 @@ #include <string> #include <vector> -namespace abi_util { + +namespace header_checker { +namespace utils { + static bool ShouldSkipFile(llvm::StringRef &file_name) { // Ignore swap files, hidden files, and hidden directories. Do not recurse @@ -87,7 +90,7 @@ std::set<std::string> CollectAllExportedHeaders( const std::vector<std::string> &exported_header_dirs) { std::set<std::string> exported_headers; for (auto &&dir : exported_header_dirs) { - if (!abi_util::CollectExportedHeaderSet(dir, &exported_headers)) { + if (!CollectExportedHeaderSet(dir, &exported_headers)) { llvm::errs() << "Couldn't collect exported headers\n"; ::exit(1); } @@ -95,4 +98,5 @@ std::set<std::string> CollectAllExportedHeaders( return exported_headers; } -} // namespace abi_util +} // namespace utils +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/header_abi_util.h b/vndk/tools/header-checker/src/utils/header_abi_util.h index aa55dad76..354c64d40 100644 --- a/vndk/tools/header-checker/header-abi-util/include/header_abi_util.h +++ b/vndk/tools/header-checker/src/utils/header_abi_util.h @@ -15,15 +15,16 @@ #ifndef HEADER_ABI_UTIL_H_ #define HEADER_ABI_UTIL_H_ -#include "ir_representation.h" - #include <map> #include <regex> #include <set> #include <string> #include <vector> -namespace abi_util { + +namespace header_checker { +namespace utils { + std::string RealPath(const std::string &path); @@ -97,6 +98,9 @@ std::vector<std::pair<T, T>> FindCommonElements( return common_elements; } -} // namespace abi_util + +} // namespace utils +} // namespace header_checker + #endif // HEADER_ABI_UTIL_H_ diff --git a/vndk/tools/header-checker/header-abi-util/include/stl_utils.h b/vndk/tools/header-checker/src/utils/stl_utils.h index 3a520adb1..9ce8b142b 100644 --- a/vndk/tools/header-checker/header-abi-util/include/stl_utils.h +++ b/vndk/tools/header-checker/src/utils/stl_utils.h @@ -16,7 +16,8 @@ #define STL_UTILS_H_ -namespace abi_util { +namespace header_checker { +namespace utils { class FreeDeleter { @@ -27,7 +28,8 @@ class FreeDeleter { }; -} // namespace abi_util +} // namespace utils +} // namespace header_checker #endif // STL_UTILS_ diff --git a/vndk/tools/header-checker/header-abi-util/src/string_utils.cpp b/vndk/tools/header-checker/src/utils/string_utils.cpp index b6a03d04e..ced07f754 100644 --- a/vndk/tools/header-checker/header-abi-util/src/string_utils.cpp +++ b/vndk/tools/header-checker/src/utils/string_utils.cpp @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "string_utils.h" +#include "utils/string_utils.h" #include <cstdlib> #include <string> #include <utility> -namespace abi_util { +namespace header_checker { +namespace utils { std::string_view Trim(std::string_view s) { @@ -90,4 +91,5 @@ bool IsGlobPattern(std::string_view s) { } -} // namespace abi_util +} // namespace utils +} // namespace header_checker diff --git a/vndk/tools/header-checker/header-abi-util/include/string_utils.h b/vndk/tools/header-checker/src/utils/string_utils.h index d222a435f..8d546f400 100644 --- a/vndk/tools/header-checker/header-abi-util/include/string_utils.h +++ b/vndk/tools/header-checker/src/utils/string_utils.h @@ -20,7 +20,8 @@ #include <vector> -namespace abi_util { +namespace header_checker { +namespace utils { std::string_view Trim(std::string_view s); @@ -37,7 +38,8 @@ std::optional<int> ParseInt(const std::string &s); bool IsGlobPattern(std::string_view s); -} // namespace abi_util +} // namespace utils +} // namespace header_checker #endif // STRING_UTILS_H_ diff --git a/vndk/tools/header-checker/header-abi-util/src/string_utils_test.cpp b/vndk/tools/header-checker/src/utils/string_utils_test.cpp index 7cc2bff31..6c5a874a8 100644 --- a/vndk/tools/header-checker/header-abi-util/src/string_utils_test.cpp +++ b/vndk/tools/header-checker/src/utils/string_utils_test.cpp @@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "string_utils.h" +#include "utils/string_utils.h" #include <gtest/gtest.h> -namespace abi_util { +namespace header_checker { +namespace utils { TEST(StringUtilsTest, Trim) { @@ -104,4 +105,5 @@ TEST(StringUtilsTest, IsGlobPattern) { } -} // namespace abi_util +} // namespace utils +} // namespace header_checker diff --git a/vndk/tools/header-checker/tests/expected/example1.cpp b/vndk/tools/header-checker/tests/expected/example1.cpp index 810159cbe..d06d81440 100644 --- a/vndk/tools/header-checker/tests/expected/example1.cpp +++ b/vndk/tools/header-checker/tests/expected/example1.cpp @@ -1,51 +1,33 @@ record_types { type_info { - name: "HiddenBase" - size: 8 - alignment: 4 - referenced_type: "type-1" - source_file: "/development/vndk/tools/header-checker/tests/input/example3.h" - linker_set_key: "HiddenBase" - self_type: "type-1" + name: "CPPHello" + size: 56 + alignment: 8 + referenced_type: "type-23" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "CPPHello" + self_type: "type-23" } fields { - referenced_type: "type-2" - field_offset: 0 - field_name: "hide" - access: private_access + referenced_type: "type-24" + field_offset: 352 + field_name: "cpp_foo" + access: public_access } fields { - referenced_type: "type-3" - field_offset: 32 - field_name: "seek" - access: private_access - } - access: public_access - record_kind: class_kind - tag_info { - unique_id: "_ZTS10HiddenBase" + referenced_type: "type-25" + field_offset: 384 + field_name: "cpp_bar" + access: public_access } -} -record_types { - type_info { - name: "test2::HelloAgain" - size: 40 - alignment: 8 + base_specifiers { referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test2::HelloAgain" - self_type: "type-4" - } - fields { - referenced_type: "type-5" - field_offset: 64 - field_name: "foo_again" - access: public_access + is_virtual: false + access: private_access } - fields { - referenced_type: "type-2" - field_offset: 256 - field_name: "bar_again" + base_specifiers { + referenced_type: "type-15" + is_virtual: false access: public_access } vtable_layout { @@ -57,25 +39,25 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTIN5test210HelloAgainE" + mangled_component_name: "_ZTI8CPPHello" component_value: 0 is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN5test210HelloAgain5againEv" + mangled_component_name: "_ZN8CPPHello5againEv" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN5test210HelloAgainD1Ev" + mangled_component_name: "_ZN8CPPHelloD1Ev" component_value: 0 is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN5test210HelloAgainD0Ev" + mangled_component_name: "_ZN8CPPHelloD0Ev" component_value: 0 is_pure: false } @@ -83,259 +65,255 @@ record_types { access: public_access record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test210HelloAgainE" + unique_id: "_ZTS8CPPHello" } } record_types { type_info { - name: "test3::ByeAgain<double>" - size: 16 - alignment: 8 - referenced_type: "type-13" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::ByeAgain<double>" - self_type: "type-13" + name: "Hello" + size: 32 + alignment: 4 + referenced_type: "type-19" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "Hello" + self_type: "type-19" } fields { - referenced_type: "type-14" + referenced_type: "type-2" field_offset: 0 - field_name: "foo_again" + field_name: "foo" access: public_access } fields { referenced_type: "type-2" + field_offset: 32 + field_name: "bar" + access: public_access + } + fields { + referenced_type: "type-20" field_offset: 64 - field_name: "bar_again" + field_name: "d" access: public_access } - template_info { - elements { - referenced_type: "type-14" - } + fields { + referenced_type: "type-9" + field_offset: 96 + field_name: "enum_field" + access: public_access + } + fields { + referenced_type: "type-9" + field_offset: 128 + field_name: "enum_field2" + access: public_access + } + fields { + referenced_type: "type-21" + field_offset: 160 + field_name: "" + access: public_access } access: public_access record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test38ByeAgainIdEE" + unique_id: "Hello" } } record_types { type_info { - name: "test3::ByeAgain<float>" - size: 8 + name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" + size: 12 alignment: 4 - referenced_type: "type-15" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::ByeAgain<float>" - self_type: "type-15" + referenced_type: "type-21" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" + self_type: "type-21" } fields { - referenced_type: "type-3" + referenced_type: "type-2" field_offset: 0 - field_name: "foo_again" + field_name: "a" access: public_access } fields { - referenced_type: "type-3" + referenced_type: "type-2" field_offset: 32 - field_name: "bar_Again" + field_name: "b" access: public_access } - template_info { - elements { - referenced_type: "type-3" - } + fields { + referenced_type: "type-22" + field_offset: 64 + field_name: "" + access: public_access } access: public_access + is_anonymous: true record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test38ByeAgainIfEE" + unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)" } } record_types { type_info { - name: "test3::Outer" + name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" size: 4 alignment: 4 - referenced_type: "type-17" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::Outer" - self_type: "type-17" + referenced_type: "type-22" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" + self_type: "type-22" } fields { referenced_type: "type-2" field_offset: 0 - field_name: "a" + field_name: "c" access: public_access } access: public_access - record_kind: class_kind + is_anonymous: true + record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test35OuterE" + unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5)" } } record_types { type_info { - name: "test3::Outer::Inner" - size: 4 + name: "HiddenBase" + size: 8 alignment: 4 - referenced_type: "type-18" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::Outer::Inner" - self_type: "type-18" + referenced_type: "type-1" + source_file: "/development/vndk/tools/header-checker/tests/input/example3.h" + linker_set_key: "HiddenBase" + self_type: "type-1" } fields { referenced_type: "type-2" field_offset: 0 - field_name: "b" + field_name: "hide" access: private_access } - access: private_access + fields { + referenced_type: "type-3" + field_offset: 32 + field_name: "seek" + access: private_access + } + access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTSN5test35Outer5InnerE" + unique_id: "_ZTS10HiddenBase" } } record_types { type_info { - name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" - size: 4 - alignment: 4 - referenced_type: "type-22" + name: "List<float>" + size: 8 + alignment: 8 + referenced_type: "type-31" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" - self_type: "type-22" + linker_set_key: "List<float>" + self_type: "type-31" } fields { - referenced_type: "type-2" + referenced_type: "type-33" field_offset: 0 - field_name: "c" + field_name: "middle" access: public_access } + template_info { + elements { + referenced_type: "type-3" + } + } access: public_access - is_anonymous: true - record_kind: struct_kind + record_kind: class_kind tag_info { - unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5)" + unique_id: "_ZTS4ListIfE" } } record_types { type_info { - name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" - size: 12 - alignment: 4 - referenced_type: "type-21" + name: "List<float>::_Node" + size: 24 + alignment: 8 + referenced_type: "type-32" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" - self_type: "type-21" + linker_set_key: "List<float>::_Node" + self_type: "type-32" } fields { - referenced_type: "type-2" + referenced_type: "type-3" field_offset: 0 - field_name: "a" - access: public_access + field_name: "mVal" + access: private_access } fields { - referenced_type: "type-2" - field_offset: 32 - field_name: "b" - access: public_access + referenced_type: "type-33" + field_offset: 64 + field_name: "mpPrev" + access: private_access } fields { - referenced_type: "type-22" - field_offset: 64 - field_name: "" - access: public_access + referenced_type: "type-33" + field_offset: 128 + field_name: "mpNext" + access: private_access } access: public_access - is_anonymous: true - record_kind: struct_kind + record_kind: class_kind tag_info { - unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)" + unique_id: "_ZTSN4ListIfE5_NodeE" } } record_types { type_info { - name: "Hello" - size: 32 - alignment: 4 - referenced_type: "type-19" + name: "List<int>" + size: 8 + alignment: 8 + referenced_type: "type-35" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "Hello" - self_type: "type-19" + linker_set_key: "List<int>" + self_type: "type-35" } fields { - referenced_type: "type-2" + referenced_type: "type-37" field_offset: 0 - field_name: "foo" - access: public_access - } - fields { - referenced_type: "type-2" - field_offset: 32 - field_name: "bar" - access: public_access - } - fields { - referenced_type: "type-20" - field_offset: 64 - field_name: "d" - access: public_access - } - fields { - referenced_type: "type-9" - field_offset: 96 - field_name: "enum_field" - access: public_access - } - fields { - referenced_type: "type-9" - field_offset: 128 - field_name: "enum_field2" + field_name: "middle" access: public_access } - fields { - referenced_type: "type-21" - field_offset: 160 - field_name: "" - access: public_access + template_info { + elements { + referenced_type: "type-2" + } } access: public_access - record_kind: struct_kind + record_kind: class_kind tag_info { - unique_id: "Hello" + unique_id: "_ZTS4ListIiE" } } record_types { type_info { - name: "CPPHello" - size: 56 + name: "test2::HelloAgain" + size: 40 alignment: 8 - referenced_type: "type-23" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "CPPHello" - self_type: "type-23" + referenced_type: "type-4" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test2::HelloAgain" + self_type: "type-4" } fields { - referenced_type: "type-24" - field_offset: 352 - field_name: "cpp_foo" + referenced_type: "type-5" + field_offset: 64 + field_name: "foo_again" access: public_access } fields { - referenced_type: "type-25" - field_offset: 384 - field_name: "cpp_bar" - access: public_access - } - base_specifiers { - referenced_type: "type-4" - is_virtual: false - access: private_access - } - base_specifiers { - referenced_type: "type-15" - is_virtual: false + referenced_type: "type-2" + field_offset: 256 + field_name: "bar_again" access: public_access } vtable_layout { @@ -347,25 +325,25 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI8CPPHello" + mangled_component_name: "_ZTIN5test210HelloAgainE" component_value: 0 is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN8CPPHello5againEv" + mangled_component_name: "_ZN5test210HelloAgain5againEv" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN8CPPHelloD1Ev" + mangled_component_name: "_ZN5test210HelloAgainD1Ev" component_value: 0 is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN8CPPHelloD0Ev" + mangled_component_name: "_ZN5test210HelloAgainD0Ev" component_value: 0 is_pure: false } @@ -373,95 +351,137 @@ record_types { access: public_access record_kind: struct_kind tag_info { - unique_id: "_ZTS8CPPHello" + unique_id: "_ZTSN5test210HelloAgainE" } } record_types { type_info { - name: "List<float>" - size: 8 + name: "test3::ByeAgain<double>" + size: 16 alignment: 8 - referenced_type: "type-31" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<float>" - self_type: "type-31" + referenced_type: "type-13" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::ByeAgain<double>" + self_type: "type-13" } fields { - referenced_type: "type-33" + referenced_type: "type-14" field_offset: 0 - field_name: "middle" + field_name: "foo_again" + access: public_access + } + fields { + referenced_type: "type-2" + field_offset: 64 + field_name: "bar_again" access: public_access } template_info { elements { - referenced_type: "type-3" + referenced_type: "type-14" } } access: public_access - record_kind: class_kind + record_kind: struct_kind tag_info { - unique_id: "_ZTS4ListIfE" + unique_id: "_ZTSN5test38ByeAgainIdEE" } } record_types { type_info { - name: "List<float>::_Node" - size: 24 - alignment: 8 - referenced_type: "type-32" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<float>::_Node" - self_type: "type-32" + name: "test3::ByeAgain<float>" + size: 8 + alignment: 4 + referenced_type: "type-15" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::ByeAgain<float>" + self_type: "type-15" } fields { referenced_type: "type-3" field_offset: 0 - field_name: "mVal" - access: private_access + field_name: "foo_again" + access: public_access } fields { - referenced_type: "type-33" - field_offset: 64 - field_name: "mpPrev" - access: private_access + referenced_type: "type-3" + field_offset: 32 + field_name: "bar_Again" + access: public_access + } + template_info { + elements { + referenced_type: "type-3" + } + } + access: public_access + record_kind: struct_kind + tag_info { + unique_id: "_ZTSN5test38ByeAgainIfEE" + } +} +record_types { + type_info { + name: "test3::Outer" + size: 4 + alignment: 4 + referenced_type: "type-17" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::Outer" + self_type: "type-17" } fields { - referenced_type: "type-33" - field_offset: 128 - field_name: "mpNext" - access: private_access + referenced_type: "type-2" + field_offset: 0 + field_name: "a" + access: public_access } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTSN4ListIfE5_NodeE" + unique_id: "_ZTSN5test35OuterE" } } record_types { type_info { - name: "List<int>" - size: 8 - alignment: 8 - referenced_type: "type-35" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<int>" - self_type: "type-35" + name: "test3::Outer::Inner" + size: 4 + alignment: 4 + referenced_type: "type-18" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::Outer::Inner" + self_type: "type-18" } fields { - referenced_type: "type-37" + referenced_type: "type-2" field_offset: 0 - field_name: "middle" - access: public_access + field_name: "b" + access: private_access } - template_info { - elements { - referenced_type: "type-2" - } + access: private_access + record_kind: class_kind + tag_info { + unique_id: "_ZTSN5test35Outer5InnerE" + } +} +enum_types { + type_info { + name: "CPPHello::Bla" + size: 4 + alignment: 4 + referenced_type: "type-27" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "CPPHello::Bla" + self_type: "type-27" + } + underlying_type: "type-9" + enum_fields { + enum_field_value: 1 + name: "CPPHello::BLA" } access: public_access - record_kind: class_kind tag_info { - unique_id: "_ZTS4ListIiE" + unique_id: "_ZTSN8CPPHello3BlaE" } } enum_types { @@ -512,57 +532,48 @@ enum_types { unique_id: "_ZTSN5test34KindE" } } -enum_types { +pointer_types { type_info { - name: "CPPHello::Bla" - size: 4 - alignment: 4 - referenced_type: "type-27" + name: "CPPHello *" + size: 8 + alignment: 8 + referenced_type: "type-23" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "CPPHello::Bla" - self_type: "type-27" - } - underlying_type: "type-9" - enum_fields { - enum_field_value: 1 - name: "CPPHello::BLA" - } - access: public_access - tag_info { - unique_id: "_ZTSN8CPPHello3BlaE" + linker_set_key: "CPPHello *" + self_type: "type-26" } } pointer_types { type_info { - name: "test2::HelloAgain *" + name: "List<float>::_Node *" size: 8 alignment: 8 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test2::HelloAgain *" - self_type: "type-7" + referenced_type: "type-32" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "List<float>::_Node *" + self_type: "type-33" } } pointer_types { type_info { - name: "CPPHello *" + name: "List<int>::_Node *" size: 8 alignment: 8 - referenced_type: "type-23" + referenced_type: "type-36" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "CPPHello *" - self_type: "type-26" + linker_set_key: "List<int>::_Node *" + self_type: "type-37" } } pointer_types { type_info { - name: "int *" + name: "const char *" size: 8 alignment: 8 - referenced_type: "type-2" + referenced_type: "type-38" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "int *" - self_type: "type-29" + linker_set_key: "const char *" + self_type: "type-39" } } pointer_types { @@ -578,35 +589,24 @@ pointer_types { } pointer_types { type_info { - name: "List<float>::_Node *" - size: 8 - alignment: 8 - referenced_type: "type-32" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<float>::_Node *" - self_type: "type-33" - } -} -pointer_types { - type_info { - name: "List<int>::_Node *" + name: "int *" size: 8 alignment: 8 - referenced_type: "type-36" + referenced_type: "type-2" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<int>::_Node *" - self_type: "type-37" + linker_set_key: "int *" + self_type: "type-29" } } pointer_types { type_info { - name: "const char *" + name: "test2::HelloAgain *" size: 8 alignment: 8 - referenced_type: "type-38" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const char *" - self_type: "type-39" + referenced_type: "type-4" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test2::HelloAgain *" + self_type: "type-7" } } lvalue_reference_types { @@ -622,19 +622,45 @@ lvalue_reference_types { } builtin_types { type_info { - name: "int" - size: 4 - alignment: 4 - referenced_type: "type-2" + name: "bool" + size: 1 + alignment: 1 + referenced_type: "type-12" source_file: "" - linker_set_key: "int" - self_type: "type-2" + linker_set_key: "bool" + self_type: "type-12" + } + is_unsigned: true + is_integral: true +} +builtin_types { + type_info { + name: "char" + size: 1 + alignment: 1 + referenced_type: "type-40" + source_file: "" + linker_set_key: "char" + self_type: "type-40" } is_unsigned: false is_integral: true } builtin_types { type_info { + name: "double" + size: 8 + alignment: 8 + referenced_type: "type-14" + source_file: "" + linker_set_key: "double" + self_type: "type-14" + } + is_unsigned: false + is_integral: false +} +builtin_types { + type_info { name: "float" size: 4 alignment: 4 @@ -648,16 +674,16 @@ builtin_types { } builtin_types { type_info { - name: "void" - size: 0 - alignment: 0 - referenced_type: "type-6" + name: "int" + size: 4 + alignment: 4 + referenced_type: "type-2" source_file: "" - linker_set_key: "void" - self_type: "type-6" + linker_set_key: "int" + self_type: "type-2" } is_unsigned: false - is_integral: false + is_integral: true } builtin_types { type_info { @@ -674,26 +700,13 @@ builtin_types { } builtin_types { type_info { - name: "bool" - size: 1 - alignment: 1 - referenced_type: "type-12" - source_file: "" - linker_set_key: "bool" - self_type: "type-12" - } - is_unsigned: true - is_integral: true -} -builtin_types { - type_info { - name: "double" - size: 8 - alignment: 8 - referenced_type: "type-14" + name: "void" + size: 0 + alignment: 0 + referenced_type: "type-6" source_file: "" - linker_set_key: "double" - self_type: "type-14" + linker_set_key: "void" + self_type: "type-6" } is_unsigned: false is_integral: false @@ -711,19 +724,6 @@ builtin_types { is_unsigned: false is_integral: true } -builtin_types { - type_info { - name: "char" - size: 1 - alignment: 1 - referenced_type: "type-40" - source_file: "" - linker_set_key: "char" - self_type: "type-40" - } - is_unsigned: false - is_integral: true -} qualified_types { type_info { name: "bool const[2]" @@ -740,13 +740,13 @@ qualified_types { } qualified_types { type_info { - name: "const int" - size: 4 - alignment: 4 - referenced_type: "type-2" + name: "const CPPHello" + size: 56 + alignment: 8 + referenced_type: "type-23" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const int" - self_type: "type-24" + linker_set_key: "const CPPHello" + self_type: "type-28" } is_const: true is_volatile: false @@ -754,13 +754,13 @@ qualified_types { } qualified_types { type_info { - name: "const float" - size: 4 - alignment: 4 - referenced_type: "type-3" + name: "const char" + size: 1 + alignment: 1 + referenced_type: "type-40" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const float" - self_type: "type-25" + linker_set_key: "const char" + self_type: "type-38" } is_const: true is_volatile: false @@ -768,13 +768,13 @@ qualified_types { } qualified_types { type_info { - name: "const CPPHello" - size: 56 - alignment: 8 - referenced_type: "type-23" + name: "const float" + size: 4 + alignment: 4 + referenced_type: "type-3" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const CPPHello" - self_type: "type-28" + linker_set_key: "const float" + self_type: "type-25" } is_const: true is_volatile: false @@ -782,13 +782,13 @@ qualified_types { } qualified_types { type_info { - name: "const char" - size: 1 - alignment: 1 - referenced_type: "type-40" + name: "const int" + size: 4 + alignment: 4 + referenced_type: "type-2" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const char" - self_type: "type-38" + linker_set_key: "const int" + self_type: "type-24" } is_const: true is_volatile: false @@ -806,99 +806,39 @@ array_types { } } functions { - return_type: "type-6" - function_name: "test2::HelloAgain::~HelloAgain" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-7" - default_arg: false - is_this_ptr: true - } - linker_set_key: "_ZN5test210HelloAgainD2Ev" - access: public_access -} -functions { - return_type: "type-6" - function_name: "test2::HelloAgain::~HelloAgain" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-7" - default_arg: false - is_this_ptr: true - } - linker_set_key: "_ZN5test210HelloAgainD1Ev" - access: public_access -} -functions { - return_type: "type-6" - function_name: "test2::HelloAgain::~HelloAgain" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + return_type: "type-31" + function_name: "castInterface" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-7" + referenced_type: "type-31" default_arg: false - is_this_ptr: true - } - linker_set_key: "_ZN5test210HelloAgainD0Ev" - access: public_access -} -functions { - return_type: "type-12" - function_name: "test3::End" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-3" - default_arg: true is_this_ptr: false } - linker_set_key: "_ZN5test33EndEf" - access: public_access -} -functions { - return_type: "type-2" - function_name: "CPPHello::again" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-26" - default_arg: false - is_this_ptr: true - } - linker_set_key: "_ZN8CPPHello5againEv" - access: public_access -} -functions { - return_type: "type-6" - function_name: "CPPHello::CPPHello" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - parameters { - referenced_type: "type-26" + referenced_type: "type-39" default_arg: false - is_this_ptr: true + is_this_ptr: false } - linker_set_key: "_ZN8CPPHelloC2Ev" - access: public_access -} -functions { - return_type: "type-6" - function_name: "CPPHello::CPPHello" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-26" + referenced_type: "type-12" default_arg: false - is_this_ptr: true + is_this_ptr: false } - linker_set_key: "_ZN8CPPHelloC1Ev" - access: public_access -} -functions { - return_type: "type-2" - function_name: "CPPHello::test_enum" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - parameters { - referenced_type: "type-26" - default_arg: false - is_this_ptr: true + template_info { + elements { + referenced_type: "type-3" + } + elements { + referenced_type: "type-3" + } + elements { + referenced_type: "type-3" + } + elements { + referenced_type: "type-3" + } } - linker_set_key: "_ZN8CPPHello9test_enumEv" + linker_set_key: "_Z13castInterfaceIffffE4ListIT_ES0_IT0_EPKcb" access: public_access } functions { @@ -925,6 +865,13 @@ functions { } functions { return_type: "type-6" + function_name: "format" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "_Z6formatv" + access: public_access +} +functions { + return_type: "type-6" function_name: "List<float>::_Node::_Node" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { @@ -937,7 +884,7 @@ functions { default_arg: false is_this_ptr: false } - linker_set_key: "_ZN4ListIfE5_NodeC2ERKf" + linker_set_key: "_ZN4ListIfE5_NodeC1ERKf" access: public_access } functions { @@ -954,7 +901,7 @@ functions { default_arg: false is_this_ptr: false } - linker_set_key: "_ZN4ListIfE5_NodeC1ERKf" + linker_set_key: "_ZN4ListIfE5_NodeC2ERKf" access: public_access } functions { @@ -966,7 +913,7 @@ functions { default_arg: false is_this_ptr: true } - linker_set_key: "_ZN4ListIfE5_NodeD2Ev" + linker_set_key: "_ZN4ListIfE5_NodeD1Ev" access: public_access } functions { @@ -978,57 +925,103 @@ functions { default_arg: false is_this_ptr: true } - linker_set_key: "_ZN4ListIfE5_NodeD1Ev" + linker_set_key: "_ZN4ListIfE5_NodeD2Ev" access: public_access } functions { - return_type: "type-31" - function_name: "castInterface" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + return_type: "type-6" + function_name: "test2::HelloAgain::~HelloAgain" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-31" + referenced_type: "type-7" default_arg: false - is_this_ptr: false + is_this_ptr: true } + linker_set_key: "_ZN5test210HelloAgainD0Ev" + access: public_access +} +functions { + return_type: "type-6" + function_name: "test2::HelloAgain::~HelloAgain" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-39" + referenced_type: "type-7" default_arg: false - is_this_ptr: false + is_this_ptr: true } + linker_set_key: "_ZN5test210HelloAgainD1Ev" + access: public_access +} +functions { + return_type: "type-6" + function_name: "test2::HelloAgain::~HelloAgain" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-12" + referenced_type: "type-7" default_arg: false + is_this_ptr: true + } + linker_set_key: "_ZN5test210HelloAgainD2Ev" + access: public_access +} +functions { + return_type: "type-12" + function_name: "test3::End" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + parameters { + referenced_type: "type-3" + default_arg: true is_this_ptr: false } - template_info { - elements { - referenced_type: "type-3" - } - elements { - referenced_type: "type-3" - } - elements { - referenced_type: "type-3" - } - elements { - referenced_type: "type-3" - } + linker_set_key: "_ZN5test33EndEf" + access: public_access +} +functions { + return_type: "type-2" + function_name: "CPPHello::again" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + parameters { + referenced_type: "type-26" + default_arg: false + is_this_ptr: true } - linker_set_key: "_Z13castInterfaceIffffE4ListIT_ES0_IT0_EPKcb" + linker_set_key: "_ZN8CPPHello5againEv" + access: public_access +} +functions { + return_type: "type-2" + function_name: "CPPHello::test_enum" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + parameters { + referenced_type: "type-26" + default_arg: false + is_this_ptr: true + } + linker_set_key: "_ZN8CPPHello9test_enumEv" access: public_access } functions { return_type: "type-6" - function_name: "format" + function_name: "CPPHello::CPPHello" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "_Z6formatv" + parameters { + referenced_type: "type-26" + default_arg: false + is_this_ptr: true + } + linker_set_key: "_ZN8CPPHelloC1Ev" access: public_access } -global_vars { - name: "test2::HelloAgain::hello_forever" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "_ZN5test210HelloAgain13hello_foreverE" - referenced_type: "type-2" +functions { + return_type: "type-6" + function_name: "CPPHello::CPPHello" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + parameters { + referenced_type: "type-26" + default_arg: false + is_this_ptr: true + } + linker_set_key: "_ZN8CPPHelloC2Ev" access: public_access } global_vars { @@ -1039,9 +1032,9 @@ global_vars { access: public_access } global_vars { - name: "test3::ByeAgain<float>::foo_forever" + name: "test2::HelloAgain::hello_forever" source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "_ZN5test38ByeAgainIfE11foo_foreverE" + linker_set_key: "_ZN5test210HelloAgain13hello_foreverE" referenced_type: "type-2" access: public_access } @@ -1053,6 +1046,13 @@ global_vars { access: public_access } global_vars { + name: "test3::ByeAgain<float>::foo_forever" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "_ZN5test38ByeAgainIfE11foo_foreverE" + referenced_type: "type-2" + access: public_access +} +global_vars { name: "float_list_test" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" linker_set_key: "float_list_test" diff --git a/vndk/tools/header-checker/tests/expected/example1.h b/vndk/tools/header-checker/tests/expected/example1.h index 13ae403b8..f2879f584 100644 --- a/vndk/tools/header-checker/tests/expected/example1.h +++ b/vndk/tools/header-checker/tests/expected/example1.h @@ -1,51 +1,33 @@ record_types { type_info { - name: "HiddenBase" - size: 8 - alignment: 4 - referenced_type: "type-1" - source_file: "/development/vndk/tools/header-checker/tests/input/example3.h" - linker_set_key: "HiddenBase" - self_type: "type-1" + name: "CPPHello" + size: 56 + alignment: 8 + referenced_type: "type-25" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "CPPHello" + self_type: "type-25" } fields { - referenced_type: "type-2" - field_offset: 0 - field_name: "hide" - access: private_access + referenced_type: "type-26" + field_offset: 352 + field_name: "cpp_foo" + access: public_access } fields { - referenced_type: "type-3" - field_offset: 32 - field_name: "seek" - access: private_access - } - access: public_access - record_kind: class_kind - tag_info { - unique_id: "_ZTS10HiddenBase" + referenced_type: "type-27" + field_offset: 384 + field_name: "cpp_bar" + access: public_access } -} -record_types { - type_info { - name: "test2::HelloAgain" - size: 40 - alignment: 8 + base_specifiers { referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test2::HelloAgain" - self_type: "type-4" - } - fields { - referenced_type: "type-5" - field_offset: 64 - field_name: "foo_again" - access: public_access + is_virtual: false + access: private_access } - fields { - referenced_type: "type-2" - field_offset: 256 - field_name: "bar_again" + base_specifiers { + referenced_type: "type-15" + is_virtual: false access: public_access } vtable_layout { @@ -57,25 +39,25 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTIN5test210HelloAgainE" + mangled_component_name: "_ZTI8CPPHello" component_value: 0 is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN5test210HelloAgain5againEv" + mangled_component_name: "_ZN8CPPHello5againEv" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN5test210HelloAgainD1Ev" + mangled_component_name: "_ZN8CPPHelloD1Ev" component_value: 0 is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN5test210HelloAgainD0Ev" + mangled_component_name: "_ZN8CPPHelloD0Ev" component_value: 0 is_pure: false } @@ -83,259 +65,255 @@ record_types { access: public_access record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test210HelloAgainE" + unique_id: "_ZTS8CPPHello" } } record_types { type_info { - name: "test3::ByeAgain<double>" - size: 16 - alignment: 8 - referenced_type: "type-13" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::ByeAgain<double>" - self_type: "type-13" + name: "Hello" + size: 32 + alignment: 4 + referenced_type: "type-21" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "Hello" + self_type: "type-21" } fields { - referenced_type: "type-14" + referenced_type: "type-2" field_offset: 0 - field_name: "foo_again" + field_name: "foo" access: public_access } fields { referenced_type: "type-2" + field_offset: 32 + field_name: "bar" + access: public_access + } + fields { + referenced_type: "type-22" field_offset: 64 - field_name: "bar_again" + field_name: "d" access: public_access } - template_info { - elements { - referenced_type: "type-14" - } + fields { + referenced_type: "type-9" + field_offset: 96 + field_name: "enum_field" + access: public_access + } + fields { + referenced_type: "type-9" + field_offset: 128 + field_name: "enum_field2" + access: public_access + } + fields { + referenced_type: "type-23" + field_offset: 160 + field_name: "" + access: public_access } access: public_access record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test38ByeAgainIdEE" + unique_id: "Hello" } } record_types { type_info { - name: "test3::ByeAgain<float>" - size: 8 + name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" + size: 12 alignment: 4 - referenced_type: "type-15" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::ByeAgain<float>" - self_type: "type-15" + referenced_type: "type-23" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" + self_type: "type-23" } fields { - referenced_type: "type-3" + referenced_type: "type-2" field_offset: 0 - field_name: "foo_again" + field_name: "a" access: public_access } fields { - referenced_type: "type-3" + referenced_type: "type-2" field_offset: 32 - field_name: "bar_Again" + field_name: "b" access: public_access } - template_info { - elements { - referenced_type: "type-3" - } + fields { + referenced_type: "type-24" + field_offset: 64 + field_name: "" + access: public_access } access: public_access + is_anonymous: true record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test38ByeAgainIfEE" + unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)" } } record_types { type_info { - name: "test3::Outer" + name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" size: 4 alignment: 4 - referenced_type: "type-17" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::Outer" - self_type: "type-17" + referenced_type: "type-24" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" + self_type: "type-24" } fields { referenced_type: "type-2" field_offset: 0 - field_name: "a" + field_name: "c" access: public_access } access: public_access - record_kind: class_kind + is_anonymous: true + record_kind: struct_kind tag_info { - unique_id: "_ZTSN5test35OuterE" + unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5)" } } record_types { type_info { - name: "test3::Outer::Inner" - size: 4 + name: "HiddenBase" + size: 8 alignment: 4 - referenced_type: "type-18" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test3::Outer::Inner" - self_type: "type-18" + referenced_type: "type-1" + source_file: "/development/vndk/tools/header-checker/tests/input/example3.h" + linker_set_key: "HiddenBase" + self_type: "type-1" } fields { referenced_type: "type-2" field_offset: 0 - field_name: "b" + field_name: "hide" access: private_access } - access: private_access + fields { + referenced_type: "type-3" + field_offset: 32 + field_name: "seek" + access: private_access + } + access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTSN5test35Outer5InnerE" + unique_id: "_ZTS10HiddenBase" } } record_types { type_info { - name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" - size: 4 - alignment: 4 - referenced_type: "type-24" + name: "List<float>" + size: 8 + alignment: 8 + referenced_type: "type-34" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5) at /development/vndk/tools/header-checker/tests/input/example1.h:22:5" - self_type: "type-24" + linker_set_key: "List<float>" + self_type: "type-34" } fields { - referenced_type: "type-2" + referenced_type: "type-36" field_offset: 0 - field_name: "c" + field_name: "middle" access: public_access } + template_info { + elements { + referenced_type: "type-3" + } + } access: public_access - is_anonymous: true - record_kind: struct_kind + record_kind: class_kind tag_info { - unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:22:5)" + unique_id: "_ZTS4ListIfE" } } record_types { type_info { - name: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" - size: 12 - alignment: 4 - referenced_type: "type-23" + name: "List<float>::_Node" + size: 24 + alignment: 8 + referenced_type: "type-35" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3) at /development/vndk/tools/header-checker/tests/input/example1.h:19:3" - self_type: "type-23" + linker_set_key: "List<float>::_Node" + self_type: "type-35" } fields { - referenced_type: "type-2" + referenced_type: "type-3" field_offset: 0 - field_name: "a" - access: public_access + field_name: "mVal" + access: private_access } fields { - referenced_type: "type-2" - field_offset: 32 - field_name: "b" - access: public_access + referenced_type: "type-36" + field_offset: 64 + field_name: "mpPrev" + access: private_access } fields { - referenced_type: "type-24" - field_offset: 64 - field_name: "" - access: public_access + referenced_type: "type-36" + field_offset: 128 + field_name: "mpNext" + access: private_access } access: public_access - is_anonymous: true - record_kind: struct_kind + record_kind: class_kind tag_info { - unique_id: "Hello::(anonymous struct at /development/vndk/tools/header-checker/tests/input/example1.h:19:3)" + unique_id: "_ZTSN4ListIfE5_NodeE" } } record_types { type_info { - name: "Hello" - size: 32 - alignment: 4 - referenced_type: "type-21" + name: "List<int>" + size: 8 + alignment: 8 + referenced_type: "type-41" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "Hello" - self_type: "type-21" + linker_set_key: "List<int>" + self_type: "type-41" } fields { - referenced_type: "type-2" + referenced_type: "type-43" field_offset: 0 - field_name: "foo" - access: public_access - } - fields { - referenced_type: "type-2" - field_offset: 32 - field_name: "bar" - access: public_access - } - fields { - referenced_type: "type-22" - field_offset: 64 - field_name: "d" - access: public_access - } - fields { - referenced_type: "type-9" - field_offset: 96 - field_name: "enum_field" - access: public_access - } - fields { - referenced_type: "type-9" - field_offset: 128 - field_name: "enum_field2" + field_name: "middle" access: public_access } - fields { - referenced_type: "type-23" - field_offset: 160 - field_name: "" - access: public_access + template_info { + elements { + referenced_type: "type-2" + } } access: public_access - record_kind: struct_kind + record_kind: class_kind tag_info { - unique_id: "Hello" + unique_id: "_ZTS4ListIiE" } } record_types { type_info { - name: "CPPHello" - size: 56 + name: "test2::HelloAgain" + size: 40 alignment: 8 - referenced_type: "type-25" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "CPPHello" - self_type: "type-25" + referenced_type: "type-4" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test2::HelloAgain" + self_type: "type-4" } fields { - referenced_type: "type-26" - field_offset: 352 - field_name: "cpp_foo" + referenced_type: "type-5" + field_offset: 64 + field_name: "foo_again" access: public_access } fields { - referenced_type: "type-27" - field_offset: 384 - field_name: "cpp_bar" - access: public_access - } - base_specifiers { - referenced_type: "type-4" - is_virtual: false - access: private_access - } - base_specifiers { - referenced_type: "type-15" - is_virtual: false + referenced_type: "type-2" + field_offset: 256 + field_name: "bar_again" access: public_access } vtable_layout { @@ -347,25 +325,25 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI8CPPHello" + mangled_component_name: "_ZTIN5test210HelloAgainE" component_value: 0 is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN8CPPHello5againEv" + mangled_component_name: "_ZN5test210HelloAgain5againEv" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN8CPPHelloD1Ev" + mangled_component_name: "_ZN5test210HelloAgainD1Ev" component_value: 0 is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN8CPPHelloD0Ev" + mangled_component_name: "_ZN5test210HelloAgainD0Ev" component_value: 0 is_pure: false } @@ -373,95 +351,137 @@ record_types { access: public_access record_kind: struct_kind tag_info { - unique_id: "_ZTS8CPPHello" + unique_id: "_ZTSN5test210HelloAgainE" } } record_types { type_info { - name: "List<float>" - size: 8 + name: "test3::ByeAgain<double>" + size: 16 alignment: 8 - referenced_type: "type-34" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<float>" - self_type: "type-34" + referenced_type: "type-13" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::ByeAgain<double>" + self_type: "type-13" } fields { - referenced_type: "type-36" + referenced_type: "type-14" field_offset: 0 - field_name: "middle" + field_name: "foo_again" + access: public_access + } + fields { + referenced_type: "type-2" + field_offset: 64 + field_name: "bar_again" access: public_access } template_info { elements { - referenced_type: "type-3" + referenced_type: "type-14" } } access: public_access - record_kind: class_kind + record_kind: struct_kind tag_info { - unique_id: "_ZTS4ListIfE" + unique_id: "_ZTSN5test38ByeAgainIdEE" } } record_types { type_info { - name: "List<float>::_Node" - size: 24 - alignment: 8 - referenced_type: "type-35" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<float>::_Node" - self_type: "type-35" + name: "test3::ByeAgain<float>" + size: 8 + alignment: 4 + referenced_type: "type-15" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::ByeAgain<float>" + self_type: "type-15" } fields { referenced_type: "type-3" field_offset: 0 - field_name: "mVal" - access: private_access + field_name: "foo_again" + access: public_access } fields { - referenced_type: "type-36" - field_offset: 64 - field_name: "mpPrev" - access: private_access + referenced_type: "type-3" + field_offset: 32 + field_name: "bar_Again" + access: public_access + } + template_info { + elements { + referenced_type: "type-3" + } + } + access: public_access + record_kind: struct_kind + tag_info { + unique_id: "_ZTSN5test38ByeAgainIfEE" + } +} +record_types { + type_info { + name: "test3::Outer" + size: 4 + alignment: 4 + referenced_type: "type-17" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::Outer" + self_type: "type-17" } fields { - referenced_type: "type-36" - field_offset: 128 - field_name: "mpNext" - access: private_access + referenced_type: "type-2" + field_offset: 0 + field_name: "a" + access: public_access } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTSN4ListIfE5_NodeE" + unique_id: "_ZTSN5test35OuterE" } } record_types { type_info { - name: "List<int>" - size: 8 - alignment: 8 - referenced_type: "type-41" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<int>" - self_type: "type-41" + name: "test3::Outer::Inner" + size: 4 + alignment: 4 + referenced_type: "type-18" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test3::Outer::Inner" + self_type: "type-18" } fields { - referenced_type: "type-43" + referenced_type: "type-2" field_offset: 0 - field_name: "middle" - access: public_access + field_name: "b" + access: private_access } - template_info { - elements { - referenced_type: "type-2" - } + access: private_access + record_kind: class_kind + tag_info { + unique_id: "_ZTSN5test35Outer5InnerE" + } +} +enum_types { + type_info { + name: "CPPHello::Bla" + size: 4 + alignment: 4 + referenced_type: "type-29" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "CPPHello::Bla" + self_type: "type-29" + } + underlying_type: "type-9" + enum_fields { + enum_field_value: 1 + name: "CPPHello::BLA" } access: public_access - record_kind: class_kind tag_info { - unique_id: "_ZTS4ListIiE" + unique_id: "_ZTSN8CPPHello3BlaE" } } enum_types { @@ -512,35 +532,15 @@ enum_types { unique_id: "_ZTSN5test34KindE" } } -enum_types { - type_info { - name: "CPPHello::Bla" - size: 4 - alignment: 4 - referenced_type: "type-29" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "CPPHello::Bla" - self_type: "type-29" - } - underlying_type: "type-9" - enum_fields { - enum_field_value: 1 - name: "CPPHello::BLA" - } - access: public_access - tag_info { - unique_id: "_ZTSN8CPPHello3BlaE" - } -} pointer_types { type_info { - name: "test2::HelloAgain *" + name: "CPPHello *" size: 8 alignment: 8 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "test2::HelloAgain *" - self_type: "type-7" + referenced_type: "type-25" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "CPPHello *" + self_type: "type-28" } } pointer_types { @@ -556,46 +556,46 @@ pointer_types { } pointer_types { type_info { - name: "CPPHello *" + name: "List<float>::_Node *" size: 8 alignment: 8 - referenced_type: "type-25" + referenced_type: "type-35" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "CPPHello *" - self_type: "type-28" + linker_set_key: "List<float>::_Node *" + self_type: "type-36" } } pointer_types { type_info { - name: "int *" + name: "List<int> *" size: 8 alignment: 8 - referenced_type: "type-2" + referenced_type: "type-41" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "int *" - self_type: "type-31" + linker_set_key: "List<int> *" + self_type: "type-44" } } pointer_types { type_info { - name: "float *" + name: "List<int>::_Node *" size: 8 alignment: 8 - referenced_type: "type-3" + referenced_type: "type-42" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "float *" - self_type: "type-33" + linker_set_key: "List<int>::_Node *" + self_type: "type-43" } } pointer_types { type_info { - name: "List<float>::_Node *" + name: "StackNode<int> *" size: 8 alignment: 8 - referenced_type: "type-35" + referenced_type: "type-45" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<float>::_Node *" - self_type: "type-36" + linker_set_key: "StackNode<int> *" + self_type: "type-46" } } pointer_types { @@ -611,57 +611,46 @@ pointer_types { } pointer_types { type_info { - name: "List<int>::_Node *" + name: "const char *" size: 8 alignment: 8 - referenced_type: "type-42" + referenced_type: "type-47" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<int>::_Node *" - self_type: "type-43" + linker_set_key: "const char *" + self_type: "type-48" } } pointer_types { type_info { - name: "List<int> *" + name: "float *" size: 8 alignment: 8 - referenced_type: "type-41" + referenced_type: "type-3" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "List<int> *" - self_type: "type-44" + linker_set_key: "float *" + self_type: "type-33" } } pointer_types { type_info { - name: "StackNode<int> *" + name: "int *" size: 8 alignment: 8 - referenced_type: "type-45" + referenced_type: "type-2" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "StackNode<int> *" - self_type: "type-46" + linker_set_key: "int *" + self_type: "type-31" } } pointer_types { type_info { - name: "const char *" - size: 8 - alignment: 8 - referenced_type: "type-47" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const char *" - self_type: "type-48" - } -} -lvalue_reference_types { - type_info { - name: "int &" + name: "test2::HelloAgain *" size: 8 alignment: 8 - referenced_type: "type-2" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "int &" - self_type: "type-30" + referenced_type: "type-4" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "test2::HelloAgain *" + self_type: "type-7" } } lvalue_reference_types { @@ -686,21 +675,58 @@ lvalue_reference_types { self_type: "type-38" } } -builtin_types { +lvalue_reference_types { type_info { - name: "int" - size: 4 - alignment: 4 + name: "int &" + size: 8 + alignment: 8 referenced_type: "type-2" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "int &" + self_type: "type-30" + } +} +builtin_types { + type_info { + name: "bool" + size: 1 + alignment: 1 + referenced_type: "type-12" source_file: "" - linker_set_key: "int" - self_type: "type-2" + linker_set_key: "bool" + self_type: "type-12" + } + is_unsigned: true + is_integral: true +} +builtin_types { + type_info { + name: "char" + size: 1 + alignment: 1 + referenced_type: "type-49" + source_file: "" + linker_set_key: "char" + self_type: "type-49" } is_unsigned: false is_integral: true } builtin_types { type_info { + name: "double" + size: 8 + alignment: 8 + referenced_type: "type-14" + source_file: "" + linker_set_key: "double" + self_type: "type-14" + } + is_unsigned: false + is_integral: false +} +builtin_types { + type_info { name: "float" size: 4 alignment: 4 @@ -714,16 +740,16 @@ builtin_types { } builtin_types { type_info { - name: "void" - size: 0 - alignment: 0 - referenced_type: "type-6" + name: "int" + size: 4 + alignment: 4 + referenced_type: "type-2" source_file: "" - linker_set_key: "void" - self_type: "type-6" + linker_set_key: "int" + self_type: "type-2" } is_unsigned: false - is_integral: false + is_integral: true } builtin_types { type_info { @@ -740,26 +766,13 @@ builtin_types { } builtin_types { type_info { - name: "bool" - size: 1 - alignment: 1 - referenced_type: "type-12" - source_file: "" - linker_set_key: "bool" - self_type: "type-12" - } - is_unsigned: true - is_integral: true -} -builtin_types { - type_info { - name: "double" - size: 8 - alignment: 8 - referenced_type: "type-14" + name: "void" + size: 0 + alignment: 0 + referenced_type: "type-6" source_file: "" - linker_set_key: "double" - self_type: "type-14" + linker_set_key: "void" + self_type: "type-6" } is_unsigned: false is_integral: false @@ -777,19 +790,6 @@ builtin_types { is_unsigned: false is_integral: true } -builtin_types { - type_info { - name: "char" - size: 1 - alignment: 1 - referenced_type: "type-49" - source_file: "" - linker_set_key: "char" - self_type: "type-49" - } - is_unsigned: false - is_integral: true -} qualified_types { type_info { name: "bool const[2]" @@ -806,34 +806,6 @@ qualified_types { } qualified_types { type_info { - name: "const int" - size: 4 - alignment: 4 - referenced_type: "type-2" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const int" - self_type: "type-26" - } - is_const: true - is_volatile: false - is_restricted: false -} -qualified_types { - type_info { - name: "const float" - size: 4 - alignment: 4 - referenced_type: "type-3" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "const float" - self_type: "type-27" - } - is_const: true - is_volatile: false - is_restricted: false -} -qualified_types { - type_info { name: "const CPPHello" size: 56 alignment: 8 @@ -874,6 +846,34 @@ qualified_types { is_volatile: false is_restricted: false } +qualified_types { + type_info { + name: "const float" + size: 4 + alignment: 4 + referenced_type: "type-3" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "const float" + self_type: "type-27" + } + is_const: true + is_volatile: false + is_restricted: false +} +qualified_types { + type_info { + name: "const int" + size: 4 + alignment: 4 + referenced_type: "type-2" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "const int" + self_type: "type-26" + } + is_const: true + is_volatile: false + is_restricted: false +} array_types { type_info { name: "bool [2]" @@ -886,128 +886,73 @@ array_types { } } functions { - return_type: "type-6" - function_name: "test2::HelloAgain::~HelloAgain" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-7" - default_arg: false - is_this_ptr: true - } - linker_set_key: "_ZN5test210HelloAgainD2Ev" - access: public_access -} -functions { - return_type: "type-6" - function_name: "test2::HelloAgain::~HelloAgain" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-7" - default_arg: false - is_this_ptr: true - } - linker_set_key: "_ZN5test210HelloAgainD1Ev" - access: public_access -} -functions { - return_type: "type-6" - function_name: "test2::HelloAgain::~HelloAgain" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-7" - default_arg: false - is_this_ptr: true - } - linker_set_key: "_ZN5test210HelloAgainD0Ev" - access: public_access -} -functions { - return_type: "type-12" - function_name: "test3::End" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-3" - default_arg: true - is_this_ptr: false - } - linker_set_key: "_ZN5test33EndEf" - access: public_access -} -functions { return_type: "type-2" - function_name: "uses_forward_decl" + function_name: "ListMangle" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-20" + referenced_type: "type-44" default_arg: false is_this_ptr: false } - linker_set_key: "uses_forward_decl" - access: public_access -} -functions { - return_type: "type-2" - function_name: "CPPHello::again" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-28" + referenced_type: "type-46" default_arg: false - is_this_ptr: true + is_this_ptr: false } - linker_set_key: "_ZN8CPPHello5againEv" + linker_set_key: "_Z10ListMangleP4ListIiEP9StackNodeIiE" access: public_access } functions { return_type: "type-6" - function_name: "CPPHello::CPPHello" + function_name: "fooVariadic" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-28" + referenced_type: "type-30" default_arg: false - is_this_ptr: true + is_this_ptr: false } - linker_set_key: "_ZN8CPPHelloC2Ev" - access: public_access -} -functions { - return_type: "type-6" - function_name: "CPPHello::CPPHello" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-28" + referenced_type: "type-31" default_arg: false - is_this_ptr: true + is_this_ptr: false } - linker_set_key: "_ZN8CPPHelloC1Ev" + linker_set_key: "_Z11fooVariadicRiPiz" access: public_access } functions { - return_type: "type-2" - function_name: "CPPHello::test_enum" + return_type: "type-34" + function_name: "castInterface" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-28" + referenced_type: "type-34" default_arg: false - is_this_ptr: true + is_this_ptr: false } - linker_set_key: "_ZN8CPPHello9test_enumEv" - access: public_access -} -functions { - return_type: "type-6" - function_name: "fooVariadic" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-30" + referenced_type: "type-48" default_arg: false is_this_ptr: false } parameters { - referenced_type: "type-31" + referenced_type: "type-12" default_arg: false is_this_ptr: false } - linker_set_key: "_Z11fooVariadicRiPiz" + template_info { + elements { + referenced_type: "type-3" + } + elements { + referenced_type: "type-3" + } + elements { + referenced_type: "type-3" + } + elements { + referenced_type: "type-3" + } + } + linker_set_key: "_Z13castInterfaceIffffE4ListIT_ES0_IT0_EPKcb" access: public_access } functions { @@ -1034,19 +979,33 @@ functions { } functions { return_type: "type-6" - function_name: "List<float>::_Node::_Node" + function_name: "format" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + linker_set_key: "_Z6formatv" + access: public_access +} +functions { + return_type: "type-6" + function_name: "List<float>::_Node::PrivateNode" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { referenced_type: "type-36" default_arg: false is_this_ptr: true } + linker_set_key: "_ZN4ListIfE5_Node11PrivateNodeEv" + access: private_access +} +functions { + return_type: "type-38" + function_name: "List<float>::_Node::getRef" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-37" + referenced_type: "type-36" default_arg: false - is_this_ptr: false + is_this_ptr: true } - linker_set_key: "_ZN4ListIfE5_NodeC2ERKf" + linker_set_key: "_ZN4ListIfE5_Node6getRefEv" access: public_access } functions { @@ -1068,14 +1027,19 @@ functions { } functions { return_type: "type-6" - function_name: "List<float>::_Node::~_Node" + function_name: "List<float>::_Node::_Node" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { referenced_type: "type-36" default_arg: false is_this_ptr: true } - linker_set_key: "_ZN4ListIfE5_NodeD2Ev" + parameters { + referenced_type: "type-37" + default_arg: false + is_this_ptr: false + } + linker_set_key: "_ZN4ListIfE5_NodeC2ERKf" access: public_access } functions { @@ -1091,106 +1055,135 @@ functions { access: public_access } functions { - return_type: "type-38" - function_name: "List<float>::_Node::getRef" + return_type: "type-6" + function_name: "List<float>::_Node::~_Node" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { referenced_type: "type-36" default_arg: false is_this_ptr: true } - linker_set_key: "_ZN4ListIfE5_Node6getRefEv" + linker_set_key: "_ZN4ListIfE5_NodeD2Ev" access: public_access } functions { - return_type: "type-37" - function_name: "List<float>::_Node::getRef" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + return_type: "type-6" + function_name: "test2::HelloAgain::~HelloAgain" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-40" + referenced_type: "type-7" default_arg: false is_this_ptr: true } - linker_set_key: "_ZNK4ListIfE5_Node6getRefEv" + linker_set_key: "_ZN5test210HelloAgainD0Ev" access: public_access } functions { return_type: "type-6" - function_name: "List<float>::_Node::PrivateNode" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + function_name: "test2::HelloAgain::~HelloAgain" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-36" + referenced_type: "type-7" default_arg: false is_this_ptr: true } - linker_set_key: "_ZN4ListIfE5_Node11PrivateNodeEv" - access: private_access + linker_set_key: "_ZN5test210HelloAgainD1Ev" + access: public_access } functions { - return_type: "type-2" - function_name: "ListMangle" - source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + return_type: "type-6" + function_name: "test2::HelloAgain::~HelloAgain" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-44" + referenced_type: "type-7" default_arg: false - is_this_ptr: false + is_this_ptr: true } + linker_set_key: "_ZN5test210HelloAgainD2Ev" + access: public_access +} +functions { + return_type: "type-12" + function_name: "test3::End" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-46" - default_arg: false + referenced_type: "type-3" + default_arg: true is_this_ptr: false } - linker_set_key: "_Z10ListMangleP4ListIiEP9StackNodeIiE" + linker_set_key: "_ZN5test33EndEf" access: public_access } functions { - return_type: "type-34" - function_name: "castInterface" + return_type: "type-2" + function_name: "CPPHello::again" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-34" + referenced_type: "type-28" default_arg: false - is_this_ptr: false + is_this_ptr: true } + linker_set_key: "_ZN8CPPHello5againEv" + access: public_access +} +functions { + return_type: "type-2" + function_name: "CPPHello::test_enum" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-48" + referenced_type: "type-28" default_arg: false - is_this_ptr: false + is_this_ptr: true } + linker_set_key: "_ZN8CPPHello9test_enumEv" + access: public_access +} +functions { + return_type: "type-6" + function_name: "CPPHello::CPPHello" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" parameters { - referenced_type: "type-12" + referenced_type: "type-28" default_arg: false - is_this_ptr: false - } - template_info { - elements { - referenced_type: "type-3" - } - elements { - referenced_type: "type-3" - } - elements { - referenced_type: "type-3" - } - elements { - referenced_type: "type-3" - } + is_this_ptr: true } - linker_set_key: "_Z13castInterfaceIffffE4ListIT_ES0_IT0_EPKcb" + linker_set_key: "_ZN8CPPHelloC1Ev" access: public_access } functions { return_type: "type-6" - function_name: "format" + function_name: "CPPHello::CPPHello" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" - linker_set_key: "_Z6formatv" + parameters { + referenced_type: "type-28" + default_arg: false + is_this_ptr: true + } + linker_set_key: "_ZN8CPPHelloC2Ev" access: public_access } -global_vars { - name: "test2::HelloAgain::hello_forever" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "_ZN5test210HelloAgain13hello_foreverE" - referenced_type: "type-2" +functions { + return_type: "type-37" + function_name: "List<float>::_Node::getRef" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + parameters { + referenced_type: "type-40" + default_arg: false + is_this_ptr: true + } + linker_set_key: "_ZNK4ListIfE5_Node6getRefEv" + access: public_access +} +functions { + return_type: "type-2" + function_name: "uses_forward_decl" + source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" + parameters { + referenced_type: "type-20" + default_arg: false + is_this_ptr: false + } + linker_set_key: "uses_forward_decl" access: public_access } global_vars { @@ -1201,9 +1194,9 @@ global_vars { access: public_access } global_vars { - name: "test3::ByeAgain<float>::foo_forever" + name: "test2::HelloAgain::hello_forever" source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "_ZN5test38ByeAgainIfE11foo_foreverE" + linker_set_key: "_ZN5test210HelloAgain13hello_foreverE" referenced_type: "type-2" access: public_access } @@ -1215,6 +1208,13 @@ global_vars { access: public_access } global_vars { + name: "test3::ByeAgain<float>::foo_forever" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "_ZN5test38ByeAgainIfE11foo_foreverE" + referenced_type: "type-2" + access: public_access +} +global_vars { name: "float_list_test" source_file: "/development/vndk/tools/header-checker/tests/input/example1.h" linker_set_key: "float_list_test" diff --git a/vndk/tools/header-checker/tests/expected/example2.h b/vndk/tools/header-checker/tests/expected/example2.h index 316441c18..686c05160 100644 --- a/vndk/tools/header-checker/tests/expected/example2.h +++ b/vndk/tools/header-checker/tests/expected/example2.h @@ -279,19 +279,32 @@ pointer_types { } builtin_types { type_info { - name: "int" - size: 4 - alignment: 4 - referenced_type: "type-2" + name: "bool" + size: 1 + alignment: 1 + referenced_type: "type-12" source_file: "" - linker_set_key: "int" - self_type: "type-2" + linker_set_key: "bool" + self_type: "type-12" } - is_unsigned: false + is_unsigned: true is_integral: true } builtin_types { type_info { + name: "double" + size: 8 + alignment: 8 + referenced_type: "type-14" + source_file: "" + linker_set_key: "double" + self_type: "type-14" + } + is_unsigned: false + is_integral: false +} +builtin_types { + type_info { name: "float" size: 4 alignment: 4 @@ -305,16 +318,16 @@ builtin_types { } builtin_types { type_info { - name: "void" - size: 0 - alignment: 0 - referenced_type: "type-7" + name: "int" + size: 4 + alignment: 4 + referenced_type: "type-2" source_file: "" - linker_set_key: "void" - self_type: "type-7" + linker_set_key: "int" + self_type: "type-2" } is_unsigned: false - is_integral: false + is_integral: true } builtin_types { type_info { @@ -331,26 +344,13 @@ builtin_types { } builtin_types { type_info { - name: "bool" - size: 1 - alignment: 1 - referenced_type: "type-12" - source_file: "" - linker_set_key: "bool" - self_type: "type-12" - } - is_unsigned: true - is_integral: true -} -builtin_types { - type_info { - name: "double" - size: 8 - alignment: 8 - referenced_type: "type-14" + name: "void" + size: 0 + alignment: 0 + referenced_type: "type-7" source_file: "" - linker_set_key: "double" - self_type: "type-14" + linker_set_key: "void" + self_type: "type-7" } is_unsigned: false is_integral: false @@ -401,7 +401,7 @@ functions { default_arg: false is_this_ptr: true } - linker_set_key: "_ZN5test210HelloAgainD2Ev" + linker_set_key: "_ZN5test210HelloAgainD0Ev" access: public_access } functions { @@ -425,41 +425,19 @@ functions { default_arg: false is_this_ptr: true } - linker_set_key: "_ZN5test210HelloAgainD0Ev" - access: public_access -} -functions { - return_type: "type-14" - function_name: "test3::ByeAgain<double>::method_foo" - source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - parameters { - referenced_type: "type-15" - default_arg: false - is_this_ptr: true - } - parameters { - referenced_type: "type-14" - default_arg: false - is_this_ptr: false - } - linker_set_key: "_ZN5test38ByeAgainIdE10method_fooEd" + linker_set_key: "_ZN5test210HelloAgainD2Ev" access: public_access } functions { - return_type: "type-3" - function_name: "test3::ByeAgain<float>::method_foo" + return_type: "type-12" + function_name: "test3::End" source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-17" - default_arg: false - is_this_ptr: true - } - parameters { - referenced_type: "type-2" - default_arg: false + referenced_type: "type-3" + default_arg: true is_this_ptr: false } - linker_set_key: "_ZN5test38ByeAgainIfE10method_fooEi" + linker_set_key: "_ZN5test33EndEf" access: public_access } functions { @@ -493,34 +471,49 @@ functions { access: public_access } functions { - return_type: "type-12" - function_name: "test3::End" + return_type: "type-21" + function_name: "test3::Dummy" source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-3" - default_arg: true + referenced_type: "type-2" + default_arg: false is_this_ptr: false } - linker_set_key: "_ZN5test33EndEf" + linker_set_key: "_ZN5test35DummyEi" access: public_access } functions { - return_type: "type-21" - function_name: "test3::Dummy" + return_type: "type-14" + function_name: "test3::ByeAgain<double>::method_foo" source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" parameters { - referenced_type: "type-2" + referenced_type: "type-15" + default_arg: false + is_this_ptr: true + } + parameters { + referenced_type: "type-14" default_arg: false is_this_ptr: false } - linker_set_key: "_ZN5test35DummyEi" + linker_set_key: "_ZN5test38ByeAgainIdE10method_fooEd" access: public_access } -global_vars { - name: "test2::HelloAgain::hello_forever" +functions { + return_type: "type-3" + function_name: "test3::ByeAgain<float>::method_foo" source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "_ZN5test210HelloAgain13hello_foreverE" - referenced_type: "type-2" + parameters { + referenced_type: "type-17" + default_arg: false + is_this_ptr: true + } + parameters { + referenced_type: "type-2" + default_arg: false + is_this_ptr: false + } + linker_set_key: "_ZN5test38ByeAgainIfE10method_fooEi" access: public_access } global_vars { @@ -531,9 +524,9 @@ global_vars { access: public_access } global_vars { - name: "test3::ByeAgain<float>::foo_forever" + name: "test2::HelloAgain::hello_forever" source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" - linker_set_key: "_ZN5test38ByeAgainIfE11foo_foreverE" + linker_set_key: "_ZN5test210HelloAgain13hello_foreverE" referenced_type: "type-2" access: public_access } @@ -544,3 +537,10 @@ global_vars { referenced_type: "type-13" access: public_access } +global_vars { + name: "test3::ByeAgain<float>::foo_forever" + source_file: "/development/vndk/tools/header-checker/tests/input/example2.h" + linker_set_key: "_ZN5test38ByeAgainIfE11foo_foreverE" + referenced_type: "type-2" + access: public_access +} diff --git a/vndk/tools/header-checker/tests/expected/example3.h b/vndk/tools/header-checker/tests/expected/example3.h index 473bac19f..25d3048dd 100644 --- a/vndk/tools/header-checker/tests/expected/example3.h +++ b/vndk/tools/header-checker/tests/expected/example3.h @@ -28,27 +28,27 @@ record_types { } builtin_types { type_info { - name: "int" + name: "float" size: 4 alignment: 4 - referenced_type: "type-2" + referenced_type: "type-3" source_file: "" - linker_set_key: "int" - self_type: "type-2" + linker_set_key: "float" + self_type: "type-3" } is_unsigned: false - is_integral: true + is_integral: false } builtin_types { type_info { - name: "float" + name: "int" size: 4 alignment: 4 - referenced_type: "type-3" + referenced_type: "type-2" source_file: "" - linker_set_key: "float" - self_type: "type-3" + linker_set_key: "int" + self_type: "type-2" } is_unsigned: false - is_integral: false + is_integral: true } diff --git a/vndk/tools/header-checker/tests/reference_dumps/arm/libgolden_cpp_json.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/arm/libgolden_cpp_json.so.lsdump index 81603fc92..f102bf251 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/arm/libgolden_cpp_json.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/arm/libgolden_cpp_json.so.lsdump @@ -228,15 +228,6 @@ [ { "alignment" : 4, - "linker_set_key" : "SuperSpeaker *", - "name" : "SuperSpeaker *", - "referenced_type" : "type-1", - "self_type" : "type-9", - "size" : 4, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" - }, - { - "alignment" : 4, "linker_set_key" : "HighVolumeSpeaker *", "name" : "HighVolumeSpeaker *", "referenced_type" : "type-11", @@ -246,19 +237,28 @@ }, { "alignment" : 4, - "linker_set_key" : "float *", - "name" : "float *", - "referenced_type" : "type-3", - "self_type" : "type-7", + "linker_set_key" : "LowVolumeSpeaker *", + "name" : "LowVolumeSpeaker *", + "referenced_type" : "type-5", + "self_type" : "type-4", "size" : 4, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" }, { "alignment" : 4, - "linker_set_key" : "LowVolumeSpeaker *", - "name" : "LowVolumeSpeaker *", - "referenced_type" : "type-5", - "self_type" : "type-4", + "linker_set_key" : "SuperSpeaker *", + "name" : "SuperSpeaker *", + "referenced_type" : "type-1", + "self_type" : "type-9", + "size" : 4, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" + }, + { + "alignment" : 4, + "linker_set_key" : "float *", + "name" : "float *", + "referenced_type" : "type-3", + "self_type" : "type-7", "size" : 4, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" } @@ -268,52 +268,6 @@ [ { "alignment" : 4, - "fields" : - [ - { - "access" : "private", - "field_name" : "mSpeakderId", - "field_offset" : 32, - "referenced_type" : "type-2" - } - ], - "linker_set_key" : "SuperSpeaker", - "name" : "SuperSpeaker", - "record_kind" : "class", - "referenced_type" : "type-1", - "self_type" : "type-1", - "size" : 8, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", - "unique_id" : "_ZTS12SuperSpeaker", - "vtable_components" : - [ - { - "kind" : "offset_to_top" - }, - { - "kind" : "rtti", - "mangled_component_name" : "_ZTI12SuperSpeaker" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" - }, - { - "kind" : "complete_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" - }, - { - "kind" : "deleting_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" - } - ] - }, - { - "alignment" : 4, "base_specifiers" : [ { @@ -406,6 +360,52 @@ "mangled_component_name" : "_ZN16LowVolumeSpeakerD0Ev" } ] + }, + { + "alignment" : 4, + "fields" : + [ + { + "access" : "private", + "field_name" : "mSpeakderId", + "field_offset" : 32, + "referenced_type" : "type-2" + } + ], + "linker_set_key" : "SuperSpeaker", + "name" : "SuperSpeaker", + "record_kind" : "class", + "referenced_type" : "type-1", + "self_type" : "type-1", + "size" : 8, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", + "unique_id" : "_ZTS12SuperSpeaker", + "vtable_components" : + [ + { + "kind" : "offset_to_top" + }, + { + "kind" : "rtti", + "mangled_component_name" : "_ZTI12SuperSpeaker" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" + }, + { + "kind" : "complete_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" + }, + { + "kind" : "deleting_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" + } + ] } ], "rvalue_reference_types" : [] diff --git a/vndk/tools/header-checker/tests/reference_dumps/arm/libpure_virtual_function.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/arm/libpure_virtual_function.so.lsdump index 29a106d81..9040218ae 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/arm/libpure_virtual_function.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/arm/libpure_virtual_function.so.lsdump @@ -1,12 +1,17 @@ record_types { type_info { - name: "PureVirtualBase" + name: "DerivedBar" size: 4 alignment: 4 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase" - self_type: "type-1" + linker_set_key: "DerivedBar" + self_type: "type-4" + } + base_specifiers { + referenced_type: "type-1" + is_virtual: false + access: public_access } vtable_layout { vtable_components { @@ -17,55 +22,50 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI15PureVirtualBase" + mangled_component_name: "_ZTI10DerivedBar" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD1Ev" + mangled_component_name: "_ZN10DerivedBarD1Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD0Ev" + mangled_component_name: "_ZN10DerivedBarD0Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" + mangled_component_name: "_ZN10DerivedBar8foo_pureEv" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" + mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" component_value: 0 - is_pure: false + is_pure: true } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS15PureVirtualBase" + unique_id: "_ZTS10DerivedBar" } } record_types { type_info { - name: "DerivedBar" + name: "PureVirtualBase" size: 4 alignment: 4 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar" - self_type: "type-4" - } - base_specifiers { referenced_type: "type-1" - is_virtual: false - access: public_access + source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" + linker_set_key: "PureVirtualBase" + self_type: "type-1" } vtable_layout { vtable_components { @@ -76,61 +76,61 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI10DerivedBar" + mangled_component_name: "_ZTI15PureVirtualBase" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN10DerivedBarD1Ev" + mangled_component_name: "_ZN15PureVirtualBaseD1Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN10DerivedBarD0Ev" + mangled_component_name: "_ZN15PureVirtualBaseD0Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar8foo_pureEv" + mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" + mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" component_value: 0 - is_pure: true + is_pure: false } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS10DerivedBar" + unique_id: "_ZTS15PureVirtualBase" } } pointer_types { type_info { - name: "PureVirtualBase *" + name: "DerivedBar *" size: 4 alignment: 4 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase *" - self_type: "type-3" + linker_set_key: "DerivedBar *" + self_type: "type-5" } } pointer_types { type_info { - name: "DerivedBar *" + name: "PureVirtualBase *" size: 4 alignment: 4 - referenced_type: "type-4" + referenced_type: "type-1" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar *" - self_type: "type-5" + linker_set_key: "PureVirtualBase *" + self_type: "type-3" } } builtin_types { diff --git a/vndk/tools/header-checker/tests/reference_dumps/arm64/libgolden_cpp_json.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/arm64/libgolden_cpp_json.so.lsdump index 3732e9382..83e05383d 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/arm64/libgolden_cpp_json.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/arm64/libgolden_cpp_json.so.lsdump @@ -228,15 +228,6 @@ [ { "alignment" : 8, - "linker_set_key" : "SuperSpeaker *", - "name" : "SuperSpeaker *", - "referenced_type" : "type-1", - "self_type" : "type-9", - "size" : 8, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" - }, - { - "alignment" : 8, "linker_set_key" : "HighVolumeSpeaker *", "name" : "HighVolumeSpeaker *", "referenced_type" : "type-11", @@ -246,19 +237,28 @@ }, { "alignment" : 8, - "linker_set_key" : "float *", - "name" : "float *", - "referenced_type" : "type-3", - "self_type" : "type-7", + "linker_set_key" : "LowVolumeSpeaker *", + "name" : "LowVolumeSpeaker *", + "referenced_type" : "type-5", + "self_type" : "type-4", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" }, { "alignment" : 8, - "linker_set_key" : "LowVolumeSpeaker *", - "name" : "LowVolumeSpeaker *", - "referenced_type" : "type-5", - "self_type" : "type-4", + "linker_set_key" : "SuperSpeaker *", + "name" : "SuperSpeaker *", + "referenced_type" : "type-1", + "self_type" : "type-9", + "size" : 8, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" + }, + { + "alignment" : 8, + "linker_set_key" : "float *", + "name" : "float *", + "referenced_type" : "type-3", + "self_type" : "type-7", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" } @@ -268,52 +268,6 @@ [ { "alignment" : 8, - "fields" : - [ - { - "access" : "private", - "field_name" : "mSpeakderId", - "field_offset" : 64, - "referenced_type" : "type-2" - } - ], - "linker_set_key" : "SuperSpeaker", - "name" : "SuperSpeaker", - "record_kind" : "class", - "referenced_type" : "type-1", - "self_type" : "type-1", - "size" : 16, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", - "unique_id" : "_ZTS12SuperSpeaker", - "vtable_components" : - [ - { - "kind" : "offset_to_top" - }, - { - "kind" : "rtti", - "mangled_component_name" : "_ZTI12SuperSpeaker" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" - }, - { - "kind" : "complete_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" - }, - { - "kind" : "deleting_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" - } - ] - }, - { - "alignment" : 8, "base_specifiers" : [ { @@ -406,6 +360,52 @@ "mangled_component_name" : "_ZN16LowVolumeSpeakerD0Ev" } ] + }, + { + "alignment" : 8, + "fields" : + [ + { + "access" : "private", + "field_name" : "mSpeakderId", + "field_offset" : 64, + "referenced_type" : "type-2" + } + ], + "linker_set_key" : "SuperSpeaker", + "name" : "SuperSpeaker", + "record_kind" : "class", + "referenced_type" : "type-1", + "self_type" : "type-1", + "size" : 16, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", + "unique_id" : "_ZTS12SuperSpeaker", + "vtable_components" : + [ + { + "kind" : "offset_to_top" + }, + { + "kind" : "rtti", + "mangled_component_name" : "_ZTI12SuperSpeaker" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" + }, + { + "kind" : "complete_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" + }, + { + "kind" : "deleting_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" + } + ] } ], "rvalue_reference_types" : [] diff --git a/vndk/tools/header-checker/tests/reference_dumps/arm64/libpure_virtual_function.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/arm64/libpure_virtual_function.so.lsdump index 573df854e..bedbba33f 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/arm64/libpure_virtual_function.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/arm64/libpure_virtual_function.so.lsdump @@ -1,12 +1,17 @@ record_types { type_info { - name: "PureVirtualBase" + name: "DerivedBar" size: 8 alignment: 8 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase" - self_type: "type-1" + linker_set_key: "DerivedBar" + self_type: "type-4" + } + base_specifiers { + referenced_type: "type-1" + is_virtual: false + access: public_access } vtable_layout { vtable_components { @@ -17,55 +22,50 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI15PureVirtualBase" + mangled_component_name: "_ZTI10DerivedBar" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD1Ev" + mangled_component_name: "_ZN10DerivedBarD1Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD0Ev" + mangled_component_name: "_ZN10DerivedBarD0Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" + mangled_component_name: "_ZN10DerivedBar8foo_pureEv" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" + mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" component_value: 0 - is_pure: false + is_pure: true } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS15PureVirtualBase" + unique_id: "_ZTS10DerivedBar" } } record_types { type_info { - name: "DerivedBar" + name: "PureVirtualBase" size: 8 alignment: 8 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar" - self_type: "type-4" - } - base_specifiers { referenced_type: "type-1" - is_virtual: false - access: public_access + source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" + linker_set_key: "PureVirtualBase" + self_type: "type-1" } vtable_layout { vtable_components { @@ -76,61 +76,61 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI10DerivedBar" + mangled_component_name: "_ZTI15PureVirtualBase" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN10DerivedBarD1Ev" + mangled_component_name: "_ZN15PureVirtualBaseD1Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN10DerivedBarD0Ev" + mangled_component_name: "_ZN15PureVirtualBaseD0Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar8foo_pureEv" + mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" + mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" component_value: 0 - is_pure: true + is_pure: false } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS10DerivedBar" + unique_id: "_ZTS15PureVirtualBase" } } pointer_types { type_info { - name: "PureVirtualBase *" + name: "DerivedBar *" size: 8 alignment: 8 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase *" - self_type: "type-3" + linker_set_key: "DerivedBar *" + self_type: "type-5" } } pointer_types { type_info { - name: "DerivedBar *" + name: "PureVirtualBase *" size: 8 alignment: 8 - referenced_type: "type-4" + referenced_type: "type-1" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar *" - self_type: "type-5" + linker_set_key: "PureVirtualBase *" + self_type: "type-3" } } builtin_types { diff --git a/vndk/tools/header-checker/tests/reference_dumps/mips/libgolden_cpp_json.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/mips/libgolden_cpp_json.so.lsdump index 81603fc92..f102bf251 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/mips/libgolden_cpp_json.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/mips/libgolden_cpp_json.so.lsdump @@ -228,15 +228,6 @@ [ { "alignment" : 4, - "linker_set_key" : "SuperSpeaker *", - "name" : "SuperSpeaker *", - "referenced_type" : "type-1", - "self_type" : "type-9", - "size" : 4, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" - }, - { - "alignment" : 4, "linker_set_key" : "HighVolumeSpeaker *", "name" : "HighVolumeSpeaker *", "referenced_type" : "type-11", @@ -246,19 +237,28 @@ }, { "alignment" : 4, - "linker_set_key" : "float *", - "name" : "float *", - "referenced_type" : "type-3", - "self_type" : "type-7", + "linker_set_key" : "LowVolumeSpeaker *", + "name" : "LowVolumeSpeaker *", + "referenced_type" : "type-5", + "self_type" : "type-4", "size" : 4, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" }, { "alignment" : 4, - "linker_set_key" : "LowVolumeSpeaker *", - "name" : "LowVolumeSpeaker *", - "referenced_type" : "type-5", - "self_type" : "type-4", + "linker_set_key" : "SuperSpeaker *", + "name" : "SuperSpeaker *", + "referenced_type" : "type-1", + "self_type" : "type-9", + "size" : 4, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" + }, + { + "alignment" : 4, + "linker_set_key" : "float *", + "name" : "float *", + "referenced_type" : "type-3", + "self_type" : "type-7", "size" : 4, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" } @@ -268,52 +268,6 @@ [ { "alignment" : 4, - "fields" : - [ - { - "access" : "private", - "field_name" : "mSpeakderId", - "field_offset" : 32, - "referenced_type" : "type-2" - } - ], - "linker_set_key" : "SuperSpeaker", - "name" : "SuperSpeaker", - "record_kind" : "class", - "referenced_type" : "type-1", - "self_type" : "type-1", - "size" : 8, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", - "unique_id" : "_ZTS12SuperSpeaker", - "vtable_components" : - [ - { - "kind" : "offset_to_top" - }, - { - "kind" : "rtti", - "mangled_component_name" : "_ZTI12SuperSpeaker" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" - }, - { - "kind" : "complete_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" - }, - { - "kind" : "deleting_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" - } - ] - }, - { - "alignment" : 4, "base_specifiers" : [ { @@ -406,6 +360,52 @@ "mangled_component_name" : "_ZN16LowVolumeSpeakerD0Ev" } ] + }, + { + "alignment" : 4, + "fields" : + [ + { + "access" : "private", + "field_name" : "mSpeakderId", + "field_offset" : 32, + "referenced_type" : "type-2" + } + ], + "linker_set_key" : "SuperSpeaker", + "name" : "SuperSpeaker", + "record_kind" : "class", + "referenced_type" : "type-1", + "self_type" : "type-1", + "size" : 8, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", + "unique_id" : "_ZTS12SuperSpeaker", + "vtable_components" : + [ + { + "kind" : "offset_to_top" + }, + { + "kind" : "rtti", + "mangled_component_name" : "_ZTI12SuperSpeaker" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" + }, + { + "kind" : "complete_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" + }, + { + "kind" : "deleting_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" + } + ] } ], "rvalue_reference_types" : [] diff --git a/vndk/tools/header-checker/tests/reference_dumps/mips/libpure_virtual_function.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/mips/libpure_virtual_function.so.lsdump index 29a106d81..9040218ae 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/mips/libpure_virtual_function.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/mips/libpure_virtual_function.so.lsdump @@ -1,12 +1,17 @@ record_types { type_info { - name: "PureVirtualBase" + name: "DerivedBar" size: 4 alignment: 4 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase" - self_type: "type-1" + linker_set_key: "DerivedBar" + self_type: "type-4" + } + base_specifiers { + referenced_type: "type-1" + is_virtual: false + access: public_access } vtable_layout { vtable_components { @@ -17,55 +22,50 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI15PureVirtualBase" + mangled_component_name: "_ZTI10DerivedBar" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD1Ev" + mangled_component_name: "_ZN10DerivedBarD1Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD0Ev" + mangled_component_name: "_ZN10DerivedBarD0Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" + mangled_component_name: "_ZN10DerivedBar8foo_pureEv" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" + mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" component_value: 0 - is_pure: false + is_pure: true } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS15PureVirtualBase" + unique_id: "_ZTS10DerivedBar" } } record_types { type_info { - name: "DerivedBar" + name: "PureVirtualBase" size: 4 alignment: 4 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar" - self_type: "type-4" - } - base_specifiers { referenced_type: "type-1" - is_virtual: false - access: public_access + source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" + linker_set_key: "PureVirtualBase" + self_type: "type-1" } vtable_layout { vtable_components { @@ -76,61 +76,61 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI10DerivedBar" + mangled_component_name: "_ZTI15PureVirtualBase" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN10DerivedBarD1Ev" + mangled_component_name: "_ZN15PureVirtualBaseD1Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN10DerivedBarD0Ev" + mangled_component_name: "_ZN15PureVirtualBaseD0Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar8foo_pureEv" + mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" + mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" component_value: 0 - is_pure: true + is_pure: false } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS10DerivedBar" + unique_id: "_ZTS15PureVirtualBase" } } pointer_types { type_info { - name: "PureVirtualBase *" + name: "DerivedBar *" size: 4 alignment: 4 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase *" - self_type: "type-3" + linker_set_key: "DerivedBar *" + self_type: "type-5" } } pointer_types { type_info { - name: "DerivedBar *" + name: "PureVirtualBase *" size: 4 alignment: 4 - referenced_type: "type-4" + referenced_type: "type-1" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar *" - self_type: "type-5" + linker_set_key: "PureVirtualBase *" + self_type: "type-3" } } builtin_types { diff --git a/vndk/tools/header-checker/tests/reference_dumps/mips64/libgolden_cpp_json.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/mips64/libgolden_cpp_json.so.lsdump index 3732e9382..83e05383d 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/mips64/libgolden_cpp_json.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/mips64/libgolden_cpp_json.so.lsdump @@ -228,15 +228,6 @@ [ { "alignment" : 8, - "linker_set_key" : "SuperSpeaker *", - "name" : "SuperSpeaker *", - "referenced_type" : "type-1", - "self_type" : "type-9", - "size" : 8, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" - }, - { - "alignment" : 8, "linker_set_key" : "HighVolumeSpeaker *", "name" : "HighVolumeSpeaker *", "referenced_type" : "type-11", @@ -246,19 +237,28 @@ }, { "alignment" : 8, - "linker_set_key" : "float *", - "name" : "float *", - "referenced_type" : "type-3", - "self_type" : "type-7", + "linker_set_key" : "LowVolumeSpeaker *", + "name" : "LowVolumeSpeaker *", + "referenced_type" : "type-5", + "self_type" : "type-4", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" }, { "alignment" : 8, - "linker_set_key" : "LowVolumeSpeaker *", - "name" : "LowVolumeSpeaker *", - "referenced_type" : "type-5", - "self_type" : "type-4", + "linker_set_key" : "SuperSpeaker *", + "name" : "SuperSpeaker *", + "referenced_type" : "type-1", + "self_type" : "type-9", + "size" : 8, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" + }, + { + "alignment" : 8, + "linker_set_key" : "float *", + "name" : "float *", + "referenced_type" : "type-3", + "self_type" : "type-7", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" } @@ -268,52 +268,6 @@ [ { "alignment" : 8, - "fields" : - [ - { - "access" : "private", - "field_name" : "mSpeakderId", - "field_offset" : 64, - "referenced_type" : "type-2" - } - ], - "linker_set_key" : "SuperSpeaker", - "name" : "SuperSpeaker", - "record_kind" : "class", - "referenced_type" : "type-1", - "self_type" : "type-1", - "size" : 16, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", - "unique_id" : "_ZTS12SuperSpeaker", - "vtable_components" : - [ - { - "kind" : "offset_to_top" - }, - { - "kind" : "rtti", - "mangled_component_name" : "_ZTI12SuperSpeaker" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" - }, - { - "kind" : "complete_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" - }, - { - "kind" : "deleting_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" - } - ] - }, - { - "alignment" : 8, "base_specifiers" : [ { @@ -406,6 +360,52 @@ "mangled_component_name" : "_ZN16LowVolumeSpeakerD0Ev" } ] + }, + { + "alignment" : 8, + "fields" : + [ + { + "access" : "private", + "field_name" : "mSpeakderId", + "field_offset" : 64, + "referenced_type" : "type-2" + } + ], + "linker_set_key" : "SuperSpeaker", + "name" : "SuperSpeaker", + "record_kind" : "class", + "referenced_type" : "type-1", + "self_type" : "type-1", + "size" : 16, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", + "unique_id" : "_ZTS12SuperSpeaker", + "vtable_components" : + [ + { + "kind" : "offset_to_top" + }, + { + "kind" : "rtti", + "mangled_component_name" : "_ZTI12SuperSpeaker" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" + }, + { + "kind" : "complete_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" + }, + { + "kind" : "deleting_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" + } + ] } ], "rvalue_reference_types" : [] diff --git a/vndk/tools/header-checker/tests/reference_dumps/mips64/libpure_virtual_function.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/mips64/libpure_virtual_function.so.lsdump index 573df854e..bedbba33f 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/mips64/libpure_virtual_function.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/mips64/libpure_virtual_function.so.lsdump @@ -1,12 +1,17 @@ record_types { type_info { - name: "PureVirtualBase" + name: "DerivedBar" size: 8 alignment: 8 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase" - self_type: "type-1" + linker_set_key: "DerivedBar" + self_type: "type-4" + } + base_specifiers { + referenced_type: "type-1" + is_virtual: false + access: public_access } vtable_layout { vtable_components { @@ -17,55 +22,50 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI15PureVirtualBase" + mangled_component_name: "_ZTI10DerivedBar" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD1Ev" + mangled_component_name: "_ZN10DerivedBarD1Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD0Ev" + mangled_component_name: "_ZN10DerivedBarD0Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" + mangled_component_name: "_ZN10DerivedBar8foo_pureEv" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" + mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" component_value: 0 - is_pure: false + is_pure: true } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS15PureVirtualBase" + unique_id: "_ZTS10DerivedBar" } } record_types { type_info { - name: "DerivedBar" + name: "PureVirtualBase" size: 8 alignment: 8 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar" - self_type: "type-4" - } - base_specifiers { referenced_type: "type-1" - is_virtual: false - access: public_access + source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" + linker_set_key: "PureVirtualBase" + self_type: "type-1" } vtable_layout { vtable_components { @@ -76,61 +76,61 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI10DerivedBar" + mangled_component_name: "_ZTI15PureVirtualBase" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN10DerivedBarD1Ev" + mangled_component_name: "_ZN15PureVirtualBaseD1Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN10DerivedBarD0Ev" + mangled_component_name: "_ZN15PureVirtualBaseD0Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar8foo_pureEv" + mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" + mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" component_value: 0 - is_pure: true + is_pure: false } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS10DerivedBar" + unique_id: "_ZTS15PureVirtualBase" } } pointer_types { type_info { - name: "PureVirtualBase *" + name: "DerivedBar *" size: 8 alignment: 8 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase *" - self_type: "type-3" + linker_set_key: "DerivedBar *" + self_type: "type-5" } } pointer_types { type_info { - name: "DerivedBar *" + name: "PureVirtualBase *" size: 8 alignment: 8 - referenced_type: "type-4" + referenced_type: "type-1" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar *" - self_type: "type-5" + linker_set_key: "PureVirtualBase *" + self_type: "type-3" } } builtin_types { diff --git a/vndk/tools/header-checker/tests/reference_dumps/x86/libgolden_cpp_json.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/x86/libgolden_cpp_json.so.lsdump index 81603fc92..f102bf251 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/x86/libgolden_cpp_json.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/x86/libgolden_cpp_json.so.lsdump @@ -228,15 +228,6 @@ [ { "alignment" : 4, - "linker_set_key" : "SuperSpeaker *", - "name" : "SuperSpeaker *", - "referenced_type" : "type-1", - "self_type" : "type-9", - "size" : 4, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" - }, - { - "alignment" : 4, "linker_set_key" : "HighVolumeSpeaker *", "name" : "HighVolumeSpeaker *", "referenced_type" : "type-11", @@ -246,19 +237,28 @@ }, { "alignment" : 4, - "linker_set_key" : "float *", - "name" : "float *", - "referenced_type" : "type-3", - "self_type" : "type-7", + "linker_set_key" : "LowVolumeSpeaker *", + "name" : "LowVolumeSpeaker *", + "referenced_type" : "type-5", + "self_type" : "type-4", "size" : 4, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" }, { "alignment" : 4, - "linker_set_key" : "LowVolumeSpeaker *", - "name" : "LowVolumeSpeaker *", - "referenced_type" : "type-5", - "self_type" : "type-4", + "linker_set_key" : "SuperSpeaker *", + "name" : "SuperSpeaker *", + "referenced_type" : "type-1", + "self_type" : "type-9", + "size" : 4, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" + }, + { + "alignment" : 4, + "linker_set_key" : "float *", + "name" : "float *", + "referenced_type" : "type-3", + "self_type" : "type-7", "size" : 4, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" } @@ -268,52 +268,6 @@ [ { "alignment" : 4, - "fields" : - [ - { - "access" : "private", - "field_name" : "mSpeakderId", - "field_offset" : 32, - "referenced_type" : "type-2" - } - ], - "linker_set_key" : "SuperSpeaker", - "name" : "SuperSpeaker", - "record_kind" : "class", - "referenced_type" : "type-1", - "self_type" : "type-1", - "size" : 8, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", - "unique_id" : "_ZTS12SuperSpeaker", - "vtable_components" : - [ - { - "kind" : "offset_to_top" - }, - { - "kind" : "rtti", - "mangled_component_name" : "_ZTI12SuperSpeaker" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" - }, - { - "kind" : "complete_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" - }, - { - "kind" : "deleting_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" - } - ] - }, - { - "alignment" : 4, "base_specifiers" : [ { @@ -406,6 +360,52 @@ "mangled_component_name" : "_ZN16LowVolumeSpeakerD0Ev" } ] + }, + { + "alignment" : 4, + "fields" : + [ + { + "access" : "private", + "field_name" : "mSpeakderId", + "field_offset" : 32, + "referenced_type" : "type-2" + } + ], + "linker_set_key" : "SuperSpeaker", + "name" : "SuperSpeaker", + "record_kind" : "class", + "referenced_type" : "type-1", + "self_type" : "type-1", + "size" : 8, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", + "unique_id" : "_ZTS12SuperSpeaker", + "vtable_components" : + [ + { + "kind" : "offset_to_top" + }, + { + "kind" : "rtti", + "mangled_component_name" : "_ZTI12SuperSpeaker" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" + }, + { + "kind" : "complete_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" + }, + { + "kind" : "deleting_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" + } + ] } ], "rvalue_reference_types" : [] diff --git a/vndk/tools/header-checker/tests/reference_dumps/x86/libpure_virtual_function.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/x86/libpure_virtual_function.so.lsdump index 29a106d81..9040218ae 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/x86/libpure_virtual_function.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/x86/libpure_virtual_function.so.lsdump @@ -1,12 +1,17 @@ record_types { type_info { - name: "PureVirtualBase" + name: "DerivedBar" size: 4 alignment: 4 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase" - self_type: "type-1" + linker_set_key: "DerivedBar" + self_type: "type-4" + } + base_specifiers { + referenced_type: "type-1" + is_virtual: false + access: public_access } vtable_layout { vtable_components { @@ -17,55 +22,50 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI15PureVirtualBase" + mangled_component_name: "_ZTI10DerivedBar" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD1Ev" + mangled_component_name: "_ZN10DerivedBarD1Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD0Ev" + mangled_component_name: "_ZN10DerivedBarD0Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" + mangled_component_name: "_ZN10DerivedBar8foo_pureEv" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" + mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" component_value: 0 - is_pure: false + is_pure: true } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS15PureVirtualBase" + unique_id: "_ZTS10DerivedBar" } } record_types { type_info { - name: "DerivedBar" + name: "PureVirtualBase" size: 4 alignment: 4 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar" - self_type: "type-4" - } - base_specifiers { referenced_type: "type-1" - is_virtual: false - access: public_access + source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" + linker_set_key: "PureVirtualBase" + self_type: "type-1" } vtable_layout { vtable_components { @@ -76,61 +76,61 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI10DerivedBar" + mangled_component_name: "_ZTI15PureVirtualBase" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN10DerivedBarD1Ev" + mangled_component_name: "_ZN15PureVirtualBaseD1Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN10DerivedBarD0Ev" + mangled_component_name: "_ZN15PureVirtualBaseD0Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar8foo_pureEv" + mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" + mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" component_value: 0 - is_pure: true + is_pure: false } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS10DerivedBar" + unique_id: "_ZTS15PureVirtualBase" } } pointer_types { type_info { - name: "PureVirtualBase *" + name: "DerivedBar *" size: 4 alignment: 4 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase *" - self_type: "type-3" + linker_set_key: "DerivedBar *" + self_type: "type-5" } } pointer_types { type_info { - name: "DerivedBar *" + name: "PureVirtualBase *" size: 4 alignment: 4 - referenced_type: "type-4" + referenced_type: "type-1" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar *" - self_type: "type-5" + linker_set_key: "PureVirtualBase *" + self_type: "type-3" } } builtin_types { diff --git a/vndk/tools/header-checker/tests/reference_dumps/x86_64/libgolden_cpp_json.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/x86_64/libgolden_cpp_json.so.lsdump index 3732e9382..83e05383d 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/x86_64/libgolden_cpp_json.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/x86_64/libgolden_cpp_json.so.lsdump @@ -228,15 +228,6 @@ [ { "alignment" : 8, - "linker_set_key" : "SuperSpeaker *", - "name" : "SuperSpeaker *", - "referenced_type" : "type-1", - "self_type" : "type-9", - "size" : 8, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" - }, - { - "alignment" : 8, "linker_set_key" : "HighVolumeSpeaker *", "name" : "HighVolumeSpeaker *", "referenced_type" : "type-11", @@ -246,19 +237,28 @@ }, { "alignment" : 8, - "linker_set_key" : "float *", - "name" : "float *", - "referenced_type" : "type-3", - "self_type" : "type-7", + "linker_set_key" : "LowVolumeSpeaker *", + "name" : "LowVolumeSpeaker *", + "referenced_type" : "type-5", + "self_type" : "type-4", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" }, { "alignment" : 8, - "linker_set_key" : "LowVolumeSpeaker *", - "name" : "LowVolumeSpeaker *", - "referenced_type" : "type-5", - "self_type" : "type-4", + "linker_set_key" : "SuperSpeaker *", + "name" : "SuperSpeaker *", + "referenced_type" : "type-1", + "self_type" : "type-9", + "size" : 8, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h" + }, + { + "alignment" : 8, + "linker_set_key" : "float *", + "name" : "float *", + "referenced_type" : "type-3", + "self_type" : "type-7", "size" : 8, "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/low_volume_speaker.h" } @@ -268,52 +268,6 @@ [ { "alignment" : 8, - "fields" : - [ - { - "access" : "private", - "field_name" : "mSpeakderId", - "field_offset" : 64, - "referenced_type" : "type-2" - } - ], - "linker_set_key" : "SuperSpeaker", - "name" : "SuperSpeaker", - "record_kind" : "class", - "referenced_type" : "type-1", - "self_type" : "type-1", - "size" : 16, - "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", - "unique_id" : "_ZTS12SuperSpeaker", - "vtable_components" : - [ - { - "kind" : "offset_to_top" - }, - { - "kind" : "rtti", - "mangled_component_name" : "_ZTI12SuperSpeaker" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" - }, - { - "is_pure" : true, - "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" - }, - { - "kind" : "complete_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" - }, - { - "kind" : "deleting_dtor_pointer", - "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" - } - ] - }, - { - "alignment" : 8, "base_specifiers" : [ { @@ -406,6 +360,52 @@ "mangled_component_name" : "_ZN16LowVolumeSpeakerD0Ev" } ] + }, + { + "alignment" : 8, + "fields" : + [ + { + "access" : "private", + "field_name" : "mSpeakderId", + "field_offset" : 64, + "referenced_type" : "type-2" + } + ], + "linker_set_key" : "SuperSpeaker", + "name" : "SuperSpeaker", + "record_kind" : "class", + "referenced_type" : "type-1", + "self_type" : "type-1", + "size" : 16, + "source_file" : "/development/vndk/tools/header-checker/tests/integration/cpp/gold/include/abstract_class.h", + "unique_id" : "_ZTS12SuperSpeaker", + "vtable_components" : + [ + { + "kind" : "offset_to_top" + }, + { + "kind" : "rtti", + "mangled_component_name" : "_ZTI12SuperSpeaker" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker5SpeakEv" + }, + { + "is_pure" : true, + "mangled_component_name" : "_ZN12SuperSpeaker6ListenEv" + }, + { + "kind" : "complete_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD1Ev" + }, + { + "kind" : "deleting_dtor_pointer", + "mangled_component_name" : "_ZN12SuperSpeakerD0Ev" + } + ] } ], "rvalue_reference_types" : [] diff --git a/vndk/tools/header-checker/tests/reference_dumps/x86_64/libpure_virtual_function.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/x86_64/libpure_virtual_function.so.lsdump index 573df854e..bedbba33f 100644 --- a/vndk/tools/header-checker/tests/reference_dumps/x86_64/libpure_virtual_function.so.lsdump +++ b/vndk/tools/header-checker/tests/reference_dumps/x86_64/libpure_virtual_function.so.lsdump @@ -1,12 +1,17 @@ record_types { type_info { - name: "PureVirtualBase" + name: "DerivedBar" size: 8 alignment: 8 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase" - self_type: "type-1" + linker_set_key: "DerivedBar" + self_type: "type-4" + } + base_specifiers { + referenced_type: "type-1" + is_virtual: false + access: public_access } vtable_layout { vtable_components { @@ -17,55 +22,50 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI15PureVirtualBase" + mangled_component_name: "_ZTI10DerivedBar" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD1Ev" + mangled_component_name: "_ZN10DerivedBarD1Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN15PureVirtualBaseD0Ev" + mangled_component_name: "_ZN10DerivedBarD0Ev" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" + mangled_component_name: "_ZN10DerivedBar8foo_pureEv" component_value: 0 - is_pure: true + is_pure: false } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" + mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" component_value: 0 - is_pure: false + is_pure: true } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS15PureVirtualBase" + unique_id: "_ZTS10DerivedBar" } } record_types { type_info { - name: "DerivedBar" + name: "PureVirtualBase" size: 8 alignment: 8 - referenced_type: "type-4" - source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar" - self_type: "type-4" - } - base_specifiers { referenced_type: "type-1" - is_virtual: false - access: public_access + source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" + linker_set_key: "PureVirtualBase" + self_type: "type-1" } vtable_layout { vtable_components { @@ -76,61 +76,61 @@ record_types { } vtable_components { kind: RTTI - mangled_component_name: "_ZTI10DerivedBar" + mangled_component_name: "_ZTI15PureVirtualBase" component_value: 0 is_pure: false } vtable_components { kind: CompleteDtorPointer - mangled_component_name: "_ZN10DerivedBarD1Ev" + mangled_component_name: "_ZN15PureVirtualBaseD1Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: DeletingDtorPointer - mangled_component_name: "_ZN10DerivedBarD0Ev" + mangled_component_name: "_ZN15PureVirtualBaseD0Ev" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar8foo_pureEv" + mangled_component_name: "_ZN15PureVirtualBase8foo_pureEv" component_value: 0 - is_pure: false + is_pure: true } vtable_components { kind: FunctionPointer - mangled_component_name: "_ZN10DerivedBar11foo_virtualEv" + mangled_component_name: "_ZN15PureVirtualBase11foo_virtualEv" component_value: 0 - is_pure: true + is_pure: false } } access: public_access record_kind: class_kind tag_info { - unique_id: "_ZTS10DerivedBar" + unique_id: "_ZTS15PureVirtualBase" } } pointer_types { type_info { - name: "PureVirtualBase *" + name: "DerivedBar *" size: 8 alignment: 8 - referenced_type: "type-1" + referenced_type: "type-4" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "PureVirtualBase *" - self_type: "type-3" + linker_set_key: "DerivedBar *" + self_type: "type-5" } } pointer_types { type_info { - name: "DerivedBar *" + name: "PureVirtualBase *" size: 8 alignment: 8 - referenced_type: "type-4" + referenced_type: "type-1" source_file: "/development/vndk/tools/header-checker/tests/integration/cpp/pure_virtual/include/header1.h" - linker_set_key: "DerivedBar *" - self_type: "type-5" + linker_set_key: "PureVirtualBase *" + self_type: "type-3" } } builtin_types { |
