dawn retitled this revision from "Parse breakpoint expressions using the 
language of the frame's CU." to "Specify a language to use when parsing 
breakpoint identifiers.".
dawn updated the summary for this revision.
dawn updated this revision to Diff 30277.
dawn added a comment.

This revised patch uses target and breakpoint options for determining the 
language instead of the selected frame's CU.


Repository:
  rL LLVM

http://reviews.llvm.org/D11119

Files:
  include/lldb/Breakpoint/BreakpointResolverName.h
  include/lldb/Core/Module.h
  include/lldb/Interpreter/OptionValueProperties.h
  include/lldb/Target/LanguageRuntime.h
  include/lldb/Target/Target.h
  source/API/SBTarget.cpp
  source/Breakpoint/BreakpointResolverName.cpp
  source/Commands/CommandObjectBreakpoint.cpp
  source/Core/Module.cpp
  source/Core/ModuleList.cpp
  source/Interpreter/OptionValueLanguage.cpp
  source/Interpreter/OptionValueProperties.cpp
  source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
  
source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
  source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
  source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
  source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
  source/Target/LanguageRuntime.cpp
  source/Target/Target.cpp
  test/functionalities/breakpoint/breakpoint_options/Makefile
  test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py
  test/functionalities/breakpoint/breakpoint_options/foo.cpp
  test/functionalities/breakpoint/breakpoint_options/main.c
  test/functionalities/breakpoint/breakpoint_options/main.cpp
  test/settings/TestSettings.py
  test/tools/lldb-mi/breakpoint/TestMiBreak.py
  test/tools/lldb-mi/breakpoint/main.cpp

Index: test/tools/lldb-mi/breakpoint/main.cpp
===================================================================
--- test/tools/lldb-mi/breakpoint/main.cpp
+++ test/tools/lldb-mi/breakpoint/main.cpp
@@ -9,11 +9,19 @@
 
 #include <cstdio>
 
+namespace ns
+{
+    int foo1(void) { printf("In foo1\n"); return 1; }
+    int foo2(void) { printf("In foo2\n"); return 2; }
+}
+
 // BP_before_main
 
+int x;
 int
 main(int argc, char const *argv[])
 {
     printf("Print a formatted string so that GCC does not optimize this printf call: %s\n", argv[0]);
+    x = ns::foo1() + ns::foo2();
     return 0; // BP_return
 }
Index: test/tools/lldb-mi/breakpoint/TestMiBreak.py
===================================================================
--- test/tools/lldb-mi/breakpoint/TestMiBreak.py
+++ test/tools/lldb-mi/breakpoint/TestMiBreak.py
@@ -206,6 +206,22 @@
         self.expect("\^running")
         self.expect("\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"3\"")
 
+        # Test that the target.language=pascal setting works and that BP #5 is not set
+        self.runCmd("-interpreter-exec console \"settings set target.language c\"")
+        self.expect("\^done")
+        self.runCmd("-break-insert ns.foo1")
+        self.expect("\^error")
+
+        # Test that the target.language=c++ setting works and that BP #6 is hit
+        # FIXME: lldb-mi interprets 'ns::func' as file:func where file='ns:'.
+        #self.runCmd("-interpreter-exec console \"settings set target.language c++\"")
+        #self.expect("\^done")
+        #self.runCmd("-break-insert ns::foo1")
+        #self.expect("\^done,bkpt={number=\"6\"")
+        #self.runCmd("-exec-run")
+        #self.expect("\^running")
+        #self.expect("\*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"6\"")
+
         # Test that BP #1 and #2 weren't set by running to program exit
         self.runCmd("-exec-continue")
         self.expect("\^running")
Index: test/settings/TestSettings.py
===================================================================
--- test/settings/TestSettings.py
+++ test/settings/TestSettings.py
@@ -405,6 +405,12 @@
         self.expect ("settings show stop-disassembly-display", SETTING_MSG("stop-disassembly-display"),
             startstr = 'stop-disassembly-display (enum) = always')
         self.runCmd("settings clear stop-disassembly-display", check=False)        
+        # language
+        self.runCmd ("settings set target.language c89")      # Set to known value
+        self.runCmd ("settings set target.language pascal ")    # Set to new value with trailing whitespace
+        self.expect ("settings show target.language", SETTING_MSG("target.language"),
+            startstr = "target.language (language) = pascal")
+        self.runCmd("settings clear target.language", check=False)
         # arguments
         self.runCmd ("settings set target.run-args 1 2 3")  # Set to known value
         self.runCmd ("settings set target.run-args 3 4 5 ") # Set to new value with trailing whitespaces
@@ -461,6 +467,7 @@
                                  "target.default-arch",
                                  "target.move-to-nearest-code",
                                  "target.expr-prefix",
+                                 "target.language",
                                  "target.prefer-dynamic-value",
                                  "target.enable-synthetic-value",
                                  "target.skip-prologue",
Index: test/functionalities/breakpoint/breakpoint_options/main.cpp
===================================================================
--- test/functionalities/breakpoint/breakpoint_options/main.cpp
+++ test/functionalities/breakpoint/breakpoint_options/main.cpp
@@ -1,7 +1,8 @@
 // Set break point at this line.
 
+extern "C" int foo(void);
 int
 main (int argc, char **argv)
 { 
-  return 0;
+  return foo();
 }
Index: test/functionalities/breakpoint/breakpoint_options/main.c
===================================================================
--- test/functionalities/breakpoint/breakpoint_options/main.c
+++ test/functionalities/breakpoint/breakpoint_options/main.c
@@ -1,7 +0,0 @@
-// Set break point at this line.
-
-int
-main (int argc, char **argv)
-{ 
-  return 0;
-}
Index: test/functionalities/breakpoint/breakpoint_options/foo.cpp
===================================================================
--- test/functionalities/breakpoint/breakpoint_options/foo.cpp
+++ test/functionalities/breakpoint/breakpoint_options/foo.cpp
@@ -0,0 +1,12 @@
+
+namespace ns {
+    int func(void)
+    {
+        return 0;
+    }
+}
+
+extern "C" int foo(void)
+{
+    return ns::func();
+}
Index: test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py
===================================================================
--- test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py
+++ test/functionalities/breakpoint/breakpoint_options/TestBreakpointOptions.py
@@ -29,7 +29,7 @@
         # Call super's setUp().
         TestBase.setUp(self)
         # Find the line number to break inside main().
-        self.line = line_number('main.c', '// Set break point at this line.')
+        self.line = line_number('main.cpp', '// Set break point at this line.')
 
     def breakpoint_options_test(self):
         """Test breakpoint command for different options."""
@@ -37,11 +37,11 @@
         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
 
         # This should create a breakpoint with 1 locations.
-        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, extra_options = "-K 1", num_expected_locations = 1)
-        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, extra_options = "-K 0", num_expected_locations = 1)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, extra_options = "-K 1", num_expected_locations = 1)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, extra_options = "-K 0", num_expected_locations = 1)
 
         # This should create a breakpoint 0 locations.
-        lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, extra_options = "-m 0", num_expected_locations = 0)
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, extra_options = "-m 0", num_expected_locations = 0)
 
         # Run the program.
         self.runCmd("run", RUN_SUCCEEDED)
@@ -52,9 +52,9 @@
 
         # Check the list of breakpoint.
         self.expect("breakpoint list -f", "Breakpoint locations shown correctly",
-            substrs = ["1: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line,
-                       "2: file = 'main.c', line = %d, exact_match = 0, locations = 1" % self.line,
-                       "3: file = 'main.c', line = %d, exact_match = 1, locations = 0" % self.line])
+            substrs = ["1: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.line,
+                       "2: file = 'main.cpp', line = %d, exact_match = 0, locations = 1" % self.line,
+                       "3: file = 'main.cpp', line = %d, exact_match = 1, locations = 0" % self.line])
 
         # Continue the program, there should be another stop.
         self.runCmd("process continue")
@@ -70,6 +70,33 @@
         self.expect("process status", "Process exited successfully",
             patterns = ["^Process [0-9]+ exited with status = 0"])
 
+    def breakpoint_options_language_test(self):
+        """Test breakpoint command for language option."""
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        # This should create a breakpoint with 1 locations.
+        lldbutil.run_break_set_by_symbol (self, 'ns::func', sym_exact=False, extra_options = "-L c++", num_expected_locations=1)
+
+        # This should create a breakpoint 0 locations.
+        lldbutil.run_break_set_by_symbol (self, 'ns::func', sym_exact=False, extra_options = "-L c", num_expected_locations=0)
+        self.runCmd("settings set target.language c")
+        lldbutil.run_break_set_by_symbol (self, 'ns::func', sym_exact=False, num_expected_locations=0)
+
+        # Run the program.
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # Stopped once.
+        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ["stop reason = breakpoint 1."])
+
+        # Continue the program, we should exit.
+        self.runCmd("process continue")
+
+        # We should exit.
+        self.expect("process status", "Process exited successfully",
+            patterns = ["^Process [0-9]+ exited with status = 0"])
+
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()
Index: test/functionalities/breakpoint/breakpoint_options/Makefile
===================================================================
--- test/functionalities/breakpoint/breakpoint_options/Makefile
+++ test/functionalities/breakpoint/breakpoint_options/Makefile
@@ -1,5 +1,5 @@
 LEVEL = ../../../make
 
-C_SOURCES := main.c
+CXX_SOURCES := main.cpp foo.cpp
 
 include $(LEVEL)/Makefile.rules
Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -371,6 +371,7 @@
                           const FileSpecList *containingSourceFiles,
                           const char *func_name, 
                           uint32_t func_name_type_mask, 
+                          LanguageType language,
                           LazyBool skip_prologue,
                           bool internal,
                           bool hardware)
@@ -382,10 +383,13 @@
 
         if (skip_prologue == eLazyBoolCalculate)
             skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+        if (language == lldb::eLanguageTypeUnknown)
+            language = GetLanguage();
 
         BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL, 
                                                                       func_name, 
                                                                       func_name_type_mask, 
+                                                                      language,
                                                                       Breakpoint::Exact, 
                                                                       skip_prologue));
         bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
@@ -398,6 +402,7 @@
                           const FileSpecList *containingSourceFiles,
                           const std::vector<std::string> &func_names,
                           uint32_t func_name_type_mask,
+                          LanguageType language,
                           LazyBool skip_prologue,
                           bool internal,
                           bool hardware)
@@ -410,10 +415,13 @@
 
         if (skip_prologue == eLazyBoolCalculate)
             skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+        if (language == lldb::eLanguageTypeUnknown)
+            language = GetLanguage();
 
         BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
                                                                       func_names,
                                                                       func_name_type_mask,
+                                                                      language,
                                                                       skip_prologue));
         bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
     }
@@ -426,6 +434,7 @@
                           const char *func_names[],
                           size_t num_names, 
                           uint32_t func_name_type_mask, 
+                          LanguageType language,
                           LazyBool skip_prologue,
                           bool internal,
                           bool hardware)
@@ -437,11 +446,15 @@
         
         if (skip_prologue == eLazyBoolCalculate)
             skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
+        if (language == lldb::eLanguageTypeUnknown)
+            language = GetLanguage();
 
+
         BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
                                                                       func_names,
                                                                       num_names, 
                                                                       func_name_type_mask,
+                                                                      language,
                                                                       skip_prologue));
         bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
     }
@@ -2938,6 +2951,7 @@
 {
     { "default-arch"                       , OptionValue::eTypeArch      , true , 0                         , NULL, NULL, "Default architecture to choose, when there's a choice." },
     { "move-to-nearest-code"               , OptionValue::eTypeBoolean   , false, true                      , NULL, NULL, "Move breakpoints to nearest code." },
+    { "language"                           , OptionValue::eTypeLanguage  , false, eLanguageTypeUnknown      , NULL, NULL, "The language to use when interpreting expressions entered in commands (note: currently only implemented for breakpoints identifiers)." },
     { "expr-prefix"                        , OptionValue::eTypeFileSpec  , false, 0                         , NULL, NULL, "Path to a file containing expressions to be prepended to all expressions." },
     { "prefer-dynamic-value"               , OptionValue::eTypeEnum      , false, eDynamicDontRunTarget     , NULL, g_dynamic_value_types, "Should printed values be shown as their dynamic value." },
     { "enable-synthetic-value"             , OptionValue::eTypeBoolean   , false, true                      , NULL, NULL, "Should synthetic values be used by default whenever available." },
@@ -2996,6 +3010,7 @@
 {
     ePropertyDefaultArch,
     ePropertyMoveToNearestCode,
+    ePropertyLanguage,
     ePropertyExprPrefix,
     ePropertyPreferDynamic,
     ePropertyEnableSynthetic,
@@ -3444,6 +3459,15 @@
     return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
 }
 
+LanguageType
+TargetProperties::GetLanguage () const
+{
+    OptionValueLanguage *value = m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage (NULL, ePropertyLanguage);
+    if (value)
+        return value->GetCurrentValue();
+    return LanguageType();
+}
+
 const char *
 TargetProperties::GetExpressionPrefixContentsAsCString ()
 {
Index: source/Target/LanguageRuntime.cpp
===================================================================
--- source/Target/LanguageRuntime.cpp
+++ source/Target/LanguageRuntime.cpp
@@ -371,7 +371,8 @@
     {   "renderscript",     eLanguageTypeExtRenderScript},
     // Now synonyms, in arbitrary order
     {   "objc",             eLanguageTypeObjC           },
-    {   "objc++",           eLanguageTypeObjC_plus_plus }
+    {   "objc++",           eLanguageTypeObjC_plus_plus },
+    {   "pascal",           eLanguageTypePascal83       }
 };
 
 static uint32_t num_languages = sizeof(language_names) / sizeof (struct language_name_pair);
@@ -420,6 +421,46 @@
     }
 }
 
+bool
+LanguageRuntime::LanguageIsObjC (LanguageType language)
+{
+    switch (language)
+    {
+        case eLanguageTypeObjC:
+        case eLanguageTypeObjC_plus_plus:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool
+LanguageRuntime::LanguageIsC (LanguageType language)
+{
+    switch (language)
+    {
+        case eLanguageTypeC:
+        case eLanguageTypeC89:
+        case eLanguageTypeC99:
+        case eLanguageTypeC11:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool
+LanguageRuntime::LanguageIsPascal (LanguageType language)
+{
+    switch (language)
+    {
+        case eLanguageTypePascal83:
+            return true;
+        default:
+            return false;
+    }
+}
+
 void
 LanguageRuntime::InitializeCommands (CommandObject* parent)
 {
Index: source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
===================================================================
--- source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -1144,6 +1144,7 @@
                                      g_bp_names,
                                      llvm::array_lengthof(g_bp_names),
                                      eFunctionNameTypeFull,
+                                     eLanguageTypeUnknown,
                                      skip_prologue,
                                      internal,
                                      hardware);
Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
===================================================================
--- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -714,6 +714,7 @@
         resolver_sp.reset (new BreakpointResolverName (bkpt,
                                                        "objc_exception_throw",
                                                        eFunctionNameTypeBase,
+                                                       eLanguageTypeObjC,
                                                        Breakpoint::Exact,
                                                        eLazyBoolNo));
     // FIXME: We don't do catch breakpoints for ObjC yet.
Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
===================================================================
--- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -132,6 +132,7 @@
         resolver_sp.reset (new BreakpointResolverName (bkpt,
                                                        "objc_exception_throw",
                                                        eFunctionNameTypeBase,
+                                                       eLanguageTypeObjC,
                                                        Breakpoint::Exact,
                                                        eLazyBoolNo));
     // FIXME: don't do catch yet.
Index: source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
===================================================================
--- source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -420,6 +420,7 @@
                                                                   exception_names.data(),
                                                                   exception_names.size(),
                                                                   eFunctionNameTypeBase,
+                                                                  eLanguageTypeC_plus_plus,
                                                                   eLazyBoolNo));
 
     return resolver_sp;
Index: source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
===================================================================
--- source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -1546,6 +1546,7 @@
                                                                   NULL,
                                                                   "OSKextLoadedKextSummariesUpdated",
                                                                   eFunctionNameTypeFull,
+                                                                  eLanguageTypeUnknown,
                                                                   skip_prologue,
                                                                   internal_bp,
                                                                   hardware).get();
Index: source/Interpreter/OptionValueProperties.cpp
===================================================================
--- source/Interpreter/OptionValueProperties.cpp
+++ source/Interpreter/OptionValueProperties.cpp
@@ -311,6 +311,15 @@
     return nullptr;
 }
 
+OptionValueLanguage *
+OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const
+{
+    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
+    if (property)
+        return property->GetValue()->GetAsLanguage();
+    return nullptr;
+}
+
 bool
 OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
 {
Index: source/Interpreter/OptionValueLanguage.cpp
===================================================================
--- source/Interpreter/OptionValueLanguage.cpp
+++ source/Interpreter/OptionValueLanguage.cpp
@@ -47,9 +47,21 @@
     case eVarSetOperationReplace:
     case eVarSetOperationAssign:
         {
-            LanguageType new_type = LanguageRuntime::GetLanguageTypeFromString(value.data());
-            m_value_was_set = true;
-            m_current_value = new_type;
+            ConstString lang_name(value.trim());
+            LanguageType new_type = LanguageRuntime::GetLanguageTypeFromString(lang_name.GetCString());
+            if (new_type)
+            {
+                m_value_was_set = true;
+                m_current_value = new_type;
+            }
+            else
+            {
+                StreamString error_strm;
+                error_strm.Printf("invalid language type '%s', ", value.str().c_str());
+                error_strm.Printf("valid values are:\n");
+                LanguageRuntime::PrintAllLanguages(error_strm, "    ", "\n");
+                error.SetErrorString(error_strm.GetData());
+            }
         }
         break;
         
Index: source/Core/ModuleList.cpp
===================================================================
--- source/Core/ModuleList.cpp
+++ source/Core/ModuleList.cpp
@@ -372,6 +372,7 @@
         uint32_t lookup_name_type_mask = 0;
         bool match_name_after_lookup = false;
         Module::PrepareForFunctionNameLookup (name, name_type_mask,
+                                              eLanguageTypeUnknown, // TODO: add support
                                               lookup_name,
                                               lookup_name_type_mask,
                                               match_name_after_lookup);
@@ -436,6 +437,7 @@
         uint32_t lookup_name_type_mask = 0;
         bool match_name_after_lookup = false;
         Module::PrepareForFunctionNameLookup (name, name_type_mask,
+                                              eLanguageTypeUnknown, // TODO: add support
                                               lookup_name,
                                               lookup_name_type_mask,
                                               match_name_after_lookup);
Index: source/Core/Module.cpp
===================================================================
--- source/Core/Module.cpp
+++ source/Core/Module.cpp
@@ -778,6 +778,7 @@
         bool match_name_after_lookup = false;
         Module::PrepareForFunctionNameLookup (name,
                                               name_type_mask,
+                                              eLanguageTypeUnknown, // TODO: add support
                                               lookup_name,
                                               lookup_name_type_mask,
                                               match_name_after_lookup);
@@ -1739,6 +1740,7 @@
 void
 Module::PrepareForFunctionNameLookup (const ConstString &name,
                                       uint32_t name_type_mask,
+                                      LanguageType language,
                                       ConstString &lookup_name,
                                       uint32_t &lookup_name_type_mask,
                                       bool &match_name_after_lookup)
@@ -1754,11 +1756,19 @@
     {
         if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
             lookup_name_type_mask = eFunctionNameTypeFull;
-        else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
+        else if ((language == eLanguageTypeUnknown ||
+                  LanguageRuntime::LanguageIsObjC(language)) &&
+                 ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
             lookup_name_type_mask = eFunctionNameTypeFull;
+        else if (LanguageRuntime::LanguageIsC(language))
+        {
+            lookup_name_type_mask = eFunctionNameTypeFull;
+        }
         else
         {
-            if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
+            if ((language == eLanguageTypeUnknown ||
+                 LanguageRuntime::LanguageIsObjC(language)) &&
+                ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
                 lookup_name_type_mask |= eFunctionNameTypeSelector;
             
             CPPLanguageRuntime::MethodName cpp_method (name);
Index: source/Commands/CommandObjectBreakpoint.cpp
===================================================================
--- source/Commands/CommandObjectBreakpoint.cpp
+++ source/Commands/CommandObjectBreakpoint.cpp
@@ -111,6 +111,7 @@
             m_throw_bp (true),
             m_hardware (false),
             m_exception_language (eLanguageTypeUnknown),
+            m_language (lldb::eLanguageTypeUnknown),
             m_skip_prologue (eLazyBoolCalculate),
             m_one_shot (false),
             m_all_files (false),
@@ -249,6 +250,12 @@
                     break;
                 }
 
+                case 'L':
+                    m_language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
+                    if (m_language == eLanguageTypeUnknown)
+                        error.SetErrorStringWithFormat ("Unknown language type: '%s' for breakpoint", option_arg);
+                    break;
+
                 case 'm':
                 {
                     bool success;
@@ -370,6 +377,7 @@
             m_throw_bp = true;
             m_hardware = false;
             m_exception_language = eLanguageTypeUnknown;
+            m_language = lldb::eLanguageTypeUnknown;
             m_skip_prologue = eLazyBoolCalculate;
             m_one_shot = false;
             m_use_dummy = false;
@@ -411,6 +419,7 @@
         bool m_throw_bp;
         bool m_hardware; // Request to use hardware breakpoints
         lldb::LanguageType m_exception_language;
+        lldb::LanguageType m_language;
         LazyBool m_skip_prologue;
         bool m_one_shot;
         bool m_use_dummy;
@@ -516,6 +525,7 @@
                                                    &(m_options.m_filenames),
                                                    m_options.m_func_names,
                                                    name_type_mask,
+                                                   m_options.m_language,
                                                    m_options.m_skip_prologue,
                                                    internal,
                                                    m_options.m_hardware).get();
@@ -709,6 +719,7 @@
 #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 )
 
 OptionDefinition
 CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
@@ -800,6 +811,9 @@
 //    { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
 //        "The breakpoint will only stop if an exception Object of this type is thrown.  Can be repeated multiple times to stop for multiple object types" },
 
+    { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
+        "Specifies the Language to use when interpreting the breakpoint's expression (note: currently only implemented for breakpoints identifiers).  If not set the target.language setting is used." },
+
     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
 
Index: source/Breakpoint/BreakpointResolverName.cpp
===================================================================
--- source/Breakpoint/BreakpointResolverName.cpp
+++ source/Breakpoint/BreakpointResolverName.cpp
@@ -30,6 +30,7 @@
 BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
                                                 const char *name_cstr,
                                                 uint32_t name_type_mask,
+                                                LanguageType language,
                                                 Breakpoint::MatchType type,
                                                 bool skip_prologue) :
     BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
@@ -36,6 +37,7 @@
     m_class_name (),
     m_regex (),
     m_match_type (type),
+    m_language (language),
     m_skip_prologue (skip_prologue)
 {
     
@@ -59,9 +61,11 @@
                                                 const char *names[],
                                                 size_t num_names,
                                                 uint32_t name_type_mask,
+                                                LanguageType language,
                                                 bool skip_prologue) :
     BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
     m_match_type (Breakpoint::Exact),
+    m_language (language),
     m_skip_prologue (skip_prologue)
 {
     for (size_t i = 0; i < num_names; i++)
@@ -73,9 +77,11 @@
 BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
                                                 std::vector<std::string> names,
                                                 uint32_t name_type_mask,
+                                                LanguageType language,
                                                 bool skip_prologue) :
     BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
     m_match_type (Breakpoint::Exact),
+    m_language (language),
     m_skip_prologue (skip_prologue)
 {
     for (const std::string& name : names)
@@ -91,6 +97,7 @@
     m_class_name (NULL),
     m_regex (func_regex),
     m_match_type (Breakpoint::Regexp),
+    m_language (eLanguageTypeUnknown),
     m_skip_prologue (skip_prologue)
 {
 }
@@ -107,6 +114,7 @@
     m_class_name (class_name),
     m_regex (),
     m_match_type (type),
+    m_language (eLanguageTypeUnknown),
     m_skip_prologue (skip_prologue)
 {
     LookupInfo lookup;
@@ -127,6 +135,7 @@
     m_class_name(rhs.m_class_name),
     m_regex(rhs.m_regex),
     m_match_type (rhs.m_match_type),
+    m_language (rhs.m_language),
     m_skip_prologue (rhs.m_skip_prologue)
 {
 
@@ -154,7 +163,7 @@
     {
         LookupInfo lookup;
         lookup.name = name;
-        Module::PrepareForFunctionNameLookup(lookup.name, name_type_mask, lookup.lookup_name, lookup.name_type_mask, lookup.match_name_after_lookup);
+        Module::PrepareForFunctionNameLookup(lookup.name, name_type_mask, m_language, lookup.lookup_name, lookup.name_type_mask, lookup.match_name_after_lookup);
         m_lookups.push_back (lookup);
     }
 }
Index: source/API/SBTarget.cpp
===================================================================
--- source/API/SBTarget.cpp
+++ source/API/SBTarget.cpp
@@ -847,11 +847,11 @@
         {
             FileSpecList module_spec_list;
             module_spec_list.Append (FileSpec (module_name, false));
-            *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal, hardware);
+            *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown, skip_prologue, internal, hardware);
         }
         else
         {
-            *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal, hardware);
+            *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown, skip_prologue, internal, hardware);
         }
     }
 
@@ -892,6 +892,7 @@
                                               comp_unit_list.get(),
                                               symbol_name,
                                               name_type_mask,
+                                              eLanguageTypeUnknown,
                                               skip_prologue,
                                               internal,
                                               hardware);
@@ -927,6 +928,7 @@
                                                 symbol_names,
                                                 num_names,
                                                 name_type_mask, 
+                                                eLanguageTypeUnknown,
                                                 skip_prologue,
                                                 internal,
                                                 hardware);
Index: include/lldb/Target/Target.h
===================================================================
--- include/lldb/Target/Target.h
+++ include/lldb/Target/Target.h
@@ -169,6 +169,9 @@
     bool
     GetBreakpointsConsultPlatformAvoidList ();
     
+    lldb::LanguageType
+    GetLanguage () const;
+
     const char *
     GetExpressionPrefixContentsAsCString ();
 
@@ -770,6 +773,7 @@
                       const FileSpecList *containingSourceFiles,
                       const char *func_name,
                       uint32_t func_name_type_mask, 
+                      lldb::LanguageType language,
                       LazyBool skip_prologue,
                       bool internal,
                       bool request_hardware);
@@ -792,6 +796,7 @@
                       const char *func_names[],
                       size_t num_names, 
                       uint32_t func_name_type_mask, 
+                      lldb::LanguageType language,
                       LazyBool skip_prologue,
                       bool internal,
                       bool request_hardware);
@@ -801,6 +806,7 @@
                       const FileSpecList *containingSourceFiles,
                       const std::vector<std::string> &func_names,
                       uint32_t func_name_type_mask,
+                      lldb::LanguageType language,
                       LazyBool skip_prologue,
                       bool internal,
                       bool request_hardware);
Index: include/lldb/Target/LanguageRuntime.h
===================================================================
--- include/lldb/Target/LanguageRuntime.h
+++ include/lldb/Target/LanguageRuntime.h
@@ -105,6 +105,15 @@
     static bool
     LanguageIsCPlusPlus (lldb::LanguageType language);
     
+    static bool
+    LanguageIsObjC (lldb::LanguageType language);
+    
+    static bool
+    LanguageIsC (lldb::LanguageType language);
+    
+    static bool
+    LanguageIsPascal (lldb::LanguageType language);
+    
     Process *
     GetProcess()
     {
Index: include/lldb/Interpreter/OptionValueProperties.h
===================================================================
--- include/lldb/Interpreter/OptionValueProperties.h
+++ include/lldb/Interpreter/OptionValueProperties.h
@@ -171,6 +171,9 @@
     OptionValueArch *
     GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const;
 
+    OptionValueLanguage *
+    GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const;
+
     bool
     GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const;
 
Index: include/lldb/Core/Module.h
===================================================================
--- include/lldb/Core/Module.h
+++ include/lldb/Core/Module.h
@@ -1067,6 +1067,10 @@
     ///     The mask of bits from lldb::FunctionNameType enumerations
     ///     that tell us what kind of name we are looking for.
     ///
+    /// @param[out] language
+    ///     If known, the language to use for determining the
+    ///     lookup_name_type_mask.
+    ///
     /// @param[out] lookup_name
     ///     The actual name that will be used when calling
     ///     SymbolVendor::FindFunctions() or Symtab::FindFunctionSymbols()
@@ -1087,6 +1091,7 @@
     static void
     PrepareForFunctionNameLookup (const ConstString &name,
                                   uint32_t name_type_mask,
+                                  lldb::LanguageType language,
                                   ConstString &lookup_name,
                                   uint32_t &lookup_name_type_mask,
                                   bool &match_name_after_lookup);
Index: include/lldb/Breakpoint/BreakpointResolverName.h
===================================================================
--- include/lldb/Breakpoint/BreakpointResolverName.h
+++ include/lldb/Breakpoint/BreakpointResolverName.h
@@ -34,6 +34,7 @@
     BreakpointResolverName (Breakpoint *bkpt,
                             const char *name,
                             uint32_t name_type_mask,
+                            lldb::LanguageType language,
                             Breakpoint::MatchType type,
                             bool skip_prologue);
 
@@ -42,6 +43,7 @@
                             const char *names[],
                             size_t num_names,
                             uint32_t name_type_mask,
+                            lldb::LanguageType language,
                             bool skip_prologue);
 
     // This one takes a C++ array of names.  It is always MatchType = Exact.
@@ -48,6 +50,7 @@
     BreakpointResolverName (Breakpoint *bkpt,
                             std::vector<std::string> names,
                             uint32_t name_type_mask,
+                            lldb::LanguageType language,
                             bool skip_prologue);
 
     // Creates a function breakpoint by regular expression.  Takes over control of the lifespan of func_regex.
@@ -114,6 +117,7 @@
     ConstString m_class_name;
     RegularExpression m_regex;
     Breakpoint::MatchType m_match_type;
+    lldb::LanguageType m_language;
     bool m_skip_prologue;
 
     void
_______________________________________________
lldb-commits mailing list
lldb-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to