1 //===-- ClangUtilityFunction.cpp ---------------------------------*- C++-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ClangUtilityFunction.h"
11 #include "ClangExpressionDeclMap.h"
12 #include "ClangExpressionParser.h"
17 #include <sys/types.h>
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/StreamFile.h"
24 #include "lldb/Expression/ExpressionSourceCode.h"
25 #include "lldb/Expression/IRExecutionUnit.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Utility/ConstString.h"
30 #include "lldb/Utility/Log.h"
31 #include "lldb/Utility/Stream.h"
33 using namespace lldb_private;
35 //------------------------------------------------------------------
39 /// The text of the function. Must be a full translation unit.
42 /// The name of the function, as used in the text.
43 //------------------------------------------------------------------
44 ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
45 const char *text, const char *name)
46 : UtilityFunction(exe_scope, text, name) {}
48 ClangUtilityFunction::~ClangUtilityFunction() {}
50 //------------------------------------------------------------------
51 /// Install the utility function into a process
53 /// @param[in] diagnostic_manager
54 /// A diagnostic manager to report errors and warnings to.
56 /// @param[in] exe_ctx
57 /// The execution context to install the utility function to.
60 /// True on success (no errors); false otherwise.
61 //------------------------------------------------------------------
62 bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
63 ExecutionContext &exe_ctx) {
64 if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
65 diagnostic_manager.PutString(eDiagnosticSeverityWarning,
70 ////////////////////////////////////
71 // Set up the target and compiler
74 Target *target = exe_ctx.GetTargetPtr();
77 diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
81 Process *process = exe_ctx.GetProcessPtr();
84 diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid process");
88 //////////////////////////
89 // Parse the expression
92 bool keep_result_in_memory = false;
94 ResetDeclMap(exe_ctx, keep_result_in_memory);
96 if (!DeclMap()->WillParse(exe_ctx, NULL)) {
97 diagnostic_manager.PutString(
98 eDiagnosticSeverityError,
99 "current process state is unsuitable for expression parsing");
103 const bool generate_debug_info = true;
104 ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
105 generate_debug_info);
107 unsigned num_errors = parser.Parse(diagnostic_manager);
115 //////////////////////////////////
116 // JIT the output of the parser
119 bool can_interpret = false; // should stay that way
121 Status jit_error = parser.PrepareForExecution(
122 m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
123 can_interpret, eExecutionPolicyAlways);
125 if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
126 m_jit_process_wp = process->shared_from_this();
127 if (parser.GetGenerateDebugInfo()) {
128 lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
131 ConstString const_func_name(FunctionName());
133 jit_file.GetFilename() = const_func_name;
134 jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
135 m_jit_module_wp = jit_module_sp;
136 target->GetImages().Append(jit_module_sp);
141 DeclMap()->DidParse();
145 if (jit_error.Success()) {
148 const char *error_cstr = jit_error.AsCString();
149 if (error_cstr && error_cstr[0]) {
150 diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
152 diagnostic_manager.PutString(eDiagnosticSeverityError,
153 "expression can't be interpreted or run");
159 void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
160 ExecutionContext &exe_ctx, bool keep_result_in_memory) {
161 m_expr_decl_map_up.reset(
162 new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));