diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h --- a/lldb/include/lldb/Symbol/Function.h +++ b/lldb/include/lldb/Symbol/Function.h @@ -475,6 +475,10 @@ /// The DeclContext, or NULL if none exists. CompilerDeclContext GetDeclContext(); + /// A quick test for being a method. This is used to filter out methods from + /// lists of functions without fully parsing debug info. + bool CanBeMethod(); + /// Get accessor for the type that describes the function return value type, /// and parameter types. /// diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -164,6 +164,7 @@ virtual CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) { return CompilerDeclContext(); } + virtual bool CanBeMethod(lldb::user_id_t uid) { return true; } virtual uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) = 0; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -1292,6 +1292,8 @@ // Filter out functions without declaration contexts, as well as // class/instance methods, since they'll be skipped in the code that // follows anyway. + if (function->CanBeMethod()) + continue; CompilerDeclContext func_decl_context = function->GetDeclContext(); if (!func_decl_context || func_decl_context.IsClassMethod(nullptr, nullptr, nullptr)) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -144,6 +144,8 @@ lldb_private::CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override; + bool CanBeMethod(lldb::user_id_t uid) override; + void ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1314,6 +1314,16 @@ return CompilerDeclContext(); } +bool SymbolFileDWARF::CanBeMethod(lldb::user_id_t uid) { + std::lock_guard guard(GetModuleMutex()); + // Anytime we have a lldb::user_id_t, we must get the DIE by calling + // SymbolFileDWARF::GetDIE(). See comments inside the + // SymbolFileDWARF::GetDIE() for details. + if (DWARFDIE die = GetDIE(uid)) + return die.IsMethod(); + return true; +} + Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { std::lock_guard guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp --- a/lldb/source/Symbol/Function.cpp +++ b/lldb/source/Symbol/Function.cpp @@ -454,6 +454,16 @@ return CompilerDeclContext(); } +bool Function::CanBeMethod() { + ModuleSP module_sp = CalculateSymbolContextModule(); + + if (module_sp) { + if (SymbolFile *sym_file = module_sp->GetSymbolFile()) + return sym_file->CanBeMethod(GetID()); + } + return true; +} + Type *Function::GetType() { if (m_type == nullptr) { SymbolContext sc;