ClangUserExpression.cpp revision 427f290ff96f3ab9f2cf3a1af7001d2c560424c7
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"
36360f53f3c216ee4fb433da0a367168785328a856Jim Ingham#include "lldb/Target/ThreadPlan.h"
37360f53f3c216ee4fb433da0a367168785328a856Jim Ingham#include "lldb/Target/ThreadPlanCallUserExpression.h"
3865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
3965dafa8344c8c018e346dd331a7782081a896239Sean Callananusing namespace lldb_private;
4065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
4177e9394f0af653ac0842066a9c7766a28d6c6b94Sean CallananClangUserExpression::ClangUserExpression (const char *expr,
4277e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                          const char *expr_prefix) :
4365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_expr_text(expr),
44b4c0f02b4ea9a160cf4af3dd0326579594d4b488Johnny Chen    m_expr_prefix(expr_prefix ? expr_prefix : ""),
453c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_transformed_text(),
463c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_jit_addr(LLDB_INVALID_ADDRESS),
473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_cplusplus(false),
483c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_objectivec(false),
49a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan    m_needs_object_ptr(false),
50e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    m_const_object(false),
51a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan    m_desired_type(NULL, NULL)
5265dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
5365dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
5465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
55830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUserExpression::~ClangUserExpression ()
56830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan{
57830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan}
58830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
5965dafa8344c8c018e346dd331a7782081a896239Sean Callananclang::ASTConsumer *
6065dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
6165dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
62a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan    return new ASTResultSynthesizer(passthrough,
63a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan                                    m_desired_type);
6465dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
6565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
663c9c5eb466869ede185e879d14a47335fb43194dSean Callananvoid
673c9c5eb466869ede185e879d14a47335fb43194dSean CallananClangUserExpression::ScanContext(ExecutionContext &exe_ctx)
683c9c5eb466869ede185e879d14a47335fb43194dSean Callanan{
693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!exe_ctx.frame)
703c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return;
713c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    VariableList *vars = exe_ctx.frame->GetVariableList(false);
733c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
743c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!vars)
753c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return;
763c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
77e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    lldb::VariableSP this_var(vars->FindVariable(ConstString("this")));
78e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    lldb::VariableSP self_var(vars->FindVariable(ConstString("self")));
79e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan
80e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    if (this_var.get())
81e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    {
82e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan        Type *this_type = this_var->GetType();
83e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan
84e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan        lldb::clang_type_t pointer_target_type;
85e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan
86e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan        if (ClangASTContext::IsPointerType(this_type->GetClangType(),
87e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan                                           &pointer_target_type))
88e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan        {
89e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan            TypeFromUser target_ast_type(pointer_target_type, this_type->GetClangAST());
90e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan
91e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan            if (target_ast_type.IsDefined())
92e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan                m_cplusplus = true;
93e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan
94e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan            if (target_ast_type.IsConst())
95e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan                m_const_object = true;
96e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan        }
97e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    }
98e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    else if (self_var.get())
99e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    {
1003c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_objectivec = true;
101e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    }
1023c9c5eb466869ede185e879d14a47335fb43194dSean Callanan}
1033c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
104550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// This is a really nasty hack, meant to fix Objective-C expressions of the form
105550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// (int)[myArray count].  Right now, because the type information for count is
106550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// not available, [myArray count] returns id, which can't be directly cast to
107550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// int without causing a clang error.
108550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananstatic void
109550f276a34e4db1aa513e18f3438454ce7429a3eSean CallananApplyObjcCastHack(std::string &expr)
110550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan{
111550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_FROM "(int)["
112550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_TO   "(int)(long long)["
113550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
114550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    size_t from_offset;
115550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
116550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
117550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan        expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
118550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
119550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_TO
120550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_FROM
121550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan}
122550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
1233089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// Another hack, meant to allow use of unichar despite it not being available in
1243089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// the type information.  Although we could special-case it in type lookup,
1253089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// hopefully we'll figure out a way to #include the same environment as is
1263089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// present in the original source file rather than try to hack specific type
1273089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// definitions in as needed.
1283089237161d7593a176e1f72dec1b5e4596aab96Sean Callananstatic void
1293089237161d7593a176e1f72dec1b5e4596aab96Sean CallananApplyUnicharHack(std::string &expr)
1303089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan{
1313089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_FROM "unichar"
1323089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_TO   "unsigned short"
1333089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
1343089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan    size_t from_offset;
1353089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
1363089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan    while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
1373089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan        expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
1383089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
1393089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_TO
1403089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_FROM
1413089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan}
1423089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
143550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananbool
144a91dd997b1e809c67901b7ac481942cacae19150Sean CallananClangUserExpression::Parse (Stream &error_stream,
145a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan                            ExecutionContext &exe_ctx,
146a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan                            TypeFromUser desired_type)
14765dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
148e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
14965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
1503c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    ScanContext(exe_ctx);
1513c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1523c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    StreamString m_transformed_stream;
1533c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1543c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    ////////////////////////////////////
1553c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    // Generate the expression
1563c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    //
157550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
158550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    ApplyObjcCastHack(m_expr_text);
159f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton    //ApplyUnicharHack(m_expr_text);
1603c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1613c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (m_cplusplus)
1623c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
16377e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan        m_transformed_stream.Printf("%s                                     \n"
16477e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    "typedef unsigned short unichar;        \n"
165f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton                                    "void                                   \n"
166e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan                                    "$__lldb_class::%s(void *$__lldb_arg) %s\n"
1673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "{                                      \n"
1683c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "    %s;                                \n"
1693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "}                                      \n",
17077e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    m_expr_prefix.c_str(),
1713c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    FunctionName(),
172e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan                                    (m_const_object ? "const" : ""),
1733c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    m_expr_text.c_str());
1743c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1753c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        m_needs_object_ptr = true;
1763c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
1773aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    else if(m_objectivec)
1783aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    {
1793aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        const char *function_name = FunctionName();
1803aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1813aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        m_transformed_stream.Printf("%s                                                     \n"
1823aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "@interface $__lldb_objc_class ($__lldb_category)       \n"
1833aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "-(void)%s:(void *)$__lldb_arg;                         \n"
1843aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "@end                                                   \n"
1853aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "@implementation $__lldb_objc_class ($__lldb_category)  \n"
1863aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "-(void)%s:(void *)$__lldb_arg                          \n"
1873aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "{                                                      \n"
1883aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "    %s;                                                \n"
1893aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "}                                                      \n"
1903aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    "@end                                                   \n",
1913aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    m_expr_prefix.c_str(),
1923aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    function_name,
1933aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    function_name,
1943aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    m_expr_text.c_str());
1953aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1963aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        m_needs_object_ptr = true;
1973aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    }
1983c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else
1993c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
20077e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan        m_transformed_stream.Printf("%s                             \n"
20177e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    "typedef unsigned short unichar;\n"
202f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton                                    "void                           \n"
203550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan                                    "%s(void *$__lldb_arg)          \n"
2043c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "{                              \n"
2053c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "    %s;                        \n"
2063c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    "}                              \n",
20777e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                                    m_expr_prefix.c_str(),
2083c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    FunctionName(),
2093c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    m_expr_text.c_str());
2103c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
2113c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
2123c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    m_transformed_text = m_transformed_stream.GetData();
2133c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
2143c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
2153c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (log)
2163c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
2173c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
21865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ////////////////////////////////////
21965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Set up the target and compiler
22065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
22165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
22265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Target *target = exe_ctx.target;
22365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
22465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target)
22565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
22665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.PutCString ("error: invalid target\n");
22765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
22865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
22965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ConstString target_triple;
23165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    target->GetTargetTriple (target_triple);
23365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target_triple)
23565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        target_triple = Host::GetTargetTriple ();
23665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
23765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target_triple)
23865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
23965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.PutCString ("error: invalid target triple\n");
24065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
24165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
24265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
24365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //////////////////////////
24465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Parse the expression
24565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
24665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
247a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan    m_desired_type = desired_type;
248a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan
249aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan    m_expr_decl_map.reset(new ClangExpressionDeclMap());
250aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
251aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan    m_expr_decl_map->WillParse(exe_ctx);
25265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
25365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ClangExpressionParser parser(target_triple.GetCString(), *this);
25465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
25565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    unsigned num_errors = parser.Parse (error_stream);
25665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
25765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (num_errors)
25865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
25965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
260aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
261aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan        m_expr_decl_map->DidParse();
262aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
26365dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
26465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
26565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
26665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ///////////////////////////////////////////////
26765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Convert the output of the parser to DWARF
26865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
26965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
27065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes.reset(new StreamString);
27165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost);
27265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary);
27365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
274427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton    m_local_variables.reset(new ClangExpressionVariableList());
27565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
27665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    Error dwarf_error = parser.MakeDWARF ();
27765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
27865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (dwarf_error.Success())
27965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
28065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (log)
28165dafa8344c8c018e346dd331a7782081a896239Sean Callanan            log->Printf("Code can be interpreted.");
28265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
283aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan        m_expr_decl_map->DidParse();
284aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
28565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
28665dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
28765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
28865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //////////////////////////////////
28965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // JIT the output of the parser
29065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
29165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
29265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_dwarf_opcodes.reset();
29365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
294830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    lldb::addr_t jit_end;
295830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
296830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan    Error jit_error = parser.MakeJIT (m_jit_addr, jit_end, exe_ctx);
29765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
298aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan    m_expr_decl_map->DidParse();
299aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
30065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (jit_error.Success())
30165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
30265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
30365dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
30465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
30565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
30665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors);
30765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
30865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
30965dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
31065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
31165dafa8344c8c018e346dd331a7782081a896239Sean Callananbool
312d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
313ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan                                                    ExecutionContext &exe_ctx,
314ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan                                                    lldb::addr_t &struct_address,
315047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                                                    lldb::addr_t &object_ptr,
316047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                                                    lldb::addr_t &cmd_ptr)
31765dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
318e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
31965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
320d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    if (m_jit_addr != LLDB_INVALID_ADDRESS)
32165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
32265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        Error materialize_error;
32365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
3243aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (m_needs_object_ptr)
3253c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        {
3263aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            ConstString object_name;
3273aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
3283aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            if (m_cplusplus)
3293aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
3303aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                object_name.SetCString("this");
3313aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
3323aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            else if (m_objectivec)
3333aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
3343aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                object_name.SetCString("self");
3353aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
3363aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            else
3373aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
3383aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                error_stream.Printf("Need object pointer but don't know the language\n");
3393aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                return false;
3403aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
3413aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
3423aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            if (!(m_expr_decl_map->GetObjectPointer(object_ptr, object_name, exe_ctx, materialize_error)))
3433aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
3443aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
3453aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                return false;
3463aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
347047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan
348047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan            if (m_objectivec)
349047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan            {
350047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                ConstString cmd_name("_cmd");
351047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan
352047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                if (!(m_expr_decl_map->GetObjectPointer(cmd_ptr, cmd_name, exe_ctx, materialize_error, true)))
353047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                {
354047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                    error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
355047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                    return false;
356047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                }
357047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan            }
3583c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        }
3593c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
360aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan        if (!m_expr_decl_map->Materialize(exe_ctx, struct_address, materialize_error))
36165dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
3623c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
36365dafa8344c8c018e346dd331a7782081a896239Sean Callanan            return false;
36465dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
36565dafa8344c8c018e346dd331a7782081a896239Sean Callanan
36665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        if (log)
36765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
36894d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan            log->Printf("-- [ClangUserExpression::PrepareToExecuteJITExpression] Materializing for execution --");
3693371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
3703371102ecdff827087df3c27549e57760a6bbc97Sean Callanan            log->Printf("  Function address  : 0x%llx", (uint64_t)m_jit_addr);
3713c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
3723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            if (m_needs_object_ptr)
3733371102ecdff827087df3c27549e57760a6bbc97Sean Callanan                log->Printf("  Object pointer    : 0x%llx", (uint64_t)object_ptr);
3743c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
3753371102ecdff827087df3c27549e57760a6bbc97Sean Callanan            log->Printf("  Structure address : 0x%llx", (uint64_t)struct_address);
37665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
37765dafa8344c8c018e346dd331a7782081a896239Sean Callanan            StreamString args;
37865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
37965dafa8344c8c018e346dd331a7782081a896239Sean Callanan            Error dump_error;
38065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
381e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan            if (struct_address)
38265dafa8344c8c018e346dd331a7782081a896239Sean Callanan            {
383aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan                if (!m_expr_decl_map->DumpMaterializedStruct(exe_ctx, args, dump_error))
384e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                {
3853371102ecdff827087df3c27549e57760a6bbc97Sean Callanan                    log->Printf("  Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
386e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                }
387e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                else
388e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                {
3893371102ecdff827087df3c27549e57760a6bbc97Sean Callanan                    log->Printf("  Structure contents:\n%s", args.GetData());
390e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan                }
39165dafa8344c8c018e346dd331a7782081a896239Sean Callanan            }
39265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
393d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
394d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return true;
395d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
396d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
397d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamThreadPlan *
398d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
399d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                       ExecutionContext &exe_ctx)
400d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
401d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    lldb::addr_t struct_address;
402d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
403d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    lldb::addr_t object_ptr = NULL;
4043aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    lldb::addr_t cmd_ptr = NULL;
405d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
406047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan    PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
407d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
408360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
409360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    // ClangUserExpression resources before the thread plan finishes execution in the target.  But because we are
4103aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    // forcing unwind_on_error to be true here, in practical terms that can't happen.
4113aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
412d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
413a65b52703554a2c2f31357cf5a367ae35db86905Sean Callanan                                                       m_jit_addr,
414a65b52703554a2c2f31357cf5a367ae35db86905Sean Callanan                                                       struct_address,
415a65b52703554a2c2f31357cf5a367ae35db86905Sean Callanan                                                       error_stream,
416a65b52703554a2c2f31357cf5a367ae35db86905Sean Callanan                                                       true,
417a65b52703554a2c2f31357cf5a367ae35db86905Sean Callanan                                                       true,
4183aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                       (m_needs_object_ptr ? &object_ptr : NULL),
4193aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                       (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
420d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
421d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
422d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Inghambool
423d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::FinalizeJITExecution (Stream &error_stream,
424d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                           ExecutionContext &exe_ctx,
425427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                                           lldb::ClangExpressionVariableSP &result)
426d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
427d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    Error expr_error;
428d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
4293371102ecdff827087df3c27549e57760a6bbc97Sean Callanan    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
4303371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
4313371102ecdff827087df3c27549e57760a6bbc97Sean Callanan    if (log)
4323371102ecdff827087df3c27549e57760a6bbc97Sean Callanan    {
43394d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan        log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
4343371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
4353371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        StreamString args;
4363371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
4373371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        Error dump_error;
4383371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
4393371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        if (!m_expr_decl_map->DumpMaterializedStruct(exe_ctx, args, dump_error))
4403371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        {
4413371102ecdff827087df3c27549e57760a6bbc97Sean Callanan            log->Printf("  Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
4423371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        }
4433371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        else
4443371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        {
4453371102ecdff827087df3c27549e57760a6bbc97Sean Callanan            log->Printf("  Structure contents:\n%s", args.GetData());
4463371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        }
4473371102ecdff827087df3c27549e57760a6bbc97Sean Callanan    }
4483371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
449aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan    if (!m_expr_decl_map->Dematerialize(exe_ctx, result, expr_error))
450d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
451d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
452d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        return false;
453d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
454d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return true;
455d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
456d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
457427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Claytonlldb::ExecutionResults
458d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::Execute (Stream &error_stream,
459d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                              ExecutionContext &exe_ctx,
460ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham                              bool discard_on_error,
461360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                              ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
462427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                              lldb::ClangExpressionVariableSP &result)
463d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
4643371102ecdff827087df3c27549e57760a6bbc97Sean Callanan    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
4653371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
466d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    if (m_dwarf_opcodes.get())
467d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
468d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        // TODO execute the JITted opcodes
469d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
470d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        error_stream.Printf("We don't currently support executing DWARF expressions");
471d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
472427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        return lldb::eExecutionSetupError;
473d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
474d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    else if (m_jit_addr != LLDB_INVALID_ADDRESS)
475d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
476d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        lldb::addr_t struct_address;
477d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
478d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        lldb::addr_t object_ptr = NULL;
4793aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        lldb::addr_t cmd_ptr = NULL;
480d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
481047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan        if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
482427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton            return lldb::eExecutionSetupError;
48365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
484ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham        const bool stop_others = true;
485ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham        const bool try_all_threads = true;
48665dafa8344c8c018e346dd331a7782081a896239Sean Callanan
487360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        Address wrapper_address (NULL, m_jit_addr);
4883aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (*(exe_ctx.thread),
4893aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                                          wrapper_address,
4903aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                                          struct_address,
4913aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                                          stop_others,
4923aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                                          discard_on_error,
4933aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                                          (m_needs_object_ptr ? &object_ptr : NULL),
4943aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                                          ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
4953aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                                          shared_ptr_to_me));
4963aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
497360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        if (call_plan_sp == NULL || !call_plan_sp->ValidatePlan (NULL))
498427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton            return lldb::eExecutionSetupError;
499360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
500360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        call_plan_sp->SetPrivate(true);
501360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
502360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        uint32_t single_thread_timeout_usec = 10000000;
5033371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
5043371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        if (log)
50594d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan            log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
5063371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
507427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        lldb::ExecutionResults execution_result = exe_ctx.process->RunThreadPlan (exe_ctx,
508427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                                                                                  call_plan_sp,
509427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                                                                                  stop_others,
510427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                                                                                  try_all_threads,
511427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                                                                                  discard_on_error,
512427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                                                                                  single_thread_timeout_usec,
513427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                                                                                  error_stream);
5143371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
5153371102ecdff827087df3c27549e57760a6bbc97Sean Callanan        if (log)
51694d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan            log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
517360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
518427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        if (execution_result == lldb::eExecutionInterrupted)
51965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
520360f53f3c216ee4fb433da0a367168785328a856Jim Ingham            if (discard_on_error)
521360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                error_stream.Printf ("Expression execution was interrupted.  The process has been returned to the state before execution.");
522360f53f3c216ee4fb433da0a367168785328a856Jim Ingham            else
523360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                error_stream.Printf ("Expression execution was interrupted.  The process has been left at the point where it was interrupted.");
524360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
525360f53f3c216ee4fb433da0a367168785328a856Jim Ingham            return execution_result;
526360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        }
527427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        else if (execution_result != lldb::eExecutionCompleted)
528360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        {
529360f53f3c216ee4fb433da0a367168785328a856Jim Ingham            error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
530360f53f3c216ee4fb433da0a367168785328a856Jim Ingham            return execution_result;
53165dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
53265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
533360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        if  (FinalizeJITExecution (error_stream, exe_ctx, result))
534427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton            return lldb::eExecutionCompleted;
535360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        else
536427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton            return lldb::eExecutionSetupError;
53765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
53865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
53965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
540cb39544fedb3a5c4834c4a741031f9121413bc63Johnny Chen        error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function is present");
541427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        return lldb::eExecutionSetupError;
54265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
54365dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
54465dafa8344c8c018e346dd331a7782081a896239Sean Callanan
54565dafa8344c8c018e346dd331a7782081a896239Sean CallananStreamString &
54665dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::DwarfOpcodeStream ()
54765dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
54865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!m_dwarf_opcodes.get())
54965dafa8344c8c018e346dd331a7782081a896239Sean Callanan        m_dwarf_opcodes.reset(new StreamString());
55065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
55165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    return *m_dwarf_opcodes.get();
55265dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
553377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
554427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Claytonlldb::ExecutionResults
55577e9394f0af653ac0842066a9c7766a28d6c6b94Sean CallananClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
556ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham                               bool discard_on_error,
55777e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                               const char *expr_cstr,
558360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                               const char *expr_prefix,
559360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                               lldb::ValueObjectSP &result_valobj_sp)
560377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton{
56194d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
56294d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
563377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    Error error;
564427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton    lldb::ExecutionResults execution_results = lldb::eExecutionSetupError;
5650baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
5660baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    if (exe_ctx.process == NULL)
567360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    {
568360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        error.SetErrorString ("Must have a process to evaluate expressions.");
569360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
570360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        result_valobj_sp.reset (new ValueObjectConstResult (error));
571427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        return lldb::eExecutionSetupError;
572360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    }
573360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
5740baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    if (!exe_ctx.process->GetDynamicCheckers())
5750baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    {
57694d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan        if (log)
57794d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan            log->Printf("== [ClangUserExpression::Evaluate] Installing dynamic checkers ==");
57894d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
5790baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
5800baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
5810baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        StreamString install_errors;
5820baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
5830baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        if (!dynamic_checkers->Install(install_errors, exe_ctx))
584f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan        {
585f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan            if (install_errors.GetString().empty())
586f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan                error.SetErrorString ("couldn't install checkers, unknown error");
587f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan            else
588f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan                error.SetErrorString (install_errors.GetString().c_str());
589f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan
590f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan            result_valobj_sp.reset (new ValueObjectConstResult (error));
591427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton            return lldb::eExecutionSetupError;
592f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan        }
593f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan
5940baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton        exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
59594d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
59694d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan        if (log)
59794d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan            log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
5980baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton    }
5990baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
600360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix));
601360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
602377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    StreamString error_stream;
603377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
60494d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan    if (log)
60594d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan        log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
60694d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
607360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    if (!user_expression_sp->Parse (error_stream, exe_ctx, TypeFromUser(NULL, NULL)))
608377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
609377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        if (error_stream.GetString().empty())
610377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString ("expression failed to parse, unknown error");
611377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        else
612377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString (error_stream.GetString().c_str());
613377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
614377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    else
615377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
616427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        lldb::ClangExpressionVariableSP expr_result;
617377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
618377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        error_stream.GetString().clear();
61994d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
62094d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan        if (log)
62194d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan            log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
622377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
623360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        execution_results = user_expression_sp->Execute (error_stream,
624360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                                                         exe_ctx,
625360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                                                         discard_on_error,
626360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                                                         user_expression_sp,
627360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                                                         expr_result);
628427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        if (execution_results != lldb::eExecutionCompleted)
629377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        {
63094d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan            if (log)
63194d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan                log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
63294d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
633377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            if (error_stream.GetString().empty())
634377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                error.SetErrorString ("expression failed to execute, unknown error");
635377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            else
636377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton                error.SetErrorString (error_stream.GetString().c_str());
637377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        }
638377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        else
639377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        {
640377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            if (expr_result)
641377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
642427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton                result_valobj_sp = expr_result->GetValueObject();
64394d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
64494d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan                if (log)
64594d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan                    log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString(exe_ctx.GetBestExecutionContextScope()));
646377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
647377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            else
648377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
64994d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan                if (log)
65094d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan                    log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
65194d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
65244820ec9b49bc08c0f4529091019b5bc95ec237aSean Callanan                error.SetErrorString ("Expression did not return a result");
653377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
654377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        }
655377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
65644820ec9b49bc08c0f4529091019b5bc95ec237aSean Callanan
657d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    if (result_valobj_sp.get() == NULL)
658d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton        result_valobj_sp.reset (new ValueObjectConstResult (error));
659d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton
660360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    return execution_results;
661b4c0f02b4ea9a160cf4af3dd0326579594d4b488Johnny Chen}
662