[Lldb-commits] [lldb] r243187 - Specify a language to use when parsing expressions.

Dawn Perchik dawn at burble.org
Fri Jul 24 17:19:40 PDT 2015


Author: dperchik
Date: Fri Jul 24 19:19:39 2015
New Revision: 243187

URL: http://llvm.org/viewvc/llvm-project?rev=243187&view=rev
Log:
Specify a language to use when parsing expressions.

This patch adds the option -l/--language to the expression command, for
use when setting the language options or choosing an alternate FE. If
not specified, the target.language setting is used.

Reviewed by: clayborg
Subscribers: lldb-commits
Differential Revision: http://reviews.llvm.org/D11447

Added:
    lldb/trunk/test/expression_command/options/
    lldb/trunk/test/expression_command/options/Makefile
    lldb/trunk/test/expression_command/options/TestExprOptions.py
    lldb/trunk/test/expression_command/options/foo.cpp
    lldb/trunk/test/expression_command/options/main.cpp
Modified:
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.h

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=243187&r1=243186&r2=243187&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Fri Jul 24 19:19:39 2015
@@ -63,6 +63,7 @@ CommandObjectExpression::CommandOptions:
     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout",            't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,  "Timeout value (in microseconds) for running the expression."},
     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error",    'u', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "Clean up program state if the expression causes a crash, or raises a signal.  Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."},
     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug",              'g', OptionParser::eNoArgument      , NULL, NULL, 0, eArgTypeNone,       "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language",           'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,   "Specifies the Language to use when parsing the expression.  If not set the target.language setting is used." },
     { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, NULL, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity,        "How verbose should the output of this expression be, if the object description is asked for."},
 };
 
@@ -84,12 +85,11 @@ CommandObjectExpression::CommandOptions:
 
     switch (short_option)
     {
-      //case 'l':
-      //if (language.SetLanguageFromCString (option_arg) == false)
-      //{
-      //    error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
-      //}
-      //break;
+    case 'l':
+        language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
+        if (language == eLanguageTypeUnknown)
+            error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg);
+        break;
 
     case 'a':
         {
@@ -180,6 +180,7 @@ CommandObjectExpression::CommandOptions:
     try_all_threads = true;
     timeout = 0;
     debug = false;
+    language = eLanguageTypeUnknown;
     m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
 }
 
@@ -192,7 +193,7 @@ CommandObjectExpression::CommandOptions:
 CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
     CommandObjectRaw (interpreter,
                       "expression",
-                      "Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
+                      "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.",
                       NULL,
                       eCommandProcessMustBePaused | eCommandTryTargetAPILock),
     IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
@@ -300,6 +301,12 @@ CommandObjectExpression::EvaluateExpress
         options.SetTryAllThreads(m_command_options.try_all_threads);
         options.SetDebug(m_command_options.debug);
         
+        // If the language was not specified, set it from target's properties
+        if (m_command_options.language != eLanguageTypeUnknown)
+            options.SetLanguage(m_command_options.language);
+        else
+            options.SetLanguage(target->GetLanguage());
+
         // If there is any chance we are going to stop and want to see
         // what went wrong with our expression, we should generate debug info
         if (!m_command_options.ignore_breakpoints ||

Modified: lldb/trunk/source/Commands/CommandObjectExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.h?rev=243187&r1=243186&r2=243187&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.h (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.h Fri Jul 24 19:19:39 2015
@@ -61,6 +61,7 @@ public:
         bool        debug;
         uint32_t    timeout;
         bool        try_all_threads;
+        lldb::LanguageType language;
         LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
     };
 

Added: lldb/trunk/test/expression_command/options/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/options/Makefile?rev=243187&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/options/Makefile (added)
+++ lldb/trunk/test/expression_command/options/Makefile Fri Jul 24 19:19:39 2015
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp foo.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/expression_command/options/TestExprOptions.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/options/TestExprOptions.py?rev=243187&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/options/TestExprOptions.py (added)
+++ lldb/trunk/test/expression_command/options/TestExprOptions.py Fri Jul 24 19:19:39 2015
@@ -0,0 +1,100 @@
+"""
+Test expression command options.
+
+Test cases:
+
+o test_expr_options:
+  Test expression command options.
+"""
+
+import os, time
+import unittest2
+import lldb
+import lldbutil
+from lldbtest import *
+
+class ExprOptionsTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+        self.main_source = "main.cpp"
+        self.main_source_spec = lldb.SBFileSpec (self.main_source)
+        self.line = line_number('main.cpp', '// breakpoint_in_main')
+        self.exe = os.path.join(os.getcwd(), "a.out")
+
+    def test_expr_options(self):
+        """These expression command options should work as expected."""
+        self.buildDefault()
+
+        # Set debugger into synchronous mode
+        self.dbg.SetAsync(False)
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(self.exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        # Set breakpoints inside main.
+        breakpoint = target.BreakpointCreateBySourceRegex('// breakpoint_in_main', self.main_source_spec)
+        self.assertTrue(breakpoint)
+
+        # Now launch the process, and do not stop at entry point.
+        process = target.LaunchSimple(None, None, self.get_process_working_directory())
+        self.assertTrue(process, PROCESS_IS_VALID)
+
+        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
+        self.assertEqual(len(threads), 1)
+
+        frame = threads[0].GetFrameAtIndex(0)
+        options = lldb.SBExpressionOptions()
+
+        # -- test --language on ObjC builtin type using the SB API's --
+        # Make sure we can evaluate the ObjC builtin type 'id':
+        val = frame.EvaluateExpression('id my_id = 0; my_id')
+        self.assertTrue(val.IsValid())
+        self.assertTrue(val.GetError().Success())
+        self.assertEqual(val.GetValueAsUnsigned(0), 0)
+        self.DebugSBValue(val)
+
+        # Make sure it still works if language is set to ObjC:
+        options.SetLanguage(lldb.eLanguageTypeObjC)
+        val = frame.EvaluateExpression('id my_id = 0; my_id', options)
+        self.assertTrue(val.IsValid())
+        self.assertTrue(val.GetError().Success())
+        self.assertEqual(val.GetValueAsUnsigned(0), 0)
+        self.DebugSBValue(val)
+
+        # Make sure it fails if language is set to C:
+        options.SetLanguage(lldb.eLanguageTypeC)
+        val = frame.EvaluateExpression('id my_id = 0; my_id', options)
+        self.assertTrue(val.IsValid())
+        self.assertFalse(val.GetError().Success())
+
+        # -- test --language on C++ expression using the SB API's --
+        # Make sure we can evaluate 'ns::func'.
+        val = frame.EvaluateExpression('ns::func')
+        self.assertTrue(val.IsValid())
+        self.assertTrue(val.GetError().Success())
+        self.DebugSBValue(val)
+
+        # Make sure it still works if language is set to C++:
+        options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+        val = frame.EvaluateExpression('ns::func', options)
+        self.assertTrue(val.IsValid())
+        self.assertTrue(val.GetError().Success())
+        self.DebugSBValue(val)
+
+        # Make sure it fails if language is set to C:
+        options.SetLanguage(lldb.eLanguageTypeC)
+        val = frame.EvaluateExpression('ns::func', options)
+        self.assertTrue(val.IsValid())
+        self.assertFalse(val.GetError().Success())
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/expression_command/options/foo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/options/foo.cpp?rev=243187&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/options/foo.cpp (added)
+++ lldb/trunk/test/expression_command/options/foo.cpp Fri Jul 24 19:19:39 2015
@@ -0,0 +1,11 @@
+namespace ns {
+    int func(void)
+    {
+        return 0;
+    }
+}
+
+extern "C" int foo(void)
+{
+    return ns::func();
+}

Added: lldb/trunk/test/expression_command/options/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/options/main.cpp?rev=243187&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/options/main.cpp (added)
+++ lldb/trunk/test/expression_command/options/main.cpp Fri Jul 24 19:19:39 2015
@@ -0,0 +1,15 @@
+extern "C" int foo(void);
+static int static_value = 0;
+
+int
+bar()
+{
+    static_value++;
+    return static_value;
+}
+
+int main (int argc, char const *argv[])
+{
+    bar(); // breakpoint_in_main
+    return foo();
+}





More information about the lldb-commits mailing list