summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDawn Perchik <dawn@burble.org>2015-09-04 01:02:30 +0000
committerDawn Perchik <dawn@burble.org>2015-09-04 01:02:30 +0000
commit009d110de476e6a1c9581b1e57a90dd73593b8aa (patch)
treeb3c21aba02ef7872b0b88463b77f5a96d9c92ba8
parentb2e9897644383e7e535a3f4465706760b336ca49 (diff)
downloadbcm5719-llvm-009d110de476e6a1c9581b1e57a90dd73593b8aa.tar.gz
bcm5719-llvm-009d110de476e6a1c9581b1e57a90dd73593b8aa.zip
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 llvm-svn: 246829
-rw-r--r--lldb/include/lldb/Target/StackFrame.h10
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp13
-rw-r--r--lldb/source/Expression/ClangExpressionParser.cpp23
-rw-r--r--lldb/source/Target/StackFrame.cpp9
-rw-r--r--lldb/test/expression_command/options/TestExprOptions.py73
-rw-r--r--lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py2
-rw-r--r--lldb/test/lang/mixed/Makefile6
-rw-r--r--lldb/test/lang/mixed/TestMixedLanguages.py59
-rw-r--r--lldb/test/lang/mixed/foo.cpp11
-rw-r--r--lldb/test/lang/mixed/main.c15
10 files changed, 162 insertions, 59 deletions
diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h
index 85dbf06b925..f333ab2b2e8 100644
--- a/lldb/include/lldb/Target/StackFrame.h
+++ b/lldb/include/lldb/Target/StackFrame.h
@@ -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
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 4aa486c0315..7e787bce8c9 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -289,8 +289,8 @@ CommandObjectExpression::EvaluateExpression
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::EvaluateExpression
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::EvaluateExpression
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)
{
diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp
index ad17c4fd1f4..d5dbaf16b4a 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Expression/ClangExpressionParser.cpp
@@ -210,17 +210,38 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
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;
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index e7baad19ffd..be86be31c04 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -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 ()
{
diff --git a/lldb/test/expression_command/options/TestExprOptions.py b/lldb/test/expression_command/options/TestExprOptions.py
index 4beba7d959b..2dca24657a3 100644
--- a/lldb/test/expression_command/options/TestExprOptions.py
+++ b/lldb/test/expression_command/options/TestExprOptions.py
@@ -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
diff --git a/lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py b/lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py
index 9c291219529..af21086c006 100644
--- a/lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py
+++ b/lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py
@@ -42,7 +42,7 @@ class PersistentPtrUpdateTestCase(TestBase):
self.runCmd("run", RUN_SUCCEEDED)
- self.runCmd("expr void* $foo = nullptr")
+ self.runCmd("expr void* $foo = 0")
self.runCmd("continue")
diff --git a/lldb/test/lang/mixed/Makefile b/lldb/test/lang/mixed/Makefile
new file mode 100644
index 00000000000..860343ee907
--- /dev/null
+++ b/lldb/test/lang/mixed/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+CXX_SOURCES := foo.cpp
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/test/lang/mixed/TestMixedLanguages.py b/lldb/test/lang/mixed/TestMixedLanguages.py
new file mode 100644
index 00000000000..2f89fb298be
--- /dev/null
+++ b/lldb/test/lang/mixed/TestMixedLanguages.py
@@ -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()
diff --git a/lldb/test/lang/mixed/foo.cpp b/lldb/test/lang/mixed/foo.cpp
new file mode 100644
index 00000000000..8a5a6a2b541
--- /dev/null
+++ b/lldb/test/lang/mixed/foo.cpp
@@ -0,0 +1,11 @@
+namespace ns {
+ int func(void)
+ {
+ return 0;
+ }
+}
+
+extern "C" int foo(void)
+{
+ return ns::func();
+}
diff --git a/lldb/test/lang/mixed/main.c b/lldb/test/lang/mixed/main.c
new file mode 100644
index 00000000000..f5c5d19f2c8
--- /dev/null
+++ b/lldb/test/lang/mixed/main.c
@@ -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();
+}
OpenPOWER on IntegriCloud