blob: d079dc43bea5b125f9df73611ad1440110c3b0e8 [file] [log] [blame]
Sean Callanan830a9032010-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 Callananc0492742011-05-23 21:40:23 +000019#include "lldb/Core/Log.h"
Sean Callanan830a9032010-08-27 23:31:21 +000020#include "lldb/Core/Stream.h"
Greg Claytonc71899e2011-01-18 19:36:39 +000021#include "lldb/Core/StreamFile.h"
Sean Callanane8a59a82010-09-13 21:34:21 +000022#include "lldb/Expression/ClangExpressionDeclMap.h"
Sean Callanan830a9032010-08-27 23:31:21 +000023#include "lldb/Expression/ClangExpressionParser.h"
24#include "lldb/Expression/ClangUtilityFunction.h"
25#include "lldb/Host/Host.h"
26#include "lldb/Target/ExecutionContext.h"
27#include "lldb/Target/Target.h"
28
29using namespace lldb_private;
30
31//------------------------------------------------------------------
32/// Constructor
33///
34/// @param[in] text
35/// The text of the function. Must be a full translation unit.
36///
37/// @param[in] name
38/// The name of the function, as used in the text.
39//------------------------------------------------------------------
40ClangUtilityFunction::ClangUtilityFunction (const char *text,
41 const char *name) :
Greg Claytond0882d02011-01-19 23:00:49 +000042 ClangExpression (),
43 m_function_text (text),
44 m_function_name (name)
Sean Callanan830a9032010-08-27 23:31:21 +000045{
46}
47
Greg Clayton6a5aa8a2010-09-24 23:07:41 +000048ClangUtilityFunction::~ClangUtilityFunction ()
49{
50}
51
Sean Callanan830a9032010-08-27 23:31:21 +000052//------------------------------------------------------------------
53/// Install the utility function into a process
54///
55/// @param[in] error_stream
56/// A stream to print parse errors and warnings to.
57///
58/// @param[in] exe_ctx
59/// The execution context to install the utility function to.
60///
61/// @return
62/// True on success (no errors); false otherwise.
63//------------------------------------------------------------------
64bool
65ClangUtilityFunction::Install (Stream &error_stream,
66 ExecutionContext &exe_ctx)
Sean Callananf18d91c2010-09-01 00:58:00 +000067{
Sean Callananc0492742011-05-23 21:40:23 +000068 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
69
Greg Claytond0882d02011-01-19 23:00:49 +000070 if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
Sean Callananf18d91c2010-09-01 00:58:00 +000071 {
72 error_stream.PutCString("error: already installed\n");
73 return false;
74 }
75
Sean Callanan830a9032010-08-27 23:31:21 +000076 ////////////////////////////////////
77 // Set up the target and compiler
78 //
79
80 Target *target = exe_ctx.target;
81
82 if (!target)
83 {
84 error_stream.PutCString ("error: invalid target\n");
85 return false;
86 }
Sean Callananc0492742011-05-23 21:40:23 +000087
88 Process *process = exe_ctx.process;
89
90 if (!process)
91 {
92 error_stream.PutCString ("error: invalid process\n");
93 return false;
94 }
Greg Clayton395fc332011-02-15 21:59:32 +000095
Sean Callanan830a9032010-08-27 23:31:21 +000096 //////////////////////////
97 // Parse the expression
98 //
Sean Callanane8a59a82010-09-13 21:34:21 +000099
Sean Callanan6a925532011-01-13 08:53:35 +0000100 bool keep_result_in_memory = false;
101
102 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory));
Sean Callananaa301c42010-12-03 01:38:59 +0000103
Sean Callananc0492742011-05-23 21:40:23 +0000104 m_data_allocator.reset(new ProcessDataAllocator(*exe_ctx.process));
105
Sean Callanan166ba102011-08-01 18:18:33 +0000106 if (!m_expr_decl_map->WillParse(exe_ctx))
107 {
108 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
109 return false;
110 }
Sean Callanan830a9032010-08-27 23:31:21 +0000111
Greg Clayton395fc332011-02-15 21:59:32 +0000112 ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this);
Sean Callanan830a9032010-08-27 23:31:21 +0000113
114 unsigned num_errors = parser.Parse (error_stream);
115
116 if (num_errors)
117 {
118 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sean Callanane8a59a82010-09-13 21:34:21 +0000119
120 m_expr_decl_map.reset();
121
Sean Callanan830a9032010-08-27 23:31:21 +0000122 return false;
123 }
124
125 //////////////////////////////////
126 // JIT the output of the parser
127 //
Sean Callanan696cf5f2011-05-07 01:06:41 +0000128
129 lldb::ClangExpressionVariableSP const_result;
Sean Callananc0492742011-05-23 21:40:23 +0000130
Sean Callanan47dc4572011-09-15 02:13:07 +0000131 bool evaluated_statically = false; // should stay that way
132
133 Error jit_error = parser.PrepareForExecution (m_jit_alloc,
134 m_jit_start_addr,
135 m_jit_end_addr,
136 exe_ctx,
137 m_data_allocator.get(),
138 evaluated_statically,
139 const_result,
140 eExecutionPolicyAlways);
Sean Callananc0492742011-05-23 21:40:23 +0000141
142 if (log)
143 {
144 StreamString dump_string;
145 m_data_allocator->Dump(dump_string);
146
147 log->Printf("Data buffer contents:\n%s", dump_string.GetString().c_str());
148 }
Greg Claytond0882d02011-01-19 23:00:49 +0000149
150 if (exe_ctx.process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
151 m_jit_process_sp = exe_ctx.process->GetSP();
Sean Callanan830a9032010-08-27 23:31:21 +0000152
Greg Claytonc71899e2011-01-18 19:36:39 +0000153#if 0
154 // jingham: look here
155 StreamFile logfile ("/tmp/exprs.txt", "a");
156 logfile.Printf ("0x%16.16llx: func = %s, source =\n%s\n",
Greg Claytond0882d02011-01-19 23:00:49 +0000157 m_jit_start_addr,
Greg Claytonc71899e2011-01-18 19:36:39 +0000158 m_function_name.c_str(),
159 m_function_text.c_str());
160#endif
161
Sean Callananaa301c42010-12-03 01:38:59 +0000162 m_expr_decl_map->DidParse();
163
Sean Callanane8a59a82010-09-13 21:34:21 +0000164 m_expr_decl_map.reset();
165
Sean Callanan830a9032010-08-27 23:31:21 +0000166 if (jit_error.Success())
167 {
168 return true;
169 }
170 else
171 {
Greg Clayton30581972011-05-17 03:51:29 +0000172 const char *error_cstr = jit_error.AsCString();
173 if (error_cstr && error_cstr[0])
174 error_stream.Printf ("error: %s\n", error_cstr);
175 else
176 error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors);
Sean Callanan830a9032010-08-27 23:31:21 +0000177 return false;
178 }
179}
180
181