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