1c0492741dc594cd02736521048fe0d8f4c9a0a61Sean 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"
23c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton#include "lldb/Core/StreamFile.h"
2465dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/StreamString.h"
25d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton#include "lldb/Core/ValueObjectConstResult.h"
2605a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan#include "lldb/Expression/ASTResultSynthesizer.h"
2765dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h"
2865dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionParser.h"
2965dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangFunction.h"
3065dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangUserExpression.h"
31de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan#include "lldb/Expression/ExpressionSourceCode.h"
32a6686e36cd56843e594139324884585fb47b918bSean Callanan#include "lldb/Expression/IRExecutionUnit.h"
330f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan#include "lldb/Expression/IRInterpreter.h"
343b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Expression/Materializer.h"
3565dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Host/Host.h"
3649ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Symbol/Block.h"
37c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham#include "lldb/Symbol/ClangASTContext.h"
38c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham#include "lldb/Symbol/Function.h"
39c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham#include "lldb/Symbol/Type.h"
40c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan#include "lldb/Symbol/VariableList.h"
4265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/ExecutionContext.h"
430baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton#include "lldb/Target/Process.h"
443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan#include "lldb/Target/StackFrame.h"
4565dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/Target.h"
46360f53f3c216ee4fb433da0a367168785328a856Jim Ingham#include "lldb/Target/ThreadPlan.h"
47360f53f3c216ee4fb433da0a367168785328a856Jim Ingham#include "lldb/Target/ThreadPlanCallUserExpression.h"
4865dafa8344c8c018e346dd331a7782081a896239Sean Callanan
49c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan#include "clang/AST/DeclCXX.h"
50c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan#include "clang/AST/DeclObjC.h"
51c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan
5265dafa8344c8c018e346dd331a7782081a896239Sean Callananusing namespace lldb_private;
5365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
5477e9394f0af653ac0842066a9c7766a28d6c6b94Sean CallananClangUserExpression::ClangUserExpression (const char *expr,
555b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan                                          const char *expr_prefix,
56daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan                                          lldb::LanguageType language,
57daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan                                          ResultType desired_type) :
58d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    ClangExpression (),
59cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan    m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
60cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan    m_stack_frame_top (LLDB_INVALID_ADDRESS),
61d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    m_expr_text (expr),
62d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    m_expr_prefix (expr_prefix ? expr_prefix : ""),
635b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    m_language (language),
64d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    m_transformed_text (),
65daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan    m_desired_type (desired_type),
6677dd4a4181f616f6d3c1205075872bc6325e0adfSean Callanan    m_enforce_valid_object (true),
67d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    m_cplusplus (false),
68d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    m_objectivec (false),
69d787da46c01f3b212a42891b3b54e608358a7efeBill Wendling    m_static_method(false),
70d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton    m_needs_object_ptr (false),
71696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    m_const_object (false),
7297c8957257a3e0b3ce6f46f8e5a28c965e30f357Daniel Dunbar    m_target (NULL),
73cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan    m_can_interpret (false),
74cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan    m_materialized_address (LLDB_INVALID_ADDRESS)
7565dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
765b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    switch (m_language)
775b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    {
785b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    case lldb::eLanguageTypeC_plus_plus:
795b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        m_allow_cxx = true;
805b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        break;
815b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    case lldb::eLanguageTypeObjC:
825b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        m_allow_objc = true;
835b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        break;
845b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    case lldb::eLanguageTypeObjC_plus_plus:
855b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    default:
865b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        m_allow_cxx = true;
875b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        m_allow_objc = true;
885b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        break;
895b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    }
9065dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
9165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
92830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUserExpression::~ClangUserExpression ()
93830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan{
94830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan}
95830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan
9665dafa8344c8c018e346dd331a7782081a896239Sean Callananclang::ASTConsumer *
9765dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
98036fa9000fdc68f45ee22ada3d7ce00422b8afccSean Callanan{
992431244f929e269c6ecd51aa3eb606b6a2474f19Sean Callanan    ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext();
1002431244f929e269c6ecd51aa3eb606b6a2474f19Sean Callanan
1012431244f929e269c6ecd51aa3eb606b6a2474f19Sean Callanan    if (!clang_ast_context)
1022431244f929e269c6ecd51aa3eb606b6a2474f19Sean Callanan        return NULL;
1032431244f929e269c6ecd51aa3eb606b6a2474f19Sean Callanan
104060d53f1559d08a6923e45bdeffe8f22ca663049Sean Callanan    if (!m_result_synthesizer.get())
105060d53f1559d08a6923e45bdeffe8f22ca663049Sean Callanan        m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
106e1301a62783cf0d5457350b90830917841cbf6fcSean Callanan                                                            *m_target));
107060d53f1559d08a6923e45bdeffe8f22ca663049Sean Callanan
108060d53f1559d08a6923e45bdeffe8f22ca663049Sean Callanan    return m_result_synthesizer.get();
10965dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
11065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
1113c9c5eb466869ede185e879d14a47335fb43194dSean Callananvoid
112fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean CallananClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
1133c9c5eb466869ede185e879d14a47335fb43194dSean Callanan{
114952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1155474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan
1165474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    if (log)
1175474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan        log->Printf("ClangUserExpression::ScanContext()");
1185474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan
119567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    m_target = exe_ctx.GetTargetPtr();
120144188bc458a35997d2f2e52206ab69747439073Greg Clayton
1215b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan    if (!(m_allow_cxx || m_allow_objc))
1225474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    {
1235474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan        if (log)
1245474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan            log->Printf("  [CUE::SC] Settings inhibit C++ and Objective-C");
1255b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        return;
1265474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    }
1275b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan
128567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    StackFrame *frame = exe_ctx.GetFramePtr();
129567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    if (frame == NULL)
1305474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    {
1315474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan        if (log)
1325474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan            log->Printf("  [CUE::SC] Null stack frame");
133c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan        return;
1345474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    }
1353c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
136b573bd6eb07845623a3b846358e082463c88667cSean Callanan    SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
137c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan
138c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan    if (!sym_ctx.function)
1395474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    {
1405474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan        if (log)
1415474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan            log->Printf("  [CUE::SC] Null function");
1423c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return;
1435474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    }
1443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
145b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton    // Find the block that defines the function represented by "sym_ctx"
146b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton    Block *function_block = sym_ctx.GetFunctionBlock();
147e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan
148b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton    if (!function_block)
1495474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    {
1505474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan        if (log)
1515474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan            log->Printf("  [CUE::SC] Null function block");
152b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton        return;
1535474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    }
154b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton
155b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton    clang::DeclContext *decl_context = function_block->GetClangDeclContext();
156b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton
157c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan    if (!decl_context)
1585474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    {
1595474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan        if (log)
1605474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan            log->Printf("  [CUE::SC] Null decl context");
161c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan        return;
1625474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan    }
1635474125bb24890a0018398cbbc5f9b4e571f61ebSean Callanan
164c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan    if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
165c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan    {
1665b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan        if (m_allow_cxx && method_decl->isInstance())
167e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan        {
1685ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan            if (m_enforce_valid_object)
169fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan            {
170b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
1715ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
1725ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
1735ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
174b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                if (!variable_list_sp)
1755ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                {
1765ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    err.SetErrorString(thisErrorString);
1775ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    return;
1785ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                }
1795ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
180b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
1815ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
182b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                if (!this_var_sp ||
183b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                    !this_var_sp->IsInScope(frame) ||
184b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                    !this_var_sp->LocationIsValidForFrame (frame))
1855ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                {
1865ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    err.SetErrorString(thisErrorString);
1875ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    return;
1885ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                }
189fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan            }
190fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan
191c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan            m_cplusplus = true;
192de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan            m_needs_object_ptr = true;
193e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan        }
194e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    }
195c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan    else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
196fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan    {
197e6ea5fe8e76b028a0565bc01543bc15f8c120e8aSean Callanan        if (m_allow_objc)
198de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan        {
1995ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan            if (m_enforce_valid_object)
200fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan            {
201b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
2025ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
2035ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
2045ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
205b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                if (!variable_list_sp)
2065ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                {
2075ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    err.SetErrorString(selfErrorString);
2085ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    return;
2095ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                }
2105ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
211b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
2125ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan
213b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                if (!self_variable_sp ||
214b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                    !self_variable_sp->IsInScope(frame) ||
215b3a1a2bba41281ba56a99fe64887a8a04760784cGreg Clayton                    !self_variable_sp->LocationIsValidForFrame (frame))
2165ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                {
2175ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    err.SetErrorString(selfErrorString);
2185ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    return;
2195ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                }
220fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan            }
221fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan
222c617a4cb4a451be9d7e97d7af6e165d282b5390fSean Callanan            m_objectivec = true;
223de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan            m_needs_object_ptr = true;
224e6ea5fe8e76b028a0565bc01543bc15f8c120e8aSean Callanan
225e6ea5fe8e76b028a0565bc01543bc15f8c120e8aSean Callanan            if (!method_decl->isInstanceMethod())
226e6ea5fe8e76b028a0565bc01543bc15f8c120e8aSean Callanan                m_static_method = true;
227de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan        }
228e8e5557af333aba8183ce6e9fed9996221eb1547Sean Callanan    }
229c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham    else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
230c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham    {
231c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham        // We might also have a function that said in the debug information that it captured an
232c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham        // object pointer.  The best way to deal with getting to the ivars at present it by pretending
233c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham        // that this is a method of a class in whatever runtime the debug info says the object pointer
234c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham        // belongs to.  Do that here.
235c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham
236017c16aa483e6edabdbbee1bdcd1ce3f8e8a12d1Greg Clayton        ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
237c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham        if (metadata && metadata->HasObjectPtr())
238c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham        {
239c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham            lldb::LanguageType language = metadata->GetObjectPtrLanguage();
240c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham            if (language == lldb::eLanguageTypeC_plus_plus)
241c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham            {
242288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                if (m_enforce_valid_object)
243288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                {
244288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
245288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
246288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
247288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
248288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    if (!variable_list_sp)
249288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
250288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        err.SetErrorString(thisErrorString);
251288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
252288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
253288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
254288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
255288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
256288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    if (!this_var_sp ||
257288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        !this_var_sp->IsInScope(frame) ||
258288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        !this_var_sp->LocationIsValidForFrame (frame))
259288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
260288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        err.SetErrorString(thisErrorString);
261288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
262288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
263288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                }
264288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
265c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham                m_cplusplus = true;
266c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham                m_needs_object_ptr = true;
267c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham            }
268c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham            else if (language == lldb::eLanguageTypeObjC)
269c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham            {
270288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                if (m_enforce_valid_object)
271288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                {
272288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
273288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
274288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
275288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
276288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    if (!variable_list_sp)
277288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
278288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        err.SetErrorString(selfErrorString);
279288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
280288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
281288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
282288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
283288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
284288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    if (!self_variable_sp ||
285288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        !self_variable_sp->IsInScope(frame) ||
286288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        !self_variable_sp->LocationIsValidForFrame (frame))
287288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
288288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        err.SetErrorString(selfErrorString);
289288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
290288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
291288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
292288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    Type *self_type = self_variable_sp->GetType();
293288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
294288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    if (!self_type)
295288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
296288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        err.SetErrorString(selfErrorString);
297288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
298288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
299288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
30052f792329be5db8e38961350589e97e8f2823acdGreg Clayton                    ClangASTType self_clang_type = self_type->GetClangForwardType();
301288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan
30252f792329be5db8e38961350589e97e8f2823acdGreg Clayton                    if (!self_clang_type)
303288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
304288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        err.SetErrorString(selfErrorString);
305288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
306288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
30752f792329be5db8e38961350589e97e8f2823acdGreg Clayton
30852f792329be5db8e38961350589e97e8f2823acdGreg Clayton                    if (self_clang_type.IsObjCClassType())
309288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
310288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
311288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
31252f792329be5db8e38961350589e97e8f2823acdGreg Clayton                    else if (self_clang_type.IsObjCObjectPointerType())
313288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
314288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        m_objectivec = true;
315288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        m_needs_object_ptr = true;
316288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
317288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    else
318288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    {
319288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        err.SetErrorString(selfErrorString);
320288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                        return;
321288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    }
322288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                }
323288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                else
324288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                {
325288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    m_objectivec = true;
326288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                    m_needs_object_ptr = true;
327288ddfedeb1946d68e467f342f600e9325060e51Sean Callanan                }
328c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham            }
329c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham        }
330c7f17c030eb0632a0bb1cd0ebf29900d6d97a902Jim Ingham    }
3313c9c5eb466869ede185e879d14a47335fb43194dSean Callanan}
3323c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
33328195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callananvoid
33428195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean CallananClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
33528195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan{
33628195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    m_process_wp = exe_ctx.GetProcessSP();
33728195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
33828195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
33928195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
34028195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    if (frame_sp)
34128195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan        m_address = frame_sp->GetFrameCodeAddress();
34228195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan}
34328195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
34428195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callananbool
34528195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean CallananClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
34628195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan                                          lldb::TargetSP &target_sp,
34728195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan                                          lldb::ProcessSP &process_sp,
34828195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan                                          lldb::StackFrameSP &frame_sp)
34928195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan{
35028195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    lldb::ProcessSP expected_process_sp = m_process_wp.lock();
35128195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    process_sp = exe_ctx.GetProcessSP();
35228195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
35328195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    if (process_sp != expected_process_sp)
35428195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan        return false;
35528195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
35628195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    process_sp = exe_ctx.GetProcessSP();
35728195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    target_sp = exe_ctx.GetTargetSP();
35828195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    frame_sp = exe_ctx.GetFrameSP();
35928195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
36028195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    if (m_address.IsValid())
36128195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    {
36228195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan        if (!frame_sp)
36328195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan            return false;
36428195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan        else
36528195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan            return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
36628195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    }
36728195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
36828195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    return true;
36928195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan}
37028195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
37128195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callananbool
37228195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean CallananClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
37328195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan{
37428195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    lldb::TargetSP target_sp;
37528195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    lldb::ProcessSP process_sp;
37628195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    lldb::StackFrameSP frame_sp;
37728195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
37828195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan    return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
37928195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan}
38028195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan
381550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// This is a really nasty hack, meant to fix Objective-C expressions of the form
382550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// (int)[myArray count].  Right now, because the type information for count is
383550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// not available, [myArray count] returns id, which can't be directly cast to
384550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// int without causing a clang error.
385550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananstatic void
386550f276a34e4db1aa513e18f3438454ce7429a3eSean CallananApplyObjcCastHack(std::string &expr)
387550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan{
388550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_FROM "(int)["
389550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_TO   "(int)(long long)["
390550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
391550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    size_t from_offset;
392550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
393550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
394550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan        expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
395550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
396550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_TO
397550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_FROM
398550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan}
399550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
4003089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// Another hack, meant to allow use of unichar despite it not being available in
4013089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// the type information.  Although we could special-case it in type lookup,
4023089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// hopefully we'll figure out a way to #include the same environment as is
4033089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// present in the original source file rather than try to hack specific type
4043089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// definitions in as needed.
4053089237161d7593a176e1f72dec1b5e4596aab96Sean Callananstatic void
4063089237161d7593a176e1f72dec1b5e4596aab96Sean CallananApplyUnicharHack(std::string &expr)
4073089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan{
4083089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_FROM "unichar"
4093089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_TO   "unsigned short"
4103089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
4113089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan    size_t from_offset;
4123089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
4133089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan    while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
4143089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan        expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
4153089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
4163089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_TO
4173089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_FROM
4183089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan}
4193089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan
420550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananbool
421a91dd997b1e809c67901b7ac481942cacae19150Sean CallananClangUserExpression::Parse (Stream &error_stream,
422a91dd997b1e809c67901b7ac481942cacae19150Sean Callanan                            ExecutionContext &exe_ctx,
42347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                            lldb_private::ExecutionPolicy execution_policy,
424696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan                            bool keep_result_in_memory)
42565dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
426952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
42765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
428fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan    Error err;
429dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan
430dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan    InstallContext(exe_ctx);
431fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan
432fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan    ScanContext(exe_ctx, err);
433fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan
434fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan    if (!err.Success())
435fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan    {
436fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan        error_stream.Printf("warning: %s\n", err.AsCString());
437fa9e6dd370331db1fdef7420e43c5aaacf0b2f65Sean Callanan    }
4383c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
4393c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    StreamString m_transformed_stream;
4403c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
4413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    ////////////////////////////////////
4423c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    // Generate the expression
4433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    //
444550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan
445550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan    ApplyObjcCastHack(m_expr_text);
446f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton    //ApplyUnicharHack(m_expr_text);
4473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
448102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton    std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
449de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan
450de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan    lldb::LanguageType lang_type;
451de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan
4523c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (m_cplusplus)
453de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan        lang_type = lldb::eLanguageTypeC_plus_plus;
454de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan    else if(m_objectivec)
455de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan        lang_type = lldb::eLanguageTypeObjC;
4563c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else
457de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan        lang_type = lldb::eLanguageTypeC;
458de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan
459e6ea5fe8e76b028a0565bc01543bc15f8c120e8aSean Callanan    if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
4603c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
461de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan        error_stream.PutCString ("error: couldn't construct expression body");
462de3d27ef1d426713d7af044cfd5c34a9aeae926aSean Callanan        return false;
4633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
4643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
4653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (log)
4663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
4673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
46865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    ////////////////////////////////////
46965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Set up the target and compiler
47065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
47165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
472567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    Target *target = exe_ctx.GetTargetPtr();
47365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
47465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (!target)
47565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
47665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.PutCString ("error: invalid target\n");
47765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
47865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
47965dafa8344c8c018e346dd331a7782081a896239Sean Callanan
48065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //////////////////////////
48165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    // Parse the expression
48265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
483daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan
4843b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan    m_materializer_ap.reset(new Materializer());
4853b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan
48673b520f4f60dca58e58e446c9504d45384ee677bSean Callanan    m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
487aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
48852f792329be5db8e38961350589e97e8f2823acdGreg Clayton    class OnExit
48952f792329be5db8e38961350589e97e8f2823acdGreg Clayton    {
49052f792329be5db8e38961350589e97e8f2823acdGreg Clayton    public:
49152f792329be5db8e38961350589e97e8f2823acdGreg Clayton        typedef std::function <void (void)> Callback;
49252f792329be5db8e38961350589e97e8f2823acdGreg Clayton
49352f792329be5db8e38961350589e97e8f2823acdGreg Clayton        OnExit (Callback const &callback) :
49452f792329be5db8e38961350589e97e8f2823acdGreg Clayton            m_callback(callback)
49552f792329be5db8e38961350589e97e8f2823acdGreg Clayton        {
49652f792329be5db8e38961350589e97e8f2823acdGreg Clayton        }
49752f792329be5db8e38961350589e97e8f2823acdGreg Clayton
49852f792329be5db8e38961350589e97e8f2823acdGreg Clayton        ~OnExit ()
49952f792329be5db8e38961350589e97e8f2823acdGreg Clayton        {
50052f792329be5db8e38961350589e97e8f2823acdGreg Clayton            m_callback();
50152f792329be5db8e38961350589e97e8f2823acdGreg Clayton        }
50252f792329be5db8e38961350589e97e8f2823acdGreg Clayton    private:
50352f792329be5db8e38961350589e97e8f2823acdGreg Clayton        Callback m_callback;
50452f792329be5db8e38961350589e97e8f2823acdGreg Clayton    };
50552f792329be5db8e38961350589e97e8f2823acdGreg Clayton
50652f792329be5db8e38961350589e97e8f2823acdGreg Clayton    OnExit on_exit([this]() { m_expr_decl_map.reset(); });
50752f792329be5db8e38961350589e97e8f2823acdGreg Clayton
5083b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan    if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
509166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan    {
510166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan        error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
511166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan        return false;
512166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan    }
51365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
514567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    Process *process = exe_ctx.GetProcessPtr();
515e7ba112632f671dc76502262e46c97cb2f7dc4e1Sean Callanan    ExecutionContextScope *exe_scope = process;
516e7ba112632f671dc76502262e46c97cb2f7dc4e1Sean Callanan
517e7ba112632f671dc76502262e46c97cb2f7dc4e1Sean Callanan    if (!exe_scope)
518e7ba112632f671dc76502262e46c97cb2f7dc4e1Sean Callanan        exe_scope = exe_ctx.GetTargetPtr();
519e7ba112632f671dc76502262e46c97cb2f7dc4e1Sean Callanan
520e7ba112632f671dc76502262e46c97cb2f7dc4e1Sean Callanan    ClangExpressionParser parser(exe_scope, *this);
52165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
52265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    unsigned num_errors = parser.Parse (error_stream);
52365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
52465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (num_errors)
52565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
52665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
527aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
528aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan        m_expr_decl_map->DidParse();
529aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan
53065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
53165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
53265dafa8344c8c018e346dd331a7782081a896239Sean Callanan
53347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    //////////////////////////////////////////////////////////////////////////////////////////
53447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    // Prepare the output of the parser for execution, evaluating it statically if possible
53565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    //
5361cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan
5371cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
53847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                                  m_jit_end_addr,
5399e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan                                                  m_execution_unit_ap,
54047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                                  exe_ctx,
5410f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                  m_can_interpret,
54247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                                  execution_policy);
5436d284ef56532873d669f8edd4b40031407f0ffe4Sean Callanan
54465dafa8344c8c018e346dd331a7782081a896239Sean Callanan    if (jit_error.Success())
54565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
5461cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan        if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
5477adfcfdb46018d16393995276699a04505727808Enrico Granata            m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
54865dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return true;
54965dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
55065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
55165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
5523058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton        const char *error_cstr = jit_error.AsCString();
5533058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton        if (error_cstr && error_cstr[0])
5543058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton            error_stream.Printf ("error: %s\n", error_cstr);
5553058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton        else
5567e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda            error_stream.Printf ("error: expression can't be interpreted or run\n");
55765dafa8344c8c018e346dd331a7782081a896239Sean Callanan        return false;
55865dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
55965dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
56065dafa8344c8c018e346dd331a7782081a896239Sean Callanan
5610f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callananstatic lldb::addr_t
5620f0551e67d8ea8d63ace5456f7d42d951827b017Sean CallananGetObjectPointer (lldb::StackFrameSP frame_sp,
5630f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                  ConstString &object_name,
5640f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                  Error &err)
5650f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan{
5660f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    err.Clear();
5670f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
5680f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (!frame_sp)
5690f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    {
5700f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
5710f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        return LLDB_INVALID_ADDRESS;
5720f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    }
5730f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
5740f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    lldb::VariableSP var_sp;
5750f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    lldb::ValueObjectSP valobj_sp;
5760f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
5770f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
5780f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            lldb::eNoDynamicValues,
5790f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            StackFrame::eExpressionPathOptionCheckPtrVsMember ||
5800f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
5810f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
5820f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
5830f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
5840f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            var_sp,
5850f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                            err);
5860f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
5870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (!err.Success())
5880f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        return LLDB_INVALID_ADDRESS;
5890f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
5900f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
5910f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
5920f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (ret == LLDB_INVALID_ADDRESS)
5930f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    {
5940f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
5950f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        return LLDB_INVALID_ADDRESS;
5960f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    }
5970f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
5980f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    return ret;
5990f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan}
6000f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
60165dafa8344c8c018e346dd331a7782081a896239Sean Callananbool
602d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
603ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan                                                    ExecutionContext &exe_ctx,
604ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan                                                    lldb::addr_t &struct_address,
605047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                                                    lldb::addr_t &object_ptr,
606047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                                                    lldb::addr_t &cmd_ptr)
60765dafa8344c8c018e346dd331a7782081a896239Sean Callanan{
608dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan    lldb::TargetSP target;
609dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan    lldb::ProcessSP process;
610dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan    lldb::StackFrameSP frame;
611dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan
612dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan    if (!LockAndCheckContext(exe_ctx,
613dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan                             target,
614dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan                             process,
615dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan                             frame))
616dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan    {
61728195f9e55173cd06c3c5f9e69cefeb1d03cc129Sean Callanan        error_stream.Printf("The context has changed before we could JIT the expression!\n");
618dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan        return false;
619dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan    }
620dd1dcfdbad297562951169ad621f895daf32b382Sean Callanan
6210f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
6220f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    {
6233aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (m_needs_object_ptr)
6243c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        {
6253aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            ConstString object_name;
6263aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
6273aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            if (m_cplusplus)
6283aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
6293aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                object_name.SetCString("this");
6303aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
6313aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            else if (m_objectivec)
6323aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
6333aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                object_name.SetCString("self");
6343aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
6353aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            else
6363aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
6373aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                error_stream.Printf("Need object pointer but don't know the language\n");
6383aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                return false;
6393aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
6403aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
6410f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            Error object_ptr_error;
6420f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
6430f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
6440f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
6450f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (!object_ptr_error.Success())
6463aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            {
6470f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
6485ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                object_ptr = 0;
6493aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            }
650047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan
651047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan            if (m_objectivec)
652047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan            {
653047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                ConstString cmd_name("_cmd");
654047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan
6550f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
6560f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
6570f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                if (!object_ptr_error.Success())
658047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                {
6590f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
6605ed59a78c1970fab44b393cd9d20f0e6fc2e326aSean Callanan                    cmd_ptr = 0;
661047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan                }
662047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan            }
6633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        }
6640f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
665cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        if (m_materialized_address == LLDB_INVALID_ADDRESS)
66665dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
667cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            Error alloc_error;
668cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
669cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
670cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
671cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
672cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                                 m_materializer_ap->GetStructAlignment(),
673cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                                 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
674cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                                 policy,
675cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                                 alloc_error);
676cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
677cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            if (!alloc_error.Success())
678cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            {
679cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
680cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                return false;
681cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            }
68265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
68365dafa8344c8c018e346dd331a7782081a896239Sean Callanan
684cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        struct_address = m_materialized_address;
6850f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
686cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
687cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        {
688cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            Error alloc_error;
689cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
690cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            const size_t stack_frame_size = 512 * 1024;
691cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
692cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
693cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                               8,
694cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                               lldb::ePermissionsReadable | lldb::ePermissionsWritable,
695cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                               IRMemoryMap::eAllocationPolicyHostOnly,
696cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                                               alloc_error);
697cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
698cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
699cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
700cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            if (!alloc_error.Success())
701cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            {
702cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
703cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                return false;
704cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            }
705cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        }
706cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
7070f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        Error materialize_error;
7080f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
7090f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
7100f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
7110f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        if (!materialize_error.Success())
71265dafa8344c8c018e346dd331a7782081a896239Sean Callanan        {
7130f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
7140f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            return false;
71565dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
716d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
717d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return true;
718d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
719d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
720d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamThreadPlan *
721d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
7226a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan                                                          ExecutionContext &exe_ctx)
723d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
724d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    lldb::addr_t struct_address;
725d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
7262bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen    lldb::addr_t object_ptr = 0;
7272bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen    lldb::addr_t cmd_ptr = 0;
728d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
729047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan    PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
730d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
731360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
732360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    // ClangUserExpression resources before the thread plan finishes execution in the target.  But because we are
7333aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    // forcing unwind_on_error to be true here, in practical terms that can't happen.
7343aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
735b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    const bool stop_others = true;
736b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    const bool unwind_on_error = true;
737b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    const bool ignore_breakpoints = false;
738d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
739d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton                                                       m_jit_start_addr,
740a65b52703554a2c2f31357cf5a367ae35db86905Sean Callanan                                                       struct_address,
741a65b52703554a2c2f31357cf5a367ae35db86905Sean Callanan                                                       error_stream,
742b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                       stop_others,
743b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                       unwind_on_error,
744b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                       ignore_breakpoints,
7453aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                       (m_needs_object_ptr ? &object_ptr : NULL),
7463aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                                       (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
747d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
748d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
749d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Inghambool
750d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::FinalizeJITExecution (Stream &error_stream,
751d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                                           ExecutionContext &exe_ctx,
7520ddf806dd9e71637846bf0ad46e1b2df7d02cbceSean Callanan                                           lldb::ClangExpressionVariableSP &result,
753cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                           lldb::addr_t function_stack_bottom,
754cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                           lldb::addr_t function_stack_top)
755d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
756952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
7573371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
7583371102ecdff827087df3c27549e57760a6bbc97Sean Callanan    if (log)
75994d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan        log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
760cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
7610f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (!m_dematerializer_sp)
7620f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    {
7634a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan        error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
7640f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        return false;
7653371102ecdff827087df3c27549e57760a6bbc97Sean Callanan    }
7660ddf806dd9e71637846bf0ad46e1b2df7d02cbceSean Callanan
7670f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    Error dematerialize_error;
7680ddf806dd9e71637846bf0ad46e1b2df7d02cbceSean Callanan
769cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan    m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
7700f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
7710f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (!dematerialize_error.Success())
772d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
7734a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan        error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
774d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham        return false;
775d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    }
7760f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
777c61349681fa2923bd30ad16afce450a0da6108cfJohnny Chen    if (result)
778c61349681fa2923bd30ad16afce450a0da6108cfJohnny Chen        result->TransferAddress();
779c61349681fa2923bd30ad16afce450a0da6108cfJohnny Chen
7800f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    m_dematerializer_sp.reset();
7810f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
782d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    return true;
783d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham}
784d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
785b344843f75ef893762c93fd0a22d2d45712ce74dGreg ClaytonExecutionResults
786d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::Execute (Stream &error_stream,
787d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham                              ExecutionContext &exe_ctx,
788b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                              bool unwind_on_error,
789b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                              bool ignore_breakpoints,
790360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                              ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
7916cca9695637b27bd583eaae310d5c09dede7cc49Enrico Granata                              lldb::ClangExpressionVariableSP &result,
79247beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              bool run_others,
79347beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              uint32_t timeout_usec)
794d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{
7957812e013be05cf8593d7a1d3a51bbb138c52ae90Jim Ingham    // The expression log is quite verbose, and if you're just tracking the execution of the
7967812e013be05cf8593d7a1d3a51bbb138c52ae90Jim Ingham    // expression, it's quite convenient to have these logs come out with the STEP log as well.
797952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
7983371102ecdff827087df3c27549e57760a6bbc97Sean Callanan
7990f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
800d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham    {
8016f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
802d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
8032bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen        lldb::addr_t object_ptr = 0;
8042bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen        lldb::addr_t cmd_ptr = 0;
805d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham
806544f2b622e58bcf43406fd7d0102dedadd49858fJohnny Chen        if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
807544f2b622e58bcf43406fd7d0102dedadd49858fJohnny Chen        {
8088165d43ee84ab51de9218ba38bea257d082cec1fJohnny Chen            error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
809b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            return eExecutionSetupError;
8108165d43ee84ab51de9218ba38bea257d082cec1fJohnny Chen        }
81165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
812cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
813cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
8140ddf806dd9e71637846bf0ad46e1b2df7d02cbceSean Callanan
8150f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        if (m_can_interpret)
8160f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        {
8170f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            llvm::Module *module = m_execution_unit_ap->GetModule();
8180f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            llvm::Function *function = m_execution_unit_ap->GetFunction();
8190f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8200f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (!module || !function)
8210f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            {
8220f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                error_stream.Printf("Supposed to interpret, but nothing is there");
8230f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                return eExecutionSetupError;
8240f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            }
8256798bd472f98f860b911a0de0586a73f3fa6ddf7Jim Ingham
8260f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            Error interpreter_error;
8270296fe73a7cb1482226b1303a795ede00e12d677Jim Ingham
8280f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            llvm::SmallVector <lldb::addr_t, 3> args;
8290296fe73a7cb1482226b1303a795ede00e12d677Jim Ingham
8300f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (m_needs_object_ptr)
8310f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            {
8320f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                args.push_back(object_ptr);
8330f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8340f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                if (m_objectivec)
8350f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    args.push_back(cmd_ptr);
8360f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            }
8370f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8380f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            args.push_back(struct_address);
8390f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
840cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            function_stack_bottom = m_stack_frame_bottom;
841cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            function_stack_top = m_stack_frame_top;
842cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
8430f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            IRInterpreter::Interpret (*module,
8440f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                      *function,
8450f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                      args,
8460f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                      *m_execution_unit_ap.get(),
847cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                      interpreter_error,
848cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                      function_stack_bottom,
849cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                                      function_stack_top);
8502370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham
8510f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (!interpreter_error.Success())
8522370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham            {
8530f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
8540f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                return eExecutionDiscarded;
8552370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham            }
856360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        }
8570f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        else
858360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        {
8590f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            const bool stop_others = true;
8600f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            const bool try_all_threads = run_others;
8610f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8620f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            Address wrapper_address (m_jit_start_addr);
8630f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
8640f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              wrapper_address,
8650f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              struct_address,
8660f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              stop_others,
8670f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              unwind_on_error,
8680f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              ignore_breakpoints,
8690f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              (m_needs_object_ptr ? &object_ptr : NULL),
8700f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
8710f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                              shared_ptr_to_me));
8720f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8730f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
8740f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                return eExecutionSetupError;
8750f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
876cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
8770f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
878cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            function_stack_bottom = function_stack_pointer - Host::GetPageSize();
879cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan            function_stack_top = function_stack_pointer;
880cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
8810f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (log)
8820f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
8830f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8840f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (exe_ctx.GetProcessPtr())
8850f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
8860f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
8880f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                                       call_plan_sp,
8890f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                                       stop_others,
8900f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                                       try_all_threads,
8910f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                                       unwind_on_error,
8920f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                                       ignore_breakpoints,
8930f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                                       timeout_usec,
8940f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                                                                       error_stream);
8950f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8960f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (exe_ctx.GetProcessPtr())
8970f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
8980f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
8990f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (log)
9000f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
9010f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
9020f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
9030f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            {
9040f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                const char *error_desc = NULL;
9050f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
9060f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                if (call_plan_sp)
9070f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                {
9080f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
9090f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    if (real_stop_info_sp)
9100f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                        error_desc = real_stop_info_sp->GetDescription();
9110f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                }
9120f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                if (error_desc)
9130f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
9140f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                else
9150f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    error_stream.Printf ("Execution was interrupted.");
9160f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
9170f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                if ((execution_result == eExecutionInterrupted && unwind_on_error)
9180f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
9190f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
9200f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                else
9210f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                    error_stream.Printf ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
9220f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
9230f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                return execution_result;
9240f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            }
9250f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            else if (execution_result != eExecutionCompleted)
9260f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            {
9270f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
9280f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                return execution_result;
9290f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            }
93065dafa8344c8c018e346dd331a7782081a896239Sean Callanan        }
93165dafa8344c8c018e346dd331a7782081a896239Sean Callanan
932cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        if  (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
933cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        {
934b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            return eExecutionCompleted;
935cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        }
936360f53f3c216ee4fb433da0a367168785328a856Jim Ingham        else
937544f2b622e58bcf43406fd7d0102dedadd49858fJohnny Chen        {
938b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            return eExecutionSetupError;
939544f2b622e58bcf43406fd7d0102dedadd49858fJohnny Chen        }
94065dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
94165dafa8344c8c018e346dd331a7782081a896239Sean Callanan    else
94265dafa8344c8c018e346dd331a7782081a896239Sean Callanan    {
94347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
944b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton        return eExecutionSetupError;
94565dafa8344c8c018e346dd331a7782081a896239Sean Callanan    }
94665dafa8344c8c018e346dd331a7782081a896239Sean Callanan}
94765dafa8344c8c018e346dd331a7782081a896239Sean Callanan
948b344843f75ef893762c93fd0a22d2d45712ce74dGreg ClaytonExecutionResults
94947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
95047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                               lldb_private::ExecutionPolicy execution_policy,
9515b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan                               lldb::LanguageType language,
952daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan                               ResultType desired_type,
953b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                               bool unwind_on_error,
954b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                               bool ignore_breakpoints,
95577e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan                               const char *expr_cstr,
956360f53f3c216ee4fb433da0a367168785328a856Jim Ingham                               const char *expr_prefix,
9576cca9695637b27bd583eaae310d5c09dede7cc49Enrico Granata                               lldb::ValueObjectSP &result_valobj_sp,
95847beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                               bool run_others,
95947beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                               uint32_t timeout_usec)
960377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton{
961ec07c0dde27ae022b87423ee106f10437864c219Jim Ingham    Error error;
96247beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham    return EvaluateWithError (exe_ctx,
96347beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              execution_policy,
96447beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              language,
96547beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              desired_type,
966b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                              unwind_on_error,
967b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                              ignore_breakpoints,
96847beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              expr_cstr,
96947beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              expr_prefix,
97047beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              result_valobj_sp,
97147beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              error,
97247beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              run_others,
97347beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                              timeout_usec);
974ec07c0dde27ae022b87423ee106f10437864c219Jim Ingham}
975ec07c0dde27ae022b87423ee106f10437864c219Jim Ingham
976ec07c0dde27ae022b87423ee106f10437864c219Jim InghamExecutionResults
97747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
97847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                        lldb_private::ExecutionPolicy execution_policy,
9795b658cc411e8810073f7f633f3c5d6f177cb3dcdSean Callanan                                        lldb::LanguageType language,
980daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan                                        ResultType desired_type,
981b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                        bool unwind_on_error,
982b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                        bool ignore_breakpoints,
98347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                        const char *expr_cstr,
98447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                        const char *expr_prefix,
98547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                                        lldb::ValueObjectSP &result_valobj_sp,
9866cca9695637b27bd583eaae310d5c09dede7cc49Enrico Granata                                        Error &error,
98747beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                                        bool run_others,
98847beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                                        uint32_t timeout_usec)
989ec07c0dde27ae022b87423ee106f10437864c219Jim Ingham{
990952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
99194d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
992b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    ExecutionResults execution_results = eExecutionSetupError;
9930baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
994567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    Process *process = exe_ctx.GetProcessPtr();
995567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton
996567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    if (process == NULL || process->GetState() != lldb::eStateStopped)
997360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    {
99847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        if (execution_policy == eExecutionPolicyAlways)
99947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        {
100047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            if (log)
100147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
1002360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
100347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            error.SetErrorString ("expression needed to run but couldn't");
100447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
100547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            return execution_results;
100647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        }
1007360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    }
1008f7649bbe2b2fc103e26a7577b49089a39d9a75d7Sean Callanan
1009567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton    if (process == NULL || !process->CanJIT())
1010f7649bbe2b2fc103e26a7577b49089a39d9a75d7Sean Callanan        execution_policy = eExecutionPolicyNever;
10110baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton
1012daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan    ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
1013360f53f3c216ee4fb433da0a367168785328a856Jim Ingham
1014377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    StreamString error_stream;
1015696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
101694d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan    if (log)
101794d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan        log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
101894d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan
101947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    const bool keep_expression_in_memory = true;
102047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
1021daa6efe771f5f068e29328a774fa5bf2358ce14aSean Callanan    if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
1022377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
1023377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        if (error_stream.GetString().empty())
1024377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString ("expression failed to parse, unknown error");
1025377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        else
1026377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            error.SetErrorString (error_stream.GetString().c_str());
1027377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
1028377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    else
1029377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    {
1030427f290ff96f3ab9f2cf3a1af7001d2c560424c7Greg Clayton        lldb::ClangExpressionVariableSP expr_result;
1031377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton
10320f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        if (execution_policy == eExecutionPolicyNever &&
10330f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            !user_expression_sp->CanInterpret())
103447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        {
103547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            if (log)
103647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
103747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
103847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            if (error_stream.GetString().empty())
103947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                error.SetErrorString ("expression needed to run but couldn't");
104047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        }
104105a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan        else
104205a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan        {
104305a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan            error_stream.GetString().clear();
104405a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan
104505a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan            if (log)
104605a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
104705a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan
104805a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan            execution_results = user_expression_sp->Execute (error_stream,
104905a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                                                             exe_ctx,
1050b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                             unwind_on_error,
1051b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                             ignore_breakpoints,
105205a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                                                             user_expression_sp,
10536cca9695637b27bd583eaae310d5c09dede7cc49Enrico Granata                                                             expr_result,
105447beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                                                             run_others,
105547beabb1386be44e3f90dbc30a0b22c23b93a4dcJim Ingham                                                             timeout_usec);
105605a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan
1057b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton            if (execution_results != eExecutionCompleted)
1058377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
105994d255f74c125889e5d0f607f4bfe5334a2999eeSean Callanan                if (log)
106005a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                    log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
106105a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan
106205a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                if (error_stream.GetString().empty())
106305a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                    error.SetErrorString ("expression failed to execute, unknown error");
106405a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                else
106505a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                    error.SetErrorString (error_stream.GetString().c_str());
1066377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
106705a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan            else
1068377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            {
106905a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                if (expr_result)
107005a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                {
107105a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                    result_valobj_sp = expr_result->GetValueObject();
107205a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan
107305a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                    if (log)
1074fa3a16a2ea380ef38388ebe323817bd1b32c20cdJim Ingham                        log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
107505a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                }
107605a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                else
107705a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                {
107805a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                    if (log)
107905a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                        log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
108005a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan
10812431244f929e269c6ecd51aa3eb606b6a2474f19Sean Callanan                    error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
108205a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan                }
1083377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton            }
1084377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton        }
1085377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton    }
108644820ec9b49bc08c0f4529091019b5bc95ec237aSean Callanan
1087d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton    if (result_valobj_sp.get() == NULL)
108847da810225d8674eb9158bcf5f1f5b847cbaeedfJim Ingham        result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
1089d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton
1090360f53f3c216ee4fb433da0a367168785328a856Jim Ingham    return execution_results;
1091b4c0f02b4ea9a160cf4af3dd0326579594d4b488Johnny Chen}
1092