ClangUserExpression.cpp revision cb39544fedb3a5c4834c4a741031f9121413bc63
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"
330baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton#include "lldb/Target/Process.h"
343c9c5eb466869ede185e879d14a47335fb43194dSean Callanan#include "lldb/Target/StackFrame.h"
3565dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/Target.h"
3665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
3765dafa8344c8c018e346dd331a7782081a896239Sean Callananusing namespace lldb_private;
3865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
3977e9394f0af653ac0842066a9c7766a28d6c6b94Sean CallananClangUserExpression::ClangUserExpression (const char *expr,
4077e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                          const char *expr_prefix) :
4165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_expr_text(expr),
42b4c0f02b4ea9a160cf4af3dd0326579594d4b488Johnny Chen    m_expr_prefix(expr_prefix ? expr_prefix : ""),
433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_transformed_text(),
443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_jit_addr(LLDB_INVALID_ADDRESS),
453c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_cplusplus(false),
463c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_objectivec(false),
473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_needs_object_ptr(false)
4865dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
4965dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
5065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
51830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUserExpression::~ClangUserExpression ()
52830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan{
53830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan}
54830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
5565dafa8344c8c018e346dd331a7782081a896239Sean Callananclang::ASTConsumer *
5665dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
5765dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
5865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    return new ASTResultSynthesizer(passthrough);
5965dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
6065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
613c9c5eb466869ede185e879d14a47335fb43194dSean Callananvoid
623c9c5eb466869ede185e879d14a47335fb43194dSean CallananClangUserExpression::ScanContext(ExecutionContext &exe_ctx)
633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan{
643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!exe_ctx.frame)
653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return;
663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    VariableList *vars = exe_ctx.frame->GetVariableList(false);
683c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!vars)
703c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return;
713c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (vars->FindVariable(ConstString("this")).get())
733c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_cplusplus = true;
743c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else if (vars->FindVariable(ConstString("self")).get())
753c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_objectivec = true;
763c9c5eb466869ede185e879d14a47335fb43194dSean Callanan}
773c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
78550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// This is a really nasty hack, meant to fix Objective-C expressions of the form
79550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// (int)[myArray count].  Right now, because the type information for count is
80550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// not available, [myArray count] returns id, which can't be directly cast to
81550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// int without causing a clang error.
82550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananstatic void
83550f276a34e4db1aa513e18f3438454ce7429a3eSean CallananApplyObjcCastHack(std::string &expr)
84550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan{
85550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_FROM "(int)["
86550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_TO   "(int)(long long)["
87550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
88550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    size_t from_offset;
89550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
90550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
91550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan        expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
92550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
93550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_TO
94550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_FROM
95550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan}
96550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
973089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// Another hack, meant to allow use of unichar despite it not being available in
983089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// the type information.  Although we could special-case it in type lookup,
993089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// hopefully we'll figure out a way to #include the same environment as is
1003089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// present in the original source file rather than try to hack specific type
1013089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// definitions in as needed.
1023089237161d7593a176e1f72dec1b5e4596aab96Sean Callananstatic void
1033089237161d7593a176e1f72dec1b5e4596aab96Sean CallananApplyUnicharHack(std::string &expr)
1043089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan{
1053089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_FROM "unichar"
1063089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_TO   "unsigned short"
1073089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
1083089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan    size_t from_offset;
1093089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
1103089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan    while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
1113089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan        expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
1123089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
1133089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_TO
1143089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_FROM
1153089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan}
1163089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
117550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananbool
11865dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx)
11965dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
120e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
12165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
1223c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    ScanContext(exe_ctx);
1233c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1243c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    StreamString m_transformed_stream;
1253c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1263c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    ////////////////////////////////////
1273c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    // Generate the expression
1283c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    //
129550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
130550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    ApplyObjcCastHack(m_expr_text);
131f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton    //ApplyUnicharHack(m_expr_text);
1323c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1333c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (m_cplusplus)
1343c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
13577e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan        m_transformed_stream.Printf("%s                                     \n"
13677e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    "typedef unsigned short unichar;        \n"
137f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton                                    "void                                   \n"
138550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan                                    "$__lldb_class::%s(void *$__lldb_arg)   \n"
1393c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "{                                      \n"
1403c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "    %s;                                \n"
1413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "}                                      \n",
14277e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    m_expr_prefix.c_str(),
1433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    FunctionName(),
1443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    m_expr_text.c_str());
1453c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1463c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_needs_object_ptr = true;
1473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
1483c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else
1493c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
15077e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan        m_transformed_stream.Printf("%s                             \n"
15177e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    "typedef unsigned short unichar;\n"
152f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton                                    "void                           \n"
153550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan                                    "%s(void *$__lldb_arg)          \n"
1543c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "{                              \n"
1553c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "    %s;                        \n"
1563c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "}                              \n",
15777e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    m_expr_prefix.c_str(),
1583c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    FunctionName(),
1593c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    m_expr_text.c_str());
1603c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
1613c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1623c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_transformed_text = m_transformed_stream.GetData();
1633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (log)
1663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
1673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
16865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ////////////////////////////////////
16965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Set up the target and compiler
17065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
17165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
17265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Target *target = exe_ctx.target;
17365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
17465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target)
17565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
17665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.PutCString ("error: invalid target\n");
17765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
17865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
17965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
18065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ConstString target_triple;
18165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
18265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    target->GetTargetTriple (target_triple);
18365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
18465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target_triple)
18565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        target_triple = Host::GetTargetTriple ();
18665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
18765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target_triple)
18865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
18965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.PutCString ("error: invalid target triple\n");
19065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
19165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
19265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
19365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //////////////////////////
19465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Parse the expression
19565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
19665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
19765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx));
19865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
19965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ClangExpressionParser parser(target_triple.GetCString(), *this);
20065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
20165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    unsigned num_errors = parser.Parse (error_stream);
20265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
20365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (num_errors)
20465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
20565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
20665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
20765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
20865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
20965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ///////////////////////////////////////////////
21065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Convert the output of the parser to DWARF
21165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
21265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
21365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes.reset(new StreamString);
21465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost);
21565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary);
21665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
21765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_local_variables.reset(new ClangExpressionVariableStore());
21865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
21965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Error dwarf_error = parser.MakeDWARF ();
22065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
22165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (dwarf_error.Success())
22265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
22365dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (log)
22465dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Code can be interpreted.");
22565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
22665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
22765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
22865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
22965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //////////////////////////////////
23065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // JIT the output of the parser
23165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
23265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes.reset();
23465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
235830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    lldb::addr_t jit_end;
236830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
237830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    Error jit_error = parser.MakeJIT (m_jit_addr, jit_end, exe_ctx);
23865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (jit_error.Success())
24065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
24165dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
24265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
24365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
24465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
24565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors);
24665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
24765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
24865dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
24965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
25065dafa8344c8c018e346dd331a7782081a896239Sean Callananbool
251d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
252ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan                                                    ExecutionContext &exe_ctx,
253ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan                                                    lldb::addr_t &struct_address,
254ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan                                                    lldb::addr_t &object_ptr)
25565dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
256e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
25765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
258d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    if (m_jit_addr != LLDB_INVALID_ADDRESS)
25965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
26065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
26165dafa8344c8c018e346dd331a7782081a896239Sean Callanan        Error materialize_error;
26265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
2633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
2643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, &exe_ctx, materialize_error)))
2653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        {
2663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
2673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
2683c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        }
2693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
27065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (!m_expr_decl_map->Materialize(&exe_ctx, struct_address, materialize_error))
27165dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
2723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
27365dafa8344c8c018e346dd331a7782081a896239Sean Callanan            return false;
27465dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
27565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
27665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (log)
27765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
27865dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Function address  : 0x%llx", (uint64_t)m_jit_addr);
2793c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
2803c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            if (m_needs_object_ptr)
2813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                log->Printf("Object pointer    : 0x%llx", (uint64_t)object_ptr);
2823c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
28365dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Structure address : 0x%llx", (uint64_t)struct_address);
28465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
28565dafa8344c8c018e346dd331a7782081a896239Sean Callanan            StreamString args;
28665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
28765dafa8344c8c018e346dd331a7782081a896239Sean Callanan            Error dump_error;
28865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
289e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan            if (struct_address)
29065dafa8344c8c018e346dd331a7782081a896239Sean Callanan            {
291e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error))
292e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                {
293e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                    log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
294e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                }
295e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                else
296e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                {
297e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                    log->Printf("Structure contents:\n%s", args.GetData());
298e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                }
29965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            }
30065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
301d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
302d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return true;
303d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
304d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
305d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamThreadPlan *
306d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
307d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                       ExecutionContext &exe_ctx)
308d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
309d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    lldb::addr_t struct_address;
310d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
311d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    lldb::addr_t object_ptr = NULL;
312d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
313d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr);
314d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
315d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
316d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                        m_jit_addr,
317d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                        struct_address,
318d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                        error_stream,
319d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                        true,
320d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                        true,
321d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                        (m_needs_object_ptr ? &object_ptr : NULL));
322d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
323d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
324d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Inghambool
325d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::FinalizeJITExecution (Stream &error_stream,
326d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                           ExecutionContext &exe_ctx,
327d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                           ClangExpressionVariable *&result)
328d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
329d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    Error expr_error;
330d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
331d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error))
332d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
333d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
334d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        return false;
335d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
336d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return true;
337d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
338d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
339d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Inghambool
340d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::Execute (Stream &error_stream,
341d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                              ExecutionContext &exe_ctx,
342ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham                              bool discard_on_error,
343d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                              ClangExpressionVariable *&result)
344d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
345d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    if (m_dwarf_opcodes.get())
346d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
347d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        // TODO execute the JITted opcodes
348d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
349d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        error_stream.Printf("We don't currently support executing DWARF expressions");
350d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
351d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        return false;
352d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
353d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    else if (m_jit_addr != LLDB_INVALID_ADDRESS)
354d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
355d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        lldb::addr_t struct_address;
356d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
357d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        lldb::addr_t object_ptr = NULL;
358d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
359d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr);
36065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
361ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham        const bool stop_others = true;
362ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham        const bool try_all_threads = true;
36365dafa8344c8c018e346dd331a7782081a896239Sean Callanan        ClangFunction::ExecutionResults execution_result =
3643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        ClangFunction::ExecuteFunction (exe_ctx,
3653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        m_jit_addr,
3663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        struct_address,
367ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham                                        stop_others,
368ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham                                        try_all_threads,
369ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham                                        discard_on_error,
3700027cec5aaccc8e53e3dde3c88e1dda21c892d4eSean Callanan                                        10000000,
3713c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        error_stream,
3723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                        (m_needs_object_ptr ? &object_ptr : NULL));
37365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
37465dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (execution_result != ClangFunction::eExecutionCompleted)
37565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
37665dafa8344c8c018e346dd331a7782081a896239Sean Callanan            const char *result_name;
37765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
37865dafa8344c8c018e346dd331a7782081a896239Sean Callanan            switch (execution_result)
37965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            {
38065dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionCompleted:
38165dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionCompleted";
38265dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
38365dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionDiscarded:
38465dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionDiscarded";
38565dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
38665dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionInterrupted:
38765dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionInterrupted";
38865dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
38965dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionSetupError:
39065dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionSetupError";
39165dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
39265dafa8344c8c018e346dd331a7782081a896239Sean Callanan                case ClangFunction::eExecutionTimedOut:
39365dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    result_name = "eExecutionTimedOut";
39465dafa8344c8c018e346dd331a7782081a896239Sean Callanan                    break;
39565dafa8344c8c018e346dd331a7782081a896239Sean Callanan            }
39665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
39765dafa8344c8c018e346dd331a7782081a896239Sean Callanan            error_stream.Printf ("Couldn't execute function; result was %s\n", result_name);
39865dafa8344c8c018e346dd331a7782081a896239Sean Callanan            return false;
39965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
40065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
401d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        return FinalizeJITExecution (error_stream, exe_ctx, result);
40265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
40365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
40465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
405cb39544fedb3a5c4834c4a741031f9121413bc63Johnny Chen        error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function is present");
40665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
40765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
40865dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
40965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
41065dafa8344c8c018e346dd331a7782081a896239Sean CallananStreamString &
41165dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::DwarfOpcodeStream ()
41265dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
41365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!m_dwarf_opcodes.get())
41465dafa8344c8c018e346dd331a7782081a896239Sean Callanan        m_dwarf_opcodes.reset(new StreamString());
41565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
41665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    return *m_dwarf_opcodes.get();
41765dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
418377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
419d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Claytonlldb::ValueObjectSP
42077e9394f0af653ac0842066a9c7766a28d6c6b94Sean CallananClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
421ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham                               bool discard_on_error,
42277e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                               const char *expr_cstr,
42377e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                               const char *expr_prefix)
424377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton{
425377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    Error error;
426d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    lldb::ValueObjectSP result_valobj_sp;
4270baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
4280baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    if (exe_ctx.process == NULL)
4290baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        return result_valobj_sp;
4300baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
4310baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    if (!exe_ctx.process->GetDynamicCheckers())
4320baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    {
4330baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
4340baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
4350baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        StreamString install_errors;
4360baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
4370baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        if (!dynamic_checkers->Install(install_errors, exe_ctx))
438f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan        {
439f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan            if (install_errors.GetString().empty())
440f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan                error.SetErrorString ("couldn't install checkers, unknown error");
441f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan            else
442f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan                error.SetErrorString (install_errors.GetString().c_str());
443f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan
444f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan            result_valobj_sp.reset (new ValueObjectConstResult (error));
4450baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton            return result_valobj_sp;
446f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan        }
447f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan
4480baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
4490baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    }
4500baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
45177e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan    ClangUserExpression user_expression (expr_cstr, expr_prefix);
452377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
453377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    StreamString error_stream;
454377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
455377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    if (!user_expression.Parse (error_stream, exe_ctx))
456377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
457377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        if (error_stream.GetString().empty())
458377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString ("expression failed to parse, unknown error");
459377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        else
460377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString (error_stream.GetString().c_str());
461377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
462377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    else
463377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
464377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        ClangExpressionVariable *expr_result = NULL;
465377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
466377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        error_stream.GetString().clear();
467377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
468ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham        if (!user_expression.Execute (error_stream, exe_ctx, discard_on_error, expr_result))
469377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        {
470377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            if (error_stream.GetString().empty())
471377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                error.SetErrorString ("expression failed to execute, unknown error");
472377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            else
473377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                error.SetErrorString (error_stream.GetString().c_str());
474377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        }
475377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        else
476377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        {
477377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // TODO: seems weird to get a pointer to a result object back from
478377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // a function. Do we own it? Feels like we do, but from looking at the
479377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // code we don't. Might be best to make this a reference and state
480377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // explicitly that we don't own it when we get a reference back from
481377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            // the execute?
482377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            if (expr_result)
483377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
484377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                result_valobj_sp = expr_result->GetExpressionResult (&exe_ctx);
485377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
486377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            else
487377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
48844820ec9b49bc08c0f4529091019b5bc95ec237aSean Callanan                error.SetErrorString ("Expression did not return a result");
489377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
490377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        }
491377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
49244820ec9b49bc08c0f4529091019b5bc95ec237aSean Callanan
493d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    if (result_valobj_sp.get() == NULL)
494d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton        result_valobj_sp.reset (new ValueObjectConstResult (error));
495d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton
496d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    return result_valobj_sp;
497b4c0f02b4ea9a160cf4af3dd0326579594d4b488Johnny Chen}
498