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
This commit is contained in:
@@ -113,7 +113,7 @@ HeaderAbiDiff::ExtractUserDefinedTypes(const repr::ModuleIR &tu) {
|
||||
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:
|
||||
|
||||
@@ -67,7 +67,8 @@ MergeStatus ModuleMerger::LookupUserDefinedType(
|
||||
|
||||
// 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 @@ MergeStatus ModuleMerger::LookupUserDefinedType(
|
||||
#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 @@ ModuleMerger::UpdateUDTypeAccounting(
|
||||
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 @@ ModuleMerger::UpdateUDTypeAccounting(
|
||||
// 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};
|
||||
|
||||
@@ -109,7 +109,7 @@ void ModuleIR::AddRecordType(RecordTypeIR &&record_type) {
|
||||
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 @@ void ModuleIR::AddFunctionType(FunctionTypeIR &&function_type) {
|
||||
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 @@ void ModuleIR::AddEnumType(EnumTypeIR &&enum_type) {
|
||||
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 @@ void ModuleIR::AddElfObject(ElfObjectIR &&elf_object) {
|
||||
}
|
||||
|
||||
|
||||
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()) {
|
||||
|
||||
@@ -37,9 +37,6 @@ using AbiElementMap = std::map<std::string, T>;
|
||||
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 ElfObjectIR : public ElfSymbolIR {
|
||||
}
|
||||
};
|
||||
|
||||
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 @@ class ModuleIR {
|
||||
return type_graph_;
|
||||
}
|
||||
|
||||
const AbiElementUnorderedMap<std::list<const TypeIR *>> &
|
||||
const AbiElementUnorderedMap<std::list<TypeDefinition>> &
|
||||
GetODRListMap() const {
|
||||
return odr_list_map_;
|
||||
}
|
||||
@@ -864,10 +871,19 @@ class ModuleIR {
|
||||
|
||||
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 @@ class ModuleIR {
|
||||
// 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 @@ class ModuleIR {
|
||||
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_;
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user