Store the sdump path for each type definition when linking ABI dumps
This commit adds sdump paths to ModuleIR::odr_list_map_. It maps type ID
to list of TypeDefinitions. A TypeDefinition consists of a TypeIR and
the sdump path where the type is defined. The path is used to
distinguish the definitions of the type in different source files.
When header-abi-linker merges modules, the compilation unit paths are
copied to the merged module. Thus, the paths are not lost when the
merged module is merged to another one.
Test: ./test.py
Bug: 147396457
Change-Id: I72a9502b4e81f8ead10c8439af76aea86e3bc3f3
diff --git a/vndk/tools/header-checker/src/diff/abi_diff.cpp b/vndk/tools/header-checker/src/diff/abi_diff.cpp
index 3136e1e..0dd4439 100644
--- a/vndk/tools/header-checker/src/diff/abi_diff.cpp
+++ b/vndk/tools/header-checker/src/diff/abi_diff.cpp
@@ -113,7 +113,7 @@
if (odr_list.size() != 1) {
continue;
}
- const repr::TypeIR *type = *(odr_list.begin());
+ const repr::TypeIR *type = odr_list.begin()->type_ir_;
const repr::RecordTypeIR *record_type = nullptr;
switch (type->GetKind()) {
case repr::RecordTypeKind:
diff --git a/vndk/tools/header-checker/src/linker/module_merger.cpp b/vndk/tools/header-checker/src/linker/module_merger.cpp
index 85ad5de..54e13af 100644
--- a/vndk/tools/header-checker/src/linker/module_merger.cpp
+++ b/vndk/tools/header-checker/src/linker/module_merger.cpp
@@ -67,7 +67,8 @@
// Compare each user-defined type with the latest input user-defined type.
// If there is a match, re-use the existing user-defined type.
- for (auto &contender_ud : it->second) {
+ for (auto &definition : it->second) {
+ const TypeIR *contender_ud = definition.type_ir_;
DiffStatus result = diff_helper.CompareAndDumpTypeDiff(
contender_ud->GetSelfType(), ud_type->GetSelfType());
if (result == DiffStatus::no_diff) {
@@ -81,7 +82,7 @@
#ifdef DEBUG
llvm::errs() << "ODR violation detected for: " << ud_type->GetName() << "\n";
#endif
- return MergeStatus(true, (*(it->second.begin()))->GetSelfType());
+ return MergeStatus(true, it->second.begin()->type_ir_->GetSelfType());
}
@@ -199,10 +200,13 @@
const T *addend_node, const ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map,
AbiElementMap<T> *specific_type_map) {
+ const std::string addend_compilation_unit_path =
+ addend.GetCompilationUnitPath(addend_node);
+ assert(addend_compilation_unit_path != "");
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);
+ added_type_id = added_type_id + "#ODR:" + addend_compilation_unit_path;
}
// Add the ud-type with type-id to the type_graph_, since if there are generic
@@ -217,7 +221,7 @@
// Add to facilitate ODR checking.
const std::string &key = GetODRListMapKey(&(it->second));
MergeStatus type_merge_status = MergeStatus(true, added_type_id);
- module_->AddToODRListMap(key, &(it->second));
+ module_->AddToODRListMap(key, &(it->second), addend_compilation_unit_path);
local_to_global_type_id_map->emplace(addend_node->GetSelfType(),
type_merge_status);
return {type_merge_status, it};
diff --git a/vndk/tools/header-checker/src/repr/ir_representation.cpp b/vndk/tools/header-checker/src/repr/ir_representation.cpp
index 50d1bf9..6f512fd 100644
--- a/vndk/tools/header-checker/src/repr/ir_representation.cpp
+++ b/vndk/tools/header-checker/src/repr/ir_representation.cpp
@@ -109,7 +109,7 @@
auto it = AddToMapAndTypeGraph(
std::move(record_type), &record_types_, &type_graph_);
const std::string &key = GetODRListMapKey(&(it->second));
- AddToODRListMap(key, &(it->second));
+ AddToODRListMap(key, &(it->second), compilation_unit_path_);
}
@@ -120,7 +120,7 @@
auto it = AddToMapAndTypeGraph(
std::move(function_type), &function_types_, &type_graph_);
const std::string &key = GetODRListMapKey(&(it->second));
- AddToODRListMap(key, &(it->second));
+ AddToODRListMap(key, &(it->second), compilation_unit_path_);
}
@@ -131,7 +131,7 @@
auto it = AddToMapAndTypeGraph(
std::move(enum_type), &enum_types_, &type_graph_);
const std::string &key = GetODRListMapKey(&(it->second));
- AddToODRListMap(key, (&it->second));
+ AddToODRListMap(key, (&it->second), compilation_unit_path_);
}
@@ -197,6 +197,34 @@
}
+std::string ModuleIR::GetCompilationUnitPath(const TypeIR *type_ir) const {
+ std::string key;
+ switch (type_ir->GetKind()) {
+ case RecordTypeKind:
+ key = GetODRListMapKey(static_cast<const RecordTypeIR *>(type_ir));
+ break;
+ case EnumTypeKind:
+ key = GetODRListMapKey(static_cast<const EnumTypeIR *>(type_ir));
+ break;
+ case FunctionTypeKind:
+ key = GetODRListMapKey(static_cast<const FunctionTypeIR *>(type_ir));
+ break;
+ default:
+ return "";
+ }
+ auto it = odr_list_map_.find(key);
+ if (it == odr_list_map_.end()) {
+ return "";
+ }
+ for (const auto &definition : it->second) {
+ if (definition.type_ir_ == type_ir) {
+ return definition.compilation_unit_path_;
+ }
+ }
+ return "";
+}
+
+
bool ModuleIR::IsLinkableMessageInExportedHeaders(
const LinkableMessageIR *linkable_message) const {
if (exported_headers_ == nullptr || exported_headers_->empty()) {
diff --git a/vndk/tools/header-checker/src/repr/ir_representation.h b/vndk/tools/header-checker/src/repr/ir_representation.h
index 12ba97a..f74d3b7 100644
--- a/vndk/tools/header-checker/src/repr/ir_representation.h
+++ b/vndk/tools/header-checker/src/repr/ir_representation.h
@@ -37,9 +37,6 @@
template <typename T>
using AbiElementUnorderedMap = std::unordered_map<std::string, T>;
-template <typename T>
-using AbiElementList = std::list<T>;
-
enum TextFormatIR {
ProtobufTextFormat = 0,
Json = 1,
@@ -759,6 +756,16 @@
}
};
+class TypeDefinition {
+ public:
+ TypeDefinition(const TypeIR *type_ir,
+ const std::string *compilation_unit_path)
+ : type_ir_(type_ir), compilation_unit_path_(*compilation_unit_path) {}
+
+ const TypeIR *type_ir_;
+ const std::string &compilation_unit_path_;
+};
+
class ModuleIR {
public:
ModuleIR(const std::set<std::string> *exported_headers)
@@ -828,7 +835,7 @@
return type_graph_;
}
- const AbiElementUnorderedMap<std::list<const TypeIR *>> &
+ const AbiElementUnorderedMap<std::list<TypeDefinition>> &
GetODRListMap() const {
return odr_list_map_;
}
@@ -864,10 +871,19 @@
void AddElfObject(ElfObjectIR &&elf_object);
- void AddToODRListMap(const std::string &key, const TypeIR *value) {
+ // Find the compilation unit path of a RecordTypeIR, FunctionTypeIR, or
+ // EnumTypeIR in odr_list_map_. Return an empty string if the type is not in
+ // the map.
+ std::string GetCompilationUnitPath(const TypeIR *type_ir) const;
+
+ void AddToODRListMap(const std::string &key, const TypeIR *type_ir,
+ const std::string &compilation_unit_path) {
+ auto compilation_unit_path_it =
+ compilation_unit_paths_.emplace(compilation_unit_path).first;
auto map_it = odr_list_map_.find(key);
+ TypeDefinition value(type_ir, &*compilation_unit_path_it);
if (map_it == odr_list_map_.end()) {
- odr_list_map_.emplace(key, std::list<const TypeIR *>({value}));
+ odr_list_map_.emplace(key, std::list<TypeDefinition>({value}));
return;
}
odr_list_map_[key].emplace_back(value);
@@ -883,7 +899,6 @@
// File path to the compilation unit (*.sdump)
std::string compilation_unit_path_;
- AbiElementList<RecordTypeIR> record_types_list_;
AbiElementMap<FunctionIR> functions_;
AbiElementMap<GlobalVarIR> global_variables_;
AbiElementMap<RecordTypeIR> record_types_;
@@ -904,8 +919,13 @@
AbiElementMap<ElfObjectIR> elf_objects_;
// type-id -> LinkableMessageIR * map
AbiElementMap<const TypeIR *> type_graph_;
- // maps unique_id + source_file -> const TypeIR *
- AbiElementUnorderedMap<std::list<const TypeIR *>> odr_list_map_;
+ // maps unique_id + source_file -> TypeDefinition
+ AbiElementUnorderedMap<std::list<TypeDefinition>> odr_list_map_;
+
+
+ private:
+ // The compilation unit paths referenced by odr_list_map_;
+ std::set<std::string> compilation_unit_paths_;
const std::set<std::string> *exported_headers_;
};
diff --git a/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump b/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump
index ff2627d..fa5cfe5 100644
--- a/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump
+++ b/vndk/tools/header-checker/tests/reference_dumps/arm64/libmerge_multi_definitions.so.lsdump
@@ -66,7 +66,7 @@
"alignment" : 8,
"linker_set_key" : "_ZTIP6Struct",
"name" : "Struct *",
- "referenced_type" : "_ZTI6Struct#ODR:",
+ "referenced_type" : "_ZTI6Struct#ODR:/def2.h.sdump",
"self_type" : "_ZTIP6Struct#ODR:",
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h"
@@ -123,7 +123,7 @@
"is_const" : true,
"linker_set_key" : "_ZTIK6Struct",
"name" : "const Struct",
- "referenced_type" : "_ZTI6Struct#ODR:",
+ "referenced_type" : "_ZTI6Struct#ODR:/def2.h.sdump",
"self_type" : "_ZTIK6Struct#ODR:",
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h"
@@ -168,8 +168,8 @@
],
"linker_set_key" : "_ZTI6Struct",
"name" : "Struct",
- "referenced_type" : "_ZTI6Struct#ODR:",
- "self_type" : "_ZTI6Struct#ODR:",
+ "referenced_type" : "_ZTI6Struct#ODR:/def2.h.sdump",
+ "self_type" : "_ZTI6Struct#ODR:/def2.h.sdump",
"size" : 8,
"source_file" : "/development/vndk/tools/header-checker/tests/integration/merge_multi_definitions/include/def2.h"
}