diff options
Diffstat (limited to 'source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp')
-rw-r--r-- | source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp | 3145 |
1 files changed, 1528 insertions, 1617 deletions
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index def0d42d32dd..0f08dd330e90 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -1,4 +1,4 @@ -//===-- ClangASTSource.cpp ---------------------------------------*- C++ -*-===// +//===-- ClangASTSource.cpp ---------------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -37,884 +37,833 @@ using namespace lldb_private; // when it goes out of scope. //------------------------------------------------------------------ namespace { - class ScopedLexicalDeclEraser - { - public: - ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls, - const clang::Decl *decl) - : m_active_lexical_decls(decls), m_decl(decl) - { - } +class ScopedLexicalDeclEraser { +public: + ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls, + const clang::Decl *decl) + : m_active_lexical_decls(decls), m_decl(decl) {} - ~ScopedLexicalDeclEraser() - { - m_active_lexical_decls.erase(m_decl); - } + ~ScopedLexicalDeclEraser() { m_active_lexical_decls.erase(m_decl); } - private: - std::set<const clang::Decl *> &m_active_lexical_decls; - const clang::Decl *m_decl; - }; +private: + std::set<const clang::Decl *> &m_active_lexical_decls; + const clang::Decl *m_decl; +}; } -ClangASTSource::~ClangASTSource() -{ - m_ast_importer_sp->ForgetDestination(m_ast_context); +ClangASTSource::~ClangASTSource() { + m_ast_importer_sp->ForgetDestination(m_ast_context); - // We are in the process of destruction, don't create clang ast context on demand - // by passing false to Target::GetScratchClangASTContext(create_on_demand). - ClangASTContext *scratch_clang_ast_context = m_target->GetScratchClangASTContext(false); + // We are in the process of destruction, don't create clang ast context on + // demand + // by passing false to Target::GetScratchClangASTContext(create_on_demand). + ClangASTContext *scratch_clang_ast_context = + m_target->GetScratchClangASTContext(false); - if (!scratch_clang_ast_context) - return; + if (!scratch_clang_ast_context) + return; - clang::ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext(); + clang::ASTContext *scratch_ast_context = + scratch_clang_ast_context->getASTContext(); - if (!scratch_ast_context) - return; + if (!scratch_ast_context) + return; - if (m_ast_context != scratch_ast_context) - m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context); + if (m_ast_context != scratch_ast_context) + m_ast_importer_sp->ForgetSource(scratch_ast_context, m_ast_context); } -void -ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) -{ - if (!m_ast_context) - return; +void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) { + if (!m_ast_context) + return; - m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage(); - m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage(); + m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage(); + m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage(); } // The core lookup interface. -bool -ClangASTSource::FindExternalVisibleDeclsByName -( - const DeclContext *decl_ctx, - DeclarationName clang_decl_name -) -{ - if (!m_ast_context) - { - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; +bool ClangASTSource::FindExternalVisibleDeclsByName( + const DeclContext *decl_ctx, DeclarationName clang_decl_name) { + if (!m_ast_context) { + SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); + return false; + } + + if (GetImportInProgress()) { + SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); + return false; + } + + std::string decl_name(clang_decl_name.getAsString()); + + // if (m_decl_map.DoingASTImport ()) + // return DeclContext::lookup_result(); + // + switch (clang_decl_name.getNameKind()) { + // Normal identifiers. + case DeclarationName::Identifier: { + clang::IdentifierInfo *identifier_info = + clang_decl_name.getAsIdentifierInfo(); + + if (!identifier_info || identifier_info->getBuiltinID() != 0) { + SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); + return false; } - - if (GetImportInProgress()) - { - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; + } break; + + // Operator names. + case DeclarationName::CXXOperatorName: + case DeclarationName::CXXLiteralOperatorName: + break; + + // Using directives found in this context. + // Tell Sema we didn't find any or we'll end up getting asked a *lot*. + case DeclarationName::CXXUsingDirective: + SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); + return false; + + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: { + llvm::SmallVector<NamedDecl *, 1> method_decls; + + NameSearchContext method_search_context(*this, method_decls, + clang_decl_name, decl_ctx); + + FindObjCMethodDecls(method_search_context); + + SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, method_decls); + return (method_decls.size() > 0); + } + // These aren't possible in the global context. + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); + return false; + } + + if (!GetLookupsEnabled()) { + // Wait until we see a '$' at the start of a name before we start doing + // any lookups so we can avoid lookup up all of the builtin types. + if (!decl_name.empty() && decl_name[0] == '$') { + SetLookupsEnabled(true); + } else { + SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); + return false; } + } + + ConstString const_decl_name(decl_name.c_str()); + + const char *uniqued_const_decl_name = const_decl_name.GetCString(); + if (m_active_lookups.find(uniqued_const_decl_name) != + m_active_lookups.end()) { + // We are currently looking up this name... + SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); + return false; + } + m_active_lookups.insert(uniqued_const_decl_name); + // static uint32_t g_depth = 0; + // ++g_depth; + // printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, + // uniqued_const_decl_name); + llvm::SmallVector<NamedDecl *, 4> name_decls; + NameSearchContext name_search_context(*this, name_decls, clang_decl_name, + decl_ctx); + FindExternalVisibleDecls(name_search_context); + SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls); + // --g_depth; + m_active_lookups.erase(uniqued_const_decl_name); + return (name_decls.size() != 0); +} - std::string decl_name (clang_decl_name.getAsString()); +void ClangASTSource::CompleteType(TagDecl *tag_decl) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); -// if (m_decl_map.DoingASTImport ()) -// return DeclContext::lookup_result(); -// - switch (clang_decl_name.getNameKind()) { - // Normal identifiers. - case DeclarationName::Identifier: - { - clang::IdentifierInfo *identifier_info = clang_decl_name.getAsIdentifierInfo(); - - if (!identifier_info || - identifier_info->getBuiltinID() != 0) - { - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; - } - } - break; + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; - // Operator names. - case DeclarationName::CXXOperatorName: - case DeclarationName::CXXLiteralOperatorName: - break; + if (log) { + log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing " + "(TagDecl*)%p named %s", + current_id, static_cast<void *>(m_ast_context), + static_cast<void *>(tag_decl), + tag_decl->getName().str().c_str()); - // Using directives found in this context. - // Tell Sema we didn't find any or we'll end up getting asked a *lot*. - case DeclarationName::CXXUsingDirective: - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; + log->Printf(" CTD[%u] Before:", current_id); + ASTDumper dumper((Decl *)tag_decl); + dumper.ToLog(log, " [CTD] "); + } - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - { - llvm::SmallVector<NamedDecl*, 1> method_decls; + auto iter = m_active_lexical_decls.find(tag_decl); + if (iter != m_active_lexical_decls.end()) + return; + m_active_lexical_decls.insert(tag_decl); + ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl); - NameSearchContext method_search_context (*this, method_decls, clang_decl_name, decl_ctx); + if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) { + // We couldn't complete the type. Maybe there's a definition + // somewhere else that can be completed. - FindObjCMethodDecls(method_search_context); + if (log) + log->Printf(" CTD[%u] Type could not be completed in the module in " + "which it was first found.", + current_id); - SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls); - return (method_decls.size() > 0); - } - // These aren't possible in the global context. - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; - } + bool found = false; + DeclContext *decl_ctx = tag_decl->getDeclContext(); - if (!GetLookupsEnabled()) - { - // Wait until we see a '$' at the start of a name before we start doing - // any lookups so we can avoid lookup up all of the builtin types. - if (!decl_name.empty() && decl_name[0] == '$') - { - SetLookupsEnabled (true); - } - else - { - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; - } - } + if (const NamespaceDecl *namespace_context = + dyn_cast<NamespaceDecl>(decl_ctx)) { + ClangASTImporter::NamespaceMapSP namespace_map = + m_ast_importer_sp->GetNamespaceMap(namespace_context); - ConstString const_decl_name(decl_name.c_str()); + if (log && log->GetVerbose()) + log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)", + current_id, static_cast<void *>(namespace_map.get()), + static_cast<int>(namespace_map->size())); - const char *uniqued_const_decl_name = const_decl_name.GetCString(); - if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end()) - { - // We are currently looking up this name... - SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name); - return false; - } - m_active_lookups.insert(uniqued_const_decl_name); -// static uint32_t g_depth = 0; -// ++g_depth; -// printf("[%5u] FindExternalVisibleDeclsByName() \"%s\"\n", g_depth, uniqued_const_decl_name); - llvm::SmallVector<NamedDecl*, 4> name_decls; - NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx); - FindExternalVisibleDecls(name_search_context); - SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls); -// --g_depth; - m_active_lookups.erase (uniqued_const_decl_name); - return (name_decls.size() != 0); -} + if (!namespace_map) + return; -void -ClangASTSource::CompleteType (TagDecl *tag_decl) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), + e = namespace_map->end(); + i != e && !found; ++i) { + if (log) + log->Printf(" CTD[%u] Searching namespace %s in module %s", + current_id, i->second.GetName().AsCString(), + i->first->GetFileSpec().GetFilename().GetCString()); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + TypeList types; - if (log) - { - log->Printf(" CompleteTagDecl[%u] on (ASTContext*)%p Completing (TagDecl*)%p named %s", - current_id, static_cast<void*>(m_ast_context), - static_cast<void*>(tag_decl), - tag_decl->getName().str().c_str()); - - log->Printf(" CTD[%u] Before:", current_id); - ASTDumper dumper((Decl*)tag_decl); - dumper.ToLog(log, " [CTD] "); - } + SymbolContext null_sc; + ConstString name(tag_decl->getName().str().c_str()); - auto iter = m_active_lexical_decls.find(tag_decl); - if (iter != m_active_lexical_decls.end()) - return; - m_active_lexical_decls.insert(tag_decl); - ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl); + i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, + types); - if (!m_ast_importer_sp->CompleteTagDecl (tag_decl)) - { - // We couldn't complete the type. Maybe there's a definition - // somewhere else that can be completed. + for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) { + lldb::TypeSP type = types.GetTypeAtIndex(ti); - if (log) - log->Printf(" CTD[%u] Type could not be completed in the module in which it was first found.", current_id); + if (!type) + continue; - bool found = false; + CompilerType clang_type(type->GetFullCompilerType()); - DeclContext *decl_ctx = tag_decl->getDeclContext(); + if (!ClangUtil::IsClangType(clang_type)) + continue; - if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(decl_ctx)) - { - ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context); + const TagType *tag_type = + ClangUtil::GetQualType(clang_type)->getAs<TagType>(); - if (log && log->GetVerbose()) - log->Printf(" CTD[%u] Inspecting namespace map %p (%d entries)", - current_id, static_cast<void*>(namespace_map.get()), - static_cast<int>(namespace_map->size())); + if (!tag_type) + continue; - if (!namespace_map) - return; + TagDecl *candidate_tag_decl = + const_cast<TagDecl *>(tag_type->getDecl()); - for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); - i != e && !found; - ++i) - { - if (log) - log->Printf(" CTD[%u] Searching namespace %s in module %s", - current_id, - i->second.GetName().AsCString(), - i->first->GetFileSpec().GetFilename().GetCString()); + if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, + candidate_tag_decl)) + found = true; + } + } + } else { + TypeList types; - TypeList types; + SymbolContext null_sc; + ConstString name(tag_decl->getName().str().c_str()); + CompilerDeclContext namespace_decl; - SymbolContext null_sc; - ConstString name(tag_decl->getName().str().c_str()); + const ModuleList &module_list = m_target->GetImages(); - i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, types); + bool exact_match = false; + llvm::DenseSet<SymbolFile *> searched_symbol_files; + module_list.FindTypes(null_sc, name, exact_match, UINT32_MAX, + searched_symbol_files, types); - for (uint32_t ti = 0, te = types.GetSize(); - ti != te && !found; - ++ti) - { - lldb::TypeSP type = types.GetTypeAtIndex(ti); + for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) { + lldb::TypeSP type = types.GetTypeAtIndex(ti); - if (!type) - continue; + if (!type) + continue; - CompilerType clang_type (type->GetFullCompilerType ()); + CompilerType clang_type(type->GetFullCompilerType()); - if (!ClangUtil::IsClangType(clang_type)) - continue; + if (!ClangUtil::IsClangType(clang_type)) + continue; - const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>(); + const TagType *tag_type = + ClangUtil::GetQualType(clang_type)->getAs<TagType>(); - if (!tag_type) - continue; + if (!tag_type) + continue; - TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl()); + TagDecl *candidate_tag_decl = + const_cast<TagDecl *>(tag_type->getDecl()); - if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) - found = true; - } - } - } - else - { - TypeList types; + // We have found a type by basename and we need to make sure the decl + // contexts + // are the same before we can try to complete this type with another + if (!ClangASTContext::DeclsAreEquivalent(tag_decl, candidate_tag_decl)) + continue; - SymbolContext null_sc; - ConstString name(tag_decl->getName().str().c_str()); - CompilerDeclContext namespace_decl; + if (m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, + candidate_tag_decl)) + found = true; + } + } + } - const ModuleList &module_list = m_target->GetImages(); + if (log) { + log->Printf(" [CTD] After:"); + ASTDumper dumper((Decl *)tag_decl); + dumper.ToLog(log, " [CTD] "); + } +} - bool exact_match = false; - llvm::DenseSet<SymbolFile *> searched_symbol_files; - module_list.FindTypes (null_sc, name, exact_match, UINT32_MAX, searched_symbol_files, types); +void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing " + "an ObjCInterfaceDecl named %s", + static_cast<void *>(m_ast_context), + interface_decl->getName().str().c_str()); + log->Printf(" [COID] Before:"); + ASTDumper dumper((Decl *)interface_decl); + dumper.ToLog(log, " [COID] "); + } + + Decl *original_decl = NULL; + ASTContext *original_ctx = NULL; + + if (m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, + &original_ctx)) { + if (ObjCInterfaceDecl *original_iface_decl = + dyn_cast<ObjCInterfaceDecl>(original_decl)) { + ObjCInterfaceDecl *complete_iface_decl = + GetCompleteObjCInterface(original_iface_decl); + + if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) { + m_ast_importer_sp->SetDeclOrigin(interface_decl, original_iface_decl); + } + } + } - for (uint32_t ti = 0, te = types.GetSize(); - ti != te && !found; - ++ti) - { - lldb::TypeSP type = types.GetTypeAtIndex(ti); + m_ast_importer_sp->CompleteObjCInterfaceDecl(interface_decl); - if (!type) - continue; + if (interface_decl->getSuperClass() && + interface_decl->getSuperClass() != interface_decl) + CompleteType(interface_decl->getSuperClass()); - CompilerType clang_type (type->GetFullCompilerType ()); + if (log) { + log->Printf(" [COID] After:"); + ASTDumper dumper((Decl *)interface_decl); + dumper.ToLog(log, " [COID] "); + } +} - if (!ClangUtil::IsClangType(clang_type)) - continue; +clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface( + clang::ObjCInterfaceDecl *interface_decl) { + lldb::ProcessSP process(m_target->GetProcessSP()); - const TagType *tag_type = ClangUtil::GetQualType(clang_type)->getAs<TagType>(); + if (!process) + return NULL; - if (!tag_type) - continue; + ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); - TagDecl *candidate_tag_decl = const_cast<TagDecl*>(tag_type->getDecl()); + if (!language_runtime) + return NULL; - // We have found a type by basename and we need to make sure the decl contexts - // are the same before we can try to complete this type with another - if (!ClangASTContext::DeclsAreEquivalent (tag_decl, candidate_tag_decl)) - continue; + ConstString class_name(interface_decl->getNameAsString().c_str()); - if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) - found = true; - } - } - } + lldb::TypeSP complete_type_sp( + language_runtime->LookupInCompleteClassCache(class_name)); - if (log) - { - log->Printf(" [CTD] After:"); - ASTDumper dumper((Decl*)tag_decl); - dumper.ToLog(log, " [CTD] "); - } -} + if (!complete_type_sp) + return NULL; -void -ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + TypeFromUser complete_type = + TypeFromUser(complete_type_sp->GetFullCompilerType()); + lldb::opaque_compiler_type_t complete_opaque_type = + complete_type.GetOpaqueQualType(); - if (log) - { - log->Printf(" [CompleteObjCInterfaceDecl] on (ASTContext*)%p Completing an ObjCInterfaceDecl named %s", - static_cast<void*>(m_ast_context), - interface_decl->getName().str().c_str()); - log->Printf(" [COID] Before:"); - ASTDumper dumper((Decl*)interface_decl); - dumper.ToLog(log, " [COID] "); - } + if (!complete_opaque_type) + return NULL; - Decl *original_decl = NULL; - ASTContext *original_ctx = NULL; + const clang::Type *complete_clang_type = + QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr(); + const ObjCInterfaceType *complete_interface_type = + dyn_cast<ObjCInterfaceType>(complete_clang_type); - if (m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx)) - { - if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl)) - { - ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl); + if (!complete_interface_type) + return NULL; - if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) - { - m_ast_importer_sp->SetDeclOrigin(interface_decl, original_iface_decl); - } - } - } + ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl()); - m_ast_importer_sp->CompleteObjCInterfaceDecl (interface_decl); + return complete_iface_decl; +} - if (interface_decl->getSuperClass() && - interface_decl->getSuperClass() != interface_decl) - CompleteType(interface_decl->getSuperClass()); +void ClangASTSource::FindExternalLexicalDecls( + const DeclContext *decl_context, + llvm::function_ref<bool(Decl::Kind)> predicate, + llvm::SmallVectorImpl<Decl *> &decls) { + ClangASTMetrics::RegisterLexicalQuery(); - if (log) - { - log->Printf(" [COID] After:"); - ASTDumper dumper((Decl*)interface_decl); - dumper.ToLog(log, " [COID] "); - } -} + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); -clang::ObjCInterfaceDecl * -ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl) -{ - lldb::ProcessSP process(m_target->GetProcessSP()); + const Decl *context_decl = dyn_cast<Decl>(decl_context); - if (!process) - return NULL; + if (!context_decl) + return; - ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); + auto iter = m_active_lexical_decls.find(context_decl); + if (iter != m_active_lexical_decls.end()) + return; + m_active_lexical_decls.insert(context_decl); + ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl); + + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; + + if (log) { + if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) + log->Printf( + "FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p", + current_id, static_cast<void *>(m_ast_context), + context_named_decl->getNameAsString().c_str(), + context_decl->getDeclKindName(), + static_cast<const void *>(context_decl)); + else if (context_decl) + log->Printf( + "FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p", + current_id, static_cast<void *>(m_ast_context), + context_decl->getDeclKindName(), + static_cast<const void *>(context_decl)); + else + log->Printf( + "FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context", + current_id, static_cast<const void *>(m_ast_context)); + } - if (!language_runtime) - return NULL; + Decl *original_decl = NULL; + ASTContext *original_ctx = NULL; - ConstString class_name(interface_decl->getNameAsString().c_str()); + if (!m_ast_importer_sp->ResolveDeclOrigin(context_decl, &original_decl, + &original_ctx)) + return; - lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name)); + if (log) { + log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", + current_id, static_cast<void *>(original_ctx), + static_cast<void *>(original_decl)); + ASTDumper(original_decl).ToLog(log, " "); + } - if (!complete_type_sp) - return NULL; + if (ObjCInterfaceDecl *original_iface_decl = + dyn_cast<ObjCInterfaceDecl>(original_decl)) { + ObjCInterfaceDecl *complete_iface_decl = + GetCompleteObjCInterface(original_iface_decl); - TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetFullCompilerType ()); - lldb::opaque_compiler_type_t complete_opaque_type = complete_type.GetOpaqueQualType(); + if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) { + original_decl = complete_iface_decl; + original_ctx = &complete_iface_decl->getASTContext(); - if (!complete_opaque_type) - return NULL; + m_ast_importer_sp->SetDeclOrigin(context_decl, original_iface_decl); + } + } - const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr(); - const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type); + if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) { + ExternalASTSource *external_source = original_ctx->getExternalSource(); - if (!complete_interface_type) - return NULL; + if (external_source) + external_source->CompleteType(original_tag_decl); + } - ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl()); + const DeclContext *original_decl_context = + dyn_cast<DeclContext>(original_decl); - return complete_iface_decl; -} + if (!original_decl_context) + return; + + for (TagDecl::decl_iterator iter = original_decl_context->decls_begin(); + iter != original_decl_context->decls_end(); ++iter) { + Decl *decl = *iter; + + if (predicate(decl->getKind())) { + if (log) { + ASTDumper ast_dumper(decl); + if (const NamedDecl *context_named_decl = + dyn_cast<NamedDecl>(context_decl)) + 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()); + else + log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, + decl->getDeclKindName(), ast_dumper.GetCString()); + } -void -ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context, - llvm::function_ref<bool(Decl::Kind)> predicate, - llvm::SmallVectorImpl<Decl*> &decls) -{ - ClangASTMetrics::RegisterLexicalQuery(); + Decl *copied_decl = + m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + if (!copied_decl) + continue; - const Decl *context_decl = dyn_cast<Decl>(decl_context); + if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) { + QualType copied_field_type = copied_field->getType(); - if (!context_decl) - return; + m_ast_importer_sp->RequireCompleteType(copied_field_type); + } - auto iter = m_active_lexical_decls.find(context_decl); - if (iter != m_active_lexical_decls.end()) - return; - m_active_lexical_decls.insert(context_decl); - ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl); + DeclContext *decl_context_non_const = + const_cast<DeclContext *>(decl_context); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + if (copied_decl->getDeclContext() != decl_context) { + if (copied_decl->getDeclContext()->containsDecl(copied_decl)) + copied_decl->getDeclContext()->removeDecl(copied_decl); + copied_decl->setDeclContext(decl_context_non_const); + } - if (log) - { - if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) - log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in '%s' (%sDecl*)%p", - current_id, static_cast<void*>(m_ast_context), - context_named_decl->getNameAsString().c_str(), - context_decl->getDeclKindName(), - static_cast<const void*>(context_decl)); - else if(context_decl) - log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in (%sDecl*)%p", - current_id, static_cast<void*>(m_ast_context), - context_decl->getDeclKindName(), - static_cast<const void*>(context_decl)); - else - log->Printf("FindExternalLexicalDecls[%u] on (ASTContext*)%p in a NULL context", - current_id, static_cast<const void*>(m_ast_context)); + if (!decl_context_non_const->containsDecl(copied_decl)) + decl_context_non_const->addDeclInternal(copied_decl); } + } - Decl *original_decl = NULL; - ASTContext *original_ctx = NULL; + return; +} - if (!m_ast_importer_sp->ResolveDeclOrigin(context_decl, &original_decl, &original_ctx)) - return; +void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) { + assert(m_ast_context); - if (log) - { - log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", - current_id, static_cast<void*>(original_ctx), - static_cast<void*>(original_decl)); - ASTDumper(original_decl).ToLog(log, " "); - } + ClangASTMetrics::RegisterVisibleQuery(); - if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl)) - { - ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl); + const ConstString name(context.m_decl_name.getAsString().c_str()); - if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) - { - original_decl = complete_iface_decl; - original_ctx = &complete_iface_decl->getASTContext(); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - m_ast_importer_sp->SetDeclOrigin(context_decl, original_iface_decl); - } + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; + + if (log) { + if (!context.m_decl_context) + log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on " + "(ASTContext*)%p for '%s' in a NULL DeclContext", + current_id, static_cast<void *>(m_ast_context), + name.GetCString()); + else if (const NamedDecl *context_named_decl = + dyn_cast<NamedDecl>(context.m_decl_context)) + log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on " + "(ASTContext*)%p for '%s' in '%s'", + current_id, static_cast<void *>(m_ast_context), + name.GetCString(), + context_named_decl->getNameAsString().c_str()); + else + log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on " + "(ASTContext*)%p for '%s' in a '%s'", + current_id, static_cast<void *>(m_ast_context), + name.GetCString(), context.m_decl_context->getDeclKindName()); + } + + context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap); + + if (const NamespaceDecl *namespace_context = + dyn_cast<NamespaceDecl>(context.m_decl_context)) { + ClangASTImporter::NamespaceMapSP namespace_map = + m_ast_importer_sp->GetNamespaceMap(namespace_context); + + if (log && log->GetVerbose()) + log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", + current_id, static_cast<void *>(namespace_map.get()), + static_cast<int>(namespace_map->size())); + + if (!namespace_map) + return; + + for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), + e = namespace_map->end(); + i != e; ++i) { + if (log) + log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s", + current_id, i->second.GetName().AsCString(), + i->first->GetFileSpec().GetFilename().GetCString()); + + FindExternalVisibleDecls(context, i->first, i->second, current_id); } + } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) { + FindObjCPropertyAndIvarDecls(context); + } else if (!isa<TranslationUnitDecl>(context.m_decl_context)) { + // we shouldn't be getting FindExternalVisibleDecls calls for these + return; + } else { + CompilerDeclContext namespace_decl; - if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl)) - { - ExternalASTSource *external_source = original_ctx->getExternalSource(); + if (log) + log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id); - if (external_source) - external_source->CompleteType (original_tag_decl); - } + FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, + current_id); + } - const DeclContext *original_decl_context = dyn_cast<DeclContext>(original_decl); + if (!context.m_namespace_map->empty()) { + if (log && log->GetVerbose()) + log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)", + current_id, + static_cast<void *>(context.m_namespace_map.get()), + static_cast<int>(context.m_namespace_map->size())); - if (!original_decl_context) - return; + NamespaceDecl *clang_namespace_decl = + AddNamespace(context, context.m_namespace_map); - for (TagDecl::decl_iterator iter = original_decl_context->decls_begin(); - iter != original_decl_context->decls_end(); - ++iter) - { - Decl *decl = *iter; - - if (predicate(decl->getKind())) - { - if (log) - { - ASTDumper ast_dumper(decl); - if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl)) - 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()); - else - log->Printf(" FELD[%d] Adding lexical %sDecl %s", current_id, decl->getDeclKindName(), ast_dumper.GetCString()); - } - - Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, original_ctx, decl); + if (clang_namespace_decl) + clang_namespace_decl->setHasExternalVisibleStorage(); + } +} - if (!copied_decl) - continue; +void ClangASTSource::FindExternalVisibleDecls( + NameSearchContext &context, lldb::ModuleSP module_sp, + CompilerDeclContext &namespace_decl, unsigned int current_id) { + assert(m_ast_context); - if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) - { - QualType copied_field_type = copied_field->getType(); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - m_ast_importer_sp->RequireCompleteType(copied_field_type); - } + SymbolContextList sc_list; - DeclContext *decl_context_non_const = const_cast<DeclContext *>(decl_context); + const ConstString name(context.m_decl_name.getAsString().c_str()); - if (copied_decl->getDeclContext() != decl_context) - { - if (copied_decl->getDeclContext()->containsDecl(copied_decl)) - copied_decl->getDeclContext()->removeDecl(copied_decl); - copied_decl->setDeclContext(decl_context_non_const); - } + const char *name_unique_cstr = name.GetCString(); - if (!decl_context_non_const->containsDecl(copied_decl)) - decl_context_non_const->addDeclInternal(copied_decl); - } - } + static ConstString id_name("id"); + static ConstString Class_name("Class"); + if (name == id_name || name == Class_name) return; -} -void -ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context) -{ - assert (m_ast_context); + if (name_unique_cstr == NULL) + return; - ClangASTMetrics::RegisterVisibleQuery(); + // The ClangASTSource is not responsible for finding $-names. + if (name_unique_cstr[0] == '$') + return; - const ConstString name(context.m_decl_name.getAsString().c_str()); + if (module_sp && namespace_decl) { + CompilerDeclContext found_namespace_decl; - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + if (symbol_vendor) { + SymbolContext null_sc; - if (log) - { - if (!context.m_decl_context) - log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a NULL DeclContext", - current_id, static_cast<void*>(m_ast_context), - name.GetCString()); - else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context)) - log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in '%s'", - current_id, static_cast<void*>(m_ast_context), - name.GetCString(), - context_named_decl->getNameAsString().c_str()); - else - log->Printf("ClangASTSource::FindExternalVisibleDecls[%u] on (ASTContext*)%p for '%s' in a '%s'", - current_id, static_cast<void*>(m_ast_context), - name.GetCString(), - context.m_decl_context->getDeclKindName()); - } + found_namespace_decl = + symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); - context.m_namespace_map.reset(new ClangASTImporter::NamespaceMap); - - if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context)) - { - ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer_sp->GetNamespaceMap(namespace_context); - - if (log && log->GetVerbose()) - log->Printf(" CAS::FEVD[%u] Inspecting namespace map %p (%d entries)", - current_id, static_cast<void*>(namespace_map.get()), - static_cast<int>(namespace_map->size())); - - if (!namespace_map) - return; - - for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); - i != e; - ++i) - { - if (log) - log->Printf(" CAS::FEVD[%u] Searching namespace %s in module %s", - current_id, - i->second.GetName().AsCString(), - i->first->GetFileSpec().GetFilename().GetCString()); - - FindExternalVisibleDecls(context, - i->first, - i->second, - current_id); - } - } - else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) - { - FindObjCPropertyAndIvarDecls(context); - } - else if (!isa<TranslationUnitDecl>(context.m_decl_context)) - { - // we shouldn't be getting FindExternalVisibleDecls calls for these - return; - } - else - { - CompilerDeclContext namespace_decl; + if (found_namespace_decl) { + context.m_namespace_map->push_back( + std::pair<lldb::ModuleSP, CompilerDeclContext>( + module_sp, found_namespace_decl)); if (log) - log->Printf(" CAS::FEVD[%u] Searching the root namespace", current_id); - - FindExternalVisibleDecls(context, - lldb::ModuleSP(), - namespace_decl, - current_id); + log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", + current_id, name.GetCString(), + module_sp->GetFileSpec().GetFilename().GetCString()); + } } + } else { + const ModuleList &target_images = m_target->GetImages(); + std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex()); + + for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) { + lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); + + if (!image) + continue; + + CompilerDeclContext found_namespace_decl; - if (!context.m_namespace_map->empty()) - { - if (log && log->GetVerbose()) - log->Printf(" CAS::FEVD[%u] Registering namespace map %p (%d entries)", - current_id, - static_cast<void*>(context.m_namespace_map.get()), - static_cast<int>(context.m_namespace_map->size())); + SymbolVendor *symbol_vendor = image->GetSymbolVendor(); - NamespaceDecl *clang_namespace_decl = AddNamespace(context, context.m_namespace_map); + if (!symbol_vendor) + continue; - if (clang_namespace_decl) - clang_namespace_decl->setHasExternalVisibleStorage(); + SymbolContext null_sc; + + found_namespace_decl = + symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); + + if (found_namespace_decl) { + context.m_namespace_map->push_back( + std::pair<lldb::ModuleSP, CompilerDeclContext>( + image, found_namespace_decl)); + + if (log) + log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", + current_id, name.GetCString(), + image->GetFileSpec().GetFilename().GetCString()); + } } -} + } -void -ClangASTSource::FindExternalVisibleDecls (NameSearchContext &context, - lldb::ModuleSP module_sp, - CompilerDeclContext &namespace_decl, - unsigned int current_id) -{ - assert (m_ast_context); + do { + if (context.m_found.type) + break; - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + TypeList types; + SymbolContext null_sc; + const bool exact_match = false; + llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files; + if (module_sp && namespace_decl) + module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types); + else + m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, + searched_symbol_files, types); - SymbolContextList sc_list; + if (size_t num_types = types.GetSize()) { + for (size_t ti = 0; ti < num_types; ++ti) { + lldb::TypeSP type_sp = types.GetTypeAtIndex(ti); - const ConstString name(context.m_decl_name.getAsString().c_str()); + if (log) { + const char *name_string = type_sp->GetName().GetCString(); - const char *name_unique_cstr = name.GetCString(); + log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s", + current_id, name.GetCString(), + (name_string ? name_string : "<anonymous>")); + } - static ConstString id_name("id"); - static ConstString Class_name("Class"); + CompilerType full_type = type_sp->GetFullCompilerType(); - if (name == id_name || name == Class_name) - return; + CompilerType copied_clang_type(GuardedCopyType(full_type)); - if (name_unique_cstr == NULL) - return; + if (!copied_clang_type) { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a type", current_id); - // The ClangASTSource is not responsible for finding $-names. - if (name_unique_cstr[0] == '$') - return; + continue; + } - if (module_sp && namespace_decl) - { - CompilerDeclContext found_namespace_decl; + context.AddTypeDecl(copied_clang_type); - SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); + context.m_found.type = true; + break; + } + } - if (symbol_vendor) - { - SymbolContext null_sc; + if (!context.m_found.type) { + // Try the modules next. - found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); + do { + if (ClangModulesDeclVendor *modules_decl_vendor = + m_target->GetClangModulesDeclVendor()) { + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; - if (found_namespace_decl) - { - context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(module_sp, found_namespace_decl)); + if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls)) + break; - if (log) - log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", - current_id, - name.GetCString(), - module_sp->GetFileSpec().GetFilename().GetCString()); + if (log) { + log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in " + "the modules", + current_id, name.GetCString()); + } + + clang::NamedDecl *const decl_from_modules = decls[0]; + + if (llvm::isa<clang::TypeDecl>(decl_from_modules) || + llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) || + llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) { + clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( + m_ast_context, &decl_from_modules->getASTContext(), + decl_from_modules); + clang::NamedDecl *copied_named_decl = + copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; + + if (!copied_named_decl) { + if (log) + log->Printf( + " CAS::FEVD[%u] - Couldn't export a type from the modules", + current_id); + + break; } + + context.AddNamedDecl(copied_named_decl); + + context.m_found.type = true; + } } + } while (0); } - else - { - const ModuleList &target_images = m_target->GetImages(); - std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex()); - for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) - { - lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); + if (!context.m_found.type) { + do { + // Couldn't find any types elsewhere. Try the Objective-C runtime if + // one exists. - if (!image) - continue; + lldb::ProcessSP process(m_target->GetProcessSP()); - CompilerDeclContext found_namespace_decl; + if (!process) + break; - SymbolVendor *symbol_vendor = image->GetSymbolVendor(); + ObjCLanguageRuntime *language_runtime( + process->GetObjCLanguageRuntime()); - if (!symbol_vendor) - continue; + if (!language_runtime) + break; - SymbolContext null_sc; + DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); - found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); + if (!decl_vendor) + break; - if (found_namespace_decl) - { - context.m_namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(image, found_namespace_decl)); + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; - if (log) - log->Printf(" CAS::FEVD[%u] Found namespace %s in module %s", - current_id, - name.GetCString(), - image->GetFileSpec().GetFilename().GetCString()); - } - } - } + if (!decl_vendor->FindDecls(name, append, max_matches, decls)) + break; - do - { - if (context.m_found.type) - break; - - TypeList types; - SymbolContext null_sc; - const bool exact_match = false; - llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files; - if (module_sp && namespace_decl) - module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types); - else - m_target->GetImages().FindTypes(null_sc, name, exact_match, 1, searched_symbol_files, types); - - if (size_t num_types = types.GetSize()) - { - for (size_t ti = 0; ti < num_types; ++ti) - { - lldb::TypeSP type_sp = types.GetTypeAtIndex(ti); - - if (log) - { - const char *name_string = type_sp->GetName().GetCString(); - - log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\": %s", - current_id, - name.GetCString(), - (name_string ? name_string : "<anonymous>")); - } - - CompilerType full_type = type_sp->GetFullCompilerType(); - - CompilerType copied_clang_type (GuardedCopyType(full_type)); - - if (!copied_clang_type) - { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a type", - current_id); - - continue; - } - - context.AddTypeDecl(copied_clang_type); - - context.m_found.type = true; - break; - } + if (log) { + log->Printf( + " CAS::FEVD[%u] Matching type found for \"%s\" in the runtime", + current_id, name.GetCString()); } - if (!context.m_found.type) - { - // Try the modules next. - - do - { - if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor()) - { - bool append = false; - uint32_t max_matches = 1; - std::vector <clang::NamedDecl *> decls; - - if (!modules_decl_vendor->FindDecls(name, - append, - max_matches, - decls)) - break; - - if (log) - { - log->Printf(" CAS::FEVD[%u] Matching entity found for \"%s\" in the modules", - current_id, - name.GetCString()); - } - - clang::NamedDecl *const decl_from_modules = decls[0]; - - if (llvm::isa<clang::TypeDecl>(decl_from_modules) || - llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) || - llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) - { - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decl_from_modules->getASTContext(), decl_from_modules); - clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; - - if (!copied_named_decl) - { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the modules", - current_id); - - break; - } - - context.AddNamedDecl(copied_named_decl); - - context.m_found.type = true; - } - } - } while (0); - } - - if (!context.m_found.type) - { - do - { - // Couldn't find any types elsewhere. Try the Objective-C runtime if one exists. - - lldb::ProcessSP process(m_target->GetProcessSP()); - - if (!process) - break; - - ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); - - if (!language_runtime) - break; - - DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); - - if (!decl_vendor) - break; - - bool append = false; - uint32_t max_matches = 1; - std::vector <clang::NamedDecl *> decls; - - if (!decl_vendor->FindDecls(name, - append, - max_matches, - decls)) - break; - - if (log) - { - log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime", - current_id, - name.GetCString()); - } - - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &decls[0]->getASTContext(), decls[0]); - clang::NamedDecl *copied_named_decl = copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; - - if (!copied_named_decl) - { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime", - current_id); - - break; - } - - context.AddNamedDecl(copied_named_decl); - } - while(0); + clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( + m_ast_context, &decls[0]->getASTContext(), decls[0]); + clang::NamedDecl *copied_named_decl = + copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr; + + if (!copied_named_decl) { + if (log) + log->Printf( + " CAS::FEVD[%u] - Couldn't export a type from the runtime", + current_id); + + break; } - } while(0); + context.AddNamedDecl(copied_named_decl); + } while (0); + } + + } while (0); } template <class D> class TaggedASTDecl { public: - TaggedASTDecl() : decl(NULL) { } - TaggedASTDecl(D *_decl) : decl(_decl) { } - bool IsValid() const { return (decl != NULL); } - bool IsInvalid() const { return !IsValid(); } - D *operator->() const { return decl; } - D *decl; + TaggedASTDecl() : decl(NULL) {} + TaggedASTDecl(D *_decl) : decl(_decl) {} + bool IsValid() const { return (decl != NULL); } + bool IsInvalid() const { return !IsValid(); } + D *operator->() const { return decl; } + D *decl; }; template <class D2, template <class D> class TD, class D1> -TD<D2> -DynCast(TD<D1> source) -{ - return TD<D2> (dyn_cast<D2>(source.decl)); +TD<D2> DynCast(TD<D1> source) { + return TD<D2>(dyn_cast<D2>(source.decl)); } template <class D = Decl> class DeclFromParser; @@ -922,1179 +871,1141 @@ template <class D = Decl> class DeclFromUser; template <class D> class DeclFromParser : public TaggedASTDecl<D> { public: - DeclFromParser() : TaggedASTDecl<D>() { } - DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) { } + DeclFromParser() : TaggedASTDecl<D>() {} + DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {} - DeclFromUser<D> GetOrigin(ClangASTImporter *importer); + DeclFromUser<D> GetOrigin(ClangASTImporter *importer); }; template <class D> class DeclFromUser : public TaggedASTDecl<D> { public: - DeclFromUser() : TaggedASTDecl<D>() { } - DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) { } + DeclFromUser() : TaggedASTDecl<D>() {} + DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {} - DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx); + DeclFromParser<D> Import(ClangASTImporter *importer, ASTContext &dest_ctx); }; template <class D> -DeclFromUser<D> -DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) -{ - DeclFromUser <> origin_decl; - importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL); - if (origin_decl.IsInvalid()) - return DeclFromUser<D>(); - return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl)); +DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTImporter *importer) { + DeclFromUser<> origin_decl; + importer->ResolveDeclOrigin(this->decl, &origin_decl.decl, NULL); + if (origin_decl.IsInvalid()) + return DeclFromUser<D>(); + return DeclFromUser<D>(dyn_cast<D>(origin_decl.decl)); } template <class D> -DeclFromParser<D> -DeclFromUser<D>::Import(ClangASTImporter *importer, ASTContext &dest_ctx) -{ - DeclFromParser <> parser_generic_decl(importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl)); - if (parser_generic_decl.IsInvalid()) - return DeclFromParser<D>(); - return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl)); +DeclFromParser<D> DeclFromUser<D>::Import(ClangASTImporter *importer, + ASTContext &dest_ctx) { + DeclFromParser<> parser_generic_decl( + importer->CopyDecl(&dest_ctx, &this->decl->getASTContext(), this->decl)); + if (parser_generic_decl.IsInvalid()) + return DeclFromParser<D>(); + return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl)); } -static bool -FindObjCMethodDeclsWithOrigin (unsigned int current_id, - NameSearchContext &context, - ObjCInterfaceDecl *original_interface_decl, - clang::ASTContext *ast_context, - ClangASTImporter *ast_importer, - const char *log_info) -{ - const DeclarationName &decl_name(context.m_decl_name); - clang::ASTContext *original_ctx = &original_interface_decl->getASTContext(); - - Selector original_selector; - - if (decl_name.isObjCZeroArgSelector()) - { - IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString()); - original_selector = original_ctx->Selectors.getSelector(0, &ident); - } - else if (decl_name.isObjCOneArgSelector()) - { - const std::string &decl_name_string = decl_name.getAsString(); - std::string decl_name_string_without_colon(decl_name_string.c_str(), decl_name_string.length() - 1); - IdentifierInfo *ident = &original_ctx->Idents.get(decl_name_string_without_colon.c_str()); - original_selector = original_ctx->Selectors.getSelector(1, &ident); +static bool FindObjCMethodDeclsWithOrigin( + unsigned int current_id, NameSearchContext &context, + ObjCInterfaceDecl *original_interface_decl, clang::ASTContext *ast_context, + ClangASTImporter *ast_importer, const char *log_info) { + const DeclarationName &decl_name(context.m_decl_name); + clang::ASTContext *original_ctx = &original_interface_decl->getASTContext(); + + Selector original_selector; + + if (decl_name.isObjCZeroArgSelector()) { + IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString()); + original_selector = original_ctx->Selectors.getSelector(0, &ident); + } else if (decl_name.isObjCOneArgSelector()) { + const std::string &decl_name_string = decl_name.getAsString(); + std::string decl_name_string_without_colon(decl_name_string.c_str(), + decl_name_string.length() - 1); + IdentifierInfo *ident = + &original_ctx->Idents.get(decl_name_string_without_colon); + original_selector = original_ctx->Selectors.getSelector(1, &ident); + } else { + SmallVector<IdentifierInfo *, 4> idents; + + clang::Selector sel = decl_name.getObjCSelector(); + + unsigned num_args = sel.getNumArgs(); + + for (unsigned i = 0; i != num_args; ++i) { + idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i))); } - else - { - SmallVector<IdentifierInfo *, 4> idents; - clang::Selector sel = decl_name.getObjCSelector(); + original_selector = + original_ctx->Selectors.getSelector(num_args, idents.data()); + } - unsigned num_args = sel.getNumArgs(); + DeclarationName original_decl_name(original_selector); - for (unsigned i = 0; - i != num_args; - ++i) - { - idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i))); - } + llvm::SmallVector<NamedDecl *, 1> methods; - original_selector = original_ctx->Selectors.getSelector(num_args, idents.data()); - } + ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl); - DeclarationName original_decl_name(original_selector); - - llvm::SmallVector<NamedDecl *, 1> methods; - - ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl); - - if (ObjCMethodDecl *instance_method_decl = original_interface_decl->lookupInstanceMethod(original_selector)) - { - methods.push_back(instance_method_decl); - } - else if (ObjCMethodDecl *class_method_decl = original_interface_decl->lookupClassMethod(original_selector)) - { - methods.push_back(class_method_decl); - } - - if (methods.empty()) - { - return false; - } - - for (NamedDecl *named_decl : methods) - { - if (!named_decl) - continue; - - ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl); + if (ObjCMethodDecl *instance_method_decl = + original_interface_decl->lookupInstanceMethod(original_selector)) { + methods.push_back(instance_method_decl); + } else if (ObjCMethodDecl *class_method_decl = + original_interface_decl->lookupClassMethod( + original_selector)) { + methods.push_back(class_method_decl); + } - if (!result_method) - continue; + if (methods.empty()) { + return false; + } - Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method); + for (NamedDecl *named_decl : methods) { + if (!named_decl) + continue; - if (!copied_decl) - continue; + ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl); - ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl); + if (!result_method) + continue; - if (!copied_method_decl) - continue; + Decl *copied_decl = ast_importer->CopyDecl( + ast_context, &result_method->getASTContext(), result_method); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + if (!copied_decl) + continue; - if (log) - { - ASTDumper dumper((Decl*)copied_method_decl); - log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, dumper.GetCString()); - } + ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl); - context.AddNamedDecl(copied_method_decl); + if (!copied_method_decl) + continue; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + ASTDumper dumper((Decl *)copied_method_decl); + log->Printf(" CAS::FOMD[%d] found (%s) %s", current_id, log_info, + dumper.GetCString()); } - return true; + context.AddNamedDecl(copied_method_decl); + } + + return true; } -void -ClangASTSource::FindObjCMethodDecls (NameSearchContext &context) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); +void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; - const DeclarationName &decl_name(context.m_decl_name); - const DeclContext *decl_ctx(context.m_decl_context); + const DeclarationName &decl_name(context.m_decl_name); + const DeclContext *decl_ctx(context.m_decl_context); - const ObjCInterfaceDecl *interface_decl = dyn_cast<ObjCInterfaceDecl>(decl_ctx); + const ObjCInterfaceDecl *interface_decl = + dyn_cast<ObjCInterfaceDecl>(decl_ctx); - if (!interface_decl) - return; + if (!interface_decl) + return; - do - { - Decl *original_decl = NULL; - ASTContext *original_ctx = NULL; + do { + Decl *original_decl = NULL; + ASTContext *original_ctx = NULL; - m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, &original_ctx); + m_ast_importer_sp->ResolveDeclOrigin(interface_decl, &original_decl, + &original_ctx); - if (!original_decl) - break; + if (!original_decl) + break; - ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl); + ObjCInterfaceDecl *original_interface_decl = + dyn_cast<ObjCInterfaceDecl>(original_decl); - if (FindObjCMethodDeclsWithOrigin(current_id, - context, - original_interface_decl, - m_ast_context, - m_ast_importer_sp.get(), - "at origin")) - return; // found it, no need to look any further - } while (0); + if (FindObjCMethodDeclsWithOrigin(current_id, context, + original_interface_decl, m_ast_context, + m_ast_importer_sp.get(), "at origin")) + return; // found it, no need to look any further + } while (0); - StreamString ss; + StreamString ss; - if (decl_name.isObjCZeroArgSelector()) - { - ss.Printf("%s", decl_name.getAsString().c_str()); - } - else if (decl_name.isObjCOneArgSelector()) - { - ss.Printf("%s", decl_name.getAsString().c_str()); - } - else - { - clang::Selector sel = decl_name.getObjCSelector(); - - for (unsigned i = 0, e = sel.getNumArgs(); - i != e; - ++i) - { - llvm::StringRef r = sel.getNameForSlot(i); - ss.Printf("%s:", r.str().c_str()); - } + if (decl_name.isObjCZeroArgSelector()) { + ss.Printf("%s", decl_name.getAsString().c_str()); + } else if (decl_name.isObjCOneArgSelector()) { + ss.Printf("%s", decl_name.getAsString().c_str()); + } else { + clang::Selector sel = decl_name.getObjCSelector(); + + for (unsigned i = 0, e = sel.getNumArgs(); i != e; ++i) { + llvm::StringRef r = sel.getNameForSlot(i); + ss.Printf("%s:", r.str().c_str()); } - ss.Flush(); + } + ss.Flush(); - if (strstr(ss.GetData(), "$__lldb")) - return; // we don't need any results + if (ss.GetString().contains("$__lldb")) + return; // we don't need any results - ConstString selector_name(ss.GetData()); + ConstString selector_name(ss.GetString()); - if (log) - log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p for selector [%s %s]", - current_id, static_cast<void*>(m_ast_context), - interface_decl->getNameAsString().c_str(), - selector_name.AsCString()); - SymbolContextList sc_list; + if (log) + log->Printf("ClangASTSource::FindObjCMethodDecls[%d] on (ASTContext*)%p " + "for selector [%s %s]", + current_id, static_cast<void *>(m_ast_context), + interface_decl->getNameAsString().c_str(), + selector_name.AsCString()); + SymbolContextList sc_list; - const bool include_symbols = false; - const bool include_inlines = false; - const bool append = false; + const bool include_symbols = false; + const bool include_inlines = false; + const bool append = false; - std::string interface_name = interface_decl->getNameAsString(); + std::string interface_name = interface_decl->getNameAsString(); - do - { - StreamString ms; - ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString()); - ms.Flush(); - ConstString instance_method_name(ms.GetData()); + do { + StreamString ms; + ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString()); + ms.Flush(); + ConstString instance_method_name(ms.GetString()); - m_target->GetImages().FindFunctions(instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list); + m_target->GetImages().FindFunctions( + instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, + include_inlines, append, sc_list); - if (sc_list.GetSize()) - break; + if (sc_list.GetSize()) + break; - ms.Clear(); - ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString()); - ms.Flush(); - ConstString class_method_name(ms.GetData()); + ms.Clear(); + ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString()); + ms.Flush(); + ConstString class_method_name(ms.GetString()); - m_target->GetImages().FindFunctions(class_method_name, lldb::eFunctionNameTypeFull, include_symbols, include_inlines, append, sc_list); + m_target->GetImages().FindFunctions( + class_method_name, lldb::eFunctionNameTypeFull, include_symbols, + include_inlines, append, sc_list); - if (sc_list.GetSize()) - break; + if (sc_list.GetSize()) + break; - // Fall back and check for methods in categories. If we find methods this way, we need to check that they're actually in - // categories on the desired class. + // Fall back and check for methods in categories. If we find methods this + // way, we need to check that they're actually in + // categories on the desired class. - SymbolContextList candidate_sc_list; + SymbolContextList candidate_sc_list; - m_target->GetImages().FindFunctions(selector_name, lldb::eFunctionNameTypeSelector, include_symbols, include_inlines, append, candidate_sc_list); + m_target->GetImages().FindFunctions( + selector_name, lldb::eFunctionNameTypeSelector, include_symbols, + include_inlines, append, candidate_sc_list); - for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); - ci != ce; - ++ci) - { - SymbolContext candidate_sc; + for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) { + SymbolContext candidate_sc; - if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc)) - continue; + if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc)) + continue; - if (!candidate_sc.function) - continue; + if (!candidate_sc.function) + continue; - const char *candidate_name = candidate_sc.function->GetName().AsCString(); + const char *candidate_name = candidate_sc.function->GetName().AsCString(); - const char *cursor = candidate_name; + const char *cursor = candidate_name; - if (*cursor != '+' && *cursor != '-') - continue; + if (*cursor != '+' && *cursor != '-') + continue; - ++cursor; + ++cursor; - if (*cursor != '[') - continue; + if (*cursor != '[') + continue; - ++cursor; + ++cursor; - size_t interface_len = interface_name.length(); + size_t interface_len = interface_name.length(); - if (strncmp(cursor, interface_name.c_str(), interface_len)) - continue; + if (strncmp(cursor, interface_name.c_str(), interface_len)) + continue; - cursor += interface_len; + cursor += interface_len; - if (*cursor == ' ' || *cursor == '(') - sc_list.Append(candidate_sc); - } + if (*cursor == ' ' || *cursor == '(') + sc_list.Append(candidate_sc); } - while (0); - - if (sc_list.GetSize()) - { - // We found a good function symbol. Use that. + } while (0); - for (uint32_t i = 0, e = sc_list.GetSize(); - i != e; - ++i) - { - SymbolContext sc; + if (sc_list.GetSize()) { + // We found a good function symbol. Use that. - if (!sc_list.GetContextAtIndex(i, sc)) - continue; + for (uint32_t i = 0, e = sc_list.GetSize(); i != e; ++i) { + SymbolContext sc; - if (!sc.function) - continue; + if (!sc_list.GetContextAtIndex(i, sc)) + continue; - CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext(); - if (!function_decl_ctx) - continue; + if (!sc.function) + continue; - ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx); + CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext(); + if (!function_decl_ctx) + continue; - if (!method_decl) - continue; + ObjCMethodDecl *method_decl = + ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx); - ObjCInterfaceDecl *found_interface_decl = method_decl->getClassInterface(); + if (!method_decl) + continue; - if (!found_interface_decl) - continue; + ObjCInterfaceDecl *found_interface_decl = + method_decl->getClassInterface(); - if (found_interface_decl->getName() == interface_decl->getName()) - { - Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, &method_decl->getASTContext(), method_decl); + if (!found_interface_decl) + continue; - if (!copied_decl) - continue; + if (found_interface_decl->getName() == interface_decl->getName()) { + Decl *copied_decl = m_ast_importer_sp->CopyDecl( + m_ast_context, &method_decl->getASTContext(), method_decl); - ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl); + if (!copied_decl) + continue; - if (!copied_method_decl) - continue; + ObjCMethodDecl *copied_method_decl = + dyn_cast<ObjCMethodDecl>(copied_decl); - if (log) - { - ASTDumper dumper((Decl*)copied_method_decl); - log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, dumper.GetCString()); - } + if (!copied_method_decl) + continue; - context.AddNamedDecl(copied_method_decl); - } + if (log) { + ASTDumper dumper((Decl *)copied_method_decl); + log->Printf(" CAS::FOMD[%d] found (in symbols) %s", current_id, + dumper.GetCString()); } - return; + context.AddNamedDecl(copied_method_decl); + } } - // Try the debug information. + return; + } - do - { - ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(interface_decl)); + // Try the debug information. - if (!complete_interface_decl) - break; + do { + ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface( + const_cast<ObjCInterfaceDecl *>(interface_decl)); - // We found the complete interface. The runtime never needs to be queried in this scenario. + if (!complete_interface_decl) + break; - DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl); + // We found the complete interface. The runtime never needs to be queried + // in this scenario. - if (complete_interface_decl == interface_decl) - break; // already checked this one + DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl( + complete_interface_decl); - if (log) - log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, static_cast<void*>(complete_interface_decl), - static_cast<void*>(&complete_iface_decl->getASTContext())); + if (complete_interface_decl == interface_decl) + break; // already checked this one + + if (log) + log->Printf("CAS::FOPD[%d] trying origin " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, static_cast<void *>(complete_interface_decl), + static_cast<void *>(&complete_iface_decl->getASTContext())); + + FindObjCMethodDeclsWithOrigin(current_id, context, complete_interface_decl, + m_ast_context, m_ast_importer_sp.get(), + "in debug info"); + + return; + } while (0); + + do { + // Check the modules only if the debug information didn't have a complete + // interface. + + if (ClangModulesDeclVendor *modules_decl_vendor = + m_target->GetClangModulesDeclVendor()) { + ConstString interface_name(interface_decl->getNameAsString().c_str()); + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; + + if (!modules_decl_vendor->FindDecls(interface_name, append, max_matches, + decls)) + break; + + ObjCInterfaceDecl *interface_decl_from_modules = + dyn_cast<ObjCInterfaceDecl>(decls[0]); - FindObjCMethodDeclsWithOrigin(current_id, - context, - complete_interface_decl, - m_ast_context, - m_ast_importer_sp.get(), - "in debug info"); + if (!interface_decl_from_modules) + break; + if (FindObjCMethodDeclsWithOrigin( + current_id, context, interface_decl_from_modules, m_ast_context, + m_ast_importer_sp.get(), "in modules")) return; } - while (0); - - do - { - // Check the modules only if the debug information didn't have a complete interface. - - if (ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor()) - { - ConstString interface_name(interface_decl->getNameAsString().c_str()); - bool append = false; - uint32_t max_matches = 1; - std::vector <clang::NamedDecl *> decls; - - if (!modules_decl_vendor->FindDecls(interface_name, - append, - max_matches, - decls)) - break; - - ObjCInterfaceDecl *interface_decl_from_modules = dyn_cast<ObjCInterfaceDecl>(decls[0]); - - if (!interface_decl_from_modules) - break; - - if (FindObjCMethodDeclsWithOrigin(current_id, - context, - interface_decl_from_modules, - m_ast_context, - m_ast_importer_sp.get(), - "in modules")) - return; - } - } - while (0); + } while (0); - do - { - // Check the runtime only if the debug information didn't have a complete interface and the modules don't get us anywhere. + do { + // Check the runtime only if the debug information didn't have a complete + // interface and the modules don't get us anywhere. - lldb::ProcessSP process(m_target->GetProcessSP()); + lldb::ProcessSP process(m_target->GetProcessSP()); - if (!process) - break; + if (!process) + break; - ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); + ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); - if (!language_runtime) - break; + if (!language_runtime) + break; - DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); + DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); - if (!decl_vendor) - break; + if (!decl_vendor) + break; - ConstString interface_name(interface_decl->getNameAsString().c_str()); - bool append = false; - uint32_t max_matches = 1; - std::vector <clang::NamedDecl *> decls; + ConstString interface_name(interface_decl->getNameAsString().c_str()); + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(interface_name, - append, - max_matches, - decls)) - break; + if (!decl_vendor->FindDecls(interface_name, append, max_matches, decls)) + break; - ObjCInterfaceDecl *runtime_interface_decl = dyn_cast<ObjCInterfaceDecl>(decls[0]); - - if (!runtime_interface_decl) - break; + ObjCInterfaceDecl *runtime_interface_decl = + dyn_cast<ObjCInterfaceDecl>(decls[0]); - FindObjCMethodDeclsWithOrigin(current_id, - context, - runtime_interface_decl, - m_ast_context, - m_ast_importer_sp.get(), - "in runtime"); - } - while(0); + if (!runtime_interface_decl) + break; + + FindObjCMethodDeclsWithOrigin(current_id, context, runtime_interface_decl, + m_ast_context, m_ast_importer_sp.get(), + "in runtime"); + } while (0); } -static bool -FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id, - NameSearchContext &context, - clang::ASTContext &ast_context, - ClangASTImporter *ast_importer, - DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); +static bool FindObjCPropertyAndIvarDeclsWithOrigin( + unsigned int current_id, NameSearchContext &context, + clang::ASTContext &ast_context, ClangASTImporter *ast_importer, + DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (origin_iface_decl.IsInvalid()) + return false; + + std::string name_str = context.m_decl_name.getAsString(); + StringRef name(name_str); + IdentifierInfo &name_identifier( + origin_iface_decl->getASTContext().Idents.get(name)); + + DeclFromUser<ObjCPropertyDecl> origin_property_decl( + origin_iface_decl->FindPropertyDeclaration( + &name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance)); + + bool found = false; + + if (origin_property_decl.IsValid()) { + DeclFromParser<ObjCPropertyDecl> parser_property_decl( + origin_property_decl.Import(ast_importer, ast_context)); + if (parser_property_decl.IsValid()) { + if (log) { + ASTDumper dumper((Decl *)parser_property_decl.decl); + log->Printf(" CAS::FOPD[%d] found %s", current_id, + dumper.GetCString()); + } + + context.AddNamedDecl(parser_property_decl.decl); + found = true; + } + } + + DeclFromUser<ObjCIvarDecl> origin_ivar_decl( + origin_iface_decl->getIvarDecl(&name_identifier)); + + if (origin_ivar_decl.IsValid()) { + DeclFromParser<ObjCIvarDecl> parser_ivar_decl( + origin_ivar_decl.Import(ast_importer, ast_context)); + if (parser_ivar_decl.IsValid()) { + if (log) { + ASTDumper dumper((Decl *)parser_ivar_decl.decl); + log->Printf(" CAS::FOPD[%d] found %s", current_id, + dumper.GetCString()); + } + + context.AddNamedDecl(parser_ivar_decl.decl); + found = true; + } + } - if (origin_iface_decl.IsInvalid()) - return false; + return found; +} - std::string name_str = context.m_decl_name.getAsString(); - StringRef name(name_str.c_str()); - IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name)); +void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance)); + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; - bool found = false; + DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl( + cast<ObjCInterfaceDecl>(context.m_decl_context)); + DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl( + parser_iface_decl.GetOrigin(m_ast_importer_sp.get())); - if (origin_property_decl.IsValid()) - { - DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context)); - if (parser_property_decl.IsValid()) - { - if (log) - { - ASTDumper dumper((Decl*)parser_property_decl.decl); - log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString()); - } + ConstString class_name(parser_iface_decl->getNameAsString().c_str()); - context.AddNamedDecl(parser_property_decl.decl); - found = true; - } - } + if (log) + log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on " + "(ASTContext*)%p for '%s.%s'", + current_id, static_cast<void *>(m_ast_context), + parser_iface_decl->getNameAsString().c_str(), + context.m_decl_name.getAsString().c_str()); - DeclFromUser<ObjCIvarDecl> origin_ivar_decl(origin_iface_decl->getIvarDecl(&name_identifier)); - - if (origin_ivar_decl.IsValid()) - { - DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context)); - if (parser_ivar_decl.IsValid()) - { - if (log) - { - ASTDumper dumper((Decl*)parser_ivar_decl.decl); - log->Printf(" CAS::FOPD[%d] found %s", current_id, dumper.GetCString()); - } + if (FindObjCPropertyAndIvarDeclsWithOrigin( + current_id, context, *m_ast_context, m_ast_importer_sp.get(), + origin_iface_decl)) + return; - context.AddNamedDecl(parser_ivar_decl.decl); - found = true; - } - } + if (log) + log->Printf("CAS::FOPD[%d] couldn't find the property on origin " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching " + "elsewhere...", + current_id, static_cast<const void *>(origin_iface_decl.decl), + static_cast<void *>(&origin_iface_decl->getASTContext())); - return found; -} + SymbolContext null_sc; + TypeList type_list; -void -ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + do { + ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface( + const_cast<ObjCInterfaceDecl *>(parser_iface_decl.decl)); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + if (!complete_interface_decl) + break; - DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context)); - DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer_sp.get())); + // We found the complete interface. The runtime never needs to be queried + // in this scenario. - ConstString class_name(parser_iface_decl->getNameAsString().c_str()); + DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl( + complete_interface_decl); - if (log) - log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'", - current_id, static_cast<void*>(m_ast_context), - parser_iface_decl->getNameAsString().c_str(), - context.m_decl_name.getAsString().c_str()); - - if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, - context, - *m_ast_context, - m_ast_importer_sp.get(), - origin_iface_decl)) - return; + if (complete_iface_decl.decl == origin_iface_decl.decl) + break; // already checked this one if (log) - log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...", - current_id, static_cast<const void*>(origin_iface_decl.decl), - static_cast<void*>(&origin_iface_decl->getASTContext())); + log->Printf("CAS::FOPD[%d] trying origin " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, + static_cast<const void *>(complete_iface_decl.decl), + static_cast<void *>(&complete_iface_decl->getASTContext())); - SymbolContext null_sc; - TypeList type_list; + FindObjCPropertyAndIvarDeclsWithOrigin(current_id, context, *m_ast_context, + m_ast_importer_sp.get(), + complete_iface_decl); - do - { - ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl)); + return; + } while (0); - if (!complete_interface_decl) - break; + do { + // Check the modules only if the debug information didn't have a complete + // interface. - // We found the complete interface. The runtime never needs to be queried in this scenario. + ClangModulesDeclVendor *modules_decl_vendor = + m_target->GetClangModulesDeclVendor(); - DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl); + if (!modules_decl_vendor) + break; - if (complete_iface_decl.decl == origin_iface_decl.decl) - break; // already checked this one + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; - if (log) - log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, - static_cast<const void*>(complete_iface_decl.decl), - static_cast<void*>(&complete_iface_decl->getASTContext())); + if (!modules_decl_vendor->FindDecls(class_name, append, max_matches, decls)) + break; - FindObjCPropertyAndIvarDeclsWithOrigin(current_id, - context, - *m_ast_context, - m_ast_importer_sp.get(), - complete_iface_decl); + DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules( + dyn_cast<ObjCInterfaceDecl>(decls[0])); - return; - } - while(0); - - do - { - // Check the modules only if the debug information didn't have a complete interface. - - ClangModulesDeclVendor *modules_decl_vendor = m_target->GetClangModulesDeclVendor(); - - if (!modules_decl_vendor) - break; - - bool append = false; - uint32_t max_matches = 1; - std::vector <clang::NamedDecl *> decls; - - if (!modules_decl_vendor->FindDecls(class_name, - append, - max_matches, - decls)) - break; - - DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(dyn_cast<ObjCInterfaceDecl>(decls[0])); - - if (!interface_decl_from_modules.IsValid()) - break; - - if (log) - log->Printf("CAS::FOPD[%d] trying module (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, - static_cast<const void*>(interface_decl_from_modules.decl), - static_cast<void*>(&interface_decl_from_modules->getASTContext())); - - if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, - context, - *m_ast_context, - m_ast_importer_sp.get(), - interface_decl_from_modules)) - return; - } - while(0); + if (!interface_decl_from_modules.IsValid()) + break; - do - { - // Check the runtime only if the debug information didn't have a complete interface - // and nothing was in the modules. + if (log) + log->Printf( + "CAS::FOPD[%d] trying module " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, + static_cast<const void *>(interface_decl_from_modules.decl), + static_cast<void *>(&interface_decl_from_modules->getASTContext())); + + if (FindObjCPropertyAndIvarDeclsWithOrigin( + current_id, context, *m_ast_context, m_ast_importer_sp.get(), + interface_decl_from_modules)) + return; + } while (0); + + do { + // Check the runtime only if the debug information didn't have a complete + // interface + // and nothing was in the modules. - lldb::ProcessSP process(m_target->GetProcessSP()); + lldb::ProcessSP process(m_target->GetProcessSP()); - if (!process) - return; + if (!process) + return; - ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); + ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime()); - if (!language_runtime) - return; + if (!language_runtime) + return; - DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); + DeclVendor *decl_vendor = language_runtime->GetDeclVendor(); - if (!decl_vendor) - break; + if (!decl_vendor) + break; - bool append = false; - uint32_t max_matches = 1; - std::vector <clang::NamedDecl *> decls; + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; - if (!decl_vendor->FindDecls(class_name, - append, - max_matches, - decls)) - break; + if (!decl_vendor->FindDecls(class_name, append, max_matches, decls)) + break; - DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(dyn_cast<ObjCInterfaceDecl>(decls[0])); - - if (!interface_decl_from_runtime.IsValid()) - break; + DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime( + dyn_cast<ObjCInterfaceDecl>(decls[0])); - if (log) - log->Printf("CAS::FOPD[%d] trying runtime (ObjCInterfaceDecl*)%p/(ASTContext*)%p...", - current_id, - static_cast<const void*>(interface_decl_from_runtime.decl), - static_cast<void*>(&interface_decl_from_runtime->getASTContext())); - - if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, - context, - *m_ast_context, - m_ast_importer_sp.get(), - interface_decl_from_runtime)) - return; - } - while(0); + if (!interface_decl_from_runtime.IsValid()) + break; + + if (log) + log->Printf( + "CAS::FOPD[%d] trying runtime " + "(ObjCInterfaceDecl*)%p/(ASTContext*)%p...", + current_id, + static_cast<const void *>(interface_decl_from_runtime.decl), + static_cast<void *>(&interface_decl_from_runtime->getASTContext())); + + if (FindObjCPropertyAndIvarDeclsWithOrigin( + current_id, context, *m_ast_context, m_ast_importer_sp.get(), + interface_decl_from_runtime)) + return; + } while (0); } typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap; typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap; template <class D, class O> -static bool -ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, llvm::DenseMap<const D *, O> &source_map, - ClangASTImporter *importer, ASTContext &dest_ctx) -{ - // When importing fields into a new record, clang has a hard requirement that - // fields be imported in field offset order. Since they are stored in a DenseMap - // with a pointer as the key type, this means we cannot simply iterate over the - // map, as the order will be non-deterministic. Instead we have to sort by the offset - // and then insert in sorted order. - typedef llvm::DenseMap<const D *, O> MapType; - typedef typename MapType::value_type PairType; - std::vector<PairType> sorted_items; - sorted_items.reserve(source_map.size()); - sorted_items.assign(source_map.begin(), source_map.end()); - std::sort(sorted_items.begin(), sorted_items.end(), - [](const PairType &lhs, const PairType &rhs) - { - return lhs.second < rhs.second; - }); - - for (const auto &item : sorted_items) - { - DeclFromUser<D> user_decl(const_cast<D *>(item.first)); - DeclFromParser <D> parser_decl(user_decl.Import(importer, dest_ctx)); - if (parser_decl.IsInvalid()) - return false; - destination_map.insert(std::pair<const D *, O>(parser_decl.decl, item.second)); - } +static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map, + llvm::DenseMap<const D *, O> &source_map, + ClangASTImporter *importer, ASTContext &dest_ctx) { + // When importing fields into a new record, clang has a hard requirement that + // fields be imported in field offset order. Since they are stored in a + // DenseMap + // with a pointer as the key type, this means we cannot simply iterate over + // the + // map, as the order will be non-deterministic. Instead we have to sort by + // the offset + // and then insert in sorted order. + typedef llvm::DenseMap<const D *, O> MapType; + typedef typename MapType::value_type PairType; + std::vector<PairType> sorted_items; + sorted_items.reserve(source_map.size()); + sorted_items.assign(source_map.begin(), source_map.end()); + std::sort(sorted_items.begin(), sorted_items.end(), + [](const PairType &lhs, const PairType &rhs) { + return lhs.second < rhs.second; + }); + + for (const auto &item : sorted_items) { + DeclFromUser<D> user_decl(const_cast<D *>(item.first)); + DeclFromParser<D> parser_decl(user_decl.Import(importer, dest_ctx)); + if (parser_decl.IsInvalid()) + return false; + destination_map.insert( + std::pair<const D *, O>(parser_decl.decl, item.second)); + } - return true; + return true; } template <bool IsVirtual> -bool -ExtractBaseOffsets(const ASTRecordLayout &record_layout, DeclFromUser<const CXXRecordDecl> &record, - BaseOffsetMap &base_offsets) -{ - for (CXXRecordDecl::base_class_const_iterator bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()), - be = (IsVirtual ? record->vbases_end() : record->bases_end()); - bi != be; ++bi) - { - if (!IsVirtual && bi->isVirtual()) - continue; +bool ExtractBaseOffsets(const ASTRecordLayout &record_layout, + DeclFromUser<const CXXRecordDecl> &record, + BaseOffsetMap &base_offsets) { + for (CXXRecordDecl::base_class_const_iterator + bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()), + be = (IsVirtual ? record->vbases_end() : record->bases_end()); + bi != be; ++bi) { + if (!IsVirtual && bi->isVirtual()) + continue; + + const clang::Type *origin_base_type = bi->getType().getTypePtr(); + const clang::RecordType *origin_base_record_type = + origin_base_type->getAs<RecordType>(); + + if (!origin_base_record_type) + return false; - const clang::Type *origin_base_type = bi->getType().getTypePtr(); - const clang::RecordType *origin_base_record_type = origin_base_type->getAs<RecordType>(); + DeclFromUser<RecordDecl> origin_base_record( + origin_base_record_type->getDecl()); - if (!origin_base_record_type) - return false; + if (origin_base_record.IsInvalid()) + return false; - DeclFromUser <RecordDecl> origin_base_record(origin_base_record_type->getDecl()); + DeclFromUser<CXXRecordDecl> origin_base_cxx_record( + DynCast<CXXRecordDecl>(origin_base_record)); - if (origin_base_record.IsInvalid()) - return false; + if (origin_base_cxx_record.IsInvalid()) + return false; - DeclFromUser <CXXRecordDecl> origin_base_cxx_record(DynCast<CXXRecordDecl>(origin_base_record)); + CharUnits base_offset; - if (origin_base_cxx_record.IsInvalid()) - return false; + if (IsVirtual) + base_offset = + record_layout.getVBaseClassOffset(origin_base_cxx_record.decl); + else + base_offset = + record_layout.getBaseClassOffset(origin_base_cxx_record.decl); - CharUnits base_offset; + base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>( + origin_base_cxx_record.decl, base_offset)); + } - if (IsVirtual) - base_offset = record_layout.getVBaseClassOffset(origin_base_cxx_record.decl); - else - base_offset = record_layout.getBaseClassOffset(origin_base_cxx_record.decl); + return true; +} - base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(origin_base_cxx_record.decl, base_offset)); - } +bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, + uint64_t &alignment, + FieldOffsetMap &field_offsets, + BaseOffsetMap &base_offsets, + BaseOffsetMap &virtual_base_offsets) { + ClangASTMetrics::RegisterRecordLayout(); - return true; -} + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; -bool -ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, uint64_t &alignment, - FieldOffsetMap &field_offsets, BaseOffsetMap &base_offsets, - BaseOffsetMap &virtual_base_offsets) -{ - ClangASTMetrics::RegisterRecordLayout(); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + if (log) + log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p " + "[name = '%s']", + current_id, static_cast<void *>(m_ast_context), + static_cast<const void *>(record), + record->getNameAsString().c_str()); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + DeclFromParser<const RecordDecl> parser_record(record); + DeclFromUser<const RecordDecl> origin_record( + parser_record.GetOrigin(m_ast_importer_sp.get())); - if (log) - log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']", - current_id, static_cast<void*>(m_ast_context), - static_cast<const void*>(record), - record->getNameAsString().c_str()); + if (origin_record.IsInvalid()) + return false; + + FieldOffsetMap origin_field_offsets; + BaseOffsetMap origin_base_offsets; + BaseOffsetMap origin_virtual_base_offsets; - DeclFromParser <const RecordDecl> parser_record(record); - DeclFromUser <const RecordDecl> origin_record(parser_record.GetOrigin(m_ast_importer_sp.get())); + ClangASTContext::GetCompleteDecl( + &origin_record->getASTContext(), + const_cast<RecordDecl *>(origin_record.decl)); - if (origin_record.IsInvalid()) - return false; + clang::RecordDecl *definition = origin_record.decl->getDefinition(); + if (!definition || !definition->isCompleteDefinition()) + return false; - FieldOffsetMap origin_field_offsets; - BaseOffsetMap origin_base_offsets; - BaseOffsetMap origin_virtual_base_offsets; + const ASTRecordLayout &record_layout( + origin_record->getASTContext().getASTRecordLayout(origin_record.decl)); - ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast<RecordDecl*>(origin_record.decl)); + int field_idx = 0, field_count = record_layout.getFieldCount(); - clang::RecordDecl* definition = origin_record.decl->getDefinition(); - if (!definition || !definition->isCompleteDefinition()) - return false; + for (RecordDecl::field_iterator fi = origin_record->field_begin(), + fe = origin_record->field_end(); + fi != fe; ++fi) { + if (field_idx >= field_count) + return false; // Layout didn't go well. Bail out. - const ASTRecordLayout &record_layout(origin_record->getASTContext().getASTRecordLayout(origin_record.decl)); + uint64_t field_offset = record_layout.getFieldOffset(field_idx); - int field_idx = 0, field_count = record_layout.getFieldCount(); + origin_field_offsets.insert( + std::pair<const FieldDecl *, uint64_t>(*fi, field_offset)); - for (RecordDecl::field_iterator fi = origin_record->field_begin(), fe = origin_record->field_end(); fi != fe; ++fi) - { - if (field_idx >= field_count) - return false; // Layout didn't go well. Bail out. + field_idx++; + } - uint64_t field_offset = record_layout.getFieldOffset(field_idx); + ASTContext &parser_ast_context(record->getASTContext()); - origin_field_offsets.insert(std::pair<const FieldDecl *, uint64_t>(*fi, field_offset)); + DeclFromUser<const CXXRecordDecl> origin_cxx_record( + DynCast<const CXXRecordDecl>(origin_record)); - field_idx++; + if (origin_cxx_record.IsValid()) { + if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, + origin_base_offsets) || + !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, + origin_virtual_base_offsets)) + return false; + } + + if (!ImportOffsetMap(field_offsets, origin_field_offsets, + m_ast_importer_sp.get(), parser_ast_context) || + !ImportOffsetMap(base_offsets, origin_base_offsets, + m_ast_importer_sp.get(), parser_ast_context) || + !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, + m_ast_importer_sp.get(), parser_ast_context)) + return false; + + size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth(); + alignment = record_layout.getAlignment().getQuantity() * + m_ast_context->getCharWidth(); + + if (log) { + log->Printf("LRT[%u] returned:", current_id); + log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, + static_cast<const void *>(origin_record.decl)); + log->Printf("LRT[%u] Size = %" PRId64, current_id, size); + log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment); + log->Printf("LRT[%u] Fields:", current_id); + for (RecordDecl::field_iterator fi = record->field_begin(), + fe = record->field_end(); + fi != fe; ++fi) { + log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 + " bits", + current_id, static_cast<void *>(*fi), + fi->getNameAsString().c_str(), field_offsets[*fi]); } + DeclFromParser<const CXXRecordDecl> parser_cxx_record = + DynCast<const CXXRecordDecl>(parser_record); + if (parser_cxx_record.IsValid()) { + log->Printf("LRT[%u] Bases:", current_id); + for (CXXRecordDecl::base_class_const_iterator + bi = parser_cxx_record->bases_begin(), + be = parser_cxx_record->bases_end(); + bi != be; ++bi) { + bool is_virtual = bi->isVirtual(); + + QualType base_type = bi->getType(); + const RecordType *base_record_type = base_type->getAs<RecordType>(); + DeclFromParser<RecordDecl> base_record(base_record_type->getDecl()); + DeclFromParser<CXXRecordDecl> base_cxx_record = + DynCast<CXXRecordDecl>(base_record); + + log->Printf( + "LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 + " chars", + current_id, (is_virtual ? "Virtual " : ""), + static_cast<void *>(base_cxx_record.decl), + base_cxx_record.decl->getNameAsString().c_str(), + (is_virtual + ? virtual_base_offsets[base_cxx_record.decl].getQuantity() + : base_offsets[base_cxx_record.decl].getQuantity())); + } + } else { + log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id); + } + } - ASTContext &parser_ast_context(record->getASTContext()); + return true; +} - DeclFromUser <const CXXRecordDecl> origin_cxx_record(DynCast<const CXXRecordDecl>(origin_record)); +void ClangASTSource::CompleteNamespaceMap( + ClangASTImporter::NamespaceMapSP &namespace_map, const ConstString &name, + ClangASTImporter::NamespaceMapSP &parent_map) const { + static unsigned int invocation_id = 0; + unsigned int current_id = invocation_id++; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) { + if (parent_map && parent_map->size()) + log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " + "namespace %s in namespace %s", + current_id, static_cast<void *>(m_ast_context), + name.GetCString(), + parent_map->begin()->second.GetName().AsCString()); + else + log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for " + "namespace %s", + current_id, static_cast<void *>(m_ast_context), + name.GetCString()); + } - if (origin_cxx_record.IsValid()) - { - if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record, origin_base_offsets) || - !ExtractBaseOffsets<true>(record_layout, origin_cxx_record, origin_virtual_base_offsets)) - return false; - } + if (parent_map) { + for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), + e = parent_map->end(); + i != e; ++i) { + CompilerDeclContext found_namespace_decl; - if (!ImportOffsetMap(field_offsets, origin_field_offsets, m_ast_importer_sp.get(), parser_ast_context) || - !ImportOffsetMap(base_offsets, origin_base_offsets, m_ast_importer_sp.get(), parser_ast_context) || - !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets, m_ast_importer_sp.get(), parser_ast_context)) - return false; + lldb::ModuleSP module_sp = i->first; + CompilerDeclContext module_parent_namespace_decl = i->second; - size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth(); - alignment = record_layout.getAlignment().getQuantity() * m_ast_context->getCharWidth(); + SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); - if (log) - { - log->Printf("LRT[%u] returned:", current_id); - log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, - static_cast<const void*>(origin_record.decl)); - log->Printf("LRT[%u] Size = %" PRId64, current_id, size); - log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment); - log->Printf("LRT[%u] Fields:", current_id); - for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end(); - fi != fe; - ++fi) - { - log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits", current_id, - static_cast<void *>(*fi), fi->getNameAsString().c_str(), field_offsets[*fi]); - } - DeclFromParser <const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record); - if (parser_cxx_record.IsValid()) - { - log->Printf("LRT[%u] Bases:", current_id); - for (CXXRecordDecl::base_class_const_iterator bi = parser_cxx_record->bases_begin(), be = parser_cxx_record->bases_end(); - bi != be; - ++bi) - { - bool is_virtual = bi->isVirtual(); - - QualType base_type = bi->getType(); - const RecordType *base_record_type = base_type->getAs<RecordType>(); - DeclFromParser <RecordDecl> base_record(base_record_type->getDecl()); - DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record); - - log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars", current_id, - (is_virtual ? "Virtual " : ""), static_cast<void *>(base_cxx_record.decl), - base_cxx_record.decl->getNameAsString().c_str(), - (is_virtual ? virtual_base_offsets[base_cxx_record.decl].getQuantity() - : base_offsets[base_cxx_record.decl].getQuantity())); - } - } - else - { - log->Printf("LRD[%u] Not a CXXRecord, so no bases", current_id); - } - } + if (!symbol_vendor) + continue; - return true; -} + SymbolContext null_sc; -void -ClangASTSource::CompleteNamespaceMap (ClangASTImporter::NamespaceMapSP &namespace_map, - const ConstString &name, - ClangASTImporter::NamespaceMapSP &parent_map) const -{ - static unsigned int invocation_id = 0; - unsigned int current_id = invocation_id++; + found_namespace_decl = symbol_vendor->FindNamespace( + null_sc, name, &module_parent_namespace_decl); - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + if (!found_namespace_decl) + continue; - if (log) - { - if (parent_map && parent_map->size()) - log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s in namespace %s", - current_id, static_cast<void*>(m_ast_context), - name.GetCString(), - parent_map->begin()->second.GetName().AsCString()); - else - log->Printf("CompleteNamespaceMap[%u] on (ASTContext*)%p Searching for namespace %s", - current_id, static_cast<void*>(m_ast_context), - name.GetCString()); + namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>( + module_sp, found_namespace_decl)); + + if (log) + log->Printf(" CMN[%u] Found namespace %s in module %s", current_id, + name.GetCString(), + module_sp->GetFileSpec().GetFilename().GetCString()); } + } else { + const ModuleList &target_images = m_target->GetImages(); + std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex()); - if (parent_map) - { - for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(), e = parent_map->end(); - i != e; - ++i) - { - CompilerDeclContext found_namespace_decl; + CompilerDeclContext null_namespace_decl; - lldb::ModuleSP module_sp = i->first; - CompilerDeclContext module_parent_namespace_decl = i->second; + for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) { + lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); - SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); + if (!image) + continue; - if (!symbol_vendor) - continue; + CompilerDeclContext found_namespace_decl; - SymbolContext null_sc; + SymbolVendor *symbol_vendor = image->GetSymbolVendor(); - found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &module_parent_namespace_decl); + if (!symbol_vendor) + continue; - if (!found_namespace_decl) - continue; + SymbolContext null_sc; - namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(module_sp, found_namespace_decl)); + found_namespace_decl = + symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl); - if (log) - log->Printf(" CMN[%u] Found namespace %s in module %s", - current_id, - name.GetCString(), - module_sp->GetFileSpec().GetFilename().GetCString()); - } + if (!found_namespace_decl) + continue; + + namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>( + image, found_namespace_decl)); + + if (log) + log->Printf(" CMN[%u] Found namespace %s in module %s", current_id, + name.GetCString(), + image->GetFileSpec().GetFilename().GetCString()); } - else - { - const ModuleList &target_images = m_target->GetImages(); - std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex()); + } +} - CompilerDeclContext null_namespace_decl; +NamespaceDecl *ClangASTSource::AddNamespace( + NameSearchContext &context, + ClangASTImporter::NamespaceMapSP &namespace_decls) { + if (!namespace_decls) + return nullptr; - for (size_t i = 0, e = target_images.GetSize(); i < e; ++i) - { - lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i); + const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second; - if (!image) - continue; + clang::ASTContext *src_ast = + ClangASTContext::DeclContextGetClangASTContext(namespace_decl); + if (!src_ast) + return nullptr; + clang::NamespaceDecl *src_namespace_decl = + ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl); - CompilerDeclContext found_namespace_decl; + if (!src_namespace_decl) + return nullptr; - SymbolVendor *symbol_vendor = image->GetSymbolVendor(); + Decl *copied_decl = + m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl); - if (!symbol_vendor) - continue; + if (!copied_decl) + return nullptr; - SymbolContext null_sc; + NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl); - found_namespace_decl = symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl); + if (!copied_namespace_decl) + return nullptr; - if (!found_namespace_decl) - continue; + context.m_decls.push_back(copied_namespace_decl); - namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(image, found_namespace_decl)); + m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl, + namespace_decls); - if (log) - log->Printf(" CMN[%u] Found namespace %s in module %s", - current_id, - name.GetCString(), - image->GetFileSpec().GetFilename().GetCString()); - } - } + return dyn_cast<NamespaceDecl>(copied_decl); } -NamespaceDecl * -ClangASTSource::AddNamespace (NameSearchContext &context, ClangASTImporter::NamespaceMapSP &namespace_decls) -{ - if (!namespace_decls) - return nullptr; +CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) { + ClangASTContext *src_ast = + llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); + if (src_ast == nullptr) + return CompilerType(); - const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second; + ClangASTMetrics::RegisterLLDBImport(); - clang::ASTContext *src_ast = ClangASTContext::DeclContextGetClangASTContext(namespace_decl); - if (!src_ast) - return nullptr; - clang::NamespaceDecl *src_namespace_decl = ClangASTContext::DeclContextGetAsNamespaceDecl(namespace_decl); + SetImportInProgress(true); - if (!src_namespace_decl) - return nullptr; + QualType copied_qual_type = + m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), + ClangUtil::GetQualType(src_type)); - Decl *copied_decl = m_ast_importer_sp->CopyDecl(m_ast_context, src_ast, src_namespace_decl); + SetImportInProgress(false); - if (!copied_decl) - return nullptr; + if (copied_qual_type.getAsOpaquePtr() && + copied_qual_type->getCanonicalTypeInternal().isNull()) + // this shouldn't happen, but we're hardening because the AST importer seems + // to be generating bad types + // on occasion. + return CompilerType(); - NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl); + return CompilerType(m_ast_context, copied_qual_type); +} + +clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) { + assert(type && "Type for variable must be valid!"); - if (!copied_namespace_decl) - return nullptr; + if (!type.IsValid()) + return NULL; + + ClangASTContext *lldb_ast = + llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); + if (!lldb_ast) + return NULL; - context.m_decls.push_back(copied_namespace_decl); + IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo(); - m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl, namespace_decls); + clang::ASTContext *ast = lldb_ast->getASTContext(); - return dyn_cast<NamespaceDecl>(copied_decl); + clang::NamedDecl *Decl = VarDecl::Create( + *ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(), + SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static); + m_decls.push_back(Decl); + + return Decl; } -CompilerType -ClangASTSource::GuardedCopyType (const CompilerType &src_type) -{ - ClangASTContext *src_ast = llvm::dyn_cast_or_null<ClangASTContext>(src_type.GetTypeSystem()); - if (src_ast == nullptr) - return CompilerType(); +clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, + bool extern_c) { + assert(type && "Type for variable must be valid!"); - ClangASTMetrics::RegisterLLDBImport(); + if (!type.IsValid()) + return NULL; - SetImportInProgress(true); + if (m_function_types.count(type)) + return NULL; - QualType copied_qual_type = - m_ast_importer_sp->CopyType(m_ast_context, src_ast->getASTContext(), ClangUtil::GetQualType(src_type)); + ClangASTContext *lldb_ast = + llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); + if (!lldb_ast) + return NULL; - SetImportInProgress(false); + m_function_types.insert(type); - if (copied_qual_type.getAsOpaquePtr() && copied_qual_type->getCanonicalTypeInternal().isNull()) - // this shouldn't happen, but we're hardening because the AST importer seems to be generating bad types - // on occasion. - return CompilerType(); + QualType qual_type(ClangUtil::GetQualType(type)); - return CompilerType(m_ast_context, copied_qual_type); -} + clang::ASTContext *ast = lldb_ast->getASTContext(); -clang::NamedDecl * -NameSearchContext::AddVarDecl(const CompilerType &type) -{ - assert (type && "Type for variable must be valid!"); + const bool isInlineSpecified = false; + const bool hasWrittenPrototype = true; + const bool isConstexprSpecified = false; - if (!type.IsValid()) - return NULL; + clang::DeclContext *context = const_cast<DeclContext *>(m_decl_context); - ClangASTContext* lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); - if (!lldb_ast) - return NULL; - - IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo(); + if (extern_c) { + context = LinkageSpecDecl::Create( + *ast, context, SourceLocation(), SourceLocation(), + clang::LinkageSpecDecl::LanguageIDs::lang_c, false); + } - clang::ASTContext *ast = lldb_ast->getASTContext(); + // Pass the identifier info for functions the decl_name is needed for + // operators + clang::DeclarationName decl_name = + m_decl_name.getNameKind() == DeclarationName::Identifier + ? m_decl_name.getAsIdentifierInfo() + : m_decl_name; - clang::NamedDecl *Decl = VarDecl::Create(*ast, const_cast<DeclContext *>(m_decl_context), SourceLocation(), - SourceLocation(), ii, ClangUtil::GetQualType(type), 0, SC_Static); - m_decls.push_back(Decl); + clang::FunctionDecl *func_decl = FunctionDecl::Create( + *ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type, + NULL, SC_Extern, isInlineSpecified, hasWrittenPrototype, + isConstexprSpecified); - return Decl; -} + // We have to do more than just synthesize the FunctionDecl. We have to + // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do + // this, we raid the function's FunctionProtoType for types. -clang::NamedDecl * -NameSearchContext::AddFunDecl (const CompilerType &type, bool extern_c) -{ - assert (type && "Type for variable must be valid!"); - - if (!type.IsValid()) - return NULL; - - if (m_function_types.count(type)) - return NULL; - - ClangASTContext* lldb_ast = llvm::dyn_cast<ClangASTContext>(type.GetTypeSystem()); - if (!lldb_ast) - return NULL; - - m_function_types.insert(type); - - QualType qual_type(ClangUtil::GetQualType(type)); - - clang::ASTContext *ast = lldb_ast->getASTContext(); - - const bool isInlineSpecified = false; - const bool hasWrittenPrototype = true; - const bool isConstexprSpecified = false; - - clang::DeclContext *context = const_cast<DeclContext*>(m_decl_context); - - if (extern_c) { - context = LinkageSpecDecl::Create(*ast, - context, - SourceLocation(), - SourceLocation(), - clang::LinkageSpecDecl::LanguageIDs::lang_c, - false); - } + const FunctionProtoType *func_proto_type = + qual_type.getTypePtr()->getAs<FunctionProtoType>(); - // Pass the identifier info for functions the decl_name is needed for operators - clang::DeclarationName decl_name = m_decl_name.getNameKind() == DeclarationName::Identifier ? m_decl_name.getAsIdentifierInfo() : m_decl_name; - - clang::FunctionDecl *func_decl = FunctionDecl::Create (*ast, - context, - SourceLocation(), - SourceLocation(), - decl_name, - qual_type, - NULL, - SC_Extern, - isInlineSpecified, - hasWrittenPrototype, - isConstexprSpecified); - - // We have to do more than just synthesize the FunctionDecl. We have to - // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do - // this, we raid the function's FunctionProtoType for types. - - const FunctionProtoType *func_proto_type = qual_type.getTypePtr()->getAs<FunctionProtoType>(); - - if (func_proto_type) - { - unsigned NumArgs = func_proto_type->getNumParams(); - unsigned ArgIndex; - - SmallVector<ParmVarDecl *, 5> parm_var_decls; - - for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) - { - QualType arg_qual_type (func_proto_type->getParamType(ArgIndex)); - - parm_var_decls.push_back(ParmVarDecl::Create (*ast, - const_cast<DeclContext*>(context), - SourceLocation(), - SourceLocation(), - NULL, - arg_qual_type, - NULL, - SC_Static, - NULL)); - } + if (func_proto_type) { + unsigned NumArgs = func_proto_type->getNumParams(); + unsigned ArgIndex; - func_decl->setParams(ArrayRef<ParmVarDecl*>(parm_var_decls)); - } - else - { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + SmallVector<ParmVarDecl *, 5> parm_var_decls; - if (log) - log->Printf("Function type wasn't a FunctionProtoType"); + for (ArgIndex = 0; ArgIndex < NumArgs; ++ArgIndex) { + QualType arg_qual_type(func_proto_type->getParamType(ArgIndex)); + + parm_var_decls.push_back(ParmVarDecl::Create( + *ast, const_cast<DeclContext *>(context), SourceLocation(), + SourceLocation(), NULL, arg_qual_type, NULL, SC_Static, NULL)); } - m_decls.push_back(func_decl); + func_decl->setParams(ArrayRef<ParmVarDecl *>(parm_var_decls)); + } else { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + if (log) + log->Printf("Function type wasn't a FunctionProtoType"); + } + + m_decls.push_back(func_decl); - return func_decl; + return func_decl; } -clang::NamedDecl * -NameSearchContext::AddGenericFunDecl() -{ - FunctionProtoType::ExtProtoInfo proto_info; +clang::NamedDecl *NameSearchContext::AddGenericFunDecl() { + FunctionProtoType::ExtProtoInfo proto_info; - proto_info.Variadic = true; + proto_info.Variadic = true; - QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType (m_ast_source.m_ast_context->UnknownAnyTy, // result - ArrayRef<QualType>(), // argument types - proto_info)); + QualType generic_function_type(m_ast_source.m_ast_context->getFunctionType( + m_ast_source.m_ast_context->UnknownAnyTy, // result + ArrayRef<QualType>(), // argument types + proto_info)); - return AddFunDecl(CompilerType (m_ast_source.m_ast_context, generic_function_type), true); + return AddFunDecl( + CompilerType(m_ast_source.m_ast_context, generic_function_type), true); } clang::NamedDecl * -NameSearchContext::AddTypeDecl(const CompilerType &clang_type) -{ - if (ClangUtil::IsClangType(clang_type)) - { - QualType qual_type = ClangUtil::GetQualType(clang_type); +NameSearchContext::AddTypeDecl(const CompilerType &clang_type) { + if (ClangUtil::IsClangType(clang_type)) { + QualType qual_type = ClangUtil::GetQualType(clang_type); - if (const TypedefType *typedef_type = llvm::dyn_cast<TypedefType>(qual_type)) - { - TypedefNameDecl *typedef_name_decl = typedef_type->getDecl(); + if (const TypedefType *typedef_type = + llvm::dyn_cast<TypedefType>(qual_type)) { + TypedefNameDecl *typedef_name_decl = typedef_type->getDecl(); - m_decls.push_back(typedef_name_decl); + m_decls.push_back(typedef_name_decl); - return (NamedDecl*)typedef_name_decl; - } - else if (const TagType *tag_type = qual_type->getAs<TagType>()) - { - TagDecl *tag_decl = tag_type->getDecl(); + return (NamedDecl *)typedef_name_decl; + } else if (const TagType *tag_type = qual_type->getAs<TagType>()) { + TagDecl *tag_decl = tag_type->getDecl(); - m_decls.push_back(tag_decl); + m_decls.push_back(tag_decl); - return tag_decl; - } - else if (const ObjCObjectType *objc_object_type = qual_type->getAs<ObjCObjectType>()) - { - ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface(); + return tag_decl; + } else if (const ObjCObjectType *objc_object_type = + qual_type->getAs<ObjCObjectType>()) { + ObjCInterfaceDecl *interface_decl = objc_object_type->getInterface(); - m_decls.push_back((NamedDecl*)interface_decl); + m_decls.push_back((NamedDecl *)interface_decl); - return (NamedDecl*)interface_decl; - } + return (NamedDecl *)interface_decl; } - return NULL; + } + return NULL; } -void -NameSearchContext::AddLookupResult (clang::DeclContextLookupResult result) -{ - for (clang::NamedDecl *decl : result) - m_decls.push_back (decl); +void NameSearchContext::AddLookupResult(clang::DeclContextLookupResult result) { + for (clang::NamedDecl *decl : result) + m_decls.push_back(decl); } -void -NameSearchContext::AddNamedDecl (clang::NamedDecl *decl) -{ - m_decls.push_back (decl); +void NameSearchContext::AddNamedDecl(clang::NamedDecl *decl) { + m_decls.push_back(decl); } |