ClangExpressionDeclMap.cpp revision 30449d50f5328ca745d09d943b7e3b1ba41bff08
1//===-- ClangExpressionDeclMap.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#include "lldb/Expression/ClangExpressionDeclMap.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "clang/AST/DeclarationName.h" 17#include "lldb/lldb-private.h" 18#include "lldb/Core/Address.h" 19#include "lldb/Core/Error.h" 20#include "lldb/Core/Log.h" 21#include "lldb/Core/Module.h" 22#include "lldb/Expression/ClangASTSource.h" 23#include "lldb/Expression/ClangPersistentVariables.h" 24#include "lldb/Symbol/ClangASTContext.h" 25#include "lldb/Symbol/CompileUnit.h" 26#include "lldb/Symbol/Function.h" 27#include "lldb/Symbol/ObjectFile.h" 28#include "lldb/Symbol/SymbolContext.h" 29#include "lldb/Symbol/Type.h" 30#include "lldb/Symbol/TypeList.h" 31#include "lldb/Symbol/Variable.h" 32#include "lldb/Symbol/VariableList.h" 33#include "lldb/Target/ExecutionContext.h" 34#include "lldb/Target/Process.h" 35#include "lldb/Target/StackFrame.h" 36#include "lldb/Target/Target.h" 37 38using namespace lldb_private; 39using namespace clang; 40 41ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) : 42 m_exe_ctx(exe_ctx), m_struct_laid_out(false), 43 m_materialized_location(0) 44{ 45 if (exe_ctx && exe_ctx->frame) 46 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything)); 47 else 48 m_sym_ctx = NULL; 49 50 if (exe_ctx && exe_ctx->process) 51 m_persistent_vars = &exe_ctx->process->GetPersistentVariables(); 52} 53 54ClangExpressionDeclMap::~ClangExpressionDeclMap() 55{ 56 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size(); 57 entity_index < num_entities; 58 ++entity_index) 59 { 60 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index)); 61 if (entity.m_parser_vars.get() && 62 entity.m_parser_vars->m_lldb_value) 63 delete entity.m_parser_vars->m_lldb_value; 64 65 entity.DisableParserVars(); 66 } 67 68 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size(); 69 pvar_index < num_pvars; 70 ++pvar_index) 71 { 72 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index)); 73 pvar.DisableParserVars(); 74 } 75 76 if (m_sym_ctx) 77 delete m_sym_ctx; 78} 79 80// Interface for IRForTarget 81 82void 83ClangExpressionDeclMap::GetPersistentResultName (std::string &name) 84{ 85 m_persistent_vars->GetNextResultName(m_result_name); 86 87 name = m_result_name; 88} 89 90bool 91ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl, 92 const char *name, 93 TypeFromParser parser_type) 94{ 95 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext()); 96 97 TypeFromUser user_type(ClangASTContext::CopyType(context, 98 parser_type.GetASTContext(), 99 parser_type.GetOpaqueQualType()), 100 context); 101 102 if (!m_persistent_vars->CreatePersistentVariable (name, user_type)) 103 return false; 104 105 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name); 106 107 if (!var) 108 return false; 109 110 var->EnableParserVars(); 111 112 var->m_parser_vars->m_named_decl = decl; 113 var->m_parser_vars->m_parser_type = parser_type; 114 115 return true; 116} 117 118bool 119ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl, 120 const char *name, 121 llvm::Value *value, 122 size_t size, 123 off_t alignment) 124{ 125 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 126 127 m_struct_laid_out = false; 128 129 if (m_struct_members.GetVariable(decl)) 130 return true; 131 132 ClangExpressionVariable *var = m_found_entities.GetVariable(decl); 133 134 if (!var) 135 var = m_persistent_vars->GetVariable(decl); 136 137 if (!var) 138 return false; 139 140 if (log) 141 log->Printf("Adding value for decl %p [%s - %s] to the structure", 142 decl, 143 name, 144 var->m_name.c_str()); 145 146 // We know entity->m_parser_vars is valid because we used a parser variable 147 // to find it 148 var->m_parser_vars->m_llvm_value = value; 149 150 var->EnableJITVars(); 151 var->m_jit_vars->m_alignment = alignment; 152 var->m_jit_vars->m_size = size; 153 154 m_struct_members.AddVariable(*var); 155 156 return true; 157} 158 159bool 160ClangExpressionDeclMap::DoStructLayout () 161{ 162 if (m_struct_laid_out) 163 return true; 164 165 off_t cursor = 0; 166 167 m_struct_alignment = 0; 168 m_struct_size = 0; 169 170 for (uint64_t member_index = 0, num_members = m_struct_members.Size(); 171 member_index < num_members; 172 ++member_index) 173 { 174 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index)); 175 176 if (!member.m_jit_vars.get()) 177 return false; 178 179 if (member_index == 0) 180 m_struct_alignment = member.m_jit_vars->m_alignment; 181 182 if (cursor % member.m_jit_vars->m_alignment) 183 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment)); 184 185 member.m_jit_vars->m_offset = cursor; 186 cursor += member.m_jit_vars->m_size; 187 } 188 189 m_struct_size = cursor; 190 191 m_struct_laid_out = true; 192 return true; 193} 194 195bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements, 196 size_t &size, 197 off_t &alignment) 198{ 199 if (!m_struct_laid_out) 200 return false; 201 202 num_elements = m_struct_members.Size(); 203 size = m_struct_size; 204 alignment = m_struct_alignment; 205 206 return true; 207} 208 209bool 210ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl, 211 llvm::Value *&value, 212 off_t &offset, 213 const char *&name, 214 uint32_t index) 215{ 216 if (!m_struct_laid_out) 217 return false; 218 219 if (index >= m_struct_members.Size()) 220 return false; 221 222 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index)); 223 224 if (!member.m_parser_vars.get() || 225 !member.m_jit_vars.get()) 226 return false; 227 228 decl = member.m_parser_vars->m_named_decl; 229 value = member.m_parser_vars->m_llvm_value; 230 offset = member.m_jit_vars->m_offset; 231 name = member.m_name.c_str(); 232 233 return true; 234} 235 236bool 237ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl, 238 llvm::Value**& value, 239 uint64_t &ptr) 240{ 241 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl); 242 243 if (!entity) 244 return false; 245 246 // We know m_parser_vars is valid since we searched for the variable by 247 // its NamedDecl 248 249 value = &entity->m_parser_vars->m_llvm_value; 250 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong(); 251 252 return true; 253} 254 255bool 256ClangExpressionDeclMap::GetFunctionAddress (const char *name, 257 uint64_t &ptr) 258{ 259 // Back out in all cases where we're not fully initialized 260 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx) 261 return false; 262 263 ConstString name_cs(name); 264 SymbolContextList sym_ctxs; 265 266 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs); 267 268 if (!sym_ctxs.GetSize()) 269 return false; 270 271 SymbolContext sym_ctx; 272 sym_ctxs.GetContextAtIndex(0, sym_ctx); 273 274 const Address *fun_address; 275 276 if (sym_ctx.function) 277 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress(); 278 else if (sym_ctx.symbol) 279 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress(); 280 else 281 return false; 282 283 ptr = fun_address->GetLoadAddress(m_exe_ctx->target); 284 285 return true; 286} 287 288// Interface for CommandObjectExpression 289 290bool 291ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx, 292 lldb::addr_t &struct_address, 293 Error &err) 294{ 295 bool result = DoMaterialize(false, exe_ctx, NULL, err); 296 297 if (result) 298 struct_address = m_materialized_location; 299 300 return result; 301} 302 303bool 304ClangExpressionDeclMap::GetObjectPointer(lldb::addr_t &object_ptr, 305 ExecutionContext *exe_ctx, 306 Error &err) 307{ 308 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process) 309 { 310 err.SetErrorString("Couldn't load 'this' because the context is incomplete"); 311 return false; 312 } 313 314 if (!m_object_pointer_type.GetOpaqueQualType()) 315 { 316 err.SetErrorString("Couldn't load 'this' because its type is unknown"); 317 return false; 318 } 319 320 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, "this", &m_object_pointer_type); 321 322 if (!object_ptr_var) 323 { 324 err.SetErrorString("Couldn't find 'this' with appropriate type in scope"); 325 return false; 326 } 327 328 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx, 329 object_ptr_var, 330 m_object_pointer_type.GetASTContext())); 331 332 if (!location_value.get()) 333 { 334 err.SetErrorString("Couldn't get the location for 'this'"); 335 return false; 336 } 337 338 if (location_value->GetValueType() == Value::eValueTypeLoadAddress) 339 { 340 lldb::addr_t value_addr = location_value->GetScalar().ULongLong(); 341 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize(); 342 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder(); 343 344 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8) 345 { 346 err.SetErrorStringWithFormat("'this' is not of an expected pointer size"); 347 return false; 348 } 349 350 DataBufferHeap data; 351 data.SetByteSize(address_byte_size); 352 Error read_error; 353 354 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size) 355 { 356 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString()); 357 return false; 358 } 359 360 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size); 361 362 uint32_t offset = 0; 363 364 object_ptr = extractor.GetPointer(&offset); 365 366 return true; 367 } 368 else 369 { 370 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers"); 371 return false; 372 } 373} 374 375bool 376ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx, 377 ClangExpressionVariable *&result, 378 Error &err) 379{ 380 return DoMaterialize(true, exe_ctx, &result, err); 381} 382 383bool 384ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx, 385 Stream &s, 386 Error &err) 387{ 388 if (!m_struct_laid_out) 389 { 390 err.SetErrorString("Structure hasn't been laid out yet"); 391 return false; 392 } 393 394 if (!exe_ctx) 395 { 396 err.SetErrorString("Received null execution context"); 397 return false; 398 } 399 400 401 if (!exe_ctx->process) 402 { 403 err.SetErrorString("Couldn't find the process"); 404 return false; 405 } 406 407 if (!exe_ctx->target) 408 { 409 err.SetErrorString("Couldn't find the target"); 410 return false; 411 } 412 413 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0)); 414 415 Error error; 416 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize()) 417 { 418 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString()); 419 return false; 420 } 421 422 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize()); 423 424 for (uint64_t member_index = 0, num_members = m_struct_members.Size(); 425 member_index < num_members; 426 ++member_index) 427 { 428 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index)); 429 430 s.Printf("[%s]\n", member.m_name.c_str()); 431 432 if (!member.m_jit_vars.get()) 433 return false; 434 435 extractor.Dump(&s, // stream 436 member.m_jit_vars->m_offset, // offset 437 lldb::eFormatBytesWithASCII, // format 438 1, // byte size of individual entries 439 member.m_jit_vars->m_size, // number of entries 440 16, // entries per line 441 m_materialized_location + member.m_jit_vars->m_offset, // address to print 442 0, // bit size (bitfields only; 0 means ignore) 443 0); // bit alignment (bitfields only; 0 means ignore) 444 445 s.PutChar('\n'); 446 } 447 448 return true; 449} 450 451bool 452ClangExpressionDeclMap::DoMaterialize (bool dematerialize, 453 ExecutionContext *exe_ctx, 454 ClangExpressionVariable **result, 455 Error &err) 456{ 457 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 458 459 if (!m_struct_laid_out) 460 { 461 err.SetErrorString("Structure hasn't been laid out yet"); 462 return LLDB_INVALID_ADDRESS; 463 } 464 465 if (!exe_ctx) 466 { 467 err.SetErrorString("Received null execution context"); 468 return LLDB_INVALID_ADDRESS; 469 } 470 471 if (!exe_ctx->frame) 472 { 473 err.SetErrorString("Received null execution frame"); 474 return LLDB_INVALID_ADDRESS; 475 } 476 477 if (!m_struct_size) 478 { 479 if (log) 480 log->PutCString("Not bothering to allocate a struct because no arguments are needed"); 481 482 m_allocated_area = NULL; 483 484 return true; 485 } 486 487 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything)); 488 489 if (!dematerialize) 490 { 491 if (m_materialized_location) 492 { 493 exe_ctx->process->DeallocateMemory(m_materialized_location); 494 m_materialized_location = 0; 495 } 496 497 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size, 498 lldb::ePermissionsReadable | lldb::ePermissionsWritable, 499 err); 500 501 if (mem == LLDB_INVALID_ADDRESS) 502 return false; 503 504 m_allocated_area = mem; 505 } 506 507 m_materialized_location = m_allocated_area; 508 509 if (m_materialized_location % m_struct_alignment) 510 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment)); 511 512 for (uint64_t member_index = 0, num_members = m_struct_members.Size(); 513 member_index < num_members; 514 ++member_index) 515 { 516 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index)); 517 518 if (!member.m_parser_vars.get()) 519 return false; 520 521 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl); 522 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str()); 523 524 if (entity) 525 { 526 if (!member.m_jit_vars.get()) 527 return false; 528 529 if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name.c_str(), member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err)) 530 return false; 531 } 532 else if (persistent_variable) 533 { 534 if (!member.m_name.compare(m_result_name)) 535 { 536 if (!dematerialize) 537 continue; 538 539 if (log) 540 log->PutCString("Found result member in the struct"); 541 542 *result = &member; 543 } 544 545 if (log) 546 log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str()); 547 548 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err)) 549 return false; 550 } 551 else 552 { 553 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str()); 554 return false; 555 } 556 } 557 558 return true; 559} 560 561bool 562ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize, 563 ExecutionContext &exe_ctx, 564 const char *name, 565 lldb::addr_t addr, 566 Error &err) 567{ 568 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); 569 570 if (!pvar) 571 { 572 err.SetErrorStringWithFormat("Undefined persistent variable %s", name); 573 return LLDB_INVALID_ADDRESS; 574 } 575 576 size_t pvar_size = pvar->Size(); 577 578 if (!pvar->m_data_vars.get()) 579 return false; 580 581 uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes(); 582 Error error; 583 584 if (dematerialize) 585 { 586 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size) 587 { 588 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); 589 return false; 590 } 591 } 592 else 593 { 594 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size) 595 { 596 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); 597 return false; 598 } 599 } 600 601 return true; 602} 603 604bool 605ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize, 606 ExecutionContext &exe_ctx, 607 const SymbolContext &sym_ctx, 608 const char *name, 609 TypeFromUser type, 610 lldb::addr_t addr, 611 Error &err) 612{ 613 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 614 615 if (!exe_ctx.frame) 616 return false; 617 618 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type); 619 620 if (!var) 621 { 622 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name); 623 return false; 624 } 625 626 if (log) 627 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType()); 628 629 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx, 630 var, 631 type.GetASTContext())); 632 633 if (!location_value.get()) 634 { 635 err.SetErrorStringWithFormat("Couldn't get value for %s", name); 636 return false; 637 } 638 639 if (location_value->GetValueType() == Value::eValueTypeLoadAddress) 640 { 641 lldb::addr_t value_addr = location_value->GetScalar().ULongLong(); 642 643 size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType()); 644 size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8); 645 646 DataBufferHeap data; 647 data.SetByteSize(byte_size); 648 649 lldb::addr_t src_addr; 650 lldb::addr_t dest_addr; 651 652 if (dematerialize) 653 { 654 src_addr = addr; 655 dest_addr = value_addr; 656 } 657 else 658 { 659 src_addr = value_addr; 660 dest_addr = addr; 661 } 662 663 Error error; 664 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size) 665 { 666 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); 667 return false; 668 } 669 670 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size) 671 { 672 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); 673 return false; 674 } 675 676 if (log) 677 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr); 678 } 679 else 680 { 681 StreamString ss; 682 683 location_value->Dump(&ss); 684 685 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str()); 686 } 687 688 return true; 689} 690 691Variable * 692ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame, 693 const char *name, 694 TypeFromUser *type) 695{ 696 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 697 698 ConstString name_cs(name); 699 700 VariableList *var_list = frame.GetVariableList(true); 701 702 lldb::VariableSP var = var_list->FindVariable(name_cs); 703 704 if (!var) 705 return NULL; 706 707 if (!type) 708 return var.get(); 709 710 if (type->GetASTContext() == var->GetType()->GetClangAST()) 711 { 712 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType())) 713 return NULL; 714 } 715 else 716 { 717 if (log) 718 log->PutCString("Skipping a candidate variable because of different AST contexts"); 719 return NULL; 720 } 721 722 return var.get(); 723 724 return NULL; 725} 726 727// Interface for ClangASTSource 728void 729ClangExpressionDeclMap::GetDecls(NameSearchContext &context, 730 const char *name) 731{ 732 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 733 734 if (log) 735 log->Printf("Hunting for a definition for %s", name); 736 737 // Back out in all cases where we're not fully initialized 738 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx) 739 return; 740 741 ConstString name_cs(name); 742 743 if (!strcmp(name, "___clang_class")) 744 { 745 // Clang is looking for the type of "this" 746 747 VariableList *vars = m_exe_ctx->frame->GetVariableList(false); 748 749 if (!vars) 750 return; 751 752 lldb::VariableSP this_var = vars->FindVariable(ConstString("this")); 753 754 if (!this_var) 755 return; 756 757 Type *this_type = this_var->GetType(); 758 759 if (!this_type) 760 return; 761 762 TypeFromUser this_user_type(this_type->GetClangType(), 763 this_type->GetClangAST()); 764 765 m_object_pointer_type = this_user_type; 766 767 void *pointer_target_type; 768 769 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(), 770 &pointer_target_type)) 771 return; 772 773 TypeFromUser class_user_type(pointer_target_type, 774 this_type->GetClangAST()); 775 776 AddOneType(context, class_user_type, true); 777 778 return; 779 } 780 781 SymbolContextList sym_ctxs; 782 783 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs); 784 785 bool found_generic = false; 786 bool found_specific = false; 787 788 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize(); 789 index < num_indices; 790 ++index) 791 { 792 SymbolContext sym_ctx; 793 sym_ctxs.GetContextAtIndex(index, sym_ctx); 794 795 if (sym_ctx.function) 796 { 797 // TODO only do this if it's a C function; C++ functions may be 798 // overloaded 799 if (!found_specific) 800 AddOneFunction(context, sym_ctx.function, NULL); 801 found_specific = true; 802 } 803 else if(sym_ctx.symbol) 804 { 805 if (!found_generic && !found_specific) 806 { 807 AddOneFunction(context, NULL, sym_ctx.symbol); 808 found_generic = true; 809 } 810 } 811 } 812 813 Variable *var = FindVariableInScope(*m_exe_ctx->frame, name); 814 815 if (var) 816 AddOneVariable(context, var); 817 818 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); 819 820 if (pvar) 821 AddOneVariable(context, pvar); 822 823 824 // See information on gating of this operation next to the definition for 825 // m_lookedup_types. 826 827 const char *name_uniq = name_cs.GetCString(); 828 829 if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end()) 830 { 831 // 1 The name is added to m_lookedup_types. 832 m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true)); 833 834 // 2 The type is looked up and added, potentially causing more type loookups. 835 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs); 836 837 if (type.get()) 838 { 839 TypeFromUser user_type(type->GetClangType(), 840 type->GetClangAST()); 841 842 AddOneType(context, user_type, false); 843 } 844 845 // 3 The name is removed from m_lookedup_types. 846 m_lookedup_types.erase(name_uniq); 847 } 848 849} 850 851Value * 852ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx, 853 Variable *var, 854 clang::ASTContext *parser_ast_context, 855 TypeFromUser *user_type, 856 TypeFromParser *parser_type) 857{ 858 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 859 860 Type *var_type = var->GetType(); 861 862 if (!var_type) 863 { 864 if (log) 865 log->PutCString("Skipped a definition because it has no type"); 866 return NULL; 867 } 868 869 void *var_opaque_type = var_type->GetClangType(); 870 871 if (!var_opaque_type) 872 { 873 if (log) 874 log->PutCString("Skipped a definition because it has no Clang type"); 875 return NULL; 876 } 877 878 TypeList *type_list = var_type->GetTypeList(); 879 880 if (!type_list) 881 { 882 if (log) 883 log->PutCString("Skipped a definition because the type has no associated type list"); 884 return NULL; 885 } 886 887 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext(); 888 889 if (!exe_ast_ctx) 890 { 891 if (log) 892 log->PutCString("There is no AST context for the current execution context"); 893 return NULL; 894 } 895 896 DWARFExpression &var_location_expr = var->LocationExpression(); 897 898 std::auto_ptr<Value> var_location(new Value); 899 900 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; 901 902 if (var_location_expr.IsLocationList()) 903 { 904 SymbolContext var_sc; 905 var->CalculateSymbolContext (&var_sc); 906 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target); 907 } 908 Error err; 909 910 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, loclist_base_load_addr, NULL, *var_location.get(), &err)) 911 { 912 if (log) 913 log->Printf("Error evaluating location: %s", err.AsCString()); 914 return NULL; 915 } 916 917 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext(); 918 919 void *type_to_use; 920 921 if (parser_ast_context) 922 { 923 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type); 924 925 if (parser_type) 926 *parser_type = TypeFromParser(type_to_use, parser_ast_context); 927 } 928 else 929 type_to_use = var_opaque_type; 930 931 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid) 932 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use); 933 934 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress) 935 { 936 SymbolContext var_sc; 937 var->CalculateSymbolContext(&var_sc); 938 939 if (!var_sc.module_sp) 940 return NULL; 941 942 ObjectFile *object_file = var_sc.module_sp->GetObjectFile(); 943 944 if (!object_file) 945 return NULL; 946 947 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList()); 948 949 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->target); 950 951 var_location->GetScalar() = load_addr; 952 var_location->SetValueType(Value::eValueTypeLoadAddress); 953 } 954 955 if (user_type) 956 *user_type = TypeFromUser(var_opaque_type, var_ast_context); 957 958 return var_location.release(); 959} 960 961void 962ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 963 Variable* var) 964{ 965 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 966 967 TypeFromUser ut; 968 TypeFromParser pt; 969 970 Value *var_location = GetVariableValue(*m_exe_ctx, 971 var, 972 context.GetASTContext(), 973 &ut, 974 &pt); 975 976 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType()); 977 978 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); 979 entity.m_name = context.Name.getAsString(); 980 entity.m_user_type = ut; 981 982 entity.EnableParserVars(); 983 entity.m_parser_vars->m_parser_type = pt; 984 entity.m_parser_vars->m_named_decl = var_decl; 985 entity.m_parser_vars->m_llvm_value = NULL; 986 entity.m_parser_vars->m_lldb_value = var_location; 987 988 if (log) 989 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl); 990} 991 992void 993ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 994 ClangExpressionVariable *pvar) 995{ 996 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 997 998 TypeFromUser user_type = pvar->m_user_type; 999 1000 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), 1001 user_type.GetASTContext(), 1002 user_type.GetOpaqueQualType()), 1003 context.GetASTContext()); 1004 1005 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); 1006 1007 pvar->EnableParserVars(); 1008 pvar->m_parser_vars->m_parser_type = parser_type; 1009 pvar->m_parser_vars->m_named_decl = var_decl; 1010 pvar->m_parser_vars->m_llvm_value = NULL; 1011 pvar->m_parser_vars->m_lldb_value = NULL; 1012 1013 if (log) 1014 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl); 1015} 1016 1017void 1018ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, 1019 Function* fun, 1020 Symbol* symbol) 1021{ 1022 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 1023 1024 NamedDecl *fun_decl; 1025 std::auto_ptr<Value> fun_location(new Value); 1026 const Address *fun_address; 1027 1028 // only valid for Functions, not for Symbols 1029 void *fun_opaque_type = NULL; 1030 clang::ASTContext *fun_ast_context = NULL; 1031 1032 if (fun) 1033 { 1034#define BROKEN_OVERLOADING 1035 // Awaiting a fix on the Clang side 1036#ifndef BROKEN_OVERLOADING 1037 Type *fun_type = fun->GetType(); 1038 1039 if (!fun_type) 1040 { 1041 if (log) 1042 log->PutCString("Skipped a function because it has no type"); 1043 return; 1044 } 1045 1046 fun_opaque_type = fun_type->GetClangType(); 1047 1048 if (!fun_opaque_type) 1049 { 1050 if (log) 1051 log->PutCString("Skipped a function because it has no Clang type"); 1052 return; 1053 } 1054 1055 fun_address = &fun->GetAddressRange().GetBaseAddress(); 1056 1057 TypeList *type_list = fun_type->GetTypeList(); 1058 fun_ast_context = type_list->GetClangASTContext().getASTContext(); 1059 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type); 1060 1061 fun_decl = context.AddFunDecl(copied_type); 1062#else 1063 fun_address = &fun->GetAddressRange().GetBaseAddress(); 1064 1065 fun_decl = context.AddGenericFunDecl(); 1066#endif 1067 } 1068 else if (symbol) 1069 { 1070 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress(); 1071 1072 fun_decl = context.AddGenericFunDecl(); 1073 } 1074 else 1075 { 1076 if (log) 1077 log->PutCString("AddOneFunction called with no function and no symbol"); 1078 return; 1079 } 1080 1081 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->target); 1082 fun_location->SetValueType(Value::eValueTypeLoadAddress); 1083 fun_location->GetScalar() = load_addr; 1084 1085 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); 1086 entity.m_name = context.Name.getAsString(); 1087 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);; 1088 1089 entity.EnableParserVars(); 1090 entity.m_parser_vars->m_named_decl = fun_decl; 1091 entity.m_parser_vars->m_llvm_value = NULL; 1092 entity.m_parser_vars->m_lldb_value = fun_location.release(); 1093 1094 if (log) 1095 log->Printf("Found %s function %s, returned (NamedDecl)%p", (fun ? "specific" : "generic"), context.Name.getAsString().c_str(), fun_decl); 1096} 1097 1098void 1099ClangExpressionDeclMap::AddOneType(NameSearchContext &context, 1100 TypeFromUser &ut, 1101 bool add_method) 1102{ 1103 clang::ASTContext *parser_ast_context = context.GetASTContext(); 1104 clang::ASTContext *user_ast_context = ut.GetASTContext(); 1105 1106 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType()); 1107 1108 TypeFromParser parser_type(copied_type, parser_ast_context); 1109 1110 if (add_method && ClangASTContext::IsAggregateType(copied_type)) 1111 { 1112 void *args[1]; 1113 1114 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false); 1115 1116 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context, 1117 ClangASTContext::GetBuiltInType_void(parser_ast_context), 1118 args, 1119 1, 1120 false, 1121 ClangASTContext::GetTypeQualifiers(copied_type)); 1122 1123 const bool is_virtual = false; 1124 const bool is_static = false; 1125 const bool is_inline = false; 1126 const bool is_explicit = false; 1127 1128 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context, 1129 copied_type, 1130 "___clang_expr", 1131 method_type, 1132 lldb::eAccessPublic, 1133 is_virtual, 1134 is_static, 1135 is_inline, 1136 is_explicit); 1137 } 1138 1139 context.AddTypeDecl(copied_type); 1140} 1141