diff options
5 files changed, 79 insertions, 1 deletions
diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h index 937a5165cd3..d557a35d0b0 100644 --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -294,6 +294,10 @@ private: const std::vector<SearchSpec> &C_specs, const SymbolContext &sc); + void + CollectFallbackNames(std::vector<SearchSpec> &fallback_specs, + const std::vector<SearchSpec> &C_specs); + lldb::addr_t FindInSymbols(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc); diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/Makefile b/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/Makefile new file mode 100644 index 00000000000..cd9ca5c86d8 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/Makefile @@ -0,0 +1,3 @@ +LEVEL = ../../../make +C_SOURCES := main.c +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py b/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py new file mode 100644 index 00000000000..f08c0dcbda9 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), []) diff --git a/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp b/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp new file mode 100644 index 00000000000..a4006c2f7ed --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp @@ -0,0 +1,29 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> +#include <stdint.h> + +extern "C" +{ + int foo(); +}; + +int foo() +{ + puts("foo"); + return 2; +} + +int main (int argc, char const *argv[], char const *envp[]) +{ + foo(); + return 0; //% self.expect("expression -- foo()", substrs = ['2']) +} + diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index 69f4ee3d174..7550b76d19e 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -758,7 +758,7 @@ struct IRExecutionUnit::SearchSpec ConstString name; uint32_t mask; - SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeAuto) : + SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeFull) : name(n), mask(m) { @@ -819,6 +819,36 @@ IRExecutionUnit::CollectCandidateCPlusPlusNames(std::vector<IRExecutionUnit::Sea } } +void +IRExecutionUnit::CollectFallbackNames(std::vector<SearchSpec> &fallback_specs, + const std::vector<SearchSpec> &C_specs) +{ + // As a last-ditch fallback, try the base name for C++ names. It's terrible, + // but the DWARF doesn't always encode "extern C" correctly. + + for (const SearchSpec &C_spec : C_specs) + { + const ConstString &name = C_spec.name; + + if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) + { + Mangled mangled_name(name); + ConstString demangled_name = mangled_name.GetDemangledName(lldb::eLanguageTypeC_plus_plus); + if (!demangled_name.IsEmpty()) + { + const char *demangled_cstr = demangled_name.AsCString(); + const char *lparen_loc = strchr(demangled_cstr, '('); + if (lparen_loc) + { + llvm::StringRef base_name(demangled_cstr, lparen_loc-demangled_cstr); + fallback_specs.push_back(ConstString(base_name)); + } + } + } + } +} + + lldb::addr_t IRExecutionUnit::FindInSymbols(const std::vector<IRExecutionUnit::SearchSpec> &specs, const lldb_private::SymbolContext &sc) { @@ -1019,6 +1049,14 @@ IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name) CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, m_sym_ctx); ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx); } + + if (ret == LLDB_INVALID_ADDRESS) + { + std::vector<SearchSpec> candidate_fallback_names; + + CollectFallbackNames(candidate_fallback_names, candidate_C_names); + ret = FindInSymbols(candidate_fallback_names, m_sym_ctx); + } return ret; } |