diff --git a/share/qtcreator/dumper/gbridge.py b/share/qtcreator/dumper/gbridge.py index 1754af35ef3b3e430477f807af4ae7052c1b24ee..3995453ec9cec33bfe37075aa2f32e5d4bc712eb 100644 --- a/share/qtcreator/dumper/gbridge.py +++ b/share/qtcreator/dumper/gbridge.py @@ -1777,6 +1777,12 @@ class Dumper: self.put('",') return True + def isReferenceType(self, typeobj): + return typeobj.code == gdb.TYPE_CODE_REF + + def isStructType(self, typeobj): + return typeobj.code == gdb.TYPE_CODE_STRUCT + def putPlotData(self, type, base, n, plotFormat): if self.isExpanded(): self.putArrayData(type, base, n) diff --git a/share/qtcreator/dumper/lbridge.py b/share/qtcreator/dumper/lbridge.py index f1d49e8e0d868038a45feacfc1eb764e002e263a..e88c6157103b2ca810c92bc7f7ad3f7328d4e299 100644 --- a/share/qtcreator/dumper/lbridge.py +++ b/share/qtcreator/dumper/lbridge.py @@ -73,9 +73,6 @@ DisplayLatin1String, \ DisplayUtf8String \ = range(7) -def lookupType(name): - return None - def isSimpleType(typeobj): typeClass = typeobj.GetTypeClass() #warn("TYPECLASS: %s" % typeClass) @@ -179,36 +176,7 @@ def fileName(file): return str(file) if file.IsValid() else '' -PointerCode = None -ArrayCode = None -StructCode = None -UnionCode = None -EnumCode = None -FlagsCode = None -FunctionCode = None -IntCode = None -FloatCode = None -VoidCode = None -SetCode = None -RangeCode = None -StringCode = None -BitStringCode = None -ErrorTypeCode = None -MethodCode = None -MethodPointerCode = None -MemberPointerCode = None -ReferenceCode = None -CharCode = None -BoolCode = None -ComplexCode = None -TypedefCode = None -NamespaceCode = None -SimpleValueCode = None # LLDB only - - # Data members -SimpleValueCode = 100 -StructCode = 101 PointerCode = 102 # Breakpoints. Keep synchronized with BreakpointType in breakpoint.h @@ -245,7 +213,7 @@ def checkPointer(p, align = 1): p.Dereference() def isNull(p): - return long(p) == 0 + return p.GetValueAsUnsigned() == 0 Value = lldb.SBValue @@ -340,9 +308,6 @@ lldb.SBType.__str__ = lldb.SBType.GetName def simpleEncoding(typeobj): code = typeobj.GetTypeClass() size = typeobj.sizeof - #if code == BoolCode or code == CharCode: - # return Hex2EncodedInt1 - #if code == IntCode: if code == lldb.eTypeClassBuiltin: name = str(typeobj) if name == "float": @@ -390,7 +355,7 @@ class Children: #if isSimpleType(childType): # self.d.put('childnumchild="0",') # self.childNumChild = 0 - #elif childType.code == PointerCode: + #elif childType.code == lldb.eTypeClassPointer: # self.d.put('childnumchild="1",') # self.childNumChild = 1 else: @@ -469,6 +434,8 @@ class SubItem: self.d.put('{') #if not self.name is None: if isinstance(self.name, str): + if self.name == '**&': + self.name = '*' self.d.put('name="%s",' % self.name) self.savedIName = self.d.currentIName self.savedCurrentAddress = self.d.currentAddress @@ -597,7 +564,7 @@ class Dumper: def templateArgument(self, typeobj, index): type = typeobj.GetTemplateArgumentType(index) - if len(type.GetName()): + if type.IsValid(): return type inner = self.extractTemplateArgument(typeobj.GetName(), index) return self.lookupType(inner) @@ -606,6 +573,12 @@ class Dumper: inner = self.extractTemplateArgument(typeobj.GetName(), index) return int(inner) + def isReferenceType(self, typeobj): + return typeobj.IsReferenceType() + + def isStructType(self, typeobj): + return typeobj.GetTypeClass() in (lldb.eTypeClassStruct, lldb.eTypeClassClass) + def qtVersion(self): return 0x050000 @@ -678,10 +651,11 @@ class Dumper: return format def isMovableType(self, type): - if type.code == PointerCode: - return True - if isSimpleType(type): + if type.GetTypeClass() in (lldb.eTypeClassBuiltin, + lldb.eTypeClassPointer): return True + warn("MOVABLE: %s" % type) + warn("CODE: %s" % type.GetTypeClass()) return self.stripNamespaceFromType(type.GetName()) in movableTypes def putIntItem(self, name, value): @@ -745,7 +719,7 @@ class Dumper: return True def putPlotData(self, type, base, n, plotFormat): - warn("PLOTDATA: %s %s" % (type, n)) + #warn("PLOTDATA: %s %s" % (type, n)) if self.isExpanded(): self.putArrayData(type, base, n) self.putValue(self.currentValue) @@ -789,9 +763,14 @@ class Dumper: self.putFields(value) def lookupType(self, name): + if name.endswith('*'): + type = self.lookupType(name[:-1].strip()) + return type.GetPointerType() if type.IsValid() else None #warn("LOOKUP TYPE NAME: %s" % name) #warn("LOOKUP RESULT: %s" % self.target.FindFirstType(name)) - return self.target.FindFirstType(name) + #warn("LOOKUP RESULT: %s" % self.target.FindFirstType(name)) + type = self.target.FindFirstType(name) + return type if type.IsValid() else None def setupInferior(self, args): executable = args['executable'] @@ -942,6 +921,17 @@ class Dumper: contents = self.process.ReadMemory(base, size, error) return binascii.hexlify(contents) + def isQObject(self, value): + try: + vtable = value.Cast(self.voidPtrType().GetPointerType()) + metaObjectEntry = vtable.Dereference() + addr = lldb.SBAddress(long(metaObjectEntry), self.target) + symbol = addr.GetSymbol() + name = symbol.GetMangledName() + return name.find("10metaObjectEv") > 0 + except: + return False + def computeLimit(self, size, limit): if limit is None: return size @@ -967,6 +957,10 @@ class Dumper: pos1 = type.rfind(">", pos) type = type[0:pos] + type[pos1+1:] pos = type.find("<") + if type.startswith("const "): + type = type[6:] + if type.startswith("volatile "): + type = type[9:] return type def putSubItem(self, component, value, tryDynamic=True): @@ -987,6 +981,7 @@ class Dumper: #value = value.GetDynamicValue(lldb.eDynamicCanRunTarget) typeName = value.GetTypeName() value.SetPreferDynamicValue(tryDynamic) + typeClass = value.GetType().GetTypeClass() if tryDynamic: self.putAddress(value.address) @@ -1020,38 +1015,53 @@ class Dumper: value.SetPreferSyntheticValue(False) # Arrays - if value.GetType().GetTypeClass() == lldb.eTypeClassArray: + if typeClass == lldb.eTypeClassArray: qdump____c_style_array__(self, value) return # References if value.GetType().IsReferenceType(): origType = value.GetTypeName(); - type = value.GetType().GetDereferencedType() - addr = int(value.GetAddress()) & 0xFFFFFFFFFFFFFFFF + type = value.GetType().GetDereferencedType().GetUnqualifiedType() + addr = int(value) & 0xFFFFFFFFFFFFFFFF self.putItem(value.CreateValueFromAddress(None, addr, type)) + #self.putItem(value.CreateValueFromData(None, value.GetData(), type)) self.putBetterType(origType) return # Pointers - if value.GetType().IsPointerType() and self.autoDerefPointers: - + if value.GetType().IsPointerType(): if isNull(value): self.putType(typeName) self.putValue("0x0") self.putNumChild(0) return - innerType = value.GetType().GetPointeeType() - self.putType(innerType) - savedCurrentChildType = self.currentChildType - self.currentChildType = str(innerType) - inner = value.Dereference() - if inner.IsValid(): - self.putItem(inner) - self.currentChildType = savedCurrentChildType - self.put('origaddr="%s",' % value.address) - return + if self.autoDerefPointers: + innerType = value.GetType().GetPointeeType().GetUnqualifiedType() + self.putType(innerType) + savedCurrentChildType = self.currentChildType + self.currentChildType = str(innerType) + inner = value.Dereference() + if inner.IsValid(): + self.putItem(inner) + self.currentChildType = savedCurrentChildType + self.put('origaddr="%s",' % value.address) + return + + else: + numchild = value.GetNumChildren() + self.put('iname="%s",' % self.currentIName) + self.putType(typeName) + self.putValue('0x%x' % value.GetValueAsUnsigned()) + self.put('numchild="1",') + self.put('addr="0x%x",' % value.GetLoadAddress()) + if self.currentIName in self.expandedINames: + with Children(self): + child = value.Dereference() + with SubItem(self, child): + self.putItem(child) + #warn("VALUE: %s" % value) #warn("FANCY: %s" % self.useFancy) @@ -1066,12 +1076,24 @@ class Dumper: return # Normal value - v = value.GetValue() #numchild = 1 if value.MightHaveChildren() else 0 numchild = value.GetNumChildren() self.put('iname="%s",' % self.currentIName) self.putType(typeName) - self.putValue('' if v is None else v) + if typeClass == lldb.eTypeClassStruct or typeClass == lldb.eTypeClassClass: + if self.isQObject(value): + self.context = value + if not self.putQObjectNameValue(value): # Is this too expensive? + self.putEmptyValue() + else: + self.putEmptyValue() + else: + v = value.GetValue() + if v: + self.putValue(v) + else: + self.putEmptyValue() + self.put('numchild="%s",' % numchild) self.put('addr="0x%x",' % value.GetLoadAddress()) if self.currentIName in self.expandedINames: diff --git a/share/qtcreator/dumper/qttypes.py b/share/qtcreator/dumper/qttypes.py index 0b101ead969ac7afad9cc04538d33f9ebf59830e..5fa2d2aeab9bbf9176e8e892a7a978c5fb3d91f7 100644 --- a/share/qtcreator/dumper/qttypes.py +++ b/share/qtcreator/dumper/qttypes.py @@ -161,7 +161,7 @@ def qPutQObjectNameValue(d, value): # - QDynamicMetaObjectData *metaObject; extra = d.dereference(dd + 5 * ptrSize + 2 * intSize) if extra == 0: - return + return False # Offset of objectName in ExtraData: 6 pointer # - QVector<QObjectUserData *> userData; only #ifndef QT_NO_USERDATA @@ -174,9 +174,12 @@ def qPutQObjectNameValue(d, value): data, size, alloc = qByteArrayData(d, objectName) - if size > 0: - str = d.readRawMemory(data, 2 * size) - d.putValue(str, Hex4EncodedLittleEndian, 1) + if size == 0: + return False + + str = d.readRawMemory(data, 2 * size) + d.putValue(str, Hex4EncodedLittleEndian, 1) + return True except: pass @@ -1973,7 +1976,7 @@ def qdumpHelper__QVariant(d, value): sizePD = d.lookupType(d.ns + 'QVariant::Private::Data').sizeof if innerType.sizeof > sizePD: sizePS = d.lookupType(d.ns + 'QVariant::PrivateShared').sizeof - val = (sizePS + data.cast(d.charPtrType())) \ + val = (data.cast(d.charPtrType()) + sizePS) \ .cast(innerType.pointer()).dereference() else: val = data.cast(innerType) @@ -2573,7 +2576,7 @@ def qdump__boost__optional(d, value): else: type = d.templateArgument(value.type, 0) storage = value["m_storage"] - if type.code == ReferenceCode: + if d.isReferenceType(type): d.putItem(storage.cast(type.target().pointer()).dereference()) else: d.putItem(storage.cast(type)) @@ -2925,7 +2928,7 @@ def qdump__Eigen__Matrix(d, value): nrows = value["m_storage"]["m_rows"] if argRow == -1 else int(argRow) ncols = value["m_storage"]["m_cols"] if argCol == -1 else int(argCol) p = storage["m_data"] - if p.type.code == StructCode: # Static + if d.isStructType(p.type): # Static p = p["array"].cast(innerType.pointer()) d.putValue("(%s x %s), %s" % (nrows, ncols, ["ColumnMajor", "RowMajor"][rowMajor])) d.putField("keeporder", "1") diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index b55b118cdb2a84f8c531a4ce3543960ec495a5b5..db4dfc14c5eb9f2566532e5de3e8e64cd08c2e48 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -3138,16 +3138,28 @@ void tst_Dumpers::dumper_data() % Check("this.@1", "[@QThread]", "\"This is thread #3\"", "@QThread") % Check("this.@1.@1", "[@QObject]", "\"This is thread #3\"", "@QObject"); - QTest::newRow("QVariant1") + QTest::newRow("QVariant0") << Data("#include <QVariant>\n", "QVariant value;\n" "QVariant::Type t = QVariant::String;\n" "value = QVariant(t, (void*)0);\n" "*(QString*)value.data() = QString(\"Some string\");\n") % CoreProfile() + % GdbOnly() % Check("t", "@QVariant::String (10)", "@QVariant::Type") % Check("value", "\"Some string\"", "@QVariant (QString)"); + QTest::newRow("QVariant1") + << Data("#include <QVariant>\n", + "QVariant value;\n" + "QVariant::Type t = QVariant::String;\n" + "value = QVariant(t, (void*)0);\n" + "*(QString*)value.data() = QString(\"Some string\");\n") + % CoreProfile() + % LldbOnly() + % Check("t", "String", "@QVariant::Type") + % Check("value", "\"Some string\"", "@QVariant (QString)"); + QTest::newRow("QVariant2") << Data("#include <QVariant>\n" "#include <QRect>\n"