blob: 3fcc24907257f31555c5a765312782b9a55c8f15 [file] [log] [blame]
Sean Callanane71d5532010-08-27 23:31:21 +00001//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
2//
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
10// C Includes
11#include <stdio.h>
12#if HAVE_SYS_TYPES_H
13# include <sys/types.h>
14#endif
15
16// C++ Includes
17
18#include "lldb/Core/ConstString.h"
Sean Callanan79763a42011-05-23 21:40:23 +000019#include "lldb/Core/Log.h"
Sean Callanane71d5532010-08-27 23:31:21 +000020#include "lldb/Core/Stream.h"
Greg Claytonc4e411f2011-01-18 19:36:39 +000021#include "lldb/Core/StreamFile.h"
Sean Callanan9e6ed532010-09-13 21:34:21 +000022#include "lldb/Expression/ClangExpressionDeclMap.h"
Sean Callanane71d5532010-08-27 23:31:21 +000023#include "lldb/Expression/ClangExpressionParser.h"
24#include "lldb/Expression/ClangUtilityFunction.h"
Greg Clayton399107a2013-02-13 23:57:48 +000025#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanane71d5532010-08-27 23:31:21 +000026#include "lldb/Host/Host.h"
27#include "lldb/Target/ExecutionContext.h"
28#include "lldb/Target/Target.h"
29
30using namespace lldb_private;
31
32//------------------------------------------------------------------
33/// Constructor
34///
35/// @param[in] text
36/// The text of the function. Must be a full translation unit.
37///
38/// @param[in] name
39/// The name of the function, as used in the text.
40//------------------------------------------------------------------
41ClangUtilityFunction::ClangUtilityFunction (const char *text,
42 const char *name) :
Greg Clayton22a939a2011-01-19 23:00:49 +000043 ClangExpression (),
Greg Clayton399107a2013-02-13 23:57:48 +000044 m_function_text (ExpressionSourceCode::g_expression_prefix),
Greg Clayton22a939a2011-01-19 23:00:49 +000045 m_function_name (name)
Sean Callanane71d5532010-08-27 23:31:21 +000046{
Greg Claytona66c4d92013-02-13 22:56:14 +000047 if (text && text[0])
48 m_function_text.append (text);
Sean Callanane71d5532010-08-27 23:31:21 +000049}
50
Greg Clayton5573fde2010-09-24 23:07:41 +000051ClangUtilityFunction::~ClangUtilityFunction ()
52{
53}
54
Sean Callanane71d5532010-08-27 23:31:21 +000055//------------------------------------------------------------------
56/// Install the utility function into a process
57///
58/// @param[in] error_stream
59/// A stream to print parse errors and warnings to.
60///
61/// @param[in] exe_ctx
62/// The execution context to install the utility function to.
63///
64/// @return
65/// True on success (no errors); false otherwise.
66//------------------------------------------------------------------
67bool
68ClangUtilityFunction::Install (Stream &error_stream,
69 ExecutionContext &exe_ctx)
Sean Callanan6961e872010-09-01 00:58:00 +000070{
Greg Clayton22a939a2011-01-19 23:00:49 +000071 if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
Sean Callanan6961e872010-09-01 00:58:00 +000072 {
73 error_stream.PutCString("error: already installed\n");
74 return false;
75 }
76
Sean Callanane71d5532010-08-27 23:31:21 +000077 ////////////////////////////////////
78 // Set up the target and compiler
79 //
80
Greg Claytonc14ee322011-09-22 04:58:26 +000081 Target *target = exe_ctx.GetTargetPtr();
Sean Callanane71d5532010-08-27 23:31:21 +000082
83 if (!target)
84 {
85 error_stream.PutCString ("error: invalid target\n");
86 return false;
87 }
Sean Callanan79763a42011-05-23 21:40:23 +000088
Greg Claytonc14ee322011-09-22 04:58:26 +000089 Process *process = exe_ctx.GetProcessPtr();
Sean Callanan79763a42011-05-23 21:40:23 +000090
91 if (!process)
92 {
93 error_stream.PutCString ("error: invalid process\n");
94 return false;
95 }
Greg Clayton514487e2011-02-15 21:59:32 +000096
Sean Callanane71d5532010-08-27 23:31:21 +000097 //////////////////////////
98 // Parse the expression
99 //
Sean Callanan9e6ed532010-09-13 21:34:21 +0000100
Sean Callanan92adcac2011-01-13 08:53:35 +0000101 bool keep_result_in_memory = false;
102
Sean Callanan1ee44b72011-10-29 01:58:46 +0000103 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sean Callanan979f74d2010-12-03 01:38:59 +0000104
Sean Callanan96d27302013-04-11 00:09:05 +0000105 if (!m_expr_decl_map->WillParse(exe_ctx, NULL))
Sean Callananb9951192011-08-01 18:18:33 +0000106 {
107 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
108 return false;
109 }
Sean Callanane71d5532010-08-27 23:31:21 +0000110
Greg Clayton514487e2011-02-15 21:59:32 +0000111 ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this);
Sean Callanane71d5532010-08-27 23:31:21 +0000112
113 unsigned num_errors = parser.Parse (error_stream);
114
115 if (num_errors)
116 {
117 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sean Callanan9e6ed532010-09-13 21:34:21 +0000118
119 m_expr_decl_map.reset();
120
Sean Callanane71d5532010-08-27 23:31:21 +0000121 return false;
122 }
123
124 //////////////////////////////////
125 // JIT the output of the parser
126 //
Sean Callanan63697e52011-05-07 01:06:41 +0000127
128 lldb::ClangExpressionVariableSP const_result;
Sean Callanan79763a42011-05-23 21:40:23 +0000129
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000130 bool evaluated_statically = false; // should stay that way
131
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000132 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000133 m_jit_end_addr,
134 m_execution_unit_ap,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000135 exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000136 evaluated_statically,
137 const_result,
138 eExecutionPolicyAlways);
Sean Callanan79763a42011-05-23 21:40:23 +0000139
Greg Claytonc14ee322011-09-22 04:58:26 +0000140 if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000141 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanane71d5532010-08-27 23:31:21 +0000142
Greg Claytonc4e411f2011-01-18 19:36:39 +0000143#if 0
144 // jingham: look here
145 StreamFile logfile ("/tmp/exprs.txt", "a");
Daniel Malead01b2952012-11-29 21:49:15 +0000146 logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n",
Greg Clayton22a939a2011-01-19 23:00:49 +0000147 m_jit_start_addr,
Greg Claytonc4e411f2011-01-18 19:36:39 +0000148 m_function_name.c_str(),
149 m_function_text.c_str());
150#endif
151
Sean Callanan979f74d2010-12-03 01:38:59 +0000152 m_expr_decl_map->DidParse();
153
Sean Callanan9e6ed532010-09-13 21:34:21 +0000154 m_expr_decl_map.reset();
155
Sean Callanane71d5532010-08-27 23:31:21 +0000156 if (jit_error.Success())
157 {
158 return true;
159 }
160 else
161 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000162 const char *error_cstr = jit_error.AsCString();
163 if (error_cstr && error_cstr[0])
164 error_stream.Printf ("error: %s\n", error_cstr);
165 else
Jason Molendafd54b362011-09-20 21:44:10 +0000166 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanane71d5532010-08-27 23:31:21 +0000167 return false;
168 }
169}
170
171