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