Author: Jaroslav Sevcik
Date: 2020-01-10T11:45:24+01:00
New Revision: 902974277d507a149e33487d32e4ba58c41451b6

URL: 
https://github.com/llvm/llvm-project/commit/902974277d507a149e33487d32e4ba58c41451b6
DIFF: 
https://github.com/llvm/llvm-project/commit/902974277d507a149e33487d32e4ba58c41451b6.diff

LOG: 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

Added: 
    
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/Makefile
    
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/TestArrayTypedef.py
    
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/main.cpp

Modified: 
    lldb/source/API/SBType.cpp
    lldb/source/DataFormatters/FormatManager.cpp
    lldb/source/Symbol/ClangASTContext.cpp

Removed: 
    


################################################################################
diff  --git 
a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/Makefile
 
b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/Makefile
new file mode 100644
index 000000000000..99998b20bcb0
--- /dev/null
+++ 
b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules

diff  --git 
a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/TestArrayTypedef.py
 
b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/TestArrayTypedef.py
new file mode 100644
index 000000000000..1f2914ad6336
--- /dev/null
+++ 
b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/TestArrayTypedef.py
@@ -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"'])

diff  --git 
a/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/main.cpp
 
b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/main.cpp
new file mode 100644
index 000000000000..5c581b07ace6
--- /dev/null
+++ 
b/lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/array_typedef/main.cpp
@@ -0,0 +1,7 @@
+typedef char MCHAR;
+
+int main() {
+  MCHAR str[5] = "abcd";
+  return 0;  // break here
+}
+

diff  --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index 8efc701a79fb..33b67ad4c004 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -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) {

diff  --git a/lldb/source/DataFormatters/FormatManager.cpp 
b/lldb/source/DataFormatters/FormatManager.cpp
index 08fc56a72eab..d5db3ee75bf3 100644
--- a/lldb/source/DataFormatters/FormatManager.cpp
+++ b/lldb/source/DataFormatters/FormatManager.cpp
@@ -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
     }
   }
 

diff  --git a/lldb/source/Symbol/ClangASTContext.cpp 
b/lldb/source/Symbol/ClangASTContext.cpp
index c846e410acfa..0cc83254947e 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -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)


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to