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
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 4aa486c..7e787bc 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -289,8 +289,8 @@
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 @@
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 @@
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 ad17c4f..d5dbaf1 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Expression/ClangExpressionParser.cpp
@@ -210,17 +210,38 @@
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 e7baad1..be86be3 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1316,6 +1316,15 @@
return false;
}
+lldb::LanguageType
+StackFrame::GetLanguage ()
+{
+ CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit;
+ if (cu)
+ return cu->GetLanguage();
+ return lldb::eLanguageTypeUnknown;
+}
+
TargetSP
StackFrame::CalculateTarget ()
{