1830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
2830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//
3830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//                     The LLVM Compiler Infrastructure
4830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//
5830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// This file is distributed under the University of Illinois Open Source
6830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// License. See LICENSE.TXT for details.
7830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//
8830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//===----------------------------------------------------------------------===//
9830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
10830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// C Includes
11830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include <stdio.h>
12830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#if HAVE_SYS_TYPES_H
13830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#  include <sys/types.h>
14830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#endif
15830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
16830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// C++ Includes
17830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
18830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Core/ConstString.h"
19c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan#include "lldb/Core/Log.h"
20830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Core/Stream.h"
21c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton#include "lldb/Core/StreamFile.h"
22e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h"
23830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Expression/ClangExpressionParser.h"
24830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Expression/ClangUtilityFunction.h"
258459ba986e7ddd1539b046648680f2283fde8304Greg Clayton#include "lldb/Expression/ExpressionSourceCode.h"
2681a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton#include "lldb/Expression/IRExecutionUnit.h"
27830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Host/Host.h"
28830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Target/ExecutionContext.h"
29830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Target/Target.h"
30830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
31830a903fd7cd4595cf52e1630b6491930ada0400Sean Callananusing namespace lldb_private;
32830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
33830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------
34830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// Constructor
35830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///
36830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] text
37830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///     The text of the function.  Must be a full translation unit.
38830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///
39830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] name
40830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///     The name of the function, as used in the text.
41830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------
42830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUtilityFunction::ClangUtilityFunction (const char *text,
43830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan                                            const char *name) :
44d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    ClangExpression (),
458459ba986e7ddd1539b046648680f2283fde8304Greg Clayton    m_function_text (ExpressionSourceCode::g_expression_prefix),
46d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    m_function_name (name)
47830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan{
48ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton    if (text && text[0])
49ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton        m_function_text.append (text);
50830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan}
51830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
526a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg ClaytonClangUtilityFunction::~ClangUtilityFunction ()
536a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg Clayton{
546a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg Clayton}
556a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg Clayton
56830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------
57830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// Install the utility function into a process
58830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///
59830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] error_stream
60830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///     A stream to print parse errors and warnings to.
61830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///
62830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] exe_ctx
63830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///     The execution context to install the utility function to.
64830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///
65830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @return
66830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan///     True on success (no errors); false otherwise.
67830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------
68830a903fd7cd4595cf52e1630b6491930ada0400Sean Callananbool
69830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUtilityFunction::Install (Stream &error_stream,
70830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan                               ExecutionContext &exe_ctx)
71f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{
72d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
73f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan    {
74f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan        error_stream.PutCString("error: already installed\n");
75f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan        return false;
76f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan    }
77f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan
78830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    ////////////////////////////////////
79830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    // Set up the target and compiler
80830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    //
81830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
82567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    Target *target = exe_ctx.GetTargetPtr();
83830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
84830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    if (!target)
85830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    {
86830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan        error_stream.PutCString ("error: invalid target\n");
87830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan        return false;
88830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    }
89c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
90567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    Process *process = exe_ctx.GetProcessPtr();
91c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
92c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    if (!process)
93c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
94c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        error_stream.PutCString ("error: invalid process\n");
95c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        return false;
96c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
97395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton
98830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    //////////////////////////
99830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    // Parse the expression
100830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    //
101e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
1026a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    bool keep_result_in_memory = false;
1036a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan
10473b520f4f60dca58e58e446c9504d45384ee677bSean Callanan    m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
105aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
1063b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan    if (!m_expr_decl_map->WillParse(exe_ctx, NULL))
107166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan    {
108166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan        error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
109166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan        return false;
110166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan    }
111830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
112395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this);
113830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
114830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    unsigned num_errors = parser.Parse (error_stream);
115830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
116830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    if (num_errors)
117830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    {
118830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan        error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
119e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
120e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan        m_expr_decl_map.reset();
121e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
122830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan        return false;
123830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    }
124830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
125830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    //////////////////////////////////
126830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    // JIT the output of the parser
127830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    //
1280f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
1290f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    bool can_interpret = false; // should stay that way
13047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
1311cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
1329e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                                                  m_jit_end_addr,
1339e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                                                  m_execution_unit_ap,
13447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                                  exe_ctx,
1350f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                  can_interpret,
13647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                                  eExecutionPolicyAlways);
137c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
138567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
1397adfcfdb46018d16393995276699a04505727808Enrico Granata        m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
140830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
141c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton#if 0
142c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton	// jingham: look here
143c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton    StreamFile logfile ("/tmp/exprs.txt", "a");
1445f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n",
145d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton                    m_jit_start_addr,
146c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton                    m_function_name.c_str(),
147c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton                    m_function_text.c_str());
148c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton#endif
149c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton
150aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan    m_expr_decl_map->DidParse();
151aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
152e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan    m_expr_decl_map.reset();
153e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
154830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    if (jit_error.Success())
155830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    {
156830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan        return true;
157830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    }
158830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    else
159830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    {
1603058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton        const char *error_cstr = jit_error.AsCString();
1613058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton        if (error_cstr && error_cstr[0])
1623058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton            error_stream.Printf ("error: %s\n", error_cstr);
1633058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton        else
1647e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda            error_stream.Printf ("error: expression can't be interpreted or run\n");
165830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan        return false;
166830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    }
167830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan}
168830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
169830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
170