diff options
author | Sean Callanan <scallanan@apple.com> | 2016-03-22 21:05:51 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2016-03-22 21:05:51 +0000 |
commit | 00294b34a3c99f3540214a148c0bd15e68f9d7fd (patch) | |
tree | a6892887ee99bed68154d36a82a975d01ec566a1 /lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp | |
parent | e32368fc6edd4f1c284a9ba0cbdd6b8931dbe925 (diff) | |
download | bcm5719-llvm-00294b34a3c99f3540214a148c0bd15e68f9d7fd.tar.gz bcm5719-llvm-00294b34a3c99f3540214a148c0bd15e68f9d7fd.zip |
Backend support for top-level Clang epxressions
This patch adds a new ExecutionPolicy, eExecutionPolicyTopLevel, which
tells the expression parser that the expression should be JITted as top
level code but nothing (except static initializers) should be run. I
have modified the Clang expression parser to recognize this execution
policy. On top of the existing patches that support storing IR and
maintaining a map of arbitrary Decls, this is mainly just patching up a
few places in the expression parser.
I intend to submit a patch for review that exposes this functionality
through the "expression" command and through the SB API. That patch
also includes a testcase for all of this.
<rdar://problem/22864976>
llvm-svn: 264095
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp')
-rw-r--r-- | lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp | 183 |
1 files changed, 109 insertions, 74 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 25ac0e21711..3066384a1a5 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -55,28 +55,25 @@ using namespace lldb_private; -ClangUserExpression::ClangUserExpression (ExecutionContextScope &exe_scope, - const char *expr, - const char *expr_prefix, - lldb::LanguageType language, - ResultType desired_type, - const EvaluateExpressionOptions &options) : - LLVMUserExpression (exe_scope, expr, expr_prefix, language, desired_type, options), - m_type_system_helper(*m_target_wp.lock().get()) +ClangUserExpression::ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix, + lldb::LanguageType language, ResultType desired_type, + const EvaluateExpressionOptions &options) + : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type, options), + m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel) { switch (m_language) { - case lldb::eLanguageTypeC_plus_plus: - m_allow_cxx = true; - break; - case lldb::eLanguageTypeObjC: - m_allow_objc = true; - break; - case lldb::eLanguageTypeObjC_plus_plus: - default: - m_allow_cxx = true; - m_allow_objc = true; - break; + case lldb::eLanguageTypeC_plus_plus: + m_allow_cxx = true; + break; + case lldb::eLanguageTypeObjC: + m_allow_objc = true; + break; + case lldb::eLanguageTypeObjC_plus_plus: + default: + m_allow_cxx = true; + m_allow_objc = true; + break; } } @@ -402,22 +399,30 @@ ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionConte } } } - - std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str())); - - lldb::LanguageType lang_type; - if (m_in_cplusplus_method) - lang_type = lldb::eLanguageTypeC_plus_plus; - else if (m_in_objectivec_method) - lang_type = lldb::eLanguageTypeObjC; + if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) + { + m_transformed_text = m_expr_text; + } else - lang_type = lldb::eLanguageTypeC; - - if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx)) { - diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't construct expression body"); - return false; + std::unique_ptr<ExpressionSourceCode> source_code( + ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str())); + + lldb::LanguageType lang_type; + + if (m_in_cplusplus_method) + lang_type = lldb::eLanguageTypeC_plus_plus; + else if (m_in_objectivec_method) + lang_type = lldb::eLanguageTypeObjC; + else + lang_type = lldb::eLanguageTypeC; + + if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx)) + { + diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't construct expression body"); + return false; + } } if (log) @@ -473,6 +478,11 @@ ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionConte return false; } + if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) + { + DeclMap()->SetLookupsEnabled(true); + } + Process *process = exe_ctx.GetProcessPtr(); ExecutionContextScope *exe_scope = process; @@ -497,16 +507,60 @@ ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionConte // Prepare the output of the parser for execution, evaluating it statically if possible // - Error jit_error = parser.PrepareForExecution (m_jit_start_addr, - m_jit_end_addr, - m_execution_unit_sp, - exe_ctx, - m_can_interpret, - execution_policy); + { + Error jit_error = parser.PrepareForExecution(m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx, + m_can_interpret, execution_policy); + + if (!jit_error.Success()) + { + const char *error_cstr = jit_error.AsCString(); + if (error_cstr && error_cstr[0]) + diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr); + else + diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run"); + return false; + } + } + + if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) + { + Error static_init_error = parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx); + + if (!static_init_error.Success()) + { + const char *error_cstr = static_init_error.AsCString(); + if (error_cstr && error_cstr[0]) + diagnostic_manager.Printf(eDiagnosticSeverityError, "couldn't run static initializers: %s\n", + error_cstr); + else + diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't run static initializers\n"); + return false; + } + } + + if (m_execution_unit_sp) + { + bool register_execution_unit = false; + + if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) + { + register_execution_unit = true; + } + + if (register_execution_unit) + { + // We currently key off there being more than one external function in the execution + // unit to determine whether it needs to live in the process. + + llvm::cast<PersistentExpressionState>( + exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(m_language)) + ->RegisterExecutionUnit(m_execution_unit_sp); + } + } if (generate_debug_info) { - lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule()); + lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule()); if (jit_module_sp) { @@ -517,41 +571,14 @@ ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionConte m_jit_module_wp = jit_module_sp; target->GetImages().Append(jit_module_sp); } -// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile(); -// StreamFile strm (stdout, false); -// if (jit_obj_file) -// { -// jit_obj_file->GetSectionList(); -// jit_obj_file->GetSymtab(); -// jit_obj_file->Dump(&strm); -// } -// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor(); -// if (jit_sym_vendor) -// { -// lldb_private::SymbolContextList sc_list; -// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list); -// sc_list.Dump(&strm, target); -// jit_sym_vendor->Dump(&strm); -// } } - ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions. + ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any + // ClangASTImporter::Minions. - if (jit_error.Success()) - { - if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS) - m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); - return true; - } - else - { - const char *error_cstr = jit_error.AsCString(); - if (error_cstr && error_cstr[0]) - diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr); - else - diagnostic_manager.Printf(eDiagnosticSeverityError, "expression can't be interpreted or run"); - return false; - } + if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS) + m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); + return true; } bool @@ -637,14 +664,22 @@ ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &e } clang::ASTConsumer * -ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough) +ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(clang::ASTConsumer *passthrough) { - m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, - m_target)); + m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, m_top_level, m_target)); return m_result_synthesizer_up.get(); } +void +ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() +{ + if (m_result_synthesizer_up.get()) + { + m_result_synthesizer_up->CommitPersistentDecls(); + } +} + ClangUserExpression::ResultDelegate::ResultDelegate() { } |