Look up referenced types' compilation unit paths when linking ABI dumps

When header-abi-linker merges a pointer, reference, array, or qualified
type, it looks up the referenced type's compilation unit path, and uses
the path to distinguish multiple definitions of the type as well as the
types referencing it.

Test: ./test.py
Bug: 147396457
Change-Id: If6b35e941f9aa03616b236289450c9b10062b719
This commit is contained in:
Hsin-Yi Chen
2020-03-21 01:55:48 +08:00
parent f9e7b620ff
commit a6bd6ed7bc
3 changed files with 51 additions and 24 deletions

View File

@@ -349,6 +349,43 @@ MergeStatus ModuleMerger::MergeReferencingTypeInternalAndUpdateParent(
}
static bool IsReferencingType(LinkableMessageKind kind) {
switch (kind) {
case PointerTypeKind:
case QualifiedTypeKind:
case ArrayTypeKind:
case LvalueReferenceTypeKind:
case RvalueReferenceTypeKind:
return true;
case RecordTypeKind:
case EnumTypeKind:
case BuiltinTypeKind:
case FunctionTypeKind:
case FunctionKind:
case GlobalVarKind:
return false;
}
}
// Trace the referenced type until reaching a RecordTypeIR, EnumTypeIR,
// FunctionTypeIR, or BuiltinTypeIR. Return nullptr if the referenced type is
// undefined or built-in.
static const TypeIR *DereferenceType(const ModuleIR &module,
const TypeIR *type_ir) {
auto &type_graph = module.GetTypeGraph();
while (IsReferencingType(type_ir->GetKind())) {
auto it = type_graph.find(type_ir->GetReferencedType());
// The referenced type is undefined in the module.
if (it == type_graph.end()) {
return nullptr;
}
type_ir = it->second;
}
return type_ir;
}
// 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 ModuleMerger::MergeReferencingType(
@@ -360,7 +397,15 @@ MergeStatus ModuleMerger::MergeReferencingType(
std::string added_type_id = addend_node->GetSelfType();
auto type_id_it = module_->type_graph_.find(added_type_id);
if (type_id_it != module_->type_graph_.end()) {
added_type_id = AllocateNewTypeId(added_type_id, addend);
const TypeIR *final_referenced_type = DereferenceType(addend, addend_node);
if (final_referenced_type != nullptr) {
std::string compilation_unit_path =
addend.GetCompilationUnitPath(final_referenced_type);
// The path is empty for built-in types.
if (compilation_unit_path != "") {
added_type_id = added_type_id + "#ODR:" + compilation_unit_path;
}
}
}
// Add the added record type to the local_to_global_type_id_map.
@@ -507,12 +552,6 @@ void ModuleMerger::MergeFunction(
}
std::string ModuleMerger::AllocateNewTypeId(const std::string &addend_type_id,
const ModuleIR &addend_module) {
return addend_type_id + "#ODR:" + addend_module.GetCompilationUnitPath();
}
void ModuleMerger::MergeGlobalVariable(
const GlobalVarIR *addend_node, const ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) {

View File

@@ -144,9 +144,6 @@ private:
const TypeIR *addend_type, const ModuleIR &addend,
AbiElementMap<MergeStatus> *merged_types_cache);
std::string AllocateNewTypeId(const std::string &addend_type_id,
const ModuleIR &addend_module);
private:
std::unique_ptr<ModuleIR> module_;

View File

@@ -67,7 +67,7 @@
"linker_set_key" : "_ZTIP6Struct",
"name" : "Struct *",
"referenced_type" : "_ZTI6Struct#ODR:/def2.h.sdump",
"self_type" : "_ZTIP6Struct#ODR:",
"self_type" : "_ZTIP6Struct#ODR:/def2.h.sdump",
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h"
},
@@ -80,15 +80,6 @@
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def1.h"
},
{
"alignment" : 8,
"linker_set_key" : "_ZTIPK6Opaque",
"name" : "const Opaque *",
"referenced_type" : "_ZTIK6Opaque#ODR:",
"self_type" : "_ZTIPK6Opaque#ODR:",
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h"
},
{
"alignment" : 8,
"linker_set_key" : "_ZTIPK6Struct",
@@ -102,8 +93,8 @@
"alignment" : 8,
"linker_set_key" : "_ZTIPK6Struct",
"name" : "const Struct *",
"referenced_type" : "_ZTIK6Struct#ODR:",
"self_type" : "_ZTIPK6Struct#ODR:",
"referenced_type" : "_ZTIK6Struct#ODR:/def2.h.sdump",
"self_type" : "_ZTIPK6Struct#ODR:/def2.h.sdump",
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h"
}
@@ -124,7 +115,7 @@
"linker_set_key" : "_ZTIK6Struct",
"name" : "const Struct",
"referenced_type" : "_ZTI6Struct#ODR:/def2.h.sdump",
"self_type" : "_ZTIK6Struct#ODR:",
"self_type" : "_ZTIK6Struct#ODR:/def2.h.sdump",
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h"
},
@@ -163,7 +154,7 @@
[
{
"field_name" : "member2",
"referenced_type" : "_ZTIP6Struct#ODR:"
"referenced_type" : "_ZTIP6Struct#ODR:/def2.h.sdump"
}
],
"linker_set_key" : "_ZTI6Struct",