ClangUserExpression.cpp revision ea9d4267a629a1c732eb0400fa0288cee31ad49d
165dafa8344c8c018e346dd331a7782081a896239Sean Callanan//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===// 265dafa8344c8c018e346dd331a7782081a896239Sean Callanan// 365dafa8344c8c018e346dd331a7782081a896239Sean Callanan// The LLVM Compiler Infrastructure 465dafa8344c8c018e346dd331a7782081a896239Sean Callanan// 565dafa8344c8c018e346dd331a7782081a896239Sean Callanan// This file is distributed under the University of Illinois Open Source 665dafa8344c8c018e346dd331a7782081a896239Sean Callanan// License. See LICENSE.TXT for details. 765dafa8344c8c018e346dd331a7782081a896239Sean Callanan// 865dafa8344c8c018e346dd331a7782081a896239Sean Callanan//===----------------------------------------------------------------------===// 965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 1065dafa8344c8c018e346dd331a7782081a896239Sean Callanan// C Includes 1165dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <stdio.h> 1265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#if HAVE_SYS_TYPES_H 1365dafa8344c8c018e346dd331a7782081a896239Sean Callanan# include <sys/types.h> 1465dafa8344c8c018e346dd331a7782081a896239Sean Callanan#endif 1565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 1665dafa8344c8c018e346dd331a7782081a896239Sean Callanan// C++ Includes 1765dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <cstdlib> 1865dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <string> 1965dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include <map> 2065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 2165dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/ConstString.h" 2265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/Log.h" 2365dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Core/StreamString.h" 24d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton#include "lldb/Core/ValueObjectConstResult.h" 2565dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h" 2665dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangExpressionParser.h" 2765dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangFunction.h" 2865dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ASTResultSynthesizer.h" 2965dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Expression/ClangUserExpression.h" 3065dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Host/Host.h" 313c9c5eb466869ede185e879d14a47335fb43194dSean Callanan#include "lldb/Symbol/VariableList.h" 3265dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/ExecutionContext.h" 330baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton#include "lldb/Target/Process.h" 343c9c5eb466869ede185e879d14a47335fb43194dSean Callanan#include "lldb/Target/StackFrame.h" 3565dafa8344c8c018e346dd331a7782081a896239Sean Callanan#include "lldb/Target/Target.h" 3665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 3765dafa8344c8c018e346dd331a7782081a896239Sean Callananusing namespace lldb_private; 3865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 3977e9394f0af653ac0842066a9c7766a28d6c6b94Sean CallananClangUserExpression::ClangUserExpression (const char *expr, 4077e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan const char *expr_prefix) : 4165dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_expr_text(expr), 42b4c0f02b4ea9a160cf4af3dd0326579594d4b488Johnny Chen m_expr_prefix(expr_prefix ? expr_prefix : ""), 433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_transformed_text(), 443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_jit_addr(LLDB_INVALID_ADDRESS), 453c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_cplusplus(false), 463c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_objectivec(false), 473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_needs_object_ptr(false) 4865dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 4965dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 5065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 51830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUserExpression::~ClangUserExpression () 52830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan{ 53830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan} 54830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 5565dafa8344c8c018e346dd331a7782081a896239Sean Callananclang::ASTConsumer * 5665dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) 5765dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 5865dafa8344c8c018e346dd331a7782081a896239Sean Callanan return new ASTResultSynthesizer(passthrough); 5965dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 6065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 613c9c5eb466869ede185e879d14a47335fb43194dSean Callananvoid 623c9c5eb466869ede185e879d14a47335fb43194dSean CallananClangUserExpression::ScanContext(ExecutionContext &exe_ctx) 633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan{ 643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (!exe_ctx.frame) 653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan return; 663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan VariableList *vars = exe_ctx.frame->GetVariableList(false); 683c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (!vars) 703c9c5eb466869ede185e879d14a47335fb43194dSean Callanan return; 713c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (vars->FindVariable(ConstString("this")).get()) 733c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_cplusplus = true; 743c9c5eb466869ede185e879d14a47335fb43194dSean Callanan else if (vars->FindVariable(ConstString("self")).get()) 753c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_objectivec = true; 763c9c5eb466869ede185e879d14a47335fb43194dSean Callanan} 773c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 78550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// This is a really nasty hack, meant to fix Objective-C expressions of the form 79550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// (int)[myArray count]. Right now, because the type information for count is 80550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// not available, [myArray count] returns id, which can't be directly cast to 81550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan// int without causing a clang error. 82550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananstatic void 83550f276a34e4db1aa513e18f3438454ce7429a3eSean CallananApplyObjcCastHack(std::string &expr) 84550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan{ 85550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_FROM "(int)[" 86550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#define OBJC_CAST_HACK_TO "(int)(long long)[" 87550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan 88550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan size_t from_offset; 89550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan 90550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos) 91550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO); 92550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan 93550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_TO 94550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan#undef OBJC_CAST_HACK_FROM 95550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan} 96550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan 973089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// Another hack, meant to allow use of unichar despite it not being available in 983089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// the type information. Although we could special-case it in type lookup, 993089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// hopefully we'll figure out a way to #include the same environment as is 1003089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// present in the original source file rather than try to hack specific type 1013089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan// definitions in as needed. 1023089237161d7593a176e1f72dec1b5e4596aab96Sean Callananstatic void 1033089237161d7593a176e1f72dec1b5e4596aab96Sean CallananApplyUnicharHack(std::string &expr) 1043089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan{ 1053089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_FROM "unichar" 1063089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#define UNICHAR_HACK_TO "unsigned short" 1073089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan 1083089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan size_t from_offset; 1093089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan 1103089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos) 1113089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO); 1123089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan 1133089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_TO 1143089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan#undef UNICHAR_HACK_FROM 1153089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan} 1163089237161d7593a176e1f72dec1b5e4596aab96Sean Callanan 117550f276a34e4db1aa513e18f3438454ce7429a3eSean Callananbool 11865dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx) 11965dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 12065dafa8344c8c018e346dd331a7782081a896239Sean Callanan Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 12165dafa8344c8c018e346dd331a7782081a896239Sean Callanan 1223c9c5eb466869ede185e879d14a47335fb43194dSean Callanan ScanContext(exe_ctx); 1233c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 1243c9c5eb466869ede185e879d14a47335fb43194dSean Callanan StreamString m_transformed_stream; 1253c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 1263c9c5eb466869ede185e879d14a47335fb43194dSean Callanan //////////////////////////////////// 1273c9c5eb466869ede185e879d14a47335fb43194dSean Callanan // Generate the expression 1283c9c5eb466869ede185e879d14a47335fb43194dSean Callanan // 129550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan 130550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan ApplyObjcCastHack(m_expr_text); 131f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton //ApplyUnicharHack(m_expr_text); 1323c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 1333c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (m_cplusplus) 1343c9c5eb466869ede185e879d14a47335fb43194dSean Callanan { 13577e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan m_transformed_stream.Printf("%s \n" 13677e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan "typedef unsigned short unichar; \n" 137f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton "void \n" 138550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan "$__lldb_class::%s(void *$__lldb_arg) \n" 1393c9c5eb466869ede185e879d14a47335fb43194dSean Callanan "{ \n" 1403c9c5eb466869ede185e879d14a47335fb43194dSean Callanan " %s; \n" 1413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan "} \n", 14277e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan m_expr_prefix.c_str(), 1433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan FunctionName(), 1443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_expr_text.c_str()); 1453c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 1463c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_needs_object_ptr = true; 1473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan } 1483c9c5eb466869ede185e879d14a47335fb43194dSean Callanan else 1493c9c5eb466869ede185e879d14a47335fb43194dSean Callanan { 15077e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan m_transformed_stream.Printf("%s \n" 15177e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan "typedef unsigned short unichar;\n" 152f3d0b0c8081691128626eb496fdfcbf8ae54c1deGreg Clayton "void \n" 153550f276a34e4db1aa513e18f3438454ce7429a3eSean Callanan "%s(void *$__lldb_arg) \n" 1543c9c5eb466869ede185e879d14a47335fb43194dSean Callanan "{ \n" 1553c9c5eb466869ede185e879d14a47335fb43194dSean Callanan " %s; \n" 1563c9c5eb466869ede185e879d14a47335fb43194dSean Callanan "} \n", 15777e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan m_expr_prefix.c_str(), 1583c9c5eb466869ede185e879d14a47335fb43194dSean Callanan FunctionName(), 1593c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_expr_text.c_str()); 1603c9c5eb466869ede185e879d14a47335fb43194dSean Callanan } 1613c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 1623c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_transformed_text = m_transformed_stream.GetData(); 1633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 1643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 1653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (log) 1663c9c5eb466869ede185e879d14a47335fb43194dSean Callanan log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); 1673c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 16865dafa8344c8c018e346dd331a7782081a896239Sean Callanan //////////////////////////////////// 16965dafa8344c8c018e346dd331a7782081a896239Sean Callanan // Set up the target and compiler 17065dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 17165dafa8344c8c018e346dd331a7782081a896239Sean Callanan 17265dafa8344c8c018e346dd331a7782081a896239Sean Callanan Target *target = exe_ctx.target; 17365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 17465dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!target) 17565dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 17665dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.PutCString ("error: invalid target\n"); 17765dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 17865dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 17965dafa8344c8c018e346dd331a7782081a896239Sean Callanan 18065dafa8344c8c018e346dd331a7782081a896239Sean Callanan ConstString target_triple; 18165dafa8344c8c018e346dd331a7782081a896239Sean Callanan 18265dafa8344c8c018e346dd331a7782081a896239Sean Callanan target->GetTargetTriple (target_triple); 18365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 18465dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!target_triple) 18565dafa8344c8c018e346dd331a7782081a896239Sean Callanan target_triple = Host::GetTargetTriple (); 18665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 18765dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!target_triple) 18865dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 18965dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.PutCString ("error: invalid target triple\n"); 19065dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 19165dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 19265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 19365dafa8344c8c018e346dd331a7782081a896239Sean Callanan ////////////////////////// 19465dafa8344c8c018e346dd331a7782081a896239Sean Callanan // Parse the expression 19565dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 19665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 19765dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx)); 19865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 19965dafa8344c8c018e346dd331a7782081a896239Sean Callanan ClangExpressionParser parser(target_triple.GetCString(), *this); 20065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 20165dafa8344c8c018e346dd331a7782081a896239Sean Callanan unsigned num_errors = parser.Parse (error_stream); 20265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 20365dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (num_errors) 20465dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 20565dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 20665dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 20765dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 20865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 20965dafa8344c8c018e346dd331a7782081a896239Sean Callanan /////////////////////////////////////////////// 21065dafa8344c8c018e346dd331a7782081a896239Sean Callanan // Convert the output of the parser to DWARF 21165dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 21265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 21365dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes.reset(new StreamString); 21465dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost); 21565dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary); 21665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 21765dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_local_variables.reset(new ClangExpressionVariableStore()); 21865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 21965dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error dwarf_error = parser.MakeDWARF (); 22065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 22165dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (dwarf_error.Success()) 22265dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 22365dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (log) 22465dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Code can be interpreted."); 22565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 22665dafa8344c8c018e346dd331a7782081a896239Sean Callanan return true; 22765dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 22865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 22965dafa8344c8c018e346dd331a7782081a896239Sean Callanan ////////////////////////////////// 23065dafa8344c8c018e346dd331a7782081a896239Sean Callanan // JIT the output of the parser 23165dafa8344c8c018e346dd331a7782081a896239Sean Callanan // 23265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 23365dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes.reset(); 23465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 235830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan lldb::addr_t jit_end; 236830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 237830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan Error jit_error = parser.MakeJIT (m_jit_addr, jit_end, exe_ctx); 23865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 23965dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (jit_error.Success()) 24065dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 24165dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (log) 24265dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 24365dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Code can be run in the target."); 24465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 24565dafa8344c8c018e346dd331a7782081a896239Sean Callanan StreamString disassembly_stream; 24665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 24765dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error err = parser.DisassembleFunction(disassembly_stream, exe_ctx); 24865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 24965dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!err.Success()) 25065dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 25165dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error")); 25265dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 25365dafa8344c8c018e346dd331a7782081a896239Sean Callanan else 25465dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 25565dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Function disassembly:\n%s", disassembly_stream.GetData()); 25665dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 25765dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 25865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 25965dafa8344c8c018e346dd331a7782081a896239Sean Callanan return true; 26065dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 26165dafa8344c8c018e346dd331a7782081a896239Sean Callanan else 26265dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 26365dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors); 26465dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 26565dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 26665dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 26765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 26865dafa8344c8c018e346dd331a7782081a896239Sean Callananbool 269d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, 270ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan ExecutionContext &exe_ctx, 271ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan lldb::addr_t &struct_address, 272ab06af92020fd4a21eaa5daac3853596b9c45398Sean Callanan lldb::addr_t &object_ptr) 27365dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 27465dafa8344c8c018e346dd331a7782081a896239Sean Callanan Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 27565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 276d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham if (m_jit_addr != LLDB_INVALID_ADDRESS) 27765dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 27865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 27965dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error materialize_error; 28065dafa8344c8c018e346dd331a7782081a896239Sean Callanan 2813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 2823c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, &exe_ctx, materialize_error))) 2833c9c5eb466869ede185e879d14a47335fb43194dSean Callanan { 2843c9c5eb466869ede185e879d14a47335fb43194dSean Callanan error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString()); 2853c9c5eb466869ede185e879d14a47335fb43194dSean Callanan return false; 2863c9c5eb466869ede185e879d14a47335fb43194dSean Callanan } 2873c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 28865dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!m_expr_decl_map->Materialize(&exe_ctx, struct_address, materialize_error)) 28965dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 2903c9c5eb466869ede185e879d14a47335fb43194dSean Callanan error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString()); 29165dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 29265dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 29365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 29465dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (log) 29565dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 29665dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Function address : 0x%llx", (uint64_t)m_jit_addr); 2973c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 2983c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (m_needs_object_ptr) 2993c9c5eb466869ede185e879d14a47335fb43194dSean Callanan log->Printf("Object pointer : 0x%llx", (uint64_t)object_ptr); 3003c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 30165dafa8344c8c018e346dd331a7782081a896239Sean Callanan log->Printf("Structure address : 0x%llx", (uint64_t)struct_address); 30265dafa8344c8c018e346dd331a7782081a896239Sean Callanan 30365dafa8344c8c018e346dd331a7782081a896239Sean Callanan StreamString args; 30465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 30565dafa8344c8c018e346dd331a7782081a896239Sean Callanan Error dump_error; 30665dafa8344c8c018e346dd331a7782081a896239Sean Callanan 307e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (struct_address) 30865dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 309e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error)) 310e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 311e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error")); 312e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 313e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan else 314e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 315e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan log->Printf("Structure contents:\n%s", args.GetData()); 316e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 31765dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 31865dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 319d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham } 320d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham return true; 321d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham} 322d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 323d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamThreadPlan * 324d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream, 325d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham ExecutionContext &exe_ctx) 326d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{ 327d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham lldb::addr_t struct_address; 328d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 329d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham lldb::addr_t object_ptr = NULL; 330d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 331d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr); 332d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 333d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham return ClangFunction::GetThreadPlanToCallFunction (exe_ctx, 334d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham m_jit_addr, 335d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham struct_address, 336d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham error_stream, 337d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham true, 338d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham true, 339d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham (m_needs_object_ptr ? &object_ptr : NULL)); 340d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham} 341d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 342d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Inghambool 343d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::FinalizeJITExecution (Stream &error_stream, 344d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham ExecutionContext &exe_ctx, 345d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham ClangExpressionVariable *&result) 346d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{ 347d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham Error expr_error; 348d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 349d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error)) 350d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham { 351d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error")); 352d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham return false; 353d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham } 354d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham return true; 355d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham} 356d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 357d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Inghambool 358d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim InghamClangUserExpression::Execute (Stream &error_stream, 359d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham ExecutionContext &exe_ctx, 360ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham bool discard_on_error, 361d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham ClangExpressionVariable *&result) 362d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham{ 363d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham if (m_dwarf_opcodes.get()) 364d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham { 365d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham // TODO execute the JITted opcodes 366d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 367d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham error_stream.Printf("We don't currently support executing DWARF expressions"); 368d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 369d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham return false; 370d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham } 371d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham else if (m_jit_addr != LLDB_INVALID_ADDRESS) 372d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham { 373d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham lldb::addr_t struct_address; 374d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 375d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham lldb::addr_t object_ptr = NULL; 376d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham 377d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr); 37865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 379ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham const bool stop_others = true; 380ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham const bool try_all_threads = true; 38165dafa8344c8c018e346dd331a7782081a896239Sean Callanan ClangFunction::ExecutionResults execution_result = 3823c9c5eb466869ede185e879d14a47335fb43194dSean Callanan ClangFunction::ExecuteFunction (exe_ctx, 3833c9c5eb466869ede185e879d14a47335fb43194dSean Callanan m_jit_addr, 3843c9c5eb466869ede185e879d14a47335fb43194dSean Callanan struct_address, 385ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham stop_others, 386ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham try_all_threads, 387ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham discard_on_error, 3880027cec5aaccc8e53e3dde3c88e1dda21c892d4eSean Callanan 10000000, 3893c9c5eb466869ede185e879d14a47335fb43194dSean Callanan error_stream, 3903c9c5eb466869ede185e879d14a47335fb43194dSean Callanan (m_needs_object_ptr ? &object_ptr : NULL)); 39165dafa8344c8c018e346dd331a7782081a896239Sean Callanan 39265dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (execution_result != ClangFunction::eExecutionCompleted) 39365dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 39465dafa8344c8c018e346dd331a7782081a896239Sean Callanan const char *result_name; 39565dafa8344c8c018e346dd331a7782081a896239Sean Callanan 39665dafa8344c8c018e346dd331a7782081a896239Sean Callanan switch (execution_result) 39765dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 39865dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionCompleted: 39965dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionCompleted"; 40065dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 40165dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionDiscarded: 40265dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionDiscarded"; 40365dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 40465dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionInterrupted: 40565dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionInterrupted"; 40665dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 40765dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionSetupError: 40865dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionSetupError"; 40965dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 41065dafa8344c8c018e346dd331a7782081a896239Sean Callanan case ClangFunction::eExecutionTimedOut: 41165dafa8344c8c018e346dd331a7782081a896239Sean Callanan result_name = "eExecutionTimedOut"; 41265dafa8344c8c018e346dd331a7782081a896239Sean Callanan break; 41365dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 41465dafa8344c8c018e346dd331a7782081a896239Sean Callanan 41565dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf ("Couldn't execute function; result was %s\n", result_name); 41665dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 41765dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 41865dafa8344c8c018e346dd331a7782081a896239Sean Callanan 419d168690e51f9020b926d3d0d57dc9a2cfb2095a8Jim Ingham return FinalizeJITExecution (error_stream, exe_ctx, result); 42065dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 42165dafa8344c8c018e346dd331a7782081a896239Sean Callanan else 42265dafa8344c8c018e346dd331a7782081a896239Sean Callanan { 42365dafa8344c8c018e346dd331a7782081a896239Sean Callanan error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function are present"); 42465dafa8344c8c018e346dd331a7782081a896239Sean Callanan return false; 42565dafa8344c8c018e346dd331a7782081a896239Sean Callanan } 42665dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 42765dafa8344c8c018e346dd331a7782081a896239Sean Callanan 42865dafa8344c8c018e346dd331a7782081a896239Sean CallananStreamString & 42965dafa8344c8c018e346dd331a7782081a896239Sean CallananClangUserExpression::DwarfOpcodeStream () 43065dafa8344c8c018e346dd331a7782081a896239Sean Callanan{ 43165dafa8344c8c018e346dd331a7782081a896239Sean Callanan if (!m_dwarf_opcodes.get()) 43265dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_dwarf_opcodes.reset(new StreamString()); 43365dafa8344c8c018e346dd331a7782081a896239Sean Callanan 43465dafa8344c8c018e346dd331a7782081a896239Sean Callanan return *m_dwarf_opcodes.get(); 43565dafa8344c8c018e346dd331a7782081a896239Sean Callanan} 436377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton 437d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Claytonlldb::ValueObjectSP 43877e9394f0af653ac0842066a9c7766a28d6c6b94Sean CallananClangUserExpression::Evaluate (ExecutionContext &exe_ctx, 439ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham bool discard_on_error, 44077e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan const char *expr_cstr, 44177e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan const char *expr_prefix) 442377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton{ 443377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton Error error; 444d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton lldb::ValueObjectSP result_valobj_sp; 4450baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton 4460baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton if (exe_ctx.process == NULL) 4470baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton return result_valobj_sp; 4480baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton 4490baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton if (!exe_ctx.process->GetDynamicCheckers()) 4500baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton { 4510baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions(); 4520baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton 4530baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton StreamString install_errors; 4540baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton 4550baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton if (!dynamic_checkers->Install(install_errors, exe_ctx)) 456f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan { 457f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan if (install_errors.GetString().empty()) 458f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan error.SetErrorString ("couldn't install checkers, unknown error"); 459f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan else 460f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan error.SetErrorString (install_errors.GetString().c_str()); 461f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan 462f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan result_valobj_sp.reset (new ValueObjectConstResult (error)); 4630baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton return result_valobj_sp; 464f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan } 465f7731456d3d6c1fddbd1a9b3504f20b21425b857Sean Callanan 4660baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton exe_ctx.process->SetDynamicCheckers(dynamic_checkers); 4670baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton } 4680baa394cd55c6dfb7a6259d215d0dea2b708067bGreg Clayton 46977e9394f0af653ac0842066a9c7766a28d6c6b94Sean Callanan ClangUserExpression user_expression (expr_cstr, expr_prefix); 470377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton 471377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton StreamString error_stream; 472377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton 473377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton if (!user_expression.Parse (error_stream, exe_ctx)) 474377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton { 475377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton if (error_stream.GetString().empty()) 476377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton error.SetErrorString ("expression failed to parse, unknown error"); 477377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton else 478377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton error.SetErrorString (error_stream.GetString().c_str()); 479377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton } 480377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton else 481377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton { 482377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton ClangExpressionVariable *expr_result = NULL; 483377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton 484377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton error_stream.GetString().clear(); 485377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton 486ea9d4267a629a1c732eb0400fa0288cee31ad49dJim Ingham if (!user_expression.Execute (error_stream, exe_ctx, discard_on_error, expr_result)) 487377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton { 488377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton if (error_stream.GetString().empty()) 489377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton error.SetErrorString ("expression failed to execute, unknown error"); 490377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton else 491377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton error.SetErrorString (error_stream.GetString().c_str()); 492377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton } 493377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton else 494377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton { 495377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton // TODO: seems weird to get a pointer to a result object back from 496377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton // a function. Do we own it? Feels like we do, but from looking at the 497377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton // code we don't. Might be best to make this a reference and state 498377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton // explicitly that we don't own it when we get a reference back from 499377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton // the execute? 500377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton if (expr_result) 501377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton { 502377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton result_valobj_sp = expr_result->GetExpressionResult (&exe_ctx); 503377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton } 504377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton else 505377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton { 50644820ec9b49bc08c0f4529091019b5bc95ec237aSean Callanan error.SetErrorString ("Expression did not return a result"); 507377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton } 508377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton } 509377e0b4b4677128244b151396f77b3421bf2b9faGreg Clayton } 51044820ec9b49bc08c0f4529091019b5bc95ec237aSean Callanan 511d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton if (result_valobj_sp.get() == NULL) 512d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton result_valobj_sp.reset (new ValueObjectConstResult (error)); 513d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton 514d171972ecc7788bdb02d3e81420a24841e09a2bfGreg Clayton return result_valobj_sp; 515b4c0f02b4ea9a160cf4af3dd0326579594d4b488Johnny Chen} 516