Author: Nerixyz
Date: 2026-06-30T20:01:09Z
New Revision: 6b5c27376a275ce34464631be3caed65967ab161

URL: 
https://github.com/llvm/llvm-project/commit/6b5c27376a275ce34464631be3caed65967ab161
DIFF: 
https://github.com/llvm/llvm-project/commit/6b5c27376a275ce34464631be3caed65967ab161.diff

LOG: Revert "[lldb] Move common functionality out of Itanium ABI runtime 
(#191275)" (#206816)

This reverts commit 0f51760a342cd8fed1c657e6ca134097c9e8f88c.

A test fails with the commit
(https://github.com/llvm/llvm-project/pull/191275#issuecomment-4846936554):

```
Traceback (most recent call last):
  File 
"/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py",
 line 596, in test_python_source_frames
    self.assertNotIn("0xffffffffffffffff", output.lower())
AssertionError: '0xffffffffffffffff' unexpectedly found in "* thread #2, name = 
'a.out', stop reason = breakpoint 1.1\n  * frame #0: compute_fibonacci at 
python_helper.py:7 [synthetic]\n    frame #1: process_data at 
python_helper.py:16 [synthetic]\n    frame #2: main at python_helper.py:27 
[synthetic]\n    frame #3: 0x0000badc2de81358 a.out`thread_func(thread_num=0) 
at main.cpp:44:13\n    frame #4: 0x0000badc2de81f9c a.out`void 
std::__invoke_impl<void, void (*)(int), int>((null)=__invoke_other @ 
0x0000f1555ebae74f, __f=0x0000badc66845ec0, __args=0x0000badc66845eb8) at 
invoke.h:61:14\n    frame #5: 0x0000badc2de81f18 
a.out`std::__invoke_result<void (*)(int), int>::type std::__invoke<void 
(*)(int), int>(__fn=0x0000badc66845ec0, __args=0x0000badc66845eb8) at 
invoke.h:96:14\n    frame #6: 0x0000badc2de81ee4 a.out`void 
std::thread::_invoker<std::tuple<void (*)(int), int>>::_m_invoke<0ul, 
1ul>(this=0x0000badc66845eb8, (null)=_index_tuple<0ul, 1ul> @ 
0x0000f1555ebae7af) at std_thread.h:259:13\n    frame #7: 0x0000badc2de81e98 
a.out`std::thread::_invoker<std::tuple<void (*)(int), 
int>>::operator()(this=0x0000badc66845eb8) at std_thread.h:266:11\n    frame 
#8: 0x0000badc2de81d70 
a.out`std::thread::_state_impl<std::thread::_invoker<std::tuple<void (*)(int), 
int>>>::_m_run(this=0xffffffffffffffff) at std_thread.h:211:13\n    frame #9: 
0x0000f1555ef029cc libstdc++.so.6`___lldb_unnamed_symbol_d29b0 + 28\n    frame 
#10: 0x0000f1555ec30398 libc.so.6`___lldb_unnamed_symbol_800c0 + 728\n    frame 
#11: 0x0000f1555ec99e9c libc.so.6`___lldb_unnamed_symbol_e9e90 + 12\n"
```

I don't know why this test fails with the PR, but I don't have time to
fix it now, so revert it to unblock CI.

The backtrace was
```
    frame #0: compute_fibonacci at python_helper.py:7 [synthetic]
    frame #1: process_data at python_helper.py:16 [synthetic]
    frame #2: main at python_helper.py:27 [synthetic]
    frame #3: 0x0000badc2de81358 a.out`thread_func(thread_num=0) at 
main.cpp:44:13
    frame #4: 0x0000badc2de81f9c a.out`void std::__invoke_impl<void, void 
(*)(int), int>((null)=__invoke_other @ 0x0000f1555ebae74f, 
__f=0x0000badc66845ec0, __args=0x0000badc66845eb8) at invoke.h:61:14
    frame #5: 0x0000badc2de81f18 a.out`std::__invoke_result<void (*)(int), 
int>::type std::__invoke<void (*)(int), int>(__fn=0x0000badc66845ec0, 
__args=0x0000badc66845eb8) at invoke.h:96:14
    frame #6: 0x0000badc2de81ee4 a.out`void 
std::thread::_invoker<std::tuple<void (*)(int), int>>::_m_invoke<0ul, 
1ul>(this=0x0000badc66845eb8, (null)=_index_tuple<0ul, 1ul> @ 
0x0000f1555ebae7af) at std_thread.h:259:13
    frame #7: 0x0000badc2de81e98 a.out`std::thread::_invoker<std::tuple<void 
(*)(int), int>>::operator()(this=0x0000badc66845eb8) at std_thread.h:266:11
    frame #8: 0x0000badc2de81d70 
a.out`std::thread::_state_impl<std::thread::_invoker<std::tuple<void (*)(int), 
int>>>::_m_run(this=0xffffffffffffffff) at std_thread.h:211:13
    frame #9: 0x0000f1555ef029cc libstdc++.so.6`___lldb_unnamed_symbol_d29b0 + 
28
    frame #10: 0x0000f1555ec30398 libc.so.6`___lldb_unnamed_symbol_800c0 + 728
    frame #11: 0x0000f1555ec99e9c libc.so.6`___lldb_unnamed_symbol_e9e90 + 12
```

This contains 0xffffffffffffffff in frame 8.

Added: 
    

Modified: 
    lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
    lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
    lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
    lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
    lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h

Removed: 
    lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp
    lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h


################################################################################
diff  --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
index dcf8fcd850db5..ca54601d99cff 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
@@ -1,6 +1,5 @@
 add_lldb_library(lldbPluginCPPRuntime PLUGIN
   CommandObjectCPlusPlus.cpp
-  CommonABIRuntime.cpp
   CPPLanguageRuntime.cpp
   ItaniumABIRuntime.cpp
   VerboseTrapFrameRecognizer.cpp

diff  --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
index 2b657796c4f5e..c517ec8611932 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp
@@ -13,7 +13,6 @@
 
 #include "CPPLanguageRuntime.h"
 #include "CommandObjectCPlusPlus.h"
-#include "ItaniumABIRuntime.h"
 #include "VerboseTrapFrameRecognizer.h"
 
 #include "llvm/ADT/StringRef.h"
@@ -33,7 +32,6 @@
 #include "lldb/Target/StackFrameRecognizer.h"
 #include "lldb/Target/ThreadPlanRunToAddress.h"
 #include "lldb/Target/ThreadPlanStepInRange.h"
-#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Timer.h"
 
 using namespace lldb;
@@ -112,7 +110,7 @@ class LibCXXFrameRecognizer : public StackFrameRecognizer {
 };
 
 CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
-    : LanguageRuntime(process) {
+    : LanguageRuntime(process), m_itanium_runtime(process) {
   if (process) {
     process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
         StackFrameRecognizerSP(new LibCXXFrameRecognizer()), {},
@@ -122,7 +120,6 @@ CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
 
     RegisterVerboseTrapFrameRecognizer(*process);
   }
-  m_abi_runtimes.emplace_back(std::make_unique<ItaniumABIRuntime>(process));
 }
 
 bool CPPLanguageRuntime::IsAllowedRuntimeValue(ConstString name) {
@@ -527,15 +524,8 @@ bool CPPLanguageRuntime::GetDynamicTypeAndAddress(
   if (!CouldHaveDynamicValue(in_value))
     return false;
 
-  llvm::Expected<VTableInfoEntry> entry =
-      GetVTableInfoEntry(in_value, /*check_type=*/false);
-  if (!entry) {
-    llvm::consumeError(entry.takeError());
-    return false;
-  }
-
-  return entry->runtime->GetDynamicTypeAndAddress(
-      in_value, use_dynamic, entry->info, class_type_or_name, dynamic_address);
+  return m_itanium_runtime.GetDynamicTypeAndAddress(
+      in_value, use_dynamic, class_type_or_name, dynamic_address, value_type);
 }
 
 TypeAndOrName
@@ -598,11 +588,7 @@ void CPPLanguageRuntime::Terminate() {
 
 llvm::Expected<LanguageRuntime::VTableInfo>
 CPPLanguageRuntime::GetVTableInfo(ValueObject &in_value, bool check_type) {
-  llvm::Expected<VTableInfoEntry> entry =
-      GetVTableInfoEntry(in_value, check_type);
-  if (!entry)
-    return entry.takeError();
-  return entry->info;
+  return m_itanium_runtime.GetVTableInfo(in_value, check_type);
 }
 
 BreakpointResolverSP
@@ -616,10 +602,8 @@ CPPLanguageRuntime::CreateExceptionResolver(const 
BreakpointSP &bkpt,
                                             bool catch_bp, bool throw_bp,
                                             bool for_expressions) {
   std::vector<const char *> exception_names;
-  for (const auto &runtime : m_abi_runtimes) {
-    runtime->AppendExceptionBreakpointFunctions(exception_names, catch_bp,
-                                                throw_bp, for_expressions);
-  }
+  m_itanium_runtime.AppendExceptionBreakpointFunctions(
+      exception_names, catch_bp, throw_bp, for_expressions);
 
   BreakpointResolverSP resolver_sp(new BreakpointResolverName(
       bkpt, exception_names.data(), exception_names.size(),
@@ -632,9 +616,8 @@ lldb::SearchFilterSP 
CPPLanguageRuntime::CreateExceptionSearchFilter() {
   Target &target = m_process->GetTarget();
 
   FileSpecList filter_modules;
-  for (const auto &runtime : m_abi_runtimes)
-    runtime->AppendExceptionBreakpointFilterModules(filter_modules, target);
-
+  m_itanium_runtime.AppendExceptionBreakpointFilterModules(filter_modules,
+                                                           target);
   return target.GetSearchFilterForModuleList(&filter_modules);
 }
 
@@ -701,127 +684,5 @@ bool CPPLanguageRuntime::ExceptionBreakpointsExplainStop(
 
 lldb::ValueObjectSP
 CPPLanguageRuntime::GetExceptionObjectForThread(lldb::ThreadSP thread_sp) {
-  for (auto &runtime : m_abi_runtimes) {
-    ValueObjectSP valobj = runtime->GetExceptionObjectForThread(thread_sp);
-    if (valobj)
-      return valobj;
-  }
-  return {};
-}
-
-static llvm::Error typeHasVTable(CompilerType type) {
-  // Check to make sure the class has a vtable.
-  CompilerType original_type = type;
-  if (type.IsPointerOrReferenceType()) {
-    CompilerType pointee_type = type.GetPointeeType();
-    if (pointee_type)
-      type = pointee_type;
-  }
-
-  // Make sure this is a class or a struct first by checking the type class
-  // bitfield that gets returned.
-  if ((type.GetTypeClass() & (eTypeClassStruct | eTypeClassClass)) == 0) {
-    return llvm::createStringError(
-        std::errc::invalid_argument,
-        "type \"%s\" is not a class or struct or a pointer to one",
-        original_type.GetTypeName().AsCString("<invalid>"));
-  }
-
-  // Check if the type has virtual functions by asking it if it is polymorphic.
-  if (!type.IsPolymorphicClass()) {
-    return llvm::createStringError(std::errc::invalid_argument,
-                                   "type \"%s\" doesn't have a vtable",
-                                   type.GetTypeName().AsCString("<invalid>"));
-  }
-  return llvm::Error::success();
-}
-
-// This function can accept both pointers or references to classes as well as
-// instances of classes. If you are using this function during dynamic type
-// detection, only valid ValueObjects that return true to
-// CouldHaveDynamicValue(...) should call this function and \a check_type
-// should be set to false. This function is also used by ValueObjectVTable
-// and is can pass in instances of classes which is not suitable for dynamic
-// type detection, these cases should pass true for \a check_type.
-llvm::Expected<CPPLanguageRuntime::VTableInfoEntry>
-CPPLanguageRuntime::GetVTableInfoEntry(ValueObject &in_value, bool check_type) 
{
-  CompilerType type = in_value.GetCompilerType();
-  if (check_type) {
-    if (llvm::Error err = typeHasVTable(type))
-      return std::move(err);
-  }
-  ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
-  Process *process = exe_ctx.GetProcessPtr();
-  if (process == nullptr)
-    return llvm::createStringError(std::errc::invalid_argument,
-                                   "invalid process");
-
-  auto [original_ptr, address_type] =
-      type.IsPointerOrReferenceType()
-          ? in_value.GetPointerValue()
-          : in_value.GetAddressOf(/*scalar_is_load_address=*/true);
-  if (original_ptr == LLDB_INVALID_ADDRESS || address_type != eAddressTypeLoad)
-    return llvm::createStringError(std::errc::invalid_argument,
-                                   "failed to get the address of the value");
-
-  Status error;
-  lldb::addr_t vtable_load_addr =
-      process->ReadPointerFromMemory(original_ptr, error);
-
-  if (!error.Success() || vtable_load_addr == LLDB_INVALID_ADDRESS)
-    return llvm::createStringError(
-        std::errc::invalid_argument,
-        "failed to read vtable pointer from memory at 0x%" PRIx64,
-        original_ptr);
-
-  // The vtable load address can have authentication bits with
-  // AArch64 targets on Darwin.
-  vtable_load_addr = process->FixDataAddress(vtable_load_addr);
-
-  // Find the symbol that contains the "vtable_load_addr" address
-  Address vtable_addr;
-  if (!process->GetTarget().ResolveLoadAddress(vtable_load_addr, vtable_addr))
-    return llvm::createStringError(std::errc::invalid_argument,
-                                   "failed to resolve vtable pointer 0x%" 
PRIx64
-                                   " to a section",
-                                   vtable_load_addr);
-
-  // Check our cache first to see if we already have this info
-  {
-    std::lock_guard<std::mutex> locker(m_vtable_mutex);
-    auto pos = m_vtable_info_map.find(vtable_addr);
-    if (pos != m_vtable_info_map.end())
-      return pos->second;
-  }
-
-  Symbol *symbol = vtable_addr.CalculateSymbolContextSymbol();
-  if (symbol == nullptr)
-    return llvm::createStringError(std::errc::invalid_argument,
-                                   "no symbol found for 0x%" PRIx64,
-                                   vtable_load_addr);
-  Mangled &mangled = symbol->GetMangled();
-  Log *log = GetLog(LLDBLog::Object);
-  for (const auto &runtime : m_abi_runtimes) {
-    if (runtime->IsVTableSymbol(mangled)) {
-      LLDB_LOG(log, "{0:x16} ({1}): symbol='{2}' matches {3}", original_ptr,
-               in_value.GetTypeName(), mangled.GetDemangledName(),
-               runtime->GetName());
-
-      VTableInfoEntry entry{
-          /*info=*/VTableInfo{vtable_addr, symbol},
-          /*runtime=*/runtime.get(),
-      };
-      std::lock_guard<std::mutex> locker(m_vtable_mutex);
-      m_vtable_info_map[vtable_addr] = entry;
-      return entry;
-    }
-  }
-
-  LLDB_LOG(log, "{0:x16} ({1}): symbol='{2}' does not match any runtime",
-           original_ptr, in_value.GetTypeName(), mangled.GetDemangledName());
-
-  return llvm::createStringError(std::errc::invalid_argument,
-                                 "symbol found that contains 0x%" PRIx64
-                                 " is not a vtable symbol",
-                                 vtable_load_addr);
+  return m_itanium_runtime.GetExceptionObjectForThread(std::move(thread_sp));
 }

diff  --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
index 823a968cbad8c..7c3dade76d703 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h
@@ -13,7 +13,7 @@
 
 #include "llvm/ADT/StringMap.h"
 
-#include "CommonABIRuntime.h"
+#include "ItaniumABIRuntime.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/lldb-private.h"
@@ -143,18 +143,7 @@ class CPPLanguageRuntime : public LanguageRuntime {
   OperatorStringToCallableInfoMap CallableLookupCache;
 
   lldb::BreakpointSP m_cxx_exception_bp_sp;
-  std::vector<std::unique_ptr<CommonABIRuntime>> m_abi_runtimes;
-
-  struct VTableInfoEntry {
-    VTableInfo info;
-    CommonABIRuntime *runtime;
-  };
-
-  llvm::Expected<VTableInfoEntry> GetVTableInfoEntry(ValueObject &in_value,
-                                                     bool check_type);
-
-  std::map<Address, VTableInfoEntry> m_vtable_info_map;
-  std::mutex m_vtable_mutex;
+  ItaniumABIRuntime m_itanium_runtime;
 };
 
 } // namespace lldb_private

diff  --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp
deleted file mode 100644
index e1241c0b583aa..0000000000000
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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) {}
-
-bool CommonABIRuntime::IsVTableSymbol(Mangled &mangled) const { return false; }
-
-bool CommonABIRuntime::GetDynamicTypeAndAddress(
-    ValueObject &in_value, lldb::DynamicValueType use_dynamic,
-    const LanguageRuntime::VTableInfo &vtable_info,
-    TypeAndOrName &class_type_or_name, Address &dynamic_address) {
-  return false;
-}
-
-void CommonABIRuntime::AppendExceptionBreakpointFunctions(
-    std::vector<const char *> &names, bool catch_bp, bool throw_bp,
-    bool for_expressions) {}
-
-void CommonABIRuntime::AppendExceptionBreakpointFilterModules(
-    FileSpecList &list, const Target &target) {}
-
-lldb::ValueObjectSP
-CommonABIRuntime::GetExceptionObjectForThread(lldb::ThreadSP thread_sp) {
-  return {};
-}
-
-lldb::TypeSP
-CommonABIRuntime::LookupTypeByName(llvm::StringRef type_name,
-                                   lldb::ModuleSP preferred_module) const {
-  Log *log = GetLog(LLDBLog::Object);
-
-  TypeList class_types;
-  // We know the class name is absolute, so tell FindTypes that by
-  // prefixing it with the root namespace:
-  std::string lookup_name("::");
-  lookup_name.append(type_name.data(), type_name.size());
-  ConstString const_lookup_name(lookup_name);
-  // 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 {};
-  }
-
-  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;
-  }
-
-  size_t i;
-  if (log) {
-    LLDB_LOG(log,
-             "'{0}' has multiple matching dynamic "
-             "types:",
-             type_name);
-    for (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 (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;
-}

diff  --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h
deleted file mode 100644
index b387ff0f8da8e..0000000000000
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CommonABIRuntime.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_COMMONABIRUNTIME_H
-#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_COMMONABIRUNTIME_H
-
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/Process.h"
-#include "lldb/ValueObject/ValueObject.h"
-
-#include <map>
-#include <mutex>
-
-namespace lldb_private {
-
-class CommonABIRuntime {
-public:
-  virtual ~CommonABIRuntime() = default;
-
-  virtual llvm::StringRef GetName() const = 0;
-
-  virtual bool IsVTableSymbol(Mangled &mangled) const;
-
-  virtual bool GetDynamicTypeAndAddress(
-      ValueObject &in_value, lldb::DynamicValueType use_dynamic,
-      const LanguageRuntime::VTableInfo &vtable_info,
-      TypeAndOrName &class_type_or_name, Address &dynamic_address);
-
-  virtual void
-  AppendExceptionBreakpointFunctions(std::vector<const char *> &names,
-                                     bool catch_bp, bool throw_bp,
-                                     bool for_expressions);
-
-  virtual void AppendExceptionBreakpointFilterModules(FileSpecList &list,
-                                                      const Target &target);
-
-  virtual lldb::ValueObjectSP
-  GetExceptionObjectForThread(lldb::ThreadSP thread_sp);
-
-protected:
-  CommonABIRuntime(Process *process);
-
-  lldb::TypeSP LookupTypeByName(llvm::StringRef type_name,
-                                lldb::ModuleSP preferred_module) const;
-
-  TypeAndOrName GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
-
-  void SetDynamicTypeInfo(const lldb_private::Address &vtable_addr,
-                          const TypeAndOrName &type_info);
-
-protected:
-  Process *m_process;
-  std::mutex m_mutex;
-
-private:
-  using DynamicTypeCache = std::map<Address, TypeAndOrName>;
-
-  DynamicTypeCache m_dynamic_type_map;
-};
-
-} // namespace lldb_private
-
-#endif

diff  --git 
a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
index 1fc835fa834db..4d9cf31c8904d 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.cpp
@@ -19,13 +19,7 @@ using namespace lldb_private;
 
 static const char *vtable_demangled_prefix = "vtable for ";
 
-ItaniumABIRuntime::ItaniumABIRuntime(Process *process)
-    : CommonABIRuntime(process) {}
-
-bool ItaniumABIRuntime::IsVTableSymbol(Mangled &mangled) const {
-  return mangled.GetDemangledName().GetStringRef().starts_with(
-      vtable_demangled_prefix);
-}
+ItaniumABIRuntime::ItaniumABIRuntime(Process *process) : m_process(process) {}
 
 TypeAndOrName
 ItaniumABIRuntime::GetTypeInfo(ValueObject &in_value,
@@ -55,16 +49,94 @@ ItaniumABIRuntime::GetTypeInfo(ValueObject &in_value,
       lookup_name.append(class_name.data(), class_name.size());
 
       type_info.SetName(class_name);
-      TypeSP type_sp = LookupTypeByName(
-          class_name, vtable_info.symbol->CalculateSymbolContextModule());
-      if (type_sp) {
-        LLDB_LOG(
-            log,
-            "static-type = '{0}' has dynamic type: uid={1:x}, type-name='{2}'",
-            in_value.GetTypeName(), type_sp->GetID(), type_sp->GetName());
-        type_info.SetTypeSP(std::move(type_sp));
+      ConstString const_lookup_name(lookup_name);
+      TypeList class_types;
+      ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
+      // 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 (module_sp) {
+        module_sp->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_LOGF(log, "0x%16.16" PRIx64 ": is not dynamic\n",
+                  in_value.GetPointerValue().address);
+        return TypeAndOrName();
+      }
+      if (class_types.GetSize() == 1) {
+        type_sp = class_types.GetTypeAtIndex(0);
+        if (type_sp) {
+          if (TypeSystemClang::IsCXXClassType(
+                  type_sp->GetForwardCompilerType())) {
+            LLDB_LOGF(log,
+                      "0x%16.16" PRIx64
+                      ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
+                      "}, type-name='%s'\n",
+                      in_value.GetPointerValue().address,
+                      in_value.GetTypeName().AsCString(""), type_sp->GetID(),
+                      type_sp->GetName().GetCString());
+            type_info.SetTypeSP(type_sp);
+          }
+        }
+      } else {
+        size_t i;
+        if (log) {
+          for (i = 0; i < class_types.GetSize(); i++) {
+            type_sp = class_types.GetTypeAtIndex(i);
+            if (type_sp) {
+              LLDB_LOGF(log,
+                        "0x%16.16" PRIx64
+                        ": static-type = '%s' has multiple matching dynamic "
+                        "types: uid={0x%" PRIx64 "}, type-name='%s'\n",
+                        in_value.GetPointerValue().address,
+                        in_value.GetTypeName().AsCString(""), type_sp->GetID(),
+                        type_sp->GetName().GetCString());
+            }
+          }
+        }
+
+        for (i = 0; i < class_types.GetSize(); i++) {
+          type_sp = class_types.GetTypeAtIndex(i);
+          if (type_sp) {
+            if (TypeSystemClang::IsCXXClassType(
+                    type_sp->GetForwardCompilerType())) {
+              LLDB_LOGF(log,
+                        "0x%16.16" PRIx64 ": static-type = '%s' has multiple "
+                        "matching dynamic types, picking "
+                        "this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
+                        in_value.GetPointerValue().address,
+                        in_value.GetTypeName().AsCString(""), type_sp->GetID(),
+                        type_sp->GetName().GetCString());
+              type_info.SetTypeSP(type_sp);
+            }
+          }
+        }
+
+        LLDB_LOGF(log,
+                  "0x%16.16" PRIx64
+                  ": static-type = '%s' has multiple matching dynamic "
+                  "types, didn't find a C++ match\n",
+                  in_value.GetPointerValue().address,
+                  in_value.GetTypeName().AsCString(""));
+      }
       if (type_info)
         SetDynamicTypeInfo(vtable_info.addr, type_info);
       return type_info;
@@ -73,10 +145,114 @@ ItaniumABIRuntime::GetTypeInfo(ValueObject &in_value,
   return TypeAndOrName();
 }
 
+llvm::Error ItaniumABIRuntime::TypeHasVTable(CompilerType type) {
+  // Check to make sure the class has a vtable.
+  CompilerType original_type = type;
+  if (type.IsPointerOrReferenceType()) {
+    CompilerType pointee_type = type.GetPointeeType();
+    if (pointee_type)
+      type = pointee_type;
+  }
+
+  // Make sure this is a class or a struct first by checking the type class
+  // bitfield that gets returned.
+  if ((type.GetTypeClass() & (eTypeClassStruct | eTypeClassClass)) == 0) {
+    return llvm::createStringError(
+        std::errc::invalid_argument,
+        "type \"%s\" is not a class or struct or a pointer to one",
+        original_type.GetTypeName().AsCString("<invalid>"));
+  }
+
+  // Check if the type has virtual functions by asking it if it is polymorphic.
+  if (!type.IsPolymorphicClass()) {
+    return llvm::createStringError(std::errc::invalid_argument,
+                                   "type \"%s\" doesn't have a vtable",
+                                   type.GetTypeName().AsCString("<invalid>"));
+  }
+  return llvm::Error::success();
+}
+
+// This function can accept both pointers or references to classes as well as
+// instances of classes. If you are using this function during dynamic type
+// detection, only valid ValueObjects that return true to
+// CouldHaveDynamicValue(...) should call this function and \a check_type
+// should be set to false. This function is also used by ValueObjectVTable
+// and is can pass in instances of classes which is not suitable for dynamic
+// type detection, these cases should pass true for \a check_type.
+llvm::Expected<LanguageRuntime::VTableInfo>
+ItaniumABIRuntime::GetVTableInfo(ValueObject &in_value, bool check_type) {
+
+  CompilerType type = in_value.GetCompilerType();
+  if (check_type) {
+    if (llvm::Error err = TypeHasVTable(type))
+      return std::move(err);
+  }
+  ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+  Process *process = exe_ctx.GetProcessPtr();
+  if (process == nullptr)
+    return llvm::createStringError(std::errc::invalid_argument,
+                                   "invalid process");
+
+  auto [original_ptr, address_type] =
+      type.IsPointerOrReferenceType()
+          ? in_value.GetPointerValue()
+          : in_value.GetAddressOf(/*scalar_is_load_address=*/true);
+  if (original_ptr == LLDB_INVALID_ADDRESS || address_type != eAddressTypeLoad)
+    return llvm::createStringError(std::errc::invalid_argument,
+                                   "failed to get the address of the value");
+
+  Status error;
+  lldb::addr_t vtable_load_addr =
+      process->ReadPointerFromMemory(original_ptr, error);
+
+  if (!error.Success() || vtable_load_addr == LLDB_INVALID_ADDRESS)
+    return llvm::createStringError(
+        std::errc::invalid_argument,
+        "failed to read vtable pointer from memory at 0x%" PRIx64,
+        original_ptr);
+
+  // The vtable load address can have authentication bits with
+  // AArch64 targets on Darwin.
+  vtable_load_addr = process->FixDataAddress(vtable_load_addr);
+
+  // Find the symbol that contains the "vtable_load_addr" address
+  Address vtable_addr;
+  if (!process->GetTarget().ResolveLoadAddress(vtable_load_addr, vtable_addr))
+    return llvm::createStringError(std::errc::invalid_argument,
+                                   "failed to resolve vtable pointer 0x%" 
PRIx64
+                                   "to a section",
+                                   vtable_load_addr);
+
+  // Check our cache first to see if we already have this info
+  {
+    std::lock_guard<std::mutex> locker(m_mutex);
+    auto pos = m_vtable_info_map.find(vtable_addr);
+    if (pos != m_vtable_info_map.end())
+      return pos->second;
+  }
+
+  Symbol *symbol = vtable_addr.CalculateSymbolContextSymbol();
+  if (symbol == nullptr)
+    return llvm::createStringError(std::errc::invalid_argument,
+                                   "no symbol found for 0x%" PRIx64,
+                                   vtable_load_addr);
+  llvm::StringRef name = 
symbol->GetMangled().GetDemangledName().GetStringRef();
+  if (name.starts_with(vtable_demangled_prefix)) {
+    LanguageRuntime::VTableInfo info = {vtable_addr, symbol};
+    std::lock_guard<std::mutex> locker(m_mutex);
+    auto pos = m_vtable_info_map[vtable_addr] = info;
+    return info;
+  }
+  return llvm::createStringError(std::errc::invalid_argument,
+                                 "symbol found that contains 0x%" PRIx64
+                                 " is not a vtable symbol",
+                                 vtable_load_addr);
+}
+
 bool ItaniumABIRuntime::GetDynamicTypeAndAddress(
     ValueObject &in_value, lldb::DynamicValueType use_dynamic,
-    const LanguageRuntime::VTableInfo &vtable_info,
-    TypeAndOrName &class_type_or_name, Address &dynamic_address) {
+    TypeAndOrName &class_type_or_name, Address &dynamic_address,
+    Value::ValueType &value_type) {
   // For Itanium, if the type has a vtable pointer in the object, it will be at
   // offset 0 in the object.  That will point to the "address point" within the
   // vtable (not the beginning of the vtable.)  We can then look up the symbol
@@ -90,6 +266,14 @@ bool ItaniumABIRuntime::GetDynamicTypeAndAddress(
   // want GetVTableInfo to check the type since we accept void * as a possible
   // dynamic type and that won't pass the type check. We already checked the
   // type above in CouldHaveDynamicValue(...).
+  llvm::Expected<LanguageRuntime::VTableInfo> vtable_info_or_err =
+      GetVTableInfo(in_value, /*check_type=*/false);
+  if (!vtable_info_or_err) {
+    llvm::consumeError(vtable_info_or_err.takeError());
+    return false;
+  }
+
+  const LanguageRuntime::VTableInfo &vtable_info = vtable_info_or_err.get();
   class_type_or_name = GetTypeInfo(in_value, vtable_info);
 
   if (!class_type_or_name)
@@ -248,3 +432,19 @@ ItaniumABIRuntime::GetExceptionObjectForThread(ThreadSP 
thread_sp) {
 
   return exception;
 }
+
+TypeAndOrName ItaniumABIRuntime::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();
+  else
+    return pos->second;
+}
+
+void ItaniumABIRuntime::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;
+}

diff  --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h 
b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h
index e44e958da4067..75a8142b26d93 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABIRuntime.h
@@ -9,7 +9,6 @@
 #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABIRUNTIME_H
 #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_CPLUSPLUS_ITANIUMABIRUNTIME_H
 
-#include "CommonABIRuntime.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/ValueObject/ValueObject.h"
 
@@ -17,40 +16,47 @@
 
 namespace lldb_private {
 
-class ItaniumABIRuntime : public CommonABIRuntime {
+class ItaniumABIRuntime {
 public:
   ItaniumABIRuntime(Process *process);
 
-  llvm::StringRef GetName() const override { return "Itanium ABI runtime"; }
-
-  bool IsVTableSymbol(Mangled &manged) const override;
-
   llvm::Expected<LanguageRuntime::VTableInfo>
   GetVTableInfo(ValueObject &in_value, bool check_type);
 
   bool GetDynamicTypeAndAddress(ValueObject &in_value,
                                 lldb::DynamicValueType use_dynamic,
-                                const LanguageRuntime::VTableInfo &vtable_info,
                                 TypeAndOrName &class_type_or_name,
-                                Address &dynamic_address) override;
+                                Address &dynamic_address,
+                                Value::ValueType &value_type);
 
   void AppendExceptionBreakpointFunctions(std::vector<const char *> &names,
                                           bool catch_bp, bool throw_bp,
-                                          bool for_expressions) override;
+                                          bool for_expressions);
 
   void AppendExceptionBreakpointFilterModules(FileSpecList &list,
-                                              const Target &target) override;
+                                              const Target &target);
 
-  lldb::ValueObjectSP
-  GetExceptionObjectForThread(lldb::ThreadSP thread_sp) override;
+  lldb::ValueObjectSP GetExceptionObjectForThread(lldb::ThreadSP thread_sp);
 
 private:
   TypeAndOrName GetTypeInfo(ValueObject &in_value,
                             const LanguageRuntime::VTableInfo &vtable_info);
 
+  llvm::Error TypeHasVTable(CompilerType type);
+
+  TypeAndOrName GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
+
+  void SetDynamicTypeInfo(const lldb_private::Address &vtable_addr,
+                          const TypeAndOrName &type_info);
+
+  using DynamicTypeCache = std::map<Address, TypeAndOrName>;
   using VTableInfoCache = std::map<Address, LanguageRuntime::VTableInfo>;
 
+  DynamicTypeCache m_dynamic_type_map;
   VTableInfoCache m_vtable_info_map;
+  std::mutex m_mutex;
+
+  Process *m_process;
 };
 
 } // namespace lldb_private


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to