Data formatters: Look through array element typedefs

Summary:
Motivation: When formatting an array of typedefed chars, we would like to display the array as a string.

The string formatter currently does not trigger because the formatter lookup does not resolve typedefs for array elements (this behavior is inconsistent with pointers, for those we do look through pointee typedefs). This patch tries to make the array formatter lookup somewhat consistent with the pointer formatter lookup.

Reviewers: teemperor, clayborg

Reviewed By: teemperor, clayborg

Subscribers: clayborg, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D72133
This commit is contained in:
Jaroslav Sevcik 2020-01-10 11:44:14 +01:00 committed by Raphael Isemann
parent f3849f739e
commit 902974277d
6 changed files with 54 additions and 6 deletions

View File

@ -0,0 +1,3 @@
CXX_SOURCES := main.cpp
include Makefile.rules

View File

@ -0,0 +1,15 @@
import lldb
from lldbsuite.test.lldbtest import *
import lldbsuite.test.lldbutil as lldbutil
class ArrayTypedefTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
def test_array_typedef(self):
self.build()
lldbutil.run_to_source_breakpoint(self, "// break here",
lldb.SBFileSpec("main.cpp", False))
self.expect("expr str", substrs=['"abcd"'])

View File

@ -0,0 +1,7 @@
typedef char MCHAR;
int main() {
MCHAR str[5] = "abcd";
return 0; // break here
}

View File

@ -212,8 +212,10 @@ SBType SBType::GetArrayElementType() {
if (!IsValid())
return LLDB_RECORD_RESULT(SBType());
return LLDB_RECORD_RESULT(SBType(TypeImplSP(
new TypeImpl(m_opaque_sp->GetCompilerType(true).GetArrayElementType()))));
CompilerType canonical_type =
m_opaque_sp->GetCompilerType(true).GetCanonicalType();
return LLDB_RECORD_RESULT(
SBType(TypeImplSP(new TypeImpl(canonical_type.GetArrayElementType()))));
}
SBType SBType::GetArrayType(uint64_t size) {

View File

@ -230,11 +230,33 @@ void FormatManager::GetPossibleMatches(
if (non_ptr_type.IsTypedefType()) {
CompilerType deffed_pointed_type =
non_ptr_type.GetTypedefedType().GetPointerType();
const bool stripped_typedef = true;
GetPossibleMatches(
valobj, deffed_pointed_type,
reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
use_dynamic, entries, did_strip_ptr, did_strip_ref,
true); // this is not exactly the usual meaning of stripping typedefs
stripped_typedef); // this is not exactly the usual meaning of
// stripping typedefs
}
}
// For arrays with typedef-ed elements, we add a candidate with the typedef
// stripped.
uint64_t array_size;
if (compiler_type.IsArrayType(nullptr, &array_size, nullptr)) {
CompilerType element_type = compiler_type.GetArrayElementType();
if (element_type.IsTypedefType()) {
// Get the stripped element type and compute the stripped array type
// from it.
CompilerType deffed_array_type =
element_type.GetTypedefedType().GetArrayType(array_size);
const bool stripped_typedef = true;
GetPossibleMatches(
valobj, deffed_array_type,
reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
use_dynamic, entries, did_strip_ptr, did_strip_ref,
stripped_typedef); // this is not exactly the usual meaning of
// stripping typedefs
}
}

View File

@ -3924,7 +3924,7 @@ CompilerType
ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
uint64_t *stride) {
if (type) {
clang::QualType qual_type(GetCanonicalQualType(type));
clang::QualType qual_type(GetQualType(type));
const clang::Type *array_eletype =
qual_type.getTypePtr()->getArrayElementTypeNoTypeQual();
@ -3932,8 +3932,7 @@ ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
if (!array_eletype)
return CompilerType();
CompilerType element_type =
GetType(array_eletype->getCanonicalTypeUnqualified());
CompilerType element_type = GetType(clang::QualType(array_eletype, 0));
// TODO: the real stride will be >= this value.. find the real one!
if (stride)