mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 01:15:29 +02:00
Bug 376901 - DSF-GDB should properly handle variable type change (based
on RTTI) Change-Id: I9869900530792ec102f39950c0dbf23d0c4ca160 Reviewed-on: https://git.eclipse.org/r/5602 Reviewed-by: Jens Elmenthaler <jens.elmenthaler@me.com> Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com> IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com> Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
This commit is contained in:
parent
5d74bf2eaf
commit
a5fd3894d1
3 changed files with 113 additions and 13 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2011 Monta Vista and others.
|
||||
* Copyright (c) 2008, 2012 Monta Vista and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -13,6 +13,7 @@
|
|||
* Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
* Axel Mueller - Workaround for GDB bug where -var-info-path-expression gives invalid result (Bug 320277)
|
||||
* Anton Gorenkov - DSF-GDB should properly handle variable type change (based on RTTI) (Bug 376901)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
|
@ -367,6 +368,8 @@ public class MIVariableManager implements ICommandControl {
|
|||
// The children of this variable, if any.
|
||||
// Null means we didn't fetch them yet, while an empty array means no children
|
||||
private ExpressionInfo[] children = null;
|
||||
// we need to keep track of fake children because they are in the LRU and need to be removed in some cases.
|
||||
private List<ExpressionInfo> fakeChildren = new ArrayList<ExpressionInfo>(3);
|
||||
private boolean hasMore = false;
|
||||
private MIDisplayHint displayHint = MIDisplayHint.NONE;
|
||||
|
||||
|
@ -504,11 +507,14 @@ public class MIVariableManager implements ICommandControl {
|
|||
public boolean isPointer() { return (getGDBType() == null) ? false : getGDBType().getType() == GDBType.POINTER; }
|
||||
public boolean isMethod() { return (getGDBType() == null) ? false : getGDBType().getType() == GDBType.FUNCTION; }
|
||||
// A complex variable is one with children. However, it must not be a pointer since a pointer
|
||||
// does have children, but is still a 'simple' variable, as it can be modifed.
|
||||
// does have children, but is still a 'simple' variable, as it can be modified.
|
||||
// A reference can be modified too, because it can be a reference to the base class before initialization
|
||||
// and after initialization it can become a reference to the derived class (if gdb shows the value type and
|
||||
// children taking into account RTTI ("set print object on")).
|
||||
// Note that the numChildrenHint can be trusted when asking if the number of children is 0 or not
|
||||
public boolean isComplex() {
|
||||
return (getGDBType() == null) ? false
|
||||
: getGDBType().getType() != GDBType.POINTER
|
||||
: getGDBType().getType() != GDBType.POINTER && getGDBType().getType() != GDBType.REFERENCE
|
||||
&& (getNumChildrenHint() > 0
|
||||
|| hasMore() || getDisplayHint().isCollectionHint());
|
||||
}
|
||||
|
@ -559,7 +565,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
|
||||
/**
|
||||
* @param info
|
||||
* @param t
|
||||
* @param typeName
|
||||
* @param num
|
||||
* If the correspinding MI variable is dynamic, the number of
|
||||
* children currently fetched by gdb.
|
||||
|
@ -568,13 +574,20 @@ public class MIVariableManager implements ICommandControl {
|
|||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setExpressionData(ExpressionInfo info, String t, int num, boolean hasMore) {
|
||||
public void setExpressionData(ExpressionInfo info, String typeName, int num, boolean hasMore) {
|
||||
exprInfo = info;
|
||||
type = t;
|
||||
gdbType = fGDBTypeParser.parse(t);
|
||||
setType(typeName);
|
||||
numChildrenHint = num;
|
||||
this.hasMore = hasMore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setType(String newTypeName) {
|
||||
type = newTypeName;
|
||||
gdbType = fGDBTypeParser.parse(newTypeName);
|
||||
}
|
||||
|
||||
public void setValue(String format, String val) { valueMap.put(format, val); }
|
||||
|
||||
|
@ -680,6 +693,47 @@ public class MIVariableManager implements ICommandControl {
|
|||
|
||||
numChildrenHint = newNumChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified child from LRU and makes the cleanup on its
|
||||
* children (if any).
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
private void cleanupChild(ExpressionInfo child) {
|
||||
String childFullExpression = child.getFullExpr();
|
||||
VariableObjectId childId = new VariableObjectId();
|
||||
childId.generateId(childFullExpression, getInternalId());
|
||||
MIVariableObject varobjOfChild = lruVariableList.remove(childId);
|
||||
if (varobjOfChild != null) {
|
||||
// Remove it from the list of modifiable descendants
|
||||
getRootToUpdate().removeModifiableDescendant(varobjOfChild.getGdbName());
|
||||
// Remove children recursively
|
||||
varobjOfChild.cleanupChildren();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the children (real and fake) of the variable object from
|
||||
* LRU cache and from variable object itself. It is used when the type
|
||||
* of variable was changed.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public void cleanupChildren() {
|
||||
hasMore = false;
|
||||
if (children != null) {
|
||||
for (ExpressionInfo child : children) {
|
||||
cleanupChild(child);
|
||||
}
|
||||
children = null;
|
||||
numChildrenHint = 0;
|
||||
}
|
||||
for (ExpressionInfo fakeChild : fakeChildren) {
|
||||
cleanupChild(fakeChild);
|
||||
}
|
||||
fakeChildren.clear();
|
||||
}
|
||||
|
||||
public void setParent(MIVariableObject p) {
|
||||
parent = p;
|
||||
|
@ -799,6 +853,19 @@ public class MIVariableManager implements ICommandControl {
|
|||
*/
|
||||
protected void processChange(final MIVarChange update, final RequestMonitor rm) {
|
||||
|
||||
// Handle the variable type change properly
|
||||
if (update.isChanged()) {
|
||||
setType(update.getNewType());
|
||||
cleanupChildren();
|
||||
editable = null;
|
||||
updateLimit(IMIExpressions.CHILD_COUNT_LIMIT_UNSPECIFIED);
|
||||
}
|
||||
|
||||
// These properties of the variable will probably not change,
|
||||
// but if they are - we should handle it properly.
|
||||
setDisplayHint(update.getDisplayHint());
|
||||
exprInfo.setDynamic(update.isDynamic());
|
||||
|
||||
MIVar[] newChildren = update.getNewChildren();
|
||||
|
||||
// children == null means fetchChildren will happen later, so
|
||||
|
@ -850,7 +917,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
rm.done();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Process all the child MIVariableObjects.
|
||||
int pendingVariableCreationCount = 0;
|
||||
if (newChildren != null && newChildren.length != 0) {
|
||||
|
@ -1441,7 +1508,9 @@ public class MIVariableManager implements ICommandControl {
|
|||
var.hasCastToBaseClassWorkaround = childHasCastToBaseClassWorkaround;
|
||||
|
||||
if (fakeChild) {
|
||||
|
||||
if (! isSuccess()) {
|
||||
fakeChildren.add(var.exprInfo);
|
||||
}
|
||||
addRealChildrenOfFake(var, exprDmc, realChildren,
|
||||
arrayPosition, countingRm);
|
||||
} else {
|
||||
|
@ -1451,7 +1520,6 @@ public class MIVariableManager implements ICommandControl {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
} else if (childVar.currentState == STATE_CREATION_FAILED) {
|
||||
// There has been an attempt the create a MIRootVariableObject for a full
|
||||
// expression representing a child of a dynamic varobj. Such an attempt always
|
||||
|
@ -1473,7 +1541,7 @@ public class MIVariableManager implements ICommandControl {
|
|||
childVar.hasCastToBaseClassWorkaround = childHasCastToBaseClassWorkaround;
|
||||
|
||||
if (fakeChild) {
|
||||
|
||||
fakeChildren.add(childVar.exprInfo);
|
||||
addRealChildrenOfFake(childVar, exprDmc, realChildren,
|
||||
arrayPosition, countingRm);
|
||||
} else {
|
||||
|
@ -2021,6 +2089,17 @@ public class MIVariableManager implements ICommandControl {
|
|||
modifiableDescendants.put(gdbName, descendant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the descendant with the specified name from the collection of
|
||||
* modifiable descendants. Does nothing if there is no child with such
|
||||
* name.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
public void removeModifiableDescendant(String gdbName) {
|
||||
modifiableDescendants.remove(gdbName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2010 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2012 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
* Anton Gorenkov - DSF-GDB should properly handle variable type change (based on RTTI) (Bug 376901)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
|
@ -21,6 +22,7 @@ public class MIVarChange {
|
|||
String value;
|
||||
boolean inScope;
|
||||
boolean changed;
|
||||
private String newType;
|
||||
private boolean isDynamic = false;
|
||||
private int newNumChildren = -1;
|
||||
private boolean hasMore = false;
|
||||
|
@ -47,6 +49,13 @@ public class MIVarChange {
|
|||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public String getNewType() {
|
||||
return newType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the associated variable's value and children are provided
|
||||
* by a pretty printer.
|
||||
|
@ -117,6 +126,13 @@ public class MIVarChange {
|
|||
changed = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNewType(String newType) {
|
||||
this.newType = newType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2010 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2012 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
* Anton Gorenkov - DSF-GDB should properly handle variable type change (based on RTTI) (Bug 376901)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
|
@ -99,6 +100,10 @@ public class MIVarUpdateInfo extends MIInfo {
|
|||
if (change != null) {
|
||||
change.setChanged("true".equals(str)); //$NON-NLS-1$
|
||||
}
|
||||
} else if (var.equals("new_type")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
change.setNewType(str);
|
||||
}
|
||||
} else if (var.equals("new_num_children")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
try {
|
||||
|
|
Loading…
Add table
Reference in a new issue