Merge "Move ModuleMerger to namespace header_checker::linker"

This commit is contained in:
Treehugger Robot
2020-05-18 03:04:34 +00:00
committed by Gerrit Code Review
3 changed files with 171 additions and 183 deletions

View File

@@ -135,7 +135,7 @@ class HeaderAbiLinker {
const repr::AbiElementMap<T> &src, const repr::AbiElementMap<T> &src,
const std::function<bool(const std::string &)> &symbol_filter); const std::function<bool(const std::string &)> &symbol_filter);
std::unique_ptr<repr::ModuleMerger> ReadInputDumpFiles(); std::unique_ptr<linker::ModuleMerger> ReadInputDumpFiles();
bool ReadExportedSymbols(); bool ReadExportedSymbols();
@@ -187,10 +187,10 @@ class HeaderAbiLinker {
static void static void
DeDuplicateAbiElementsThread(const std::vector<std::string> &dump_files, DeDuplicateAbiElementsThread(const std::vector<std::string> &dump_files,
const std::set<std::string> *exported_headers, const std::set<std::string> *exported_headers,
repr::ModuleMerger *global_merger, linker::ModuleMerger *global_merger,
std::mutex *global_merger_lock, std::mutex *global_merger_lock,
std::atomic<std::size_t> *cnt) { std::atomic<std::size_t> *cnt) {
repr::ModuleMerger local_merger(exported_headers); linker::ModuleMerger local_merger(exported_headers);
auto begin_it = dump_files.begin(); auto begin_it = dump_files.begin();
std::size_t num_sources = dump_files.size(); std::size_t num_sources = dump_files.size();
@@ -216,9 +216,9 @@ DeDuplicateAbiElementsThread(const std::vector<std::string> &dump_files,
global_merger->MergeGraphs(local_merger.GetModule()); global_merger->MergeGraphs(local_merger.GetModule());
} }
std::unique_ptr<repr::ModuleMerger> HeaderAbiLinker::ReadInputDumpFiles() { std::unique_ptr<linker::ModuleMerger> HeaderAbiLinker::ReadInputDumpFiles() {
std::unique_ptr<repr::ModuleMerger> merger( std::unique_ptr<linker::ModuleMerger> merger(
new repr::ModuleMerger(&exported_headers_)); new linker::ModuleMerger(&exported_headers_));
std::size_t max_threads = std::thread::hardware_concurrency(); std::size_t max_threads = std::thread::hardware_concurrency();
std::size_t num_threads = std::size_t num_threads =

View File

@@ -22,12 +22,12 @@
namespace header_checker { namespace header_checker {
namespace repr { namespace linker {
MergeStatus ModuleMerger::MergeBuiltinType( MergeStatus ModuleMerger::MergeBuiltinType(
const BuiltinTypeIR *builtin_type, const ModuleIR &addend, const repr::BuiltinTypeIR *builtin_type, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
std::string linker_set_key = builtin_type->GetLinkerSetKey(); std::string linker_set_key = builtin_type->GetLinkerSetKey();
auto builtin_it = module_->builtin_types_.find(linker_set_key); auto builtin_it = module_->builtin_types_.find(linker_set_key);
if (builtin_it != module_->builtin_types_.end()) { if (builtin_it != module_->builtin_types_.end()) {
@@ -46,9 +46,9 @@ MergeStatus ModuleMerger::MergeBuiltinType(
MergeStatus ModuleMerger::LookupUserDefinedType( MergeStatus ModuleMerger::LookupUserDefinedType(
const TypeIR *ud_type, const ModuleIR &addend, const repr::TypeIR *ud_type, const repr::ModuleIR &addend,
const std::string &ud_type_unique_id_and_source, const std::string &ud_type_unique_id_and_source,
AbiElementMap<MergeStatus> *local_to_global_type_id_map_) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map_) {
auto it = module_->odr_list_map_.find(ud_type_unique_id_and_source); auto it = module_->odr_list_map_.find(ud_type_unique_id_and_source);
if (it == module_->odr_list_map_.end()) { if (it == module_->odr_list_map_.end()) {
// Calling this an ODR violation even though it means no UD with the same // Calling this an ODR violation even though it means no UD with the same
@@ -61,17 +61,17 @@ MergeStatus ModuleMerger::LookupUserDefinedType(
// Initialize type comparator (which will compare the referenced types // Initialize type comparator (which will compare the referenced types
// recursively). // recursively).
std::set<std::string> type_cache; std::set<std::string> type_cache;
DiffPolicyOptions diff_policy_options(false); repr::DiffPolicyOptions diff_policy_options(false);
AbiDiffHelper diff_helper(module_->type_graph_, addend.type_graph_, repr::AbiDiffHelper diff_helper(module_->type_graph_, addend.type_graph_,
diff_policy_options, &type_cache, nullptr); diff_policy_options, &type_cache, nullptr);
// Compare each user-defined type with the latest input user-defined type. // Compare each user-defined type with the latest input user-defined type.
// If there is a match, re-use the existing user-defined type. // If there is a match, re-use the existing user-defined type.
for (auto &definition : it->second) { for (auto &definition : it->second) {
const TypeIR *contender_ud = definition.type_ir_; const repr::TypeIR *contender_ud = definition.type_ir_;
DiffStatus result = diff_helper.CompareAndDumpTypeDiff( repr::DiffStatus result = diff_helper.CompareAndDumpTypeDiff(
contender_ud->GetSelfType(), ud_type->GetSelfType()); contender_ud->GetSelfType(), ud_type->GetSelfType());
if (result == DiffStatus::no_diff) { if (result == repr::DiffStatus::no_diff) {
local_to_global_type_id_map_->emplace( local_to_global_type_id_map_->emplace(
ud_type->GetSelfType(), ud_type->GetSelfType(),
MergeStatus(false, contender_ud->GetSelfType())); MergeStatus(false, contender_ud->GetSelfType()));
@@ -87,21 +87,21 @@ MergeStatus ModuleMerger::LookupUserDefinedType(
MergeStatus ModuleMerger::LookupType( MergeStatus ModuleMerger::LookupType(
const TypeIR *addend_node, const ModuleIR &addend, const repr::TypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
std::string unique_type_id; std::string unique_type_id;
switch (addend_node->GetKind()) { switch (addend_node->GetKind()) {
case RecordTypeKind: case repr::RecordTypeKind:
unique_type_id = unique_type_id = repr::GetODRListMapKey(
GetODRListMapKey(static_cast<const RecordTypeIR *>(addend_node)); static_cast<const repr::RecordTypeIR *>(addend_node));
break; break;
case EnumTypeKind: case repr::EnumTypeKind:
unique_type_id = unique_type_id = repr::GetODRListMapKey(
GetODRListMapKey(static_cast<const EnumTypeIR *>(addend_node)); static_cast<const repr::EnumTypeIR *>(addend_node));
break; break;
case FunctionTypeKind: case repr::FunctionTypeKind:
unique_type_id = unique_type_id = repr::GetODRListMapKey(
GetODRListMapKey(static_cast<const FunctionTypeIR *>(addend_node)); static_cast<const repr::FunctionTypeIR *>(addend_node));
break; break;
default: default:
// Other kinds (e.g. PointerTypeKind, QualifiedTypeKind, ArrayTypeKind, // Other kinds (e.g. PointerTypeKind, QualifiedTypeKind, ArrayTypeKind,
@@ -120,8 +120,8 @@ MergeStatus ModuleMerger::LookupType(
// graph. It also corrects the referenced_type field in the references_type // graph. It also corrects the referenced_type field in the references_type
// object passed and returns the merge status of the *referenced type*. // object passed and returns the merge status of the *referenced type*.
MergeStatus ModuleMerger::MergeReferencingTypeInternal( MergeStatus ModuleMerger::MergeReferencingTypeInternal(
const ModuleIR &addend, ReferencesOtherType *references_type, const repr::ModuleIR &addend, repr::ReferencesOtherType *references_type,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
// First look in the local_to_global_type_id_map for the referenced type's // First look in the local_to_global_type_id_map for the referenced type's
// id. // id.
const std::string &referenced_type_id = references_type->GetReferencedType(); const std::string &referenced_type_id = references_type->GetReferencedType();
@@ -154,8 +154,8 @@ MergeStatus ModuleMerger::MergeReferencingTypeInternal(
void ModuleMerger::MergeRecordFields( void ModuleMerger::MergeRecordFields(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
for (auto &field : added_node->GetFields()) { for (auto &field : added_node->GetFields()) {
MergeReferencingTypeInternal(addend, &field, local_to_global_type_id_map); MergeReferencingTypeInternal(addend, &field, local_to_global_type_id_map);
} }
@@ -163,8 +163,8 @@ void ModuleMerger::MergeRecordFields(
void ModuleMerger::MergeRecordCXXBases( void ModuleMerger::MergeRecordCXXBases(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
for (auto &base : added_node->GetBases()) { for (auto &base : added_node->GetBases()) {
MergeReferencingTypeInternal(addend, &base, local_to_global_type_id_map); MergeReferencingTypeInternal(addend, &base, local_to_global_type_id_map);
} }
@@ -172,8 +172,8 @@ void ModuleMerger::MergeRecordCXXBases(
void ModuleMerger::MergeRecordTemplateElements( void ModuleMerger::MergeRecordTemplateElements(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
for (auto &template_element : added_node->GetTemplateElements()) { for (auto &template_element : added_node->GetTemplateElements()) {
MergeReferencingTypeInternal( MergeReferencingTypeInternal(
addend, &template_element, local_to_global_type_id_map); addend, &template_element, local_to_global_type_id_map);
@@ -182,8 +182,8 @@ void ModuleMerger::MergeRecordTemplateElements(
void ModuleMerger::MergeRecordDependencies( void ModuleMerger::MergeRecordDependencies(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
// First call MergeType on all its fields. // First call MergeType on all its fields.
MergeRecordFields(addend, added_node, local_to_global_type_id_map); MergeRecordFields(addend, added_node, local_to_global_type_id_map);
@@ -195,11 +195,11 @@ void ModuleMerger::MergeRecordDependencies(
template <typename T> template <typename T>
std::pair<MergeStatus, typename AbiElementMap<T>::iterator> std::pair<MergeStatus, typename repr::AbiElementMap<T>::iterator>
ModuleMerger::UpdateUDTypeAccounting( ModuleMerger::UpdateUDTypeAccounting(
const T *addend_node, const ModuleIR &addend, const T *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map, repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map,
AbiElementMap<T> *specific_type_map) { repr::AbiElementMap<T> *specific_type_map) {
const std::string addend_compilation_unit_path = const std::string addend_compilation_unit_path =
addend.GetCompilationUnitPath(addend_node); addend.GetCompilationUnitPath(addend_node);
assert(addend_compilation_unit_path != ""); assert(addend_compilation_unit_path != "");
@@ -231,8 +231,8 @@ ModuleMerger::UpdateUDTypeAccounting(
// This method is necessarily going to have a was_newly_merged_ = true in its // This method is necessarily going to have a was_newly_merged_ = true in its
// MergeStatus return. So it necessarily merges a new RecordType. // MergeStatus return. So it necessarily merges a new RecordType.
MergeStatus ModuleMerger::MergeRecordAndDependencies( MergeStatus ModuleMerger::MergeRecordAndDependencies(
const RecordTypeIR *addend_node, const ModuleIR &addend, const repr::RecordTypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
auto p = UpdateUDTypeAccounting( auto p = UpdateUDTypeAccounting(
addend_node, addend, local_to_global_type_id_map, addend_node, addend, local_to_global_type_id_map,
&module_->record_types_); &module_->record_types_);
@@ -243,8 +243,8 @@ MergeStatus ModuleMerger::MergeRecordAndDependencies(
void ModuleMerger::MergeEnumDependencies( void ModuleMerger::MergeEnumDependencies(
const ModuleIR &addend, EnumTypeIR *added_node, const repr::ModuleIR &addend, repr::EnumTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
const std::string underlying_type_id = added_node->GetUnderlyingType(); const std::string underlying_type_id = added_node->GetUnderlyingType();
// Get the underlying type, it nessarily has to be present in the addend's // Get the underlying type, it nessarily has to be present in the addend's
// type graph since builtin types can't be hidden. Call MergeType on it and // type graph since builtin types can't be hidden. Call MergeType on it and
@@ -263,8 +263,8 @@ void ModuleMerger::MergeEnumDependencies(
// This method is necessarily going to have a was_newly_merged_ = true in its // This method is necessarily going to have a was_newly_merged_ = true in its
// MergeStatus return. So it necessarily merges a new EnumType. // MergeStatus return. So it necessarily merges a new EnumType.
MergeStatus ModuleMerger::MergeEnumType( MergeStatus ModuleMerger::MergeEnumType(
const EnumTypeIR *addend_node, const ModuleIR &addend, const repr::EnumTypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
auto p = UpdateUDTypeAccounting( auto p = UpdateUDTypeAccounting(
addend_node, addend, local_to_global_type_id_map, &module_->enum_types_); addend_node, addend, local_to_global_type_id_map, &module_->enum_types_);
MergeEnumDependencies(addend, &p.second->second, local_to_global_type_id_map); MergeEnumDependencies(addend, &p.second->second, local_to_global_type_id_map);
@@ -273,8 +273,8 @@ MergeStatus ModuleMerger::MergeEnumType(
MergeStatus ModuleMerger::MergeFunctionType( MergeStatus ModuleMerger::MergeFunctionType(
const FunctionTypeIR *addend_node, const ModuleIR &addend, const repr::FunctionTypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
auto p = UpdateUDTypeAccounting( auto p = UpdateUDTypeAccounting(
addend_node, addend, local_to_global_type_id_map, addend_node, addend, local_to_global_type_id_map,
&module_->function_types_); &module_->function_types_);
@@ -286,11 +286,11 @@ MergeStatus ModuleMerger::MergeFunctionType(
template <typename T> template <typename T>
MergeStatus ModuleMerger::MergeReferencingTypeInternalAndUpdateParent( MergeStatus ModuleMerger::MergeReferencingTypeInternalAndUpdateParent(
const ModuleIR &addend, const T *addend_node, const repr::ModuleIR &addend, const T *addend_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map, repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map,
AbiElementMap<T> *parent_map, const std::string &updated_self_type_id) { repr::AbiElementMap<T> *parent_map,
const std::string &updated_self_type_id) {
MergeStatus merge_status; MergeStatus merge_status;
uint64_t old_max_type_id = max_type_id_;
// Create copy of addend_node // Create copy of addend_node
T added_node = *addend_node; T added_node = *addend_node;
@@ -306,19 +306,6 @@ MergeStatus ModuleMerger::MergeReferencingTypeInternalAndUpdateParent(
return MergeStatus(true, updated_self_type_id); return MergeStatus(true, updated_self_type_id);
} }
// The type that the added_node references was not newly added to the parent
// graph. However, we still might need to add the added_node to the parent
// graph, since for the particular 'Kind' of the added_node, it may not be
// present in the parent graph. This will be determined by looking at the
// appropriate 'type-referenced' -> TypeElement map in the parent for the
// type-id returned by the MergeStatus. If the map doesn't have an entry for
// the type-id returned by the MergeStatus, the added_type is not present in
// the parent graph and needs to be 'newly' added. We also need to modify the
// global type id in the local_to_global_type_id map. The added_node should
// already have it's self_type and referenced_type fields fixed up.
// We maintain a rollback id to have contiguous type ids.
max_type_id_ = old_max_type_id;
// Try finding the referenced_type is referred to by any referencing type // Try finding the referenced_type is referred to by any referencing type
// of the same kind in the parent graph. It is safe to call this on the // of the same kind in the parent graph. It is safe to call this on the
// added_node, since the referenced_type in the added_node would have been // added_node, since the referenced_type in the added_node would have been
@@ -349,30 +336,29 @@ MergeStatus ModuleMerger::MergeReferencingTypeInternalAndUpdateParent(
} }
static bool IsReferencingType(LinkableMessageKind kind) { static bool IsReferencingType(repr::LinkableMessageKind kind) {
switch (kind) { switch (kind) {
case PointerTypeKind: case repr::PointerTypeKind:
case QualifiedTypeKind: case repr::QualifiedTypeKind:
case ArrayTypeKind: case repr::ArrayTypeKind:
case LvalueReferenceTypeKind: case repr::LvalueReferenceTypeKind:
case RvalueReferenceTypeKind: case repr::RvalueReferenceTypeKind:
return true; return true;
case RecordTypeKind: case repr::RecordTypeKind:
case EnumTypeKind: case repr::EnumTypeKind:
case BuiltinTypeKind: case repr::BuiltinTypeKind:
case FunctionTypeKind: case repr::FunctionTypeKind:
case FunctionKind: case repr::FunctionKind:
case GlobalVarKind: case repr::GlobalVarKind:
return false; return false;
} }
} }
// Trace the referenced type until reaching a RecordTypeIR, EnumTypeIR, // Trace the referenced type until reaching a RecordTypeIR, EnumTypeIR,
// FunctionTypeIR, or BuiltinTypeIR. Return nullptr if the referenced type is // FunctionTypeIR, or BuiltinTypeIR. Return nullptr if the referenced type is
// undefined or built-in. // undefined or built-in.
static const TypeIR *DereferenceType(const ModuleIR &module, static const repr::TypeIR *DereferenceType(const repr::ModuleIR &module,
const TypeIR *type_ir) { const repr::TypeIR *type_ir) {
auto &type_graph = module.GetTypeGraph(); auto &type_graph = module.GetTypeGraph();
while (IsReferencingType(type_ir->GetKind())) { while (IsReferencingType(type_ir->GetKind())) {
auto it = type_graph.find(type_ir->GetReferencedType()); auto it = type_graph.find(type_ir->GetReferencedType());
@@ -389,15 +375,16 @@ static const TypeIR *DereferenceType(const ModuleIR &module,
// This method creates a new node for the addend node in the graph if MergeType // 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. // on the reference returned a MergeStatus with was_newly_added_ = true.
MergeStatus ModuleMerger::MergeReferencingType( MergeStatus ModuleMerger::MergeReferencingType(
const ModuleIR &addend, const TypeIR *addend_node, const repr::ModuleIR &addend, const repr::TypeIR *addend_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
// First add the type 'pro-actively'. We need to do this since we'll need to // First add the type 'pro-actively'. We need to do this since we'll need to
// fill in 'referenced-type' fields in all this type's descendants and // fill in 'referenced-type' fields in all this type's descendants and
// descendants which are compound types (records), can refer to this type. // descendants which are compound types (records), can refer to this type.
std::string added_type_id = addend_node->GetSelfType(); std::string added_type_id = addend_node->GetSelfType();
auto type_id_it = module_->type_graph_.find(added_type_id); auto type_id_it = module_->type_graph_.find(added_type_id);
if (type_id_it != module_->type_graph_.end()) { if (type_id_it != module_->type_graph_.end()) {
const TypeIR *final_referenced_type = DereferenceType(addend, addend_node); const repr::TypeIR *final_referenced_type =
DereferenceType(addend, addend_node);
if (final_referenced_type != nullptr) { if (final_referenced_type != nullptr) {
std::string compilation_unit_path = std::string compilation_unit_path =
addend.GetCompilationUnitPath(final_referenced_type); addend.GetCompilationUnitPath(final_referenced_type);
@@ -414,29 +401,29 @@ MergeStatus ModuleMerger::MergeReferencingType(
// Merge the type. // Merge the type.
switch (addend_node->GetKind()) { switch (addend_node->GetKind()) {
case PointerTypeKind: case repr::PointerTypeKind:
return MergeReferencingTypeInternalAndUpdateParent( return MergeReferencingTypeInternalAndUpdateParent(
addend, static_cast<const PointerTypeIR *>(addend_node), addend, static_cast<const repr::PointerTypeIR *>(addend_node),
local_to_global_type_id_map, &module_->pointer_types_, local_to_global_type_id_map, &module_->pointer_types_,
added_type_id); added_type_id);
case QualifiedTypeKind: case repr::QualifiedTypeKind:
return MergeReferencingTypeInternalAndUpdateParent( return MergeReferencingTypeInternalAndUpdateParent(
addend, static_cast<const QualifiedTypeIR *>(addend_node), addend, static_cast<const repr::QualifiedTypeIR *>(addend_node),
local_to_global_type_id_map, &module_->qualified_types_, local_to_global_type_id_map, &module_->qualified_types_,
added_type_id); added_type_id);
case ArrayTypeKind: case repr::ArrayTypeKind:
return MergeReferencingTypeInternalAndUpdateParent( return MergeReferencingTypeInternalAndUpdateParent(
addend, static_cast<const ArrayTypeIR *>(addend_node), addend, static_cast<const repr::ArrayTypeIR *>(addend_node),
local_to_global_type_id_map, &module_->array_types_, local_to_global_type_id_map, &module_->array_types_,
added_type_id); added_type_id);
case LvalueReferenceTypeKind: case repr::LvalueReferenceTypeKind:
return MergeReferencingTypeInternalAndUpdateParent( return MergeReferencingTypeInternalAndUpdateParent(
addend, static_cast<const LvalueReferenceTypeIR *>(addend_node), addend, static_cast<const repr::LvalueReferenceTypeIR *>(addend_node),
local_to_global_type_id_map, &module_->lvalue_reference_types_, local_to_global_type_id_map, &module_->lvalue_reference_types_,
added_type_id); added_type_id);
case RvalueReferenceTypeKind: case repr::RvalueReferenceTypeKind:
return MergeReferencingTypeInternalAndUpdateParent( return MergeReferencingTypeInternalAndUpdateParent(
addend, static_cast<const RvalueReferenceTypeIR *>(addend_node), addend, static_cast<const repr::RvalueReferenceTypeIR *>(addend_node),
local_to_global_type_id_map, &module_->rvalue_reference_types_, local_to_global_type_id_map, &module_->rvalue_reference_types_,
added_type_id); added_type_id);
default: default:
@@ -447,24 +434,23 @@ MergeStatus ModuleMerger::MergeReferencingType(
MergeStatus ModuleMerger::MergeTypeInternal( MergeStatus ModuleMerger::MergeTypeInternal(
const TypeIR *addend_node, const ModuleIR &addend, const repr::TypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
switch (addend_node->GetKind()) { switch (addend_node->GetKind()) {
case BuiltinTypeKind: case repr::BuiltinTypeKind:
return MergeBuiltinType( return MergeBuiltinType(
static_cast<const BuiltinTypeIR *>(addend_node), addend, static_cast<const repr::BuiltinTypeIR *>(addend_node), addend,
local_to_global_type_id_map); local_to_global_type_id_map);
case RecordTypeKind: case repr::RecordTypeKind:
return MergeRecordAndDependencies( return MergeRecordAndDependencies(
static_cast<const RecordTypeIR *>(addend_node), addend, static_cast<const repr::RecordTypeIR *>(addend_node), addend,
local_to_global_type_id_map); local_to_global_type_id_map);
case EnumTypeKind: case repr::EnumTypeKind:
return MergeEnumType( return MergeEnumType(static_cast<const repr::EnumTypeIR *>(addend_node),
static_cast<const EnumTypeIR *>(addend_node), addend, addend, local_to_global_type_id_map);
local_to_global_type_id_map); case repr::FunctionTypeKind:
case FunctionTypeKind:
return MergeFunctionType( return MergeFunctionType(
static_cast<const FunctionTypeIR *>(addend_node), addend, static_cast<const repr::FunctionTypeIR *>(addend_node), addend,
local_to_global_type_id_map); local_to_global_type_id_map);
default: default:
return MergeReferencingType(addend, addend_node, return MergeReferencingType(addend, addend_node,
@@ -475,8 +461,8 @@ MergeStatus ModuleMerger::MergeTypeInternal(
MergeStatus ModuleMerger::MergeType( MergeStatus ModuleMerger::MergeType(
const TypeIR *addend_node, const ModuleIR &addend, const repr::TypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
// Check if the addend type is already in the parent graph. Since we're // Check if the addend type is already in the parent graph. Since we're
// going to traverse all the dependencies add whichever ones are not in the // going to traverse all the dependencies add whichever ones are not in the
// parent graph. This does not add the node itself though. // parent graph. This does not add the node itself though.
@@ -497,8 +483,8 @@ MergeStatus ModuleMerger::MergeType(
void ModuleMerger::MergeCFunctionLikeDeps( void ModuleMerger::MergeCFunctionLikeDeps(
const ModuleIR &addend, CFunctionLikeIR *cfunction_like_ir, const repr::ModuleIR &addend, repr::CFunctionLikeIR *cfunction_like_ir,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
// Merge the return type. // Merge the return type.
auto ret_type_it = auto ret_type_it =
addend.type_graph_.find(cfunction_like_ir->GetReturnType()); addend.type_graph_.find(cfunction_like_ir->GetReturnType());
@@ -517,8 +503,8 @@ void ModuleMerger::MergeCFunctionLikeDeps(
void ModuleMerger::MergeFunctionDeps( void ModuleMerger::MergeFunctionDeps(
FunctionIR *added_node, const ModuleIR &addend, repr::FunctionIR *added_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
MergeCFunctionLikeDeps(addend, added_node, local_to_global_type_id_map); MergeCFunctionLikeDeps(addend, added_node, local_to_global_type_id_map);
// Merge the template arguments. // Merge the template arguments.
@@ -530,22 +516,23 @@ void ModuleMerger::MergeFunctionDeps(
template <typename T> template <typename T>
static bool IsLinkableMessagePresent(const LinkableMessageIR *lm, static bool
const AbiElementMap<T> &message_map) { IsLinkableMessagePresent(const repr::LinkableMessageIR *lm,
const repr::AbiElementMap<T> &message_map) {
return (message_map.find(lm->GetLinkerSetKey()) != message_map.end()); return (message_map.find(lm->GetLinkerSetKey()) != message_map.end());
} }
void ModuleMerger::MergeFunction( void ModuleMerger::MergeFunction(
const FunctionIR *addend_node, const ModuleIR &addend, const repr::FunctionIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
const std::string &function_linkage_name = addend_node->GetLinkerSetKey(); const std::string &function_linkage_name = addend_node->GetLinkerSetKey();
if (IsLinkableMessagePresent(addend_node, module_->functions_)) { if (IsLinkableMessagePresent(addend_node, module_->functions_)) {
// The functions and all of its dependencies have already been added. // The functions and all of its dependencies have already been added.
// No two globally visible functions can have the same symbol name. // No two globally visible functions can have the same symbol name.
return; return;
} }
FunctionIR function_ir = *addend_node; repr::FunctionIR function_ir = *addend_node;
MergeFunctionDeps(&function_ir, addend, local_to_global_type_id_map); MergeFunctionDeps(&function_ir, addend, local_to_global_type_id_map);
// Add it to the parent's function map. // Add it to the parent's function map.
module_->functions_.emplace(function_linkage_name, std::move(function_ir)); module_->functions_.emplace(function_linkage_name, std::move(function_ir));
@@ -553,15 +540,15 @@ void ModuleMerger::MergeFunction(
void ModuleMerger::MergeGlobalVariable( void ModuleMerger::MergeGlobalVariable(
const GlobalVarIR *addend_node, const ModuleIR &addend, const repr::GlobalVarIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map) { repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map) {
const std::string &global_variable_linkage_name = const std::string &global_variable_linkage_name =
addend_node->GetLinkerSetKey(); addend_node->GetLinkerSetKey();
if (IsLinkableMessagePresent(addend_node, module_->global_variables_)) { if (IsLinkableMessagePresent(addend_node, module_->global_variables_)) {
// The global variable and all of its dependencies have already been added. // The global variable and all of its dependencies have already been added.
return; return;
} }
GlobalVarIR global_variable_ir = *addend_node; repr::GlobalVarIR global_variable_ir = *addend_node;
MergeReferencingTypeInternal(addend, &global_variable_ir, MergeReferencingTypeInternal(addend, &global_variable_ir,
local_to_global_type_id_map); local_to_global_type_id_map);
module_->global_variables_.emplace( module_->global_variables_.emplace(
@@ -569,11 +556,11 @@ void ModuleMerger::MergeGlobalVariable(
} }
void ModuleMerger::MergeGraphs(const ModuleIR &addend) { void ModuleMerger::MergeGraphs(const repr::ModuleIR &addend) {
// Iterate through nodes of addend reader and merge them. // Iterate through nodes of addend reader and merge them.
// Keep a merged types cache since if a type is merged, so will all of its // Keep a merged types cache since if a type is merged, so will all of its
// dependencies which weren't already merged. // dependencies which weren't already merged.
AbiElementMap<MergeStatus> merged_types_cache; repr::AbiElementMap<MergeStatus> merged_types_cache;
for (auto &&type_ir : addend.type_graph_) { for (auto &&type_ir : addend.type_graph_) {
MergeType(type_ir.second, addend, &merged_types_cache); MergeType(type_ir.second, addend, &merged_types_cache);
@@ -589,6 +576,6 @@ void ModuleMerger::MergeGraphs(const ModuleIR &addend) {
} }
} // namespace repr } // namespace linker
} // namespace header_checker } // namespace header_checker

View File

@@ -16,7 +16,7 @@
namespace header_checker { namespace header_checker {
namespace repr { namespace linker {
class MergeStatus { class MergeStatus {
@@ -41,115 +41,116 @@ public:
class ModuleMerger { class ModuleMerger {
public: public:
ModuleMerger(const std::set<std::string> *exported_headers) ModuleMerger(const std::set<std::string> *exported_headers)
: module_(new ModuleIR(exported_headers)) {} : module_(new repr::ModuleIR(exported_headers)) {}
const ModuleIR &GetModule() { const repr::ModuleIR &GetModule() {
return *module_; return *module_;
} }
void MergeGraphs(const ModuleIR &addend); void MergeGraphs(const repr::ModuleIR &addend);
private: private:
void MergeCFunctionLikeDeps( void MergeCFunctionLikeDeps(
const ModuleIR &addend, CFunctionLikeIR *cfunction_like_ir, const repr::ModuleIR &addend, repr::CFunctionLikeIR *cfunction_like_ir,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
MergeStatus MergeFunctionType( MergeStatus MergeFunctionType(
const FunctionTypeIR *addend_node, const ModuleIR &addend, const repr::FunctionTypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
MergeStatus MergeEnumType( MergeStatus
const EnumTypeIR *addend_node, const ModuleIR &addend, MergeEnumType(const repr::EnumTypeIR *addend_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); const repr::ModuleIR &addend,
repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeEnumDependencies( void MergeEnumDependencies(
const ModuleIR &addend, EnumTypeIR *added_node, const repr::ModuleIR &addend, repr::EnumTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
MergeStatus MergeRecordAndDependencies( MergeStatus MergeRecordAndDependencies(
const RecordTypeIR *addend_node, const ModuleIR &addend, const repr::RecordTypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeRecordDependencies( void MergeRecordDependencies(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeRecordFields( void MergeRecordFields(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeRecordCXXBases( void MergeRecordCXXBases(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeRecordTemplateElements( void MergeRecordTemplateElements(
const ModuleIR &addend, RecordTypeIR *added_node, const repr::ModuleIR &addend, repr::RecordTypeIR *added_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeGlobalVariable( void MergeGlobalVariable(
const GlobalVarIR *addend_node, const ModuleIR &addend, const repr::GlobalVarIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeGlobalVariables( void MergeGlobalVariables(
const ModuleIR &addend, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeFunctionDeps( void MergeFunctionDeps(
FunctionIR *added_node, const ModuleIR &addend, repr::FunctionIR *added_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
void MergeFunction( void
const FunctionIR *addend_node, const ModuleIR &addend, MergeFunction(const repr::FunctionIR *addend_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); const repr::ModuleIR &addend,
repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
template <typename T> template <typename T>
MergeStatus MergeReferencingTypeInternalAndUpdateParent( MergeStatus MergeReferencingTypeInternalAndUpdateParent(
const ModuleIR &addend, const T *addend_node, const repr::ModuleIR &addend, const T *addend_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map, repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map,
AbiElementMap<T> *parent_map, const std::string &updated_self_type_id); repr::AbiElementMap<T> *parent_map,
const std::string &updated_self_type_id);
MergeStatus MergeReferencingTypeInternal( MergeStatus MergeReferencingTypeInternal(
const ModuleIR &addend, ReferencesOtherType *references_type, const repr::ModuleIR &addend, repr::ReferencesOtherType *references_type,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
MergeStatus MergeReferencingType( MergeStatus MergeReferencingType(
const ModuleIR &addend, const TypeIR *addend_node, const repr::ModuleIR &addend, const repr::TypeIR *addend_node,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
template <typename T> template <typename T>
std::pair<MergeStatus, typename AbiElementMap<T>::iterator> std::pair<MergeStatus, typename repr::AbiElementMap<T>::iterator>
UpdateUDTypeAccounting( UpdateUDTypeAccounting(
const T *addend_node, const ModuleIR &addend, const T *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map, repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map,
AbiElementMap<T> *specific_type_map); repr::AbiElementMap<T> *specific_type_map);
MergeStatus MergeBuiltinType( MergeStatus MergeBuiltinType(
const BuiltinTypeIR *builtin_type, const ModuleIR &addend, const repr::BuiltinTypeIR *builtin_type, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
MergeStatus LookupUserDefinedType( MergeStatus LookupUserDefinedType(
const TypeIR *ud_type, const ModuleIR &addend, const repr::TypeIR *ud_type, const repr::ModuleIR &addend,
const std::string &ud_type_unique_id, const std::string &ud_type_unique_id,
AbiElementMap<MergeStatus> *local_to_global_type_id_map_); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map_);
MergeStatus LookupType( MergeStatus
const TypeIR *addend_node, const ModuleIR &addend, LookupType(const repr::TypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
MergeStatus MergeTypeInternal( MergeStatus MergeTypeInternal(
const TypeIR *addend_node, const ModuleIR &addend, const repr::TypeIR *addend_node, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *local_to_global_type_id_map); repr::AbiElementMap<MergeStatus> *local_to_global_type_id_map);
MergeStatus MergeType( MergeStatus MergeType(const repr::TypeIR *addend_type,
const TypeIR *addend_type, const ModuleIR &addend, const repr::ModuleIR &addend,
AbiElementMap<MergeStatus> *merged_types_cache); repr::AbiElementMap<MergeStatus> *merged_types_cache);
private: private:
std::unique_ptr<ModuleIR> module_; std::unique_ptr<repr::ModuleIR> module_;
uint64_t max_type_id_ = 0;
}; };
} // namespace repr } // namespace linker
} // namespace header_checker } // namespace header_checker