Fix abi diffing to incporporate changes in type graphs.

We now need to convert from type ids to type names while adding a diff
message, since types don't have type names as references anymore.

Bug: 71486971

Test: tests/test.py test updation CL; all tests pass.

Test: tests/gen_all.py; manually diff between libcpp_gold.so.lsdump and
      libcpp_gold_member_diff.so.lsdump, diff is visually the same as
      before.

Test: build android source tree for aosp_arm64_ab; create reference
      dumps; rebuild; confirm no errors or warnings.

Change-Id: I17a3a1a02c5c2312e543a930ae3a1d9037e683b8
This commit is contained in:
Jayant Chowdhary
2018-01-22 12:50:40 -08:00
parent 3dc86c5263
commit 29738b5c14
7 changed files with 291 additions and 78 deletions

View File

@@ -46,34 +46,16 @@ abi_util::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() {
return status;
}
template <typename KeyGetter, typename ValueGetter>
static void AddTypesToMap(AbiElementMap<const abi_util::TypeIR *> *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<const abi_util::TypeIR *> old_types;
AbiElementMap<const abi_util::TypeIR *> 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<const abi_util::TypeIR *> old_types =
old_tu->GetTypeGraph();
const AbiElementMap<const abi_util::TypeIR *> 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<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;
// 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<const abi_util::RecordTypeIR *>(type));
break;
case abi_util::EnumTypeKind:
enum_types.emplace(type->GetLinkerSetKey(),
static_cast<const abi_util::EnumTypeIR *>(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<const abi_util::TypeIR *> &old_types_map,
const AbiElementMap<const abi_util::TypeIR *> &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 <typename T>
bool HeaderAbiDiff::CollectUserDefinedTypesInternal(
const AbiElementMap<T> &old_ud_types,
const AbiElementMap<T> &new_ud_types,
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) {
// No elf information for records and enums.
AbiElementMap<const T *> old_ud_types_map;
AbiElementMap<const T *> 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<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) {
abi_util::IRDiffDumper *ir_diff_dumper,
const AbiElementMap<const abi_util::TypeIR *> &old_types_map,
const AbiElementMap<const abi_util::TypeIR *> &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<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) {
abi_util::IRDiffDumper::DiffKind diff_kind,
const AbiElementMap<const abi_util::TypeIR *> &removed_types_map) {
std::vector<const T *> 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<const T *> &elements,
const AbiElementMap<const abi_util::ElfSymbolIR *> *elf_map,
abi_util::IRDiffDumper *ir_diff_dumper,
abi_util::IRDiffDumper::DiffKind diff_kind) {
abi_util::IRDiffDumper::DiffKind diff_kind,
const AbiElementMap<const abi_util::TypeIR *> &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;
}

View File

@@ -60,7 +60,9 @@ class HeaderAbiDiff {
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);
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,
@@ -78,7 +80,8 @@ class HeaderAbiDiff {
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);
abi_util::IRDiffDumper::DiffKind diff_kind,
const AbiElementMap<const abi_util::TypeIR *> &types_map);
template <typename T>
bool PopulateCommonElements(
@@ -102,7 +105,12 @@ class HeaderAbiDiff {
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);
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,
@@ -113,8 +121,8 @@ class HeaderAbiDiff {
template <typename T>
bool CollectUserDefinedTypesInternal(
const AbiElementMap<T> &old_ud_types,
const AbiElementMap<T> &new_ud_types,
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);

View File

@@ -65,7 +65,12 @@ 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::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<abi_util::FunctionIR>::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);

View File

@@ -36,6 +36,7 @@ static bool IgnoreSymbol(const T *element,
template <typename T>
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<std::string> *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_;

View File

@@ -102,6 +102,19 @@ class AbiDiffHelper {
std::deque<std::string> *type_queue,
abi_util::IRDiffDumper::DiffKind diff_kind);
void ReplaceRemovedFieldTypeIdsWithTypeNames(
std::vector<abi_util::RecordFieldIR *> *removed_fields);
void ReplaceDiffedFieldTypeIdsWithTypeNames(
abi_util::RecordFieldDiffIR *diffed_field);
std::vector<std::pair<abi_util::RecordFieldIR, abi_util::RecordFieldIR>>
FixupDiffedFieldTypeIds(
const std::vector<abi_util::RecordFieldDiffIR> &field_diffs);
std::vector<abi_util::RecordFieldIR>FixupRemovedFieldTypeIds(
const std::vector<const abi_util::RecordFieldIR *> &fields_removed);
DiffStatusPair<std::unique_ptr<abi_util::RecordFieldDiffIR>>
CompareCommonRecordFields(
const abi_util::RecordFieldIR *old_field,
@@ -158,5 +171,8 @@ class AbiDiffHelper {
AbiElementMap<MergeStatus> *local_to_global_type_id_map_ = nullptr;
};
void ReplaceTypeIdsWithTypeNames(
const AbiElementMap<const TypeIR *> &type_graph, LinkableMessageIR *lm);
} // namespace abi_util
#endif

View File

@@ -1104,7 +1104,6 @@ class RecordFieldDiffIR {
return new_field_;
}
protected:
const RecordFieldIR *old_field_;
const RecordFieldIR *new_field_;
};

View File

@@ -51,6 +51,96 @@ static bool IsAccessDownGraded(abi_util::AccessSpecifierIR old_access,
return access_downgraded;
}
static std::string ConvertTypeIdToString(
const AbiElementMap<const TypeIR *> &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 <typename Container>
static void ReplaceReferencesOtherTypeIdWithName(
const AbiElementMap<const TypeIR *> &type_graph,
Container &to_fix_elements) {
for (auto &element : to_fix_elements) {
element.SetReferencedType(
ConvertTypeIdToString(type_graph, element.GetReferencedType()));
}
}
static void ReplaceEnumTypeIRTypeIdsWithTypeNames(
const AbiElementMap<const TypeIR *> &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<const TypeIR *> &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<const TypeIR *> &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<const TypeIR *> &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<const TypeIR *> &type_graph,
LinkableMessageIR *lm) {
switch (lm->GetKind()) {
case FunctionKind:
ReplaceFunctionTypeIdsWithTypeNames(type_graph,
static_cast<FunctionIR *>(lm));
break;
case GlobalVarKind:
ReplaceGlobalVarTypeIdsWithTypeNames(type_graph,
static_cast<GlobalVarIR *>(lm));
break;
case RecordTypeKind:
ReplaceRecordTypeIRTypeIdsWithTypeNames(type_graph,
static_cast<RecordTypeIR *>(lm));
break;
case EnumTypeKind:
ReplaceEnumTypeIRTypeIdsWithTypeNames(type_graph,
static_cast<EnumTypeIR *>(lm));
break;
default:
// This method should not be called on any other LinkableMessage
assert(0);
}
}
void AbiDiffHelper::CompareEnumFields(
const std::vector<abi_util::EnumFieldIR> &old_fields,
const std::vector<abi_util::EnumFieldIR> &new_fields,
@@ -98,8 +188,10 @@ DiffStatus AbiDiffHelper::CompareEnumTypes(
}
auto enum_type_diff_ir = std::make_unique<abi_util::EnumTypeDiffIR>();
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<std::pair<std::string, std::string>>(
@@ -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<std::pair<
const abi_util::RecordFieldIR *, const abi_util::RecordFieldIR *>> cf =
@@ -292,7 +385,6 @@ void AbiDiffHelper::CompareTemplateInfo(
std::deque<std::string> *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 <typename DiffContainer, typename T>
static std::vector<DiffContainer> ConvertToDiffContainerVector(
std::vector<std::pair<T, T>> &nc_vector) {
std::vector<DiffContainer> cptr_vec;
for (auto &e : nc_vector) {
cptr_vec.emplace_back(&e.first, &e.second);
}
return cptr_vec;
}
template <typename T>
static std::vector<const T*> ConvertToConstPtrVector(
std::vector<T> &nc_vector) {
std::vector<const T*> cptr_vec;
for (auto &e : nc_vector) {
cptr_vec.emplace_back(&e);
}
return cptr_vec;
}
std::vector<abi_util::RecordFieldIR> AbiDiffHelper::FixupRemovedFieldTypeIds(
const std::vector<const abi_util::RecordFieldIR *> &removed_fields) {
std::vector<abi_util::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];
it.SetReferencedType(
ConvertTypeIdToString(old_types_, it.GetReferencedType()));
}
return removed_fields_dup;
}
std::vector<std::pair<abi_util::RecordFieldIR, abi_util::RecordFieldIR>>
AbiDiffHelper::FixupDiffedFieldTypeIds(
const std::vector<abi_util::RecordFieldDiffIR> &field_diffs) {
std::vector<std::pair<abi_util::RecordFieldIR, abi_util::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;
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<abi_util::VTableLayoutDiffIR>(
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<abi_util::CXXBaseSpecifierIR> &old_bases =
old_type->GetBases();
const std::vector<abi_util::CXXBaseSpecifierIR> &new_bases =
new_type->GetBases();
if (!CompareBaseSpecifiers(old_bases, new_bases, type_queue, diff_kind)) {
std::vector<abi_util::CXXBaseSpecifierIR> old_bases = old_type->GetBases();
std::vector<abi_util::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,
new_bases));
}
if (ir_diff_dumper_) {
// Make copies of the fields removed and diffed, since we have to change
// type ids -> type strings.
std::vector<std::pair<RecordFieldIR, RecordFieldIR>> field_diff_dups =
FixupDiffedFieldTypeIds(field_diffs.first);
std::vector<abi_util::RecordFieldDiffIR> field_diffs_fixed =
ConvertToDiffContainerVector<abi_util::RecordFieldDiffIR,
abi_util::RecordFieldIR>(field_diff_dups);
std::vector<abi_util::RecordFieldIR> field_removed_dups =
FixupRemovedFieldTypeIds(field_diffs.second);
std::vector<const abi_util::RecordFieldIR *> 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_ &&
!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 abi_util::TypeIR *>::const_iterator old_it =
old_types_.find(old_type_id);