blob: 590ce52faebb3097ac524249df90df6a63515158 [file] [log] [blame]
Alexander Shaposhnikov696bd632016-11-26 05:23:44 +00001//===-- ClangUtilityFunction.cpp ---------------------------------*- C++-*-===//
Sean Callanane71d5532010-08-27 23:31:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Kate Stoneb9c1b512016-09-06 20:57:50 +000010#include "ClangUtilityFunction.h"
Sean Callanan4dbb2712015-09-25 20:35:58 +000011#include "ClangExpressionDeclMap.h"
12#include "ClangExpressionParser.h"
Sean Callanan4dbb2712015-09-25 20:35:58 +000013
Sean Callanane71d5532010-08-27 23:31:21 +000014// C Includes
15#include <stdio.h>
16#if HAVE_SYS_TYPES_H
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include <sys/types.h>
Sean Callanane71d5532010-08-27 23:31:21 +000018#endif
19
20// C++ Includes
21
Sean Callanan79763a42011-05-23 21:40:23 +000022#include "lldb/Core/Log.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000023#include "lldb/Core/Module.h"
Greg Claytonc4e411f2011-01-18 19:36:39 +000024#include "lldb/Core/StreamFile.h"
Greg Clayton399107a2013-02-13 23:57:48 +000025#include "lldb/Expression/ExpressionSourceCode.h"
Greg Claytone01e07b2013-04-18 18:10:51 +000026#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanane71d5532010-08-27 23:31:21 +000027#include "lldb/Host/Host.h"
28#include "lldb/Target/ExecutionContext.h"
29#include "lldb/Target/Target.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000030#include "lldb/Utility/ConstString.h"
31#include "lldb/Utility/Stream.h"
Sean Callanane71d5532010-08-27 23:31:21 +000032
33using namespace lldb_private;
34
35//------------------------------------------------------------------
36/// Constructor
37///
38/// @param[in] text
39/// The text of the function. Must be a full translation unit.
40///
41/// @param[in] name
42/// The name of the function, as used in the text.
43//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000044ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
45 const char *text, const char *name)
46 : UtilityFunction(exe_scope, text, name) {}
Sean Callanane71d5532010-08-27 23:31:21 +000047
Kate Stoneb9c1b512016-09-06 20:57:50 +000048ClangUtilityFunction::~ClangUtilityFunction() {}
Greg Clayton5573fde2010-09-24 23:07:41 +000049
Sean Callanane71d5532010-08-27 23:31:21 +000050//------------------------------------------------------------------
51/// Install the utility function into a process
52///
Sean Callanan579e70c2016-03-19 00:03:59 +000053/// @param[in] diagnostic_manager
54/// A diagnostic manager to report errors and warnings to.
Sean Callanane71d5532010-08-27 23:31:21 +000055///
56/// @param[in] exe_ctx
57/// The execution context to install the utility function to.
58///
59/// @return
60/// True on success (no errors); false otherwise.
61//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000062bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
63 ExecutionContext &exe_ctx) {
64 if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
Zachary Turnere2411fa2016-11-12 19:12:56 +000065 diagnostic_manager.PutString(eDiagnosticSeverityWarning,
66 "already installed");
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 return false;
68 }
69
70 ////////////////////////////////////
71 // Set up the target and compiler
72 //
73
74 Target *target = exe_ctx.GetTargetPtr();
75
76 if (!target) {
Zachary Turnere2411fa2016-11-12 19:12:56 +000077 diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 return false;
79 }
80
81 Process *process = exe_ctx.GetProcessPtr();
82
83 if (!process) {
Zachary Turnere2411fa2016-11-12 19:12:56 +000084 diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid process");
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 return false;
86 }
87
88 //////////////////////////
89 // Parse the expression
90 //
91
92 bool keep_result_in_memory = false;
93
94 ResetDeclMap(exe_ctx, keep_result_in_memory);
95
96 if (!DeclMap()->WillParse(exe_ctx, NULL)) {
Zachary Turnere2411fa2016-11-12 19:12:56 +000097 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 eDiagnosticSeverityError,
99 "current process state is unsuitable for expression parsing");
100 return false;
101 }
102
103 const bool generate_debug_info = true;
104 ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
105 generate_debug_info);
106
107 unsigned num_errors = parser.Parse(diagnostic_manager);
108
109 if (num_errors) {
110 ResetDeclMap();
111
112 return false;
113 }
114
115 //////////////////////////////////
116 // JIT the output of the parser
117 //
118
119 bool can_interpret = false; // should stay that way
120
121 Error jit_error = parser.PrepareForExecution(
122 m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
123 can_interpret, eExecutionPolicyAlways);
124
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());
129
130 if (jit_module_sp) {
131 ConstString const_func_name(FunctionName());
132 FileSpec jit_file;
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);
137 }
Sean Callanan6961e872010-09-01 00:58:00 +0000138 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 }
Sean Callanan579e70c2016-03-19 00:03:59 +0000140
Greg Claytonc4e411f2011-01-18 19:36:39 +0000141#if 0
142 // jingham: look here
143 StreamFile logfile ("/tmp/exprs.txt", "a");
Daniel Malead01b2952012-11-29 21:49:15 +0000144 logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n",
Greg Clayton22a939a2011-01-19 23:00:49 +0000145 m_jit_start_addr,
Greg Claytonc4e411f2011-01-18 19:36:39 +0000146 m_function_name.c_str(),
147 m_function_text.c_str());
148#endif
149
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150 DeclMap()->DidParse();
151
152 ResetDeclMap();
153
154 if (jit_error.Success()) {
155 return true;
156 } else {
157 const char *error_cstr = jit_error.AsCString();
158 if (error_cstr && error_cstr[0]) {
159 diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
160 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000161 diagnostic_manager.PutString(eDiagnosticSeverityError,
162 "expression can't be interpreted or run");
Sean Callanane71d5532010-08-27 23:31:21 +0000163 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 return false;
165 }
Sean Callanane71d5532010-08-27 23:31:21 +0000166}
167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
169 ExecutionContext &exe_ctx, bool keep_result_in_memory) {
170 m_expr_decl_map_up.reset(
171 new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
Jim Ingham151c0322015-09-15 21:13:50 +0000172}