ClangUserExpression.cpp revision 5f35a4be95aed0e5b2cb36f7d785bcbfc67284ae
1//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// C Includes 11#include <stdio.h> 12#if HAVE_SYS_TYPES_H 13# include <sys/types.h> 14#endif 15 16// C++ Includes 17#include <cstdlib> 18#include <string> 19#include <map> 20 21#include "lldb/Core/ConstString.h" 22#include "lldb/Core/Log.h" 23#include "lldb/Core/StreamFile.h" 24#include "lldb/Core/StreamString.h" 25#include "lldb/Core/ValueObjectConstResult.h" 26#include "lldb/Expression/ASTResultSynthesizer.h" 27#include "lldb/Expression/ClangExpressionDeclMap.h" 28#include "lldb/Expression/ClangExpressionParser.h" 29#include "lldb/Expression/ClangFunction.h" 30#include "lldb/Expression/ClangUserExpression.h" 31#include "lldb/Expression/ExpressionSourceCode.h" 32#include "lldb/Host/Host.h" 33#include "lldb/Symbol/Block.h" 34#include "lldb/Symbol/ClangASTContext.h" 35#include "lldb/Symbol/Function.h" 36#include "lldb/Symbol/Type.h" 37#include "lldb/Symbol/ClangExternalASTSourceCommon.h" 38#include "lldb/Symbol/VariableList.h" 39#include "lldb/Target/ExecutionContext.h" 40#include "lldb/Target/Process.h" 41#include "lldb/Target/StackFrame.h" 42#include "lldb/Target/Target.h" 43#include "lldb/Target/ThreadPlan.h" 44#include "lldb/Target/ThreadPlanCallUserExpression.h" 45 46#include "clang/AST/DeclCXX.h" 47#include "clang/AST/DeclObjC.h" 48 49using namespace lldb_private; 50 51ClangUserExpression::ClangUserExpression (const char *expr, 52 const char *expr_prefix, 53 lldb::LanguageType language, 54 ResultType desired_type) : 55 ClangExpression (), 56 m_expr_text (expr), 57 m_expr_prefix (expr_prefix ? expr_prefix : ""), 58 m_language (language), 59 m_transformed_text (), 60 m_desired_type (desired_type), 61 m_enforce_valid_object (false), 62 m_cplusplus (false), 63 m_objectivec (false), 64 m_static_method(false), 65 m_needs_object_ptr (false), 66 m_const_object (false), 67 m_target (NULL), 68 m_evaluated_statically (false), 69 m_const_result () 70{ 71 switch (m_language) 72 { 73 case lldb::eLanguageTypeC_plus_plus: 74 m_allow_cxx = true; 75 break; 76 case lldb::eLanguageTypeObjC: 77 m_allow_objc = true; 78 break; 79 case lldb::eLanguageTypeObjC_plus_plus: 80 default: 81 m_allow_cxx = true; 82 m_allow_objc = true; 83 break; 84 } 85} 86 87ClangUserExpression::~ClangUserExpression () 88{ 89} 90 91clang::ASTConsumer * 92ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough) 93{ 94 ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext(); 95 96 if (!clang_ast_context) 97 return NULL; 98 99 if (!m_result_synthesizer.get()) 100 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough, 101 *m_target)); 102 103 return m_result_synthesizer.get(); 104} 105 106void 107ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) 108{ 109 m_target = exe_ctx.GetTargetPtr(); 110 111 if (!(m_allow_cxx || m_allow_objc)) 112 return; 113 114 StackFrame *frame = exe_ctx.GetFramePtr(); 115 if (frame == NULL) 116 return; 117 118 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock); 119 120 if (!sym_ctx.function) 121 return; 122 123 // Find the block that defines the function represented by "sym_ctx" 124 Block *function_block = sym_ctx.GetFunctionBlock(); 125 126 if (!function_block) 127 return; 128 129 clang::DeclContext *decl_context = function_block->GetClangDeclContext(); 130 131 if (!decl_context) 132 return; 133 134 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context)) 135 { 136 if (m_allow_cxx && method_decl->isInstance()) 137 { 138 if (m_enforce_valid_object) 139 { 140 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 141 142 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context"; 143 144 if (!variable_list_sp) 145 { 146 err.SetErrorString(thisErrorString); 147 return; 148 } 149 150 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this"))); 151 152 if (!this_var_sp || 153 !this_var_sp->IsInScope(frame) || 154 !this_var_sp->LocationIsValidForFrame (frame)) 155 { 156 err.SetErrorString(thisErrorString); 157 return; 158 } 159 } 160 161 m_cplusplus = true; 162 m_needs_object_ptr = true; 163 } 164 } 165 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context)) 166 { 167 if (m_allow_objc) 168 { 169 if (m_enforce_valid_object) 170 { 171 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); 172 173 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context"; 174 175 if (!variable_list_sp) 176 { 177 err.SetErrorString(selfErrorString); 178 return; 179 } 180 181 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self")); 182 183 if (!self_variable_sp || 184 !self_variable_sp->IsInScope(frame) || 185 !self_variable_sp->LocationIsValidForFrame (frame)) 186 { 187 err.SetErrorString(selfErrorString); 188 return; 189 } 190 } 191 192 m_objectivec = true; 193 m_needs_object_ptr = true; 194 195 if (!method_decl->isInstanceMethod()) 196 m_static_method = true; 197 } 198 } 199 else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context)) 200 { 201 // We might also have a function that said in the debug information that it captured an 202 // object pointer. The best way to deal with getting to the ivars at present it by pretending 203 // that this is a method of a class in whatever runtime the debug info says the object pointer 204 // belongs to. Do that here. 205 206 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), (uintptr_t) function_decl); 207 if (metadata && metadata->HasObjectPtr()) 208 { 209 lldb::LanguageType language = metadata->GetObjectPtrLanguage(); 210 if (language == lldb::eLanguageTypeC_plus_plus) 211 { 212 m_cplusplus = true; 213 m_needs_object_ptr = true; 214 } 215 else if (language == lldb::eLanguageTypeObjC) 216 { 217 m_objectivec = true; 218 m_needs_object_ptr = true; 219 } 220 } 221 } 222} 223 224// This is a really nasty hack, meant to fix Objective-C expressions of the form 225// (int)[myArray count]. Right now, because the type information for count is 226// not available, [myArray count] returns id, which can't be directly cast to 227// int without causing a clang error. 228static void 229ApplyObjcCastHack(std::string &expr) 230{ 231#define OBJC_CAST_HACK_FROM "(int)[" 232#define OBJC_CAST_HACK_TO "(int)(long long)[" 233 234 size_t from_offset; 235 236 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos) 237 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO); 238 239#undef OBJC_CAST_HACK_TO 240#undef OBJC_CAST_HACK_FROM 241} 242 243// Another hack, meant to allow use of unichar despite it not being available in 244// the type information. Although we could special-case it in type lookup, 245// hopefully we'll figure out a way to #include the same environment as is 246// present in the original source file rather than try to hack specific type 247// definitions in as needed. 248static void 249ApplyUnicharHack(std::string &expr) 250{ 251#define UNICHAR_HACK_FROM "unichar" 252#define UNICHAR_HACK_TO "unsigned short" 253 254 size_t from_offset; 255 256 while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos) 257 expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO); 258 259#undef UNICHAR_HACK_TO 260#undef UNICHAR_HACK_FROM 261} 262 263bool 264ClangUserExpression::Parse (Stream &error_stream, 265 ExecutionContext &exe_ctx, 266 lldb_private::ExecutionPolicy execution_policy, 267 bool keep_result_in_memory) 268{ 269 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 270 271 Error err; 272 273 InstallContext(exe_ctx); 274 275 ScanContext(exe_ctx, err); 276 277 if (!err.Success()) 278 { 279 error_stream.Printf("warning: %s\n", err.AsCString()); 280 } 281 282 StreamString m_transformed_stream; 283 284 //////////////////////////////////// 285 // Generate the expression 286 // 287 288 ApplyObjcCastHack(m_expr_text); 289 //ApplyUnicharHack(m_expr_text); 290 291 std::auto_ptr <ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str())); 292 293 lldb::LanguageType lang_type; 294 295 if (m_cplusplus) 296 lang_type = lldb::eLanguageTypeC_plus_plus; 297 else if(m_objectivec) 298 lang_type = lldb::eLanguageTypeObjC; 299 else 300 lang_type = lldb::eLanguageTypeC; 301 302 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method)) 303 { 304 error_stream.PutCString ("error: couldn't construct expression body"); 305 return false; 306 } 307 308 if (log) 309 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); 310 311 //////////////////////////////////// 312 // Set up the target and compiler 313 // 314 315 Target *target = exe_ctx.GetTargetPtr(); 316 317 if (!target) 318 { 319 error_stream.PutCString ("error: invalid target\n"); 320 return false; 321 } 322 323 ////////////////////////// 324 // Parse the expression 325 // 326 327 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx)); 328 329 if (!m_expr_decl_map->WillParse(exe_ctx)) 330 { 331 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n"); 332 return false; 333 } 334 335 Process *process = exe_ctx.GetProcessPtr(); 336 ExecutionContextScope *exe_scope = process; 337 338 if (!exe_scope) 339 exe_scope = exe_ctx.GetTargetPtr(); 340 341 ClangExpressionParser parser(exe_scope, *this); 342 343 unsigned num_errors = parser.Parse (error_stream); 344 345 if (num_errors) 346 { 347 error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 348 349 m_expr_decl_map->DidParse(); 350 351 return false; 352 } 353 354 ////////////////////////////////////////////////////////////////////////////////////////// 355 // Prepare the output of the parser for execution, evaluating it statically if possible 356 // 357 358 if (execution_policy != eExecutionPolicyNever && process) 359 m_data_allocator.reset(new ProcessDataAllocator(*process)); 360 361 Error jit_error = parser.PrepareForExecution (m_jit_alloc, 362 m_jit_start_addr, 363 m_jit_end_addr, 364 exe_ctx, 365 m_data_allocator.get(), 366 m_evaluated_statically, 367 m_const_result, 368 execution_policy); 369 370 if (log && m_data_allocator.get()) 371 { 372 StreamString dump_string; 373 m_data_allocator->Dump(dump_string); 374 375 log->Printf("Data buffer contents:\n%s", dump_string.GetString().c_str()); 376 } 377 378 if (jit_error.Success()) 379 { 380 if (process && m_jit_alloc != LLDB_INVALID_ADDRESS) 381 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); 382 return true; 383 } 384 else 385 { 386 const char *error_cstr = jit_error.AsCString(); 387 if (error_cstr && error_cstr[0]) 388 error_stream.Printf ("error: %s\n", error_cstr); 389 else 390 error_stream.Printf ("error: expression can't be interpreted or run\n"); 391 return false; 392 } 393} 394 395bool 396ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, 397 ExecutionContext &exe_ctx, 398 lldb::addr_t &struct_address, 399 lldb::addr_t &object_ptr, 400 lldb::addr_t &cmd_ptr) 401{ 402 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 403 404 lldb::TargetSP target; 405 lldb::ProcessSP process; 406 lldb::StackFrameSP frame; 407 408 if (!LockAndCheckContext(exe_ctx, 409 target, 410 process, 411 frame)) 412 { 413 error_stream.Printf("The context has changed before we could JIT the expression!"); 414 return false; 415 } 416 417 if (m_jit_start_addr != LLDB_INVALID_ADDRESS) 418 { 419 Error materialize_error; 420 421 if (m_needs_object_ptr) 422 { 423 ConstString object_name; 424 425 if (m_cplusplus) 426 { 427 object_name.SetCString("this"); 428 } 429 else if (m_objectivec) 430 { 431 object_name.SetCString("self"); 432 } 433 else 434 { 435 error_stream.Printf("Need object pointer but don't know the language\n"); 436 return false; 437 } 438 439 if (!(m_expr_decl_map->GetObjectPointer(object_ptr, object_name, materialize_error))) 440 { 441 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", materialize_error.AsCString()); 442 object_ptr = 0; 443 } 444 445 if (m_objectivec) 446 { 447 ConstString cmd_name("_cmd"); 448 449 if (!(m_expr_decl_map->GetObjectPointer(cmd_ptr, cmd_name, materialize_error, true))) 450 { 451 error_stream.Printf("warning: couldn't get object pointer (substituting NULL): %s\n", materialize_error.AsCString()); 452 cmd_ptr = 0; 453 } 454 } 455 } 456 457 if (!m_expr_decl_map->Materialize(struct_address, materialize_error)) 458 { 459 error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString()); 460 return false; 461 } 462 463#if 0 464 // jingham: look here 465 StreamFile logfile ("/tmp/exprs.txt", "a"); 466 logfile.Printf("0x%16.16" PRIx64 ": thread = 0x%4.4x, expr = '%s'\n", m_jit_start_addr, exe_ctx.thread ? exe_ctx.thread->GetID() : -1, m_expr_text.c_str()); 467#endif 468 469 if (log) 470 { 471 log->Printf("-- [ClangUserExpression::PrepareToExecuteJITExpression] Materializing for execution --"); 472 473 log->Printf(" Function address : 0x%" PRIx64, (uint64_t)m_jit_start_addr); 474 475 if (m_needs_object_ptr) 476 log->Printf(" Object pointer : 0x%" PRIx64, (uint64_t)object_ptr); 477 478 log->Printf(" Structure address : 0x%" PRIx64, (uint64_t)struct_address); 479 480 StreamString args; 481 482 Error dump_error; 483 484 if (struct_address) 485 { 486 if (!m_expr_decl_map->DumpMaterializedStruct(args, dump_error)) 487 { 488 log->Printf(" Couldn't extract variable values : %s", dump_error.AsCString("unknown error")); 489 } 490 else 491 { 492 log->Printf(" Structure contents:\n%s", args.GetData()); 493 } 494 } 495 } 496 } 497 return true; 498} 499 500ThreadPlan * 501ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream, 502 ExecutionContext &exe_ctx) 503{ 504 lldb::addr_t struct_address; 505 506 lldb::addr_t object_ptr = 0; 507 lldb::addr_t cmd_ptr = 0; 508 509 PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr); 510 511 // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the 512 // ClangUserExpression resources before the thread plan finishes execution in the target. But because we are 513 // forcing unwind_on_error to be true here, in practical terms that can't happen. 514 515 return ClangFunction::GetThreadPlanToCallFunction (exe_ctx, 516 m_jit_start_addr, 517 struct_address, 518 error_stream, 519 true, 520 true, 521 (m_needs_object_ptr ? &object_ptr : NULL), 522 (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL); 523} 524 525bool 526ClangUserExpression::FinalizeJITExecution (Stream &error_stream, 527 ExecutionContext &exe_ctx, 528 lldb::ClangExpressionVariableSP &result, 529 lldb::addr_t function_stack_pointer) 530{ 531 Error expr_error; 532 533 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 534 535 if (log) 536 { 537 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --"); 538 539 StreamString args; 540 541 Error dump_error; 542 543 if (!m_expr_decl_map->DumpMaterializedStruct(args, dump_error)) 544 { 545 log->Printf(" Couldn't extract variable values : %s", dump_error.AsCString("unknown error")); 546 } 547 else 548 { 549 log->Printf(" Structure contents:\n%s", args.GetData()); 550 } 551 } 552 553 lldb::addr_t function_stack_bottom = function_stack_pointer - Host::GetPageSize(); 554 555 556 if (!m_expr_decl_map->Dematerialize(result, function_stack_pointer, function_stack_bottom, expr_error)) 557 { 558 error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error")); 559 return false; 560 } 561 562 if (result) 563 result->TransferAddress(); 564 565 return true; 566} 567 568ExecutionResults 569ClangUserExpression::Execute (Stream &error_stream, 570 ExecutionContext &exe_ctx, 571 bool discard_on_error, 572 ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me, 573 lldb::ClangExpressionVariableSP &result, 574 bool run_others, 575 uint32_t timeout_usec) 576{ 577 // The expression log is quite verbose, and if you're just tracking the execution of the 578 // expression, it's quite convenient to have these logs come out with the STEP log as well. 579 lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); 580 581 if (m_jit_start_addr != LLDB_INVALID_ADDRESS) 582 { 583 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS; 584 585 lldb::addr_t object_ptr = 0; 586 lldb::addr_t cmd_ptr = 0; 587 588 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr)) 589 { 590 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__); 591 return eExecutionSetupError; 592 } 593 594 const bool stop_others = true; 595 const bool try_all_threads = true; 596 597 Address wrapper_address (m_jit_start_addr); 598 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(), 599 wrapper_address, 600 struct_address, 601 stop_others, 602 discard_on_error, 603 (m_needs_object_ptr ? &object_ptr : NULL), 604 ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL), 605 shared_ptr_to_me)); 606 607 if (!call_plan_sp || !call_plan_sp->ValidatePlan (NULL)) 608 return eExecutionSetupError; 609 610 lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer(); 611 612 call_plan_sp->SetPrivate(true); 613 614 if (log) 615 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --"); 616 617 if (exe_ctx.GetProcessPtr()) 618 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true); 619 620 ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx, 621 call_plan_sp, 622 stop_others, 623 try_all_threads, 624 discard_on_error, 625 timeout_usec, 626 error_stream); 627 628 if (exe_ctx.GetProcessPtr()) 629 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false); 630 631 if (log) 632 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --"); 633 634 if (execution_result == eExecutionInterrupted) 635 { 636 const char *error_desc = NULL; 637 638 if (call_plan_sp) 639 { 640 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo(); 641 if (real_stop_info_sp) 642 error_desc = real_stop_info_sp->GetDescription(); 643 } 644 if (error_desc) 645 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc); 646 else 647 error_stream.Printf ("Execution was interrupted."); 648 649 if (discard_on_error) 650 error_stream.Printf ("\nThe process has been returned to the state before execution."); 651 else 652 error_stream.Printf ("\nThe process has been left at the point where it was interrupted."); 653 654 return execution_result; 655 } 656 else if (execution_result != eExecutionCompleted) 657 { 658 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result)); 659 return execution_result; 660 } 661 662 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_pointer)) 663 return eExecutionCompleted; 664 else 665 { 666 error_stream.Printf("Errored out in %s: Couldn't FinalizeJITExpression", __FUNCTION__); 667 return eExecutionSetupError; 668 } 669 } 670 else 671 { 672 error_stream.Printf("Expression can't be run, because there is no JIT compiled function"); 673 return eExecutionSetupError; 674 } 675} 676 677ExecutionResults 678ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, 679 lldb_private::ExecutionPolicy execution_policy, 680 lldb::LanguageType language, 681 ResultType desired_type, 682 bool discard_on_error, 683 const char *expr_cstr, 684 const char *expr_prefix, 685 lldb::ValueObjectSP &result_valobj_sp, 686 bool run_others, 687 uint32_t timeout_usec) 688{ 689 Error error; 690 return EvaluateWithError (exe_ctx, 691 execution_policy, 692 language, 693 desired_type, 694 discard_on_error, 695 expr_cstr, 696 expr_prefix, 697 result_valobj_sp, 698 error, 699 run_others, 700 timeout_usec); 701} 702 703ExecutionResults 704ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx, 705 lldb_private::ExecutionPolicy execution_policy, 706 lldb::LanguageType language, 707 ResultType desired_type, 708 bool discard_on_error, 709 const char *expr_cstr, 710 const char *expr_prefix, 711 lldb::ValueObjectSP &result_valobj_sp, 712 Error &error, 713 bool run_others, 714 uint32_t timeout_usec) 715{ 716 lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); 717 718 ExecutionResults execution_results = eExecutionSetupError; 719 720 Process *process = exe_ctx.GetProcessPtr(); 721 722 if (process == NULL || process->GetState() != lldb::eStateStopped) 723 { 724 if (execution_policy == eExecutionPolicyAlways) 725 { 726 if (log) 727 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); 728 729 error.SetErrorString ("expression needed to run but couldn't"); 730 731 return execution_results; 732 } 733 } 734 735 if (process == NULL || !process->CanJIT()) 736 execution_policy = eExecutionPolicyNever; 737 738 ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type)); 739 740 StreamString error_stream; 741 742 if (log) 743 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr); 744 745 const bool keep_expression_in_memory = true; 746 747 if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory)) 748 { 749 if (error_stream.GetString().empty()) 750 error.SetErrorString ("expression failed to parse, unknown error"); 751 else 752 error.SetErrorString (error_stream.GetString().c_str()); 753 } 754 else 755 { 756 lldb::ClangExpressionVariableSP expr_result; 757 758 if (user_expression_sp->EvaluatedStatically()) 759 { 760 if (log) 761 log->Printf("== [ClangUserExpression::Evaluate] Expression evaluated as a constant =="); 762 763 if (user_expression_sp->m_const_result) 764 result_valobj_sp = user_expression_sp->m_const_result->GetValueObject(); 765 else 766 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric); 767 768 execution_results = eExecutionCompleted; 769 } 770 else if (execution_policy == eExecutionPolicyNever) 771 { 772 if (log) 773 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant =="); 774 775 if (error_stream.GetString().empty()) 776 error.SetErrorString ("expression needed to run but couldn't"); 777 } 778 else 779 { 780 error_stream.GetString().clear(); 781 782 if (log) 783 log->Printf("== [ClangUserExpression::Evaluate] Executing expression =="); 784 785 execution_results = user_expression_sp->Execute (error_stream, 786 exe_ctx, 787 discard_on_error, 788 user_expression_sp, 789 expr_result, 790 run_others, 791 timeout_usec); 792 793 if (execution_results != eExecutionCompleted) 794 { 795 if (log) 796 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally =="); 797 798 if (error_stream.GetString().empty()) 799 error.SetErrorString ("expression failed to execute, unknown error"); 800 else 801 error.SetErrorString (error_stream.GetString().c_str()); 802 } 803 else 804 { 805 if (expr_result) 806 { 807 result_valobj_sp = expr_result->GetValueObject(); 808 809 if (log) 810 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString()); 811 } 812 else 813 { 814 if (log) 815 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result =="); 816 817 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric); 818 } 819 } 820 } 821 } 822 823 if (result_valobj_sp.get() == NULL) 824 result_valobj_sp = ValueObjectConstResult::Create (NULL, error); 825 826 return execution_results; 827} 828