Commit 53ff0e1c authored by hjk's avatar hjk
Browse files

Debugger: Add a workaround for bad gcc debug info generation

Gcc does not write out full type names with 'using template ...', see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80466



This is in most cases harmless for Creator as dumpers are triggered
independently of template arguments. However, if the dumper takes
different code path based on the template argument type, as is
e.g. needed for std::vector<bool>, wrong results are produced,
as the type cache only used the template base name as type id.

Work around by mangling the id of the un-typedef-ed type into
the type id of a typedef, which, in case of templates contain
the full parameter list.

Change-Id: I63c59cccdc186b09ff780e9dfd57b0ad668ae98f
Reviewed-by: Christian Stenger's avatarChristian Stenger <christian.stenger@qt.io>
parent e2be021c
......@@ -3637,7 +3637,9 @@ class DumperBase:
self.registerType(typeId, tdata)
return self.Type(self, typeId)
def createTypedefedType(self, targetType, typeId):
def createTypedefedType(self, targetType, typeName, typeId = None):
if typeId is None:
typeId = typeName
if not isinstance(targetType, self.Type):
error('Expected type in createTypedefType(), got %s'
% type(targetType))
......@@ -3645,12 +3647,13 @@ class DumperBase:
if targetType.typeId == typeId:
return targetType
tdata = self.TypeData(self)
tdata.name = typeId
tdata.name = typeName
tdata.typeId = typeId
tdata.code = TypeCodeTypedef
tdata.ltarget = targetType
tdata.lbitsize = targetType.lbitsize
#tdata.lfields = targetType.lfields
tdata.lbitsize = targetType.lbitsize
self.registerType(typeId, tdata)
return self.Type(self, typeId)
......
......@@ -315,7 +315,8 @@ class Dumper(DumperBase):
while nativeTargetType.code == gdb.TYPE_CODE_TYPEDEF:
nativeTargetType = nativeTargetType.strip_typedefs().unqualified()
targetType = self.fromNativeType(nativeTargetType)
return self.createTypedefedType(targetType, str(nativeType))
return self.createTypedefedType(targetType, str(nativeType),
self.nativeTypeId(nativeType))
if code == gdb.TYPE_CODE_ERROR:
warn('Type error: %s' % nativeType)
......@@ -408,6 +409,8 @@ class Dumper(DumperBase):
return '%d' % intval
def nativeTypeId(self, nativeType):
if nativeType.code == gdb.TYPE_CODE_TYPEDEF:
return '%s{%s}' % (nativeType, nativeType.strip_typedefs())
name = str(nativeType)
if len(name) == 0:
c = '0'
......
......@@ -526,7 +526,7 @@ struct Check
const Check &operator%(GccVersion version) const
{
enginesForCheck = GdbEngine;
enginesForCheck = NoCdbEngine;
gccVersionForCheck = version;
return *this;
}
......@@ -1330,6 +1330,7 @@ void tst_Dumpers::dumper()
"\n#endif"
"\n#ifdef __clang__"
"\n int clangversion = 10000 * __clang_major__ + 100 * __clang_minor__; unused(&clangversion);"
"\n gccversion = 0;"
"\n#else"
"\n int clangversion = 0; unused(&clangversion);"
"\n#endif"
......@@ -5451,6 +5452,30 @@ void tst_Dumpers::dumper_data()
+ Check("t2", "0", "myType2");
QTest::newRow("Typedef2")
<< Data("#include <vector>\n"
"template<typename T> using TVector = std::vector<T>;\n",
"std::vector<bool> b1(10); unused(&b1);\n"
"std::vector<int> b2(10); unused(&b2);\n"
"TVector<bool> b3(10); unused(&b3);\n"
"TVector<int> b4(10); unused(&b4);\n"
"TVector<bool> b5(10); unused(&b5);\n"
"TVector<int> b6(10); unused(&b6);\n")
+ NoCdbEngine
// The test is for a gcc bug
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80466,
// so check for any gcc version vs any other compiler
// (identified by gccversion == 0).
+ Check("b1", "<10 items>", "std::vector<bool>")
+ Check("b2", "<10 items>", "std::vector<int>")
+ Check("b3", "<10 items>", "TVector") % GccVersion(1)
+ Check("b4", "<10 items>", "TVector") % GccVersion(1)
+ Check("b5", "<10 items>", "TVector<bool>") % GccVersion(0, 0)
+ Check("b6", "<10 items>", "TVector<int>") % GccVersion(0, 0);
QTest::newRow("Struct")
<< Data(fooData,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment