diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp index e13d04f0a..ee3e2295c 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.cpp @@ -46,34 +46,16 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() { return status; } -template -static void AddTypesToMap(AbiElementMap *dst, - const abi_util::TextFormatToIRReader *tu, - KeyGetter get_key, ValueGetter get_value) { - AddToMap(dst, tu->GetRecordTypes(), get_key, get_value); - AddToMap(dst, tu->GetEnumTypes(), get_key, get_value); - AddToMap(dst, tu->GetPointerTypes(), get_key, get_value); - AddToMap(dst, tu->GetBuiltinTypes(), get_key, get_value); - AddToMap(dst, tu->GetArrayTypes(), get_key, get_value); - AddToMap(dst, tu->GetLvalueReferenceTypes(), get_key, get_value); - AddToMap(dst, tu->GetRvalueReferenceTypes(), get_key, get_value); - AddToMap(dst, tu->GetQualifiedTypes(), get_key, get_value); -} - abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( const abi_util::TextFormatToIRReader *old_tu, const abi_util::TextFormatToIRReader *new_tu, abi_util::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. - AbiElementMap old_types; - AbiElementMap new_types; - AddTypesToMap(&old_types, old_tu, - [](auto e) {return e->first;}, - [](auto e) {return &(e->second);}); - AddTypesToMap(&new_types, new_tu, - [](auto e) {return e->first;}, - [](auto e) {return &(e->second);}); + const AbiElementMap old_types = + old_tu->GetTypeGraph(); + const AbiElementMap new_types = + new_tu->GetTypeGraph(); // Collect fills in added, removed ,unsafe and safe function diffs. if (!CollectDynsymExportables(old_tu->GetFunctions(), new_tu->GetFunctions(), @@ -108,42 +90,68 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::CompareTUs( return combined_status; } +std::pair, + AbiElementMap> +HeaderAbiDiff::ExtractUserDefinedTypes( + const abi_util::TextFormatToIRReader *tu) { + AbiElementMap enum_types; + AbiElementMap 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 ODRListMapKey -> const Record(Enum)TypeIR *. + for (auto &it : tu->GetODRListMap()) { + auto &odr_list = it.second; + if (odr_list.size() != 1) { + continue; + } + const abi_util::TypeIR *type = *(odr_list.begin()); + switch (type->GetKind()) { + case abi_util::RecordTypeKind: + record_types.emplace(type->GetLinkerSetKey(), + static_cast(type)); + break; + case abi_util::EnumTypeKind: + enum_types.emplace(type->GetLinkerSetKey(), + static_cast(type)); + break; + default: + // Only user defined types should have ODR list entries. + assert(0); + } + } + return std::make_pair(std::move(enum_types), std::move(record_types)); +} + bool HeaderAbiDiff::CollectUserDefinedTypes( const abi_util::TextFormatToIRReader *old_tu, const abi_util::TextFormatToIRReader *new_tu, const AbiElementMap &old_types_map, const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper) { + + auto old_enums_and_records_extracted = ExtractUserDefinedTypes(old_tu); + auto new_enums_and_records_extracted = ExtractUserDefinedTypes(new_tu); + return CollectUserDefinedTypesInternal( - old_tu->GetRecordTypes(), new_tu->GetRecordTypes(), old_types_map, + old_enums_and_records_extracted.second, + new_enums_and_records_extracted.second, old_types_map, new_types_map, ir_diff_dumper) && - CollectUserDefinedTypesInternal(old_tu->GetEnumTypes(), - new_tu->GetEnumTypes(), old_types_map, - new_types_map, ir_diff_dumper); + CollectUserDefinedTypesInternal(old_enums_and_records_extracted.first, + new_enums_and_records_extracted.first, + old_types_map, new_types_map, + ir_diff_dumper); } template bool HeaderAbiDiff::CollectUserDefinedTypesInternal( - const AbiElementMap &old_ud_types, - const AbiElementMap &new_ud_types, + const AbiElementMap &old_ud_types_map, + const AbiElementMap &new_ud_types_map, const AbiElementMap &old_types_map, const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper) { - // No elf information for records and enums. - AbiElementMap old_ud_types_map; - AbiElementMap new_ud_types_map; - - abi_util::AddToMap(&old_ud_types_map, old_ud_types, - [](auto e) { return e->first;}, - [](auto e) {return &(e->second);}); - - abi_util::AddToMap(&new_ud_types_map, new_ud_types, - [](auto e) { return e->first;}, - [](auto e) {return &(e->second);}); - return Collect(old_ud_types_map, new_ud_types_map, nullptr, nullptr, - ir_diff_dumper) && + 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); @@ -182,7 +190,7 @@ bool HeaderAbiDiff::CollectDynsymExportables( if (!Collect(old_exportables_map, new_exportables_map, &old_elf_symbol_map, &new_elf_symbol_map, - ir_diff_dumper) || + ir_diff_dumper, old_types_map, new_types_map) || !CollectElfSymbols(old_elf_symbol_map, new_elf_symbol_map, ir_diff_dumper) || !PopulateCommonElements(old_exportables_map, new_exportables_map, @@ -206,13 +214,16 @@ bool HeaderAbiDiff::Collect( const AbiElementMap &new_elements_map, const AbiElementMap *old_elf_map, const AbiElementMap *new_elf_map, - abi_util::IRDiffDumper *ir_diff_dumper) { + abi_util::IRDiffDumper *ir_diff_dumper, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map) { if (!PopulateRemovedElements( old_elements_map, new_elements_map, new_elf_map, ir_diff_dumper, - abi_util::DiffMessageIR::Removed) || + abi_util::DiffMessageIR::Removed, old_types_map) || !PopulateRemovedElements(new_elements_map, old_elements_map, old_elf_map, ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind::Added)) { + abi_util::IRDiffDumper::DiffKind::Added, + new_types_map)) { llvm::errs() << "Populating functions in report failed\n"; return false; } @@ -253,10 +264,12 @@ bool HeaderAbiDiff::PopulateRemovedElements( const AbiElementMap &new_elements_map, const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind) { + abi_util::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap &removed_types_map) { std::vector removed_elements = abi_util::FindRemovedElements(old_elements_map, new_elements_map); - if (!DumpLoneElements(removed_elements, elf_map, ir_diff_dumper, diff_kind)) { + if (!DumpLoneElements(removed_elements, elf_map, ir_diff_dumper, diff_kind, + removed_types_map)) { llvm::errs() << "Dumping added / removed element to report failed\n"; return false; } @@ -289,7 +302,8 @@ bool HeaderAbiDiff::DumpLoneElements( std::vector &elements, const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind) { + abi_util::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap &types_map) { // If the record / enum has source file information, skip it. std::smatch source_file_match; std::regex source_file_regex(" at "); @@ -310,7 +324,9 @@ bool HeaderAbiDiff::DumpLoneElements( source_file_regex)) { continue; } - if (!ir_diff_dumper->AddLinkableMessageIR(element, diff_kind)) { + auto element_copy = *element; + ReplaceTypeIdsWithTypeNames(types_map, &element_copy); + if (!ir_diff_dumper->AddLinkableMessageIR(&element_copy, diff_kind)) { llvm::errs() << "Couldn't dump added /removed element\n"; return false; } 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 index a12031626..18e785dac 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff.h @@ -60,7 +60,9 @@ class HeaderAbiDiff { const AbiElementMap &new_elements_map, const AbiElementMap *old_elf_map, const AbiElementMap *new_elf_map, - abi_util::IRDiffDumper *ir_diff_dumper); + abi_util::IRDiffDumper *ir_diff_dumper, + const AbiElementMap &old_types_map, + const AbiElementMap &new_types_map); bool CollectElfSymbols( const AbiElementMap &old_symbols, @@ -78,7 +80,8 @@ class HeaderAbiDiff { const AbiElementMap &new_elements_map, const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind); + abi_util::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap &types_map); template bool PopulateCommonElements( @@ -102,7 +105,12 @@ class HeaderAbiDiff { std::vector &elements, const AbiElementMap *elf_map, abi_util::IRDiffDumper *ir_diff_dumper, - abi_util::IRDiffDumper::DiffKind diff_kind); + abi_util::IRDiffDumper::DiffKind diff_kind, + const AbiElementMap &old_types_map); + + std::pair, + AbiElementMap> + ExtractUserDefinedTypes(const abi_util::TextFormatToIRReader *tu); bool CollectUserDefinedTypes( const abi_util::TextFormatToIRReader *old_tu, @@ -113,8 +121,8 @@ class HeaderAbiDiff { template bool CollectUserDefinedTypesInternal( - const AbiElementMap &old_ud_types, - const AbiElementMap &new_ud_types, + const AbiElementMap &old_ud_types_map, + const AbiElementMap &new_ud_types_map, const AbiElementMap &old_types_map, const AbiElementMap &new_types_map, abi_util::IRDiffDumper *ir_diff_dumper); diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp index 4a556f3d3..b038d885d 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.cpp @@ -65,7 +65,12 @@ bool DiffWrapper::DumpDiff( DiffStatus access_diff = (oldp_->GetAccess() == newp_->GetAccess()) ? DiffStatus::no_diff : DiffStatus::direct_diff; if ((type_diff | access_diff) & DiffStatus::direct_diff) { - abi_util::GlobalVarDiffIR global_var_diff_ir(oldp_, newp_); + abi_util::GlobalVarIR old_global_var = *oldp_; + abi_util::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, + &new_global_var); global_var_diff_ir.SetName(oldp_->GetName()); return ir_diff_dumper_->AddDiffMessageIR(&global_var_diff_ir, Unwind(&type_queue), diff_kind); @@ -92,7 +97,11 @@ bool DiffWrapper::DumpDiff( if ((param_diffs == DiffStatus::direct_diff || return_type_diff == DiffStatus::direct_diff) || (oldp_->GetAccess() != newp_->GetAccess())) { - abi_util::FunctionDiffIR function_diff_ir(oldp_, newp_); + abi_util::FunctionIR old_function = *oldp_; + abi_util::FunctionIR new_function = *newp_; + ReplaceTypeIdsWithTypeNames(old_types_, &old_function); + ReplaceTypeIdsWithTypeNames(new_types_, &new_function); + abi_util::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); diff --git a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h index f49a50d6f..5376d2ffd 100644 --- a/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h +++ b/vndk/tools/header-checker/header-abi-diff/src/abi_diff_wrappers.h @@ -36,6 +36,7 @@ static bool IgnoreSymbol(const T *element, template class DiffWrapper : public AbiDiffHelper { + public: DiffWrapper(const T *oldp, const T *newp, abi_util::IRDiffDumper *ir_diff_dumper, @@ -44,7 +45,9 @@ class DiffWrapper : public AbiDiffHelper { std::set *type_cache) : AbiDiffHelper(old_types, new_types, type_cache, ir_diff_dumper), oldp_(oldp), newp_(newp) { } + bool DumpDiff(abi_util::IRDiffDumper::DiffKind diff_kind); + private: const T *oldp_; const T *newp_; diff --git a/vndk/tools/header-checker/header-abi-util/include/abi_diff_helpers.h b/vndk/tools/header-checker/header-abi-util/include/abi_diff_helpers.h index d9bc824e5..c83a19c09 100644 --- a/vndk/tools/header-checker/header-abi-util/include/abi_diff_helpers.h +++ b/vndk/tools/header-checker/header-abi-util/include/abi_diff_helpers.h @@ -102,6 +102,19 @@ class AbiDiffHelper { std::deque *type_queue, abi_util::IRDiffDumper::DiffKind diff_kind); + void ReplaceRemovedFieldTypeIdsWithTypeNames( + std::vector *removed_fields); + + void ReplaceDiffedFieldTypeIdsWithTypeNames( + abi_util::RecordFieldDiffIR *diffed_field); + + std::vector> + FixupDiffedFieldTypeIds( + const std::vector &field_diffs); + + std::vectorFixupRemovedFieldTypeIds( + const std::vector &fields_removed); + DiffStatusPair> CompareCommonRecordFields( const abi_util::RecordFieldIR *old_field, @@ -158,5 +171,8 @@ class AbiDiffHelper { AbiElementMap *local_to_global_type_id_map_ = nullptr; }; +void ReplaceTypeIdsWithTypeNames( + const AbiElementMap &type_graph, LinkableMessageIR *lm); + } // namespace abi_util #endif diff --git a/vndk/tools/header-checker/header-abi-util/include/ir_representation.h b/vndk/tools/header-checker/header-abi-util/include/ir_representation.h index 2b652ee9f..134dbeb77 100644 --- a/vndk/tools/header-checker/header-abi-util/include/ir_representation.h +++ b/vndk/tools/header-checker/header-abi-util/include/ir_representation.h @@ -1104,7 +1104,6 @@ class RecordFieldDiffIR { return new_field_; } - protected: const RecordFieldIR *old_field_; const RecordFieldIR *new_field_; }; diff --git a/vndk/tools/header-checker/header-abi-util/src/abi_diff_helpers.cpp b/vndk/tools/header-checker/header-abi-util/src/abi_diff_helpers.cpp index 6b3e88348..f0eec42f5 100644 --- a/vndk/tools/header-checker/header-abi-util/src/abi_diff_helpers.cpp +++ b/vndk/tools/header-checker/header-abi-util/src/abi_diff_helpers.cpp @@ -19,7 +19,7 @@ std::string Unwind(const std::deque *type_queue) { } static void TypeQueueCheckAndPushBack(std::deque *type_queue, - const std::string &str) { + const std::string &str) { if (type_queue) { type_queue->push_back(str); } @@ -51,6 +51,96 @@ static bool IsAccessDownGraded(abi_util::AccessSpecifierIR old_access, return access_downgraded; } +static std::string ConvertTypeIdToString( + const AbiElementMap &type_graph, + const std::string &type_id) { + auto it = type_graph.find(type_id); + if (it != type_graph.end()) { + return it->second->GetName(); + } + return "type-unexported"; +} + +template +static void ReplaceReferencesOtherTypeIdWithName( + const AbiElementMap &type_graph, + Container &to_fix_elements) { + for (auto &element : to_fix_elements) { + element.SetReferencedType( + ConvertTypeIdToString(type_graph, element.GetReferencedType())); + } +} + +static void ReplaceEnumTypeIRTypeIdsWithTypeNames( + const AbiElementMap &type_graph, + EnumTypeIR *enum_type_ir) { + // Replace underlying type. + enum_type_ir->SetUnderlyingType( + ConvertTypeIdToString(type_graph, enum_type_ir->GetUnderlyingType())); +} + +static void ReplaceRecordTypeIRTypeIdsWithTypeNames( + const AbiElementMap &type_graph, + RecordTypeIR *record_type_ir) { + // Replace Fields + ReplaceReferencesOtherTypeIdWithName(type_graph, + record_type_ir->GetFields()); + // Replace template parameters + ReplaceReferencesOtherTypeIdWithName(type_graph, + record_type_ir->GetTemplateElements()); + // Replace bases + ReplaceReferencesOtherTypeIdWithName(type_graph, + record_type_ir->GetBases()); +} + +static void ReplaceGlobalVarTypeIdsWithTypeNames( + const AbiElementMap &type_graph, + GlobalVarIR *global_var_ir) { + // Replace referenced type id. + global_var_ir->SetReferencedType( + ConvertTypeIdToString(type_graph, global_var_ir->GetReferencedType())); +} + +static void ReplaceFunctionTypeIdsWithTypeNames( + const AbiElementMap &type_graph, FunctionIR *function_ir) { + // Replace return type + function_ir->SetReturnType( + ConvertTypeIdToString(type_graph, function_ir->GetReturnType())); + // Replace function parameters + ReplaceReferencesOtherTypeIdWithName(type_graph, + function_ir->GetParameters()); + // Replace function template parameters + ReplaceReferencesOtherTypeIdWithName(type_graph, + function_ir->GetTemplateElements()); +} + +void ReplaceTypeIdsWithTypeNames( + const AbiElementMap &type_graph, + LinkableMessageIR *lm) { + switch (lm->GetKind()) { + case FunctionKind: + ReplaceFunctionTypeIdsWithTypeNames(type_graph, + static_cast(lm)); + break; + case GlobalVarKind: + ReplaceGlobalVarTypeIdsWithTypeNames(type_graph, + static_cast(lm)); + break; + case RecordTypeKind: + ReplaceRecordTypeIRTypeIdsWithTypeNames(type_graph, + static_cast(lm)); + + break; + case EnumTypeKind: + ReplaceEnumTypeIRTypeIdsWithTypeNames(type_graph, + static_cast(lm)); + break; + default: + // This method should not be called on any other LinkableMessage + assert(0); + } +} + void AbiDiffHelper::CompareEnumFields( const std::vector &old_fields, const std::vector &new_fields, @@ -98,8 +188,10 @@ DiffStatus AbiDiffHelper::CompareEnumTypes( } auto enum_type_diff_ir = std::make_unique(); enum_type_diff_ir->SetName(old_type->GetName()); - const std::string &old_underlying_type = old_type->GetUnderlyingType(); - const std::string &new_underlying_type = new_type->GetUnderlyingType(); + const std::string &old_underlying_type = + ConvertTypeIdToString(old_types_, old_type->GetUnderlyingType()); + const std::string &new_underlying_type = + ConvertTypeIdToString(new_types_, new_type->GetUnderlyingType()); if (old_underlying_type != new_underlying_type) { enum_type_diff_ir->SetUnderlyingTypeDiff( std::make_unique>( @@ -189,7 +281,7 @@ AbiDiffHelper::CompareRecordFields( std::deque *type_queue, abi_util::DiffMessageIR::DiffKind diff_kind) { std::pair, - std::vector> diffed_and_removed_fields; + std::vector> diffed_and_removed_fields; AbiElementMap old_fields_map; AbiElementMap new_fields_map; std::map old_fields_offset_map; @@ -235,6 +327,7 @@ AbiDiffHelper::CompareRecordFields( removed_fields.erase( std::remove_if(removed_fields.begin(), removed_fields.end(), predicate), removed_fields.end()); + diffed_and_removed_fields.second = std::move(removed_fields); std::vector> cf = @@ -292,7 +385,6 @@ void AbiDiffHelper::CompareTemplateInfo( std::deque *type_queue, abi_util::DiffMessageIR::DiffKind diff_kind) { uint32_t old_template_size = old_template_elements.size(); - assert(old_template_size == new_template_elements.size()); uint32_t i = 0; while (i < old_template_size) { const abi_util::TemplateElementIR &old_template_element = @@ -306,6 +398,57 @@ void AbiDiffHelper::CompareTemplateInfo( } } +template +static std::vector ConvertToDiffContainerVector( + std::vector> &nc_vector) { + std::vector cptr_vec; + for (auto &e : nc_vector) { + cptr_vec.emplace_back(&e.first, &e.second); + } + return cptr_vec; +} + +template +static std::vector ConvertToConstPtrVector( + std::vector &nc_vector) { + std::vector cptr_vec; + for (auto &e : nc_vector) { + cptr_vec.emplace_back(&e); + } + return cptr_vec; +} + +std::vector AbiDiffHelper::FixupRemovedFieldTypeIds( + const std::vector &removed_fields) { + std::vector 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]; + it.SetReferencedType( + ConvertTypeIdToString(old_types_, it.GetReferencedType())); + } + return removed_fields_dup; +} + +std::vector> +AbiDiffHelper::FixupDiffedFieldTypeIds( + const std::vector &field_diffs) { + std::vector> + 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; + old_field.SetReferencedType( + ConvertTypeIdToString(old_types_, old_field.GetReferencedType())); + new_field.SetReferencedType( + ConvertTypeIdToString(new_types_, new_field.GetReferencedType())); + } + return diffed_fields_dup; +} + DiffStatus AbiDiffHelper::CompareRecordTypes( const abi_util::RecordTypeIR *old_type, const abi_util::RecordTypeIR *new_type, @@ -342,32 +485,50 @@ DiffStatus AbiDiffHelper::CompareRecordTypes( std::make_unique( old_type->GetVTableLayout(), new_type->GetVTableLayout())); } + auto &old_fields_dup = old_type->GetFields(); + auto &new_fields_dup = new_type->GetFields(); + auto field_status_and_diffs = - CompareRecordFields(old_type->GetFields(), new_type->GetFields(), + CompareRecordFields(old_fields_dup, new_fields_dup, type_queue, diff_kind); // TODO: combine this with base class diffs as well. final_diff_status = final_diff_status | field_status_and_diffs.first; auto field_diffs = field_status_and_diffs.second; - record_type_diff_ir->SetFieldDiffs(std::move(field_diffs.first)); - record_type_diff_ir->SetFieldsRemoved(std::move(field_diffs.second)); - const std::vector &old_bases = - old_type->GetBases(); - const std::vector &new_bases = - new_type->GetBases(); - if (!CompareBaseSpecifiers(old_bases, new_bases, type_queue, diff_kind)) { + std::vector old_bases = old_type->GetBases(); + std::vector 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(old_bases, new_bases)); } - if (record_type_diff_ir->DiffExists() && - ir_diff_dumper_ && - !ir_diff_dumper_->AddDiffMessageIR(record_type_diff_ir.get(), - Unwind(type_queue), diff_kind)) { - llvm::errs() << "AddDiffMessage on record type failed\n"; - ::exit(1); - } // No need to add a dump for an extension since records can't be "extended". + if (ir_diff_dumper_) { + // Make copies of the fields removed and diffed, since we have to change + // type ids -> type strings. + std::vector> field_diff_dups = + FixupDiffedFieldTypeIds(field_diffs.first); + std::vector field_diffs_fixed = + ConvertToDiffContainerVector(field_diff_dups); + std::vector field_removed_dups = + FixupRemovedFieldTypeIds(field_diffs.second); + std::vector fields_removed_fixed = + ConvertToConstPtrVector(field_removed_dups); + + record_type_diff_ir->SetFieldDiffs(std::move(field_diffs_fixed)); + record_type_diff_ir->SetFieldsRemoved(std::move(fields_removed_fixed)); + if (record_type_diff_ir->DiffExists() && + !ir_diff_dumper_->AddDiffMessageIR(record_type_diff_ir.get(), + Unwind(type_queue), diff_kind)) { + llvm::errs() << "AddDiffMessage on record type failed\n"; + ::exit(1); + } // No need to add a dump for an extension since records can't be "extended". + } CompareTemplateInfo(old_type->GetTemplateElements(), new_type->GetTemplateElements(), type_queue, diff_kind); @@ -545,7 +706,8 @@ DiffStatus AbiDiffHelper::CompareAndDumpTypeDiff( if (!type_cache_->insert(old_type_id + new_type_id).second) { return DiffStatus::no_diff; } else { - TypeQueueCheckAndPushBack(type_queue, old_type_id); + TypeQueueCheckAndPushBack(type_queue, + ConvertTypeIdToString(old_types_,old_type_id)); } AbiElementMap::const_iterator old_it = old_types_.find(old_type_id);