blob: d0496965650c652af63137dd87462f4efa2dda3a [file]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "CommonABIRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Module.h"
#include "lldb/Utility/LLDBLog.h"
using namespace lldb;
using namespace lldb_private;
CommonABIRuntime::CommonABIRuntime(Process *process) : m_process(process) {}
lldb::TypeSP CommonABIRuntime::LookupTypeByName(llvm::StringRef type_name,
lldb::ModuleSP preferred_module,
bool &any_found) const {
Log *log = GetLog(LLDBLog::Object);
any_found = false;
ConstString const_lookup_name(type_name);
TypeList class_types;
// First look in the module that the vtable symbol came from and
// look for a single exact match.
TypeResults results;
TypeQuery query(const_lookup_name.GetStringRef(),
TypeQueryOptions::e_exact_match |
TypeQueryOptions::e_strict_namespaces |
TypeQueryOptions::e_find_one);
if (preferred_module) {
preferred_module->FindTypes(query, results);
TypeSP type_sp = results.GetFirstType();
if (type_sp)
class_types.Insert(type_sp);
}
// If we didn't find a symbol, then move on to the entire module
// list in the target and get as many unique matches as possible
if (class_types.Empty()) {
query.SetFindOne(false);
m_process->GetTarget().GetImages().FindTypes(nullptr, query, results);
for (const auto &type_sp : results.GetTypeMap().Types())
class_types.Insert(type_sp);
}
lldb::TypeSP type_sp;
if (class_types.Empty()) {
LLDB_LOG(log, "Failed to find '{0}'", type_name);
return {};
}
any_found = true;
if (class_types.GetSize() == 1) {
type_sp = class_types.GetTypeAtIndex(0);
if (!type_sp)
return {};
if (!TypeSystemClang::IsCXXClassType(type_sp->GetForwardCompilerType()))
return {};
return type_sp;
}
if (log) {
LLDB_LOG(log,
"'{0}' has multiple matching dynamic "
"types:",
type_name);
for (size_t i = 0; i < class_types.GetSize(); i++) {
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp) {
LLDB_LOG(log, "[{0}]: uid={1:x}, type-name='{2}'", i, type_sp->GetID(),
type_sp->GetName());
}
}
}
for (size_t i = 0; i < class_types.GetSize(); i++) {
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp) {
if (TypeSystemClang::IsCXXClassType(type_sp->GetForwardCompilerType())) {
LLDB_LOG(log,
"'{0}' has multiple matching dynamic types, "
"picking this one: [{1}] uid={2:x}, type-name='{3}'\n",
type_name, i, type_sp->GetID(), type_sp->GetName());
return type_sp;
}
}
}
LLDB_LOG(log,
"'{0}' has multiple matching dynamic types, didn't find a C++ match",
type_name);
return {};
}
TypeAndOrName
CommonABIRuntime::GetDynamicTypeInfo(const lldb_private::Address &vtable_addr) {
std::lock_guard<std::mutex> locker(m_mutex);
DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
if (pos == m_dynamic_type_map.end())
return TypeAndOrName();
return pos->second;
}
void CommonABIRuntime::SetDynamicTypeInfo(
const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info) {
std::lock_guard<std::mutex> locker(m_mutex);
m_dynamic_type_map[vtable_addr] = type_info;
}