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