diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbExpressionVMProvider.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbExpressionVMProvider.java index 55a4b2bc643..dbd2caf21ee 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbExpressionVMProvider.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbExpressionVMProvider.java @@ -7,9 +7,11 @@ * * Contributors: * Freescale Semiconductor - initial API and implementation + * Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel; +import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport; import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants; import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.DisabledExpressionVMNode; import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionManagerVMNode; @@ -21,6 +23,7 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterGroupVMNode; import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMNode; import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess; import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess; +import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode; @@ -32,6 +35,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * A specialization of ExpressionVMProvider that uses a GDB-specific variable VM * node. To understand why this is necessary, see GdbVariableVMNode. */ +@SuppressWarnings("restriction") public class GdbExpressionVMProvider extends ExpressionVMProvider { /** @@ -99,6 +103,11 @@ public class GdbExpressionVMProvider extends ExpressionVMProvider { IExpressionVMNode variableNode = new GdbVariableVMNode(this, getSession(), syncvarDataAccess); addChildNodes(variableNode, new IExpressionVMNode[] {variableNode}); + /* Wire up the casting support. IExpressions2 service is always available + * for gdb. No need to call hookUpCastingSupport */ + ((VariableVMNode) variableNode).setCastToTypeSupport( + new DsfCastToTypeSupport(getSession(), GdbExpressionVMProvider.this, syncvarDataAccess)); + /* * Tell the expression node which sub-nodes it will directly support. It is very important * that the variables node be the last in this chain. The model assumes that there is some diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMProvider.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMProvider.java index ac3e063c233..7df51ff683f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMProvider.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/viewmodel/GdbVariableVMProvider.java @@ -7,10 +7,13 @@ * * Contributors: * Freescale Semiconductor - initial API and implementation + * Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel; +import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport; import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess; +import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode; import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter; @@ -23,6 +26,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont * A specialization of VariableVMProvider that uses a GDB-specific variable VM * node. To understand why this is necessary, see GdbVariableVMNode. */ +@SuppressWarnings("restriction") public class GdbVariableVMProvider extends VariableVMProvider { /** @@ -49,6 +53,11 @@ public class GdbVariableVMProvider extends VariableVMProvider { IVMNode subExpressioNode = new GdbVariableVMNode(this, getSession(), varAccess); addChildNodes(rootNode, new IVMNode[] { subExpressioNode }); + /* Wire up the casting support. IExpressions2 service is always available + * for gdb. No need to call hookUpCastingSupport */ + ((VariableVMNode) subExpressioNode).setCastToTypeSupport( + new DsfCastToTypeSupport(getSession(), GdbVariableVMProvider.this, varAccess)); + // Configure the sub-expression node to be a child of itself. This way the content // provider will recursively drill-down the variable hierarchy. addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode }); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIExpressions.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIExpressions.java index 7407a56be86..cf2608bd761 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIExpressions.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIExpressions.java @@ -7,7 +7,8 @@ * * Contributors: * Wind River Systems - initial API and implementation - * Ericsson - Modified for handling of multiple execution contexts + * Ericsson - Modified for handling of multiple execution contexts + * Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -24,6 +25,7 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.ICachingService; import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions2; import org.eclipse.cdt.dsf.debug.service.IFormattedValues; import org.eclipse.cdt.dsf.debug.service.IRunControl; import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent; @@ -65,7 +67,7 @@ import org.osgi.framework.BundleContext; * * @since 2.0 */ -public class MIExpressions extends AbstractDsfService implements IExpressions, ICachingService { +public class MIExpressions extends AbstractDsfService implements IExpressions2, ICachingService { /** * A format that gives more details about an expression and supports pretty-printing @@ -478,6 +480,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I // Register this service. register(new String[] { IExpressions.class.getName(), + IExpressions2.class.getName(), MIExpressions.class.getName() }, new Hashtable()); @@ -1042,5 +1045,83 @@ public class MIExpressions extends AbstractDsfService implements IExpressions, I // to refresh them as well varManager.markAllOutOfDate(); } + + /** A casted or array-displayed expression. + * @since 3.0 */ + public class CastedExpressionDMC extends MIExpressionDMC implements ICastedExpressionDMContext { + + private final CastInfo castInfo; + /** if non-null, interpret result as this type rather than the raw expression's type */ + private String expression; + + public CastedExpressionDMC(MIExpressionDMC exprDMC, CastInfo castInfo) { + super(getSession().getId(), exprDMC.getExpression(), exprDMC.getRelativeExpression(), exprDMC); + this.castInfo = castInfo; + + String castType = castInfo.getTypeString(); + String castExpression = exprDMC.getExpression(); + int castingLength = castInfo.getArrayCount(); + int castingIndex = castInfo.getArrayStartIndex(); + + // cast to type + if (castType != null) { + StringBuffer buffer = new StringBuffer(); + buffer.append('(').append(castType).append(')'); + buffer.append('(').append(castExpression).append(')'); + castExpression = buffer.toString(); + } + + // cast to array (can be in addition to cast to type) + if (castingLength > 0) { + StringBuffer buffer = new StringBuffer(); + buffer.append("*("); //$NON-NLS-1$ + buffer.append('(').append(castExpression).append(')'); + buffer.append('+').append(castingIndex).append(')'); + buffer.append('@').append(castingLength); + castExpression = buffer.toString(); + } + this.expression = castExpression; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.IExpressions2.ICastedExpressionDMContext#getCastInfo() + */ + public CastInfo getCastInfo() { + return castInfo; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.mi.service.MIExpressions.java#getExpression() + */ + @Override + public String getExpression() { + return expression; + } + + /** + * @return True if the two objects are equal, false otherwise. + */ + @Override + public boolean equals(Object other) { + return super.equals(other) + && castInfo.equals(((CastedExpressionDMC) other).castInfo); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.service.IExpressions2#createCastedExpression(org.eclipse.cdt.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.cdt.dsf.debug.service.IExpressions2.ICastedExpressionDMContext) + */ + /** @since 3.0 */ + public ICastedExpressionDMContext createCastedExpression( + IExpressionDMContext exprDMC, CastInfo castInfo) { + if (exprDMC instanceof MIExpressionDMC) { + CastedExpressionDMC castedDMC = new CastedExpressionDMC( + (MIExpressionDMC) exprDMC, castInfo); + return castedDMC; + } else { + assert false; + return null; + } + } } 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 92a60e208a9..e526d9f8c61 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 @@ -10,6 +10,7 @@ * Ericsson - Modified for handling of multiple execution contexts * Ericsson - Major updates for GDB/MI implementation * Ericsson - Major re-factoring to deal with children + * Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service; @@ -28,6 +29,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.debug.service.IExpressions; import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.cdt.dsf.debug.service.IExpressions2.CastInfo; import org.eclipse.cdt.dsf.debug.service.IFormattedValues; import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; @@ -47,6 +49,7 @@ import org.eclipse.cdt.dsf.gdb.GDBTypeParser; import org.eclipse.cdt.dsf.gdb.GDBTypeParser.GDBType; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent; +import org.eclipse.cdt.dsf.mi.service.MIExpressions.CastedExpressionDMC; import org.eclipse.cdt.dsf.mi.service.MIExpressions.ExpressionInfo; import org.eclipse.cdt.dsf.mi.service.MIExpressions.MIExpressionDMC; import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; @@ -645,10 +648,21 @@ public class MIVariableManager implements ICommandControl { if (isArray()) { // We can trust the numChildrenHint value for arrays. ExpressionInfo[] childrenOfArray = new ExpressionInfo[getNumChildrenHint()]; + String exprName = exprDmc.getExpression(); + + int castingLength = 0; + int castingIndex = 0; + // in case of casts, need to resolve that before dereferencing, to be safe + if ( exprDmc instanceof CastedExpressionDMC ) { + CastInfo castInfo = ((CastedExpressionDMC)exprDmc).getCastInfo(); + castingLength = castInfo.getArrayCount(); + castingIndex = castInfo.getArrayStartIndex(); + if (castingLength > 0) + exprName = '(' + exprName + ')'; + } for (int i= 0; i < childrenOfArray.length; i++) { - String indexStr = "[" + i + "]";//$NON-NLS-1$//$NON-NLS-2$ - String fullExpr = exprDmc.getExpression() + indexStr; - String relExpr = exprDmc.getRelativeExpression() + indexStr; + String fullExpr = exprName + "[" + i + "]";//$NON-NLS-1$//$NON-NLS-2$ + String relExpr = exprDmc.getRelativeExpression() + "[" + (castingIndex + i) + "]";//$NON-NLS-1$//$NON-NLS-2$ childrenOfArray[i] = new ExpressionInfo(fullExpr, relExpr); }