From bb8aed629f9e48f4a47a6acaae0cd5a80c7e2291 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Fri, 2 Jul 2010 09:57:22 +0200
Subject: [PATCH] debugger: make type lookup more robust

... by stripping out 'const', 'volatile', 'struct' and 'class'.
---
 share/qtcreator/gdbmacros/dumper.py | 110 ++++++++++++++++++----------
 1 file changed, 72 insertions(+), 38 deletions(-)

diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index 106d537acf9..e6ffdbd8a20 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -92,12 +92,45 @@ typeCache = {}
 
 def lookupType(typestring):
     type = typeCache.get(typestring)
-    #warn("LOOKUP: %s -> %s" % (typestring, type))
+    #warn("LOOKUP 1: %s -> %s" % (typestring, type))
     if type is None:
-        type = gdb.lookup_type(typestring)
+        ts = typestring
+        while True:
+            #WARN("ts: '%s'" % ts)
+            if ts.startswith("class "):
+                ts = ts[6:]
+            elif ts.startswith("struct "):
+                ts = ts[7:]
+            elif ts.startswith("const "):
+                ts = ts[6:]
+            elif ts.startswith("volatile "):
+                ts = ts[9:]
+            elif ts.startswith("const "):
+                ts = ts[6:]
+            elif ts.startswith("volatile "):
+                ts = ts[9:]
+            elif ts.endswith("const"):
+                ts = ts[-5:]
+            elif ts.endswith("volatile"):
+                ts = ts[-8:]
+            else:
+                break
+        try:
+            #warn("LOOKING UP '%s'" % ts)
+            type = gdb.lookup_type(ts)
+        except:
+            # Can throw "RuntimeError: No type named class Foo."
+            #warn("LOOKING UP '%s' FAILED" % ts)
+            pass
+        #warn("  RESULT: '%s'" % type)
+        #if not type is None:
+        #    warn("  FIELDS: '%s'" % type.fields())
         typeCache[typestring] = type
     return type
 
+def cleanType(type):
+    return lookupType(str(type))
+
 def cleanAddress(addr):
     if addr is None:
         return "<no address>"
@@ -595,6 +628,10 @@ def stripClassTag(type):
         return type[6:]
     elif type.startswith("struct "):
         return type[7:]
+    elif type.startswith("const "):
+        return type[6:]
+    elif type.startswith("volatile "):
+        return type[9:]
     return type
 
 def checkPointerRange(p, n):
@@ -755,12 +792,27 @@ def encodeString(value):
         p += 1
     return s
 
-def stripTypedefs(typeobj):
-    type = typeobj
+def stripTypedefs(type):
+    type = type.unqualified()
     while type.code == gdb.TYPE_CODE_TYPEDEF:
         type = type.strip_typedefs().unqualified()
     return type
 
+def extractFields(type):
+    # Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953:
+    #fields = value.type.fields()
+    # Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=11777:
+    #fields = stripTypedefs(value.type).fields()
+    # This seems to work.
+    #warn("TYPE 0: %s" % type)
+    type = stripTypedefs(type)
+    #warn("TYPE 1: %s" % type)
+    type = lookupType(str(type))
+    #warn("TYPE 2: %s" % type)
+    fields = type.fields()
+    #warn("FIELDS: %s" % fields)
+    return fields
+
 #######################################################################
 #
 # Item
@@ -1296,17 +1348,26 @@ class Dumper:
 
 
         elif typedefStrippedType.code == gdb.TYPE_CODE_PTR:
-            #warn("POINTER: %s" % format)
+            warn("POINTER: %s" % format)
             isHandled = False
             target = stripTypedefs(type.target())
 
+            if (not isHandled) and isNull(value):
+                warn("NULL POINTER")
+                self.putType(item.value.type)
+                self.putValue("0x0")
+                self.putNumChild(0)
+                isHandled = True
+
             if (not isHandled) and target.code == gdb.TYPE_CODE_VOID:
+                warn("VOID POINTER: %s" % format)
                 self.putType(item.value.type)
                 self.putValue(str(value))
                 self.putNumChild(0)
                 isHandled = True
 
             if (not isHandled) and (not format is None):
+                warn("SPECIAL FORMAT POINTER: %s" % format)
                 self.putAddress(value.address)
                 self.putType(item.value.type)
                 isHandled = True
@@ -1328,10 +1389,8 @@ class Dumper:
                     self.putValue(encodeChar4Array(value, 100), Hex8EncodedBigEndian)
                     self.putNumChild(0)
 
-            if (not isHandled):
-                anonStrippedType = str(typedefStrippedType) \
-                    .replace("(anonymous namespace)", "")
-                if anonStrippedType.find("(") != -1:
+            if (not isHandled) and (str(typedefStrippedType) 
+                    .replace("(anonymous namespace)", "").find("(") != -1):
                     # A function pointer.
                     self.putValue(str(item.value))
                     self.putAddress(value.address)
@@ -1339,25 +1398,12 @@ class Dumper:
                     self.putNumChild(0)
                     isHandled = True
 
-            if (not isHandled) and self.useFancy:
-                if isNull(value):
-                    self.putValue("0x0")
-                    self.putType(item.value.type)
-                    self.putNumChild(0)
-                    isHandled = True
-
-                if (not isHandled):
-                    self.putType(item.value.type)
-                    self.putValue(str(value))
-                    self.putNumChild(0)
-                    isHandled = True
-
             #warn("AUTODEREF: %s" % self.autoDerefPointers)
             #warn("IS HANDLED: %s" % isHandled)
             #warn("RES: %s" % (self.autoDerefPointers and not isHandled))
             if (not isHandled) and (self.autoDerefPointers or name == "this"):
                 ## Generic pointer type.
-                #warn("GENERIC AUTODEREF POINTER: %s" % value.address)
+                warn("GENERIC AUTODEREF POINTER: %s" % value.address)
                 innerType = item.value.type.target()
                 self.putType(innerType)
                 savedCurrentChildType = self.currentChildType
@@ -1392,21 +1438,11 @@ class Dumper:
                 self.listAnonymous(item, "#%d" % self.anonNumber, type)
 
         else:
-            #warn("GENERIC STRUCT: %s" % item.value.type)
+            warn("GENERIC STRUCT: %s" % item.value.type)
             #warn("INAME: %s " % item.iname)
             #warn("INAMES: %s " % self.expandedINames)
             #warn("EXPANDED: %s " % (item.iname in self.expandedINames))
-
-            # Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=10953
-            #fields = value.type.fields()
-
-            # Insufficient, see http://sourceware.org/bugzilla/show_bug.cgi?id=11777
-            #fields = stripTypedefs(value.type).fields()
-
-            # This seems to work.
-            type = stripTypedefs(type)
-            type = lookupType(str(type))
-            fields = type.fields()
+            fields = extractFields(type)
 
             self.putType(item.value.type)
             try:
@@ -1444,9 +1480,7 @@ class Dumper:
     def putFields(self, item, innerType = None):
             value = item.value
             type = stripTypedefs(value.type)
-            # http://sourceware.org/bugzilla/show_bug.cgi?id=11777
-            type = lookupType(str(type))
-            fields = stripTypedefs(type).fields()
+            fields = extractFields(type)
             baseNumber = 0
             for field in fields:
                 #warn("FIELD: %s" % field)
-- 
GitLab