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:
Hsin-Yi Chen
2020-03-20 20:00:05 +08:00
parent 4bc670f91d
commit f9e7b620ff
5 changed files with 73 additions and 21 deletions

View File

@@ -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:

View File

@@ -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};

View File

@@ -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()) {

View File

@@ -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_;
};

View File

@@ -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"
}