forked from qt-creator/qt-creator
Debugger: Support rvalue references in functions args with gdb
Change-Id: I5383ffa38f07e3f191619555a9e735c211b3dd8b Reviewed-by: Marco Bubke <marco.bubke@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -120,7 +120,8 @@ TypeCodeMemberPointer, \
|
||||
TypeCodeFortranString, \
|
||||
TypeCodeUnresolvable, \
|
||||
TypeCodeBitfield, \
|
||||
= range(0, 15)
|
||||
TypeCodeRValueReference, \
|
||||
= range(0, 16)
|
||||
|
||||
def isIntegralTypeName(name):
|
||||
return name in ('int', 'unsigned int', 'signed int',
|
||||
@@ -2784,7 +2785,7 @@ class DumperBase:
|
||||
self.putType(typeobj.name)
|
||||
return
|
||||
|
||||
if typeobj.code == TypeCodeReference:
|
||||
if typeobj.code in (TypeCodeReference, TypeCodeRValueReference):
|
||||
#warn('REFERENCE VALUE: %s' % value)
|
||||
val = value.dereference()
|
||||
if val.laddress != 0:
|
||||
@@ -3040,7 +3041,7 @@ class DumperBase:
|
||||
self.check()
|
||||
if self.type.code == TypeCodeTypedef:
|
||||
return self.findMemberByName(self.detypedef())
|
||||
if self.type.code in (TypeCodePointer, TypeCodeReference):
|
||||
if self.type.code in (TypeCodePointer, TypeCodeReference, TypeCodeRValueReference):
|
||||
res = self.dereference().findMemberByName(name)
|
||||
if res is not None:
|
||||
return res
|
||||
@@ -3114,7 +3115,7 @@ class DumperBase:
|
||||
|
||||
if self.type.code == TypeCodeTypedef:
|
||||
return self.cast(self.type.ltarget).extractField(field)
|
||||
if self.type.code == TypeCodeReference:
|
||||
if self.type.code in (TypeCodeReference, TypeCodeRValueReference):
|
||||
return self.dereference().extractField(field)
|
||||
#warn('FIELD: %s ' % field)
|
||||
val = self.dumper.Value(self.dumper)
|
||||
@@ -3159,7 +3160,7 @@ class DumperBase:
|
||||
else:
|
||||
self.dumper.check(False)
|
||||
|
||||
if fieldType.code == TypeCodeReference:
|
||||
if fieldType.code in (TypeCodeReference, TypeCodeRValueReference):
|
||||
if val.laddress is not None:
|
||||
val = self.dumper.createReferenceValue(val.laddress, fieldType.ltarget)
|
||||
val.name = field.name
|
||||
@@ -3228,7 +3229,7 @@ class DumperBase:
|
||||
if self.type.code == TypeCodeTypedef:
|
||||
return self.detypedef().dereference()
|
||||
val = self.dumper.Value(self.dumper)
|
||||
if self.type.code == TypeCodeReference:
|
||||
if self.type.code in (TypeCodeReference, TypeCodeRValueReference):
|
||||
val.summary = self.summary
|
||||
if self.nativeValue is None:
|
||||
val.laddress = self.pointer()
|
||||
@@ -3586,7 +3587,7 @@ class DumperBase:
|
||||
# Crude approximation.
|
||||
return 8 if self.dumper.isWindowsTarget() else self.dumper.ptrSize()
|
||||
return self.size()
|
||||
if tdata.code in (TypeCodePointer, TypeCodeReference):
|
||||
if tdata.code in (TypeCodePointer, TypeCodeReference, TypeCodeRValueReference):
|
||||
return self.dumper.ptrSize()
|
||||
if tdata.lalignment is not None:
|
||||
#if isinstance(tdata.lalignment, function): # Does not work that way.
|
||||
@@ -3743,6 +3744,20 @@ class DumperBase:
|
||||
self.registerType(typeId, tdata)
|
||||
return self.Type(self, typeId)
|
||||
|
||||
def createRValueReferenceType(self, targetType):
|
||||
if not isinstance(targetType, self.Type):
|
||||
error('Expected type in createRValueReferenceType(), got %s'
|
||||
% type(targetType))
|
||||
typeId = targetType.typeId + ' &&'
|
||||
tdata = self.TypeData(self)
|
||||
tdata.name = targetType.name + ' &&'
|
||||
tdata.typeId = typeId
|
||||
tdata.code = TypeCodeRValueReference
|
||||
tdata.ltarget = targetType
|
||||
tdata.lbitsize = None
|
||||
self.registerType(typeId, tdata)
|
||||
return self.Type(self, typeId)
|
||||
|
||||
def createArrayType(self, targetType, count):
|
||||
if not isinstance(targetType, self.Type):
|
||||
error('Expected type in createArrayType(), got %s'
|
||||
|
@@ -309,6 +309,11 @@ class Dumper(DumperBase):
|
||||
targetType = self.fromNativeType(nativeType.target().unqualified())
|
||||
return self.createReferenceType(targetType)
|
||||
|
||||
if code == gdb.TYPE_CODE_RVALUE_REF:
|
||||
#warn('RVALUEREF')
|
||||
targetType = self.fromNativeType(nativeType.target())
|
||||
return self.createRValueReferenceType(targetType)
|
||||
|
||||
if code == gdb.TYPE_CODE_ARRAY:
|
||||
#warn('ARRAY')
|
||||
nativeTargetType = nativeType.target().unqualified()
|
||||
|
@@ -59,7 +59,9 @@ enum TypeCodes {
|
||||
TypeCodeFunction,
|
||||
TypeCodeMemberPointer,
|
||||
TypeCodeFortranString,
|
||||
TypeCodeUnresolvable
|
||||
TypeCodeUnresolvable,
|
||||
TypeCodeBitField,
|
||||
TypeCodeRValueReference,
|
||||
};
|
||||
|
||||
static bool isType(const std::string &typeName, const std::vector<std::string> &types)
|
||||
|
@@ -5976,6 +5976,17 @@ void tst_Dumpers::dumper_data()
|
||||
+ Check("x2", "", "X &")
|
||||
+ Check("x3", "", "X &");
|
||||
|
||||
QTest::newRow("RValueReference")
|
||||
<< Data("",
|
||||
"struct S { int a = 32; };\n"
|
||||
"auto foo = [](int && i, S && s) { BREAK; return i + s.a; };\n"
|
||||
"foo(int(1), S());\n")
|
||||
+ Cxx11Profile()
|
||||
+ GdbVersion(80200)
|
||||
+ Check("i", "1", "int &&")
|
||||
+ CheckType("s", "S &&")
|
||||
+ Check("s.a", "32", "int");
|
||||
|
||||
QTest::newRow("SSE")
|
||||
<< Data("#include <xmmintrin.h>\n"
|
||||
"#include <stddef.h>\n",
|
||||
|
Reference in New Issue
Block a user