Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2015-03-10 19:22:52 +0000
committerEugene Tarassov2015-03-10 19:22:52 +0000
commit09d7b0b7c4ba6ae8a83e173f4b13d9af85d1cf34 (patch)
tree925f55f008bef91135907989d2614ac7006f41f0
parent4904421444e5f3cb06871c5216c2666d82450cff (diff)
downloadorg.eclipse.tcf-09d7b0b7c4ba6ae8a83e173f4b13d9af85d1cf34.tar.gz
org.eclipse.tcf-09d7b0b7c4ba6ae8a83e173f4b13d9af85d1cf34.tar.xz
org.eclipse.tcf-09d7b0b7c4ba6ae8a83e173f4b13d9af85d1cf34.zip
TCF Debugger: fixed: Step Into Selection is disabled in the TCF debugger
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF4
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/plugin.xml3
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFNodeAdapterFactory.java141
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/StepIntoSelectionLocation.java457
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/TCFStepIntoSelectionHandler.java239
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java1
6 files changed, 780 insertions, 65 deletions
diff --git a/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF
index 04b209730..f6ae7b9c8 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF
@@ -21,7 +21,9 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.jface.text;bundle-version="3.8.1",
org.eclipse.core.expressions;bundle-version="3.4.400",
org.eclipse.cdt.launch;bundle-version="7.1.0",
- org.eclipse.cdt.dsf.ui;bundle-version="2.3.0"
+ org.eclipse.cdt.dsf.ui;bundle-version="2.3.0",
+ org.eclipse.ui.editors,
+ org.eclipse.ui.workbench
Bundle-ActivationPolicy: lazy
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/plugins/org.eclipse.tcf.cdt.ui/plugin.xml b/plugins/org.eclipse.tcf.cdt.ui/plugin.xml
index d06d68709..835a9cd58 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/plugin.xml
+++ b/plugins/org.eclipse.tcf.cdt.ui/plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?><!--
- Copyright (c) 2010, 2014 Wind River Systems, Inc. and others.
+ Copyright (c) 2010, 2015 Wind River Systems, Inc. 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
@@ -29,6 +29,7 @@
<adapter type="org.eclipse.cdt.debug.core.model.IReverseStepIntoHandler"/>
<adapter type="org.eclipse.cdt.debug.core.model.IReverseStepOverHandler"/>
<adapter type="org.eclipse.cdt.debug.core.model.IReverseResumeHandler"/>
+ <adapter type="org.eclipse.cdt.debug.core.model.IStepIntoSelectionHandler"/>
<adapter type="org.eclipse.cdt.debug.core.model.IUncallHandler"/>
<adapter type="org.eclipse.cdt.debug.ui.IPinProvider"/>
<adapter type="org.eclipse.cdt.debug.core.ICWatchpointTarget"/>
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFNodeAdapterFactory.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFNodeAdapterFactory.java
index d112ddb86..1c9d6ece9 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFNodeAdapterFactory.java
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFNodeAdapterFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2012 Wind River Systems, Inc. and others.
+ * Copyright (c) 2010, 2015 Wind River Systems, Inc. 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
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.tcf.internal.cdt.ui;
+import java.util.ArrayList;
+
import org.eclipse.cdt.debug.core.model.IReverseResumeHandler;
import org.eclipse.cdt.debug.core.model.IReverseStepIntoHandler;
import org.eclipse.cdt.debug.core.model.IReverseStepOverHandler;
@@ -29,6 +31,7 @@ import org.eclipse.tcf.internal.cdt.ui.commands.TCFReverseStepIntoCommand;
import org.eclipse.tcf.internal.cdt.ui.commands.TCFReverseStepOverCommand;
import org.eclipse.tcf.internal.cdt.ui.commands.TCFReverseStepReturnCommand;
import org.eclipse.tcf.internal.cdt.ui.commands.TCFReverseToggleCommand;
+import org.eclipse.tcf.internal.cdt.ui.commands.TCFStepIntoSelectionHandler;
import org.eclipse.tcf.internal.cdt.ui.disassembly.TCFDisassemblyBackend;
import org.eclipse.tcf.internal.cdt.ui.hover.TCFDebugTextHover;
import org.eclipse.tcf.internal.cdt.ui.sourcelookup.TCFSourceNotFoundPresentation;
@@ -42,7 +45,11 @@ import org.eclipse.tcf.internal.debug.ui.model.TCFNodeStackFrame;
@SuppressWarnings({ "rawtypes", "restriction" })
public class TCFNodeAdapterFactory implements IAdapterFactory {
- private static final Class<?>[] CLASSES = {
+ // Not available before CDT 8.2
+ private static final String STEP_INTO_SELECTION =
+ "org.eclipse.cdt.debug.core.model.IStepIntoSelectionHandler";
+
+ private static final Object[] class_names = {
IDisassemblyBackend.class,
ISteppingModeTarget.class,
ISuspendResume.class,
@@ -51,85 +58,95 @@ public class TCFNodeAdapterFactory implements IAdapterFactory {
IReverseStepIntoHandler.class,
IReverseStepOverHandler.class,
IReverseResumeHandler.class,
+ STEP_INTO_SELECTION,
IUncallHandler.class,
IPinProvider.class,
ICWatchpointTarget.class,
ISourceNotFoundPresentation.class
};
- private static final TCFSourceNotFoundPresentation fgSourceNotFoundPresentation = new TCFSourceNotFoundPresentation();
+ private static final Class[] class_list;
+
+ static {
+ ArrayList<Class> l = new ArrayList<Class>();
+ for (Object o : class_names) {
+ if (o instanceof Class) {
+ l.add((Class)o);
+ }
+ else {
+ try {
+ l.add(Class.forName((String)o));
+ }
+ catch (ClassNotFoundException e) {
+ }
+ }
+ }
+ class_list = l.toArray(new Class[l.size()]);
+ }
public Object getAdapter(Object obj, Class type) {
if (obj instanceof TCFNode) {
final TCFNode node = (TCFNode)obj;
TCFModel model = node.getModel();
- if (IDisassemblyBackend.class == type) {
- TCFDisassemblyBackend backend = new TCFDisassemblyBackend();
- if (backend.supportsDebugContext((TCFNode)obj)) return backend;
- }
- else if (ISteppingModeTarget.class == type) {
- ISteppingModeTarget target = (ISteppingModeTarget)model.getAdapter(type, node);
- if (target == null) model.setAdapter(type, target = new TCFSteppingModeTarget(model));
- return target;
- }
- else if (ISuspendResume.class == type) {
- TCFNodeExecContext exec = null;
- if (node instanceof TCFNodeExecContext) {
- exec = (TCFNodeExecContext)node;
+ Object handler = model.getAdapter(type, node);
+ if (handler == null) {
+ if (IDisassemblyBackend.class == type) {
+ TCFDisassemblyBackend backend = new TCFDisassemblyBackend();
+ if (backend.supportsDebugContext(node)) return backend;
+ backend.dispose();
}
- else if (node instanceof TCFNodeStackFrame) {
- exec = (TCFNodeExecContext)node.getParent();
+ else if (ISteppingModeTarget.class == type) {
+ model.setAdapter(type, handler = new TCFSteppingModeTarget(model));
}
- if (exec != null) {
- return new TCFSuspendResumeAdapter(exec);
+ else if (ISuspendResume.class == type) {
+ TCFNodeExecContext exec = null;
+ if (node instanceof TCFNodeExecContext) {
+ exec = (TCFNodeExecContext)node;
+ }
+ else if (node instanceof TCFNodeStackFrame) {
+ exec = (TCFNodeExecContext)node.getParent();
+ }
+ if (exec != null) {
+ return new TCFSuspendResumeAdapter(exec);
+ }
+ }
+ else if (ICEditorTextHover.class == type) {
+ model.setAdapter(type, handler = new TCFDebugTextHover());
+ }
+ else if (IReverseToggleHandler.class == type) {
+ model.setAdapter(type, handler = new TCFReverseToggleCommand());
+ }
+ else if (IReverseStepIntoHandler.class == type) {
+ model.setAdapter(type, handler = new TCFReverseStepIntoCommand(model));
+ }
+ else if (IReverseStepOverHandler.class == type) {
+ model.setAdapter(type, handler = new TCFReverseStepOverCommand(model));
+ }
+ else if (IUncallHandler.class == type) {
+ model.setAdapter(type, handler = new TCFReverseStepReturnCommand(model));
+ }
+ else if (IReverseResumeHandler.class == type) {
+ model.setAdapter(type, handler = new TCFReverseResumeCommand(model));
+ }
+ else if (IPinProvider.class == type) {
+ model.setAdapter(type, handler = new TCFPinViewCommand(model));
+ }
+ else if (ICWatchpointTarget.class == type) {
+ if (node instanceof TCFNodeExpression) return new TCFWatchpointTarget((TCFNodeExpression)node);
+ }
+ else if (ISourceNotFoundPresentation.class == type) {
+ model.setAdapter(type, handler = new TCFSourceNotFoundPresentation());
+ }
+ else if (type.getName().equals(STEP_INTO_SELECTION)) {
+ model.setAdapter(type, handler = new TCFStepIntoSelectionHandler());
}
}
- else if (ICEditorTextHover.class == type) {
- ICEditorTextHover hover = (ICEditorTextHover)model.getAdapter(type, node);
- if (hover == null) model.setAdapter(type, hover = new TCFDebugTextHover());
- return hover;
- }
- else if (IReverseToggleHandler.class == type) {
- IReverseToggleHandler handler = (IReverseToggleHandler)model.getAdapter(type, node);
- if (handler == null) model.setAdapter(type, handler = new TCFReverseToggleCommand());
- return handler;
- }
- else if (IReverseStepIntoHandler.class == type) {
- IReverseStepIntoHandler handler = (IReverseStepIntoHandler)model.getAdapter(type, node);
- if (handler == null) model.setAdapter(type, handler = new TCFReverseStepIntoCommand(model));
- return handler;
- }
- else if (IReverseStepOverHandler.class == type) {
- IReverseStepOverHandler handler = (IReverseStepOverHandler)model.getAdapter(type, node);
- if (handler == null) model.setAdapter(type, handler = new TCFReverseStepOverCommand(model));
- return handler;
- }
- else if (IUncallHandler.class == type) {
- IUncallHandler handler = (IUncallHandler)model.getAdapter(type, node);
- if (handler == null) model.setAdapter(type, handler = new TCFReverseStepReturnCommand(model));
- return handler;
- }
- else if (IReverseResumeHandler.class == type) {
- IReverseResumeHandler handler = (IReverseResumeHandler)model.getAdapter(type, node);
- if (handler == null) model.setAdapter(type, handler = new TCFReverseResumeCommand(model));
- return handler;
- }
- else if (IPinProvider.class == type) {
- IPinProvider handler = (IPinProvider)model.getAdapter(type, node);
- if (handler == null) model.setAdapter(type, handler = new TCFPinViewCommand(model));
- return handler;
- }
- else if (ICWatchpointTarget.class == type) {
- if (node instanceof TCFNodeExpression) return new TCFWatchpointTarget((TCFNodeExpression)node);
- }
- else if (ISourceNotFoundPresentation.class == type) {
- return fgSourceNotFoundPresentation;
- }
+ return handler;
}
return null;
}
public Class[] getAdapterList() {
- return CLASSES;
+ return class_list;
}
}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/StepIntoSelectionLocation.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/StepIntoSelectionLocation.java
new file mode 100644
index 000000000..bdda7f2ca
--- /dev/null
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/StepIntoSelectionLocation.java
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Xilinx, Inc. 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.cdt.ui.commands;
+
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IName;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
+import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IParameter;
+import org.eclipse.cdt.core.dom.ast.IProblemBinding;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
+import org.eclipse.cdt.core.index.IIndex;
+import org.eclipse.cdt.core.index.IIndexManager;
+import org.eclipse.cdt.core.index.IIndexName;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IFunctionDeclaration;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
+import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
+import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
+import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
+import org.eclipse.cdt.internal.ui.editor.ASTProvider;
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.tcf.internal.cdt.ui.Activator;
+import org.eclipse.tcf.internal.debug.ui.model.TCFModel;
+import org.eclipse.tcf.internal.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tcf.internal.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.editors.text.TextEditor;
+
+@SuppressWarnings("restriction")
+class StepIntoSelectionLocation {
+
+ IDebugCommandRequest request;
+ TCFNodeExecContext node;
+ TextEditor editor;
+ ITextSelection text_selection;
+ String text_file;
+ int text_line;
+ ITranslationUnit compilation_unit;
+ IIndex project_index;
+ IFunctionDeclaration[] resolved_functions;
+ IFunctionDeclaration target_function;
+
+ private enum NameKind { REFERENCE, DECLARATION, USING_DECL, DEFINITION }
+
+ void getTextLocation(IDebugCommandRequest request) {
+ this.request = request;
+ Object[] elements = request.getElements();
+ if (elements.length != 1) return;
+
+ if (elements[0] instanceof TCFNodeExecContext) {
+ node = (TCFNodeExecContext)elements[0];
+ }
+ else if (elements[0] instanceof TCFNodeStackFrame) {
+ node = (TCFNodeExecContext)((TCFNodeStackFrame)elements[0]).getParent();
+ }
+ else {
+ return;
+ }
+
+ IWorkbench wb = PlatformUI.getWorkbench();
+ IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
+ if (win != null && win.getActivePage() != null) {
+ IEditorPart part = win.getActivePage().getActiveEditor();
+ if (part instanceof TextEditor) editor = (TextEditor)part;
+ }
+ if (editor != null) {
+ ISelection selection = editor.getEditorSite().getSelectionProvider().getSelection();
+ if (selection instanceof ITextSelection) text_selection = (ITextSelection)selection;
+ try {
+ text_file = CDebugUIUtils.getEditorFilePath(editor.getEditorInput());
+ }
+ catch (CoreException x) {
+ request.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ IStatus.ERROR, TCFModel.getErrorMessage(x, true), x));
+ return;
+ }
+ }
+ if (text_selection != null) {
+ text_line = text_selection.getStartLine() + 1;
+ }
+ }
+
+ private IName[] findDefinitions(IIndex index, IASTTranslationUnit ast, StepIntoSelectionLocation.NameKind kind, IBinding binding) throws CoreException {
+ List<IASTName> declNames = new ArrayList<IASTName>();
+ declNames.addAll(Arrays.asList(ast.getDefinitionsInAST(binding)));
+ for (Iterator<IASTName> i = declNames.iterator(); i.hasNext();) {
+ IASTName name = i.next();
+ final IBinding b2 = name.resolveBinding();
+ if (b2 instanceof ICPPUsingDeclaration) {
+ i.remove();
+ }
+ if (binding != b2 && binding instanceof ICPPSpecialization) {
+ // Make sure binding specializes b2 so that for instance we do
+ // not navigate from
+ // one partial specialization to another.
+ IBinding spec = binding;
+ while (spec instanceof ICPPSpecialization) {
+ spec = ((ICPPSpecialization) spec).getSpecializedBinding();
+ if (spec == b2)
+ break;
+ }
+ if (!(spec instanceof ICPPSpecialization)) {
+ i.remove();
+ }
+ }
+ }
+ if (!declNames.isEmpty()) {
+ return declNames.toArray(new IASTName[declNames.size()]);
+ }
+
+ // 2. Try definition in index.
+ return index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
+ }
+
+ private IName[] findDeclarations(IIndex index, IASTTranslationUnit ast, IBinding binding) throws CoreException {
+ IASTName[] astNames = ast.getDeclarationsInAST(binding);
+ ArrayList<IASTName> usingDeclarations = null;
+ for (int i = 0; i < astNames.length; i++) {
+ IASTName name = astNames[i];
+ if (name.isDefinition()) {
+ astNames[i] = null;
+ } else if (CPPVisitor.findAncestorWithType(name, ICPPASTUsingDeclaration.class) != null) {
+ if (usingDeclarations == null)
+ usingDeclarations = new ArrayList<IASTName>(1);
+ usingDeclarations.add(name);
+ astNames[i] = null;
+ }
+ }
+ IName[] declNames = ArrayUtil.removeNulls(astNames);
+ if (declNames.length == 0) {
+ declNames = index.findNames(binding, IIndex.FIND_DECLARATIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
+ }
+ // 'using' declarations are considered only when there are no other
+ // declarations.
+ if (declNames.length == 0 && usingDeclarations != null) {
+ declNames = usingDeclarations.toArray(new IName[usingDeclarations.size()]);
+ }
+ return declNames;
+ }
+
+ private IName[] findNames(IIndex index, IASTTranslationUnit ast, StepIntoSelectionLocation.NameKind kind, IBinding binding) throws CoreException {
+ IName[] declNames;
+ if (kind == NameKind.DEFINITION) {
+ declNames = findDeclarations(index, ast, binding);
+ }
+ else {
+ declNames = findDefinitions(index, ast, kind, binding);
+ }
+
+ if (declNames.length == 0) {
+ if (kind == NameKind.DEFINITION) {
+ declNames = findDefinitions(index, ast, kind, binding);
+ }
+ else {
+ declNames = findDeclarations(index, ast, binding);
+ }
+ }
+ return declNames;
+ }
+
+ private IName[] findDeclNames(IASTTranslationUnit ast, StepIntoSelectionLocation.NameKind kind, IBinding binding) throws CoreException {
+ IName[] declNames = findNames(project_index, ast, kind, binding);
+ while (declNames.length == 0 && binding instanceof ICPPSpecialization) {
+ binding = ((ICPPSpecialization) binding).getSpecializedBinding();
+ if (binding != null && !(binding instanceof IProblemBinding)) {
+ declNames = findNames(project_index, ast, NameKind.DEFINITION, binding);
+ }
+ }
+ if (declNames.length == 0 && binding instanceof ICPPMethod) {
+ ICPPMethod method = (ICPPMethod) binding;
+ if (method.isImplicit()) {
+ IBinding clsBinding = method.getClassOwner();
+ if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) {
+ declNames = findNames(project_index, ast, NameKind.REFERENCE, clsBinding);
+ }
+ }
+ }
+ return declNames;
+ }
+
+ /*
+ * Returns definitions of bindings referenced by implicit name at the given location.
+ */
+ private IName[] findImplicitTargets(IASTTranslationUnit ast, IASTNodeSelector nodeSelector, int offset, int length) throws CoreException {
+ IName[] definitions = IName.EMPTY_ARRAY;
+ IASTName firstName = nodeSelector.findEnclosingImplicitName(offset, length);
+ if (firstName != null) {
+ IASTImplicitNameOwner owner = (IASTImplicitNameOwner) firstName.getParent();
+ for (IASTImplicitName name : owner.getImplicitNames()) {
+ if (((ASTNode) name).getOffset() == ((ASTNode) firstName).getOffset()) {
+ IBinding binding = name.resolveBinding(); // Guaranteed to
+ // resolve.
+ IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, binding);
+ definitions = ArrayUtil.addAll(definitions, declNames);
+ }
+ }
+ }
+ return ArrayUtil.trim(definitions);
+ }
+
+ private static IBinding getBinding(IName name) {
+ if (name instanceof IASTName) {
+ return ((IASTName) name).resolveBinding();
+ }
+ else if (name instanceof IIndexFragmentName) {
+ try {
+ return ((IIndexFragmentName) name).getBinding();
+ }
+ catch (CoreException e) {
+ // Fall through to return null.
+ }
+ }
+ return null;
+ }
+
+ private static StepIntoSelectionLocation.NameKind getNameKind(IName name) {
+ if (name.isDefinition()) {
+ if (getBinding(name) instanceof ICPPUsingDeclaration) {
+ return NameKind.USING_DECL;
+ }
+ else {
+ return NameKind.DEFINITION;
+ }
+ }
+ else if (name.isDeclaration()) {
+ return NameKind.DECLARATION;
+ }
+ return NameKind.REFERENCE;
+ }
+
+ private boolean areOverlappingNames(IName n1, IName n2) {
+ if (n1 == n2)
+ return true;
+
+ IASTFileLocation loc1 = n1.getFileLocation();
+ IASTFileLocation loc2 = n2.getFileLocation();
+ if (loc1 == null || loc2 == null) return false;
+ return loc1.getFileName().equals(loc2.getFileName())
+ && max(loc1.getNodeOffset(), loc2.getNodeOffset()) < min(loc1.getNodeOffset() + loc1.getNodeLength(), loc2.getNodeOffset() + loc2.getNodeLength());
+ }
+
+ private static IASTDeclaration getEnclosingFunctionDefinition(IASTNode node) {
+ while (node != null && !(node instanceof IASTFunctionDefinition)) {
+ node = node.getParent();
+ }
+ return (IASTDeclaration) node;
+ }
+
+ private static boolean isInSameFunction(IASTName refName, IName funcDeclName) {
+ if (funcDeclName instanceof IASTName) {
+ IASTDeclaration fdef = getEnclosingFunctionDefinition((IASTNode) funcDeclName);
+ return fdef != null && fdef.contains(refName);
+ }
+ return false;
+ }
+
+ private static IASTDeclaration getEnclosingTemplateDeclaration(IASTNode node) {
+ while (node != null && !(node instanceof ICPPASTTemplateDeclaration)) {
+ node = node.getParent();
+ }
+ return (IASTDeclaration) node;
+ }
+
+ private static boolean isInSameTemplate(IASTName refName, IName templateDeclName) {
+ if (templateDeclName instanceof IASTName) {
+ IASTDeclaration template = getEnclosingTemplateDeclaration(refName);
+ return template != null && template.contains(refName);
+ }
+ return false;
+ }
+
+ private ICElementHandle getCElementForName(ICProject project, IIndex index, IName declName) throws CoreException {
+ if (declName instanceof IIndexName) {
+ return IndexUI.getCElementForName(project, index, (IIndexName) declName);
+ }
+ if (declName instanceof IASTName) {
+ IASTName astName = (IASTName) declName;
+ IBinding binding = astName.resolveBinding();
+ if (binding != null) {
+ ITranslationUnit tu = IndexUI.getTranslationUnit(project, astName);
+ if (tu != null) {
+ IASTFileLocation loc = astName.getFileLocation();
+ IRegion region = new Region(loc.getNodeOffset(), loc.getNodeLength());
+ return CElementHandleFactory.create(tu, binding, astName.isDefinition(), region, 0);
+ }
+ }
+ return null;
+ }
+ return null;
+ }
+
+ private void filterToFunctions(ICProject project, IIndex index, IName[] declNames, List<IFunctionDeclaration> functionElements) {
+ for (IName declName : declNames) {
+ try {
+ ICElement elem = getCElementForName(project, index, declName);
+ if (elem instanceof IFunctionDeclaration) {
+ functionElements.add((IFunctionDeclaration) elem);
+ }
+ }
+ catch (CoreException e) {
+ CUIPlugin.log(e);
+ }
+ }
+ }
+
+ void getTargetFunction(IDebugCommandRequest request) {
+ getTextLocation(request);
+ if (text_selection == null) return;
+ text_line = text_selection.getStartLine() + 1;
+ if (editor instanceof CEditor) {
+ compilation_unit = ((CEditor)editor).getInputCElement();
+ if (compilation_unit == null) return;
+ try {
+ project_index = CCorePlugin.getIndexManager().getIndex(compilation_unit.getCProject(),
+ IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT | IIndexManager.ADD_EXTENSION_FRAGMENTS_NAVIGATION);
+ }
+ catch (Exception x) {
+ request.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ IStatus.ERROR, TCFModel.getErrorMessage(x, true), x));
+ return;
+ }
+ IStatus status = ASTProvider.getASTProvider().runOnAST(compilation_unit, ASTProvider.WAIT_NO, null, new ASTRunnable() {
+ @Override
+ public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
+ if (ast == null) return Status.OK_STATUS;
+
+ int selection_start = text_selection.getOffset();
+ int selection_length = text_selection.getLength();
+
+ final IASTNodeSelector node_selector = ast.getNodeSelector(null);
+
+ IASTName source_name = node_selector.findEnclosingName(selection_start, selection_length);
+ if (source_name == null) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ "Unable to resolve the selection to a semantic object");
+ }
+
+ IName[] implicitTargets = findImplicitTargets(ast, node_selector, selection_start, selection_length);
+
+ StepIntoSelectionLocation.NameKind kind = getNameKind(source_name);
+ IBinding b = source_name.resolveBinding();
+ IBinding[] bindings = new IBinding[] { b };
+ if (b instanceof IProblemBinding) {
+ IBinding[] candidateBindings = ((IProblemBinding) b).getCandidateBindings();
+ if (candidateBindings.length != 0) {
+ bindings = candidateBindings;
+ }
+ }
+ else if (kind == NameKind.DEFINITION && b instanceof IType) {
+ // No resolution of type definitions.
+ return Status.OK_STATUS;
+ }
+
+ IName[] targets = IName.EMPTY_ARRAY;
+ String file_path = ast.getFilePath();
+ for (IBinding binding : bindings) {
+ if (binding != null && !(binding instanceof IProblemBinding)) {
+ IName[] names = findDeclNames(ast, kind, binding);
+ for (final IName name : names) {
+ if (name != null) {
+ if (name instanceof IIndexName && file_path.equals(((IIndexName)name).getFileLocation().getFileName())) {
+ // Exclude index names from the current file.
+ }
+ else if (areOverlappingNames(name, source_name)) {
+ // Exclude the current location.
+ }
+ else if (binding instanceof IParameter) {
+ if (isInSameFunction(source_name, name)) {
+ targets = ArrayUtil.append(targets, name);
+ }
+ }
+ else if (binding instanceof ICPPTemplateParameter) {
+ if (isInSameTemplate(source_name, name)) {
+ targets = ArrayUtil.append(targets, name);
+ }
+ }
+ else {
+ targets = ArrayUtil.append(targets, name);
+ }
+ }
+ }
+ }
+ }
+
+ targets = ArrayUtil.trim(ArrayUtil.addAll(targets, implicitTargets));
+
+ final ArrayList<IFunctionDeclaration> functionElements = new ArrayList<IFunctionDeclaration>();
+ filterToFunctions(compilation_unit.getCProject(), project_index, targets, functionElements);
+
+ // save the resolved function declarations
+ resolved_functions = functionElements.toArray(new IFunctionDeclaration[functionElements.size()]);
+
+ return Status.OK_STATUS;
+ }
+ });
+ if (status.getSeverity() != Status.OK) request.setStatus(status);
+ }
+ if (resolved_functions != null && resolved_functions.length == 1 && resolved_functions[0] != null) {
+ target_function = resolved_functions[0];
+ }
+ }
+
+ boolean isValid() {
+ return request != null && request.getStatus() == null && text_file != null && text_line > 0;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/TCFStepIntoSelectionHandler.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/TCFStepIntoSelectionHandler.java
new file mode 100644
index 000000000..ba39ed595
--- /dev/null
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/commands/TCFStepIntoSelectionHandler.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Xilinx, Inc. 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.cdt.ui.commands;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandHandler;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.tcf.internal.cdt.ui.Activator;
+import org.eclipse.tcf.internal.debug.actions.TCFAction;
+import org.eclipse.tcf.internal.debug.model.TCFContextState;
+import org.eclipse.tcf.internal.debug.ui.model.TCFModel;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.services.IBreakpoints;
+import org.eclipse.tcf.services.IRunControl;
+import org.eclipse.tcf.services.IRunControl.RunControlContext;
+import org.eclipse.tcf.services.IRunControl.RunControlListener;
+import org.eclipse.tcf.util.TCFDataCache;
+
+public class TCFStepIntoSelectionHandler implements IDebugCommandHandler {
+
+ @Override
+ public void canExecute(final IEnabledStateRequest request) {
+ final StepIntoSelectionLocation l = new StepIntoSelectionLocation();
+ l.getTextLocation(request);
+
+ if (!l.isValid()) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+
+ Protocol.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ if (l.node.isDisposed()) {
+ done(null, false);
+ return;
+ }
+ TCFDataCache<TCFContextState> cache = l.node.getState();
+ if (!cache.validate(this)) return;
+ if (cache.getError() != null) {
+ done(cache.getError(), false);
+ return;
+ }
+ TCFContextState state = cache.getData();
+ done(null, state != null && state.is_suspended);
+ }
+ private void done(Throwable e, boolean enabled) {
+ if (e != null) {
+ request.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ IStatus.ERROR, TCFModel.getErrorMessage(e, true), e));
+ }
+ request.setEnabled(enabled);
+ request.done();
+ }
+ });
+ }
+
+ @Override
+ public boolean execute(final IDebugCommandRequest request) {
+ final StepIntoSelectionLocation l = new StepIntoSelectionLocation();
+ l.getTargetFunction(request);
+
+ if (!l.isValid()) {
+ request.done();
+ return true;
+ }
+
+ Protocol.invokeLater(new Runnable() {
+ boolean run_to_line_done;
+ boolean req_done;
+ String bp_id;
+ @Override
+ public void run() {
+ if (l.node.isDisposed()) {
+ done(null);
+ return;
+ }
+ IChannel channel = l.node.getChannel();
+ if (bp_id == null) {
+ IBreakpoints breakpoints = channel.getRemoteService(IBreakpoints.class);
+ if (breakpoints == null) {
+ done(new Exception("Cannot set breakpoint."));
+ return;
+ }
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put(IBreakpoints.PROP_FILE, l.text_file);
+ properties.put(IBreakpoints.PROP_LINE, l.text_line);
+ if (run_to_line_done) {
+ assert l.target_function != null;
+ properties.put(IBreakpoints.PROP_LOCATION, l.target_function.getElementName());
+ properties.put(IBreakpoints.PROP_SKIP_PROLOGUE, true);
+ }
+ properties.put(IBreakpoints.PROP_CONTEXT_IDS, new String[] { l.node.getID() });
+ properties.put(IBreakpoints.PROP_ENABLED, Boolean.TRUE);
+ bp_id = TCFAction.STEP_BREAKPOINT_PREFIX + l.node.getID();
+ properties.put(IBreakpoints.PROP_ID, bp_id);
+ breakpoints.add(properties, new IBreakpoints.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) {
+ bp_id = null;
+ done(error);
+ }
+ else {
+ run();
+ }
+ }
+ });
+ return;
+ }
+ final IRunControl run_ctrl = channel.getRemoteService(IRunControl.class);
+ if (run_ctrl == null) {
+ done(new Exception("Cannot resume."));
+ return;
+ }
+ TCFDataCache<TCFContextState> state_cache = l.node.getState();
+ if (!state_cache.validate(this)) return;
+ if (state_cache.getError() != null) {
+ done(state_cache.getError());
+ return;
+ }
+ TCFContextState state = state_cache.getData();
+ if (state == null || !state.is_suspended) {
+ done(null);
+ return;
+ }
+ TCFDataCache<IRunControl.RunControlContext> ctx_cache = l.node.getRunContext();
+ if (!ctx_cache.validate(this)) return;
+ if (ctx_cache.getError() != null) {
+ done(ctx_cache.getError());
+ return;
+ }
+ final String node_id = l.node.getID();
+ run_ctrl.addListener(new RunControlListener() {
+ private void suspended() {
+ run_ctrl.removeListener(this);
+ if (!run_to_line_done) {
+ run_to_line_done = true;
+ if (l.target_function != null) {
+ assert bp_id != null;
+ IChannel channel = l.node.getChannel();
+ IBreakpoints breakpoints = channel.getRemoteService(IBreakpoints.class);
+ breakpoints.remove(new String[] { bp_id }, new IBreakpoints.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) done(error);
+ else run();
+ }
+ });
+ bp_id = null;
+ return;
+ }
+ }
+ done(null);
+ }
+ public void contextSuspended(String context, String pc, String reason, Map<String,Object> params) {
+ if (node_id.equals(context)) {
+ suspended();
+ }
+ }
+ public void contextResumed(String context) {
+ }
+ public void contextRemoved(String[] context_ids) {
+ for (String context : context_ids) {
+ if (node_id.equals(context)) {
+ suspended();
+ return;
+ }
+ }
+ }
+ public void contextException(String context, String msg) {
+ }
+ public void contextChanged(RunControlContext[] contexts) {
+ }
+ public void contextAdded(RunControlContext[] contexts) {
+ }
+ public void containerSuspended(String context, String pc, String reason, Map<String,Object> params, String[] suspended_ids) {
+ for (String context2 : suspended_ids) {
+ if (node_id.equals(context2)) {
+ suspended();
+ return;
+ }
+ }
+ }
+ public void containerResumed(String[] context_ids) {
+ }
+ });
+ IRunControl.RunControlContext ctx = ctx_cache.getData();
+ ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) {
+ done(error);
+ }
+ else if (!req_done) {
+ req_done = true;
+ request.done();
+ }
+ }
+ });
+ }
+ private void done(Throwable e) {
+ if (bp_id != null) {
+ IChannel channel = l.node.getChannel();
+ IBreakpoints breakpoints = channel.getRemoteService(IBreakpoints.class);
+ breakpoints.remove(new String[] { bp_id }, new IBreakpoints.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ done(error);
+ }
+ });
+ bp_id = null;
+ return;
+ }
+ if (!req_done) {
+ if (e != null) {
+ request.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ IStatus.ERROR, TCFModel.getErrorMessage(e, true), e));
+ }
+ req_done = true;
+ request.done();
+ }
+ }
+ });
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
index f6b3e4cc2..5510e95c2 100644
--- a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
@@ -791,7 +791,6 @@ public class TCFModel implements ITCFModel, IElementContentProvider, IElementLab
*/
public void setAdapter(Class<?> adapterType, Object adapter) {
synchronized (adapters) {
- assert adapterType.isInstance(adapter);
adapters.put(adapterType, adapter);
}
}

Back to the top