[Lldb-commits] [lldb] r246829 - Set the default language to use when evaluating to that of the frame's CU.
Dawn Perchik via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 3 18:02:30 PDT 2015
Author: dperchik
Date: Thu Sep 3 20:02:30 2015
New Revision: 246829
URL: http://llvm.org/viewvc/llvm-project?rev=246829&view=rev
Log:
Set the default language to use when evaluating to that of the frame's CU.
* Use the frame's context (instead of just the target's) when evaluating,
so that the language of the frame's CU can be used to select the
compiler and/or compiler options to use when parsing the expression.
This allows for modules built with mixed languages to be parsed in
the context of their frame.
* Add all C and C++ language variants when determining the language options
to set.
* Enable C++ language options when language is C or ObjC as a workaround since
the expression parser uses features of C++ to capture values.
* Enable ObjC language options when language is C++ as a workaround for ObjC
requirements.
* Disable C++11 language options when language is C++03.
* Add test TestMixedLanguages.py to check that the language being used
for evaluation is that of the frame.
* Fix test TestExprOptions.py to check for C++11 instead of C++ since C++ has
to be enabled for C, and remove redundant expr --language test for ObjC.
* Fix TestPersistentPtrUpdate.py to not require C++11 in C.
Reviewed by: clayborg, spyffe, jingham
Subscribers: lldb-commits
Differential Revision: http://reviews.llvm.org/D11102
Added:
lldb/trunk/test/lang/mixed/
lldb/trunk/test/lang/mixed/Makefile
lldb/trunk/test/lang/mixed/TestMixedLanguages.py
lldb/trunk/test/lang/mixed/foo.cpp
lldb/trunk/test/lang/mixed/main.c
Modified:
lldb/trunk/include/lldb/Target/StackFrame.h
lldb/trunk/source/Commands/CommandObjectExpression.cpp
lldb/trunk/source/Expression/ClangExpressionParser.cpp
lldb/trunk/source/Target/StackFrame.cpp
lldb/trunk/test/expression_command/options/TestExprOptions.py
lldb/trunk/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py
Modified: lldb/trunk/include/lldb/Target/StackFrame.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StackFrame.h?rev=246829&r1=246828&r2=246829&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StackFrame.h (original)
+++ lldb/trunk/include/lldb/Target/StackFrame.h Thu Sep 3 20:02:30 2015
@@ -466,6 +466,16 @@ public:
TrackGlobalVariable (const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic);
//------------------------------------------------------------------
+ /// Query this frame to determine what the default language should be
+ /// when parsing expressions given the execution context.
+ ///
+ /// @return
+ /// The language of the frame if known, else lldb::eLanguageTypeUnknown.
+ //------------------------------------------------------------------
+ lldb::LanguageType
+ GetLanguage ();
+
+ //------------------------------------------------------------------
// lldb::ExecutionContextScope pure virtual functions
//------------------------------------------------------------------
lldb::TargetSP
Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=246829&r1=246828&r2=246829&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Sep 3 20:02:30 2015
@@ -289,8 +289,8 @@ CommandObjectExpression::EvaluateExpress
if (target)
{
lldb::ValueObjectSP result_valobj_sp;
-
bool keep_in_memory = true;
+ StackFrame *frame = exe_ctx.GetFramePtr();
EvaluateExpressionOptions options;
options.SetCoerceToId(m_varobj_options.use_objc);
@@ -301,11 +301,15 @@ 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 the language was not specified in the expression command,
+ // set it to the language in the target's properties if
+ // specified, else default to the langage for the frame.
if (m_command_options.language != eLanguageTypeUnknown)
options.SetLanguage(m_command_options.language);
- else
+ else if (target->GetLanguage() != eLanguageTypeUnknown)
options.SetLanguage(target->GetLanguage());
+ else if (frame)
+ options.SetLanguage(frame->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
@@ -318,8 +322,7 @@ CommandObjectExpression::EvaluateExpress
else
options.SetTimeoutUsec(0);
- target->EvaluateExpression(expr, exe_ctx.GetFramePtr(),
- result_valobj_sp, options);
+ target->EvaluateExpression(expr, frame, result_valobj_sp, options);
if (result_valobj_sp)
{
Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=246829&r1=246828&r2=246829&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Thu Sep 3 20:02:30 2015
@@ -210,17 +210,38 @@ ClangExpressionParser::ClangExpressionPa
switch (language)
{
case lldb::eLanguageTypeC:
+ case lldb::eLanguageTypeC89:
+ case lldb::eLanguageTypeC99:
+ case lldb::eLanguageTypeC11:
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for C, get C++."
+ // For now, the expression parser must use C++ anytime the
+ // language is a C family language, because the expression parser
+ // uses features of C++ to capture values.
+ m_compiler->getLangOpts().CPlusPlus = true;
break;
case lldb::eLanguageTypeObjC:
m_compiler->getLangOpts().ObjC1 = true;
m_compiler->getLangOpts().ObjC2 = true;
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for ObjC, get ObjC++" (see comment above).
+ m_compiler->getLangOpts().CPlusPlus = true;
break;
case lldb::eLanguageTypeC_plus_plus:
- m_compiler->getLangOpts().CPlusPlus = true;
+ case lldb::eLanguageTypeC_plus_plus_11:
+ case lldb::eLanguageTypeC_plus_plus_14:
m_compiler->getLangOpts().CPlusPlus11 = true;
m_compiler->getHeaderSearchOpts().UseLibcxx = true;
+ // fall thru ...
+ case lldb::eLanguageTypeC_plus_plus_03:
+ m_compiler->getLangOpts().CPlusPlus = true;
+ // FIXME: the following language option is a temporary workaround,
+ // to "ask for C++, get ObjC++". Apple hopes to remove this requirement
+ // on non-Apple platforms, but for now it is needed.
+ m_compiler->getLangOpts().ObjC1 = true;
break;
case lldb::eLanguageTypeObjC_plus_plus:
+ case lldb::eLanguageTypeUnknown:
default:
m_compiler->getLangOpts().ObjC1 = true;
m_compiler->getLangOpts().ObjC2 = true;
Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=246829&r1=246828&r2=246829&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Thu Sep 3 20:02:30 2015
@@ -1316,6 +1316,15 @@ StackFrame::IsInlined ()
return false;
}
+lldb::LanguageType
+StackFrame::GetLanguage ()
+{
+ CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
+ if (cu)
+ return cu->GetLanguage();
+ return lldb::eLanguageTypeUnknown;
+}
+
TargetSP
StackFrame::CalculateTarget ()
{
Modified: lldb/trunk/test/expression_command/options/TestExprOptions.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/options/TestExprOptions.py?rev=246829&r1=246828&r2=246829&view=diff
==============================================================================
--- lldb/trunk/test/expression_command/options/TestExprOptions.py (original)
+++ lldb/trunk/test/expression_command/options/TestExprOptions.py Thu Sep 3 20:02:30 2015
@@ -26,15 +26,7 @@ class ExprOptionsTestCase(TestBase):
self.line = line_number('main.cpp', '// breakpoint_in_main')
self.exe = os.path.join(os.getcwd(), "a.out")
- @skipUnlessDarwin
- def test_expr_options_objc_cpp(self):
- self.expr_options(test_objc = True, test_cpp = True)
-
- @skipIfDarwin # Already covered by test_expr_options_objc_cpp
- def test_expr_options_cpp(self):
- self.expr_options(test_objc = False, test_cpp = True)
-
- def expr_options(self, test_objc, test_cpp):
+ def test_expr_options(self):
"""These expression command options should work as expected."""
self.buildDefault()
@@ -59,49 +51,26 @@ class ExprOptionsTestCase(TestBase):
frame = threads[0].GetFrameAtIndex(0)
options = lldb.SBExpressionOptions()
- if test_objc:
- # -- 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_plus_plus)
- 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())
-
- if test_cpp:
- # -- 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())
+ # test --language on C++ expression using the SB API's
+
+ # Make sure we can evaluate 'ns::func'.
+ val = frame.EvaluateExpression('foo != nullptr')
+ self.assertTrue(val.IsValid())
+ self.assertTrue(val.GetError().Success())
+ self.DebugSBValue(val)
+
+ # Make sure it still works if language is set to C++11:
+ options.SetLanguage(lldb.eLanguageTypeC_plus_plus_11)
+ val = frame.EvaluateExpression('foo != nullptr', 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('foo != nullptr', options)
+ self.assertTrue(val.IsValid())
+ self.assertFalse(val.GetError().Success())
if __name__ == '__main__':
import atexit
Modified: lldb/trunk/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py?rev=246829&r1=246828&r2=246829&view=diff
==============================================================================
--- lldb/trunk/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py (original)
+++ lldb/trunk/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py Thu Sep 3 20:02:30 2015
@@ -42,7 +42,7 @@ class PersistentPtrUpdateTestCase(TestBa
self.runCmd("run", RUN_SUCCEEDED)
- self.runCmd("expr void* $foo = nullptr")
+ self.runCmd("expr void* $foo = 0")
self.runCmd("continue")
Added: lldb/trunk/test/lang/mixed/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/mixed/Makefile?rev=246829&view=auto
==============================================================================
--- lldb/trunk/test/lang/mixed/Makefile (added)
+++ lldb/trunk/test/lang/mixed/Makefile Thu Sep 3 20:02:30 2015
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+CXX_SOURCES := foo.cpp
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/lang/mixed/TestMixedLanguages.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/mixed/TestMixedLanguages.py?rev=246829&view=auto
==============================================================================
--- lldb/trunk/test/lang/mixed/TestMixedLanguages.py (added)
+++ lldb/trunk/test/lang/mixed/TestMixedLanguages.py Thu Sep 3 20:02:30 2015
@@ -0,0 +1,59 @@
+"""Test that lldb works correctly on compile units form different languages."""
+
+import os, time, re
+import unittest2
+import lldb
+from lldbtest import *
+
+class MixedLanguagesTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def test_language_of_frame(self):
+ """Test that the language defaults to the language of the current frame."""
+ self.buildDefault()
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Execute the cleanup function during test case tear down
+ # to restore the frame format.
+ def cleanup():
+ self.runCmd("settings set frame-format %s" % self.format_string, check=False)
+ self.addTearDownHook(cleanup)
+ self.runCmd("settings show frame-format")
+ m = re.match(
+ '^frame-format \(format-string\) = "(.*)\"$',
+ self.res.GetOutput())
+ self.assertTrue(m, "Bad settings string")
+ self.format_string = m.group(1)
+
+ # Change the default format to print the language.
+ format_string = "frame #${frame.index}: ${frame.pc}{ ${module.file.basename}`${function.name}{${function.pc-offset}}}{, lang=${language}}\n"
+ self.runCmd("settings set frame-format %s" % format_string)
+ self.expect("settings show frame-format", SETTING_MSG("frame-format"),
+ substrs = [format_string])
+
+ # Run to BP at main (in main.c) and test that the language is C.
+ self.runCmd("breakpoint set -n main")
+ self.runCmd("run")
+ self.expect("thread backtrace",
+ substrs = ["`main", "lang=c"])
+ # Make sure evaluation of C++11 fails.
+ self.expect("expr foo != nullptr", error=True,
+ startstr = "error")
+
+ # Run to BP at foo (in foo.cpp) and test that the language is C++.
+ self.runCmd("breakpoint set -n foo")
+ self.runCmd("continue")
+ self.expect("thread backtrace",
+ substrs = ["`::foo()", "lang=c++"])
+ # Make sure we can evaluate an expression requiring C++11
+ # (note: C++11 is enabled by default for C++).
+ self.expect("expr foo != nullptr",
+ patterns = ["true"])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/lang/mixed/foo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/mixed/foo.cpp?rev=246829&view=auto
==============================================================================
--- lldb/trunk/test/lang/mixed/foo.cpp (added)
+++ lldb/trunk/test/lang/mixed/foo.cpp Thu Sep 3 20:02:30 2015
@@ -0,0 +1,11 @@
+namespace ns {
+ int func(void)
+ {
+ return 0;
+ }
+}
+
+extern "C" int foo(void)
+{
+ return ns::func();
+}
Added: lldb/trunk/test/lang/mixed/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/mixed/main.c?rev=246829&view=auto
==============================================================================
--- lldb/trunk/test/lang/mixed/main.c (added)
+++ lldb/trunk/test/lang/mixed/main.c Thu Sep 3 20:02:30 2015
@@ -0,0 +1,15 @@
+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