ClangUserExpression.cpp revision 0027cec5aaccc8e53e3dde3c88e1dda21c892d4e
165dafa8344c8c018e346dd331a7782081a896239Sean Callanan//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
265dafa8344c8c018e346dd331a7782081a896239Sean Callanan//
365dafa8344c8c018e346dd331a7782081a896239Sean Callanan//                     The LLVM Compiler Infrastructure
465dafa8344c8c018e346dd331a7782081a896239Sean Callanan//
565dafa8344c8c018e346dd331a7782081a896239Sean Callanan// This file is distributed under the University of Illinois Open Source
665dafa8344c8c018e346dd331a7782081a896239Sean Callanan// License. See LICENSE.TXT for details.
765dafa8344c8c018e346dd331a7782081a896239Sean Callanan//
865dafa8344c8c018e346dd331a7782081a896239Sean Callanan//===----------------------------------------------------------------------===//
965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
1065dafa8344c8c018e346dd331a7782081a896239Sean Callanan// C Includes
1165dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <stdio.h>
1265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#if HAVE_SYS_TYPES_H
1365dafa8344c8c018e346dd331a7782081a896239Sean Callanan#  include <sys/types.h>
1465dafa8344c8c018e346dd331a7782081a896239Sean Callanan#endif
1565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
1665dafa8344c8c018e346dd331a7782081a896239Sean Callanan// C++ Includes
1765dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <cstdlib>
1865dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <string>
1965dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <map>
2065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
2165dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/ConstString.h"
2265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/Log.h"
2365dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/StreamString.h"
24d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton#include "lldb/Core/ValueObjectConstResult.h"
2565dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h"
2665dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionParser.h"
2765dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangFunction.h"
2865dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ASTResultSynthesizer.h"
2965dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangUserExpression.h"
3065dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Host/Host.h"
313c9c5eb466869ede185e879d14a47335fb43194dSean Callanan#include "lldb/Symbol/VariableList.h"
3265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/ExecutionContext.h"
333c9c5eb466869ede185e879d14a47335fb43194dSean Callanan#include "lldb/Target/StackFrame.h"
3465dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/Target.h"
3565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
3665dafa8344c8c018e346dd331a7782081a896239Sean Callananusing namespace lldb_private;
3765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
3865dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ClangUserExpression (const char *expr) :
3965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_expr_text(expr),
403c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_transformed_text(),
413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_jit_addr(LLDB_INVALID_ADDRESS),
423c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_cplusplus(false),
433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_objectivec(false),
443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_needs_object_ptr(false)
4565dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
4665dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
4765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
48830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUserExpression::~ClangUserExpression ()
49830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan{
50830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan}
51830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
5265dafa8344c8c018e346dd331a7782081a896239Sean Callananclang::ASTConsumer *
5365dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
5465dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
5565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    return new ASTResultSynthesizer(passthrough);
5665dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
5765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
583c9c5eb466869ede185e879d14a47335fb43194dSean Callananvoid
593c9c5eb466869ede185e879d14a47335fb43194dSean CallananClangUserExpression::ScanContext(ExecutionContext &exe_ctx)
603c9c5eb466869ede185e879d14a47335fb43194dSean Callanan{
613c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!exe_ctx.frame)
623c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return;
633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    VariableList *vars = exe_ctx.frame->GetVariableList(false);
653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!vars)
673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return;
683c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (vars->FindVariable(ConstString("this")).get())
703c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_cplusplus = true;
713c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else if (vars->FindVariable(ConstString("self")).get())
723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_objectivec = true;
733c9c5eb466869ede185e879d14a47335fb43194dSean Callanan}
743c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
7565dafa8344c8c018e346dd331a7782081a896239Sean Callananbool
7665dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx)
7765dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
7865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
7965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
803c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    ScanContext(exe_ctx);
813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
823c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    StreamString m_transformed_stream;
833c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
843c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    ////////////////////////////////////
853c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    // Generate the expression
863c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    //
873c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
883c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (m_cplusplus)
893c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
903c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_transformed_stream.Printf("void                                   \n"
913c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "___clang_class::%s(void *___clang_arg) \n"
923c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "{                                      \n"
933c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "    %s;                                \n"
943c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "}                                      \n",
953c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    FunctionName(),
963c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    m_expr_text.c_str());
973c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
983c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_needs_object_ptr = true;
993c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
1003c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else
1013c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
1023c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_transformed_stream.Printf("void                           \n"
1033c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "%s(void *___clang_arg)         \n"
1043c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "{                              \n"
1053c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "    %s;                        \n"
1063c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "}                              \n",
1073c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    FunctionName(),
1083c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    m_expr_text.c_str());
1093c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
1103c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1113c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_transformed_text = m_transformed_stream.GetData();
1123c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1133c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1143c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (log)
1153c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
1163c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
11765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ////////////////////////////////////
11865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Set up the target and compiler
11965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
12065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
12165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Target *target = exe_ctx.target;
12265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
12365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target)
12465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
12565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.PutCString ("error: invalid target\n");
12665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
12765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
12865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
12965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ConstString target_triple;
13065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
13165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    target->GetTargetTriple (target_triple);
13265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
13365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target_triple)
13465dafa8344c8c018e346dd331a7782081a896239Sean Callanan        target_triple = Host::GetTargetTriple ();
13565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
13665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target_triple)
13765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
13865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.PutCString ("error: invalid target triple\n");
13965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
14065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
14165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
14265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //////////////////////////
14365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Parse the expression
14465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
14565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
14665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx));
14765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
14865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ClangExpressionParser parser(target_triple.GetCString(), *this);
14965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
15065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    unsigned num_errors = parser.Parse (error_stream);
15165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
15265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (num_errors)
15365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
15465dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
15565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
15665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
15765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
15865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ///////////////////////////////////////////////
15965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Convert the output of the parser to DWARF
16065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
16165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
16265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes.reset(new StreamString);
16365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost);
16465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary);
16565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
16665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_local_variables.reset(new ClangExpressionVariableStore());
16765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
16865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Error dwarf_error = parser.MakeDWARF ();
16965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
17065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (dwarf_error.Success())
17165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
17265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (log)
17365dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Code can be interpreted.");
17465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
17565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
17665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
17765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
17865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //////////////////////////////////
17965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // JIT the output of the parser
18065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
18165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
18265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes.reset();
18365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
184830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    lldb::addr_t jit_end;
185830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
186830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    Error jit_error = parser.MakeJIT (m_jit_addr, jit_end, exe_ctx);
18765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
18865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (jit_error.Success())
18965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
19065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (log)
19165dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
19265dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Code can be run in the target.");
19365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
19465dafa8344c8c018e346dd331a7782081a896239Sean Callanan            StreamString disassembly_stream;
19565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
19665dafa8344c8c018e346dd331a7782081a896239Sean Callanan            Error err = parser.DisassembleFunction(disassembly_stream, exe_ctx);
19765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
19865dafa8344c8c018e346dd331a7782081a896239Sean Callanan            if (!err.Success())
19965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            {
20065dafa8344c8c018e346dd331a7782081a896239Sean Callanan                log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
20165dafa8344c8c018e346dd331a7782081a896239Sean Callanan            }
20265dafa8344c8c018e346dd331a7782081a896239Sean Callanan            else
20365dafa8344c8c018e346dd331a7782081a896239Sean Callanan            {
20465dafa8344c8c018e346dd331a7782081a896239Sean Callanan                log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
20565dafa8344c8c018e346dd331a7782081a896239Sean Callanan            }
20665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
20765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
20865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
20965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
21065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
21165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
21265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors);
21365dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
21465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
21565dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
21665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
21765dafa8344c8c018e346dd331a7782081a896239Sean Callananbool
21865dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::Execute (Stream &error_stream,
21965dafa8344c8c018e346dd331a7782081a896239Sean Callanan                              ExecutionContext &exe_ctx,
22065dafa8344c8c018e346dd331a7782081a896239Sean Callanan                              ClangExpressionVariable *&result)
22165dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
22265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
22365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
22465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (m_dwarf_opcodes.get())
22565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
22665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        // TODO execute the JITted opcodes
22765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
22865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf("We don't currently support executing DWARF expressions");
22965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
23165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
23265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else if (m_jit_addr != LLDB_INVALID_ADDRESS)
23365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
23465dafa8344c8c018e346dd331a7782081a896239Sean Callanan        lldb::addr_t struct_address;
23565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        Error materialize_error;
23765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
2383c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        lldb::addr_t object_ptr = NULL;
2393c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
2403c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, &exe_ctx, materialize_error)))
2413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        {
2423c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
2433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
2443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        }
2453c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
24665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (!m_expr_decl_map->Materialize(&exe_ctx, struct_address, materialize_error))
24765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
2483c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
24965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            return false;
25065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
25165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
25265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (log)
25365dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
25465dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Function address  : 0x%llx", (uint64_t)m_jit_addr);
2553c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
2563c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            if (m_needs_object_ptr)
2573c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                log->Printf("Object pointer    : 0x%llx", (uint64_t)object_ptr);
2583c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
25965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Structure address : 0x%llx", (uint64_t)struct_address);
26065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
26165dafa8344c8c018e346dd331a7782081a896239Sean Callanan            StreamString args;
26265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
26365dafa8344c8c018e346dd331a7782081a896239Sean Callanan            Error dump_error;
26465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
265e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan            if (struct_address)
26665dafa8344c8c018e346dd331a7782081a896239Sean Callanan            {
267e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error))
268e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                {
269e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                    log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
270e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                }
271e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                else
272e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                {
273e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                    log->Printf("Structure contents:\n%s", args.GetData());
274e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                }
27565dafa8344c8c018e346dd331a7782081a896239Sean Callanan            }
27665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
27765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
27865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        ClangFunction::ExecutionResults execution_result =
2793c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        ClangFunction::ExecuteFunction (exe_ctx,
2803c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        m_jit_addr,
2813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        struct_address,
2823c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        true,
2833c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        true,
2840027cec5aaccc8e53e3dde3c88e1dda21c892d4eSean Callanan                                        10000000,
2853c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        error_stream,
2863c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        (m_needs_object_ptr ? &object_ptr : NULL));
28765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
28865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (execution_result != ClangFunction::eExecutionCompleted)
28965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
29065dafa8344c8c018e346dd331a7782081a896239Sean Callanan            const char *result_name;
29165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
29265dafa8344c8c018e346dd331a7782081a896239Sean Callanan            switch (execution_result)
29365dafa8344c8c018e346dd331a7782081a896239Sean Callanan            {
29465dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionCompleted:
29565dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionCompleted";
29665dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
29765dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionDiscarded:
29865dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionDiscarded";
29965dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
30065dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionInterrupted:
30165dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionInterrupted";
30265dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
30365dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionSetupError:
30465dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionSetupError";
30565dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
30665dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionTimedOut:
30765dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionTimedOut";
30865dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
30965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            }
31065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
31165dafa8344c8c018e346dd331a7782081a896239Sean Callanan            error_stream.Printf ("Couldn't execute function; result was %s\n", result_name);
31265dafa8344c8c018e346dd331a7782081a896239Sean Callanan            return false;
31365dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
31465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
31565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        Error expr_error;
31665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
31765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error))
31865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
31965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
32065dafa8344c8c018e346dd331a7782081a896239Sean Callanan            return false;
32165dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
32265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
32365dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
32465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
32565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
32665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
32765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function are present");
32865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
32965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
33065dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
33165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
33265dafa8344c8c018e346dd331a7782081a896239Sean CallananStreamString &
33365dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::DwarfOpcodeStream ()
33465dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
33565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!m_dwarf_opcodes.get())
33665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        m_dwarf_opcodes.reset(new StreamString());
33765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
33865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    return *m_dwarf_opcodes.get();
33965dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
340377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
341377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
342d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Claytonlldb::ValueObjectSP
343d171972ecc7788bdb02d3e81420a24841e09a2bfGreg ClaytonClangUserExpression::Evaluate (ExecutionContext &exe_ctx, const char *expr_cstr)
344377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton{
345377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    Error error;
346d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    lldb::ValueObjectSP result_valobj_sp;
347377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    ClangUserExpression user_expression (expr_cstr);
348377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
349377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    StreamString error_stream;
350377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
351377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    if (!user_expression.Parse (error_stream, exe_ctx))
352377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
353377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        if (error_stream.GetString().empty())
354377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString ("expression failed to parse, unknown error");
355377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        else
356377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString (error_stream.GetString().c_str());
357377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
358377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    else
359377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
360377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        ClangExpressionVariable *expr_result = NULL;
361377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
362377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        error_stream.GetString().clear();
363377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
364377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        if (!user_expression.Execute (error_stream, exe_ctx, expr_result))
365377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        {
366377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            if (error_stream.GetString().empty())
367377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                error.SetErrorString ("expression failed to execute, unknown error");
368377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            else
369377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                error.SetErrorString (error_stream.GetString().c_str());
370377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        }
371377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        else
372377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        {
373377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // TODO: seems weird to get a pointer to a result object back from
374377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // a function. Do we own it? Feels like we do, but from looking at the
375377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // code we don't. Might be best to make this a reference and state
376377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // explicitly that we don't own it when we get a reference back from
377377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // the execute?
378377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            if (expr_result)
379377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
380377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                result_valobj_sp = expr_result->GetExpressionResult (&exe_ctx);
381377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
382377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            else
383377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
384377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                error.SetErrorString ("NULL expression result");
385377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
386377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        }
387377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
388d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    if (result_valobj_sp.get() == NULL)
389d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton        result_valobj_sp.reset (new ValueObjectConstResult (error));
390d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton
391d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    return result_valobj_sp;
392377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
393377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton}