Index: include/lldb/Target/Target.h =================================================================== --- include/lldb/Target/Target.h +++ include/lldb/Target/Target.h @@ -172,6 +172,8 @@ lldb::LanguageType GetLanguage () const; + void SetLanguage (lldb::LanguageType); + const char * GetExpressionPrefixContentsAsCString (); @@ -948,6 +950,9 @@ void SymbolsDidLoad (ModuleList &module_list); + + lldb::LanguageType + ComputeLanguageType(const ModuleList &module_list); void ClearModules(bool delete_locations); Index: source/Commands/CommandObjectExpression.cpp =================================================================== --- source/Commands/CommandObjectExpression.cpp +++ source/Commands/CommandObjectExpression.cpp @@ -300,13 +300,8 @@ options.SetUseDynamic(m_varobj_options.use_dynamic); options.SetTryAllThreads(m_command_options.try_all_threads); options.SetDebug(m_command_options.debug); + options.SetLanguage(m_command_options.language); - // 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 || Index: source/Expression/ClangUserExpression.cpp =================================================================== --- source/Expression/ClangUserExpression.cpp +++ source/Expression/ClangUserExpression.cpp @@ -16,6 +16,7 @@ #include #include +#include "lldb/lldb-enumerations.h" #include "lldb/Core/ConstString.h" #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" @@ -52,6 +53,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +using namespace lldb; using namespace lldb_private; ClangUserExpression::ClangUserExpression (const char *expr, @@ -1030,7 +1032,36 @@ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); - const lldb::LanguageType language = options.GetLanguage(); + + // Predict the language if it was not set in options + lldb::LanguageType language = options.GetLanguage(); + if (language == eLanguageTypeUnknown) { + StackFrameSP frame = exe_ctx.GetFrameSP(); + if (frame && frame->HasDebugInformation()) { + Block *block = frame->GetFrameBlock(); + if (block != NULL) { + lldb::ModuleSP module = block->CalculateSymbolContextModule(); + SymbolContext symbol_context; + block->CalculateSymbolContext(&symbol_context); + + if (module) + language = module->GetSymbolVendor()->ParseCompileUnitLanguage(symbol_context); + } + } + } + if (language == eLanguageTypeUnknown) { + StackFrameSP frame = exe_ctx.GetFrameSP(); + if (frame) { + TargetSP target = frame->CalculateTarget(); + if (target) + language = target->GetLanguage(); + } + } + // Treat C and C++ as C++11 + std::set c_langs = {eLanguageTypeC99, eLanguageTypeC, eLanguageTypeC89, eLanguageTypeC11, eLanguageTypeC_plus_plus, eLanguageTypeC_plus_plus_11, eLanguageTypeC_plus_plus_03}; + if (c_langs.find(language) != c_langs.end()) + language = eLanguageTypeC_plus_plus_11; + const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny; lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; Index: source/Target/Target.cpp =================================================================== --- source/Target/Target.cpp +++ source/Target/Target.cpp @@ -44,6 +44,7 @@ #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" @@ -1291,12 +1292,43 @@ m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp, new_module_sp); } +lldb::LanguageType +Target::ComputeLanguageType(const ModuleList &module_list) { + std::set languages; + + for (size_t i = 0; i < module_list.GetSize(); i++) { + lldb::ModuleSP module = module_list.GetModuleAtIndex(i); + + if (module) { + for (size_t compile_unit_id = 0; compile_unit_id < module->GetNumCompileUnits(); compile_unit_id++) { + CompUnitSP compile_unit = module->GetCompileUnitAtIndex(compile_unit_id); + SymbolContext module_symbol_context(CalculateTarget(), module, compile_unit.get()); + lldb::LanguageType module_language = module->GetSymbolVendor()->ParseCompileUnitLanguage(module_symbol_context); + languages.insert(module_language); + } + } + } + + + lldb::LanguageType target_language = eLanguageTypeUnknown; + if (languages.size() == 1) { + target_language = *languages.begin(); + } + + return target_language; +} + void Target::ModulesDidLoad (ModuleList &module_list) { if (m_valid && module_list.GetSize()) { m_breakpoint_list.UpdateBreakpoints (module_list, true, false); + + ModuleList ml; + ml.Append(GetExecutableModule()); + SetLanguage(ComputeLanguageType(ml)); + if (m_process_sp) { m_process_sp->ModulesDidLoad (module_list); @@ -3166,6 +3198,7 @@ m_collection_sp.reset (new TargetOptionValueProperties(target, Target::GetGlobalProperties())); // Set callbacks to update launch_info whenever "settins set" updated any of these properties + m_collection_sp->SetValueChangedCallback(ePropertyArg0, TargetProperties::Arg0ValueChangedCallback, this); m_collection_sp->SetValueChangedCallback(ePropertyRunArgs, TargetProperties::RunArgsValueChangedCallback, this); m_collection_sp->SetValueChangedCallback(ePropertyEnvVars, TargetProperties::EnvVarsValueChangedCallback, this); @@ -3468,6 +3501,12 @@ return LanguageType(); } +void +TargetProperties::SetLanguage (lldb::LanguageType language) { + OptionValueLanguage *value = m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage(NULL, ePropertyLanguage); + value->SetLanguageValue(language); +} + const char * TargetProperties::GetExpressionPrefixContentsAsCString () { Index: test/lang/cpp/restricted_names/TestCppRestrictedNames.py =================================================================== --- test/lang/cpp/restricted_names/TestCppRestrictedNames.py +++ test/lang/cpp/restricted_names/TestCppRestrictedNames.py @@ -24,7 +24,6 @@ TestBase.setUp(self) def check(self): - # Get main source file src_file = "main.cpp" src_file_spec = lldb.SBFileSpec(src_file) @@ -57,13 +56,11 @@ frame = thread.GetSelectedFrame() # Test result for restricted names (check for wrong result) - self.expect("expression --language c++11 -- Class(2)", substrs = ["= 4"]) - #test_result = frame.EvaluateExpression("Class(2)") - #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 4, "Class(2) = 4") + test_result = frame.EvaluateExpression("Class(2)") + self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 4, "Class(2) = 4") - self.expect("expression --language c++11 -- Class(3)", substrs = ["= 6"]) - #test_result = frame.EvaluateExpression("Class(3)") - #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 6, "Class(3) = 6") + test_result = frame.EvaluateExpression("Class(3)") + self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 6, "Class(3) = 6") if __name__ == '__main__': Index: test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py =================================================================== --- test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py +++ test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py @@ -11,15 +11,14 @@ mydir = TestBase.compute_mydir(__file__) @skipUnlessDarwin - @python_api_test - + @unittest2.expectedFailure @dsym_test def test_with_dsym_and_python_api(self): """Test expression parser respect for ObjC built-in types.""" self.buildDsym() self.objc_builtin_types() - @python_api_test + @unittest2.expectedFailure @dwarf_test def test_with_dwarf_and_python_api(self): """Test expression parser respect for ObjC built-in types."""