diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h --- a/lldb/include/lldb/Symbol/CompilerType.h +++ b/lldb/include/lldb/Symbol/CompilerType.h @@ -164,6 +164,8 @@ bool IsFunctionPointerType() const; + bool IsMemberFunctionPointerType() const; + bool IsBlockPointerType(CompilerType *function_pointer_type_ptr = nullptr) const; diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -169,6 +169,9 @@ virtual bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) = 0; + virtual bool + IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) = 0; + virtual bool IsBlockPointerType(lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) = 0; diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1390,7 +1390,8 @@ TypeSummaryImpl::Flags(), lldb_private::formatters::CXXFunctionPointerSummaryProvider, "Function pointer summary provider")); - if (valobj.GetCompilerType().IsFunctionPointerType()) { + if (CompilerType CT = valobj.GetCompilerType(); + CT.IsFunctionPointerType() || CT.IsMemberFunctionPointerType()) { return formatter_sp; } return nullptr; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -658,6 +658,8 @@ bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; + bool IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) override; + bool IsBlockPointerType(lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -3194,6 +3194,15 @@ return false; } +bool TypeSystemClang::IsMemberFunctionPointerType( + lldb::opaque_compiler_type_t type) { + auto isMemberFunctionPointerType = [](clang::QualType qual_type) { + return qual_type->isMemberFunctionPointerType(); + }; + + return IsTypeImpl(type, isMemberFunctionPointerType); +} + bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { auto isFunctionPointerType = [](clang::QualType qual_type) { return qual_type->isFunctionPointerType(); diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp --- a/lldb/source/Symbol/CompilerType.cpp +++ b/lldb/source/Symbol/CompilerType.cpp @@ -154,6 +154,13 @@ return false; } +bool CompilerType::IsMemberFunctionPointerType() const { + if (IsValid()) + if (auto type_system_sp = GetTypeSystem()) + return type_system_sp->IsMemberFunctionPointerType(m_type); + return false; +} + bool CompilerType::IsBlockPointerType( CompilerType *function_pointer_type_ptr) const { if (IsValid()) diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py b/lldb/test/API/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py --- a/lldb/test/API/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py @@ -292,7 +292,9 @@ substrs=['member_ptr = 0x']) self.expect( "frame variable member_func_ptr", - substrs=['member_func_ptr = 0x']) + substrs=['member_func_ptr = 0x', + '(a.out`IUseCharStar::member_func(int) at main.cpp:61)']) self.expect( "frame variable ref_to_member_func_ptr", - substrs=['ref_to_member_func_ptr = 0x']) + substrs=['ref_to_member_func_ptr = 0x', + '(a.out`IUseCharStar::member_func(int) at main.cpp:61)'])