ClangASTSource.cpp revision 269024
1//===-- ClangASTSource.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 11#include "clang/AST/ASTContext.h" 12#include "clang/AST/RecordLayout.h" 13#include "lldb/Core/Log.h" 14#include "lldb/Core/Module.h" 15#include "lldb/Core/ModuleList.h" 16#include "lldb/Expression/ASTDumper.h" 17#include "lldb/Expression/ClangASTSource.h" 18#include "lldb/Expression/ClangExpression.h" 19#include "lldb/Symbol/ClangNamespaceDecl.h" 20#include "lldb/Symbol/Function.h" 21#include "lldb/Symbol/SymbolVendor.h" 22#include "lldb/Target/ObjCLanguageRuntime.h" 23#include "lldb/Target/Target.h" 24 25using namespace clang; 26using namespace lldb_private; 27 28ClangASTSource::~ClangASTSource() 29{ 30 m_ast_importer->ForgetDestination(m_ast_context); 31 32 // We are in the process of destruction, don't create clang ast context on demand 33 // by passing false to Target::GetScratchClangASTContext(create_on_demand). 34 ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false); 35 36 if (!scratch_clang_ast_context) 37 return; 38 39 clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext(); 40 41 if (!scratch_ast_context) 42 return; 43 44 if (m_ast_context != scratch_ast_context) 45 m_ast_importer->ForgetSource(scratch_ast_context, m_ast_context); 46} 47 48void 49ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) 50{ 51 if (!m_ast_context) 52 return; 53 54 m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage(); 55 m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage(); 56} 57 58// The core lookup interface. 59bool 60ClangASTSource::FindExternalVisibleDeclsByName 61( 62 const DeclContext *decl_ctx, 63 DeclarationName clang_decl_name 64) 65{ 66 if (!m_ast_context) 67 { 68 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 69 return false; 70 } 71 72 if (GetImportInProgress()) 73 { 74 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 75 return false; 76 } 77 78 std::string decl_name (clang_decl_name.getAsString()); 79 80// if (m_decl_map.DoingASTImport ()) 81// return DeclContext::lookup_result(); 82// 83 switch (clang_decl_name.getNameKind()) { 84 // Normal identifiers. 85 case DeclarationName::Identifier: 86 { 87 clang::IdentifierInfo *identifier_info = clang_decl_name.getAsIdentifierInfo(); 88 89 if (!identifier_info || 90 identifier_info->getBuiltinID() != 0) 91 { 92 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 93 return false; 94 } 95 } 96 break; 97 98 // Operator names. Not important for now. 99 case DeclarationName::CXXOperatorName: 100 case DeclarationName::CXXLiteralOperatorName: 101 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 102 return false; 103 104 // Using directives found in this context. 105 // Tell Sema we didn't find any or we'll end up getting asked a *lot*. 106 case DeclarationName::CXXUsingDirective: 107 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 108 return false; 109 110 case DeclarationName::ObjCZeroArgSelector: 111 case DeclarationName::ObjCOneArgSelector: 112 case DeclarationName::ObjCMultiArgSelector: 113 { 114 llvm::SmallVector<NamedDecl*, 1> method_decls; 115 116 NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx); 117 118 FindObjCMethodDecls(method_search_context); 119 120 SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls); 121 return (method_decls.size() > 0); 122 } 123 // These aren't possible in the global context. 124 case DeclarationName::CXXConstructorName: 125 case DeclarationName::CXXDestructorName: 126 case DeclarationName::CXXConversionFunctionName: 127 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 128 return false; 129 } 130 131 132 if (!GetLookupsEnabled()) 133 { 134 // Wait until we see a '$' at the start of a name before we start doing 135 // any lookups so we can avoid lookup up all of the builtin types. 136 if (!decl_name.empty() && decl_name[0] == '$') 137 { 138 SetLookupsEnabled (true); 139 } 140 else 141 { 142 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 143 return false; 144 } 145 } 146 147 ConstString const_decl_name(decl_name.c_str()); 148 149 const char *uniqued_const_decl_name = const_decl_name.GetCString(); 150 if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end()) 151 { 152 // We are currently looking up this name... 153 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); 154 return false; 155 } 156 m_active_lookups.insert(uniqued_const_decl_name); 157// static uint32_t g_depth = 0; 158// ++g_depth; 159// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name); 160 llvm::SmallVector<NamedDecl*, 4> name_decls; 161 NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx); 162 FindExternalVisibleDecls(name_search_context); 163 SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls); 164// --g_depth; 165 m_active_lookups.erase (uniqued_const_decl_name); 166 return (name_decls.size() != 0); 167} 168 169void 170ClangASTSource::CompleteType (TagDecl *tag_decl) 171{ 172 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 173 174 static unsigned int invocation_id = 0; 175 unsigned int current_id = invocation_id++; 176 177 if (log) 178 { 179 log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s", 180 current_id, 181 m_ast_context, 182 tag_decl, 183 tag_decl->getName().str().c_str()); 184 185 log->Printf(" CTD[%u] Before:", current_id); 186 ASTDumper dumper((Decl*)tag_decl); 187 dumper.ToLog(log, " [CTD] "); 188 } 189 190 if (!m_ast_importer->CompleteTagDecl (tag_decl)) 191 { 192 // We couldn't complete the type. Maybe there's a definition 193 // somewhere else that can be completed. 194 195 if (log) 196 log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id); 197 198 bool found = false; 199 200 DeclContext *decl_ctx = tag_decl->getDeclContext(); 201 202 if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx)) 203 { 204 ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context); 205 206 if (log && log->GetVerbose()) 207 log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)", 208 current_id, 209 namespace_map.get(), 210 (int)namespace_map->size()); 211 212 if (!namespace_map) 213 return; 214 215 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); 216 i != e && !found; 217 ++i) 218 { 219 if (log) 220 log->Printf(" CTD[%u] Searching namespace %s in module %s", 221 current_id, 222 i->second.GetNamespaceDecl()->getNameAsString().c_str(), 223 i->first->GetFileSpec().GetFilename().GetCString()); 224 225 TypeList types; 226 227 SymbolContext null_sc; 228 ConstString name(tag_decl->getName().str().c_str()); 229 230 i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types); 231 232 for (uint32_t ti = 0, te = types.GetSize(); 233 ti != te && !found; 234 ++ti) 235 { 236 lldb::TypeSP type = types.GetTypeAtIndex(ti); 237 238 if (!type) 239 continue; 240 241 ClangASTType clang_type (type->GetClangFullType()); 242 243 if (!clang_type) 244 continue; 245 246 const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>(); 247 248 if (!tag_type) 249 continue; 250 251 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl()); 252 253 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) 254 found = true; 255 } 256 } 257 } 258 else 259 { 260 TypeList types; 261 262 SymbolContext null_sc; 263 ConstString name(tag_decl->getName().str().c_str()); 264 ClangNamespaceDecl namespace_decl; 265 266 const ModuleList &module_list = m_target->GetImages(); 267 268 bool exact_match = false; 269 module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, types); 270 271 for (uint32_t ti = 0, te = types.GetSize(); 272 ti != te && !found; 273 ++ti) 274 { 275 lldb::TypeSP type = types.GetTypeAtIndex(ti); 276 277 if (!type) 278 continue; 279 280 ClangASTType clang_type (type->GetClangFullType()); 281 282 if (!clang_type) 283 continue; 284 285 const TagType *tag_type = clang_type.GetQualType()->getAs<TagType>(); 286 287 if (!tag_type) 288 continue; 289 290 TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl()); 291 292 if (m_ast_importer->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) 293 found = true; 294 } 295 } 296 } 297 298 if (log) 299 { 300 log->Printf(" [CTD] After:"); 301 ASTDumper dumper((Decl*)tag_decl); 302 dumper.ToLog(log, " [CTD] "); 303 } 304} 305 306void 307ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl) 308{ 309 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 310 311 if (log) 312 { 313 log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s", m_ast_context, interface_decl->getName().str().c_str()); 314 log->Printf(" [COID] Before:"); 315 ASTDumper dumper((Decl*)interface_decl); 316 dumper.ToLog(log, " [COID] "); 317 } 318 319 m_ast_importer->CompleteObjCInterfaceDecl (interface_decl); 320 321 if (interface_decl->getSuperClass() && 322 interface_decl->getSuperClass() != interface_decl) 323 CompleteType(interface_decl->getSuperClass()); 324 325 if (log) 326 { 327 log->Printf(" [COID] After:"); 328 ASTDumper dumper((Decl*)interface_decl); 329 dumper.ToLog(log, " [COID] "); 330 } 331} 332 333clang::ObjCInterfaceDecl * 334ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl) 335{ 336 lldb::ProcessSP process(m_target->GetProcessSP()); 337 338 if (!process) 339 return NULL; 340 341 ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); 342 343 if (!language_runtime) 344 return NULL; 345 346 ConstString class_name(interface_decl->getNameAsString().c_str()); 347 348 lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name)); 349 350 if (!complete_type_sp) 351 return NULL; 352 353 TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType()); 354 lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType(); 355 356 if (!complete_opaque_type) 357 return NULL; 358 359 const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr(); 360 const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type); 361 362 if (!complete_interface_type) 363 return NULL; 364 365 ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl()); 366 367 return complete_iface_decl; 368} 369 370clang::ExternalLoadResult 371ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context, 372 bool (*predicate)(Decl::Kind), 373 llvm::SmallVectorImpl<Decl*> &decls) 374{ 375 ClangASTMetrics::RegisterLexicalQuery(); 376 377 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 378 379 const Decl *context_decl = dyn_cast<Decl>(decl_context); 380 381 if (!context_decl) 382 return ELR_Failure; 383 384 static unsigned int invocation_id = 0; 385 unsigned int current_id = invocation_id++; 386 387 if (log) 388 { 389 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) 390 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p with %s predicate", 391 current_id, 392 m_ast_context, 393 context_named_decl->getNameAsString().c_str(), 394 context_decl->getDeclKindName(), 395 context_decl, 396 (predicate ? "non-null" : "null")); 397 else if(context_decl) 398 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p with %s predicate", 399 current_id, 400 m_ast_context, 401 context_decl->getDeclKindName(), 402 context_decl, 403 (predicate ? "non-null" : "null")); 404 else 405 log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context with %s predicate", 406 current_id, 407 m_ast_context, 408 (predicate ? "non-null" : "null")); 409 } 410 411 Decl *original_decl = NULL; 412 ASTContext *original_ctx = NULL; 413 414 if (!m_ast_importer->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx)) 415 return ELR_Failure; 416 417 if (log) 418 { 419 log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id, original_ctx, original_decl); 420 ASTDumper(original_decl).ToLog(log, " "); 421 } 422 423 if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl)) 424 { 425 ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl); 426 427 if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) 428 { 429 original_decl = complete_iface_decl; 430 original_ctx = &complete_iface_decl->getASTContext(); 431 432 m_ast_importer->SetDeclOrigin(context_decl, original_iface_decl); 433 } 434 } 435 436 if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) 437 { 438 ExternalASTSource *external_source = original_ctx->getExternalSource(); 439 440 if (external_source) 441 external_source->CompleteType (original_tag_decl); 442 } 443 444 const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl); 445 446 if (!original_decl_context) 447 return ELR_Failure; 448 449 for (TagDecl::decl_iterator iter = original_decl_context->decls_begin(); 450 iter != original_decl_context->decls_end(); 451 ++iter) 452 { 453 Decl *decl = *iter; 454 455 if (!predicate || predicate(decl->getKind())) 456 { 457 if (log) 458 { 459 ASTDumper ast_dumper(decl); 460 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) 461 log->Printf(" FELD[%d] Adding [to %sDecl %s] lexical %sDecl %s", current_id, context_named_decl->getDeclKindName(), context_named_decl->getNameAsString().c_str(), decl->getDeclKindName(), ast_dumper.GetCString()); 462 else 463 log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString()); 464 } 465 466 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, original_ctx, decl); 467 468 if (!copied_decl) 469 continue; 470 471 if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) 472 { 473 QualType copied_field_type = copied_field->getType(); 474 475 m_ast_importer->RequireCompleteType(copied_field_type); 476 } 477 478 decls.push_back(copied_decl); 479 480 DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context); 481 482 if (copied_decl->getDeclContext() != decl_context) 483 { 484 if (copied_decl->getDeclContext()->containsDecl(copied_decl)) 485 copied_decl->getDeclContext()->removeDecl(copied_decl); 486 copied_decl->setDeclContext(decl_context_non_const); 487 } 488 489 if (!decl_context_non_const->containsDecl(copied_decl)) 490 decl_context_non_const->addDeclInternal(copied_decl); 491 } 492 } 493 494 return ELR_AlreadyLoaded; 495} 496 497void 498ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context) 499{ 500 assert (m_ast_context); 501 502 ClangASTMetrics::RegisterVisibleQuery(); 503 504 const ConstString name(context.m_decl_name.getAsString().c_str()); 505 506 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 507 508 static unsigned int invocation_id = 0; 509 unsigned int current_id = invocation_id++; 510 511 if (log) 512 { 513 if (!context.m_decl_context) 514 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext", current_id, m_ast_context, name.GetCString()); 515 else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context)) 516 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in '%s'", current_id, m_ast_context, name.GetCString(), context_named_decl->getNameAsString().c_str()); 517 else 518 log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a '%s'", current_id, m_ast_context, name.GetCString(), context.m_decl_context->getDeclKindName()); 519 } 520 521 context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap); 522 523 if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context)) 524 { 525 ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context); 526 527 if (log && log->GetVerbose()) 528 log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", 529 current_id, 530 namespace_map.get(), 531 (int)namespace_map->size()); 532 533 if (!namespace_map) 534 return; 535 536 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); 537 i != e; 538 ++i) 539 { 540 if (log) 541 log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s", 542 current_id, 543 i->second.GetNamespaceDecl()->getNameAsString().c_str(), 544 i->first->GetFileSpec().GetFilename().GetCString()); 545 546 FindExternalVisibleDecls(context, 547 i->first, 548 i->second, 549 current_id); 550 } 551 } 552 else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) 553 { 554 FindObjCPropertyAndIvarDecls(context); 555 } 556 else if (!isa<TranslationUnitDecl>(context.m_decl_context)) 557 { 558 // we shouldn't be getting FindExternalVisibleDecls calls for these 559 return; 560 } 561 else 562 { 563 ClangNamespaceDecl namespace_decl; 564 565 if (log) 566 log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id); 567 568 FindExternalVisibleDecls(context, 569 lldb::ModuleSP(), 570 namespace_decl, 571 current_id); 572 } 573 574 if (!context.m_namespace_map->empty()) 575 { 576 if (log && log->GetVerbose()) 577 log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)", 578 current_id, 579 context.m_namespace_map.get(), 580 (int)context.m_namespace_map->size()); 581 582 NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map); 583 584 if (clang_namespace_decl) 585 clang_namespace_decl->setHasExternalVisibleStorage(); 586 } 587} 588 589void 590ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, 591 lldb::ModuleSP module_sp, 592 ClangNamespaceDecl &namespace_decl, 593 unsigned int current_id) 594{ 595 assert (m_ast_context); 596 597 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 598 599 SymbolContextList sc_list; 600 601 const ConstString name(context.m_decl_name.getAsString().c_str()); 602 603 const char *name_unique_cstr = name.GetCString(); 604 605 static ConstString id_name("id"); 606 static ConstString Class_name("Class"); 607 608 if (name == id_name || name == Class_name) 609 return; 610 611 if (name_unique_cstr == NULL) 612 return; 613 614 // The ClangASTSource is not responsible for finding $-names. 615 if (name_unique_cstr[0] == '$') 616 return; 617 618 if (module_sp && namespace_decl) 619 { 620 ClangNamespaceDecl found_namespace_decl; 621 622 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); 623 624 if (symbol_vendor) 625 { 626 SymbolContext null_sc; 627 628 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); 629 630 if (found_namespace_decl) 631 { 632 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl)); 633 634 if (log) 635 log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", 636 current_id, 637 name.GetCString(), 638 module_sp->GetFileSpec().GetFilename().GetCString()); 639 } 640 } 641 } 642 else 643 { 644 const ModuleList &target_images = m_target->GetImages(); 645 Mutex::Locker modules_locker (target_images.GetMutex()); 646 647 for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) 648 { 649 lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); 650 651 if (!image) 652 continue; 653 654 ClangNamespaceDecl found_namespace_decl; 655 656 SymbolVendor *symbol_vendor = image->GetSymbolVendor(); 657 658 if (!symbol_vendor) 659 continue; 660 661 SymbolContext null_sc; 662 663 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); 664 665 if (found_namespace_decl) 666 { 667 context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl)); 668 669 if (log) 670 log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", 671 current_id, 672 name.GetCString(), 673 image->GetFileSpec().GetFilename().GetCString()); 674 } 675 } 676 } 677 678 do 679 { 680 TypeList types; 681 SymbolContext null_sc; 682 const bool exact_match = false; 683 684 if (module_sp && namespace_decl) 685 module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types); 686 else 687 m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, types); 688 689 if (types.GetSize()) 690 { 691 lldb::TypeSP type_sp = types.GetTypeAtIndex(0); 692 693 if (log) 694 { 695 const char *name_string = type_sp->GetName().GetCString(); 696 697 log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s", 698 current_id, 699 name.GetCString(), 700 (name_string ? name_string : "<anonymous>")); 701 } 702 703 ClangASTType full_type = type_sp->GetClangFullType(); 704 705 ClangASTType copied_clang_type (GuardedCopyType(full_type)); 706 707 if (!copied_clang_type) 708 { 709 if (log) 710 log->Printf(" CAS::FEVD[%u] - Couldn't export a type", 711 current_id); 712 713 break; 714 } 715 716 context.AddTypeDecl(copied_clang_type); 717 } 718 else 719 { 720 do 721 { 722 // Couldn't find any types elsewhere. Try the Objective-C runtime if one exists. 723 724 lldb::ProcessSP process(m_target->GetProcessSP()); 725 726 if (!process) 727 break; 728 729 ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); 730 731 if (!language_runtime) 732 break; 733 734 TypeVendor *type_vendor = language_runtime->GetTypeVendor(); 735 736 if (!type_vendor) 737 break; 738 739 bool append = false; 740 uint32_t max_matches = 1; 741 std::vector <ClangASTType> types; 742 743 if (!type_vendor->FindTypes(name, 744 append, 745 max_matches, 746 types)) 747 break; 748 749 if (log) 750 { 751 log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime", 752 current_id, 753 name.GetCString()); 754 } 755 756 ClangASTType copied_clang_type (GuardedCopyType(types[0])); 757 758 if (!copied_clang_type) 759 { 760 if (log) 761 log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime", 762 current_id); 763 764 break; 765 } 766 767 context.AddTypeDecl(copied_clang_type); 768 } 769 while(0); 770 } 771 772 } while(0); 773} 774 775template <class D> class TaggedASTDecl { 776public: 777 TaggedASTDecl() : decl(NULL) { } 778 TaggedASTDecl(D *_decl) : decl(_decl) { } 779 bool IsValid() const { return (decl != NULL); } 780 bool IsInvalid() const { return !IsValid(); } 781 D *operator->() const { return decl; } 782 D *decl; 783}; 784 785template <class D2, template <class D> class TD, class D1> 786TD<D2> 787DynCast(TD<D1> source) 788{ 789 return TD<D2> (dyn_cast<D2>(source.decl)); 790} 791 792template <class D = Decl> class DeclFromParser; 793template <class D = Decl> class DeclFromUser; 794 795template <class D> class DeclFromParser : public TaggedASTDecl<D> { 796public: 797 DeclFromParser() : TaggedASTDecl<D>() { } 798 DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { } 799 800 DeclFromUser<D> GetOrigin(ClangASTImporter *importer); 801}; 802 803template <class D> class DeclFromUser : public TaggedASTDecl<D> { 804public: 805 DeclFromUser() : TaggedASTDecl<D>() { } 806 DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { } 807 808 DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx); 809}; 810 811template <class D> 812DeclFromUser<D> 813DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) 814{ 815 DeclFromUser <> origin_decl; 816 importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL); 817 if (origin_decl.IsInvalid()) 818 return DeclFromUser<D>(); 819 return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl)); 820} 821 822template <class D> 823DeclFromParser<D> 824DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx) 825{ 826 DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl)); 827 if (parser_generic_decl.IsInvalid()) 828 return DeclFromParser<D>(); 829 return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl)); 830} 831 832static bool 833FindObjCMethodDeclsWithOrigin (unsigned int current_id, 834 NameSearchContext &context, 835 ObjCInterfaceDecl *original_interface_decl, 836 clang::ASTContext *ast_context, 837 ClangASTImporter *ast_importer, 838 const char *log_info) 839{ 840 const DeclarationName &decl_name(context.m_decl_name); 841 clang::ASTContext *original_ctx = &original_interface_decl->getASTContext(); 842 843 Selector original_selector; 844 845 if (decl_name.isObjCZeroArgSelector()) 846 { 847 IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString()); 848 original_selector = original_ctx->Selectors.getSelector(0, &ident); 849 } 850 else if (decl_name.isObjCOneArgSelector()) 851 { 852 const std::string &decl_name_string = decl_name.getAsString(); 853 std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1); 854 IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str()); 855 original_selector = original_ctx->Selectors.getSelector(1, &ident); 856 } 857 else 858 { 859 SmallVector<IdentifierInfo *, 4> idents; 860 861 clang::Selector sel = decl_name.getObjCSelector(); 862 863 unsigned num_args = sel.getNumArgs(); 864 865 for (unsigned i = 0; 866 i != num_args; 867 ++i) 868 { 869 idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i))); 870 } 871 872 original_selector = original_ctx->Selectors.getSelector(num_args, idents.data()); 873 } 874 875 DeclarationName original_decl_name(original_selector); 876 877 ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name); 878 879 if (result.empty()) 880 return false; 881 882 if (!result[0]) 883 return false; 884 885 for (NamedDecl *named_decl : result) 886 { 887 ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl); 888 889 if (!result_method) 890 return false; 891 892 Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method); 893 894 if (!copied_decl) 895 return false; 896 897 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl); 898 899 if (!copied_method_decl) 900 return false; 901 902 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 903 904 if (log) 905 { 906 ASTDumper dumper((Decl*)copied_method_decl); 907 log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString()); 908 } 909 910 context.AddNamedDecl(copied_method_decl); 911 } 912 913 return true; 914} 915 916void 917ClangASTSource::FindObjCMethodDecls (NameSearchContext &context) 918{ 919 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 920 921 static unsigned int invocation_id = 0; 922 unsigned int current_id = invocation_id++; 923 924 const DeclarationName &decl_name(context.m_decl_name); 925 const DeclContext *decl_ctx(context.m_decl_context); 926 927 const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx); 928 929 if (!interface_decl) 930 return; 931 932 do 933 { 934 Decl *original_decl = NULL; 935 ASTContext *original_ctx = NULL; 936 937 m_ast_importer->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx); 938 939 if (!original_decl) 940 break; 941 942 ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl); 943 944 if (FindObjCMethodDeclsWithOrigin(current_id, 945 context, 946 original_interface_decl, 947 m_ast_context, 948 m_ast_importer, 949 "at origin")) 950 return; // found it, no need to look any further 951 } while (0); 952 953 StreamString ss; 954 955 if (decl_name.isObjCZeroArgSelector()) 956 { 957 ss.Printf("%s", decl_name.getAsString().c_str()); 958 } 959 else if (decl_name.isObjCOneArgSelector()) 960 { 961 ss.Printf("%s", decl_name.getAsString().c_str()); 962 } 963 else 964 { 965 clang::Selector sel = decl_name.getObjCSelector(); 966 967 for (unsigned i = 0, e = sel.getNumArgs(); 968 i != e; 969 ++i) 970 { 971 llvm::StringRef r = sel.getNameForSlot(i); 972 ss.Printf("%s:", r.str().c_str()); 973 } 974 } 975 ss.Flush(); 976 977 if (strstr(ss.GetData(), "$__lldb")) 978 return; // we don't need any results 979 980 ConstString selector_name(ss.GetData()); 981 982 if (log) 983 log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]", 984 current_id, 985 m_ast_context, 986 interface_decl->getNameAsString().c_str(), 987 selector_name.AsCString()); 988 SymbolContextList sc_list; 989 990 const bool include_symbols = false; 991 const bool include_inlines = false; 992 const bool append = false; 993 994 std::string interface_name = interface_decl->getNameAsString(); 995 996 do 997 { 998 StreamString ms; 999 ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString()); 1000 ms.Flush(); 1001 ConstString instance_method_name(ms.GetData()); 1002 1003 m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list); 1004 1005 if (sc_list.GetSize()) 1006 break; 1007 1008 ms.Clear(); 1009 ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString()); 1010 ms.Flush(); 1011 ConstString class_method_name(ms.GetData()); 1012 1013 m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list); 1014 1015 if (sc_list.GetSize()) 1016 break; 1017 1018 // Fall back and check for methods in categories. If we find methods this way, we need to check that they're actually in 1019 // categories on the desired class. 1020 1021 SymbolContextList candidate_sc_list; 1022 1023 m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, candidate_sc_list); 1024 1025 for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); 1026 ci != ce; 1027 ++ci) 1028 { 1029 SymbolContext candidate_sc; 1030 1031 if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc)) 1032 continue; 1033 1034 if (!candidate_sc.function) 1035 continue; 1036 1037 const char *candidate_name = candidate_sc.function->GetName().AsCString(); 1038 1039 const char *cursor = candidate_name; 1040 1041 if (*cursor != '+' && *cursor != '-') 1042 continue; 1043 1044 ++cursor; 1045 1046 if (*cursor != '[') 1047 continue; 1048 1049 ++cursor; 1050 1051 size_t interface_len = interface_name.length(); 1052 1053 if (strncmp(cursor, interface_name.c_str(), interface_len)) 1054 continue; 1055 1056 cursor += interface_len; 1057 1058 if (*cursor == ' ' || *cursor == '(') 1059 sc_list.Append(candidate_sc); 1060 } 1061 } 1062 while (0); 1063 1064 if (sc_list.GetSize()) 1065 { 1066 // We found a good function symbol. Use that. 1067 1068 for (uint32_t i = 0, e = sc_list.GetSize(); 1069 i != e; 1070 ++i) 1071 { 1072 SymbolContext sc; 1073 1074 if (!sc_list.GetContextAtIndex(i, sc)) 1075 continue; 1076 1077 if (!sc.function) 1078 continue; 1079 1080 DeclContext *function_ctx = sc.function->GetClangDeclContext(); 1081 1082 if (!function_ctx) 1083 continue; 1084 1085 ObjCMethodDecl *method_decl = dyn_cast<ObjCMethodDecl>(function_ctx); 1086 1087 if (!method_decl) 1088 continue; 1089 1090 ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface(); 1091 1092 if (!found_interface_decl) 1093 continue; 1094 1095 if (found_interface_decl->getName() == interface_decl->getName()) 1096 { 1097 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl); 1098 1099 if (!copied_decl) 1100 continue; 1101 1102 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl); 1103 1104 if (!copied_method_decl) 1105 continue; 1106 1107 if (log) 1108 { 1109 ASTDumper dumper((Decl*)copied_method_decl); 1110 log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString()); 1111 } 1112 1113 context.AddNamedDecl(copied_method_decl); 1114 } 1115 } 1116 1117 return; 1118 } 1119 1120 // Try the debug information. 1121 1122 do 1123 { 1124 ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(interface_decl)); 1125 1126 if (!complete_interface_decl) 1127 break; 1128 1129 // We found the complete interface. The runtime never needs to be queried in this scenario. 1130 1131 DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl); 1132 1133 if (complete_interface_decl == interface_decl) 1134 break; // already checked this one 1135 1136 if (log) 1137 log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", 1138 current_id, 1139 complete_interface_decl, 1140 &complete_iface_decl->getASTContext()); 1141 1142 FindObjCMethodDeclsWithOrigin(current_id, 1143 context, 1144 complete_interface_decl, 1145 m_ast_context, 1146 m_ast_importer, 1147 "in debug info"); 1148 1149 return; 1150 } 1151 while (0); 1152 1153 do 1154 { 1155 // Check the runtime only if the debug information didn't have a complete interface. 1156 1157 lldb::ProcessSP process(m_target->GetProcessSP()); 1158 1159 if (!process) 1160 break; 1161 1162 ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); 1163 1164 if (!language_runtime) 1165 break; 1166 1167 TypeVendor *type_vendor = language_runtime->GetTypeVendor(); 1168 1169 if (!type_vendor) 1170 break; 1171 1172 ConstString interface_name(interface_decl->getNameAsString().c_str()); 1173 bool append = false; 1174 uint32_t max_matches = 1; 1175 std::vector <ClangASTType> types; 1176 1177 if (!type_vendor->FindTypes(interface_name, 1178 append, 1179 max_matches, 1180 types)) 1181 break; 1182 1183 const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr(); 1184 1185 const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type); 1186 1187 if (!runtime_interface_type) 1188 break; 1189 1190 ObjCInterfaceDecl *runtime_interface_decl = runtime_interface_type->getDecl(); 1191 1192 FindObjCMethodDeclsWithOrigin(current_id, 1193 context, 1194 runtime_interface_decl, 1195 m_ast_context, 1196 m_ast_importer, 1197 "in runtime"); 1198 } 1199 while(0); 1200} 1201 1202static bool 1203FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id, 1204 NameSearchContext &context, 1205 clang::ASTContext &ast_context, 1206 ClangASTImporter *ast_importer, 1207 DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) 1208{ 1209 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1210 1211 if (origin_iface_decl.IsInvalid()) 1212 return false; 1213 1214 std::string name_str = context.m_decl_name.getAsString(); 1215 StringRef name(name_str.c_str()); 1216 IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name)); 1217 1218 DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier)); 1219 1220 bool found = false; 1221 1222 if (origin_property_decl.IsValid()) 1223 { 1224 DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context)); 1225 if (parser_property_decl.IsValid()) 1226 { 1227 if (log) 1228 { 1229 ASTDumper dumper((Decl*)parser_property_decl.decl); 1230 log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString()); 1231 } 1232 1233 context.AddNamedDecl(parser_property_decl.decl); 1234 found = true; 1235 } 1236 } 1237 1238 DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier)); 1239 1240 if (origin_ivar_decl.IsValid()) 1241 { 1242 DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context)); 1243 if (parser_ivar_decl.IsValid()) 1244 { 1245 if (log) 1246 { 1247 ASTDumper dumper((Decl*)parser_ivar_decl.decl); 1248 log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString()); 1249 } 1250 1251 context.AddNamedDecl(parser_ivar_decl.decl); 1252 found = true; 1253 } 1254 } 1255 1256 return found; 1257} 1258 1259void 1260ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context) 1261{ 1262 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1263 1264 static unsigned int invocation_id = 0; 1265 unsigned int current_id = invocation_id++; 1266 1267 DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context)); 1268 DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer)); 1269 1270 ConstString class_name(parser_iface_decl->getNameAsString().c_str()); 1271 1272 if (log) 1273 log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'", 1274 current_id, 1275 m_ast_context, 1276 parser_iface_decl->getNameAsString().c_str(), 1277 context.m_decl_name.getAsString().c_str()); 1278 1279 if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 1280 context, 1281 *m_ast_context, 1282 m_ast_importer, 1283 origin_iface_decl)) 1284 return; 1285 1286 if (log) 1287 log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...", 1288 current_id, 1289 origin_iface_decl.decl, 1290 &origin_iface_decl->getASTContext()); 1291 1292 SymbolContext null_sc; 1293 TypeList type_list; 1294 1295 do 1296 { 1297 ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl)); 1298 1299 if (!complete_interface_decl) 1300 break; 1301 1302 // We found the complete interface. The runtime never needs to be queried in this scenario. 1303 1304 DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl); 1305 1306 if (complete_iface_decl.decl == origin_iface_decl.decl) 1307 break; // already checked this one 1308 1309 if (log) 1310 log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", 1311 current_id, 1312 complete_iface_decl.decl, 1313 &complete_iface_decl->getASTContext()); 1314 1315 FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 1316 context, 1317 *m_ast_context, 1318 m_ast_importer, 1319 complete_iface_decl); 1320 1321 return; 1322 } 1323 while(0); 1324 1325 do 1326 { 1327 // Check the runtime only if the debug information didn't have a complete interface. 1328 1329 lldb::ProcessSP process(m_target->GetProcessSP()); 1330 1331 if (!process) 1332 return; 1333 1334 ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); 1335 1336 if (!language_runtime) 1337 return; 1338 1339 TypeVendor *type_vendor = language_runtime->GetTypeVendor(); 1340 1341 if (!type_vendor) 1342 break; 1343 1344 bool append = false; 1345 uint32_t max_matches = 1; 1346 std::vector <ClangASTType> types; 1347 1348 if (!type_vendor->FindTypes(class_name, 1349 append, 1350 max_matches, 1351 types)) 1352 break; 1353 1354 const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr(); 1355 1356 const ObjCInterfaceType *runtime_interface_type = dyn_cast<ObjCInterfaceType>(runtime_clang_type); 1357 1358 if (!runtime_interface_type) 1359 break; 1360 1361 DeclFromUser<const ObjCInterfaceDecl> runtime_iface_decl(runtime_interface_type->getDecl()); 1362 1363 if (log) 1364 log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", 1365 current_id, 1366 runtime_iface_decl.decl, 1367 &runtime_iface_decl->getASTContext()); 1368 1369 if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 1370 context, 1371 *m_ast_context, 1372 m_ast_importer, 1373 runtime_iface_decl)) 1374 return; 1375 } 1376 while(0); 1377} 1378 1379typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap; 1380typedef llvm::DenseMap <const CXXRecordDecl *, CharUnits> BaseOffsetMap; 1381 1382template <class D, class O> 1383static bool 1384ImportOffsetMap (llvm::DenseMap <const D*, O> &destination_map, 1385 llvm::DenseMap <const D*, O> &source_map, 1386 ClangASTImporter *importer, 1387 ASTContext &dest_ctx) 1388{ 1389 typedef llvm::DenseMap <const D*, O> MapType; 1390 1391 for (typename MapType::iterator fi = source_map.begin(), fe = source_map.end(); 1392 fi != fe; 1393 ++fi) 1394 { 1395 DeclFromUser <D> user_decl(const_cast<D*>(fi->first)); 1396 DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx)); 1397 if (parser_decl.IsInvalid()) 1398 return false; 1399 destination_map.insert(std::pair<const D *, O>(parser_decl.decl, fi->second)); 1400 } 1401 1402 return true; 1403} 1404 1405template <bool IsVirtual> bool ExtractBaseOffsets (const ASTRecordLayout &record_layout, 1406 DeclFromUser<const CXXRecordDecl> &record, 1407 BaseOffsetMap &base_offsets) 1408{ 1409 for (CXXRecordDecl::base_class_const_iterator 1410 bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()), 1411 be = (IsVirtual ? record->vbases_end() : record->bases_end()); 1412 bi != be; 1413 ++bi) 1414 { 1415 if (!IsVirtual && bi->isVirtual()) 1416 continue; 1417 1418 const clang::Type *origin_base_type = bi->getType().getTypePtr(); 1419 const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>(); 1420 1421 if (!origin_base_record_type) 1422 return false; 1423 1424 DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl()); 1425 1426 if (origin_base_record.IsInvalid()) 1427 return false; 1428 1429 DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record)); 1430 1431 if (origin_base_cxx_record.IsInvalid()) 1432 return false; 1433 1434 CharUnits base_offset; 1435 1436 if (IsVirtual) 1437 base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl); 1438 else 1439 base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl); 1440 1441 base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset)); 1442 } 1443 1444 return true; 1445} 1446 1447bool 1448ClangASTSource::layoutRecordType(const RecordDecl *record, 1449 uint64_t &size, 1450 uint64_t &alignment, 1451 FieldOffsetMap &field_offsets, 1452 BaseOffsetMap &base_offsets, 1453 BaseOffsetMap &virtual_base_offsets) 1454{ 1455 ClangASTMetrics::RegisterRecordLayout(); 1456 1457 static unsigned int invocation_id = 0; 1458 unsigned int current_id = invocation_id++; 1459 1460 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1461 1462 if (log) 1463 { 1464 log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']", 1465 current_id, 1466 m_ast_context, 1467 record, 1468 record->getNameAsString().c_str()); 1469 } 1470 1471 1472 DeclFromParser <const RecordDecl> parser_record(record); 1473 DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer)); 1474 1475 if (origin_record.IsInvalid()) 1476 return false; 1477 1478 FieldOffsetMap origin_field_offsets; 1479 BaseOffsetMap origin_base_offsets; 1480 BaseOffsetMap origin_virtual_base_offsets; 1481 1482 ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl)); 1483 1484 if (!origin_record.decl->getDefinition()) 1485 return false; 1486 1487 const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl)); 1488 1489 int field_idx = 0, field_count = record_layout.getFieldCount(); 1490 1491 for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end(); 1492 fi != fe; 1493 ++fi) 1494 { 1495 if (field_idx >= field_count) 1496 return false; // Layout didn't go well. Bail out. 1497 1498 uint64_t field_offset = record_layout.getFieldOffset(field_idx); 1499 1500 origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset)); 1501 1502 field_idx++; 1503 } 1504 1505 ASTContext &parser_ast_context(record->getASTContext()); 1506 1507 DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record)); 1508 1509 if (origin_cxx_record.IsValid()) 1510 { 1511 if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) || 1512 !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets)) 1513 return false; 1514 } 1515 1516 if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer, parser_ast_context) || 1517 !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer, parser_ast_context) || 1518 !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer, parser_ast_context)) 1519 return false; 1520 1521 size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth(); 1522 alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth(); 1523 1524 if (log) 1525 { 1526 log->Printf("LRT[%u] returned:", current_id); 1527 log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, origin_record.decl); 1528 log->Printf("LRT[%u] Size = %" PRId64, current_id, size); 1529 log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment); 1530 log->Printf("LRT[%u] Fields:", current_id); 1531 for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end(); 1532 fi != fe; 1533 ++fi) 1534 { 1535 log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits", 1536 current_id, 1537 *fi, 1538 fi->getNameAsString().c_str(), 1539 field_offsets[*fi]); 1540 } 1541 DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record); 1542 if (parser_cxx_record.IsValid()) 1543 { 1544 log->Printf("LRT[%u] Bases:", current_id); 1545 for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end(); 1546 bi != be; 1547 ++bi) 1548 { 1549 bool is_virtual = bi->isVirtual(); 1550 1551 QualType base_type = bi->getType(); 1552 const RecordType *base_record_type = base_type->getAs<RecordType>(); 1553 DeclFromParser <RecordDecl> base_record(base_record_type->getDecl()); 1554 DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record); 1555 1556 log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", 1557 current_id, 1558 (is_virtual ? "Virtual " : ""), 1559 base_cxx_record.decl, 1560 base_cxx_record.decl->getNameAsString().c_str(), 1561 (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() : 1562 base_offsets[base_cxx_record.decl].getQuantity())); 1563 } 1564 } 1565 else 1566 { 1567 log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id); 1568 } 1569 } 1570 1571 return true; 1572} 1573 1574void 1575ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map, 1576 const ConstString &name, 1577 ClangASTImporter::NamespaceMapSP &parent_map) const 1578{ 1579 static unsigned int invocation_id = 0; 1580 unsigned int current_id = invocation_id++; 1581 1582 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1583 1584 if (log) 1585 { 1586 if (parent_map && parent_map->size()) 1587 log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s", 1588 current_id, 1589 m_ast_context, 1590 name.GetCString(), 1591 parent_map->begin()->second.GetNamespaceDecl()->getDeclName().getAsString().c_str()); 1592 else 1593 log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s", 1594 current_id, 1595 m_ast_context, 1596 name.GetCString()); 1597 } 1598 1599 1600 if (parent_map) 1601 { 1602 for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end(); 1603 i != e; 1604 ++i) 1605 { 1606 ClangNamespaceDecl found_namespace_decl; 1607 1608 lldb::ModuleSP module_sp = i->first; 1609 ClangNamespaceDecl module_parent_namespace_decl = i->second; 1610 1611 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); 1612 1613 if (!symbol_vendor) 1614 continue; 1615 1616 SymbolContext null_sc; 1617 1618 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl); 1619 1620 if (!found_namespace_decl) 1621 continue; 1622 1623 namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(module_sp, found_namespace_decl)); 1624 1625 if (log) 1626 log->Printf(" CMN[%u] Found namespace %s in module %s", 1627 current_id, 1628 name.GetCString(), 1629 module_sp->GetFileSpec().GetFilename().GetCString()); 1630 } 1631 } 1632 else 1633 { 1634 const ModuleList &target_images = m_target->GetImages(); 1635 Mutex::Locker modules_locker(target_images.GetMutex()); 1636 1637 ClangNamespaceDecl null_namespace_decl; 1638 1639 for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) 1640 { 1641 lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); 1642 1643 if (!image) 1644 continue; 1645 1646 ClangNamespaceDecl found_namespace_decl; 1647 1648 SymbolVendor *symbol_vendor = image->GetSymbolVendor(); 1649 1650 if (!symbol_vendor) 1651 continue; 1652 1653 SymbolContext null_sc; 1654 1655 found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl); 1656 1657 if (!found_namespace_decl) 1658 continue; 1659 1660 namespace_map->push_back(std::pair<lldb::ModuleSP, ClangNamespaceDecl>(image, found_namespace_decl)); 1661 1662 if (log) 1663 log->Printf(" CMN[%u] Found namespace %s in module %s", 1664 current_id, 1665 name.GetCString(), 1666 image->GetFileSpec().GetFilename().GetCString()); 1667 } 1668 } 1669} 1670 1671NamespaceDecl * 1672ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls) 1673{ 1674 if (!namespace_decls) 1675 return NULL; 1676 1677 const ClangNamespaceDecl &namespace_decl = namespace_decls->begin()->second; 1678 1679 Decl *copied_decl = m_ast_importer->CopyDecl(m_ast_context, namespace_decl.GetASTContext(), namespace_decl.GetNamespaceDecl()); 1680 1681 if (!copied_decl) 1682 return NULL; 1683 1684 NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl); 1685 1686 if (!copied_namespace_decl) 1687 return NULL; 1688 1689 context.m_decls.push_back(copied_namespace_decl); 1690 1691 m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls); 1692 1693 return dyn_cast<NamespaceDecl>(copied_decl); 1694} 1695 1696ClangASTType 1697ClangASTSource::GuardedCopyType (const ClangASTType &src_type) 1698{ 1699 ClangASTMetrics::RegisterLLDBImport(); 1700 1701 SetImportInProgress(true); 1702 1703 QualType copied_qual_type = m_ast_importer->CopyType (m_ast_context, src_type.GetASTContext(), src_type.GetQualType()); 1704 1705 SetImportInProgress(false); 1706 1707 if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull()) 1708 // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types 1709 // on occasion. 1710 return ClangASTType(); 1711 1712 return ClangASTType(m_ast_context, copied_qual_type); 1713} 1714 1715clang::NamedDecl * 1716NameSearchContext::AddVarDecl(const ClangASTType &type) 1717{ 1718 assert (type && "Type for variable must be valid!"); 1719 1720 if (!type.IsValid()) 1721 return NULL; 1722 1723 IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo(); 1724 1725 clang::ASTContext *ast = type.GetASTContext(); 1726 1727 clang::NamedDecl *Decl = VarDecl::Create(*ast, 1728 const_cast<DeclContext*>(m_decl_context), 1729 SourceLocation(), 1730 SourceLocation(), 1731 ii, 1732 type.GetQualType(), 1733 0, 1734 SC_Static); 1735 m_decls.push_back(Decl); 1736 1737 return Decl; 1738} 1739 1740clang::NamedDecl * 1741NameSearchContext::AddFunDecl (const ClangASTType &type) 1742{ 1743 assert (type && "Type for variable must be valid!"); 1744 1745 if (!type.IsValid()) 1746 return NULL; 1747 1748 if (m_function_types.count(type)) 1749 return NULL; 1750 1751 m_function_types.insert(type); 1752 1753 QualType qual_type (type.GetQualType()); 1754 1755 clang::ASTContext *ast = type.GetASTContext(); 1756 1757 const bool isInlineSpecified = false; 1758 const bool hasWrittenPrototype = true; 1759 const bool isConstexprSpecified = false; 1760 1761 clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast, 1762 const_cast<DeclContext*>(m_decl_context), 1763 SourceLocation(), 1764 SourceLocation(), 1765 m_decl_name.getAsIdentifierInfo(), 1766 qual_type, 1767 NULL, 1768 SC_Static, 1769 isInlineSpecified, 1770 hasWrittenPrototype, 1771 isConstexprSpecified); 1772 1773 // We have to do more than just synthesize the FunctionDecl. We have to 1774 // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do 1775 // this, we raid the function's FunctionProtoType for types. 1776 1777 const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>(); 1778 1779 if (func_proto_type) 1780 { 1781 unsigned NumArgs = func_proto_type->getNumArgs(); 1782 unsigned ArgIndex; 1783 1784 SmallVector<ParmVarDecl *, 5> parm_var_decls; 1785 1786 for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) 1787 { 1788 QualType arg_qual_type (func_proto_type->getArgType(ArgIndex)); 1789 1790 parm_var_decls.push_back(ParmVarDecl::Create (*ast, 1791 const_cast<DeclContext*>(m_decl_context), 1792 SourceLocation(), 1793 SourceLocation(), 1794 NULL, 1795 arg_qual_type, 1796 NULL, 1797 SC_Static, 1798 NULL)); 1799 } 1800 1801 func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls)); 1802 } 1803 else 1804 { 1805 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1806 1807 if (log) 1808 log->Printf("Function type wasn't a FunctionProtoType"); 1809 } 1810 1811 m_decls.push_back(func_decl); 1812 1813 return func_decl; 1814} 1815 1816clang::NamedDecl * 1817NameSearchContext::AddGenericFunDecl() 1818{ 1819 FunctionProtoType::ExtProtoInfo proto_info; 1820 1821 proto_info.Variadic = true; 1822 1823 QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy, // result 1824 ArrayRef<QualType>(), // argument types 1825 proto_info)); 1826 1827 return AddFunDecl(ClangASTType (m_ast_source.m_ast_context, generic_function_type)); 1828} 1829 1830clang::NamedDecl * 1831NameSearchContext::AddTypeDecl(const ClangASTType &clang_type) 1832{ 1833 if (clang_type) 1834 { 1835 QualType qual_type = clang_type.GetQualType(); 1836 1837 if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type)) 1838 { 1839 TypedefNameDecl *typedef_name_decl = typedef_type->getDecl(); 1840 1841 m_decls.push_back(typedef_name_decl); 1842 1843 return (NamedDecl*)typedef_name_decl; 1844 } 1845 else if (const TagType *tag_type = qual_type->getAs<TagType>()) 1846 { 1847 TagDecl *tag_decl = tag_type->getDecl(); 1848 1849 m_decls.push_back(tag_decl); 1850 1851 return tag_decl; 1852 } 1853 else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>()) 1854 { 1855 ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface(); 1856 1857 m_decls.push_back((NamedDecl*)interface_decl); 1858 1859 return (NamedDecl*)interface_decl; 1860 } 1861 } 1862 return NULL; 1863} 1864 1865void 1866NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result) 1867{ 1868 for (clang::NamedDecl *decl : result) 1869 m_decls.push_back (decl); 1870} 1871 1872void 1873NameSearchContext::AddNamedDecl (clang::NamedDecl *decl) 1874{ 1875 m_decls.push_back (decl); 1876} 1877