1254721Semaste//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste// C Includes 11254721Semaste#include <stdio.h> 12254721Semaste#if HAVE_SYS_TYPES_H 13254721Semaste# include <sys/types.h> 14254721Semaste#endif 15254721Semaste 16254721Semaste// C++ Includes 17254721Semaste 18254721Semaste#include "lldb/Core/ConstString.h" 19254721Semaste#include "lldb/Core/Log.h" 20254721Semaste#include "lldb/Core/Stream.h" 21254721Semaste#include "lldb/Core/StreamFile.h" 22254721Semaste#include "lldb/Expression/ClangExpressionDeclMap.h" 23254721Semaste#include "lldb/Expression/ClangExpressionParser.h" 24254721Semaste#include "lldb/Expression/ClangUtilityFunction.h" 25254721Semaste#include "lldb/Expression/ExpressionSourceCode.h" 26254721Semaste#include "lldb/Expression/IRExecutionUnit.h" 27254721Semaste#include "lldb/Host/Host.h" 28254721Semaste#include "lldb/Target/ExecutionContext.h" 29254721Semaste#include "lldb/Target/Target.h" 30254721Semaste 31254721Semasteusing namespace lldb_private; 32254721Semaste 33254721Semaste//------------------------------------------------------------------ 34254721Semaste/// Constructor 35254721Semaste/// 36254721Semaste/// @param[in] text 37254721Semaste/// The text of the function. Must be a full translation unit. 38254721Semaste/// 39254721Semaste/// @param[in] name 40254721Semaste/// The name of the function, as used in the text. 41254721Semaste//------------------------------------------------------------------ 42254721SemasteClangUtilityFunction::ClangUtilityFunction (const char *text, 43254721Semaste const char *name) : 44254721Semaste ClangExpression (), 45254721Semaste m_function_text (ExpressionSourceCode::g_expression_prefix), 46254721Semaste m_function_name (name) 47254721Semaste{ 48254721Semaste if (text && text[0]) 49254721Semaste m_function_text.append (text); 50254721Semaste} 51254721Semaste 52254721SemasteClangUtilityFunction::~ClangUtilityFunction () 53254721Semaste{ 54254721Semaste} 55254721Semaste 56254721Semaste//------------------------------------------------------------------ 57254721Semaste/// Install the utility function into a process 58254721Semaste/// 59254721Semaste/// @param[in] error_stream 60254721Semaste/// A stream to print parse errors and warnings to. 61254721Semaste/// 62254721Semaste/// @param[in] exe_ctx 63254721Semaste/// The execution context to install the utility function to. 64254721Semaste/// 65254721Semaste/// @return 66254721Semaste/// True on success (no errors); false otherwise. 67254721Semaste//------------------------------------------------------------------ 68254721Semastebool 69254721SemasteClangUtilityFunction::Install (Stream &error_stream, 70254721Semaste ExecutionContext &exe_ctx) 71254721Semaste{ 72254721Semaste if (m_jit_start_addr != LLDB_INVALID_ADDRESS) 73254721Semaste { 74254721Semaste error_stream.PutCString("error: already installed\n"); 75254721Semaste return false; 76254721Semaste } 77254721Semaste 78254721Semaste //////////////////////////////////// 79254721Semaste // Set up the target and compiler 80254721Semaste // 81254721Semaste 82254721Semaste Target *target = exe_ctx.GetTargetPtr(); 83254721Semaste 84254721Semaste if (!target) 85254721Semaste { 86254721Semaste error_stream.PutCString ("error: invalid target\n"); 87254721Semaste return false; 88254721Semaste } 89254721Semaste 90254721Semaste Process *process = exe_ctx.GetProcessPtr(); 91254721Semaste 92254721Semaste if (!process) 93254721Semaste { 94254721Semaste error_stream.PutCString ("error: invalid process\n"); 95254721Semaste return false; 96254721Semaste } 97254721Semaste 98254721Semaste ////////////////////////// 99254721Semaste // Parse the expression 100254721Semaste // 101254721Semaste 102254721Semaste bool keep_result_in_memory = false; 103254721Semaste 104254721Semaste m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx)); 105254721Semaste 106254721Semaste if (!m_expr_decl_map->WillParse(exe_ctx, NULL)) 107254721Semaste { 108254721Semaste error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n"); 109254721Semaste return false; 110254721Semaste } 111254721Semaste 112254721Semaste ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this); 113254721Semaste 114254721Semaste unsigned num_errors = parser.Parse (error_stream); 115254721Semaste 116254721Semaste if (num_errors) 117254721Semaste { 118254721Semaste error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 119254721Semaste 120254721Semaste m_expr_decl_map.reset(); 121254721Semaste 122254721Semaste return false; 123254721Semaste } 124254721Semaste 125254721Semaste ////////////////////////////////// 126254721Semaste // JIT the output of the parser 127254721Semaste // 128254721Semaste 129254721Semaste bool can_interpret = false; // should stay that way 130254721Semaste 131254721Semaste Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 132254721Semaste m_jit_end_addr, 133254721Semaste m_execution_unit_ap, 134254721Semaste exe_ctx, 135254721Semaste can_interpret, 136254721Semaste eExecutionPolicyAlways); 137254721Semaste 138254721Semaste if (m_jit_start_addr != LLDB_INVALID_ADDRESS) 139254721Semaste m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); 140254721Semaste 141254721Semaste#if 0 142254721Semaste // jingham: look here 143254721Semaste StreamFile logfile ("/tmp/exprs.txt", "a"); 144254721Semaste logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n", 145254721Semaste m_jit_start_addr, 146254721Semaste m_function_name.c_str(), 147254721Semaste m_function_text.c_str()); 148254721Semaste#endif 149254721Semaste 150254721Semaste m_expr_decl_map->DidParse(); 151254721Semaste 152254721Semaste m_expr_decl_map.reset(); 153254721Semaste 154254721Semaste if (jit_error.Success()) 155254721Semaste { 156254721Semaste return true; 157254721Semaste } 158254721Semaste else 159254721Semaste { 160254721Semaste const char *error_cstr = jit_error.AsCString(); 161254721Semaste if (error_cstr && error_cstr[0]) 162254721Semaste error_stream.Printf ("error: %s\n", error_cstr); 163254721Semaste else 164254721Semaste error_stream.Printf ("error: expression can't be interpreted or run\n"); 165254721Semaste return false; 166254721Semaste } 167254721Semaste} 168254721Semaste 169254721Semaste 170