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:
@@ -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) {
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user