Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIVariableManager.java101
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarChange.java18
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarUpdateInfo.java7
3 files changed, 113 insertions, 13 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIVariableManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIVariableManager.java
index 2aa69e0d216..86b3809040b 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIVariableManager.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIVariableManager.java
@@ -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 {
@@ -2022,6 +2090,17 @@ public class MIVariableManager implements ICommandControl {
}
/**
+ * 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
*/
public void processChanges(MIVarChange[] updates, RequestMonitor rm) {
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarChange.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarChange.java
index dd5c45fc9d8..ee2ea03607c 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarChange.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarChange.java
@@ -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;
@@ -48,6 +50,13 @@ public class MIVarChange {
}
/**
+ * @since 4.1
+ */
+ public String getNewType() {
+ return newType;
+ }
+
+ /**
* @return Whether the associated variable's value and children are provided
* by a pretty printer.
*
@@ -118,6 +127,13 @@ public class MIVarChange {
}
/**
+ * @since 4.1
+ */
+ public void setNewType(String newType) {
+ this.newType = newType;
+ }
+
+ /**
* @since 4.0
*/
public void setDynamic(boolean isDynamic) {
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarUpdateInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarUpdateInfo.java
index 78438adcec4..d1fd9f49dfd 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarUpdateInfo.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIVarUpdateInfo.java
@@ -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 {

Back to the top