diff options
author | Jim Ingham <jingham@apple.com> | 2015-11-06 22:48:59 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2015-11-06 22:48:59 +0000 |
commit | 0fcdac363cbff6c16cf205cc88e072e82bbf8975 (patch) | |
tree | 1e90db3b67c17ae66fe0c205e47535fbcd2e431f | |
parent | 569aaf9e1a22df61f15ac7840fc8800f8c948de0 (diff) | |
download | bcm5719-llvm-0fcdac363cbff6c16cf205cc88e072e82bbf8975.tar.gz bcm5719-llvm-0fcdac363cbff6c16cf205cc88e072e82bbf8975.zip |
Make the language specifier to "break set" actually filter the names by their language. So for
instance:
break set -l c++ -r Name
will only break on C++ symbols that match Name, not ObjC or plain C symbols. This also works
for "break set -n" and there are SB API's to pass this as well.
llvm-svn: 252356
15 files changed, 278 insertions, 47 deletions
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 5481c6293be..6bd2c3dba7e 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -636,6 +636,13 @@ public: const SBFileSpecList &comp_unit_list); lldb::SBBreakpoint + BreakpointCreateByName (const char *symbol_name, + uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits + lldb::LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + + lldb::SBBreakpoint BreakpointCreateByNames (const char *symbol_name[], uint32_t num_names, uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits @@ -643,7 +650,15 @@ public: const SBFileSpecList &comp_unit_list); lldb::SBBreakpoint - BreakpointCreateByRegex(const char *symbol_name_regex, const char *module_name = nullptr); + BreakpointCreateByNames (const char *symbol_name[], + uint32_t num_names, + uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits + lldb::LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + + lldb::SBBreakpoint + BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = nullptr); lldb::SBBreakpoint BreakpointCreateByRegex (const char *symbol_name_regex, @@ -651,6 +666,12 @@ public: const SBFileSpecList &comp_unit_list); lldb::SBBreakpoint + BreakpointCreateByRegex (const char *symbol_name_regex, + lldb::LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + + lldb::SBBreakpoint BreakpointCreateBySourceRegex(const char *source_regex, const SBFileSpec &source_file, const char *module_name = nullptr); diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h index 4d9c4b1ec98..aaae9c1a12c 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h @@ -57,6 +57,7 @@ public: // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex. BreakpointResolverName (Breakpoint *bkpt, RegularExpression &func_regex, + lldb::LanguageType language, bool skip_prologue); BreakpointResolverName (Breakpoint *bkpt, diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h index 686ec5ea347..f94517f0f4a 100644 --- a/lldb/include/lldb/Target/LanguageRuntime.h +++ b/lldb/include/lldb/Target/LanguageRuntime.h @@ -117,6 +117,9 @@ public: return m_process; } + static lldb::LanguageType + GetLanguageForSymbolByName (Target &target, const char *symbol_name); + Target& GetTargetRef() { diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 1de77b46454..6708c6c19ad 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -791,6 +791,7 @@ public: CreateFuncRegexBreakpoint (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, RegularExpression &func_regexp, + lldb::LanguageType requested_language, LazyBool skip_prologue, bool internal, bool request_hardware); diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile new file mode 100644 index 00000000000..4f6b058fa32 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := a.c +CXX_SOURCES := main.cpp b.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py new file mode 100644 index 00000000000..94fc7bf79f6 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/TestBreakpointLanguage.py @@ -0,0 +1,85 @@ +""" +Test that the language option for breakpoints works correctly +parser. +""" + +from __future__ import print_function + + + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +import shutil +import subprocess + +class TestBreakpointLanguage(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + + def check_location_file (self, bp, loc, test_name): + bp_loc = bp.GetLocationAtIndex(loc) + addr = bp_loc.GetAddress() + comp_unit = addr.GetCompileUnit() + comp_name = comp_unit.GetFileSpec().GetFilename() + return comp_name == test_name + + def test_regex_breakpoint_language(self): + """Test that the name regex breakpoint commands obey the language filter.""" + + self.build() + # Create a target by the debugger. + exe = os.path.join(os.getcwd(), "a.out") + error = lldb.SBError() + # Don't read in dependencies so we don't come across false matches that + # add unwanted breakpoint hits. + self.target = self.dbg.CreateTarget(exe, None, None, False, error) + self.assertTrue(self.target, VALID_TARGET) + + cpp_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(cpp_bp.GetNumLocations() == 1, "Only one C++ symbol matches") + self.assertTrue(self.check_location_file(cpp_bp, 0, "b.cpp")) + + c_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(c_bp.GetNumLocations() == 1, "Only one C symbol matches") + self.assertTrue(self.check_location_file(c_bp, 0, "a.c")) + + objc_bp = self.target.BreakpointCreateByRegex("func_from", lldb.eLanguageTypeObjC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(objc_bp.GetNumLocations() == 0, "No ObjC symbol matches") + + def test_by_name_breakpoint_language(self): + """Test that the name regex breakpoint commands obey the language filter.""" + + self.build() + # Create a target by the debugger. + exe = os.path.join(os.getcwd(), "a.out") + error = lldb.SBError() + # Don't read in dependencies so we don't come across false matches that + # add unwanted breakpoint hits. + self.target = self.dbg.CreateTarget(exe, None, None, False, error) + self.assertTrue(self.target, VALID_TARGET) + + cpp_bp = self.target.BreakpointCreateByName("func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(cpp_bp.GetNumLocations() == 1, "Only one C++ symbol matches") + self.assertTrue(self.check_location_file(cpp_bp, 0, "b.cpp")) + + no_cpp_bp = self.target.BreakpointCreateByName("func_from_c", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC_plus_plus, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(no_cpp_bp.GetNumLocations() == 0, "And the C one doesn't match") + + c_bp = self.target.BreakpointCreateByName("func_from_c", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(c_bp.GetNumLocations() == 1, "Only one C symbol matches") + self.assertTrue(self.check_location_file(c_bp, 0, "a.c")) + + no_c_bp = self.target.BreakpointCreateByName("func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(no_c_bp.GetNumLocations() == 0, "And the C++ one doesn't match") + + objc_bp = self.target.BreakpointCreateByName("func_from_cpp", lldb.eFunctionNameTypeAuto, lldb.eLanguageTypeObjC, lldb.SBFileSpecList(), lldb.SBFileSpecList()) + self.assertTrue(objc_bp.GetNumLocations() == 0, "No ObjC symbol matches") + + diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c new file mode 100644 index 00000000000..b90e2bdcca5 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/a.c @@ -0,0 +1,5 @@ +int +func_from_c () +{ + return 5; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp new file mode 100644 index 00000000000..89373445b9a --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/b.cpp @@ -0,0 +1,5 @@ +int +func_from_cpp() +{ + return 10; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp new file mode 100644 index 00000000000..b7d00a60202 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_language/main.cpp @@ -0,0 +1,11 @@ +#include <stdio.h> +extern "C" int func_from_c(); +extern int func_from_cpp(); + +int +main() +{ + func_from_c(); + func_from_cpp(); + return 0; +} diff --git a/lldb/scripts/interface/SBTarget.i b/lldb/scripts/interface/SBTarget.i index 2a19ebd7378..e71f2563b84 100644 --- a/lldb/scripts/interface/SBTarget.i +++ b/lldb/scripts/interface/SBTarget.i @@ -595,9 +595,24 @@ public: const SBFileSpecList &comp_unit_list); lldb::SBBreakpoint + BreakpointCreateByName (const char *symbol_name, + uint32_t func_name_type, // Logical OR one or more FunctionNameType enum bits + lldb::LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + + lldb::SBBreakpoint + BreakpointCreateByNames (const char *symbol_name[], + uint32_t num_names, + uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + + lldb::SBBreakpoint BreakpointCreateByNames (const char *symbol_name[], uint32_t num_names, uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits + lldb::LanguageType symbol_language, const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list); @@ -605,6 +620,12 @@ public: BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL); lldb::SBBreakpoint + BreakpointCreateByRegex (const char *symbol_name_regex, + lldb::LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + + lldb::SBBreakpoint BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name = NULL); lldb::SBBreakpoint diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index a15b654246d..8a63ea304bb 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -870,7 +870,7 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, const SBFileSpecList &comp_unit_list) { uint32_t name_type_mask = eFunctionNameTypeAuto; - return BreakpointCreateByName (symbol_name, name_type_mask, module_list, comp_unit_list); + return BreakpointCreateByName (symbol_name, name_type_mask, eLanguageTypeUnknown, module_list, comp_unit_list); } lldb::SBBreakpoint @@ -879,6 +879,16 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) { + return BreakpointCreateByName (symbol_name, name_type_mask, eLanguageTypeUnknown, module_list, comp_unit_list); +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateByName (const char *symbol_name, + uint32_t name_type_mask, + LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list) +{ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBBreakpoint sb_bp; @@ -893,7 +903,7 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, comp_unit_list.get(), symbol_name, name_type_mask, - eLanguageTypeUnknown, + symbol_language, skip_prologue, internal, hardware); @@ -914,6 +924,17 @@ SBTarget::BreakpointCreateByNames (const char *symbol_names[], const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) { + return BreakpointCreateByNames(symbol_names, num_names, name_type_mask, eLanguageTypeUnknown, module_list, comp_unit_list); +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateByNames (const char *symbol_names[], + uint32_t num_names, + uint32_t name_type_mask, + LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list) +{ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBBreakpoint sb_bp; @@ -925,14 +946,14 @@ SBTarget::BreakpointCreateByNames (const char *symbol_names[], const bool hardware = false; const LazyBool skip_prologue = eLazyBoolCalculate; *sb_bp = target_sp->CreateBreakpoint (module_list.get(), - comp_unit_list.get(), - symbol_names, - num_names, - name_type_mask, - eLanguageTypeUnknown, - skip_prologue, - internal, - hardware); + comp_unit_list.get(), + symbol_names, + num_names, + name_type_mask, + symbol_language, + skip_prologue, + internal, + hardware); } if (log) @@ -962,37 +983,14 @@ SBBreakpoint SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name) { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - - SBBreakpoint sb_bp; - TargetSP target_sp(GetSP()); - if (target_sp && symbol_name_regex && symbol_name_regex[0]) + SBFileSpecList module_spec_list; + SBFileSpecList comp_unit_list; + if (module_name && module_name[0]) { - Mutex::Locker api_locker (target_sp->GetAPIMutex()); - RegularExpression regexp(symbol_name_regex); - const bool internal = false; - const bool hardware = false; - const LazyBool skip_prologue = eLazyBoolCalculate; - - if (module_name && module_name[0]) - { - FileSpecList module_spec_list; - module_spec_list.Append (FileSpec (module_name, false)); - - *sb_bp = target_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, skip_prologue, internal, hardware); - } - else - { - *sb_bp = target_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, skip_prologue, internal, hardware); - } + module_spec_list.Append (FileSpec (module_name, false)); + } - - if (log) - log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", - static_cast<void*>(target_sp.get()), symbol_name_regex, - module_name, static_cast<void*>(sb_bp.get())); - - return sb_bp; + return BreakpointCreateByRegex (symbol_name_regex, eLanguageTypeUnknown, module_spec_list, comp_unit_list); } lldb::SBBreakpoint @@ -1000,6 +998,15 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) { + return BreakpointCreateByRegex (symbol_name_regex, eLanguageTypeUnknown, module_list, comp_unit_list); +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, + LanguageType symbol_language, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list) +{ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBBreakpoint sb_bp; @@ -1011,8 +1018,8 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const bool internal = false; const bool hardware = false; const LazyBool skip_prologue = eLazyBoolCalculate; - - *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal, hardware); + + *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, symbol_language, skip_prologue, internal, hardware); } if (log) diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp index 7bfa35d43f3..c5b3242fc59 100644 --- a/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -21,6 +21,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/LanguageRuntime.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" using namespace lldb; @@ -90,12 +91,13 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt, BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt, RegularExpression &func_regex, + lldb::LanguageType language, bool skip_prologue) : BreakpointResolver (bkpt, BreakpointResolver::NameResolver), m_class_name (nullptr), m_regex (func_regex), m_match_type (Breakpoint::Regexp), - m_language (eLanguageTypeUnknown), + m_language (language), m_skip_prologue (skip_prologue) { } @@ -211,6 +213,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, return Searcher::eCallbackReturnStop; } bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0; + bool filter_by_language = (m_language != eLanguageTypeUnknown); const bool include_symbols = !filter_by_cu; const bool include_inlines = true; const bool append = true; @@ -254,15 +257,48 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, } // If the filter specifies a Compilation Unit, remove the ones that don't pass at this point. - if (filter_by_cu) + if (filter_by_cu || filter_by_language) { + Target &target = m_breakpoint->GetTarget(); + uint32_t num_functions = func_list.GetSize(); for (size_t idx = 0; idx < num_functions; idx++) { + bool remove_it = false; SymbolContext sc; func_list.GetContextAtIndex(idx, sc); - if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit)) + if (filter_by_cu) + { + if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit)) + remove_it = true; + } + + if (filter_by_language) + { + const char *name = sc.GetFunctionName(Mangled::ePreferMangled).AsCString(); + if (name) + { + LanguageType sym_language = LanguageRuntime::GetLanguageForSymbolByName(target, name); + if (m_language == eLanguageTypeC) + { + // We don't currently have a way to say "This symbol name is C" so for now, C means + // not ObjC and not C++, etc... + if (sym_language == eLanguageTypeC_plus_plus + || sym_language == eLanguageTypeObjC + || sym_language == eLanguageTypeSwift) + { + remove_it = true; + } + } + else if (sym_language != m_language) + { + remove_it = true; + } + } + } + + if (remove_it) { func_list.RemoveContextAtIndex(idx); num_functions--; @@ -370,6 +406,10 @@ BreakpointResolverName::GetDescription (Stream *s) s->Printf ("'%s'}", m_lookups[num_names - 1].name.GetCString()); } } + if (m_language != eLanguageTypeUnknown) + { + s->Printf (", language = %s", Language::GetNameForLanguageType(m_language)); + } } void diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index fe475338c3e..edd733667d6 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -546,6 +546,7 @@ protected: bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp, + m_options.m_language, m_options.m_skip_prologue, internal, m_options.m_hardware).get(); @@ -717,7 +718,7 @@ private: #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 ) #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) ) #define LLDB_OPT_MOVE_TO_NEAREST_CODE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_9 ) -#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) & ~LLDB_OPT_SET_7 ) +#define LLDB_OPT_EXPR_LANGUAGE ( LLDB_OPT_SET_FROM_TO(3, 8) ) OptionDefinition CommandObjectBreakpointSet::CommandOptions::g_option_table[] = diff --git a/lldb/source/Target/LanguageRuntime.cpp b/lldb/source/Target/LanguageRuntime.cpp index f930f40ace6..0d67436a38e 100644 --- a/lldb/source/Target/LanguageRuntime.cpp +++ b/lldb/source/Target/LanguageRuntime.cpp @@ -12,6 +12,8 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/LanguageRuntime.h" +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Core/PluginManager.h" @@ -343,3 +345,23 @@ LanguageRuntime::CreateExceptionSearchFilter () { return m_process->GetTarget().GetSearchFilterForModule(NULL); } + +lldb::LanguageType +LanguageRuntime::GetLanguageForSymbolByName (Target &target, const char *symbol_name) +{ + // This is not the right way to do this. Different targets could have different ways of mangling names + // from a given language. So we should ask the various LanguageRuntime plugin instances for this target + // to recognize the name. But right now the plugin instances depend on the process, not the target. + // That is unfortunate, because I want to use this for filtering breakpoints by language, and so I need to know + // the "language for symbol-name" prior to running. So we'd have to make a "LanguageRuntimeTarget" and + // "LanguageRuntimeProcess", and direct the questions that don't need a running process to the former, and that + // do to the latter. + // + // That's more work than I want to do for this feature. + if (CPlusPlusLanguage::IsCPPMangledName (symbol_name)) + return eLanguageTypeC_plus_plus; + else if (ObjCLanguage::IsPossibleObjCMethodName (symbol_name)) + return eLanguageTypeObjC; + else + return eLanguageTypeUnknown; +} diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 1f6bacca2b4..eb43752c7f1 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -582,6 +582,7 @@ BreakpointSP Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, RegularExpression &func_regex, + lldb::LanguageType requested_language, LazyBool skip_prologue, bool internal, bool hardware) @@ -591,7 +592,8 @@ Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules, (skip_prologue == eLazyBoolCalculate) ? GetSkipPrologue() : static_cast<bool>(skip_prologue); BreakpointResolverSP resolver_sp(new BreakpointResolverName (NULL, - func_regex, + func_regex, + requested_language, skip)); return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); |