diff --git a/.gitignore b/.gitignore index 2b8d68958c1..51524d8fa7e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /*/*/index /*/*/target .DS_Store +.nfs* diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeUIPlugin.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeUIPlugin.java index f9c87fcc19a..b6a4e6d6fe0 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeUIPlugin.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeUIPlugin.java @@ -16,6 +16,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.MissingResourceException; import java.util.ResourceBundle; +import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.internal.ui.editor.IMakefileDocumentProvider; import org.eclipse.cdt.make.internal.ui.editor.MakefileDocumentProvider; import org.eclipse.cdt.make.internal.ui.editor.WorkingCopyManager; @@ -26,6 +27,7 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; @@ -36,6 +38,7 @@ import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.texteditor.ChainedPreferenceStore; import org.osgi.framework.BundleContext; @@ -50,6 +53,7 @@ public class MakeUIPlugin extends AbstractUIPlugin { private IWorkingCopyManager fWorkingCopyManager; private IMakefileDocumentProvider fMakefileDocumentProvider; + private ScopedPreferenceStore fCorePreferenceStore; /** * The constructor. @@ -269,6 +273,16 @@ public class MakeUIPlugin extends AbstractUIPlugin { return chainedStore; } + /** + * Returns a preference store for org.eclipse.cdt.make.core preferences + * @return the preference store + */ + public IPreferenceStore getCorePreferenceStore() { + if (fCorePreferenceStore == null) { + fCorePreferenceStore= new ScopedPreferenceStore(InstanceScope.INSTANCE, MakeCorePlugin.PLUGIN_ID); + } + return fCorePreferenceStore; + } @Override public void start(BundleContext context) throws Exception { diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/MakefileSettingsPreferencePage.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/MakefileSettingsPreferencePage.java index a4a5372cb8c..d0581a4483a 100644 --- a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/MakefileSettingsPreferencePage.java +++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/preferences/MakefileSettingsPreferencePage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2002, 2010 QNX Software Systems and others. + * Copyright (c) 2002, 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 @@ -13,8 +13,8 @@ package org.eclipse.cdt.make.internal.ui.preferences; import org.eclipse.cdt.make.core.MakeCorePlugin; +import org.eclipse.cdt.make.internal.ui.MakeUIPlugin; import org.eclipse.cdt.make.ui.IMakeHelpContextIds; -import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PathEditor; @@ -23,7 +23,6 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.preferences.ScopedPreferenceStore; /** * MakePreferencePage @@ -37,7 +36,7 @@ public class MakefileSettingsPreferencePage extends FieldEditorPreferencePage im public MakefileSettingsPreferencePage() { super(GRID); - IPreferenceStore store = new ScopedPreferenceStore(new InstanceScope(), MakeCorePlugin.PLUGIN_ID); + IPreferenceStore store = MakeUIPlugin.getDefault().getCorePreferenceStore(); setPreferenceStore(store); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java index 86129eac8bb..9378bdf1988 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java @@ -632,26 +632,27 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider private int decodeParallelizationNumber(String value) { int parallelNumber = -1; - if (VALUE_OPTIMAL.equals(value)) { + if (value == null || VALUE_OPTIMAL.equals(value)) { parallelNumber = -getOptimalParallelJobNum(); } else if (VALUE_UNLIMITED.equals(value)) { parallelNumber = UNLIMITED_JOBS; } else { try { parallelNumber = Integer.decode(value); + if (parallelNumber <= 0) { + // compatibility with legacy representation - it was that inconsistent + if (isInternalBuilder()) { + // "optimal" for Internal Builder + parallelNumber = -getOptimalParallelJobNum(); + } else { + // unlimited for External Builder + parallelNumber = UNLIMITED_JOBS; + } + } } catch (NumberFormatException e) { ManagedBuilderCorePlugin.log(e); - parallelNumber = getOptimalParallelJobNum(); - } - if (parallelNumber <= 0) { - // compatibility with legacy representation - it was that inconsistent - if (isInternalBuilder()) { - // "optimal" for Internal Builder - parallelNumber = -getOptimalParallelJobNum(); - } else { - // unlimited for External Builder - parallelNumber = UNLIMITED_JOBS; - } + // default to "optimal" if not recognized + parallelNumber = -getOptimalParallelJobNum(); } } return parallelNumber; diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml index cbb257072dd..b5284497ffb 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml @@ -167,6 +167,11 @@ wizardId="org.eclipse.cdt.ui.wizards.ConvertToMakeWizard"> + + + + diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java index 07825aa1ab4..26483db4617 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ReturnChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Alena Laskavaia + * Copyright (c) 2009, 2012 Alena Laskavaia * 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 @@ -7,6 +7,7 @@ * * Contributors: * Alena Laskavaia - initial API and implementation + * Tomasz Wesolowski - Bug 348387 *******************************************************************************/ package org.eclipse.cdt.codan.internal.checkers; @@ -47,6 +48,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; @@ -205,8 +207,9 @@ public class ReturnChecker extends AbstractAstFunctionChecker { */ private boolean isCompoundStatement(IASTStatement last) { return last instanceof IASTIfStatement || last instanceof IASTWhileStatement || - last instanceof IASTDoStatement || last instanceof IASTForStatement || - last instanceof IASTSwitchStatement || last instanceof IASTCompoundStatement; + last instanceof IASTDoStatement || last instanceof IASTForStatement || + last instanceof IASTSwitchStatement || last instanceof IASTCompoundStatement || + last instanceof ICPPASTTryBlockStatement; } protected boolean isFuncExitStatement(IASTStatement statement) { diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java index 22076c92a50..058ad120e75 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/model/cfg/ControlFlowGraphBuilder.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Alena Laskavaia + * Copyright (c) 2009, 2012 Alena Laskavaia 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: - * Alena Laskavaia - initial API and implementation + * Alena Laskavaia - initial API and implementation + * Tomasz Wesolowski - Bug 348387 *******************************************************************************/ package org.eclipse.cdt.codan.core.cxx.internal.model.cfg; @@ -32,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBreakStatement; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTContinueStatement; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement; import org.eclipse.cdt.core.dom.ast.IASTDoStatement; @@ -231,14 +233,20 @@ public class ControlFlowGraphBuilder { addOutgoing(prev, ifNode); IConnectorNode mergeNode = factory.createConnectorNode(); ifNode.setMergeNode(mergeNode); - IBranchNode thenNode = factory.createBranchNode(IBranchNode.THEN); - addOutgoing(ifNode, thenNode); - IBasicBlock then = createSubGraph(thenNode, body.getTryBody()); - addJump(then, mergeNode); + IBranchNode tryBodyNode = factory.createBranchNode(IBranchNode.TRY_BODY); + addOutgoing(ifNode, tryBodyNode); + IBasicBlock tryBody = createSubGraph(tryBodyNode, body.getTryBody()); + addJump(tryBody, mergeNode); ICPPASTCatchHandler[] catchHandlers = body.getCatchHandlers(); for (int i = 0; i < catchHandlers.length; i++) { ICPPASTCatchHandler handler = catchHandlers[i]; - IBranchNode handlerNode = factory.createBranchNode(handler.getDeclaration()); + IBranchNode handlerNode; + IASTDeclaration declaration = handler.getDeclaration(); + if (declaration != null) { + handlerNode = factory.createBranchNode(declaration); + } else { + handlerNode = factory.createBranchNode(IBranchNode.CATCH_ANY); + } addOutgoing(ifNode, handlerNode); IBasicBlock els = createSubGraph(handlerNode, handler.getCatchBody()); addJump(els, mergeNode); diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java index 63d226ae0ca..dd6c6d20592 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/cfg/ControlFlowGraphTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Alena Laskavaia + * Copyright (c) 2009, 2012 Alena Laskavaia * 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 @@ -363,7 +363,7 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase { IPlainNode decl = (IPlainNode) startNode.getOutgoing(); IDecisionNode des = (IDecisionNode) decl.getOutgoing(); //assertEquals("", data(des)); - IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.THEN); + IPlainNode bThen = (IPlainNode) branchEnd(des, IBranchNode.TRY_BODY); assertEquals("*p = 1;", data(bThen)); IBasicBlock bElse = null; IBasicBlock[] outgoingNodes = des.getOutgoingNodes(); diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java index 75584462eb4..a3507569211 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ReturnCheckerTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Alena Laskavaia + * Copyright (c) 2009, 2012 Alena Laskavaia * 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: * Alena Laskavaia - initial API and implementation * Felipe Martinez - ReturnCheckerTest implementation + * Tomasz Wesolowski - Bug 348387 *******************************************************************************/ package org.eclipse.cdt.codan.core.internal.checkers; @@ -310,4 +311,39 @@ public class ReturnCheckerTest extends CheckerTestCase { loadCodeAndRun(getAboveComment()); checkNoErrors(); } + + // int try1() { + // try { + // return 5; + // } catch (...) { + // return 5; + // } + // } + public void testTryBlock1() throws Exception { + // bug 348387 + loadCodeAndRunCpp(getAboveComment()); + checkNoErrors(); + } + + // int try2() { + // try { + // return 5; + // } catch (int) { + // } + // } + public void testTryBlock2() throws Exception { + loadCodeAndRunCpp(getAboveComment()); + checkErrorLine(1); + } + + // int try3() { + // try { + // } catch (int a) { + // return 5; + // } + // } + public void testTryBlock3() throws Exception { + loadCodeAndRunCpp(getAboveComment()); + checkErrorLine(1); + } } \ No newline at end of file diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java index ec0005df95c..a4e78202081 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/cfg/IBranchNode.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Alena Laskavaia + * Copyright (c) 2009, 2012 Alena Laskavaia 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: - * Alena Laskavaia - initial API and implementation + * Alena Laskavaia - initial API and implementation + * Tomasz Wesolowski - Bug 348387 *******************************************************************************/ package org.eclipse.cdt.codan.core.model.cfg; @@ -29,6 +30,14 @@ public interface IBranchNode extends IBasicBlock, ISingleIncoming, ISingleOutgoi * Default branch of "switch" statement */ public static String DEFAULT = "default"; //$NON-NLS-1$ + /** + * Try branch of "try" block statement + */ + public static String TRY_BODY = "try"; //$NON-NLS-1$ + /** + * Catch "..." branch of "try" block statement + */ + public static String CATCH_ANY = "..."; //$NON-NLS-1$ /** * @return label of a branch diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java index 02cda147d9c..6ca46bb190f 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanRunner.java @@ -168,6 +168,9 @@ public class CodanRunner { private static void removeMarkersForDisabledProblems(CheckersRegistry chegistry, Set markerTypes, IResource resource, IProgressMonitor monitor) throws CoreException { + if (!resource.isAccessible()) { + return; + } IResource[] children = null; if (resource instanceof IContainer) { children = ((IContainer) resource).members(); diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/CodanUIActivator.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/CodanUIActivator.java index 20800ee4011..e0ae2add77f 100644 --- a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/CodanUIActivator.java +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/CodanUIActivator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Alena Laskavaia + * Copyright (c) 2010, 2012 Alena Laskavaia 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 @@ -19,6 +19,10 @@ import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.osgi.framework.BundleContext; @@ -71,6 +75,26 @@ public class CodanUIActivator extends AbstractUIPlugin { public static ImageDescriptor getImageDescriptor(String path) { return imageDescriptorFromPlugin(PLUGIN_ID, path); } + + /** + * + * @param key - key is usually plug-in relative path to image like icons/xxx.gif + * @return Image loaded from key location or from registry cache, it will be stored in plug-in registry and disposed when plug-in unloads + */ + public Image getImage(String key) { + ImageRegistry registry = getImageRegistry(); + Image image = registry.get(key); + if (image == null) { + ImageDescriptor descriptor = imageDescriptorFromPlugin(PLUGIN_ID, key); + if (descriptor==null) { + ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages(); + return sharedImages.getImage(key); + } + registry.put(key, descriptor); + image = registry.get(key); + } + return image; + } /** * Logs the specified status with this plug-in's log. diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/ImageConstants.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/ImageConstants.java new file mode 100644 index 00000000000..f65ad853333 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/ImageConstants.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2012 Marc-Andre Laperle + * 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: + * Marc-Andre Laperle - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.ui; + +public interface ImageConstants { + String ICON_WARNING = "icons/yellow_bug.gif"; //$NON-NLS-1$ + String ICON_ERROR = "icons/red_bug.gif"; //$NON-NLS-1$ + String ICON_INFO = "icons/blue_bug.gif"; //$NON-NLS-1$ +} diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/ProblemsTreeEditor.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/ProblemsTreeEditor.java index 664d2b3d750..58749efb69e 100644 --- a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/ProblemsTreeEditor.java +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/ProblemsTreeEditor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Alena Laskavaia and others. + * Copyright (c) 2009, 2012 Alena Laskavaia 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,9 +8,12 @@ * Contributors: * Alena Laskavaia - initial API and implementation * IBM Corporation + * Marc-Andre Laperle *******************************************************************************/ package org.eclipse.cdt.codan.internal.ui.preferences; +import java.text.MessageFormat; + import org.eclipse.cdt.codan.core.CodanRuntime; import org.eclipse.cdt.codan.core.PreferenceConstants; import org.eclipse.cdt.codan.core.model.CodanSeverity; @@ -23,7 +26,9 @@ import org.eclipse.cdt.codan.core.param.IProblemPreference; import org.eclipse.cdt.codan.core.param.LaunchModeProblemPreference; import org.eclipse.cdt.codan.core.param.RootProblemPreference; import org.eclipse.cdt.codan.internal.core.CodanPreferencesLoader; +import org.eclipse.cdt.codan.internal.ui.CodanUIActivator; import org.eclipse.cdt.codan.internal.ui.CodanUIMessages; +import org.eclipse.cdt.codan.internal.ui.ImageConstants; import org.eclipse.core.resources.IMarker; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.CheckStateChangedEvent; @@ -40,10 +45,6 @@ import org.eclipse.jface.window.ToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; - -import java.text.MessageFormat; public class ProblemsTreeEditor extends CheckedTreeEditor { private static final String EMPTY_STRING = ""; //$NON-NLS-1$ @@ -261,16 +262,15 @@ public class ProblemsTreeEditor extends CheckedTreeEditor { column2.setLabelProvider(new ColumnLabelProvider() { @Override public Image getImage(Object element) { - final ISharedImages images = PlatformUI.getWorkbench().getSharedImages(); if (element instanceof IProblem) { IProblem p = (IProblem) element; switch (p.getSeverity().intValue()) { case IMarker.SEVERITY_INFO: - return images.getImage(ISharedImages.IMG_OBJS_INFO_TSK); + return CodanUIActivator.getDefault().getImage(ImageConstants.ICON_INFO); case IMarker.SEVERITY_WARNING: - return images.getImage(ISharedImages.IMG_OBJS_WARN_TSK); + return CodanUIActivator.getDefault().getImage(ImageConstants.ICON_WARNING); case IMarker.SEVERITY_ERROR: - return images.getImage(ISharedImages.IMG_OBJS_ERROR_TSK); + return CodanUIActivator.getDefault().getImage(ImageConstants.ICON_ERROR); } } return null; diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorTests.java index 68a4db6e9d0..728d8fd8590 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorTests.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorTests.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2004, 2009 QNX Software Systems Ltd and others. + * Copyright (c) 2004, 2012 QNX Software Systems Ltd 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 @@ -47,12 +47,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; -/** - * @author David - * - * To change the template for this generated type comment go to - * Window>Preferences>Java>Code Generation>Code and Comments - */ public class CDescriptorTests extends BaseTestCase { static String projectId = CTestPlugin.PLUGIN_ID + ".TestProject"; @@ -176,8 +170,9 @@ public class CDescriptorTests extends BaseTestCase { Assert.assertEquals("C/C++ Test Project", owner.getName()); } - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=185930 - public void testConcurrentDescriptorCreation() throws Exception { + // Disabled this test because it fails every now and then and it tests deprecated API + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=340123 + public void _testConcurrentDescriptorCreation() throws Exception { for (int i = 0; i < 100 ; i++) { fProject.close(null); fProject.open(null); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index dbebb3faec8..814b5d1b62f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -153,18 +153,20 @@ public class AST2BaseTest extends BaseTestCase { AbstractGNUSourceCodeParser parser = null; if (lang == ParserLanguage.CPP) { ICPPParserExtensionConfiguration config = null; - if (useGNUExtensions) + if (useGNUExtensions) { config = new GPPParserExtensionConfiguration(); - else + } else { config = new ANSICPPParserExtensionConfiguration(); + } parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG,config, null); } else { ICParserExtensionConfiguration config = null; - if (useGNUExtensions) + if (useGNUExtensions) { config = new GCCParserExtensionConfiguration(); - else + } else { config = new ANSICParserExtensionConfiguration(); + } parser = new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config, null); } @@ -204,10 +206,11 @@ public class AST2BaseTest extends BaseTestCase { public static IScanner createScanner(FileContent codeReader, ParserLanguage lang, ParserMode mode, IScannerInfo scannerInfo) { IScannerExtensionConfiguration configuration = null; - if (lang == ParserLanguage.C) - configuration= GCCScannerExtensionConfiguration.getInstance(); - else + if (lang == ParserLanguage.C) { + configuration= GCCScannerExtensionConfiguration.getInstance(scannerInfo); + } else { configuration= GPPScannerExtensionConfiguration.getInstance(scannerInfo); + } IScanner scanner; scanner= new CPreprocessor(codeReader, scannerInfo, lang, NULL_LOG, configuration, IncludeFileContentProvider.getSavedFilesProvider()); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index af797d32842..80574be3204 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -91,7 +91,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; @@ -1535,6 +1534,43 @@ public class AST2CPPTests extends AST2BaseTest { } } + // struct A { + // A(int x); + // A(char x); + // }; + // + // A a = A(1); + public void testConstructorCall() throws Exception { + BindingAssertionHelper bh = new BindingAssertionHelper(getAboveComment(), CPP); + ICPPConstructor ctor = bh.assertNonProblem("A(int x)", "A", ICPPConstructor.class); + ICPPClassType classType = bh.assertNonProblem("A(1)", "A", ICPPClassType.class); + assertSame(ctor.getOwner(), classType); + IASTName name = bh.findName("A(1)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + IBinding ctor2 = implicitNames[0].getBinding(); + assertSame(ctor, ctor2); + } + + // struct A { + // A(int x); + // }; + // struct B { + // operator A(); + // }; + // + // void test() { + // B b; + // A a = A(b); + // } + public void _testConversionOperator() throws Exception { + BindingAssertionHelper bh = new BindingAssertionHelper(getAboveComment(), CPP); + ICPPMethod oper = bh.assertNonProblem("operator A", "operator A", ICPPMethod.class); + ICPPMethod conv = bh.assertNonProblem("A(b)", "A", ICPPMethod.class); + // This assertion fails because conv is the copy ctor A(const A&), not the conversion operator B::operator A() + assertSame(oper, conv); + } + // namespace A { int x; } // namespace B = A; // int f(){ B::x; } @@ -2581,25 +2617,25 @@ public class AST2CPPTests extends AST2BaseTest { assertTrue(d.getNestedDeclarator().getPointerOperators()[0] instanceof ICPPASTPointerToMember); } - // struct T1 { - // T1 operator() (int x) { - // return T1(x); + // struct A { + // A operator()(int x) { + // return A(x); // } - // T1(int) {} + // A(int) {} // }; public void testBug86336() throws Exception { - IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor T1_ctor = (ICPPConstructor) col.getName(6).resolveBinding(); - ICPPClassType T1 = (ICPPClassType) col.getName(0).resolveBinding(); - assertInstances(col, T1_ctor, 1); - assertInstances(col, T1, 3); - - ICPPASTFunctionCallExpression fc= (ICPPASTFunctionCallExpression) col.getName(4).getParent().getParent(); - IBinding ctor2 = fc.getImplicitNames()[0].resolveBinding(); - assertSame(T1_ctor, ctor2); + BindingAssertionHelper bh = getAssertionHelper(); + ICPPClassType clazz = bh.assertNonProblem("A {", "A", ICPPClassType.class); + ICPPConstructor ctor = bh.assertNonProblem("A(int)", "A", ICPPConstructor.class); + ICPPClassType clazz2 = bh.assertNonProblem("A(x)", "A", ICPPClassType.class); + assertSame(clazz, clazz2); + clazz2 = bh.assertNonProblem("A operator", "A", ICPPClassType.class); + assertSame(clazz, clazz2); + IASTName name = bh.findName("A(x)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + IBinding ctor2 = implicitNames[0].getBinding(); + assertSame(ctor, ctor2); } // struct S { int i; }; @@ -3783,6 +3819,24 @@ public class AST2CPPTests extends AST2BaseTest { assertTrue(((ITypedef) binding).getType() instanceof IFunctionType); } + // struct A { + // A(int x); + // }; + // typedef A B; + // + // B a = B(1); + public void testTypedefConstructorCall() throws Exception { + BindingAssertionHelper bh = new BindingAssertionHelper(getAboveComment(), CPP); + ICPPConstructor ctor = bh.assertNonProblem("A(int x)", "A", ICPPConstructor.class); + ITypedef typedef = bh.assertNonProblem("B(1)", "B", ITypedef.class); + assertSame(ctor.getOwner(), typedef.getType()); + IASTName name = bh.findName("B(1)", "B"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + IBinding ctor2 = implicitNames[0].getBinding(); + assertSame(ctor, ctor2); + } + // void f(int); // void foo(){ // f((1, 2)); @@ -4709,97 +4763,6 @@ public class AST2CPPTests extends AST2BaseTest { assertSame(i, col.getName(7).resolveBinding()); } - // template - // struct basic_string { - // basic_string& operator+=(const T* s); - // basic_string& append(const T* s); - // }; - // - // template - // basic_string operator+(const T* cs, const basic_string& s); - // - // template - // basic_string operator+(const basic_string& s, const T* cs); - // - // typedef basic_string string; - // - // void test(const string& s) { - // auto s1 = "" + s + ""; - // auto s2 = s1 += ""; - // auto s3 = s2.append("foo"); - // } - public void testTypedefPreservation_380498_1() throws Exception { - BindingAssertionHelper ba= getAssertionHelper(); - ICPPVariable s1 = ba.assertNonProblem("s1", ICPPVariable.class); - assertTrue(s1.getType() instanceof ITypedef); - assertEquals("string", ((ITypedef) s1.getType()).getName()); - ICPPVariable s2 = ba.assertNonProblem("s2", ICPPVariable.class); - assertTrue(s2.getType() instanceof ITypedef); - assertEquals("string", ((ITypedef) s2.getType()).getName()); - ICPPVariable s3 = ba.assertNonProblem("s3", ICPPVariable.class); - assertTrue(s3.getType() instanceof ITypedef); - assertEquals("string", ((ITypedef) s3.getType()).getName()); - } - - // template - // struct vector { - // typedef T* const_iterator; - // const_iterator begin() const; - // }; - // - // typedef int Element; - // - // void test(const vector& v) { - // auto it = v.begin(); - // } - public void testTypedefPreservation_380498_2() throws Exception { - BindingAssertionHelper ba= getAssertionHelper(); - ICPPVariable it = ba.assertNonProblem("it =", "it", ICPPVariable.class); - assertTrue(it.getType() instanceof ITypedef); - assertEquals("vector::const_iterator", ASTTypeUtil.getType(it.getType(), false)); - } - - // template class char_traits {}; - // template > class basic_string {}; - // - // template - // struct iterator_traits { - // typedef typename _Iterator::reference reference; - // }; - // - // template - // struct iterator_traits<_Tp*> { - // typedef _Tp& reference; - // }; - // - // template - // struct normal_iterator { - // typedef iterator_traits<_Iterator> traits_type; - // typedef typename traits_type::reference reference; - // reference operator*() const; - // }; - // - // template struct vector { - // typedef T* pointer; - // typedef normal_iterator iterator; - // iterator begin(); - // iterator end(); - // }; - // - // typedef basic_string string; - // - // void test() { - // vector v; - // for (auto s : v) { - // } - // } - public void testTypedefPreservation_380498_3() throws Exception { - BindingAssertionHelper ba= getAssertionHelper(); - ICPPVariable s = ba.assertNonProblem("s :", "s", ICPPVariable.class); - assertTrue(s.getType() instanceof ITypedef); - assertEquals("string", ASTTypeUtil.getType(s.getType(), false)); - } - // int f() { // return 5; // } @@ -9971,4 +9934,16 @@ public class AST2CPPTests extends AST2BaseTest { public void testFinalParameter() throws Exception { parseAndCheckBindings(); } + + // struct S1 {}; + // S1 s1; + // const int i= 1; + // template struct CT {}; + // typedef int TD; + // bool operator==(S1 a, int r ); + // static const int x = sizeof(CT((TD * (CT::*)) 0 )); + // template bool operator==(S1 a, const CT& r ); + public void testOrderInAmbiguityResolution_390759() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index ccef1360111..5e44688939c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -18,6 +18,9 @@ import static org.eclipse.cdt.core.parser.ParserLanguage.CPP; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType; + +import java.io.IOException; + import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.IName; @@ -29,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; 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; @@ -50,7 +54,6 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -89,6 +92,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.parser.ParserException; public class AST2TemplateTests extends AST2BaseTest { @@ -111,6 +115,11 @@ public class AST2TemplateTests extends AST2BaseTest { return parseAndCheckBindings(code, CPP); } + protected BindingAssertionHelper getAssertionHelper() throws ParserException, IOException { + String code= getAboveComment(); + return new BindingAssertionHelper(code, true); + } + public void testBasicClassTemplate() throws Exception { IASTTranslationUnit tu = parse("template class A{ T t; };", CPP); //$NON-NLS-1$ CPPNameCollector col = new CPPNameCollector(); @@ -1719,23 +1728,19 @@ public class AST2TemplateTests extends AST2BaseTest { // void m(){ // f(A(1)); // } - public void testBug99254() throws Exception{ - IASTTranslationUnit tu = parse(getAboveComment(), CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding(); - ICPPFunction f = (ICPPFunction) col.getName(5).resolveBinding(); - - final IASTName typeConversion = col.getName(11); - ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding(); + public void testBug99254_1() throws Exception { + BindingAssertionHelper bh= getAssertionHelper(); + ICPPConstructor ctor = bh.assertNonProblem("A(T t)", "A", ICPPConstructor.class); + ICPPSpecialization spec = bh.assertNonProblem("A(1)", "A", ICPPSpecialization.class); assertSame(ctor.getOwner(), spec.getSpecializedBinding()); - - final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent(); - final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding(); - assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding())); - - assertSame(f, col.getName(10).resolveBinding()); + IASTName name = bh.findName("A(1)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + ICPPSpecialization ctor2 = (ICPPSpecialization) implicitNames[0].getBinding(); + assertSame(ctor, ctor2.getSpecializedBinding()); + ICPPFunction f = bh.assertNonProblem("f(A a)", "f", ICPPFunction.class); + ICPPFunction f2 = bh.assertNonProblem("f(A(1))", "f", ICPPFunction.class); + assertSame(f, f2); } // namespace core { @@ -1744,67 +1749,59 @@ public class AST2TemplateTests extends AST2BaseTest { // }; // } // class B { - // int add(const core::A &rect); + // int add(const core::A& rect); // }; // void f(B* b){ // b->add(core::A(10, 2)); // } public void testBug99254_2() throws Exception { - IASTTranslationUnit tu = parse(getAboveComment(), CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor ctor = (ICPPConstructor) col.getName(3).resolveBinding(); - ICPPMethod add = (ICPPMethod) col.getName(9).resolveBinding(); - - final IASTName typeConversion = col.getName(20); - ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding(); + BindingAssertionHelper bh= getAssertionHelper(); + ICPPConstructor ctor = bh.assertNonProblem("A(T x, T y)", "A", ICPPConstructor.class); + ICPPSpecialization spec = bh.assertNonProblem("A(10, 2)", "A", ICPPSpecialization.class); assertSame(ctor.getOwner(), spec.getSpecializedBinding()); - - final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent(); - final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding(); - assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding())); - - assertSame(add, col.getName(19).resolveBinding()); + IASTName name = bh.findName("A(10, 2)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + ICPPSpecialization ctor2 = (ICPPSpecialization) implicitNames[0].getBinding(); + assertSame(ctor, ctor2.getSpecializedBinding()); + ICPPMethod add = bh.assertNonProblem("add(const core::A& rect)", "add", ICPPMethod.class); + ICPPMethod add2 = bh.assertNonProblem("b->add(core::A(10, 2))", "add", ICPPMethod.class); + assertSame(add, add2); } // template class A { A(T); }; // typedef signed int s32; // class B { - // int add(const A &rect); + // int add(const A& rect); // }; // void f(B* b){ // b->add(A(10)); // } public void testBug99254_3() throws Exception { - IASTTranslationUnit tu = parse(getAboveComment(), CPP); - CPPNameCollector col = new CPPNameCollector(); - tu.accept(col); - - ICPPConstructor ctor = (ICPPConstructor) col.getName(2).resolveBinding(); - ICPPMethod add = (ICPPMethod) col.getName(7).resolveBinding(); - - final IASTName typeConversion = col.getName(17); - ICPPSpecialization spec = (ICPPSpecialization) typeConversion.resolveBinding(); + BindingAssertionHelper bh= getAssertionHelper(); + ICPPConstructor ctor = bh.assertNonProblem("A(T)", "A", ICPPConstructor.class); + ICPPSpecialization spec = bh.assertNonProblem("A(10)", "A", ICPPSpecialization.class); assertSame(ctor.getOwner(), spec.getSpecializedBinding()); - - final ICPPASTFunctionCallExpression fcall = (ICPPASTFunctionCallExpression) typeConversion.getParent().getParent(); - final IBinding ctorSpec = fcall.getImplicitNames()[0].resolveBinding(); - assertSame(ctor, (((ICPPSpecialization) ctorSpec).getSpecializedBinding())); - - assertSame(add, col.getName(16).resolveBinding()); + IASTName name = bh.findName("A(10)", "A"); + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) name.getParent().getParent()).getImplicitNames(); + assertEquals(1, implicitNames.length); + ICPPSpecialization ctor2 = (ICPPSpecialization) implicitNames[0].getBinding(); + assertSame(ctor, ctor2.getSpecializedBinding()); + ICPPMethod add = bh.assertNonProblem("add(const A& rect)", "add", ICPPMethod.class); + ICPPMethod add2 = bh.assertNonProblem("b->add(A(10))", "add", ICPPMethod.class); + assertSame(add, add2); } public void testBug98666() throws Exception { CPPASTNameBase.sAllowNameComputation= true; - IASTTranslationUnit tu = parse("A::template B b;", CPP); //$NON-NLS-1$ + IASTTranslationUnit tu = parse("A::template B b;", CPP); CPPNameCollector col = new CPPNameCollector(); tu.accept(col); ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0); IASTName[] ns = qn.getNames(); assertTrue(ns[1] instanceof ICPPASTTemplateId); - assertEquals(ns[1].toString(), "B"); //$NON-NLS-1$ + assertEquals(ns[1].toString(), "B"); } // template struct A{ @@ -2278,8 +2275,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(p); // } public void testFunctionTemplate_272848_1() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -2295,8 +2291,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(p); // } public void testFunctionTemplate_272848_2() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -2309,8 +2304,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(x); // } public void testFunctionTemplate_309564() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void f1(void(*f)(const U&)) {} @@ -2319,8 +2313,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f1(&f2); // problem on f1 // } public void testSimplifiedFunctionTemplateWithFunctionPointer_281783() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -2638,8 +2631,7 @@ public class AST2TemplateTests extends AST2BaseTest { // AI y; // AT z; public void testDefaultTemplateParameter_281781() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // class A {}; @@ -3254,7 +3246,7 @@ public class AST2TemplateTests extends AST2BaseTest { // }; // } public void testBug238180_ArrayOutOfBounds() throws Exception { - // the code above used to trigger an ArrayOutOfBoundsException + // The code above used to trigger an ArrayOutOfBoundsException parse(getAboveComment(), CPP); } @@ -3557,8 +3549,7 @@ public class AST2TemplateTests extends AST2BaseTest { // xt.partial; // } public void testDefaultArgsWithPartialSpecialization() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class XT { @@ -3707,6 +3698,116 @@ public class AST2TemplateTests extends AST2BaseTest { bh.assertNonProblem("func(p)", 4, ICPPFunction.class); } + // template + // struct C { + // typedef void (T::*PMF)(); + // C(PMF member); + // }; + // + // struct A { + // void m(); + // }; + // + // typedef A B; + // + // void test() { + // new C(&B::m); + // } + public void testTypedef() throws Exception { + parseAndCheckBindings(); + } + + // template + // struct basic_string { + // basic_string& operator+=(const T* s); + // basic_string& append(const T* s); + // }; + // + // template + // basic_string operator+(const T* cs, const basic_string& s); + // + // template + // basic_string operator+(const basic_string& s, const T* cs); + // + // typedef basic_string string; + // + // void test(const string& s) { + // auto s1 = "" + s + ""; + // auto s2 = s1 += ""; + // auto s3 = s2.append("foo"); + // } + public void testTypedefPreservation_380498_1() throws Exception { + BindingAssertionHelper ba= getAssertionHelper(); + ICPPVariable s1 = ba.assertNonProblem("s1", ICPPVariable.class); + assertTrue(s1.getType() instanceof ITypedef); + assertEquals("string", ((ITypedef) s1.getType()).getName()); + ICPPVariable s2 = ba.assertNonProblem("s2", ICPPVariable.class); + assertTrue(s2.getType() instanceof ITypedef); + assertEquals("string", ((ITypedef) s2.getType()).getName()); + ICPPVariable s3 = ba.assertNonProblem("s3", ICPPVariable.class); + assertTrue(s3.getType() instanceof ITypedef); + assertEquals("string", ((ITypedef) s3.getType()).getName()); + } + + // template + // struct vector { + // typedef T* const_iterator; + // const_iterator begin() const; + // }; + // + // typedef int Element; + // + // void test(const vector& v) { + // auto it = v.begin(); + // } + public void testTypedefPreservation_380498_2() throws Exception { + BindingAssertionHelper ba= getAssertionHelper(); + ICPPVariable it = ba.assertNonProblem("it =", "it", ICPPVariable.class); + assertTrue(it.getType() instanceof ITypedef); + assertEquals("vector::const_iterator", ASTTypeUtil.getType(it.getType(), false)); + } + + // template class char_traits {}; + // template > class basic_string {}; + // + // template + // struct iterator_traits { + // typedef typename _Iterator::reference reference; + // }; + // + // template + // struct iterator_traits<_Tp*> { + // typedef _Tp& reference; + // }; + // + // template + // struct normal_iterator { + // typedef iterator_traits<_Iterator> traits_type; + // typedef typename traits_type::reference reference; + // reference operator*() const; + // }; + // + // template struct vector { + // typedef T* pointer; + // typedef normal_iterator iterator; + // iterator begin(); + // iterator end(); + // }; + // + // typedef basic_string string; + // + // void test() { + // vector v; + // for (auto s : v) { + // } + // } + public void testTypedefPreservation_380498_3() throws Exception { + BindingAssertionHelper ba= getAssertionHelper(); + ICPPVariable s = ba.assertNonProblem("s :", "s", ICPPVariable.class); + assertTrue(s.getType() instanceof ITypedef); + assertEquals("string", ASTTypeUtil.getType(s.getType(), false)); + } + // template // struct A { // template struct C { @@ -3853,8 +3954,7 @@ public class AST2TemplateTests extends AST2BaseTest { // } // }; public void testResolutionOfUnknownFunctions() throws Exception { - String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // class C {}; @@ -3866,8 +3966,7 @@ public class AST2TemplateTests extends AST2BaseTest { // } // }; public void testResolutionOfUnknownArrayAccess() throws Exception { - String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class CT { @@ -3880,7 +3979,7 @@ public class AST2TemplateTests extends AST2BaseTest { // x.append(3, 'c'); // } public void testConflictInTemplateArgumentDeduction() throws Exception { - String code= getAboveComment(); + final String code= getAboveComment(); parseAndCheckBindings(code); BindingAssertionHelper bh= new BindingAssertionHelper(code, CPP); ICPPMethod m= bh.assertNonProblem("append(3", 6); @@ -3921,10 +4020,9 @@ public class AST2TemplateTests extends AST2BaseTest { // return A(p); // } public void testForwardDeclarations_264109() throws Exception { - final String code = getAboveComment(); - BindingAssertionHelper bh= new BindingAssertionHelper(code, CPP); + BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP); bh.assertNonProblem("A make_A(C* p) {", 4, ICPPTemplateInstance.class); - parseAndCheckBindings(code); + parseAndCheckBindings(getAboveComment()); } // template class CT { @@ -3937,8 +4035,7 @@ public class AST2TemplateTests extends AST2BaseTest { // any(CT(iptr)); // } public void testConstructorTemplateInClassTemplate_264314() throws Exception { - String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class XT {}; @@ -3955,8 +4052,7 @@ public class AST2TemplateTests extends AST2BaseTest { // func(y, xy, xint); // } public void testDistinctDeferredInstances_264367() throws Exception { - String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class XT { @@ -3965,8 +4061,7 @@ public class AST2TemplateTests extends AST2BaseTest { // } // }; public void testUnknownParameter_264988() throws Exception { - String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -3977,8 +4072,7 @@ public class AST2TemplateTests extends AST2BaseTest { // int x = A<0>::e; // A<0>::E y; public void testEnumeratorInTemplateInstance_265070() throws Exception { - String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class CT {}; @@ -3989,10 +4083,9 @@ public class AST2TemplateTests extends AST2BaseTest { // getline2(i); // } public void testAmbiguousDeclaratorInFunctionTemplate_265342() throws Exception { - final String code = getAboveComment(); - BindingAssertionHelper bh= new BindingAssertionHelper(code, CPP); + BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP); bh.assertNonProblem("getline2(i)", 8, ICPPTemplateInstance.class); - parseAndCheckBindings(code); + parseAndCheckBindings(getAboveComment()); } // class C { @@ -4008,8 +4101,7 @@ public class AST2TemplateTests extends AST2BaseTest { // }; // }; public void testOwnerOfFriendTemplate_265671() throws Exception { - final String code = getAboveComment(); - BindingAssertionHelper bh= new BindingAssertionHelper(code, CPP); + BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP); IFunction f= bh.assertNonProblem("f1(", 2, IFunction.class); IBinding owner= f.getOwner(); assertNull(owner); @@ -4026,7 +4118,7 @@ public class AST2TemplateTests extends AST2BaseTest { tpar= bh.assertNonProblem("T3", 2, ICPPTemplateParameter.class); assertEquals(2, tpar.getTemplateNestingLevel()); - parseAndCheckBindings(code); + parseAndCheckBindings(getAboveComment()); } // template void f(T t) { @@ -4034,13 +4126,12 @@ public class AST2TemplateTests extends AST2BaseTest { // } // template void g(T t) {} public void testDependentNameReferencingLaterDeclaration_265926a() throws Exception { - final String code = getAboveComment(); - BindingAssertionHelper bh= new BindingAssertionHelper(code, CPP); + BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP); IFunction gref= bh.assertNonProblem("g(t)", 1); assertInstance(gref, ICPPUnknownBinding.class); IFunction gdecl= bh.assertNonProblem("g(T t)", 1); - parseAndCheckBindings(code); + parseAndCheckBindings(getAboveComment()); } // class C; @@ -4060,8 +4151,7 @@ public class AST2TemplateTests extends AST2BaseTest { // void a() {}; // }; public void testDependentNameReferencingLaterDeclaration_265926b() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class XT { @@ -4072,22 +4162,20 @@ public class AST2TemplateTests extends AST2BaseTest { // } // }; public void testDeferredConversionOperator() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class X {}; // template class X1 { // friend class X; // }; - // template class Y : X1 { + // template class Y : X1 { // void test() { // X x; // problem binding on X // } // }; public void testFriendClassTemplate_266992() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -4098,8 +4186,19 @@ public class AST2TemplateTests extends AST2BaseTest { // S(a); // } public void testFunctionTemplateWithArrayReferenceParameter_269926() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); + } + + // typedef unsigned int uint; + // template + // void S(int (&array)[N]); + // + // int a[1]; + // void test() { + // S(a); + // } + public void testFunctionTemplateWithArrayReferenceParameter_394024() throws Exception { + parseAndCheckBindings(); } // template @@ -4116,8 +4215,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(p); // } public void testTemplateConversionOperator_271948_1() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -4136,16 +4234,14 @@ public class AST2TemplateTests extends AST2BaseTest { // f(x); // } public void testTemplateConversionOperator_271948_2() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template struct ST{}; // template class T> class CT {}; // typedef CT TDef; public void testUsingTemplateTemplateParameter_279619() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void T(int (&array)[N]) {}; @@ -4154,8 +4250,7 @@ public class AST2TemplateTests extends AST2BaseTest { // T<2>(a); // } public void testInstantiationOfArraySize_269926() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class CT { @@ -4164,8 +4259,7 @@ public class AST2TemplateTests extends AST2BaseTest { // void CT::init(void) { // } public void testMethodSpecialization_322988() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code, CPP); + parseAndCheckBindings(); } @@ -4179,8 +4273,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(x); // } public void testInlineFriendFunction_284690_1() throws Exception { - final String code = getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -4218,8 +4311,7 @@ public class AST2TemplateTests extends AST2BaseTest { // typedef NullType Type; // }; public void testDefaultArgument_289132() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class XT { @@ -4278,8 +4370,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(ch, cint); // } public void testFunctionTemplateOrdering_293468() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void func(T* t) {}; @@ -4296,8 +4387,7 @@ public class AST2TemplateTests extends AST2BaseTest { // func1 (a); // } public void testFunctionTemplateOrdering_294539() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class CT {}; @@ -4310,8 +4400,7 @@ public class AST2TemplateTests extends AST2BaseTest { // return a; // } public void testClosingAngleBrackets1_261268() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class CT {}; @@ -4340,8 +4429,7 @@ public class AST2TemplateTests extends AST2BaseTest { // a < a >> (1+2); // binary expression via ambiguity // } public void testClosingAngleBracketsAmbiguity_261268() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // #define OPASSIGN(x) x##= @@ -4350,8 +4438,7 @@ public class AST2TemplateTests extends AST2BaseTest { // a OPASSIGN(>>) 1; // } public void testTokenPasteShiftROperator_261268() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class X { @@ -4485,16 +4572,14 @@ public class AST2TemplateTests extends AST2BaseTest { // CTx<1,2> c; // } public void testNonTypeTemplateParameterPack_280909() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template // struct count { static const int value = sizeof...(Types); // }; public void testVariadicTemplateExamples_280909a() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void f(T (* ...t)(int, int)); @@ -4504,8 +4589,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(add, subtract); // } public void testVariadicTemplateExamples_280909b() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template @@ -4514,15 +4598,13 @@ public class AST2TemplateTests extends AST2BaseTest { // X(const Mixins&... mixins) : Mixins(mixins)... { } // }; public void testVariadicTemplateExamples_280909c() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class Tuple; // Types is a template type parameter pack // template struct multi array; // Dims is a non-type template parameter pack public void testVariadicTemplateExamples_280909d() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class String; @@ -4631,8 +4713,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(0, 0, 0); // Types is the sequence int*, float*, int // } public void testVariadicTemplateExamples_280909j() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void f(Types&...); @@ -4643,8 +4724,7 @@ public class AST2TemplateTests extends AST2BaseTest { // g(x, y, z); // T1 is deduced to int, Types is deduced to float, int // } public void testVariadicTemplateExamples_280909k() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template struct X { }; @@ -4661,8 +4741,7 @@ public class AST2TemplateTests extends AST2BaseTest { // Y y3; // uses primary template, Types contains int, float, double // int fv = f(g); // okay, Types contains int, float public void testVariadicTemplateExamples_280909n() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template struct Tuple { }; @@ -4688,8 +4767,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(2, 1.0); // okay: args contains two arguments, an int and a double // } public void testVariadicTemplateExamples_280909q() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void f(Types... rest); @@ -4697,8 +4775,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(&rest...); // '&rest...' is a pack expansion, '&rest' is its pattern // } public void testVariadicTemplateExamples_280909r() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template struct Tuple {}; @@ -4748,8 +4825,7 @@ public class AST2TemplateTests extends AST2BaseTest { // bind(&Test::Update); // } public void testFunctionOrdering_299608() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void f(T t = 0, U u = 0); @@ -4858,8 +4934,7 @@ public class AST2TemplateTests extends AST2BaseTest { // CT::CT() : value_(0) { // } public void testConstructorOfExplicitSpecialization() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template struct CT; @@ -4907,8 +4982,7 @@ public class AST2TemplateTests extends AST2BaseTest { // CT::T2 b; // } public void testBug306213c() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class CT {}; @@ -4985,7 +5059,7 @@ public class AST2TemplateTests extends AST2BaseTest { // template void N::f(int&); // template<> void N::f(long&) {} public void testInlineNamespaces_305980() throws Exception { - final String code= getAboveComment(); + final String code = getAboveComment(); parseAndCheckBindings(code); BindingAssertionHelper bh= new BindingAssertionHelper(code, CPP); ICPPFunctionTemplate ft= bh.assertNonProblem("f(T&)", 1); @@ -5021,8 +5095,7 @@ public class AST2TemplateTests extends AST2BaseTest { // g(x); // } public void testUnnamedTypesAsTemplateArgument_316317a() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template class X { }; @@ -5041,8 +5114,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(b); // OK // } public void testUnnamedTypesAsTemplateArgument_316317b() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // struct S { @@ -5058,8 +5130,7 @@ public class AST2TemplateTests extends AST2BaseTest { // (x + 1)->s; // } public void testOverloadResolutionBetweenMethodTemplateAndFunction() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template void f(T..., T...); @@ -5067,8 +5138,7 @@ public class AST2TemplateTests extends AST2BaseTest { // f(1,1); // } public void testFunctionParameterPacksInNonFinalPosition_324096() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template struct OutStream { @@ -5576,8 +5646,7 @@ public class AST2TemplateTests extends AST2BaseTest { // typedef r::s t; // t::u x; public void testBoolExpressionAsTemplateArgument_361604() throws Exception { - final String code= getAboveComment(); - parseAndCheckBindings(code); + parseAndCheckBindings(); } // template struct B { @@ -6074,4 +6143,14 @@ public class AST2TemplateTests extends AST2BaseTest { public void testAddressAsTemplateArgument_391190() throws Exception { parseAndCheckBindings(getAboveComment(), CPP, true); } + + // template struct CT { + // const static int const_min= 1; + // }; + // void test(int off) { + // off < CT::const_min || off > CT::const_min; + // } + public void testTemplateIDAmbiguity_393959() throws Exception { + parseAndCheckBindings(getAboveComment(), CPP, true); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java index 48f4e1a6c1a..f031afca0a5 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java @@ -1,13 +1,13 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation 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: - * John Camelon (IBM Rational Software) - Initial API and implementation - * Markus Schorn (Wind River Systems) + * Copyright (c) 2004, 2011 IBM Corporation 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: + * John Camelon (IBM Rational Software) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -41,211 +41,200 @@ public class GCCCompleteParseExtensionsTest extends AST2BaseTest { } private IASTTranslationUnit parseGCC(String code) throws ParserException { - IASTTranslationUnit tu = parse(code, ParserLanguage.C, true, true); - + IASTTranslationUnit tu = parse(code, ParserLanguage.C, true, true); + CNameResolver resolver = new CNameResolver(); tu.accept(resolver); if (resolver.numProblemBindings > 0) - throw new ParserException(" there are " + resolver.numProblemBindings + " ProblemBindings on the tu"); //$NON-NLS-1$ //$NON-NLS-2$ + throw new ParserException(" there are " + resolver.numProblemBindings + " ProblemBindings on the tu"); //$NON-NLS-2$ if (resolver.numNullBindings > 0) - throw new ParserException("Expected no null bindings, encountered " + resolver.numNullBindings); //$NON-NLS-1$ - + throw new ParserException("Expected no null bindings, encountered " + resolver.numNullBindings); return tu; } - + private IASTTranslationUnit parseGPP(String code) throws ParserException { - IASTTranslationUnit tu = parse(code, ParserLanguage.CPP, true, true); + IASTTranslationUnit tu = parse(code, ParserLanguage.CPP, true, true); CPPNameResolver resolver = new CPPNameResolver(); tu.accept(resolver); if (resolver.numProblemBindings > 0) - throw new ParserException(" there are " + resolver.numProblemBindings + " ProblemBindings on the tu"); //$NON-NLS-1$ //$NON-NLS-2$ + throw new ParserException(" there are " + resolver.numProblemBindings + " ProblemBindings on the tu"); //$NON-NLS-2$ if (resolver.numNullBindings > 0) - throw new ParserException("Expected no null bindings, encountered " + resolver.numNullBindings); //$NON-NLS-1$ - + throw new ParserException("Expected no null bindings, encountered " + resolver.numNullBindings); return tu; } - - public void testBug39695() throws Exception - { - parseGCC("int a = __alignof__ (int);").getDeclarations(); //$NON-NLS-1$ + + public void testBug39695() throws Exception { + parseGCC("int a = __alignof__ (int);").getDeclarations(); } - - public void testBug39684() throws Exception - { - IASTDeclaration bar = parseGCC("typeof(foo(1)) bar () { return foo(1); }").getDeclarations()[0]; //$NON-NLS-1$ + + public void testBug39684() throws Exception { + IASTDeclaration bar = parseGCC("typeof(foo(1)) bar () { return foo(1); }").getDeclarations()[0]; assertTrue(bar instanceof CASTFunctionDefinition); CFunction barFunc = (CFunction)((CASTFunctionDefinition)bar).getDeclarator().getName().resolveBinding(); IFunctionType type = barFunc.getType(); - + // TODO Devin typeof declSpec has 0 length, also doesn't seem to have a type for typeof... raise a bug // IASTSimpleTypeSpecifier simpleTypeSpec = ((IASTSimpleTypeSpecifier)bar.getReturnType().getTypeSpecifier()); -// assertEquals( simpleTypeSpec.getType(), IASTGCCSimpleTypeSpecifier.Type.TYPEOF ); +// assertEquals(simpleTypeSpec.getType(), IASTGCCSimpleTypeSpecifier.Type.TYPEOF); } - public void testBug39698A() throws Exception - { - IASTDeclaration[] decls = parseGPP("int a=0; \n int b=1; \n int c = a ? b;").getDeclarations(); //$NON-NLS-1$ - assertEquals( ASTStringUtil.getExpressionString( (IASTExpression) ((IASTEqualsInitializer)((IASTSimpleDeclaration)decls[2]).getDeclarators()[0].getInitializer()).getInitializerClause() ), "a >? b" ); //$NON-NLS-1$ + + public void testBug39698B() throws Exception { + IASTDeclaration[] decls = parseGPP("int a=0; \n int b=1; \n int c = a >? b;").getDeclarations(); + assertEquals(ASTStringUtil.getExpressionString((IASTExpression) ((IASTEqualsInitializer)((IASTSimpleDeclaration)decls[2]).getDeclarators()[0].getInitializer()).getInitializerClause()), "a >? b"); } public void testPredefinedSymbol_bug69791() throws Exception { - parseGPP("typedef __builtin_va_list __gnuc_va_list; \n").getDeclarations();//$NON-NLS-1$ - parseGCC("typedef __builtin_va_list __gnuc_va_list; \n").getDeclarations();//$NON-NLS-1$ + parseGPP("typedef __builtin_va_list __gnuc_va_list; \n").getDeclarations(); + parseGCC("typedef __builtin_va_list __gnuc_va_list; \n").getDeclarations(); } - public void testBug39697() throws Exception - { + public void testBug39697() throws Exception { Writer writer = new StringWriter(); - writer.write( "__asm__( \"CODE\" );\n" ); //$NON-NLS-1$ - writer.write( "__inline__ int foo() { return 4; }\n"); //$NON-NLS-1$ - writer.write( "__const__ int constInt;\n"); //$NON-NLS-1$ - writer.write( "__volatile__ int volInt;\n"); //$NON-NLS-1$ - writer.write( "__signed__ int signedInt;\n"); //$NON-NLS-1$ - IASTDeclaration[] decls = parseGCC( writer.toString() ).getDeclarations(); - - assertEquals(((IASTASMDeclaration)decls[0]).getAssembly(), "\"CODE\""); //$NON-NLS-1$ - assertTrue( ((IASTFunctionDefinition)decls[1]).getDeclSpecifier().isInline() ); - assertTrue( ((IASTSimpleDeclaration)decls[2]).getDeclSpecifier().isConst() ); - assertTrue( ((IASTSimpleDeclaration)decls[3]).getDeclSpecifier().isVolatile() ); - assertTrue( ((ICASTSimpleDeclSpecifier)((IASTSimpleDeclaration)decls[4]).getDeclSpecifier()).isSigned() ); + writer.write("__asm__( \"CODE\" );\n"); + writer.write("__inline__ int foo() { return 4; }\n"); + writer.write("__const__ int constInt;\n"); + writer.write("__volatile__ int volInt;\n"); + writer.write("__signed__ int signedInt;\n"); + IASTDeclaration[] decls = parseGCC(writer.toString()).getDeclarations(); + + assertEquals(((IASTASMDeclaration)decls[0]).getAssembly(), "\"CODE\""); + assertTrue(((IASTFunctionDefinition)decls[1]).getDeclSpecifier().isInline()); + assertTrue(((IASTSimpleDeclaration)decls[2]).getDeclSpecifier().isConst()); + assertTrue(((IASTSimpleDeclaration)decls[3]).getDeclSpecifier().isVolatile()); + assertTrue(((ICASTSimpleDeclSpecifier)((IASTSimpleDeclaration)decls[4]).getDeclSpecifier()).isSigned()); writer = new StringWriter(); - writer.write( "int * __restrict__ resPointer1;\n"); //$NON-NLS-1$ - writer.write( "int * __restrict resPointer2;\n"); //$NON-NLS-1$ - decls = parseGCC( writer.toString() ).getDeclarations(); - assertTrue( ((ICASTPointer)((IASTSimpleDeclaration)decls[0]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); - assertTrue( ((ICASTPointer)((IASTSimpleDeclaration)decls[1]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); + writer.write("int * __restrict__ resPointer1;\n"); + writer.write("int * __restrict resPointer2;\n"); + decls = parseGCC(writer.toString()).getDeclarations(); + assertTrue(((ICASTPointer)((IASTSimpleDeclaration)decls[0]).getDeclarators()[0].getPointerOperators()[0]).isRestrict()); + assertTrue(((ICASTPointer)((IASTSimpleDeclaration)decls[1]).getDeclarators()[0].getPointerOperators()[0]).isRestrict()); writer = new StringWriter(); - writer.write( "int * __restrict__ resPointer1;\n"); //$NON-NLS-1$ - writer.write( "int * __restrict resPointer2;\n"); //$NON-NLS-1$ - decls = parseGPP( writer.toString() ).getDeclarations(); - assertTrue( ((IASTPointer)((IASTSimpleDeclaration)decls[0]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); - assertTrue( ((IASTPointer)((IASTSimpleDeclaration)decls[1]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); - + writer.write("int * __restrict__ resPointer1;\n"); + writer.write("int * __restrict resPointer2;\n"); + decls = parseGPP(writer.toString()).getDeclarations(); + assertTrue(((IASTPointer)((IASTSimpleDeclaration)decls[0]).getDeclarators()[0].getPointerOperators()[0]).isRestrict()); + assertTrue(((IASTPointer)((IASTSimpleDeclaration)decls[1]).getDeclarators()[0].getPointerOperators()[0]).isRestrict()); } - public void testBug73954A() throws Exception{ + public void testBug73954A() throws Exception { StringWriter writer = new StringWriter(); - writer.write("void f(){ \n");//$NON-NLS-1$ - writer.write(" __builtin_expect( 23, 2); \n");//$NON-NLS-1$ - writer.write(" __builtin_prefetch( (const void *)0, 1, 2); \n");//$NON-NLS-1$ - writer.write(" __builtin_huge_val(); \n");//$NON-NLS-1$ - writer.write(" __builtin_huge_valf(); \n");//$NON-NLS-1$ - writer.write(" __builtin_huge_vall(); \n");//$NON-NLS-1$ - writer.write(" __builtin_inf(); \n");//$NON-NLS-1$ - writer.write(" __builtin_inff(); \n");//$NON-NLS-1$ - writer.write(" __builtin_infl(); \n");//$NON-NLS-1$ - writer.write(" __builtin_nan(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_nanf(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_nanl(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_nans(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_nansf(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_nansl(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_ffs (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_clz (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_ctz (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_popcount (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_parity (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_ffsl (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_clzl (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_ctzl (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_popcountl (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_parityl (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_ffsll (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_clzll (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_ctzll (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_popcountll (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_parityll (0); \n");//$NON-NLS-1$ - writer.write(" __builtin_powi (0, 0); \n");//$NON-NLS-1$ - writer.write(" __builtin_powif (0, 0); \n");//$NON-NLS-1$ - writer.write(" __builtin_powil (0, 0); \n");//$NON-NLS-1$ - writer.write("} \n"); //$NON-NLS-1$ - - parseGCC( writer.toString() ); + writer.write("void f(){ \n"); + writer.write(" __builtin_expect( 23, 2); \n"); + writer.write(" __builtin_prefetch( (const void *)0, 1, 2); \n"); + writer.write(" __builtin_huge_val(); \n"); + writer.write(" __builtin_huge_valf(); \n"); + writer.write(" __builtin_huge_vall(); \n"); + writer.write(" __builtin_inf(); \n"); + writer.write(" __builtin_inff(); \n"); + writer.write(" __builtin_infl(); \n"); + writer.write(" __builtin_nan(\"\"); \n"); + writer.write(" __builtin_nanf(\"\"); \n"); + writer.write(" __builtin_nanl(\"\"); \n"); + writer.write(" __builtin_nans(\"\"); \n"); + writer.write(" __builtin_nansf(\"\"); \n"); + writer.write(" __builtin_nansl(\"\"); \n"); + writer.write(" __builtin_ffs (0); \n"); + writer.write(" __builtin_clz (0); \n"); + writer.write(" __builtin_ctz (0); \n"); + writer.write(" __builtin_popcount (0); \n"); + writer.write(" __builtin_parity (0); \n"); + writer.write(" __builtin_ffsl (0); \n"); + writer.write(" __builtin_clzl (0); \n"); + writer.write(" __builtin_ctzl (0); \n"); + writer.write(" __builtin_popcountl (0); \n"); + writer.write(" __builtin_parityl (0); \n"); + writer.write(" __builtin_ffsll (0); \n"); + writer.write(" __builtin_clzll (0); \n"); + writer.write(" __builtin_ctzll (0); \n"); + writer.write(" __builtin_popcountll (0); \n"); + writer.write(" __builtin_parityll (0); \n"); + writer.write(" __builtin_powi (0, 0); \n"); + writer.write(" __builtin_powif (0, 0); \n"); + writer.write(" __builtin_powil (0, 0); \n"); + writer.write("} \n"); + + parseGCC(writer.toString()); } - - public void testBug39686() throws Exception - { + + public void testBug39686() throws Exception { Writer code = new StringWriter(); - code.write("__complex__ double x; // complex double\n"); //$NON-NLS-1$ - code.write("__complex__ short int a; // complex short int\n"); //$NON-NLS-1$ - code.write("__complex__ float y = 2.5fi; // 2.5 imaginary float literal\n"); //$NON-NLS-1$ - code.write("__complex__ int z = 3i; // imaginary intege r literal\n"); //$NON-NLS-1$ - code.write("double v = __real__ x; // real part of expression\n"); //$NON-NLS-1$ - code.write("double w = __imag__ x; // imaginary part of expression\n"); //$NON-NLS-1$ + code.write("__complex__ double x; // complex double\n"); + code.write("__complex__ short int a; // complex short int\n"); + code.write("__complex__ float y = 2.5fi; // 2.5 imaginary float literal\n"); + code.write("__complex__ int z = 3i; // imaginary intege r literal\n"); + code.write("double v = __real__ x; // real part of expression\n"); + code.write("double w = __imag__ x; // imaginary part of expression\n"); parseGCC(code.toString()); } - - public void testBug39551B() throws Exception - { + + public void testBug39551B() throws Exception { //this used to be 99.99 * __I__, but I don't know where the __I__ came from, its not in C99, nor in GCC - IASTDeclaration decl = parseGCC("_Imaginary double id = 99.99 * 1i;").getDeclarations()[0]; //$NON-NLS-1$ + IASTDeclaration decl = parseGCC("_Imaginary double id = 99.99 * 1i;").getDeclarations()[0]; // TODO Devin does ICPPASTSimpleDeclSpecifier need something for isImaginary ? - // assertEquals( variable.getName(), "id"); //$NON-NLS-1$ -// assertTrue( ((IASTSimpleTypeSpecifier)variable.getAbstractDeclaration().getTypeSpecifier()).isImaginary() ); + // assertEquals(variable.getName(), "id"); +// assertTrue(((IASTSimpleTypeSpecifier)variable.getAbstractDeclaration().getTypeSpecifier()).isImaginary()); } - - public void testBug39681() throws Exception - { + + public void testBug39681() throws Exception { Writer code = new StringWriter(); - code.write("double\n"); //$NON-NLS-1$ - code.write("foo (double a, double b)\n"); //$NON-NLS-1$ - code.write("{\n"); //$NON-NLS-1$ - code.write(" double square (double z) { return z * z; }\n"); //$NON-NLS-1$ - code.write(" return square (a) + square (b);\n"); //$NON-NLS-1$ - code.write("}\n"); //$NON-NLS-1$ + code.write("double\n"); + code.write("foo (double a, double b)\n"); + code.write("{\n"); + code.write(" double square (double z) { return z * z; }\n"); + code.write(" return square (a) + square (b);\n"); + code.write("}\n"); parseGCC(code.toString()); } - - public void testBug39677() throws Exception - { - parseGPP("class B { public: B(); int a;}; B::B() : a(({ 1; })) {}"); //$NON-NLS-1$ + + public void testBug39677() throws Exception { + parseGPP("class B { public: B(); int a;}; B::B() : a(({ 1; })) {}"); Writer writer = new StringWriter(); - writer.write( "int foo(); class B { public: B(); int a;};"); - writer.write( "B::B() : a(( { int y = foo (); int z;\n" ); //$NON-NLS-1$ - writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ - writer.write( "else z = - y;\n" );//$NON-NLS-1$ - writer.write( "z; })) {}\n" );//$NON-NLS-1$ - parseGPP( writer.toString() ); - + writer.write("int foo(); class B { public: B(); int a;};"); + writer.write("B::B() : a(( { int y = foo (); int z;\n"); + writer.write("if (y > 0) z = y;\n"); + writer.write("else z = - y;\n"); + writer.write("z; })) {}\n"); + parseGPP(writer.toString()); + writer = new StringWriter(); - writer.write( "int x = ({ int foo(); int y = foo (); int z;\n" ); //$NON-NLS-1$ - writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ - writer.write( "else z = - y;\n" );//$NON-NLS-1$ - writer.write( "z; });\n" );//$NON-NLS-1$ - parseGPP( writer.toString() ); - + writer.write("int x = ({ int foo(); int y = foo (); int z;\n"); + writer.write("if (y > 0) z = y;\n"); + writer.write("else z = - y;\n"); + writer.write("z; });\n"); + parseGPP(writer.toString()); + writer = new StringWriter(); - writer.write( "int foo(); \n" ); //$NON-NLS-1$ - writer.write( "typeof({ int y = foo (); \n" ); //$NON-NLS-1$ - writer.write( " int z; \n" ); //$NON-NLS-1$ - writer.write( " if (y > 0) z = y; \n" ); //$NON-NLS-1$ - writer.write( " else z = - y; \n" ); //$NON-NLS-1$ - writer.write( " z; \n" ); //$NON-NLS-1$ - writer.write( " }) zoot; \n" ); //$NON-NLS-1$ - - parseGPP( writer.toString() ); // TODO Devin raised bug 93980 + writer.write("int foo(); \n"); + writer.write("typeof({ int y = foo (); \n"); + writer.write(" int z; \n"); + writer.write(" if (y > 0) z = y; \n"); + writer.write(" else z = - y; \n"); + writer.write(" z; \n"); + writer.write(" }) zoot; \n"); + + parseGPP(writer.toString()); // TODO Devin raised bug 93980 } - + public void testBug75401() throws Exception { Writer writer = new StringWriter(); - writer.write( "#define va_list __builtin_va_list \n"); //$NON-NLS-1$ - writer.write( "#define va_arg(v,l) __builtin_va_arg(v,l) \n"); //$NON-NLS-1$ - writer.write( "#define va_start(v,l) __builtin_va_start(v,l) \n"); //$NON-NLS-1$ - writer.write( "#define va_end(v) __builtin_va_end(v) \n"); //$NON-NLS-1$ - writer.write( "void variadic(int first, ...) { \n"); //$NON-NLS-1$ - writer.write( " va_list v; \n"); //$NON-NLS-1$ - writer.write( " va_start(v, first); \n"); //$NON-NLS-1$ - writer.write( " long l = va_arg(v, long); \n"); //$NON-NLS-1$ - writer.write( " va_end(v); \n"); //$NON-NLS-1$ - writer.write( "} \n"); //$NON-NLS-1$ + writer.write("#define va_list __builtin_va_list \n"); + writer.write("#define va_arg(v,l) __builtin_va_arg(v,l) \n"); + writer.write("#define va_start(v,l) __builtin_va_start(v,l) \n"); + writer.write("#define va_end(v) __builtin_va_end(v) \n"); + writer.write("void variadic(int first, ...) { \n"); + writer.write(" va_list v; \n"); + writer.write(" va_start(v, first); \n"); + writer.write(" long l = va_arg(v, long); \n"); + writer.write(" va_end(v); \n"); + writer.write("} \n"); parseGCC(writer.toString()); parseGPP(writer.toString()); @@ -253,136 +242,136 @@ public class GCCCompleteParseExtensionsTest extends AST2BaseTest { public void testBug73954B() throws Exception { Writer writer = new StringWriter(); - writer.write( "#define foo(x) \\\n"); //$NON-NLS-1$ - writer.write( " __builtin_choose_expr( 1, foo_d(x), (void)0 ) \n"); //$NON-NLS-1$ - writer.write( "int foo_d( int x ); \n"); //$NON-NLS-1$ - writer.write( "int main() { \n"); //$NON-NLS-1$ - writer.write( " if( __builtin_constant_p(1) && \n"); //$NON-NLS-1$ - writer.write( " __builtin_types_compatible_p( 1, 'c') ) \n"); //$NON-NLS-1$ - writer.write( " foo(1); \n"); //$NON-NLS-1$ - writer.write( "} \n"); //$NON-NLS-1$ - - parseGCC( writer.toString()); + writer.write("#define foo(x) \\\n"); + writer.write(" __builtin_choose_expr( 1, foo_d(x), (void)0 ) \n"); + writer.write("int foo_d( int x ); \n"); + writer.write("int main() { \n"); + writer.write(" if( __builtin_constant_p(1) && \n"); + writer.write(" __builtin_types_compatible_p( 1, 'c') ) \n"); + writer.write(" foo(1); \n"); + writer.write("} \n"); + + parseGCC(writer.toString()); } - + public void testGNUExternalTemplate_bug71603() throws Exception { - parseGPP("template \n class A {}; \n extern template class A; \n").getDeclarations(); //$NON-NLS-1$ + parseGPP("template \n class A {}; \n extern template class A; \n").getDeclarations(); } public void testBug74190_g_assert_1() throws Exception { Writer writer = new StringWriter(); - writer.write( "void log( int ); \n"); //$NON-NLS-1$ - writer.write( "void f() { \n"); //$NON-NLS-1$ - writer.write( " int a = 1; \n"); //$NON-NLS-1$ - writer.write( " (void)({ if( a ){ } \n"); //$NON-NLS-1$ - writer.write( " else{ log( a ); } \n"); //$NON-NLS-1$ - writer.write( " }); \n"); //$NON-NLS-1$ - writer.write( "} \n"); //$NON-NLS-1$ - - parseGCC( writer.toString() ); - parseGPP( writer.toString() ); + writer.write("void log( int ); \n"); + writer.write("void f() { \n"); + writer.write(" int a = 1; \n"); + writer.write(" (void)({ if( a ){ } \n"); + writer.write(" else{ log( a ); } \n"); + writer.write(" }); \n"); + writer.write("} \n"); + + parseGCC(writer.toString()); + parseGPP(writer.toString()); } - + public void testBug74190_g_return_if_fail() throws Exception { Writer writer = new StringWriter(); - writer.write( "void f() { \n"); //$NON-NLS-1$ - writer.write( " (void)({ if( ( ({ 0; }) ) ) \n"); //$NON-NLS-1$ - writer.write( " { } \n"); //$NON-NLS-1$ - writer.write( " }); \n"); //$NON-NLS-1$ - writer.write( "} \n"); //$NON-NLS-1$ - - parseGCC( writer.toString() ); - parseGPP( writer.toString() ); + writer.write("void f() { \n"); + writer.write(" (void)({ if( ( ({ 0; }) ) ) \n"); + writer.write(" { } \n"); + writer.write(" }); \n"); + writer.write("} \n"); + + parseGCC(writer.toString()); + parseGPP(writer.toString()); } - + public void testBug95635() throws Exception{ StringWriter writer = new StringWriter(); - writer.write("void f(){ \n");//$NON-NLS-1$ - writer.write(" char a[10]; \n"); //$NON-NLS-1$ - writer.write(" __builtin_va_list b; \n"); //$NON-NLS-1$ - writer.write(" __builtin_abort(); \n");//$NON-NLS-1$ - writer.write(" __builtin_exit(1); \n");//$NON-NLS-1$ - writer.write(" __builtin__Exit(1); \n");//$NON-NLS-1$ - writer.write(" __builtin__exit(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_conj(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_conjf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_conjl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_creal(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_crealf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_creall(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_cimag(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_cimagf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_cimagl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_imaxabs(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_llabs(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_vscanf(\"\",b);\n");//$NON-NLS-1$ - writer.write(" __builtin_vsnprintf(a, 1, \"\", b); \n");//$NON-NLS-1$ - writer.write(" __builtin_vsscanf(\"\", \"\", b);\n");//$NON-NLS-1$ - writer.write(" __builtin_cosf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_cosl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_expf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_expl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_fabsf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_fabsl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_logf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_logl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_sinf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_sinl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_sqrtf(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_sqrtl(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_abs(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_cos(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_exp(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_fabs(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_fprintf((void*)0, \"\");\n");//$NON-NLS-1$ - writer.write(" __builtin_fputs(\"\", (void*)0);\n");//$NON-NLS-1$ - writer.write(" __builtin_labs(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_log(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_memcmp((void*)0, (void*)0, 1);\n");//$NON-NLS-1$ - writer.write(" __builtin_memcpy((void*)0,(void*)0, 1);\n");//$NON-NLS-1$ - writer.write(" __builtin_memset((void*)0, 1, 1);\n");//$NON-NLS-1$ - writer.write(" __builtin_printf(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_putchar(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_puts(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_scanf(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_sin(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_snprintf(a, 1, \"\");\n");//$NON-NLS-1$ - writer.write(" __builtin_sprintf(a, \"\");\n");//$NON-NLS-1$ - writer.write(" __builtin_sqrt(1); \n");//$NON-NLS-1$ - writer.write(" __builtin_sscanf(\"\", \"\"); \n");//$NON-NLS-1$1 - writer.write(" __builtin_strcat(a, \"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_strchr(\"\", 1); \n");//$NON-NLS-1$ - writer.write(" __builtin_strcmp(\"\", \"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_strcpy(a, \"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_strcspn(\"\", \"\");\n");//$NON-NLS-1$ - writer.write(" __builtin_strlen(\"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_strncat(a, \"\", 1);\n");//$NON-NLS-1$ - writer.write(" __builtin_strncmp(\"\", \"\", 1);\n");//$NON-NLS-1$ - writer.write(" __builtin_strncpy(a, \"\", 1);\n");//$NON-NLS-1$ - writer.write(" __builtin_strpbrk(\"\", \"\");\n");//$NON-NLS-1$ - writer.write(" __builtin_strrchr(\"\", 1); \n");//$NON-NLS-1$ - writer.write(" __builtin_strspn(\"\", \"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_strstr(\"\", \"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_strstr(\"\", \"\"); \n");//$NON-NLS-1$ - writer.write(" __builtin_vprintf(a, b);\n");//$NON-NLS-1$ - writer.write(" __builtin_vsprintf(a, \"\", b); \n");//$NON-NLS-1$ - writer.write(" __builtin_isgreater(1.0,1.0); \n");//$NON-NLS-1$ - writer.write(" __builtin_isgreaterequal(1.0,1.0);\n");//$NON-NLS-1$ - writer.write(" __builtin_isless(1.0,1.0); \n");//$NON-NLS-1$ - writer.write(" __builtin_islessequal(1.0,1.0); \n");//$NON-NLS-1$ - writer.write(" __builtin_islessgreater(1.0,1.0); \n");//$NON-NLS-1$ - writer.write(" __builtin_isunordered(1.0,1.0); \n");//$NON-NLS-1$ - writer.write("} \n"); //$NON-NLS-1$ - + writer.write("void f(){ \n"); + writer.write(" char a[10]; \n"); + writer.write(" __builtin_va_list b; \n"); + writer.write(" __builtin_abort(); \n"); + writer.write(" __builtin_exit(1); \n"); + writer.write(" __builtin__Exit(1); \n"); + writer.write(" __builtin__exit(1); \n"); + writer.write(" __builtin_conj(1); \n"); + writer.write(" __builtin_conjf(1); \n"); + writer.write(" __builtin_conjl(1); \n"); + writer.write(" __builtin_creal(1); \n"); + writer.write(" __builtin_crealf(1); \n"); + writer.write(" __builtin_creall(1); \n"); + writer.write(" __builtin_cimag(1); \n"); + writer.write(" __builtin_cimagf(1); \n"); + writer.write(" __builtin_cimagl(1); \n"); + writer.write(" __builtin_imaxabs(1); \n"); + writer.write(" __builtin_llabs(1); \n"); + writer.write(" __builtin_vscanf(\"\",b);\n"); + writer.write(" __builtin_vsnprintf(a, 1, \"\", b); \n"); + writer.write(" __builtin_vsscanf(\"\", \"\", b);\n"); + writer.write(" __builtin_cosf(1); \n"); + writer.write(" __builtin_cosl(1); \n"); + writer.write(" __builtin_expf(1); \n"); + writer.write(" __builtin_expl(1); \n"); + writer.write(" __builtin_fabsf(1); \n"); + writer.write(" __builtin_fabsl(1); \n"); + writer.write(" __builtin_logf(1); \n"); + writer.write(" __builtin_logl(1); \n"); + writer.write(" __builtin_sinf(1); \n"); + writer.write(" __builtin_sinl(1); \n"); + writer.write(" __builtin_sqrtf(1); \n"); + writer.write(" __builtin_sqrtl(1); \n"); + writer.write(" __builtin_abs(1); \n"); + writer.write(" __builtin_cos(1); \n"); + writer.write(" __builtin_exp(1); \n"); + writer.write(" __builtin_fabs(1); \n"); + writer.write(" __builtin_fprintf((void*)0, \"\");\n"); + writer.write(" __builtin_fputs(\"\", (void*)0);\n"); + writer.write(" __builtin_labs(1); \n"); + writer.write(" __builtin_log(1); \n"); + writer.write(" __builtin_memcmp((void*)0, (void*)0, 1);\n"); + writer.write(" __builtin_memcpy((void*)0,(void*)0, 1);\n"); + writer.write(" __builtin_memset((void*)0, 1, 1);\n"); + writer.write(" __builtin_printf(\"\"); \n"); + writer.write(" __builtin_putchar(1); \n"); + writer.write(" __builtin_puts(\"\"); \n"); + writer.write(" __builtin_scanf(\"\"); \n"); + writer.write(" __builtin_sin(1); \n"); + writer.write(" __builtin_snprintf(a, 1, \"\");\n"); + writer.write(" __builtin_sprintf(a, \"\");\n"); + writer.write(" __builtin_sqrt(1); \n"); + writer.write(" __builtin_sscanf(\"\", \"\"); \n"); + writer.write(" __builtin_strcat(a, \"\"); \n"); + writer.write(" __builtin_strchr(\"\", 1); \n"); + writer.write(" __builtin_strcmp(\"\", \"\"); \n"); + writer.write(" __builtin_strcpy(a, \"\"); \n"); + writer.write(" __builtin_strcspn(\"\", \"\");\n"); + writer.write(" __builtin_strlen(\"\"); \n"); + writer.write(" __builtin_strncat(a, \"\", 1);\n"); + writer.write(" __builtin_strncmp(\"\", \"\", 1);\n"); + writer.write(" __builtin_strncpy(a, \"\", 1);\n"); + writer.write(" __builtin_strpbrk(\"\", \"\");\n"); + writer.write(" __builtin_strrchr(\"\", 1); \n"); + writer.write(" __builtin_strspn(\"\", \"\"); \n"); + writer.write(" __builtin_strstr(\"\", \"\"); \n"); + writer.write(" __builtin_strstr(\"\", \"\"); \n"); + writer.write(" __builtin_vprintf(a, b);\n"); + writer.write(" __builtin_vsprintf(a, \"\", b); \n"); + writer.write(" __builtin_isgreater(1.0,1.0); \n"); + writer.write(" __builtin_isgreaterequal(1.0,1.0);\n"); + writer.write(" __builtin_isless(1.0,1.0); \n"); + writer.write(" __builtin_islessequal(1.0,1.0); \n"); + writer.write(" __builtin_islessgreater(1.0,1.0); \n"); + writer.write(" __builtin_isunordered(1.0,1.0); \n"); + writer.write("} \n"); + final String code = writer.toString(); - parseGCC( code ); - parseGPP( code ); + parseGCC(code); + parseGPP(code); } - + // typedef int size_t; // will be defined in // struct S {int m;}; // void test() { - // int a= __builtin_offsetof(struct S, m); + // int a= __builtin_offsetof(struct S, m); // }; public void test__builtinOffsetof_Bug265001() throws Exception { // gcc with __GNUC__ >= 4 defines: @@ -395,7 +384,7 @@ public class GCCCompleteParseExtensionsTest extends AST2BaseTest { // typedef struct S {int m;} T; // void test() { - // int a= __offsetof__(1); + // int a= __offsetof__(1); // }; public void test__offsetof__Bug265001() throws Exception { // gcc with __GNUC__ < 4 defines: @@ -403,10 +392,9 @@ public class GCCCompleteParseExtensionsTest extends AST2BaseTest { // (__offsetof__ (reinterpret_cast <__size_t> \ // (& reinterpret_cast \ // (static_cast (0)->field)))) - String code= getAboveComment(); - parseGPP(code); + parseGPP(getAboveComment()); } - + // void test(){ // bool b; // b= __has_nothrow_assign (int); @@ -429,4 +417,12 @@ public class GCCCompleteParseExtensionsTest extends AST2BaseTest { public void testTypeTraits_Bug342683() throws Exception { parseGPP(getAboveComment()); } + + // __int128 a; + // unsigned __int128 b; + public void test__int128() throws Exception { + String code= getAboveComment(); + parseGCC(code); + parseGPP(code); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java index a8ef3b40f40..51515f83f85 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCTests.java @@ -40,26 +40,26 @@ public class GCCTests extends AST2BaseTest { public void testGCC20000113() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("struct x { \n"); //$NON-NLS-1$ - buffer.append(" unsigned x1:1; \n"); //$NON-NLS-1$ - buffer.append(" unsigned x2:2; \n"); //$NON-NLS-1$ - buffer.append(" unsigned x3:3; \n"); //$NON-NLS-1$ - buffer.append("}; \n"); //$NON-NLS-1$ - buffer.append("foobar(int x, int y, int z) { \n"); //$NON-NLS-1$ - buffer.append(" struct x a = {x, y, z}; \n"); //$NON-NLS-1$ - buffer.append(" struct x b = {x, y, z}; \n"); //$NON-NLS-1$ - buffer.append(" struct x *c = &b; \n"); //$NON-NLS-1$ - buffer.append(" c->x3 += (a.x2 - a.x1) * c->x2; \n"); //$NON-NLS-1$ - buffer.append(" if (a.x1 != 1 || c->x3 != 5) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("struct x { \n"); + buffer.append(" unsigned x1:1; \n"); + buffer.append(" unsigned x2:2; \n"); + buffer.append(" unsigned x3:3; \n"); + buffer.append("}; \n"); + buffer.append("foobar(int x, int y, int z) { \n"); + buffer.append(" struct x a = {x, y, z}; \n"); + buffer.append(" struct x b = {x, y, z}; \n"); + buffer.append(" struct x *c = &b; \n"); + buffer.append(" c->x3 += (a.x2 - a.x1) * c->x2; \n"); + buffer.append(" if (a.x1 != 1 || c->x3 != 5) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); - + CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 33); ICompositeType x = (ICompositeType) collector.getName(0).resolveBinding(); IField x1 = (IField) collector.getName(1).resolveBinding(); @@ -71,7 +71,7 @@ public class GCCTests extends AST2BaseTest { IVariable a = (IVariable) collector.getName(9).resolveBinding(); IVariable b = (IVariable) collector.getName(14).resolveBinding(); IVariable c = (IVariable) collector.getName(19).resolveBinding(); - + assertInstances(collector, x, 4); assertInstances(collector, x1, 3); assertInstances(collector, x2, 3); @@ -83,181 +83,181 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, b, 2); assertInstances(collector, c, 4); } - + public void testGCC20000205() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("static int f(int a) { \n"); //$NON-NLS-1$ - buffer.append(" if (a == 0) \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append(" do \n"); //$NON-NLS-1$ - buffer.append(" if (a & 128) \n"); //$NON-NLS-1$ - buffer.append(" return 1; \n"); //$NON-NLS-1$ - buffer.append(" while (f(0)); \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("static int f(int a) { \n"); + buffer.append(" if (a == 0) \n"); + buffer.append(" return 0; \n"); + buffer.append(" do \n"); + buffer.append(" if (a & 128) \n"); + buffer.append(" return 1; \n"); + buffer.append(" while (f(0)); \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); - + CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 5); IFunction f = (IFunction) collector.getName(0).resolveBinding(); IVariable a = (IVariable) collector.getName(1).resolveBinding(); - + assertInstances(collector, f, 2); assertInstances(collector, a, 3); } - + public void testGCC20000217() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("unsigned short int showbug(unsigned short int * a, \n"); //$NON-NLS-1$ - buffer.append(" unsigned short int * b) { \n"); //$NON-NLS-1$ - buffer.append(" *a += *b - 8; \n"); //$NON-NLS-1$ - buffer.append(" return (*a >= 8); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" unsigned short int x = 0; \n"); //$NON-NLS-1$ - buffer.append(" unsigned short int y = 10; \n"); //$NON-NLS-1$ - buffer.append(" if (showbug(&x, &y) != 0) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("unsigned short int showbug(unsigned short int * a, \n"); + buffer.append(" unsigned short int * b) { \n"); + buffer.append(" *a += *b - 8; \n"); + buffer.append(" return (*a >= 8); \n"); + buffer.append("} \n"); + buffer.append("int main() { \n"); + buffer.append(" unsigned short int x = 0; \n"); + buffer.append(" unsigned short int y = 10; \n"); + buffer.append(" if (showbug(&x, &y) != 0) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 12); - + IFunction showBug = (IFunction) collector.getName(0).resolveBinding(); IVariable a = (IVariable) collector.getName(1).resolveBinding(); IVariable b = (IVariable) collector.getName(2).resolveBinding(); IVariable x = (IVariable) collector.getName(7).resolveBinding(); IVariable y = (IVariable) collector.getName(8).resolveBinding(); - + assertInstances(collector, showBug, 2); assertInstances(collector, a, 3); assertInstances(collector, b, 2); assertInstances(collector, x, 2); assertInstances(collector, y, 2); } - + public void testGCC20000224() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("int loop_1 = 100; \n"); //$NON-NLS-1$ - buffer.append("int loop_2 = 7; \n"); //$NON-NLS-1$ - buffer.append("int flag = 0; \n"); //$NON-NLS-1$ - buffer.append("int test(void) { \n"); //$NON-NLS-1$ - buffer.append(" int i; \n"); //$NON-NLS-1$ - buffer.append(" int counter = 0; \n"); //$NON-NLS-1$ - buffer.append(" while (loop_1 > counter) { \n"); //$NON-NLS-1$ - buffer.append(" if (flag & 1) { \n"); //$NON-NLS-1$ - buffer.append(" for (i = 0; i < loop_2; i++) { \n"); //$NON-NLS-1$ - buffer.append(" counter++; \n"); //$NON-NLS-1$ - buffer.append(" } \n"); //$NON-NLS-1$ - buffer.append(" } \n"); //$NON-NLS-1$ - buffer.append(" flag++; \n"); //$NON-NLS-1$ - buffer.append(" } \n"); //$NON-NLS-1$ - buffer.append(" return 1; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("int loop_1 = 100; \n"); + buffer.append("int loop_2 = 7; \n"); + buffer.append("int flag = 0; \n"); + buffer.append("int test(void) { \n"); + buffer.append(" int i; \n"); + buffer.append(" int counter = 0; \n"); + buffer.append(" while (loop_1 > counter) { \n"); + buffer.append(" if (flag & 1) { \n"); + buffer.append(" for (i = 0; i < loop_2; i++) { \n"); + buffer.append(" counter++; \n"); + buffer.append(" } \n"); + buffer.append(" } \n"); + buffer.append(" flag++; \n"); + buffer.append(" } \n"); + buffer.append(" return 1; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 16); IVariable loop1 = (IVariable) collector.getName(0).resolveBinding(); IVariable loop2 = (IVariable) collector.getName(1).resolveBinding(); IVariable flag = (IVariable) collector.getName(2).resolveBinding(); IVariable i = (IVariable) collector.getName(5).resolveBinding(); IVariable counter = (IVariable) collector.getName(6).resolveBinding(); - + assertInstances(collector, loop1, 2); assertInstances(collector, loop2, 2); assertInstances(collector, flag, 3); assertInstances(collector, i, 4); assertInstances(collector, counter, 3); } - + public void testGCC20000225() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" int nResult, b = 0, i = -1; \n"); //$NON-NLS-1$ - buffer.append(" do { \n"); //$NON-NLS-1$ - buffer.append(" if (b != 0) { \n"); //$NON-NLS-1$ - buffer.append(" nResult = 1; \n"); //$NON-NLS-1$ - buffer.append(" } else { \n"); //$NON-NLS-1$ - buffer.append(" nResult = 0; \n"); //$NON-NLS-1$ - buffer.append(" } \n"); //$NON-NLS-1$ - buffer.append(" i++; \n"); //$NON-NLS-1$ - buffer.append(" b = (i + 2) * 4; \n"); //$NON-NLS-1$ - buffer.append(" } while (i < 0); \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ + buffer.append("int main() { \n"); + buffer.append(" int nResult, b = 0, i = -1; \n"); + buffer.append(" do { \n"); + buffer.append(" if (b != 0) { \n"); + buffer.append(" nResult = 1; \n"); + buffer.append(" } else { \n"); + buffer.append(" nResult = 0; \n"); + buffer.append(" } \n"); + buffer.append(" i++; \n"); + buffer.append(" b = (i + 2) * 4; \n"); + buffer.append(" } while (i < 0); \n"); + buffer.append(" return -1; \n"); + buffer.append("} \n"); IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 11); IVariable nResult = (IVariable) collector.getName(1).resolveBinding(); IVariable b = (IVariable) collector.getName(2).resolveBinding(); IVariable i = (IVariable) collector.getName(3).resolveBinding(); - + assertInstances(collector, nResult, 3); assertInstances(collector, b, 3); assertInstances(collector, i, 4); } - + public void testGCC20000227() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("static const unsigned char f[] = \"\\0\\377\"; \n"); //$NON-NLS-1$ - buffer.append("static const unsigned char g[] = \"\\0y\"; \n"); //$NON-NLS-1$ - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" if (sizeof f != 3 || sizeof g != 3) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" if (f[0] != g[0]) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" if (f[1] != g[1] || f[2] != g[2]) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("static const unsigned char f[] = \"\\0\\377\"; \n"); + buffer.append("static const unsigned char g[] = \"\\0y\"; \n"); + buffer.append("int main() { \n"); + buffer.append(" if (sizeof f != 3 || sizeof g != 3) \n"); + buffer.append(" return -1; \n"); + buffer.append(" if (f[0] != g[0]) \n"); + buffer.append(" return -1; \n"); + buffer.append(" if (f[1] != g[1] || f[2] != g[2]) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 11); IVariable f = (IVariable) collector.getName(0).resolveBinding(); IVariable g = (IVariable) collector.getName(1).resolveBinding(); - + assertInstances(collector, f, 5); assertInstances(collector, g, 5); } - + public void testGCC20000313() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("unsigned int buggy(unsigned int *param) { \n"); //$NON-NLS-1$ - buffer.append(" unsigned int accu, zero = 0, borrow; \n"); //$NON-NLS-1$ - buffer.append(" accu = - *param; \n"); //$NON-NLS-1$ - buffer.append(" borrow = - (accu > zero); \n"); //$NON-NLS-1$ - buffer.append(" return borrow; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main(void) { \n"); //$NON-NLS-1$ - buffer.append(" unsigned int param = 1; \n"); //$NON-NLS-1$ - buffer.append(" unsigned int borrow = buggy (¶m); \n"); //$NON-NLS-1$ - buffer.append(" if (param != 0) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" if (borrow +1 != 0) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("unsigned int buggy(unsigned int *param) { \n"); + buffer.append(" unsigned int accu, zero = 0, borrow; \n"); + buffer.append(" accu = - *param; \n"); + buffer.append(" borrow = - (accu > zero); \n"); + buffer.append(" return borrow; \n"); + buffer.append("} \n"); + buffer.append("int main(void) { \n"); + buffer.append(" unsigned int param = 1; \n"); + buffer.append(" unsigned int borrow = buggy (¶m); \n"); + buffer.append(" if (param != 0) \n"); + buffer.append(" return -1; \n"); + buffer.append(" if (borrow +1 != 0) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 19); IFunction buggy = (IFunction) collector.getName(0).resolveBinding(); IParameter param = (IParameter) collector.getName(1).resolveBinding(); @@ -266,7 +266,7 @@ public class GCCTests extends AST2BaseTest { IVariable borrow = (IVariable) collector.getName(4).resolveBinding(); IVariable param2 = (IVariable) collector.getName(13).resolveBinding(); IVariable borrow2 = (IVariable) collector.getName(14).resolveBinding(); - + assertInstances(collector, buggy, 2); assertInstances(collector, param, 2); assertInstances(collector, accu, 3); @@ -275,50 +275,50 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, param2, 3); assertInstances(collector, borrow2, 2); } - + public void testGCC20000314_1() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" long winds = 0; \n"); //$NON-NLS-1$ - buffer.append(" while (winds != 0) { \n"); //$NON-NLS-1$ - buffer.append(" if (*(char*)winds) \n"); //$NON-NLS-1$ - buffer.append(" break; \n"); //$NON-NLS-1$ - buffer.append(" } \n"); //$NON-NLS-1$ - buffer.append(" if (winds == 0 || winds != 0 || *(char*) winds) \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("int main() { \n"); + buffer.append(" long winds = 0; \n"); + buffer.append(" while (winds != 0) { \n"); + buffer.append(" if (*(char*)winds) \n"); + buffer.append(" break; \n"); + buffer.append(" } \n"); + buffer.append(" if (winds == 0 || winds != 0 || *(char*) winds) \n"); + buffer.append(" return 0; \n"); + buffer.append(" return -1; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 7); IVariable winds = (IVariable) collector.getName(1).resolveBinding(); assertInstances(collector, winds, 6); } - + public void testGCC20000314_2() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("typedef unsigned long long uint64; \n"); //$NON-NLS-1$ - buffer.append("const uint64 bigconst = 1ULL << 34; \n"); //$NON-NLS-1$ - buffer.append("int a = 1; \n"); //$NON-NLS-1$ - buffer.append("static uint64 getmask(void) { \n"); //$NON-NLS-1$ - buffer.append(" if (a) return bigconst; \n"); //$NON-NLS-1$ - buffer.append(" else return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("main() { \n"); //$NON-NLS-1$ - buffer.append(" uint64 f = getmask(); \n"); //$NON-NLS-1$ - buffer.append(" if (sizeof (long long) == 8 && f != bigconst) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("typedef unsigned long long uint64; \n"); + buffer.append("const uint64 bigconst = 1ULL << 34; \n"); + buffer.append("int a = 1; \n"); + buffer.append("static uint64 getmask(void) { \n"); + buffer.append(" if (a) return bigconst; \n"); + buffer.append(" else return 0; \n"); + buffer.append("} \n"); + buffer.append("main() { \n"); + buffer.append(" uint64 f = getmask(); \n"); + buffer.append(" if (sizeof (long long) == 8 && f != bigconst) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 15); ITypedef uint64 = (ITypedef) collector.getName(0).resolveBinding(); IVariable bigconst = (IVariable) collector.getName(2).resolveBinding(); @@ -332,31 +332,31 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, getmask, 2); assertInstances(collector, f, 2); } - + public void testGCC20000403() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("extern unsigned long aa[], bb[]; \n"); //$NON-NLS-1$ - buffer.append("int seqgt(unsigned long a, unsigned short win, unsigned long b); \n"); //$NON-NLS-1$ - buffer.append("int seqgt2 (unsigned long a, unsigned short win, unsigned long b); \n"); //$NON-NLS-1$ - buffer.append("main() { \n"); //$NON-NLS-1$ - buffer.append(" if (!seqgt(*aa, 0x1000, *bb) || !seqgt2(*aa, 0x1000, *bb)) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int seqgt(unsigned long a, unsigned short win, unsigned long b) { \n"); //$NON-NLS-1$ - buffer.append(" return (long) ((a + win) - b) > 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int seqgt2(unsigned long a, unsigned short win, unsigned long b) { \n"); //$NON-NLS-1$ - buffer.append(" long l = ((a + win) - b); \n"); //$NON-NLS-1$ - buffer.append(" return 1 > 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("unsigned long aa[] = { (1UL << (sizeof(long) *8 - 1)) = 0xfff }; \n"); //$NON-NLS-1$ - buffer.append("unsigned long bb[] = { (1UL << (sizeof(long) *8 - 1)) = 0xfff }; \n"); //$NON-NLS-1$ - + buffer.append("extern unsigned long aa[], bb[]; \n"); + buffer.append("int seqgt(unsigned long a, unsigned short win, unsigned long b); \n"); + buffer.append("int seqgt2 (unsigned long a, unsigned short win, unsigned long b); \n"); + buffer.append("main() { \n"); + buffer.append(" if (!seqgt(*aa, 0x1000, *bb) || !seqgt2(*aa, 0x1000, *bb)) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + buffer.append("int seqgt(unsigned long a, unsigned short win, unsigned long b) { \n"); + buffer.append(" return (long) ((a + win) - b) > 0; \n"); + buffer.append("} \n"); + buffer.append("int seqgt2(unsigned long a, unsigned short win, unsigned long b) { \n"); + buffer.append(" long l = ((a + win) - b); \n"); + buffer.append(" return 1 > 0; \n"); + buffer.append("} \n"); + buffer.append("unsigned long aa[] = { (1UL << (sizeof(long) *8 - 1)) = 0xfff }; \n"); + buffer.append("unsigned long bb[] = { (1UL << (sizeof(long) *8 - 1)) = 0xfff }; \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 34); IVariable aa = (IVariable) collector.getName(0).resolveBinding(); IVariable bb = (IVariable) collector.getName(1).resolveBinding(); @@ -368,7 +368,7 @@ public class GCCTests extends AST2BaseTest { IParameter a2 = (IParameter) collector.getName(7).resolveBinding(); IParameter win2 = (IParameter) collector.getName(8).resolveBinding(); IParameter b2 = (IParameter) collector.getName(9).resolveBinding(); - + assertInstances(collector, aa, 4); assertInstances(collector, bb, 4); assertInstances(collector, seqgt, 3); @@ -380,94 +380,94 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, win2, 3); assertInstances(collector, b2, 3); } - + public void testGCC20000412_1 () throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("short int i = -1; \n"); //$NON-NLS-1$ - buffer.append("const char * const wordlist[207]; \n"); //$NON-NLS-1$ - buffer.append("const char * const * foo(void) { \n"); //$NON-NLS-1$ - buffer.append(" register const char * const *wordptr = &wordlist[207u + i]; \n"); //$NON-NLS-1$ - buffer.append(" return wordptr; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" if (foo() != &wordlist[206]) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("short int i = -1; \n"); + buffer.append("const char * const wordlist[207]; \n"); + buffer.append("const char * const * foo(void) { \n"); + buffer.append(" register const char * const *wordptr = &wordlist[207u + i]; \n"); + buffer.append(" return wordptr; \n"); + buffer.append("} \n"); + buffer.append("int main() { \n"); + buffer.append(" if (foo() != &wordlist[206]) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 11); IVariable i = (IVariable) collector.getName(0).resolveBinding(); IVariable wordlist = (IVariable) collector.getName(1).resolveBinding(); IFunction foo = (IFunction) collector.getName(2).resolveBinding(); IVariable wordptr = (IVariable) collector.getName(4).resolveBinding(); - + assertInstances(collector, i, 2); assertInstances(collector, wordlist, 3); assertInstances(collector, foo, 2); assertInstances(collector, wordptr, 2); } - + public void testGCC20000412_2() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("int f(int a, int *y) { \n"); //$NON-NLS-1$ - buffer.append(" int x = a; \n"); //$NON-NLS-1$ - buffer.append(" if (a == 0) return *y; \n"); //$NON-NLS-1$ - buffer.append(" return f(a-1, &x); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main(int argc, char** argv) { \n"); //$NON-NLS-1$ - buffer.append(" if (f(100, (int *) 0) != 1) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("int f(int a, int *y) { \n"); + buffer.append(" int x = a; \n"); + buffer.append(" if (a == 0) return *y; \n"); + buffer.append(" return f(a-1, &x); \n"); + buffer.append("} \n"); + buffer.append("int main(int argc, char** argv) { \n"); + buffer.append(" if (f(100, (int *) 0) != 1) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 14); IFunction f = (IFunction) collector.getName(0).resolveBinding(); IParameter a = (IParameter) collector.getName(1).resolveBinding(); IParameter y = (IParameter) collector.getName(2).resolveBinding(); IVariable x = (IVariable) collector.getName(3).resolveBinding(); - + assertInstances(collector, f, 3); assertInstances(collector, a, 4); assertInstances(collector, y, 2); assertInstances(collector, x, 2); } - + public void testGCC20000412_3() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("typedef struct { \n"); //$NON-NLS-1$ - buffer.append(" char y; \n"); //$NON-NLS-1$ - buffer.append(" char x[32]; \n"); //$NON-NLS-1$ - buffer.append("} X; \n"); //$NON-NLS-1$ - buffer.append("int z(void) { \n"); //$NON-NLS-1$ - buffer.append(" X xxx; \n"); //$NON-NLS-1$ - buffer.append(" xxx.x[0] = xxx.x[31] = '0'; \n"); //$NON-NLS-1$ - buffer.append(" xxx.y = 0xf; \n"); //$NON-NLS-1$ - buffer.append(" return f(xxx, xxx); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main (void) { \n"); //$NON-NLS-1$ - buffer.append(" int val; \n"); //$NON-NLS-1$ - buffer.append(" val = z(); \n"); //$NON-NLS-1$ - buffer.append(" if (val != 0x60) return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int f(X x, X y) { \n"); //$NON-NLS-1$ - buffer.append(" if (x.y != y.y) \n"); //$NON-NLS-1$ - buffer.append(" return 'F'; \n"); //$NON-NLS-1$ - buffer.append(" return x.x[0] + y.x[0]; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("typedef struct { \n"); + buffer.append(" char y; \n"); + buffer.append(" char x[32]; \n"); + buffer.append("} X; \n"); + buffer.append("int z(void) { \n"); + buffer.append(" X xxx; \n"); + buffer.append(" xxx.x[0] = xxx.x[31] = '0'; \n"); + buffer.append(" xxx.y = 0xf; \n"); + buffer.append(" return f(xxx, xxx); \n"); + buffer.append("} \n"); + buffer.append("int main (void) { \n"); + buffer.append(" int val; \n"); + buffer.append(" val = z(); \n"); + buffer.append(" if (val != 0x60) return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + buffer.append("int f(X x, X y) { \n"); + buffer.append(" if (x.y != y.y) \n"); + buffer.append(" return 'F'; \n"); + buffer.append(" return x.x[0] + y.x[0]; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 36); IField y = (IField) collector.getName(1).resolveBinding(); IField x = (IField) collector.getName(2).resolveBinding(); @@ -477,7 +477,7 @@ public class GCCTests extends AST2BaseTest { IVariable val = (IVariable) collector.getName(19).resolveBinding(); IParameter px = (IParameter) collector.getName(25).resolveBinding(); IParameter py = (IParameter) collector.getName(27).resolveBinding(); - + assertInstances(collector, y, 4); assertInstances(collector, x, 5); assertInstances(collector, X, 4); @@ -487,32 +487,32 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, px, 3); assertInstances(collector, py, 3); } - + public void testGCC20000412_4() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("void f(int i, int j, int radius, int width, int N) { \n"); //$NON-NLS-1$ - buffer.append(" const int diff = i - radius; \n"); //$NON-NLS-1$ - buffer.append(" const int lowk = (diff > 0 ? diff : 0); \n"); //$NON-NLS-1$ - buffer.append(" int k; \n"); //$NON-NLS-1$ - buffer.append(" for (k = lowk; k <= 2; k++) { \n"); //$NON-NLS-1$ - buffer.append(" int idx = ((k-i+radius) * width - j + radius); \n"); //$NON-NLS-1$ - buffer.append(" if (idx < 0) return -1; \n"); //$NON-NLS-1$ - buffer.append(" } \n"); //$NON-NLS-1$ - buffer.append(" for (k = lowk; k <= 2; k++) ; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main (int argc, char** argv) { \n"); //$NON-NLS-1$ - buffer.append(" int exc_rad = 2; \n"); //$NON-NLS-1$ - buffer.append(" int N = 8; \n"); //$NON-NLS-1$ - buffer.append(" int i; \n"); //$NON-NLS-1$ - buffer.append(" for (i = 1; i < 4; i++) \n"); //$NON-NLS-1$ - buffer.append(" f(i, 1, exc_rad, 2*exc_rad + 1, N); \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("void f(int i, int j, int radius, int width, int N) { \n"); + buffer.append(" const int diff = i - radius; \n"); + buffer.append(" const int lowk = (diff > 0 ? diff : 0); \n"); + buffer.append(" int k; \n"); + buffer.append(" for (k = lowk; k <= 2; k++) { \n"); + buffer.append(" int idx = ((k-i+radius) * width - j + radius); \n"); + buffer.append(" if (idx < 0) return -1; \n"); + buffer.append(" } \n"); + buffer.append(" for (k = lowk; k <= 2; k++) ; \n"); + buffer.append("} \n"); + buffer.append("int main (int argc, char** argv) { \n"); + buffer.append(" int exc_rad = 2; \n"); + buffer.append(" int N = 8; \n"); + buffer.append(" int i; \n"); + buffer.append(" for (i = 1; i < 4; i++) \n"); + buffer.append(" f(i, 1, exc_rad, 2*exc_rad + 1, N); \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 43); IFunction f = (IFunction) collector.getName(0).resolveBinding(); IParameter i1 = (IParameter) collector.getName(1).resolveBinding(); @@ -542,52 +542,52 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, N2, 2); assertInstances(collector, i2, 5); } - + public void testGCC20000412_5() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("int main(void) { \n"); //$NON-NLS-1$ - buffer.append(" struct { \n"); //$NON-NLS-1$ - buffer.append(" int node; \n"); //$NON-NLS-1$ - buffer.append(" int type; \n"); //$NON-NLS-1$ - buffer.append(" } lastglob[1] = { { 0, 1 } }; \n"); //$NON-NLS-1$ - buffer.append(" if (lastglob[0].node != 0 || lastglob[0].type != 1) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("int main(void) { \n"); + buffer.append(" struct { \n"); + buffer.append(" int node; \n"); + buffer.append(" int type; \n"); + buffer.append(" } lastglob[1] = { { 0, 1 } }; \n"); + buffer.append(" if (lastglob[0].node != 0 || lastglob[0].type != 1) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 10); IField node = (IField) collector.getName(3).resolveBinding(); IField type = (IField) collector.getName(4).resolveBinding(); IVariable lastglob = (IVariable) collector.getName(5).resolveBinding(); - + assertInstances(collector, node, 2); assertInstances(collector, type, 2); assertInstances(collector, lastglob, 3); } - + public void testGCC20000419() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("struct foo { int a, b, c; }; \n"); //$NON-NLS-1$ - buffer.append("void brother(int a, int b, int c) { \n"); //$NON-NLS-1$ - buffer.append(" if (a) return; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("void sister(struct foo f, int b, int c) { \n"); //$NON-NLS-1$ - buffer.append(" brother((f.b == b), b, c); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" struct foo f = { 7, 8, 9 }; \n"); //$NON-NLS-1$ - buffer.append(" sister(f, 1, 2); \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("struct foo { int a, b, c; }; \n"); + buffer.append("void brother(int a, int b, int c) { \n"); + buffer.append(" if (a) return; \n"); + buffer.append("} \n"); + buffer.append("void sister(struct foo f, int b, int c) { \n"); + buffer.append(" brother((f.b == b), b, c); \n"); + buffer.append("} \n"); + buffer.append("int main() { \n"); + buffer.append(" struct foo f = { 7, 8, 9 }; \n"); + buffer.append(" sister(f, 1, 2); \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 25); ICompositeType foo = (ICompositeType) collector.getName(0).resolveBinding(); IField fa = (IField) collector.getName(1).resolveBinding(); @@ -602,7 +602,7 @@ public class GCCTests extends AST2BaseTest { IParameter sb = (IParameter) collector.getName(12).resolveBinding(); IParameter sc = (IParameter) collector.getName(13).resolveBinding(); IVariable f = (IVariable) collector.getName(22).resolveBinding(); - + assertInstances(collector, foo, 3); assertInstances(collector, fa, 1); assertInstances(collector, fb, 2); @@ -617,61 +617,62 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, sc, 2); assertInstances(collector, f, 2); } + public void testGCC20000503() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("unsigned long sub(int a) { \n"); //$NON-NLS-1$ - buffer.append(" return ((0 > a - 2) ? 0 : a - 2) * sizeof(long); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("main() { \n"); //$NON-NLS-1$ - buffer.append(" return (sub(0) != 0); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("unsigned long sub(int a) { \n"); + buffer.append(" return ((0 > a - 2) ? 0 : a - 2) * sizeof(long); \n"); + buffer.append("} \n"); + buffer.append("main() { \n"); + buffer.append(" return (sub(0) != 0); \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 6); IFunction sub = (IFunction) collector.getName(0).resolveBinding(); IParameter a = (IParameter) collector.getName(1).resolveBinding(); - + assertInstances(collector, sub, 2); assertInstances(collector, a, 3); } - + public void testGCC20000511() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("int f(int value, int expect) { \n"); //$NON-NLS-1$ - buffer.append(" return (value == expect); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("main() { \n"); //$NON-NLS-1$ - buffer.append(" int a = 7, b = 6, c = 4, d = 7, e = 2; \n"); //$NON-NLS-1$ - buffer.append(" f(a || b % c, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(a ? b % c : 0, 2); \n"); //$NON-NLS-1$ - buffer.append(" f(a = b % c, 2); \n"); //$NON-NLS-1$ - buffer.append(" f(a *= b % c, 4); \n"); //$NON-NLS-1$ - buffer.append(" f(a /= b % c, 2); \n"); //$NON-NLS-1$ - buffer.append(" f(a %= b % c, 0); \n"); //$NON-NLS-1$ - buffer.append(" f(a += b % c, 2); \n"); //$NON-NLS-1$ - buffer.append(" f(d || c && e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d ? c && e : 0, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d = c && e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d *= c && e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d %= c && e, 0); \n"); //$NON-NLS-1$ - buffer.append(" f(d += c && e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d -= c && e, 0); \n"); //$NON-NLS-1$ - buffer.append(" f(d || c || e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d ? c || e : 0, 0); \n"); //$NON-NLS-1$ - buffer.append(" f(d = c || e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d *= c || e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d %= c || e, 0); \n"); //$NON-NLS-1$ - buffer.append(" f(d += c || e, 1); \n"); //$NON-NLS-1$ - buffer.append(" f(d -= c || e, 0); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("int f(int value, int expect) { \n"); + buffer.append(" return (value == expect); \n"); + buffer.append("} \n"); + buffer.append("main() { \n"); + buffer.append(" int a = 7, b = 6, c = 4, d = 7, e = 2; \n"); + buffer.append(" f(a || b % c, 1); \n"); + buffer.append(" f(a ? b % c : 0, 2); \n"); + buffer.append(" f(a = b % c, 2); \n"); + buffer.append(" f(a *= b % c, 4); \n"); + buffer.append(" f(a /= b % c, 2); \n"); + buffer.append(" f(a %= b % c, 0); \n"); + buffer.append(" f(a += b % c, 2); \n"); + buffer.append(" f(d || c && e, 1); \n"); + buffer.append(" f(d ? c && e : 0, 1); \n"); + buffer.append(" f(d = c && e, 1); \n"); + buffer.append(" f(d *= c && e, 1); \n"); + buffer.append(" f(d %= c && e, 0); \n"); + buffer.append(" f(d += c && e, 1); \n"); + buffer.append(" f(d -= c && e, 0); \n"); + buffer.append(" f(d || c || e, 1); \n"); + buffer.append(" f(d ? c || e : 0, 0); \n"); + buffer.append(" f(d = c || e, 1); \n"); + buffer.append(" f(d *= c || e, 1); \n"); + buffer.append(" f(d %= c || e, 0); \n"); + buffer.append(" f(d += c || e, 1); \n"); + buffer.append(" f(d -= c || e, 0); \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 95); IFunction f = (IFunction) collector.getName(0).resolveBinding(); IParameter v = (IParameter) collector.getName(1).resolveBinding(); @@ -681,8 +682,8 @@ public class GCCTests extends AST2BaseTest { IVariable c = (IVariable) collector.getName(8).resolveBinding(); IVariable d = (IVariable) collector.getName(9).resolveBinding(); IVariable e = (IVariable) collector.getName(10).resolveBinding(); - - + + assertInstances(collector, f, 22); assertInstances(collector, v, 2); assertInstances(collector, ex, 2); @@ -692,26 +693,27 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, d, 15); assertInstances(collector, e, 15); } + public void testGCC20000603() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("struct s1 { double d; }; \n"); //$NON-NLS-1$ - buffer.append("struct s2 { double d; }; \n"); //$NON-NLS-1$ - buffer.append("double f(struct s1 * a, struct s2 *b) { \n"); //$NON-NLS-1$ - buffer.append(" a->d = 1.0; \n"); //$NON-NLS-1$ - buffer.append(" return b->d + 1.0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" struct s1 a; \n"); //$NON-NLS-1$ - buffer.append(" a.d = 0.0; \n"); //$NON-NLS-1$ - buffer.append(" if (f(&a, (struct s2 *)&a) != 2.0) \n"); //$NON-NLS-1$ - buffer.append(" return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("struct s1 { double d; }; \n"); + buffer.append("struct s2 { double d; }; \n"); + buffer.append("double f(struct s1 * a, struct s2 *b) { \n"); + buffer.append(" a->d = 1.0; \n"); + buffer.append(" return b->d + 1.0; \n"); + buffer.append("} \n"); + buffer.append("int main() { \n"); + buffer.append(" struct s1 a; \n"); + buffer.append(" a.d = 0.0; \n"); + buffer.append(" if (f(&a, (struct s2 *)&a) != 2.0) \n"); + buffer.append(" return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 22); ICompositeType s1 = (ICompositeType) collector.getName(0).resolveBinding(); IField d1 = (IField) collector.getName(1).resolveBinding(); @@ -721,7 +723,7 @@ public class GCCTests extends AST2BaseTest { IParameter pa = (IParameter) collector.getName(6).resolveBinding(); IParameter pb = (IParameter) collector.getName(8).resolveBinding(); IVariable a = (IVariable) collector.getName(15).resolveBinding(); - + assertInstances(collector, s1, 3); assertInstances(collector, s2, 3); assertInstances(collector, d1, 3); @@ -731,25 +733,26 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, pb, 2); assertInstances(collector, a, 4); } + public void testGCC20000605_2() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("struct F { int i; }; \n"); //$NON-NLS-1$ - buffer.append("void f1(struct F *x, struct F * y) { \n"); //$NON-NLS-1$ - buffer.append(" int timeout = 0; \n"); //$NON-NLS-1$ - buffer.append(" for (; ((const struct F*)x)->i < y->i; x->i++) \n"); //$NON-NLS-1$ - buffer.append(" if (++timeout > 5) \n"); //$NON-NLS-1$ - buffer.append(" return; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - buffer.append("main() { \n"); //$NON-NLS-1$ - buffer.append(" struct F x, y; \n"); //$NON-NLS-1$ - buffer.append(" x.i = 0; y.i = 1; \n"); //$NON-NLS-1$ - buffer.append(" f1(&x, &y); \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("struct F { int i; }; \n"); + buffer.append("void f1(struct F *x, struct F * y) { \n"); + buffer.append(" int timeout = 0; \n"); + buffer.append(" for (; ((const struct F*)x)->i < y->i; x->i++) \n"); + buffer.append(" if (++timeout > 5) \n"); + buffer.append(" return; \n"); + buffer.append("} \n"); + buffer.append("main() { \n"); + buffer.append(" struct F x, y; \n"); + buffer.append(" x.i = 0; y.i = 1; \n"); + buffer.append(" f1(&x, &y); \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 27); ICompositeType F = (ICompositeType) collector.getName(0).resolveBinding(); IField i = (IField) collector.getName(1).resolveBinding(); @@ -759,7 +762,7 @@ public class GCCTests extends AST2BaseTest { IVariable timeout = (IVariable) collector.getName(7).resolveBinding(); IVariable x = (IVariable) collector.getName(18).resolveBinding(); IVariable y = (IVariable) collector.getName(19).resolveBinding(); - + assertInstances(collector, F, 5); assertInstances(collector, i, 6); assertInstances(collector, f1, 2); @@ -769,25 +772,26 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, x, 3); assertInstances(collector, y, 3); } + public void testGCC20000605_3() throws Exception{ StringBuilder buffer = new StringBuilder(); - buffer.append("struct F { int x; int y; }; \n"); //$NON-NLS-1$ - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" int timeout = 0, x = 0; \n"); //$NON-NLS-1$ - buffer.append(" while (1) { \n"); //$NON-NLS-1$ - buffer.append(" const struct F i = { x++, }; \n"); //$NON-NLS-1$ - buffer.append(" if (i.x > 0) \n"); //$NON-NLS-1$ - buffer.append(" break; \n"); //$NON-NLS-1$ - buffer.append(" if (++timeout > 5) \n"); //$NON-NLS-1$ - buffer.append(" goto die; \n"); //$NON-NLS-1$ - buffer.append(" } \n"); //$NON-NLS-1$ - buffer.append(" die: return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("struct F { int x; int y; }; \n"); + buffer.append("int main() { \n"); + buffer.append(" int timeout = 0, x = 0; \n"); + buffer.append(" while (1) { \n"); + buffer.append(" const struct F i = { x++, }; \n"); + buffer.append(" if (i.x > 0) \n"); + buffer.append(" break; \n"); + buffer.append(" if (++timeout > 5) \n"); + buffer.append(" goto die; \n"); + buffer.append(" } \n"); + buffer.append(" die: return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 14); ICompositeType F = (ICompositeType) collector.getName(0).resolveBinding(); IField fx = (IField) collector.getName(1).resolveBinding(); @@ -796,7 +800,7 @@ public class GCCTests extends AST2BaseTest { IVariable x = (IVariable) collector.getName(5).resolveBinding(); IVariable i = (IVariable) collector.getName(7).resolveBinding(); ILabel die = (ILabel) collector.getName(13).resolveBinding(); - + assertInstances(collector, F, 2); assertInstances(collector, fx, 2); assertInstances(collector, fy, 1); @@ -805,20 +809,21 @@ public class GCCTests extends AST2BaseTest { assertInstances(collector, i, 2); assertInstances(collector, die, 2); } + public void testGCCenum_2() throws Exception { StringBuilder buffer = new StringBuilder(); - buffer.append("enum foo { FOO, BAR }; \n"); //$NON-NLS-1$ - buffer.append("int main() { \n"); //$NON-NLS-1$ - buffer.append(" int i; \n"); //$NON-NLS-1$ - buffer.append(" for (i = BAR; i >= FOO; --i) \n"); //$NON-NLS-1$ - buffer.append(" if (i == -1) return -1; \n"); //$NON-NLS-1$ - buffer.append(" return 0; \n"); //$NON-NLS-1$ - buffer.append("} \n"); //$NON-NLS-1$ - + buffer.append("enum foo { FOO, BAR }; \n"); + buffer.append("int main() { \n"); + buffer.append(" int i; \n"); + buffer.append(" for (i = BAR; i >= FOO; --i) \n"); + buffer.append(" if (i == -1) return -1; \n"); + buffer.append(" return 0; \n"); + buffer.append("} \n"); + IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); CNameCollector collector = new CNameCollector(); tu.accept(collector); - + assertEquals(collector.size(), 11); IEnumeration foo = (IEnumeration) collector.getName(0).resolveBinding(); IEnumerator FOO = (IEnumerator) collector.getName(1).resolveBinding(); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java index c0ef5db339e..694a90a7186 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/VariableReadWriteFlagsTest.java @@ -159,6 +159,32 @@ public class VariableReadWriteFlagsTest extends AST2BaseTest { a.assertReadWriteFlags("g(&a, b, c)", "c", READ); } + // struct A { + // A(int* x, int& y); + // A(const int* x, const int& y, int z); + // }; + // + // void test(int a, int b, int c) { + // A(&a, b); + // A x(&a, b); + // A(&a, b, c); + // A y(&a, b, c); + // }; + public void testConstructorCall_393068() throws Exception { + AssertionHelper a = getCPPAssertionHelper(); +// a.assertReadWriteFlags("A(&a, b)", "a", READ | WRITE); +// a.assertReadWriteFlags("A(&a, b)", "b", READ | WRITE); +// a.assertReadWriteFlags("x(&a, b)", "a", READ | WRITE); +// a.assertReadWriteFlags("x(&a, b)", "b", READ | WRITE); +// a.assertReadWriteFlags("x(&a, b)", "x", WRITE); + a.assertReadWriteFlags("A(&a, b, c)", "a", READ); + a.assertReadWriteFlags("A(&a, b, c)", "b", READ); + a.assertReadWriteFlags("A(&a, b, c)", "c", READ); + a.assertReadWriteFlags("y(&a, b, c)", "a", READ); + a.assertReadWriteFlags("y(&a, b, c)", "b", READ); + a.assertReadWriteFlags("y(&a, b, c)", "c", READ); + } + // struct A { // void m(); // void mc() const; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/AddDeclarationBug.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/AddDeclarationBugTest.java similarity index 88% rename from core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/AddDeclarationBug.java rename to core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/AddDeclarationBugTest.java index e02fd1869bf..31d6ca8e89e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/AddDeclarationBug.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/AddDeclarationBugTest.java @@ -35,14 +35,14 @@ import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore; /** * @author Emanuel Graf IFS */ -public class AddDeclarationBug extends ChangeGeneratorTest { +public class AddDeclarationBugTest extends ChangeGeneratorTest { - AddDeclarationBug() { + AddDeclarationBugTest() { super("AddDeclarationBug"); } public static Test suite() { - return new AddDeclarationBug(); + return new AddDeclarationBugTest(); } @Override @@ -65,16 +65,16 @@ public class AddDeclarationBug extends ChangeGeneratorTest { ICPPASTCompositeTypeSpecifier classNode = (ICPPASTCompositeTypeSpecifier) declSpec; IASTSimpleDeclaration newDecl = new CPPASTSimpleDeclaration(); - IASTSimpleDeclSpecifier returnTyp = new CPPASTSimpleDeclSpecifier(); - returnTyp.setType(IASTSimpleDeclSpecifier.t_int); - newDecl.setDeclSpecifier(returnTyp); + IASTSimpleDeclSpecifier returnType = new CPPASTSimpleDeclSpecifier(); + returnType.setType(IASTSimpleDeclSpecifier.t_int); + newDecl.setDeclSpecifier(returnType); IASTStandardFunctionDeclarator declarator = new CPPASTFunctionDeclarator( new CPPASTName("exp".toCharArray())); //$NON-NLS-1$ - IASTSimpleDeclSpecifier paramTyp = new CPPASTSimpleDeclSpecifier(); - paramTyp.setType(IASTSimpleDeclSpecifier.t_int); + IASTSimpleDeclSpecifier paramType = new CPPASTSimpleDeclSpecifier(); + paramType.setType(IASTSimpleDeclSpecifier.t_int); IASTDeclarator decl = new CPPASTDeclarator(new CPPASTName("i".toCharArray())); //$NON-NLS-1$ - ICPPASTParameterDeclaration param = new CPPASTParameterDeclaration(paramTyp, decl); + ICPPASTParameterDeclaration param = new CPPASTParameterDeclaration(paramType, decl); declarator.addParameterDeclaration(param); newDecl.addDeclarator(declarator); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/InsertBeforeTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/InsertBeforeTestSuite.java index 4fcc0039c70..f22e76c32e0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/InsertBeforeTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/changegenerator/insertbefore/InsertBeforeTestSuite.java @@ -29,7 +29,7 @@ public class InsertBeforeTestSuite { suite.addTest(ArrayModifierTest.suite()); suite.addTest(ExpressionTest.suite()); suite.addTest(ArraySizeExpressionTest.suite()); - suite.addTest(AddDeclarationBug.suite()); + suite.addTest(AddDeclarationBugTest.suite()); suite.addTest(MultilineWhitespaceHandlingTest.suite()); suite.addTest(SelfInsertionTest.suite()); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java index 8ea33061118..90f083bfcde 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/language/settings/providers/ScannerDiscoveryLegacySupport.java @@ -62,6 +62,22 @@ public class ScannerDiscoveryLegacySupport { } } + /** + * Checks if Language Settings functionality is defined for given project in preferences. + * + * @param project - project to check the preference + * @return {@code true} if functionality is defined + * + * @noreference This method is temporary and not intended to be referenced by clients. + * + * @since 5.5 + */ + public static boolean isLanguageSettingsProvidersFunctionalityDefined(IProject project) { + Preferences pref = getPreferences(project); + String value = pref.get(DISABLE_LSP_PREFERENCE, null); + return value != null; + } + /** * Checks if Language Settings functionality is enabled for given project. * diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java index c2a1aade167..282727ca63b 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsProvidersSerializer.java @@ -1178,7 +1178,6 @@ public class LanguageSettingsProvidersSerializer { } else { providers.add(LanguageSettingsManager.getExtensionProviderCopy(id, true)); } - } ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); } @@ -1193,6 +1192,11 @@ public class LanguageSettingsProvidersSerializer { } } } + + if (!ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityDefined(project)) { + // if not yet defined by user - set preference to tell if this is legacy .cproject (i.e. no LSP storageElement) + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, storageElement != null); + } } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java index b7d37b494cd..6eb4359f1ab 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java @@ -73,6 +73,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; +import org.eclipse.cdt.core.parser.GCCKeywords; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; @@ -625,6 +626,9 @@ public class ASTStringUtil { case IASTSimpleDeclSpecifier.t_int: buffer.append(Keywords.INT).append(' '); break; + case IASTSimpleDeclSpecifier.t_int128: + buffer.append(GCCKeywords.cp__int128).append(' '); + break; case IASTSimpleDeclSpecifier.t_float: buffer.append(Keywords.FLOAT).append(' '); break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java index 4754e8f09e8..8b367ba9017 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java @@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTArrayRangeDesignator; +import org.eclipse.cdt.core.parser.GCCKeywords; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.internal.core.dom.parser.ASTProblem; import org.eclipse.cdt.internal.core.model.ASTStringUtil; @@ -775,6 +776,14 @@ public class ASTSignatureUtil { result.append(Keywords.INT); needSpace = true; break; + case IASTSimpleDeclSpecifier.t_int128: + if (needSpace) { + result.append(SPACE); + needSpace = false; + } + result.append(GCCKeywords.__INT128); + needSpace = true; + break; case IASTSimpleDeclSpecifier.t_void: if (needSpace) { result.append(SPACE); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java index b10654669a4..8562e33e5b4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java @@ -100,6 +100,11 @@ public interface IASTSimpleDeclSpecifier extends IASTDeclSpecifier { */ public static final int t_char32_t = 12; + /** + * __int128 i; + * @since 5.5 + */ + public static final int t_int128 = 13; /** * @since 5.1 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java index cae0573c04a..e13798ce231 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java @@ -22,40 +22,25 @@ public interface IBasicType extends IType { * @since 5.2 */ enum Kind { - eUnspecified, eVoid, eChar, eWChar, eInt, eFloat, eDouble, eBoolean, eChar16, eChar32, - /** @since 5.4 */ eNullPtr + eUnspecified, eVoid, eChar, eWChar, eInt, eFloat, eDouble, + eBoolean, eChar16, eChar32, /** @since 5.4 */ eNullPtr, /** @since 5.5 */ eInt128 } - /** - * @since 5.2 - */ + /** @since 5.2 */ final int IS_LONG = 1; - /** - * @since 5.2 - */ + /** @since 5.2 */ final int IS_SHORT = 1 << 1; - /** - * @since 5.2 - */ + /** @since 5.2 */ final int IS_SIGNED = 1 << 2; - /** - * @since 5.2 - */ + /** @since 5.2 */ final int IS_UNSIGNED = 1 << 3; - /** - * @since 5.2 - */ + /** @since 5.2 */ final int IS_COMPLEX = 1 << 4; - /** - * @since 5.2 - */ + /** @since 5.2 */ final int IS_IMAGINARY = 1 << 5; - /** - * @since 5.2 - */ + /** @since 5.2 */ final int IS_LONG_LONG = 1 << 6; - /** * This returns the kind of basic type you are looking at. The type is * then refined by qualifiers for signed/unsigned and short/long/long long. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java index 388ca388670..522729372ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java @@ -128,7 +128,7 @@ public interface IScope { fLookupPoint= point; fLookupPointIsName= false; fLookupKey= name; - fIgnorePointOfDeclaration= true; + fIgnorePointOfDeclaration= false; if (fLookupPoint == null) { fTu= null; fIgnorePointOfDeclaration= true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionCallExpression.java index 79150a2a080..0f3735ccafd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionCallExpression.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Mike Kucera (IBM) - Initial API and implementation + * Mike Kucera (IBM) - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; @@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; * @noimplement This interface is not intended to be implemented by clients. */ public interface ICPPASTFunctionCallExpression extends IASTFunctionCallExpression, ICPPASTExpression, IASTImplicitNameOwner { - @Override ICPPASTFunctionCallExpression copy(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java index bb22d42ff5a..36b3711d1fc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java @@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.parser.c.ICParserExtensionConfiguration; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScanner; +import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser; @@ -70,6 +71,11 @@ public class GCCLanguage extends AbstractCLikeLanguage { return C_GNU_SCANNER_EXTENSION; } + @Override + protected IScannerExtensionConfiguration getScannerExtensionConfiguration(IScannerInfo info) { + return GCCScannerExtensionConfiguration.getInstance(info); + } + /** * Returns the extension configuration used for creating the parser. * @since 5.1 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/GNUScannerExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/GNUScannerExtensionConfiguration.java index ba8107ec9f3..b6e62c0f8de 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/GNUScannerExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/GNUScannerExtensionConfiguration.java @@ -27,7 +27,14 @@ import org.eclipse.cdt.core.parser.util.CharArrayIntMap; */ public abstract class GNUScannerExtensionConfiguration extends AbstractScannerExtensionConfiguration { private static GNUScannerExtensionConfiguration sInstance; - + + /** + * @noreference This method is not intended to be referenced by clients. + */ + protected static int version(int major, int minor) { + return (major << 16) + minor; + } + @SuppressWarnings("nls") public GNUScannerExtensionConfiguration() { addMacro("__complex__", "_Complex"); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCParserExtensionConfiguration.java index 74ff3989434..14f7e49584a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCParserExtensionConfiguration.java @@ -6,9 +6,9 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Rational Software - Initial API and implementation - * Ed Swartz (Nokia) - * Markus Schorn (Wind River Systems) + * IBM Rational Software - Initial API and implementation + * Ed Swartz (Nokia) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.parser.c; @@ -21,6 +21,7 @@ import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider; */ public class GCCParserExtensionConfiguration extends AbstractCParserExtensionConfiguration { private static GCCParserExtensionConfiguration sInstance= new GCCParserExtensionConfiguration(); + /** * @since 5.1 */ @@ -28,65 +29,41 @@ public class GCCParserExtensionConfiguration extends AbstractCParserExtensionCon return sInstance; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#supportStatementsInExpressions() - */ @Override public boolean supportStatementsInExpressions() { return true; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#supportGCCStyleDesignators() - */ @Override public boolean supportGCCStyleDesignators() { return true; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#supportTypeofUnaryExpressions() - */ @Override public boolean supportTypeofUnaryExpressions() { return true; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#supportAlignOfUnaryExpression() - */ @Override public boolean supportAlignOfUnaryExpression() { return true; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#supportKnRC() - */ @Override public boolean supportKnRC() { return true; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#supportAttributeSpecifiers() - */ @Override public boolean supportAttributeSpecifiers() { return true; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#supportDeclspecSpecifiers() - */ @Override public boolean supportDeclspecSpecifiers() { return true; } - /* - * @see org.eclipse.cdt.core.dom.parser.c.AbstractCParserExtensionConfiguration#getBuiltinSymbolProvider() - */ @Override public IBuiltinBindingsProvider getBuiltinBindingsProvider() { return new GCCBuiltinSymbolProvider(ParserLanguage.C, true); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCScannerExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCScannerExtensionConfiguration.java index 0d6ec995977..fc9a3ac3758 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCScannerExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/GCCScannerExtensionConfiguration.java @@ -1,42 +1,77 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation 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 + * Copyright (c) 2004, 2010 IBM Corporation 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: - * IBM - Initial API and implementation - * Ed Swartz (Nokia) - * Markus Schorn (Wind River Systems) - * Sergey Prigogin (Google) + * Contributors: + * IBM - Initial API and implementation + * Ed Swartz (Nokia) + * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.parser.c; +import java.util.Map; + import org.eclipse.cdt.core.dom.parser.GNUScannerExtensionConfiguration; +import org.eclipse.cdt.core.parser.GCCKeywords; +import org.eclipse.cdt.core.parser.IGCCToken; +import org.eclipse.cdt.core.parser.IScannerInfo; /** * Configures the preprocessor for parsing c-sources as accepted by gcc. */ public class GCCScannerExtensionConfiguration extends GNUScannerExtensionConfiguration { + private static final int VERSION_4_7 = version(4, 7); + private static GCCScannerExtensionConfiguration CONFIG= new GCCScannerExtensionConfiguration(); + private static GCCScannerExtensionConfiguration CONFIG_4_7= new GCCScannerExtensionConfiguration(VERSION_4_7); - private static GCCScannerExtensionConfiguration sInstance= new GCCScannerExtensionConfiguration(); /** * @since 5.1 */ public static GCCScannerExtensionConfiguration getInstance() { - return sInstance; + return CONFIG; + } + + /** + * @since 5.5 + */ + public static GCCScannerExtensionConfiguration getInstance(IScannerInfo info) { + if (info != null) { + try { + final Map definedSymbols = info.getDefinedSymbols(); + int major= Integer.valueOf(definedSymbols.get("__GNUC__")); //$NON-NLS-1$ + int minor= Integer.valueOf(definedSymbols.get("__GNUC_MINOR__")); //$NON-NLS-1$ + int version= version(major, minor); + if (version >= VERSION_4_7) { + return CONFIG_4_7; + } + } catch (Exception e) { + // Fall-back to the default configuration. + } + } + return CONFIG; } - @SuppressWarnings("nls") public GCCScannerExtensionConfiguration() { + this(0); + } + + /** + * @since 5.5 + */ + @SuppressWarnings("nls") + public GCCScannerExtensionConfiguration(int version) { addMacro("__null", "(void *)0"); addMacro("__builtin_offsetof(T,m)", "((size_t) &((T *)0)->m)"); + + if (version >= VERSION_4_7) { + addKeyword(GCCKeywords.cp__int128, IGCCToken.t__int128); + } } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#supportMinAndMaxOperators() - */ @Override public boolean supportMinAndMaxOperators() { return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java index dbeeadf4140..b643cd4652b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java @@ -29,13 +29,11 @@ import org.eclipse.cdt.core.parser.Keywords; public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfiguration { private static final int VERSION_4_3 = version(4, 3); private static final int VERSION_4_6 = version(4, 6); + private static final int VERSION_4_7 = version(4, 7); private static GPPScannerExtensionConfiguration CONFIG= new GPPScannerExtensionConfiguration(); private static GPPScannerExtensionConfiguration CONFIG_4_3= new GPPScannerExtensionConfiguration(VERSION_4_3); private static GPPScannerExtensionConfiguration CONFIG_4_6= new GPPScannerExtensionConfiguration(VERSION_4_6); - - private static int version(int major, int minor) { - return (major << 16) + minor; - } + private static GPPScannerExtensionConfiguration CONFIG_4_7= new GPPScannerExtensionConfiguration(VERSION_4_7); public static GPPScannerExtensionConfiguration getInstance() { return CONFIG; @@ -51,6 +49,9 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu int major= Integer.valueOf(definedSymbols.get("__GNUC__")); //$NON-NLS-1$ int minor= Integer.valueOf(definedSymbols.get("__GNUC_MINOR__")); //$NON-NLS-1$ int version= version(major, minor); + if (version >= VERSION_4_7) { + return CONFIG_4_7; + } if (version >= VERSION_4_6) { return CONFIG_4_6; } @@ -102,11 +103,11 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu addKeyword(GCCKeywords.cp__is_standard_layout, IGCCToken.tTT_is_standard_layout); addKeyword(GCCKeywords.cp__is_trivial, IGCCToken.tTT_is_trivial); } + if (version >= VERSION_4_7) { + addKeyword(GCCKeywords.cp__int128, IGCCToken.t__int128); + } } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#supportMinAndMaxOperators() - */ @Override public boolean supportMinAndMaxOperators() { return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java index 269a05bb526..765f962c5de 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java @@ -23,6 +23,8 @@ public class GCCKeywords { public static final String __ALIGNOF__ = "__alignof__"; public static final String __ATTRIBUTE__ = "__attribute__"; public static final String __DECLSPEC = "__declspec"; + /** @since 5.5 */ + public static final String __INT128 = "__int128"; public static final char[] cpTYPEOF = TYPEOF.toCharArray(), @@ -46,9 +48,7 @@ public class GCCKeywords { cp__TYPEOF= "__typeof".toCharArray(), cp__TYPEOF__= "__typeof__".toCharArray(); - /** - * @since 5.3 - */ + /** @since 5.3 */ public static final char[] cp__has_nothrow_assign= "__has_nothrow_assign".toCharArray(), cp__has_nothrow_copy= "__has_nothrow_copy".toCharArray(), @@ -67,10 +67,9 @@ public class GCCKeywords { cp__is_polymorphic= "__is_polymorphic".toCharArray(), cp__is_union= "__is_union".toCharArray(); - /** - * @since 5.5 - */ + /** @since 5.5 */ public static final char[] + cp__int128= __INT128.toCharArray(), cp__is_literal_type= "__is_literal_type".toCharArray(), cp__is_standard_layout= "__is_standard_layout".toCharArray(), cp__is_trivial= "__is_trivial".toCharArray(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java index 6eb92f22f9c..a1c0f9606c0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java @@ -44,4 +44,6 @@ public interface IGCCToken extends IToken { /** @since 5.5 */ int tTT_is_literal_type= FIRST_RESERVED_IGCCToken + 22; /** @since 5.5 */ int tTT_is_standard_layout= FIRST_RESERVED_IGCCToken + 23; /** @since 5.5 */ int tTT_is_trivial= FIRST_RESERVED_IGCCToken + 24; + + /** @since 5.5 */ int t__int128 = FIRST_RESERVED_IGCCToken + 25; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index d01186b5027..cc8f38428db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -2591,6 +2591,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { case IToken.t_short: case IToken.t_int: case IToken.t_long: + case IGCCToken.t__int128: case IToken.t_float: case IToken.t_double: case IToken.t__Bool: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java index b8d7de011e3..d04bacd3eb6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java @@ -58,10 +58,12 @@ public class SizeofCalculator { public final SizeAndAlignment size_2; public final SizeAndAlignment size_4; public final SizeAndAlignment size_8; + public final SizeAndAlignment size_16; public final SizeAndAlignment sizeof_pointer; public final SizeAndAlignment sizeof_int; public final SizeAndAlignment sizeof_long; public final SizeAndAlignment sizeof_long_long; + public final SizeAndAlignment sizeof_int128; public final SizeAndAlignment sizeof_short; public final SizeAndAlignment sizeof_bool; public final SizeAndAlignment sizeof_wchar_t; @@ -118,10 +120,12 @@ public class SizeofCalculator { size_2 = new SizeAndAlignment(2, Math.min(2, maxAlignment)); size_4 = new SizeAndAlignment(4, Math.min(4, maxAlignment)); size_8 = new SizeAndAlignment(8, Math.min(8, maxAlignment)); + size_16 = new SizeAndAlignment(16, Math.min(16, maxAlignment)); sizeof_pointer = getSize(sizeofMacros, "__SIZEOF_POINTER__", maxAlignment); //$NON-NLS-1$ sizeof_int = getSize(sizeofMacros, "__SIZEOF_INT__", maxAlignment); //$NON-NLS-1$ sizeof_long = getSize(sizeofMacros, "__SIZEOF_LONG__", maxAlignment); //$NON-NLS-1$ sizeof_long_long = getSize(sizeofMacros, "__SIZEOF_LONG_LONG__", maxAlignment); //$NON-NLS-1$ + sizeof_int128 = getSize(sizeofMacros, "__SIZEOF_INT128__", maxAlignment); //$NON-NLS-1$ sizeof_short = getSize(sizeofMacros, "__SIZEOF_SHORT__", maxAlignment); //$NON-NLS-1$ sizeof_bool = getSize(sizeofMacros, "__SIZEOF_BOOL__", maxAlignment); //$NON-NLS-1$ sizeof_wchar_t = getSize(sizeofMacros, "__SIZEOF_WCHAR_T__", maxAlignment); //$NON-NLS-1$ @@ -137,10 +141,12 @@ public class SizeofCalculator { size_2 = new SizeAndAlignment(2, 2); size_4 = new SizeAndAlignment(4, 4); size_8 = new SizeAndAlignment(8, 8); + size_16 = new SizeAndAlignment(16, 16); sizeof_pointer = null; sizeof_int = null; sizeof_long = null; sizeof_long_long = null; + sizeof_int128 = size_16; sizeof_short = null; sizeof_bool = null; sizeof_wchar_t = null; @@ -201,9 +207,10 @@ public class SizeofCalculator { case eInt: return type.isShort() ? sizeof_short : type.isLong() ? sizeof_long : type.isLongLong() ? sizeof_long_long : sizeof_int; - case eFloat: { + case eInt128: + return sizeof_int128; + case eFloat: return type.isComplex() ? sizeof_complex_float : sizeof_float; - } case eDouble: return type.isComplex() ? (type.isLong() ? sizeof_long_double : sizeof_double) : @@ -215,7 +222,7 @@ public class SizeofCalculator { case eChar32: return size_4; case eNullPtr: - return sizeAndAlignmentOfPointer(); + return sizeof_pointer; default: return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java index 881a069faf8..a800794bc05 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/VariableReadWriteFlags.java @@ -28,6 +28,8 @@ import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIfStatement; +import org.eclipse.cdt.core.dom.ast.IASTImplicitName; +import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -41,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -188,12 +191,21 @@ public abstract class VariableReadWriteFlags { final IType type= functionNameExpression.getExpressionType(); if (type instanceof IFunctionType) { return rwArgumentForFunctionCall((IFunctionType) type, i, indirection); + } else { + IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) funcCall).getImplicitNames(); + if (implicitNames.length == 1) { + IASTImplicitName name = implicitNames[0]; + IBinding binding = name.resolveBinding(); + if (binding instanceof IFunction) { + return rwArgumentForFunctionCall(((IFunction) binding).getType(), i, indirection); + } + } } } break; } } - return READ | WRITE; // fallback + return READ | WRITE; // Fallback } protected int rwArgumentForFunctionCall(IFunctionType type, int parameterIdx, int indirection) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTSimpleDeclSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTSimpleDeclSpecifier.java index 7e2b043811f..f2cf88daf27 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTSimpleDeclSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTSimpleDeclSpecifier.java @@ -98,7 +98,7 @@ public class CASTSimpleDeclSpecifier extends CASTBaseDeclSpecifier implements IC } private int getType(Kind kind) { - switch(kind) { + switch (kind) { case eBoolean: return t_bool; case eChar: @@ -112,6 +112,8 @@ public class CASTSimpleDeclSpecifier extends CASTBaseDeclSpecifier implements IC return t_float; case eInt: return t_int; + case eInt128: + return t_int128; case eUnspecified: return t_unspecified; case eVoid: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java index 377d591ab31..3409058e745 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java @@ -71,6 +71,8 @@ public class CBasicType implements ICBasicType, ISerializableType { return Kind.eFloat; case IASTSimpleDeclSpecifier.t_int: return Kind.eInt; + case IASTSimpleDeclSpecifier.t_int128: + return Kind.eInt128; case IASTSimpleDeclSpecifier.t_void: return Kind.eVoid; default: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 613b0bcee29..7aa0db02fd8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -1002,6 +1002,13 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { encounteredRawType= true; endOffset= consume().getEndOffset(); break; + case IGCCToken.t__int128: + if (encounteredTypename) + break declSpecifiers; + simpleType = IASTSimpleDeclSpecifier.t_int128; + encounteredRawType= true; + endOffset= consume().getEndOffset(); + break; case IToken.t_long: if (encounteredTypename) break declSpecifiers; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index c2fb4dcb4b2..827e8d992c7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -276,7 +277,11 @@ public class CPPASTFieldReference extends ASTNode n= ns[ns.length - 1]; } if (n instanceof ICPPASTTemplateId) { - args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); + try { + args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); + } catch (DOMException e) { + return EvalFixed.INCOMPLETE; + } } return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, true, args); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java index b4dbc11f2a5..6402b496a29 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation 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 @@ -313,7 +313,7 @@ public class CPPASTFunctionCallExpression extends ASTNode if (b instanceof IType) { ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length]; for (int i = 0; i < args.length; i++) { - args[i]= ((ICPPASTExpression) fArguments[i]).getEvaluation(); + args[i]= ((ICPPASTInitializerClause) fArguments[i]).getEvaluation(); } return new EvalTypeId((IType) b, args); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleDeclSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleDeclSpecifier.java index 45804b803d4..6c7333ffc2c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleDeclSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleDeclSpecifier.java @@ -92,6 +92,8 @@ public class CPPASTSimpleDeclSpecifier extends CPPASTBaseDeclSpecifier return t_float; case eInt: return t_int; + case eInt128: + return t_int128; case eUnspecified: return t_unspecified; case eVoid: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java index 959973e4038..1d03067fe9e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java @@ -17,7 +17,6 @@ import java.util.List; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; -import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -43,17 +42,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.NameOrTemplateIDVariants.Var */ public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTAmbiguousExpression, ICPPASTExpression { - private BinaryOperator fLastOperator; - private IASTInitializerClause fLastExpression; + private final BinaryOperator fEndOperator; private final BranchPoint fVariants; private IASTNode[] fNodes; private final AbstractGNUSourceCodeParser fParser; - public CPPASTTemplateIDAmbiguity(AbstractGNUSourceCodeParser parser, BinaryOperator lastOperator, IASTInitializerClause expr, - BranchPoint variants) { + public CPPASTTemplateIDAmbiguity(AbstractGNUSourceCodeParser parser, BinaryOperator endOperator, BranchPoint variants) { fParser= parser; - fLastOperator= lastOperator; - fLastExpression= expr; + fEndOperator= endOperator; fVariants= variants; } @@ -92,10 +88,7 @@ public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTA if (selected != null) { minOffset= selected.getRightOffset(); BinaryOperator targetOp = selected.getTargetOperator(); - if (targetOp == null) { - fLastExpression= selected.getExpression(); - fLastOperator= v.getLeftOperator(); - } else { + if (targetOp != null) { targetOp.exchange(selected.getExpression()); targetOp.setNext(v.getLeftOperator()); } @@ -106,7 +99,7 @@ public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTA owner.replace(nodeToReplace, this); // Create the expression and replace it - IASTExpression expr = fParser.buildExpression(fLastOperator, fLastExpression); + IASTExpression expr = fParser.buildExpression(fEndOperator.getNext(), fEndOperator.getExpression()); owner.replace(this, expr); // Resolve further ambiguities within the new expression. @@ -149,8 +142,7 @@ public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTA public IASTNode[] getNodes() { if (fNodes == null) { List nl= new ArrayList(); - nl.add(fLastExpression); - BinaryOperator op= fLastOperator; + BinaryOperator op= fEndOperator; while (op != null) { nl.add(op.getExpression()); op= op.getNext(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java index 56aa33d361f..0dd4aba9b71 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation 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: * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -101,6 +102,8 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { return Kind.eFloat; case IASTSimpleDeclSpecifier.t_int: return Kind.eInt; + case IASTSimpleDeclSpecifier.t_int128: + return Kind.eInt128; case IASTSimpleDeclSpecifier.t_void: return Kind.eVoid; default: @@ -119,16 +122,17 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { if (!(object instanceof ICPPBasicType)) return false; - ICPPBasicType t = (ICPPBasicType) object; - if (fKind != t.getKind()) + ICPPBasicType other = (ICPPBasicType) object; + if (fKind != other.getKind()) return false; int modifiers = getModifiers(); + int otherModifiers = other.getModifiers(); if (fKind == Kind.eInt) { // Signed int and int are equivalent. - return (modifiers & ~IS_SIGNED) == (t.getModifiers() & ~IS_SIGNED); + return (modifiers & ~IS_SIGNED) == (otherModifiers & ~IS_SIGNED); } - return modifiers == t.getModifiers(); + return modifiers == otherModifiers; } @Override @@ -278,7 +282,7 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType { } /** - * @deprecated types don't have values + * @deprecated Types don't have values */ @Override @Deprecated diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java index 8f619a4e91b..b7ad7ff7c0d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeArgument.java @@ -15,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.Assert; /** @@ -25,7 +26,7 @@ public class CPPTemplateTypeArgument implements ICPPTemplateArgument { private final IType fOriginalType; public CPPTemplateTypeArgument(IType type) { - this(type, type); + this(SemanticUtil.getSimplifiedType(type), type); } public CPPTemplateTypeArgument(IType simplifiedType, IType originalType) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 5cc638281ce..a23acd37a51 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -764,6 +764,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { BinaryOperator lastOperator= null; NameOrTemplateIDVariants variants= null; + IToken variantMark= mark(); if (expr == null) { Object e = castExpressionForBinaryExpression(strat); if (e instanceof IASTExpression) { @@ -773,20 +774,21 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { final Variant variant = (Variant) e; expr= variant.getExpression(); - variants.addBranchPoint(variant.getNext(), lastOperator, allowAssignment, conditionCount); + variants.addBranchPoint(variant.getNext(), null, allowAssignment, conditionCount); } } - boolean doneExpression= false; - do { + boolean stopWithNextOperator= false; + castExprLoop: for(;;) { // Typically after a binary operator there cannot be a throw expression boolean allowThrow= false; // Brace initializers are allowed on the right hand side of an expression boolean allowBraceInitializer= false; - BacktrackException tryRecovery= null; - final int operatorOffset= LA().getOffset(); - lt1= LT(1); + boolean doneExpression= false; + BacktrackException failure= null; + final int opOffset= LA().getOffset(); + lt1= stopWithNextOperator ? IToken.tSEMI : LT(1); switch (lt1) { case IToken.tQUESTION: conditionCount++; @@ -879,7 +881,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (LT(2) != IToken.tGT_in_SHIFTR) { IToken token = LA(1); backtrack.initialize(token.getOffset(), token.getLength()); - tryRecovery= backtrack; + failure= backtrack; break; } @@ -907,35 +909,46 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { doneExpression= true; break; } - - if (!doneExpression && tryRecovery == null) { - consume(); // consumes the operator - - // Link variants that are closed by the new operator - if (variants != null) { - variants.closeVariants(operatorOffset, lastOperator); + + // Close variants + if (failure == null) { + if (doneExpression) { + if (variants != null && !variants.hasRightBound(opOffset)) { + // We have a longer variant, ignore this one. + backtrack.initialize(opOffset, 1); + failure= backtrack; + } else { + break castExprLoop; + } + } + // Close variants with matching end + if (variants != null && lastOperator != null) { + variants.closeVariants(opOffset, lastOperator); } + } - // Determine next sub-expression - if (lt1 == IToken.tQUESTION && LT(1) == IToken.tCOLON) { - // Missing sub-expression after '?' (gnu-extension) - expr= null; - } else if (allowThrow && LT(1) == IToken.t_throw) { - // Throw expression - expr= throwExpression(); - lt1= LT(1); - if (lt1 != IToken.tCOLON && lt1 != IToken.tCOMMA) + if (failure == null && !doneExpression) { + // Determine next cast-expression + consume(); // consumes the operator + stopWithNextOperator= false; + try { + if (lt1 == IToken.tQUESTION && LT(1) == IToken.tCOLON) { + // Missing sub-expression after '?' (gnu-extension) + expr= null; + } else if (allowThrow && LT(1) == IToken.t_throw) { + // Throw expression + expr= throwExpression(); + lt1= LT(1); + if (lt1 != IToken.tCOLON && lt1 != IToken.tCOMMA) + stopWithNextOperator= true; break; - } else if (allowBraceInitializer && LT(1) == IToken.tLBRACE) { - // Brace initializer - expr= bracedInitList(true); - lt1= LT(1); - if (lt1 != IToken.tCOLON && lt1 != IToken.tCOMMA) - break; - } else { - // Cast expression - IToken m= mark(); - try { + } else if (allowBraceInitializer && LT(1) == IToken.tLBRACE) { + // Brace initializer + expr= bracedInitList(true); + lt1= LT(1); + if (lt1 != IToken.tCOLON && lt1 != IToken.tCOMMA) + stopWithNextOperator= true; + } else { Object e = castExpressionForBinaryExpression(strat); if (e instanceof IASTExpression) { expr= (IASTExpression) e; @@ -947,55 +960,49 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { variants.addBranchPoint(ae.getNext(), lastOperator, allowAssignment, conditionCount); } - } catch (BacktrackException e) { - if (variants == null) - throw e; - tryRecovery= e; - backup(m); } + continue castExprLoop; + } catch (BacktrackException e) { + failure= e; } - } + } - if (tryRecovery != null || doneExpression) { - if (variants != null) { - if (lt1 == IToken.tEOC) { - variants.discardOpenVariants(operatorOffset); - } else { - // Try fall-back to an open variant - Variant fallback= variants.findFallback(operatorOffset); - if (fallback == null) { - if (tryRecovery != null) - throw tryRecovery; - variants.discardOpenVariants(operatorOffset); - } else { - // Restore state and continue - doneExpression= false; - BranchPoint varPoint= fallback.getOwner(); - allowAssignment= varPoint.isAllowAssignment(); - conditionCount= varPoint.getConditionCount(); - lastOperator= varPoint.getLeftOperator(); - expr= fallback.getExpression(); - variants.useFallback(fallback); + // We need a new variant + Variant variant= variants == null ? null : variants.selectFallback(); + if (variant == null) { + if (failure != null) + throw failure; + throwBacktrack(LA(1)); + } else { + // Restore variant and continue + BranchPoint varPoint= variant.getOwner(); + allowAssignment= varPoint.isAllowAssignment(); + conditionCount= varPoint.getConditionCount(); + lastOperator= varPoint.getLeftOperator(); + expr= variant.getExpression(); - // Advance to the right token - int offset= fallback.getRightOffset(); - while (LA().getOffset() < offset) { - consume(); - } - } - } + backup(variantMark); + int offset= variant.getRightOffset(); + while (LA().getOffset() < offset) { + consume(); } + variantMark= mark(); } - } while (!doneExpression); + } // Check for incomplete conditional expression if (lt1 != IToken.tEOC && conditionCount > 0) throwBacktrack(LA(1)); - - if (variants != null && !variants.isEmpty()) { - CPPASTTemplateIDAmbiguity result = new CPPASTTemplateIDAmbiguity(this, lastOperator, expr, variants.getOrderedBranchPoints()); - setRange(result, startOffset, calculateEndOffset(expr)); - return result; + + if (variants != null) { + BinaryOperator end = new BinaryOperator(lastOperator, expr, -1, 0, 0); + variants.closeVariants(LA(1).getOffset(), end); + variants.removeInvalid(end); + if (!variants.isEmpty()) { + CPPASTTemplateIDAmbiguity result = new CPPASTTemplateIDAmbiguity(this, end, variants.getOrderedBranchPoints()); + setRange(result, startOffset, calculateEndOffset(expr)); + return result; + } } return buildExpression(lastOperator, expr); @@ -1009,7 +1016,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { TemplateIdStrategy strat= new TemplateIdStrategy(); Variant variants= null; - IASTExpression singleExpression= null; + IASTExpression singleResult= null; IASTName[] firstNames= null; final IToken mark= mark(); @@ -1018,12 +1025,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { try { IASTExpression e = castExpression(CastExprCtx.eDirectlyInBExpr, strat); if (variants == null) { - if (singleExpression == null || lastToken == null) { - singleExpression= e; + if (singleResult == null || lastToken == null) { + singleResult= e; firstNames= strat.getTemplateNames(); } else { - variants= new Variant(null, singleExpression, firstNames, lastToken.getOffset()); - singleExpression= null; + variants= new Variant(null, singleResult, firstNames, lastToken.getOffset()); + singleResult= null; firstNames= null; } } @@ -1045,7 +1052,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } backup(mark); } - return variants != null ? variants : singleExpression; + return variants != null ? variants : singleResult; } @Override @@ -2823,6 +2830,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { encounteredRawType= true; endOffset= consume().getEndOffset(); break; + case IGCCToken.t__int128: + if (encounteredTypename) + break declSpecifiers; + simpleType = IASTSimpleDeclSpecifier.t_int128; + encounteredRawType= true; + endOffset= consume().getEndOffset(); + break; case IToken.t_float: if (encounteredTypename) break declSpecifiers; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/NameOrTemplateIDVariants.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/NameOrTemplateIDVariants.java index 6bc530b875d..489d610c054 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/NameOrTemplateIDVariants.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/NameOrTemplateIDVariants.java @@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser.BinaryOperator; /** @@ -132,59 +131,31 @@ public class NameOrTemplateIDVariants { if (v.getTargetOperator() == null) { if (offset == v.getRightOffset()) { v.setTargetOperator(lastOperator); - } else if (offset > v.getRightOffset()) { - // Should not happen - assert false; - remove(v); - } + } } } } } - public void discardOpenVariants(int operatorOffset) { - for (BranchPoint p = fFirst; p != null; p= p.getNext()) { - for (Variant v= p.getFirstVariant(); v != null; v= v.getNext()) { - if (v.getTargetOperator() == null && v.getRightOffset() != operatorOffset) { - remove(v); - } - } - } - } - - public Variant findFallback(int operatorOffset) { + public Variant selectFallback() { // Search for an open variant, with a small right offset and a large left offset - Variant best= null; for (BranchPoint p = fFirst; p != null; p= p.getNext()) { + Variant best= null; for (Variant v= p.getFirstVariant(); v != null; v= v.getNext()) { - if (v.fRightOffset > operatorOffset) { + if (v.getTargetOperator() == null) { if (best == null || v.fRightOffset < best.fRightOffset) { best= v; } } } - } - return best; - } - - public void useFallback(Variant fallback) { - // Discard variants that end within the fallback - int begin= ((ASTNode) fallback.getExpression()).getOffset(); - int end= fallback.getRightOffset(); - for (BranchPoint p = fFirst; p != null; p= p.getNext()) { - for (Variant v= p.getFirstVariant(); v != null; v= v.getNext()) { - if (v == fallback) { - remove(v); - } else { - int vend= v.getRightOffset(); - if (vend > begin && vend < end) - remove(v); - } + if (best != null) { + remove(best); + return best; } } + return null; } - private void remove(Variant remove) { final BranchPoint owner = remove.fOwner; final Variant next = remove.getNext(); @@ -236,4 +207,41 @@ public class NameOrTemplateIDVariants { fFirst= null; return prev; } + + public boolean hasRightBound(int opOffset) { + // Search for an open variant, with a small right offset and a large left offset + for (BranchPoint p = fFirst; p != null; p= p.getNext()) { + for (Variant v= p.getFirstVariant(); v != null; v= v.getNext()) { + if (v.fRightOffset > opOffset) + return false; + } + } + return true; + } + + public void removeInvalid(BinaryOperator lastOperator) { + for (BranchPoint p = fFirst; p != null; p= p.getNext()) { + if (!isReachable(p, lastOperator)) { + remove(p); + } else { + for (Variant v= p.getFirstVariant(); v != null; v= v.getNext()) { + if (v.getTargetOperator() == null) { + remove(v); + } + } + } + } + } + + private boolean isReachable(BranchPoint bp, BinaryOperator endOperator) { + BinaryOperator op = bp.getLeftOperator(); + if (op == null) + return true; + + for(; endOperator != null; endOperator= endOperator.getNext()) { + if (endOperator == op) + return true; + } + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 878ca093ec2..276c7903673 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; @@ -44,12 +45,12 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; -import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; @@ -1201,11 +1202,9 @@ public class CPPTemplates { ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer; IType memberOfClass = ptm.getMemberOfClass(); IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within, point); - if (newMemberOfClass instanceof IQualifierType) { - newMemberOfClass = ((IQualifierType) newMemberOfClass).getType(); - } - if (!(newMemberOfClass instanceof ICPPClassType || newMemberOfClass instanceof UniqueType - || newMemberOfClass instanceof ICPPUnknownBinding)) { + IType classType = SemanticUtil.getNestedType(newMemberOfClass, CVTYPE | TDEF); + if (!(classType instanceof ICPPClassType || classType instanceof UniqueType + || classType instanceof ICPPUnknownBinding)) { return new ProblemType(ISemanticProblem.BINDING_INVALID_TYPE); } if (newNestedType != nestedType || newMemberOfClass != memberOfClass) { @@ -1669,7 +1668,7 @@ public class CPPTemplates { * @return an array of template arguments, currently modeled as IType objects. * The empty ICPPTemplateArgument array is returned if id is {@code null} */ - public static ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) { + public static ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) throws DOMException { ICPPTemplateArgument[] result= ICPPTemplateArgument.EMPTY_ARGUMENTS; if (id != null) { IASTNode[] args= id.getTemplateArguments(); @@ -1681,6 +1680,9 @@ public class CPPTemplates { } else if (arg instanceof ICPPASTExpression) { ICPPASTExpression expr= (ICPPASTExpression) arg; result[i]= new CPPTemplateNonTypeArgument(expr.getEvaluation(), expr); + } else if (arg instanceof ICPPASTAmbiguousTemplateArgument) { + IProblemBinding problem = new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); + throw new DOMException(problem); } else { throw new IllegalArgumentException("Unexpected type: " + arg.getClass().getName()); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index d47fbbb1270..2c3cc53bf77 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -196,7 +196,11 @@ public class EvalID extends CPPEvaluation { ICPPTemplateArgument[] templateArgs = null; final IASTName lastName = name.getLastName(); if (lastName instanceof ICPPASTTemplateId) { - templateArgs= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) lastName); + try { + templateArgs= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) lastName); + } catch (DOMException e) { + return EvalFixed.INCOMPLETE; + } } return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr), name instanceof ICPPASTQualifiedName, templateArgs); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index fd7005e882b..abf0cde7259 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -20,7 +20,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; @@ -116,11 +118,15 @@ public class LookupData extends ScopeLookupData { if (n == null) throw new IllegalArgumentException(); + ICPPTemplateArgument[] args = null; if (n instanceof ICPPASTTemplateId) { - fTemplateArguments= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); - } else { - fTemplateArguments= null; + try { + args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); + } catch (DOMException e) { + CCorePlugin.log(e); + } } + fTemplateArguments= args; configureWith(n); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 6921ea4348d..5431c752d7c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -318,7 +318,7 @@ public class SemanticUtil { /** * Simplifies type by resolving typedefs within the given type. */ - static IType getSimplifiedType(IType type) { + public static IType getSimplifiedType(IType type) { if (type instanceof ICPPFunctionType) { final ICPPFunctionType ft = (ICPPFunctionType) type; IType ret = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 6ba3d1832b4..4813905721f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -73,6 +73,12 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; * Algorithms for deducing template arguments in various contexts. */ public class TemplateArgumentDeduction { + private static class TypeOfValueDeducedFromArraySize extends CPPBasicType { + public TypeOfValueDeducedFromArraySize() { + super(ICPPBasicType.Kind.eInt, 0); + } + } + /** * Deduce arguments for a template function from the template id and the template function * parameters. @@ -194,8 +200,15 @@ public class TemplateArgumentDeduction { IType type1 = ((ICPPTemplateNonTypeParameter) tpar).getType(); type1= CPPTemplates.instantiateType(type1, map, -1, null, point); IType type2= arg.getTypeOfNonTypeValue(); - if (!type1.isSameType(type2)) + // Template-argument deduced from an array bound may be of any integral + // type. + if (type2 instanceof TypeOfValueDeducedFromArraySize && isIntegralType(type1)) { + IValue value = isBooleanType(type1) ? Value.create(true) : arg.getNonTypeValue(); + arg = new CPPTemplateNonTypeArgument(value, type1); + deduct.fDeducedArgs.put(tpar, arg); + } else if (!type1.isSameType(type2)) { return false; + } } } } @@ -206,11 +219,37 @@ public class TemplateArgumentDeduction { return false; } - private static boolean deduceFromFunctionArg(IType par, IType arg, ValueCategory valueCat, TemplateArgumentDeduction deduct, IASTNode point) throws DOMException { + // 3.9.1 - 7 + private static boolean isIntegralType(IType type) { + type = SemanticUtil.getNestedType(type, SemanticUtil.TDEF); + if (!(type instanceof IBasicType)) + return false; + switch (((IBasicType) type).getKind()) { + case eInt: + case eInt128: + case eBoolean: + case eChar: + case eChar16: + case eChar32: + case eWChar: + return true; + default: + return false; + } + } + + private static boolean isBooleanType(IType type) { + type = SemanticUtil.getNestedType(type, SemanticUtil.TDEF); + return type instanceof IBasicType && ((IBasicType) type).getKind() == IBasicType.Kind.eBoolean; + } + + private static boolean deduceFromFunctionArg(IType par, IType arg, ValueCategory valueCat, + TemplateArgumentDeduction deduct, IASTNode point) throws DOMException { boolean isReferenceTypeParameter= false; if (par instanceof ICPPReferenceType) { - // If P is an rvalue reference to a cv-unqualified template parameter and the argument is an - // lvalue, the type "lvalue reference to A" is used in place of A for type deduction. + // If P is an rvalue reference to a cv-unqualified template parameter and the argument + // is an lvalue, the type "lvalue reference to A" is used in place of A for type + // deduction. isReferenceTypeParameter= true; final ICPPReferenceType refPar = (ICPPReferenceType) par; if (refPar.isRValueReference() && refPar.getType() instanceof ICPPTemplateParameter && @@ -615,7 +654,8 @@ public class TemplateArgumentDeduction { private int fPackOffset; private final int fPackSize; - private TemplateArgumentDeduction(ICPPTemplateParameter[] tpars, CPPTemplateParameterMap explicit, CPPTemplateParameterMap result, int packSize) { + private TemplateArgumentDeduction(ICPPTemplateParameter[] tpars, CPPTemplateParameterMap explicit, + CPPTemplateParameterMap result, int packSize) { fExplicitArgs= explicit; fDeducedArgs= result; fPackSize= packSize; @@ -654,7 +694,8 @@ public class TemplateArgumentDeduction { /** * Deduces the template parameter mapping from one pair of template arguments. */ - private boolean fromTemplateArgument(ICPPTemplateArgument p, ICPPTemplateArgument a, IASTNode point) throws DOMException { + private boolean fromTemplateArgument(ICPPTemplateArgument p, ICPPTemplateArgument a, IASTNode point) + throws DOMException { if (p.isNonTypeValue() != a.isNonTypeValue()) return false; @@ -735,7 +776,7 @@ public class TemplateArgumentDeduction { if (parID >= 0) { ICPPTemplateArgument old= fDeducedArgs.getArgument(parID, fPackOffset); if (old == null) { - if (!deduce(parID, new CPPTemplateNonTypeArgument(as, new CPPBasicType(ICPPBasicType.Kind.eInt, 0)))) { + if (!deduce(parID, new CPPTemplateNonTypeArgument(as, new TypeOfValueDeducedFromArraySize()))) { return false; } } else if (!as.equals(old.getNonTypeValue())) { @@ -761,14 +802,16 @@ public class TemplateArgumentDeduction { if (p instanceof IQualifierType) return false; if (remaining != CVQualifier.NONE) { - a= SemanticUtil.addQualifiers(a, remaining.isConst(), remaining.isVolatile(), remaining.isRestrict()); + a= SemanticUtil.addQualifiers(a, remaining.isConst(), remaining.isVolatile(), + remaining.isRestrict()); } } else if (p instanceof ICPPFunctionType) { if (!(a instanceof ICPPFunctionType)) return false; return fromFunctionType((ICPPFunctionType) p, (ICPPFunctionType) a, point); } else if (p instanceof ICPPTemplateParameter) { - ICPPTemplateArgument current= fDeducedArgs.getArgument(((ICPPTemplateParameter) p).getParameterID(), fPackOffset); + ICPPTemplateArgument current= + fDeducedArgs.getArgument(((ICPPTemplateParameter) p).getParameterID(), fPackOffset); if (current != null) { if (current.isNonTypeValue()) return false; @@ -776,7 +819,8 @@ public class TemplateArgumentDeduction { } if (a == null) return false; - return deduce(((ICPPTemplateParameter) p).getParameterID(), new CPPTemplateTypeArgument(a, argumentTypeBeforeTypedefResolution)); + return deduce(((ICPPTemplateParameter) p).getParameterID(), + new CPPTemplateTypeArgument(a, argumentTypeBeforeTypedefResolution)); } else if (p instanceof ICPPTemplateInstance) { if (!(a instanceof ICPPTemplateInstance)) return false; @@ -791,8 +835,8 @@ public class TemplateArgumentDeduction { return false; } - private boolean fromTemplateInstance(ICPPTemplateInstance pInst, ICPPTemplateInstance aInst, IASTNode point) - throws DOMException { + private boolean fromTemplateInstance(ICPPTemplateInstance pInst, ICPPTemplateInstance aInst, + IASTNode point) throws DOMException { ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst); ICPPClassTemplate aTemplate= getPrimaryTemplate(aInst); if (pTemplate == null || aTemplate == null) @@ -853,7 +897,8 @@ public class TemplateArgumentDeduction { return true; } - private boolean fromFunctionType(ICPPFunctionType ftp, ICPPFunctionType fta, IASTNode point) throws DOMException { + private boolean fromFunctionType(ICPPFunctionType ftp, ICPPFunctionType fta, IASTNode point) + throws DOMException { if (ftp.isConst() != fta.isConst() || ftp.isVolatile() != fta.isVolatile()) return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java index e1ddfb49265..df7e77c86cf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java @@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.parser.GCCKeywords; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; @@ -79,6 +80,8 @@ public class DeclSpecWriter extends NodeWriter { return Keywords.CHAR; case IASTSimpleDeclSpecifier.t_int: return Keywords.INT; + case IASTSimpleDeclSpecifier.t_int128: + return GCCKeywords.__INT128; case IASTSimpleDeclSpecifier.t_float: return Keywords.FLOAT; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java index a096be9440b..e89395bbdd5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclaratorWriter.java @@ -89,7 +89,7 @@ public class DeclaratorWriter extends NodeWriter { private void writeFunctionDeclarator(IASTStandardFunctionDeclarator funcDec) { IASTPointerOperator[] pointOps = funcDec.getPointerOperators(); writePointerOperators(funcDec, pointOps); - // XXX: Lambda declarators happen to have null names rather than empty ones when parsed + // Lambda declarators happen to have null names rather than empty ones when parsed. if (funcDec.getName() != null) { funcDec.getName().accept(visitor); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexManager.java index ff7be452df5..b9553056e6e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IWritableIndexManager.java @@ -6,9 +6,8 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.core.index; import org.eclipse.cdt.core.index.IIndexManager; @@ -16,7 +15,6 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.core.runtime.CoreException; public interface IWritableIndexManager extends IIndexManager { - /** * Returns a writable index or null if the project does not exist or is not yet * registered with the pdom manager. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerProgress.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerProgress.java index 2a630de225f..f4ca6367fe3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerProgress.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexerProgress.java @@ -6,18 +6,16 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.core.pdom; public class IndexerProgress { - public int fRequestedFilesCount; public int fCompletedSources; - public int fPrimaryHeaderCount; // headers parsed that were actually requested - public int fCompletedHeaders; // all headers including those found through inclusions - public int fTimeEstimate; // fall-back for the time where no file-count is available + public int fPrimaryHeaderCount; // Headers parsed that were actually requested + public int fCompletedHeaders; // All headers including those found through inclusions + public int fTimeEstimate; // Fall-back for the time where no file-count is available public IndexerProgress() { } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index e7377606f53..30ba6a2ac00 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -226,10 +226,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 134.0 - Storing unknown bindings via direct marshalling, bug 381824. * 135.0 - Changed marshalling of EvalUnary, bug 391001. * 136.0 - Extended CPPTemplateTypeArgument to include the original type, bug 392278. + * 137.0 - Fixed serialization of very large types and template arguments, bug 392278. */ - private static final int MIN_SUPPORTED_VERSION= version(136, 0); - private static final int MAX_SUPPORTED_VERSION= version(136, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(136, 0); + private static final int MIN_SUPPORTED_VERSION= version(137, 0); + private static final int MAX_SUPPORTED_VERSION= version(137, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(137, 0); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index 715dbfb1f31..0728d56c8ba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -111,9 +111,7 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import com.ibm.icu.text.MessageFormat; /** - * The PDOM Provider. This is likely temporary since I hope - * to integrate the PDOM directly into the core once it has - * stabilized. + * Manages PDOM updates and events associated with them. Provides methods for index access. */ public class PDOMManager implements IWritableIndexManager, IListener { private static final String TRACE_INDEXER_SETUP = CCorePlugin.PLUGIN_ID + "/debug/indexer/setup"; //$NON-NLS-1$ @@ -697,10 +695,10 @@ public class PDOMManager implements IWritableIndexManager, IListener { } else { if (fCurrentTask != null) { IndexerProgress info= fCurrentTask.getProgressInformation(); - fSourceCount+= info.fCompletedSources; - fHeaderCount+= info.fCompletedHeaders; + fSourceCount += info.fCompletedSources; + fHeaderCount += info.fCompletedHeaders; // for the ticks we don't consider additional headers - fTickCount+= info.fCompletedSources + info.fPrimaryHeaderCount; + fTickCount += info.fCompletedSources + info.fPrimaryHeaderCount; } result= fCurrentTask= fTaskQueue.removeFirst(); } @@ -1138,26 +1136,41 @@ public class PDOMManager implements IWritableIndexManager, IListener { int sourceCount, sourceEstimate, headerCount, tickCount, tickEstimate; String detail= null; synchronized (fTaskQueue) { - // add historic data + // Add historic data. sourceCount= sourceEstimate= fSourceCount; headerCount= fHeaderCount; tickCount= tickEstimate= fTickCount; - // add future data + // Add future data. for (IPDOMIndexerTask task : fTaskQueue) { final IndexerProgress info= task.getProgressInformation(); - sourceEstimate+= info.fRequestedFilesCount; - tickEstimate+= info.getEstimatedTicks(); + sourceEstimate += info.fRequestedFilesCount; + tickEstimate += info.getEstimatedTicks(); } - // add current data + // Add current data. if (fCurrentTask != null) { final IndexerProgress info= fCurrentTask.getProgressInformation(); - sourceCount+= info.fCompletedSources; - sourceEstimate+= info.fRequestedFilesCount - info.fPrimaryHeaderCount; - headerCount+= info.fCompletedHeaders; - // for the ticks we don't consider additional headers - tickCount+= info.fCompletedSources + info.fPrimaryHeaderCount; - tickEstimate+= info.getEstimatedTicks(); + sourceCount += info.fCompletedSources; + sourceEstimate += info.fRequestedFilesCount - info.fPrimaryHeaderCount; + headerCount += info.fCompletedHeaders; + int completedPrimary = info.fCompletedSources + info.fPrimaryHeaderCount; + if (info.fRequestedFilesCount != 0) { + // We estimate the number of additional header files that will be encountered + // through resolution of includes by assuming that the number of the completed + // additional header files is proportional to the square root of the number of + // the completed requested files. This assumption reflects the fact that more + // additional header files are encountered at the beginning of indexing than + // towards the end. + tickCount += completedPrimary; + int additionalHeaders = info.fCompletedHeaders - info.fPrimaryHeaderCount; + tickEstimate += info.fRequestedFilesCount; + tickCount += additionalHeaders; + tickEstimate += additionalHeaders * Math.sqrt((double) info.fRequestedFilesCount / Math.max(completedPrimary, 1)); + } else { + // For the ticks we don't consider additional headers. + tickCount += completedPrimary; + tickEstimate += info.fTimeEstimate; + } detail= PDOMIndexerJob.sMonitorDetail; } } @@ -1171,9 +1184,9 @@ public class PDOMManager implements IWritableIndexManager, IListener { job.subTask(msg); if (tickCount > 0 && tickCount <= tickEstimate) { - int newTick= tickCount*base/tickEstimate; + int newTick= tickCount * base / tickEstimate; if (newTick > currentTicks) { - job.worked(newTick-currentTicks); + job.worked(newTick - currentTicks); return newTick; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java index d4342da6751..a7d5e4ea432 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 QNX Software Systems and others. + * Copyright (c) 2005, 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 @@ -9,6 +9,7 @@ * QNX - Initial API and implementation * Markus Schorn (Wind River Systems) * IBM Corporation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.db; @@ -301,21 +302,22 @@ final class Chunk { } void put(final long offset, final byte[] data, final int len) { + put(offset, data, 0, len); + } + + void put(final long offset, final byte[] data, int dataPos, final int len) { assert fLocked; - fDirty= true; + fDirty = true; int idx = recPtrToIndex(offset); - int i= 0; - while (i < len) { - fBuffer[idx++]= data[i++]; - } + System.arraycopy(data, dataPos, fBuffer, idx, len); } public void get(final long offset, byte[] data) { + get(offset, data, 0, data.length); + } + + public void get(final long offset, byte[] data, int dataPos, int len) { int idx = recPtrToIndex(offset); - final int end= idx + data.length; - int i= 0; - while (idx < end) { - data[i++]= fBuffer[idx++]; - } + System.arraycopy(fBuffer, idx, data, dataPos, len); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java index 3f7274ce4bb..4963a86f84e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 QNX Software Systems and others. + * Copyright (c) 2005, 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 @@ -10,6 +10,7 @@ * Symbian - Add some non-javadoc implementation notes * Markus Schorn (Wind River Systems) * IBM Corporation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.db; @@ -72,10 +73,10 @@ public class Database { public static final int BLOCK_SIZE_DELTA_BITS = 3; public static final int BLOCK_SIZE_DELTA= 1 << BLOCK_SIZE_DELTA_BITS; public static final int MIN_BLOCK_DELTAS = 2; // a block must at least be 2 + 2*4 bytes to link the free blocks. - public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE/BLOCK_SIZE_DELTA; - public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS*BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE; + public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE / BLOCK_SIZE_DELTA; + public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS * BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE; public static final int PTR_SIZE = 4; // size of a pointer in the database in bytes - public static final int TYPE_SIZE = 2+PTR_SIZE; // size of a type in the database in bytes + public static final int TYPE_SIZE = 2 + PTR_SIZE; // size of a type in the database in bytes public static final int VALUE_SIZE = TYPE_SIZE; // size of a value in the database in bytes public static final int ARGUMENT_SIZE = TYPE_SIZE; // size of a template argument in the database in bytes public static final long MAX_DB_SIZE= ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS)); @@ -90,9 +91,9 @@ public class Database { private final File fLocation; private final boolean fReadOnly; private RandomAccessFile fFile; - private boolean fExclusiveLock= false; // necessary for any write operation + private boolean fExclusiveLock; // necessary for any write operation private boolean fLocked; // necessary for any operation. - private boolean fIsMarkedIncomplete= false; + private boolean fIsMarkedIncomplete; private int fVersion; private final Chunk fHeaderChunk; @@ -150,7 +151,7 @@ public class Database { fFile.getChannel().read(buf, position); return; } catch (ClosedChannelException e) { - // bug 219834 file may have be closed by interrupting a thread during an I/O operation. + // Bug 219834 file may have be closed by interrupting a thread during an I/O operation. reopen(e, ++retries); } } while (true); @@ -163,14 +164,14 @@ public class Database { fFile.getChannel().write(buf, position); return; } catch (ClosedChannelException e) { - // bug 219834 file may have be closed by interrupting a thread during an I/O operation. + // Bug 219834 file may have be closed by interrupting a thread during an I/O operation. reopen(e, ++retries); } } } private void reopen(ClosedChannelException e, int attempt) throws ClosedChannelException, FileNotFoundException { - // only if the current thread was not interrupted we try to reopen the file. + // Only if the current thread was not interrupted we try to reopen the file. if (e instanceof ClosedByInterruptException || attempt >= 20) { throw e; } @@ -184,9 +185,9 @@ public class Database { long position = 0; long size = from.size(); while (position < size) { - nRead = from.transferTo(position, 4096*16, target); + nRead = from.transferTo(position, 4096 * 16, target); if (nRead == 0) { - break; // should not happen + break; // Should not happen } else { position+= nRead; } @@ -530,10 +531,18 @@ public class Database { getChunk(offset).put(offset, data, len); } + public void putBytes(long offset, byte[] data, int dataPos, int len) throws CoreException { + getChunk(offset).put(offset, data, dataPos, len); + } + public void getBytes(long offset, byte[] data) throws CoreException { getChunk(offset).get(offset, data); } + public void getBytes(long offset, byte[] data, int dataPos, int len) throws CoreException { + getChunk(offset).get(offset, data, dataPos, len); + } + public IString newString(String string) throws CoreException { return newString(string.toCharArray()); } @@ -545,7 +554,7 @@ public class Database { if (useBytes) { bytelen= len; } else { - bytelen= 2*len; + bytelen= 2 * len; } if (bytelen > ShortString.MAX_BYTE_LENGTH) { @@ -607,7 +616,7 @@ public class Database { // chunks have been removed from the cache, so we are fine fHeaderChunk.clear(0, CHUNK_SIZE); fHeaderChunk.fDirty= false; - fChunks= new Chunk[] {null}; + fChunks= new Chunk[] { null }; fChunksUsed = fChunksAllocated = fChunks.length; try { fFile.close(); @@ -686,8 +695,7 @@ public class Database { } // also handles header chunk flushAndUnlockChunks(dirtyChunks, flush); - } - finally { + } finally { fExclusiveLock= false; } } @@ -721,7 +729,7 @@ public class Database { private void flushAndUnlockChunks(final ArrayList dirtyChunks, boolean isComplete) throws CoreException { assert !Thread.holdsLock(fCache); - synchronized(fHeaderChunk) { + synchronized (fHeaderChunk) { final boolean haveDirtyChunks = !dirtyChunks.isEmpty(); if (haveDirtyChunks || fHeaderChunk.fDirty) { markFileIncomplete(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java index 82ff86be4ba..d5294c33b68 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java @@ -189,8 +189,14 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer { putByte(VALUE); arg.getNonTypeEvaluation().marshal(this, true); } else { - marshalType(arg.getTypeValue()); - marshalType(arg.getOriginalTypeValue()); + final IType typeValue = arg.getTypeValue(); + final IType originalTypeValue = arg.getOriginalTypeValue(); + marshalType(typeValue); + if (typeValue != originalTypeValue) { + marshalType(originalTypeValue); + } else { + marshalType(null); + } } } @@ -203,6 +209,8 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer { fPos--; IType type = unmarshalType(); IType originalType = unmarshalType(); + if (originalType == null) + originalType= type; return new CPPTemplateTypeArgument(type, originalType); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index ef857541949..2bdfc076faf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -11,6 +11,7 @@ * IBM Corporation * Andrew Ferguson (Symbian) * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; @@ -168,7 +169,6 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage } } - @Override public void addChild(PDOMNode child) throws CoreException { getIndex().insert(child.getRecord()); @@ -438,46 +438,94 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage if (type != null) { TypeMarshalBuffer bc= new TypeMarshalBuffer(this); bc.marshalType(type); - int len= bc.getPosition(); - if (len > 0) { - if (len <= Database.TYPE_SIZE) { - db.putBytes(offset, bc.getBuffer(), len); - } else if (len <= Database.MAX_MALLOC_SIZE-2){ - long ptr= db.malloc(len+2); + storeBuffer(db, offset, bc, Database.TYPE_SIZE); + } + } + + private void storeBuffer(Database db, long offset, TypeMarshalBuffer buf, int maxInlineSize) throws CoreException { + int len= buf.getPosition(); + if (len > 0) { + if (len <= maxInlineSize) { + db.putBytes(offset, buf.getBuffer(), len); + } else { + db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE); + long chainOffset = offset + 1; + int bufferPos = 0; + while (bufferPos < len) { + int chunkLength = len - bufferPos + 2; + boolean chainingRequired = false; + if (chunkLength > Database.MAX_MALLOC_SIZE) { + chunkLength = Database.MAX_MALLOC_SIZE; + chainingRequired = true; + } + long ptr = db.malloc(chunkLength); + db.putRecPtr(chainOffset, ptr); db.putShort(ptr, (short) len); - db.putBytes(ptr+2, bc.getBuffer(), len); - db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE); - db.putRecPtr(offset+2, ptr); + int pos = 2; + if (chainingRequired) { + // Reserve space for the chaining pointer. + chainOffset = ptr + 2; pos += Database.PTR_SIZE; + } + chunkLength -= pos; + db.putBytes(ptr + pos, buf.getBuffer(), bufferPos, chunkLength); + bufferPos += chunkLength; } } } } - private void deleteType(Database db, long offset) throws CoreException { - byte firstByte= db.getByte(offset); - if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) { - long ptr= db.getRecPtr(offset+2); - clearType(db, offset); - db.free(ptr); - } else { - clearType(db, offset); + private byte[] loadLinkedSerializedData(final Database db, long offset) throws CoreException { + long ptr= db.getRecPtr(offset); + int len= db.getShort(ptr) & 0xffff; + byte[] data= new byte[len]; + int bufferPos = 0; + while (bufferPos < len) { + int chunkLength = len - bufferPos + 2; + int pos = 2; + long chunkPtr = ptr; + if (chunkLength > Database.MAX_MALLOC_SIZE) { + chunkLength = Database.MAX_MALLOC_SIZE; + ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE; + } + chunkLength -= pos; + db.getBytes(chunkPtr + pos, data, bufferPos, chunkLength); + bufferPos += chunkLength; } + return data; } - private void clearType(Database db, long offset) throws CoreException { - db.clearBytes(offset, Database.TYPE_SIZE); + private void deleteSerializedData(Database db, long offset, int maxInlineSize) throws CoreException { + byte firstByte= db.getByte(offset); + if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) { + long ptr= db.getRecPtr(offset + 1); + int len= db.getShort(ptr) & 0xffff; + while (len > 0) { + int chunkLength = len + 2; + int pos = 2; + long chunkPtr = ptr; + if (chunkLength > Database.MAX_MALLOC_SIZE) { + chunkLength = Database.MAX_MALLOC_SIZE; + ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE; + } + chunkLength -= pos; + db.free(chunkPtr); + len -= chunkLength; + } + } + db.clearBytes(offset, maxInlineSize); + } + + private void deleteType(Database db, long offset) throws CoreException { + deleteSerializedData(db, offset, Database.TYPE_SIZE); } public IType loadType(long offset) throws CoreException { final Database db= getDB(); final byte firstByte= db.getByte(offset); byte[] data= null; - switch(firstByte) { + switch (firstByte) { case TypeMarshalBuffer.INDIRECT_TYPE: - long ptr= db.getRecPtr(offset+2); - int len= db.getShort(ptr) & 0xffff; - data= new byte[len]; - db.getBytes(ptr+2, data); + data = loadLinkedSerializedData(db, offset + 1); break; case TypeMarshalBuffer.UNSTORABLE_TYPE: return TypeMarshalBuffer.UNSTORABLE_TYPE_PROBLEM; @@ -501,46 +549,21 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage if (binding != null) { TypeMarshalBuffer bc= new TypeMarshalBuffer(this); bc.marshalBinding(binding); - int len= bc.getPosition(); - if (len > 0) { - if (len <= Database.TYPE_SIZE) { - db.putBytes(offset, bc.getBuffer(), len); - } else if (len <= Database.MAX_MALLOC_SIZE-2){ - long ptr= db.malloc(len+2); - db.putShort(ptr, (short) len); - db.putBytes(ptr+2, bc.getBuffer(), len); - db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE); - db.putRecPtr(offset+2, ptr); - } - } + storeBuffer(db, offset, bc, Database.TYPE_SIZE); } } private void deleteBinding(Database db, long offset) throws CoreException { - byte firstByte= db.getByte(offset); - if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) { - long ptr= db.getRecPtr(offset+2); - clearBinding(db, offset); - db.free(ptr); - } else { - clearBinding(db, offset); - } - } - - private void clearBinding(Database db, long offset) throws CoreException { - db.clearBytes(offset, Database.TYPE_SIZE); + deleteSerializedData(db, offset, Database.TYPE_SIZE); } public IBinding loadBinding(long offset) throws CoreException { final Database db= getDB(); final byte firstByte= db.getByte(offset); byte[] data= null; - switch(firstByte) { + switch (firstByte) { case TypeMarshalBuffer.INDIRECT_TYPE: - long ptr= db.getRecPtr(offset+2); - int len= db.getShort(ptr) & 0xffff; - data= new byte[len]; - db.getBytes(ptr+2, data); + data = loadLinkedSerializedData(db, offset + 1); break; case TypeMarshalBuffer.UNSTORABLE_TYPE: return new ProblemBinding(null, ISemanticProblem.TYPE_NOT_PERSISTED); @@ -564,52 +587,27 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage if (arg != null) { TypeMarshalBuffer bc= new TypeMarshalBuffer(this); bc.marshalTemplateArgument(arg); - int len= bc.getPosition(); - if (len > 0) { - if (len <= Database.ARGUMENT_SIZE) { - db.putBytes(offset, bc.getBuffer(), len); - } else if (len <= Database.MAX_MALLOC_SIZE-2){ - long ptr= db.malloc(len+2); - db.putShort(ptr, (short) len); - db.putBytes(ptr+2, bc.getBuffer(), len); - db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE); - db.putRecPtr(offset+2, ptr); - } - } + storeBuffer(db, offset, bc, Database.ARGUMENT_SIZE); } } private void deleteArgument(Database db, long offset) throws CoreException { - byte firstByte= db.getByte(offset); - if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) { - long ptr= db.getRecPtr(offset+2); - clearArgument(db, offset); - db.free(ptr); - } else { - clearArgument(db, offset); - } - } - - private void clearArgument(Database db, long offset) throws CoreException { - db.clearBytes(offset, Database.ARGUMENT_SIZE); + deleteSerializedData(db, offset, Database.ARGUMENT_SIZE); } public ICPPTemplateArgument loadTemplateArgument(long offset) throws CoreException { final Database db= getDB(); final byte firstByte= db.getByte(offset); byte[] data= null; - switch(firstByte) { + switch (firstByte) { case TypeMarshalBuffer.INDIRECT_TYPE: - long ptr= db.getRecPtr(offset+2); - int len= db.getShort(ptr) & 0xffff; - data= new byte[len]; - db.getBytes(ptr+2, data); + data = loadLinkedSerializedData(db, offset + 1); break; case TypeMarshalBuffer.UNSTORABLE_TYPE: case TypeMarshalBuffer.NULL_TYPE: return null; default: - data= new byte[Database.TYPE_SIZE]; + data= new byte[Database.ARGUMENT_SIZE]; db.getBytes(offset, data); break; } @@ -626,40 +624,26 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage if (value != null) { TypeMarshalBuffer bc= new TypeMarshalBuffer(this); bc.marshalValue(value); - int len= bc.getPosition(); - if (len > 0) { - if (len <= Database.TYPE_SIZE) { - db.putBytes(offset, bc.getBuffer(), len); - } else if (len <= Database.MAX_MALLOC_SIZE-2){ - long ptr= db.malloc(len+2); - db.putShort(ptr, (short) len); - db.putBytes(ptr+2, bc.getBuffer(), len); - db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE); - db.putRecPtr(offset+2, ptr); - } - } + storeBuffer(db, offset, bc, Database.VALUE_SIZE); } } private void deleteValue(Database db, long offset) throws CoreException { - deleteType(db, offset); + deleteSerializedData(db, offset, Database.VALUE_SIZE); } public IValue loadValue(long offset) throws CoreException { final Database db= getDB(); final byte firstByte= db.getByte(offset); byte[] data= null; - switch(firstByte) { + switch (firstByte) { case TypeMarshalBuffer.INDIRECT_TYPE: - long ptr= db.getRecPtr(offset+2); - int len= db.getShort(ptr) & 0xffff; - data= new byte[len]; - db.getBytes(ptr+2, data); + data = loadLinkedSerializedData(db, offset + 1); break; case TypeMarshalBuffer.NULL_TYPE: return null; default: - data= new byte[Database.TYPE_SIZE]; + data= new byte[Database.VALUE_SIZE]; db.getBytes(offset, data); break; } diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 94270588d84..aeaba85ccbc 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -3767,14 +3767,40 @@ menuGroupId="org.eclipse.cdt.ui.newProject" type="new" wizardId="org.eclipse.cdt.ui.wizards.NewCWizard1"> - + + + + + + + + + + + + + - + + + + + + + + + + + + + 0; - return w; - } - - @Override - public void propertyChange(PropertyChangeEvent event) { - checkWS(); - } -} +/******************************************************************************* + * Copyright (c) 2008, 2009, 2012 Intel Corporation, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Intel Corporation - initial API and implementation + * QNX Software Systems - [272416] Rework the config sets dialog + * Freescale Semiconductor - [392954] disable the action if only empty working sets exist + *******************************************************************************/ +package org.eclipse.cdt.ui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; + +import org.eclipse.cdt.ui.CUIPlugin; + +import org.eclipse.cdt.internal.ui.workingsets.WorkingSetConfigurationDialog; + +/** + */ +public class WorkingSetConfigAction implements IWorkbenchWindowActionDelegate, IPropertyChangeListener { + + private static final IWorkingSetManager wsm = CUIPlugin.getDefault().getWorkbench().getWorkingSetManager(); + private boolean enabled = true; + private IWorkbenchWindow window; + private IAction action; + + @Override + public void run(IAction action) { + this.action = action; + checkWS(); + if (enabled) { + new WorkingSetConfigurationDialog(window.getShell()).open(); + } + } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + this.action = action; + checkWS(); + } + + @Override + public void dispose() { + wsm.removePropertyChangeListener(this); + } + + @Override + public void init(IWorkbenchWindow window) { + this.window = window; + wsm.addPropertyChangeListener(this); + checkWS(); + } + + private void checkWS() { + enabled = false; + IWorkingSet[] w = wsm.getWorkingSets(); + if (w == null) + w = new IWorkingSet[0]; + for (IWorkingSet ws : w) { + if (!ws.isEmpty()) { + enabled = true; + break; + } + } + if (action != null) { + action.setEnabled(enabled); + } + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + checkWS(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CacheSizeBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CacheSizeBlock.java index 4547cbf212b..3edf9241595 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CacheSizeBlock.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/CacheSizeBlock.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2012 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 @@ -14,9 +14,9 @@ package org.eclipse.cdt.ui.dialogs; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; @@ -26,13 +26,12 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.preferences.ScopedPreferenceStore; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePreferenceConstants; import org.eclipse.cdt.core.dom.CDOM; import org.eclipse.cdt.core.parser.CodeReaderCache; import org.eclipse.cdt.core.parser.ICodeReaderCache; +import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.utils.ui.controls.ControlFactory; import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil; @@ -140,7 +139,7 @@ public class CacheSizeBlock extends AbstractCOptionPage { } private void initializeValues() { - ScopedPreferenceStore prefStore= new ScopedPreferenceStore(InstanceScope.INSTANCE, CCorePlugin.PLUGIN_ID); + IPreferenceStore prefStore= CUIPlugin.getDefault().getCorePreferenceStore(); fDBLimitPct.setPreferenceStore(prefStore); fDBLimitPct.setPropertyChangeListener(validityChangeListener); diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java index 8735d96e3b6..751c3ed9636 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java @@ -74,34 +74,32 @@ public class MapEntrySourceContainer extends AbstractSourceContainer { public static IPath createPath(String path) { if (path == null) return null; - if (path.contains("\\")) { //$NON-NLS-1$ - // handle Windows slashes and canonicalize - path = path.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - // also check for device or UNC - int firstSep = path.indexOf("/"); //$NON-NLS-1$ - int idx = path.indexOf(":"); //$NON-NLS-1$ - // ':' indicates a Windows device separator if it comes before - // the first segment separator - if (idx > 0 && (firstSep < 0 || idx < firstSep)) { - String device = path.substring(0, idx + 1); - path = path.substring(idx + 1); - return new Path(path).setDevice(device); - } else { - // Cygwin or UNC path - if (path.startsWith("//")) { //$NON-NLS-1$ - String network; - idx = path.indexOf("/", 2); //$NON-NLS-1$ - if (idx > 0) { - network = path.substring(0, idx); - path = path.substring(idx); - } else { - network = path; - path = ""; //$NON-NLS-1$ - } - return new Path(network, path).makeUNC(true); + + // Check for windows full-path formatting. + if (path.matches("^([a-zA-Z])[:](.*)$")) { //$NON-NLS-1$ + String device = null; + String missingfile = path.replace("\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$ + int idx = missingfile.indexOf(":"); //$NON-NLS-1$ + if ( idx > 0 ) { + device = missingfile.substring(0, idx + 1); + missingfile = missingfile.substring(idx + 1); } + return new Path(device, missingfile); + } + + int idx = 0; + // Cygwin or UNC path + if (path.startsWith("//")) { //$NON-NLS-1$ + String network; + idx = path.indexOf("/", 2); //$NON-NLS-1$ + if (idx > 0) { + network = path.substring(0, idx); + path = path.substring(idx); + } else { + network = path; + path = ""; //$NON-NLS-1$ + } + return new Path(network, path).makeUNC(true); } // fallthrough diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java index 7e536e80630..a87f1fe3f52 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java @@ -37,7 +37,7 @@ public class MapEntrySourceContainerType extends AbstractSourceContainerTypeDele Element element = (Element)node; if (ELEMENT_NAME.equals(element.getNodeName())) { String path = element.getAttribute(BACKEND_PATH); - IPath backend = new Path(path); + IPath backend = MapEntrySourceContainer.createPath(path); if (!backend.isValidPath(path)) { abort(InternalSourceLookupMessages.MapEntrySourceContainerType_0, null); } diff --git a/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/MapEntrySourceContainerTests.java b/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/MapEntrySourceContainerTests.java new file mode 100644 index 00000000000..10144aa170d --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui.tests/core/org/eclipse/cdt/debug/core/tests/MapEntrySourceContainerTests.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.core.tests; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.debug.internal.core.sourcelookup.MapEntrySourceContainer; +import org.eclipse.core.runtime.IPath; + +@SuppressWarnings("restriction") +public class MapEntrySourceContainerTests extends TestCase { + + public static Test suite() { + return new TestSuite(MapEntrySourceContainerTests.class); + } + + public MapEntrySourceContainerTests(String name) { + super(name); + } + + public void testUNCPath() { + String uncPath = "//server/path/on/server"; + IPath path = MapEntrySourceContainer.createPath(uncPath); + assertEquals(uncPath, path.toString()); + + uncPath = "\\\\server\\path\\on\\server"; + path = MapEntrySourceContainer.createPath(uncPath); + assertEquals(uncPath, path.toOSString()); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java index 587af11855d..2ada2e60f51 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/breakpoints/CBreakpointPropertyPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 QNX Software Systems and others. + * Copyright (c) 2004, 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 @@ -9,6 +9,7 @@ * QNX Software Systems - Initial API and implementation * Nokia - https://bugs.eclipse.org/bugs/show_bug.cgi?id=145606 * QNX Software Systems - Catchpoints support https://bugs.eclipse.org/bugs/show_bug.cgi?id=226689 + * Scott Tepavich (WindRiver) - Fixed bad reference to messages.properties string (Bug 393178) *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui.breakpoints; @@ -567,7 +568,7 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement } else if (!isReadType && isWriteType) { return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_watchpoint_label"); //$NON-NLS-1$ } else { - return BreakpointsMessages.getString("CBreakpointPropertyPage.watchpointType_breakpointType_watchpoint_access_label"); //$NON-NLS-1$ + return BreakpointsMessages.getString("CBreakpointPropertyPage.breakpointType_watchpoint_access_label"); //$NON-NLS-1$ } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java index 3a3441510f8..3f098fa3505 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java @@ -272,7 +272,7 @@ public class CSourceNotFoundEditor extends CommonSourceNotFoundEditor { protected void locateFile() { FileDialog dialog = new FileDialog(getEditorSite().getShell(), SWT.NONE); - Path missingPath = new Path(missingFile); + IPath missingPath = MapEntrySourceContainer.createPath(missingFile); dialog.setFilterNames(new String[] {SourceLookupUIMessages.CSourceNotFoundEditor_2}); dialog.setFilterExtensions(new String[] {"*." + missingPath.getFileExtension()}); //$NON-NLS-1$ String res = dialog.open(); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.java index ae708ab7f14..1654ca6e03d 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.java @@ -29,6 +29,7 @@ public class Messages extends NLS { public static String OSView_12; public static String OSView_13; public static String OSView_14; + public static String OSView_15; static { // initialize resource bundle NLS.initializeMessages(Messages.class.getName(), Messages.class); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.properties index 79bea302796..184a619b1de 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.properties +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/Messages.properties @@ -9,7 +9,7 @@ # Vladimir Prus (Mentor Graphics) - initial API and implementation ############################################################################### OSView_3=Refresh -OSView_4=Invalid debug session selected. +OSView_4=Invalid debug object selected. Please select a process, thread or frame inside DSF GDB debug session. OSView_5=Please select resource class. OSView_6=Fetching data... OSView_7=No data has been fetched yet. Fetch now. @@ -20,3 +20,4 @@ OSView_11=Determining available OS resource classes... OSView_12=No data has been fetched yet. Target is busy. OSView_13=Waiting for the debug session to initialize. OSView_14=Objects from different debug sessions are selected. +OSView_15=No debug session is selected. diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/OSResourcesView.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/OSResourcesView.java index 5e5f2a7cc5a..8306f3dc224 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/OSResourcesView.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/OSResourcesView.java @@ -82,6 +82,8 @@ public class OSResourcesView extends ViewPart implements DsfSession.SessionEnded // Indicates that we've selected objects from different debug sessions. boolean fMultiple = false; + // Indicates that we have selected object with a wrong type + boolean fWrongType = false; // UI objects @@ -225,14 +227,20 @@ public class OSResourcesView extends ViewPart implements DsfSession.SessionEnded ICommandControlDMContext context = null; fMultiple = false; + fWrongType = false; if (s instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) s; if (ss.size() > 0) { @SuppressWarnings("rawtypes") Iterator i = ss.iterator(); context = getCommandControlContext(i.next()); + if (context == null) + fWrongType = true; + while (i.hasNext()) { - ICommandControlDMContext nextContext = getCommandControlContext(i.next()); + ICommandControlDMContext nextContext = getCommandControlContext(i.next()); + if (nextContext == null) + fWrongType = true; if (nextContext == null && context != null || nextContext != null && context == null || nextContext != null && context != null && !nextContext.equals(context)) @@ -300,18 +308,13 @@ public class OSResourcesView extends ViewPart implements DsfSession.SessionEnded public void update() { // Note that fSessionData always calls the listener in // UI thread, so we can directly call 'update' here. - OSResourcesView.this.update(); + OSResourcesView.this.updateSessionDataContents(); } }, fViewer.getControl()); } } - - if (newSessionData != fSessionData) - { - fSessionData = newSessionData; - update(); - } + update(newSessionData); } @Override @@ -323,7 +326,39 @@ public class OSResourcesView extends ViewPart implements DsfSession.SessionEnded } } - private void update() { + // Update UI to showing new session data. If this session data is already + // shown, does nothing. + private void update(SessionOSData newSessionData) + { + if (fViewer == null || fViewer.getControl() == null) + return; + + if (fViewer.getControl().isDisposed()) + return; + + if (newSessionData == null) + { + fSessionData = null; + if (fMultiple) + hideTable(Messages.OSView_14); + else if (fWrongType) + hideTable(Messages.OSView_4); + else + hideTable(Messages.OSView_15); + fResourceClassEditor.setEnabled(false); + fRefreshAction.setEnabled(false); + return; + } + + if (newSessionData != fSessionData) { + fSessionData = newSessionData; + updateSessionDataContents(); + } + } + + // Update the UI according to actual content of fSessionData, + // which must be not null. + private void updateSessionDataContents() { if (fViewer == null || fViewer.getControl() == null) return; @@ -331,14 +366,6 @@ public class OSResourcesView extends ViewPart implements DsfSession.SessionEnded if (fViewer.getControl().isDisposed()) return; - if (fSessionData == null) - { - hideTable(fMultiple ? Messages.OSView_14 : Messages.OSView_4); - fResourceClassEditor.setEnabled(false); - fRefreshAction.setEnabled(false); - return; - } - boolean enable = fSessionData.canFetchData(); fRefreshAction.setEnabled(enable); fResourceClass = fResourceClassEditor.updateClasses(fSessionData.getResourceClasses()); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/LaunchUtils.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/LaunchUtils.java index 2d51b0b1677..c8e0232d3b0 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/LaunchUtils.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/LaunchUtils.java @@ -9,6 +9,7 @@ * Ericsson - Initial API and implementation * Ericsson - Added support for Mac OS * Sergey Prigogin (Google) + * Marc Khouzam (Ericsson) - Add timer when fetching GDB version (Bug 376203) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.launching; @@ -48,11 +49,13 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.ILaunchConfiguration; @@ -290,7 +293,7 @@ public class LaunchUtils { * only once and the resulting version string stored for future uses. */ public static String getGDBVersion(final ILaunchConfiguration configuration) throws CoreException { - Process process = null; + final Process process; String cmd = getGDBPath(configuration).toOSString() + " --version"; //$NON-NLS-1$ try { process = ProcessFactory.getFactory().exec(cmd, getLaunchEnvironment(configuration)); @@ -299,6 +302,21 @@ public class LaunchUtils { "Error while launching command: " + cmd, e.getCause()));//$NON-NLS-1$ } + // Start a timeout job to make sure we don't get stuck waiting for + // an answer from a gdb that is hanging + // Bug 376203 + Job timeoutJob = new Job("GDB version timeout job") { //$NON-NLS-1$ + { setSystem(true); } + @Override + protected IStatus run(IProgressMonitor arg) { + // Took too long. Kill the gdb process and + // let things clean up. + process.destroy(); + return Status.OK_STATUS; + } + }; + timeoutJob.schedule(10000); + InputStream stream = null; StringBuilder cmdOutput = new StringBuilder(200); try { @@ -314,6 +332,10 @@ public class LaunchUtils { throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error reading GDB STDOUT after sending: " + cmd, e.getCause()));//$NON-NLS-1$ } finally { + // If we get here we are obviously not stuck so we can cancel the timeout job. + // Note that it may already have executed, but that is not a problem. + timeoutJob.cancel(); + // Cleanup to avoid leaking pipes // Close the stream we used, and then destroy the process // Bug 345164 @@ -325,7 +347,12 @@ public class LaunchUtils { process.destroy(); } - return getGDBVersionFromText(cmdOutput.toString()); + String gdbVersion = getGDBVersionFromText(cmdOutput.toString()); + if (gdbVersion == null || gdbVersion.isEmpty()) { + throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, + "Could not determine GDB version after sending: " + cmd, null));//$NON-NLS-1$ + } + return gdbVersion; } public static boolean getIsAttach(ILaunchConfiguration config) { diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java index 1a679dc8a85..9cb79faecf8 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java @@ -10,6 +10,7 @@ * Wind River System * Ericsson * Marc Khouzam (Ericsson) - Use the new IMIBackend2 interface (Bug 350837) + * Mark Bozeman (Mentor Graphics) - Report GDB start failures (Bug 376203) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -19,7 +20,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.Reader; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; @@ -561,22 +561,53 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend, IMIBa return Status.OK_STATUS; } + BufferedReader inputReader = null; + BufferedReader errorReader = null; + boolean success = false; try { - Reader r = new InputStreamReader(getMIInputStream()); - BufferedReader reader = new BufferedReader(r); + // Read initial GDB prompt + inputReader = new BufferedReader(new InputStreamReader(getMIInputStream())); String line; - while ((line = reader.readLine()) != null) { + while ((line = inputReader.readLine()) != null) { line = line.trim(); if (line.endsWith("(gdb)")) { //$NON-NLS-1$ + success = true; break; } } + + // Failed to read initial prompt, check for error + if (!success) { + errorReader = new BufferedReader(new InputStreamReader(getMIErrorStream())); + String errorInfo = errorReader.readLine(); + if (errorInfo == null) { + errorInfo = "GDB prompt not read"; //$NON-NLS-1$ + } + gdbLaunchRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, errorInfo, null)); + } } catch (IOException e) { - gdbLaunchRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Error reading GDB STDOUT", e)); //$NON-NLS-1$ - gdbLaunchRequestMonitor.done(); - return Status.OK_STATUS; + success = false; + gdbLaunchRequestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Error reading GDB output", e)); //$NON-NLS-1$ } + // In the case of failure, close the MI streams so + // they are not leaked. + if (!success) + { + if (inputReader != null) { + try { + inputReader.close(); + } catch (IOException e) { + } + } + if (errorReader != null) { + try { + errorReader.close(); + } catch (IOException e) { + } + } + } + gdbLaunchRequestMonitor.done(); return Status.OK_STATUS; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBPatternMatchingExpressions.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBPatternMatchingExpressions.java index fd3e5e03253..ce30b9e152f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBPatternMatchingExpressions.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBPatternMatchingExpressions.java @@ -7,6 +7,7 @@ * * Contributors: * Marc Khouzam (Ericsson) - initial API and implementation + * Grzegorz Kuligowski - Cannot cast to type that contain commas (bug 393474) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -69,9 +70,10 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements * the different expressions contained in a group-expression. * The [] are not part the characters, but are used in the regex format. * Note that we don't allow a space separator because spaces are valid within - * an expression (e.g., i + 1) + * an expression (e.g., i + 1). + * We also don't allow a comma because they are used in templates (bug 393474) */ - private final static String GROUP_EXPRESSION_SEPARATORS_REGEXP = "[,;]"; //$NON-NLS-1$ + private final static String GROUP_EXPRESSION_SEPARATORS_REGEXP = "[;]"; //$NON-NLS-1$ /** * A group-expression is an expression that requires expansion into a (potentially empty) diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/LargePipedInputStream.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/LargePipedInputStream.java index 4b5ba151cd4..d680c9bb0b1 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/LargePipedInputStream.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/LargePipedInputStream.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2009 Wind River Systems and others. + * Copyright (c) 2006, 2012 Wind River 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 @@ -7,6 +7,8 @@ * * Contributors: * Wind River Systems - initial API and implementation + * Marc Khouzam (Ericsson) - Specify the larger size in the new constructor + * of PipedInputStream provided by Java 6 *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service.command; @@ -17,13 +19,12 @@ import java.io.PipedOutputStream; class LargePipedInputStream extends PipedInputStream { - private final int LARGE_BUF_SIZE = 1024 * 1024; // 1 megs + private static final int LARGE_BUF_SIZE = 1024 * 1024; // 1M public LargePipedInputStream(PipedOutputStream pipedoutputstream) throws IOException { - super(pipedoutputstream); - buffer = new byte[LARGE_BUF_SIZE]; + super(pipedoutputstream, LARGE_BUF_SIZE); } } diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBPatternMatchingExpressionsTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBPatternMatchingExpressionsTest.java index bfb58add8c9..6427d789bf5 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBPatternMatchingExpressionsTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/GDBPatternMatchingExpressionsTest.java @@ -404,7 +404,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupAllRegsAllLocals() throws Throwable { - final String exprString = "$*, *"; + final String exprString = "$*; *"; List list = get_X86_REGS(); Collections.sort(list); list.addAll(Arrays.asList(new String[] { "firstarg", "firstvar", "secondarg", "secondvar" })); @@ -427,7 +427,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupAllLocalsAllRegs() throws Throwable { - final String exprString = "*, $*"; + final String exprString = "*; $*"; List list = get_X86_REGS(); Collections.sort(list); list.addAll(0, Arrays.asList(new String[] { "firstarg", "firstvar", "secondarg", "secondvar" })); @@ -449,7 +449,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupSubExprRange() throws Throwable { - final String exprString = "$eax, $es, *"; + final String exprString = "$eax; $es; *"; final String[] children = new String[] { "$es", "firstarg", "firstvar", "secondarg" }; SyncUtil.runToLocation("foo"); @@ -468,7 +468,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupOneLocalAllReg() throws Throwable { - final String exprString = "firstvar, $*"; + final String exprString = "firstvar; $*"; List list = get_X86_REGS(); Collections.sort(list); list.addAll(0, Arrays.asList(new String[] { "firstvar" })); @@ -492,7 +492,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testUniqueWhenOverlapReg() throws Throwable { - final String exprString = "$eax, $e?x, $eb?"; + final String exprString = "$eax; $e?x; $eb?"; final String[] children = new String[] { "$eax","$ebx","$ecx","$edx", "$ebp" }; SyncUtil.runToLocation("foo"); @@ -513,7 +513,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testUniqueWhenOverlapLocal() throws Throwable { - final String exprString = "firstvar,*,firstvar"; + final String exprString = "firstvar;*;firstvar"; final String[] children = new String[] { "firstvar", "firstarg", "secondarg", "secondvar" }; SyncUtil.runToLocation("foo"); @@ -577,7 +577,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testSeparatlySorted() throws Throwable { - final String exprString = "$*, *"; + final String exprString = "$*; *"; List list = get_X86_REGS(); Collections.sort(list); List localsList = Arrays.asList(new String[] { "firstarg", "firstvar", "secondarg", "secondvar" }); @@ -596,24 +596,25 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { checkChildrenCount(exprDmc, children.length); } - /** - * Test that group-expression can use a comma as a separator - */ - @Test - public void testCommaSeparation() throws Throwable { - final String exprString = "firstvar,$eax"; - final String[] children = new String[] { "firstvar","$eax" }; - - SyncUtil.runToLocation("foo"); - MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER); - - IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); - - final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString); - - checkChildren(exprDmc, -1, -1, children); - checkChildrenCount(exprDmc, children.length); - } + // Cannot use comma separator because of templates (bug 393474) +// /** +// * Test that group-expression can use a comma as a separator +// */ +// @Test +// public void testCommaSeparation() throws Throwable { +// final String exprString = "firstvar,$eax"; +// final String[] children = new String[] { "firstvar","$eax" }; +// +// SyncUtil.runToLocation("foo"); +// MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER); +// +// IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); +// +// final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString); +// +// checkChildren(exprDmc, -1, -1, children); +// checkChildrenCount(exprDmc, children.length); +// } /** * Test that group-expression can use a semi-colon as a separator @@ -634,46 +635,46 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { checkChildrenCount(exprDmc, children.length); } - - /** - * Test that group-expression can use a comma and a semi-colon as a - * separator at the same time - */ - @Test - public void testCommaAndSemiColonSeparation() throws Throwable { - final String exprString = "firstvar,$eax;$es"; - final String[] children = new String[] { "firstvar","$eax","$es" }; - - SyncUtil.runToLocation("foo"); - MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER); - - IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); - - final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString); - - checkChildren(exprDmc, -1, -1, children); - checkChildrenCount(exprDmc, children.length); - - } + // Cannot use comma separator because of templates (bug 393474) +// /** +// * Test that group-expression can use a comma and a semi-colon as a +// * separator at the same time +// */ +// @Test +// public void testCommaAndSemiColonSeparation() throws Throwable { +// final String exprString = "firstvar,$eax;$es"; +// final String[] children = new String[] { "firstvar","$eax","$es" }; +// +// SyncUtil.runToLocation("foo"); +// MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER); +// +// IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); +// +// final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString); +// +// checkChildren(exprDmc, -1, -1, children); +// checkChildrenCount(exprDmc, children.length); +// } - /** - * Test that group-expression can have empty terms with commas. - */ - @Test - public void testGroupCommaEmptyTerm() throws Throwable { - final String exprString = ",,firstvar,,$eax,,"; - final String[] children = new String[] { "firstvar","$eax" }; - - SyncUtil.runToLocation("foo"); - MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER); - - IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); - - final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString); - - checkChildren(exprDmc, -1, -1, children); - checkChildrenCount(exprDmc, children.length); - } + // Cannot use comma separator because of templates (bug 393474) +// /** +// * Test that group-expression can have empty terms with commas. +// */ +// @Test +// public void testGroupCommaEmptyTerm() throws Throwable { +// final String exprString = ",,firstvar,,$eax,,"; +// final String[] children = new String[] { "firstvar","$eax" }; +// +// SyncUtil.runToLocation("foo"); +// MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER); +// +// IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); +// +// final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString); +// +// checkChildren(exprDmc, -1, -1, children); +// checkChildrenCount(exprDmc, children.length); +// } /** * Test that group-expression can have empty terms with semi-colon. @@ -699,7 +700,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testExtraSpaces() throws Throwable { - final String exprString = " firstvar , $eax , , "; + final String exprString = " firstvar ; $eax ; ; "; final String[] children = new String[] { "firstvar","$eax" }; SyncUtil.runToLocation("foo"); @@ -718,7 +719,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupExpressionData() throws Throwable { - final String exprString = "$eax,*"; + final String exprString = "$eax;*"; // final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" }; SyncUtil.runToLocation("foo"); @@ -763,7 +764,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupExpressionAddressData() throws Throwable { - final String exprString = "$eax,*"; + final String exprString = "$eax;*"; // final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" }; SyncUtil.runToLocation("foo"); @@ -795,7 +796,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupGetSubExpressions() throws Throwable { - final String exprString = "$eax,*"; + final String exprString = "$eax;*"; final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" }; SyncUtil.runToLocation("foo"); @@ -837,7 +838,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupExpressionNotModifiable() throws Throwable { - final String exprString = "$eax,*"; + final String exprString = "$eax;*"; // final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" }; SyncUtil.runToLocation("foo"); @@ -865,7 +866,7 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { */ @Test public void testGroupExpressionAvailableFormats() throws Throwable { - final String exprString = "$eax,*"; + final String exprString = "$eax;*"; // final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" }; SyncUtil.runToLocation("foo"); @@ -895,8 +896,8 @@ public class GDBPatternMatchingExpressionsTest extends BaseTestCase { @Test public void testGroupExpressionValue() throws Throwable { final String noMatchExpr = "$zzz*"; - final String singleMatchExpr = "$eax,"; - final String doubleMatchExpr = "$eax,$ebx"; + final String singleMatchExpr = "$eax;"; + final String doubleMatchExpr = "$eax;$ebx"; SyncUtil.runToLocation("foo"); MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER); diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/ExpressionInformationControlCreator.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/ExpressionInformationControlCreator.java index 88239eb1769..ca0ee3decc8 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/ExpressionInformationControlCreator.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/ExpressionInformationControlCreator.java @@ -380,6 +380,7 @@ public class ExpressionInformationControlCreator implements IInformationControlC } }); + setForegroundColor(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); setBackgroundColor(getShell().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); } @@ -428,7 +429,16 @@ public class ExpressionInformationControlCreator implements IInformationControlC } } - @Override + @Override + public void setForegroundColor(Color foreground) { + super.setForegroundColor(foreground); + if (fDetailPaneComposite != null) { + fDetailPaneComposite.setForeground(foreground); + } + fTree.setForeground(foreground); + } + + @Override public void setBackgroundColor(Color background) { super.setBackgroundColor(background); if (fDetailPaneComposite != null) { diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda/pdavm/src/org/eclipse/cdt/examples/pdavm/PDAVirtualMachine.java b/dsf/org.eclipse.cdt.examples.dsf.pda/pdavm/src/org/eclipse/cdt/examples/pdavm/PDAVirtualMachine.java index 949b439f6d7..24bcb448e37 100644 --- a/dsf/org.eclipse.cdt.examples.dsf.pda/pdavm/src/org/eclipse/cdt/examples/pdavm/PDAVirtualMachine.java +++ b/dsf/org.eclipse.cdt.examples.dsf.pda/pdavm/src/org/eclipse/cdt/examples/pdavm/PDAVirtualMachine.java @@ -197,9 +197,55 @@ public class PDAVirtualMachine { fPC = pc; } + private int parseArrayParam(String name) { + int lb = name.indexOf('['); + int rb = name.indexOf(']', lb); + if (rb < 0) return -1; + String paramStr = name.substring(lb + 1, rb); + if (paramStr.length() == 0) return -1; + + try { + return Integer.parseInt(name.substring(lb + 1, rb)); + } catch (NumberFormatException e) {} // Not a number + + Object paramVar = fLocalVariables.get(paramStr); + if (paramVar instanceof Integer) { + return (Integer)paramVar; + } + return -1; + } + + void declare(String name) { + Object value = Integer.valueOf(0); + if (name.startsWith("$")) { + setRegisterValue(name, value); + } else if (name.indexOf('[') >= 0) { + int size = parseArrayParam(name); + if (size >= 0) { + String arrayName = name.substring(0, name.indexOf('[')); + Object[] array = new Object[size]; + for (int i = 0; i < size; i++) { + array[i] = value; + } + fLocalVariables.put(arrayName, array); + } + } else { + fLocalVariables.put(name, value); + } + } + void set(String name, Object value) { if (name.startsWith("$")) { setRegisterValue(name, value); + } else if (name.indexOf('[') >= 0) { + int index = parseArrayParam(name); + if (index >=0) { + String arrayName = name.substring(0, name.indexOf('[')); + Object array = fLocalVariables.get(arrayName); + if (array instanceof Object[] && ((Object[])array).length > index) { + ((Object[])array)[index] = value; + } + } } else { fLocalVariables.put(name, value); } @@ -208,6 +254,16 @@ public class PDAVirtualMachine { Object get(String name) { if (name.startsWith("$")) { return getRegisterValue(name); + } else if (name.indexOf('[') >= 0) { + int index = parseArrayParam(name); + if (index >= 0) { + String arrayName = name.substring(0, name.indexOf('[')); + Object array = fLocalVariables.get(arrayName); + if (array instanceof Object[] && ((Object[])array).length > index) { + return ((Object[])array)[index]; + } + } + return null; } else { return fLocalVariables.get(name); } @@ -716,6 +772,14 @@ public class PDAVirtualMachine { } } + Object value = frame.fLocalVariables.get(var); + if (value instanceof Object[]) { + int size = ((Object[])value).length; + for (int i = 0; i < size; i++) { + children.add(var + "[" + Integer.toString(i) + "]"); + } + } + StringBuffer result = new StringBuffer(); for (String child : children) { result.append(child); @@ -1032,10 +1096,12 @@ public class PDAVirtualMachine { buf.append('|'); buf.append(frame.fFunction); for (String var : frame.fLocalVariables.keySet()) { - if (var.indexOf('.') == -1) { - buf.append('|'); - buf.append(var); + if (var.indexOf('.') >= 0) continue; + if (var.indexOf('[') >= 0) { + var = var.substring(0, var.indexOf('[')); } + buf.append('|'); + buf.append(var); } return buf.toString(); } @@ -1153,6 +1219,8 @@ public class PDAVirtualMachine { Object val = frame.get(var); if (val == null) { sendCommandResponse("error: variable undefined\n"); + } else if (val instanceof Object[]) { + sendCommandResponse("[" + Integer.toString(((Object[])val).length) + "]" + "\n"); } else { sendCommandResponse(val.toString() + "\n"); } @@ -1362,7 +1430,7 @@ public class PDAVirtualMachine { void iVar(PDAThread thread, Args args) { String var = args.getNextStringArg(); - thread.fCurrentFrame.set(var, 0); + thread.fCurrentFrame.declare(var); } void iInternalEndEval(PDAThread thread, Args args) { diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda/samples/arrays.pda b/dsf/org.eclipse.cdt.examples.dsf.pda/samples/arrays.pda new file mode 100644 index 00000000000..6c5056c6e3f --- /dev/null +++ b/dsf/org.eclipse.cdt.examples.dsf.pda/samples/arrays.pda @@ -0,0 +1,14 @@ +var a[10000] +var i +push 10000 +pop $i +:start +push $i +dec +pop $i +push $i +pop $a[i] +push $i +branch_not_zero start +halt + diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java b/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java index eebb3013c65..04b03b75a7e 100644 --- a/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java +++ b/dsf/org.eclipse.cdt.examples.dsf.pda/src/org/eclipse/cdt/examples/dsf/pda/service/PDAExpressions.java @@ -316,7 +316,7 @@ public class PDAExpressions extends AbstractDsfService implements ICachingServic int end = lengthArg > 0 ? (start + lengthArg) : getData().fValues.length; IExpressionDMContext[] contexts = new IExpressionDMContext[end - start]; for (int i = start; i < end && i < getData().fValues.length; i++) { - contexts[i] = new ExpressionDMContext( + contexts[i - start] = new ExpressionDMContext( getSession().getId(), frameCtx, getData().fValues[i]); } rm.setData(contexts); diff --git a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties index 827e75627cc..58974a665b6 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties +++ b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties @@ -29,7 +29,7 @@ providerName=Eclipse CDT updateSiteName=Eclipse CDT Update Site # "description" property - description of the feature -description=Additional features for debug Memory View - traditional rendering, Find/Replace, Import/Export. +description=Additional features for debug Memory View - traditional rendering, floating-point rendering, Find/Replace, Import/Export. # "licenseURL" property - URL of the "Feature License" # do not translate value - just change to point to a locale-specific HTML page diff --git a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml index 27fbf4a0fb8..334d34a8d3b 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml +++ b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml @@ -30,6 +30,13 @@ install-size="0" version="0.0.0" unpack="false"/> + + + + + + + + diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.gitignore b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.gitignore new file mode 100644 index 00000000000..ea8c4bf7f35 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.gitignore @@ -0,0 +1 @@ +/target diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.project b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.project new file mode 100644 index 00000000000..91d6dff85c8 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.project @@ -0,0 +1,28 @@ + + + org.eclipse.cdt.debug.ui.memory.floatingpoint + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.core.prefs b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..40227fe6c21 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,95 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=warning +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.ui.prefs b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..56613a2a55a --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.ui.javadoc=true +org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.pde.prefs b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.pde.prefs new file mode 100644 index 00000000000..cf80c8bc5b8 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.pde.prefs @@ -0,0 +1,32 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=1 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=1 +compilers.p.missing-version-require-bundle=1 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/META-INF/MANIFEST.MF b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..edfa244b84d --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.cdt.debug.ui.memory.floatingpoint;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Localization: plugin +Require-Bundle: org.eclipse.debug.core;bundle-version="3.7.100", + org.eclipse.debug.ui;bundle-version="3.8.1", + org.eclipse.core.runtime;bundle-version="3.8.0", + org.eclipse.ui;bundle-version="3.8.0", + org.eclipse.search;bundle-version="3.8.0", + org.eclipse.cdt.debug.core;bundle-version="7.2.0" +Bundle-ActivationPolicy: lazy +Bundle-Activator: org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPlugin +Bundle-Vendor: %providerName +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: org.eclipse.cdt.debug.ui.memory.floatingpoint diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/about.html b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/about.html new file mode 100644 index 00000000000..d7c511887d6 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/about.html @@ -0,0 +1,24 @@ + + +About + + +

About This Content

+ +

June 22, 2007

+

License

+ +

The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at http://www.eclipse.org/legal/epl-v10.html. +For purposes of the EPL, "Program" will mean the Content.

+ +

If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at http://www.eclipse.org.

+ + \ No newline at end of file diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/build.properties b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/build.properties new file mode 100644 index 00000000000..52d1a28c6b4 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/build.properties @@ -0,0 +1,7 @@ +bin.includes = about.html, \ + META-INF/,\ + plugin.properties,\ + plugin.xml,\ + . +source.. = src/ +src.includes = about.html diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.properties b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.properties new file mode 100644 index 00000000000..fa0cd17819e --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.properties @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2012 Wind River 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 +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Randy Rohrbach (Wind River) - Initial implementation +# IBM Corporation +############################################################################### +# +# Plugin information +# +pluginName = Floating Point Memory Renderer +providerName = Eclipse CDT +renderingType.name = Floating Point +page.name = Floating Point Memory Renderer +# +# Action preference text +# +FPRenderingPreferenceActionName=Floating Point Rendering Preferences ... diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.xml b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.xml new file mode 100644 index 00000000000..0f687ebde07 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/pom.xml b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/pom.xml new file mode 100644 index 00000000000..8b0477e7110 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + org.eclipse.cdt + cdt-parent + 8.2.0-SNAPSHOT + ../../pom.xml + + + org.eclipse.cdt.debug.ui.memory.floatingpoint + 1.0.0.qualifier + eclipse-plugin + diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAbstractPane.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAbstractPane.java new file mode 100644 index 00000000000..c8da9cf9c48 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAbstractPane.java @@ -0,0 +1,903 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Caret; + +public abstract class FPAbstractPane extends Canvas +{ + protected Rendering fRendering; + + // Selection state + + protected boolean fSelectionStarted = false; + protected boolean fSelectionInProgress = false; + protected BigInteger fSelectionStartAddress = null; + protected int fSelectionStartAddressSubPosition; + + // Caret + + protected Caret fCaret = null; + + // Character may not fall on byte boundary + + protected int fSubCellCaretPosition = 0; + protected int fOldSubCellCaretPosition = 0; + protected boolean fCaretEnabled = false; + protected BigInteger fCaretAddress = null; + + // Storage + + protected int fRowCount = 0; + protected boolean fPaneVisible = true; + + // Mouse listener class + + class AbstractPaneMouseListener implements MouseListener + { + @Override + public void mouseUp(MouseEvent me) + { + // Move the caret + + positionCaret(me.x, me.y); + + fCaret.setVisible(true); + + if (fSelectionInProgress && me.button == 1) + endSelection(me.x, me.y); + + fSelectionInProgress = fSelectionStarted = false; + } + + // Mouse down click + + @Override + public void mouseDown(MouseEvent me) + { + // Any click, whether inside this cell or elsewhere, terminates the edit and acts the same as a carriage return would. + + handleCarriageReturn(); + + // Switch focus and check for selection + + FPAbstractPane.this.forceFocus(); + positionCaret(me.x, me.y); + fCaret.setVisible(false); + + if (me.button == 1) + { + // If shift is down and we have an existing start address, append selection + + if ((me.stateMask & SWT.SHIFT) != 0 && fRendering.getSelection().getStart() != null) + { + // If the pane doesn't have a selection start (the selection was created in a different + // pane) then initialize the pane's selection start to the rendering's selection start. + + if (FPAbstractPane.this.fSelectionStartAddress == null) + FPAbstractPane.this.fSelectionStartAddress = fRendering.getSelection().getStart(); + + FPAbstractPane.this.fSelectionStarted = true; + FPAbstractPane.this.appendSelection(me.x, me.y); + + } + else + { + // Start a new selection + + FPAbstractPane.this.startSelection(me.x, me.y); + } + } + + } + + // Double click + + @Override + public void mouseDoubleClick(MouseEvent me) + { + handleMouseDoubleClick(me); + } + } + + // Mouse move listener class + + class AbstractPaneMouseMoveListener implements MouseMoveListener + { + @Override + public void mouseMove(MouseEvent me) + { + if (fSelectionStarted) + { + fSelectionInProgress = true; + appendSelection(me.x, me.y); + } + } + } + + // Focus listener class + + class AbstractPaneFocusListener implements FocusListener + { + @Override + public void focusLost(FocusEvent fe) + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY.equals(store.getString(FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE))) + fRendering.getViewportCache().clearEditBuffer(); + else + fRendering.getViewportCache().writeEditBuffer(); + + // clear the pane local selection start + FPAbstractPane.this.fSelectionStartAddress = null; + } + + @Override + public void focusGained(FocusEvent fe) + { + // Set the floating point edit mode indicator if the user clicked in the Data Pane; otherwise clear it + + if (FPAbstractPane.this instanceof FPDataPane) + fRendering.displayEditModeIndicator(true); + else + fRendering.displayEditModeIndicator(false); + } + } + + // Key listener class + + class AbstractPaneKeyListener implements KeyListener + { + @Override + public void keyPressed(KeyEvent ke) + { + fOldSubCellCaretPosition = fSubCellCaretPosition; + + // Shift + + if ((ke.stateMask & SWT.SHIFT) != 0) + { + switch (ke.keyCode) + { + case SWT.ARROW_RIGHT: + case SWT.ARROW_LEFT: + case SWT.ARROW_UP: + case SWT.ARROW_DOWN: + case SWT.PAGE_DOWN: + case SWT.PAGE_UP: + { + if (fRendering.getSelection().getStart() == null) + fRendering.getSelection().setStart(fCaretAddress.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), fCaretAddress); + break; + } + } + } + + // Arrow, Page, Insert, Escape and standard characters + + if (ke.keyCode == SWT.ARROW_RIGHT) + { + handleRightArrowKey(); + } + else if (ke.keyCode == SWT.ARROW_LEFT || ke.keyCode == SWT.BS) + { + handleLeftArrowKey(); + } + else if (ke.keyCode == SWT.ARROW_DOWN) + { + handleDownArrowKey(); + } + else if (ke.keyCode == SWT.ARROW_UP) + { + handleUpArrowKey(); + } + else if (ke.keyCode == SWT.PAGE_DOWN) + { + handlePageDownKey(); + } + else if (ke.keyCode == SWT.PAGE_UP) + { + handlePageUpKey(); + } + else if (ke.keyCode == SWT.INSERT) + { + handleInsertKey(); + } + else if (ke.keyCode == SWT.ESC) + { + fRendering.getViewportCache().clearEditBuffer(); + handleCTRLZ(); + } + else if (ke.character == '\r') + { + fRendering.getViewportCache().writeEditBuffer(); + handleCarriageReturn(); + } + else if (FPutilities.validEditCharacter(ke.character)) + { + // Check for selection + + if (fRendering.getSelection().hasSelection()) + { + setCaretAddress(fRendering.getSelection().getLow()); + fSubCellCaretPosition = 0; + } + + // Add the chatacter to the cell + + editCell(fCaretAddress, fSubCellCaretPosition, ke.character); + } + + // Control + + if ((ke.stateMask & SWT.CTRL) != 0) + { + // CTRL/Z + + if (ke.keyCode == 'z' || ke.keyCode == 'Z') + handleCTRLZ(); + } + + // Alt + + if ((ke.stateMask & SWT.ALT) != 0) + { + // Future use + } + + // Shift + + if ((ke.stateMask & SWT.SHIFT) != 0) + { + switch (ke.keyCode) + { + case SWT.ARROW_RIGHT: + case SWT.ARROW_LEFT: + case SWT.ARROW_UP: + case SWT.ARROW_DOWN: + case SWT.PAGE_DOWN: + case SWT.PAGE_UP: + fRendering.getSelection().setEnd(fCaretAddress.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), fCaretAddress); + break; + } + } + else if (ke.keyCode != SWT.SHIFT) + { + // If it's a SHIFT key, keep the selection since we may add to it + fRendering.getSelection().clear(); + } + } + + @Override + public void keyReleased(KeyEvent ke) + { + // do nothing + } + } + + class AbstractPanePaintListener implements PaintListener + { + @Override + public void paintControl(PaintEvent pe) + { + FPAbstractPane.this.paint(pe); + } + } + + public FPAbstractPane(Rendering rendering) + { + super(rendering, SWT.DOUBLE_BUFFERED); + + fRendering = rendering; + + try + { + fCaretAddress = rendering.getBigBaseAddress(); + } + catch (Exception e) + { + // do nothing + } + + // pref + + this.setFont(fRendering.getFont()); + + GC gc = new GC(this); + gc.setFont(this.getFont()); + fCaret = new Caret(this, SWT.NONE); + fCaret.setSize(1, gc.stringExtent("|").y); //$NON-NLS-1$ + gc.dispose(); + + this.addPaintListener(createPaintListener()); + this.addMouseListener(createMouseListener()); + this.addMouseMoveListener(createMouseMoveListener()); + this.addKeyListener(createKeyListener()); + this.addFocusListener(createFocusListener()); + } + + // Listener methods + + protected MouseListener createMouseListener() + { + return new AbstractPaneMouseListener(); + } + + protected MouseMoveListener createMouseMoveListener() + { + return new AbstractPaneMouseMoveListener(); + } + + protected FocusListener createFocusListener() + { + return new AbstractPaneFocusListener(); + } + + protected KeyListener createKeyListener() + { + return new AbstractPaneKeyListener(); + } + + protected PaintListener createPaintListener() + { + return new AbstractPanePaintListener(); + } + + // Right arrow + + protected void handleRightArrowKey() + { + fSubCellCaretPosition++; + + if (fSubCellCaretPosition >= getCellCharacterCount()) + { + // We've moved beyond the end of the cell: End the edit to the previous cell. + + handleCarriageReturn(); + + // Move to the next cell; ensure that caret is within the addressable range + + fSubCellCaretPosition = 0; + BigInteger newCaretAddress = fCaretAddress.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + + if (newCaretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) > 0) + fSubCellCaretPosition = getCellCharacterCount(); + else + setCaretAddress(newCaretAddress); + } + + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Left arrow + + protected void handleLeftArrowKey() + { + fSubCellCaretPosition--; + + if (fSubCellCaretPosition < 0) + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Move to the previous cell; ensure that caret is within the addressable range + + fSubCellCaretPosition = getCellCharacterCount() - 1; + BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + + if (newCaretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) < 0) + fSubCellCaretPosition = 0; + else + setCaretAddress(newCaretAddress); + } + + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Down arrow + + protected void handleDownArrowKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount())); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Up arrow + + protected void handleUpArrowKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount())); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Page down + + protected void handlePageDownKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.add(BigInteger.valueOf(fRendering.getAddressableCellsPerRow() * (fRendering.getRowCount() - 1))); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Page up + + protected void handlePageUpKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger.valueOf(fRendering.getAddressableCellsPerRow() * (fRendering.getRowCount() - 1))); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Insert key + + protected void handleInsertKey() + { + // If focus is in the Data Pane, toggle Insert/Overwrite mode and make sure the cell edit + // status line indicator is displayed. Otherwise, make clear the status line indicator. + + if (FPAbstractPane.this instanceof FPDataPane) + { + if (!fRendering.isEditingCell()) fRendering.setInsertMode(!fRendering.insertMode()); + fRendering.displayEditModeIndicator(true); + } + else + fRendering.displayEditModeIndicator(false); + } + + // Double-click + + protected void handleMouseDoubleClick(MouseEvent me) + { + try + { + BigInteger address = getViewportAddress(me.x / getCellWidth(), me.y / getCellHeight()); + + fRendering.getSelection().clear(); + fRendering.getSelection().setStart(address.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), address); + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), address); + } + catch (DebugException de) + { + // do nothing + } + } + + // Carriage return + + protected void handleCarriageReturn() + { + // If we're not editing a cell or there is no string buffer to use, nothing to do: Exit edit mode and return. + + if (!fRendering.isEditingCell() || fRendering.getEditBuffer() == null) + { + fRendering.endCellEditing(); + return; + } + + // Remove all whitespace from the string buffer. + + fRendering.setEditBuffer(new StringBuffer(fRendering.getEditBuffer().toString().trim().replaceAll(" ", ""))); //$NON-NLS-1$ //$NON-NLS-2$ + + // Check the string to make sure it's in valid, acceptable form. + + if (FPutilities.isValidFormat(fRendering.getEditBuffer().toString())) + { + // Valid string: Convert it to a byte array and write the buffer back to memory; + // a subsequent re-draw/paint converts it to normalized scientific notation. + + fRendering.convertAndUpdateCell(fRendering.getCellEditAddress(), fRendering.getEditBuffer().toString()); + } + else + { + // Invalid string: Create the error text and restore the previous value + + String errorText = NLS.bind(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TEXT"), fRendering.getEditBuffer().toString()); //$NON-NLS-1$ + + try + { + fRendering.setEditBuffer(new StringBuffer(fRendering.fDataPane.bytesToSciNotation(fRendering.getBytes(fCaretAddress, fRendering.getFPDataType().getByteLength())))); + } + catch (DebugException e) + { + e.printStackTrace(); + } + + // Put together the pop-up window components and show the user the error + + String statusString = FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_STATUS"); //$NON-NLS-1$ + Status status = new Status(IStatus.ERROR, FPRenderingPlugin.getUniqueIdentifier(), statusString); + FPutilities.popupMessage(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TITLE"), errorText, status); //$NON-NLS-1$ + } + + // Exit cell-edit mode + + fRendering.endCellEditing(); + } + + // CTRL/Z handling + + protected void handleCTRLZ() + { + // CTRL/Z: Replace the cell contents with the original value and exit "number edit mode" + + try + { + fRendering.setEditBuffer(new StringBuffer(fRendering.fDataPane.bytesToSciNotation(fRendering.getBytes(fCaretAddress, fRendering.getFPDataType().getByteLength())))); + } + catch (DebugException e) + { + e.printStackTrace(); + } + + fRendering.endCellEditing(); + } + + // Other getter/setters + + protected boolean isPaneVisible() + { + return fPaneVisible; + } + + protected void setPaneVisible(boolean visible) + { + fPaneVisible = visible; + this.setVisible(visible); + } + + protected int getNumberOfBytesRepresentedByColumn() + { + return fRendering.getCharsPerColumn(); + } + + protected void editCell(BigInteger cellAddress, int subCellPosition, char character) + { + // Do nothing; overridden in subclass FPDataPane + } + + // Set the caret address + + protected void setCaretAddress(BigInteger caretAddress) + { + // Ensure that caret is within the addressable range + + if ((caretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) >= 0) && (caretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) <= 0)) + { + fCaretAddress = caretAddress; + } + else if (caretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) < 0) + { + // Calculate offset from the beginning of the row + + int cellOffset = fCaretAddress.subtract(fRendering.getViewportStartAddress()).intValue(); + int row = cellOffset / (fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter()); + + cellOffset -= row * fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter(); + + fCaretAddress = fRendering.getMemoryBlockStartAddress().add(BigInteger.valueOf(cellOffset / fRendering.getAddressableSize())); + } + else if (caretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) > 0) + { + // Calculate offset from the end of the row + + int cellOffset = fCaretAddress.subtract(fRendering.getViewportEndAddress()).intValue() + 1; + int row = cellOffset / (fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter()); + + cellOffset -= row * fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter(); + + fCaretAddress = fRendering.getMemoryBlockEndAddress().add(BigInteger.valueOf(cellOffset / fRendering.getAddressableSize())); + } + + fRendering.setCaretAddress(fCaretAddress); + } + + protected boolean isOdd(int value) + { + return (value / 2) * 2 == value; + } + + protected void updateTheCaret() + { + try + { + if (fCaretAddress != null) + { + Point cellPosition = getCellLocation(fCaretAddress); + + if (cellPosition != null) + fCaret.setLocation(cellPosition.x + fSubCellCaretPosition * getCellCharacterWidth(), cellPosition.y); + } + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$ + } + } + + // This method scrolls the viewport to insure that the caret is within the viewable area + + protected void ensureCaretWithinViewport() // TODO getAddressableSize() > 1 ? + { + // If the caret is before the viewport start if so, scroll viewport up by several rows + + BigInteger rowCount = BigInteger.valueOf(getRowCount()); + BigInteger rowMemBytes = BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount()); + BigInteger viewableBytes = rowCount.multiply(rowMemBytes); + BigInteger viewableEnd = fRendering.getViewportStartAddress().add(viewableBytes); + + if (fCaretAddress.compareTo(fRendering.getViewportStartAddress()) < 0) + { + fRendering.setViewportStartAddress(fRendering.getViewportStartAddress().subtract(rowMemBytes)); + fRendering.ensureViewportAddressDisplayable(); + fRendering.gotoAddress(fRendering.getViewportStartAddress()); + } + + // If the caret is after the viewport end if so, scroll viewport down by appropriate rows + + else if (fCaretAddress.compareTo(viewableEnd) >= 0) + { + fRendering.setViewportStartAddress(fRendering.getViewportStartAddress().add(rowMemBytes)); + fRendering.ensureViewportAddressDisplayable(); + fRendering.gotoAddress(fRendering.getViewportStartAddress()); + } + + fRendering.setCaretAddress(fCaretAddress); + } + + protected void advanceCursor() + { + handleRightArrowKey(); + } + + protected void positionCaret(int x, int y) + { + // do nothing + } + + protected int getRowCount() + { + return fRowCount; + } + + protected void setRowCount() + { + fRowCount = getBounds().height / getCellHeight(); + } + + protected void settingsChanged() + { + fSubCellCaretPosition = 0; + } + + // Start selection + + protected void startSelection(int x, int y) + { + try + { + BigInteger address = getViewportAddress(x / getCellWidth(), y / getCellHeight()); + + if (address != null) + { + this.fSelectionStartAddress = address; + Point cellPosition = getCellLocation(address); + + if (cellPosition != null) + { + int offset = x - cellPosition.x; + fSelectionStartAddressSubPosition = offset / getCellCharacterWidth(); + } + + fRendering.getSelection().clear(); + fRendering.getSelection().setStart(address.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())), address); + fSelectionStarted = true; + + new CopyAction(fRendering, DND.SELECTION_CLIPBOARD).run(); + } + } + catch (DebugException e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_START_SELECTION"), e); //$NON-NLS-1$ + } + } + + // End selection + + protected void endSelection(int x, int y) + { + appendSelection(x, y); + fSelectionInProgress = false; + } + + protected void appendSelection(int x, int y) + { + try + { + if (this.fSelectionStartAddress == null) return; + + BigInteger address = getViewportAddress(x / getCellWidth(), y / getCellHeight()); + + if (address.compareTo(this.fSelectionStartAddress) == 0) + { + // Sub-cell selection + + Point cellPosition = getCellLocation(address); + int offset = x - cellPosition.x; + int subCellCharacterPosition = offset / getCellCharacterWidth(); + + if (Math.abs(subCellCharacterPosition - this.fSelectionStartAddressSubPosition) > this.getCellCharacterCount() / 4) + { + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf((fRendering.getFPDataType().getByteLength()))), address); + } + else + { + fRendering.getSelection().setEnd(null, null); + } + } + else + { + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())), address); + } + + if (fRendering.getSelection().getEnd() != null) + { + this.fCaretAddress = fRendering.getSelection().getEnd(); + this.fSubCellCaretPosition = 0; + } + + updateTheCaret(); + + new CopyAction(fRendering, DND.SELECTION_CLIPBOARD).run(); + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_APPEND_SELECTION"), e); //$NON-NLS-1$ + } + } + + protected void paint(PaintEvent pe) + { + fRowCount = getBounds().height / getCellHeight(); + + if (fRendering.isDirty()) + { + fRendering.setDirty(false); + fRendering.refresh(); + } + } + + abstract protected BigInteger getViewportAddress(int col, int row) throws DebugException; + + protected Point getCellLocation(BigInteger address) + { + return null; + } + + protected String getCellText(MemoryByte bytes[]) + { + return null; + } + + abstract protected int getCellWidth(); + + abstract protected int getCellCharacterCount(); + + @Override + public void setFont(Font font) + { + super.setFont(font); + fCharacterWidth = -1; + fCellHeight = -1; + fTextHeight = -1; + } + + private int fCellHeight = -1; // called often, cache + + protected int getCellHeight() + { + if (fCellHeight == -1) + { + fCellHeight = getCellTextHeight() + (fRendering.getCellPadding() * 2); + } + + return fCellHeight; + } + + private int fCharacterWidth = -1; // called often, cache + + protected int getCellCharacterWidth() + { + if (fCharacterWidth == -1) + { + GC gc = new GC(this); + gc.setFont(fRendering.getFont()); + fCharacterWidth = gc.getAdvanceWidth('F'); + gc.dispose(); + } + + return fCharacterWidth; + } + + private int fTextHeight = -1; // called often, cache + + protected int getCellTextHeight() + { + if (fTextHeight == -1) + { + GC gc = new GC(this); + gc.setFont(fRendering.getFont()); + FontMetrics fontMetrics = gc.getFontMetrics(); + fTextHeight = fontMetrics.getHeight(); + gc.dispose(); + } + return fTextHeight; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAddressPane.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAddressPane.java new file mode 100644 index 00000000000..3e7ff179772 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAddressPane.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class FPAddressPane extends FPAbstractPane +{ + final int bytesPerColumn = fRendering.getFPDataType().getByteLength(); + + public FPAddressPane(Rendering parent) + { + super(parent); + } + + @Override + protected BigInteger getViewportAddress(int col, int row) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); +// address = address.add(BigInteger.valueOf((row * fRendering.getColumnCount() + col) * fRendering.getAddressesPerColumn())); + address = address.add(BigInteger.valueOf((row * fRendering.getColumnCount() + col) * fRendering.getFPDataType().getByteLength())); + return address; + } + + @Override + protected void appendSelection(int x, int y) + { + try + { + if (this.fSelectionStartAddress == null) return; + + BigInteger address = getViewportAddress(x / getCellWidth(), y / getCellHeight()); + + if (address.compareTo(this.fSelectionStartAddress) == 0) + { + // The address hasn't changed + + fRendering.getSelection().setEnd(null, null); + } + else + { + // The address has changed + + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount())), address); + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_APPEND_SELECTION"), e); //$NON-NLS-1$ + } + } + + @Override + public Point computeSize(int wHint, int hHint) + { + return new Point(getCellWidth() + fRendering.getRenderSpacing(), 100); + } + + @Override + protected int getCellCharacterCount() + { + // Two characters per byte of HEX address + + return fRendering.getAddressBytes() * 2 + 2; // 0x + } + + @Override + protected int getCellWidth() + { + GC gc = new GC(this); + StringBuffer buf = new StringBuffer(); + for(int index = 0; index < getCellCharacterCount(); index++) + buf.append("0"); //$NON-NLS-1$ + int width = gc.textExtent(buf.toString()).x; + gc.dispose(); + return width; + } + + private int getColumnCount() + { + return 0; + } + + private BigInteger getCellAddressAt(int x, int y) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); + + int col = x / getCellWidth(); + int row = y / getCellHeight(); + + if(col > getColumnCount()) + return null; + + address = address.add(BigInteger.valueOf(row * fRendering.getColumnCount() * fRendering.getAddressesPerColumn() / fRendering.getBytesPerCharacter())); + address = address.add(BigInteger.valueOf(col * fRendering.getAddressesPerColumn())); + + return address; + } + + @Override + protected Point getCellLocation(BigInteger cellAddress) + { + try + { + BigInteger address = fRendering.getViewportStartAddress(); + + int cellOffset = cellAddress.subtract(address).intValue(); + + cellOffset *= fRendering.getAddressableSize(); + + if(fRendering.getColumnCount() == 0) // avoid divide by zero + return new Point(0,0); + + int row = cellOffset / (fRendering.getColumnCount() * fRendering.getCharsPerColumn() / fRendering.getBytesPerCharacter()); + cellOffset -= row * fRendering.getColumnCount() * fRendering.getCharsPerColumn() / fRendering.getBytesPerCharacter(); + int col = cellOffset / fRendering.getCharsPerColumn() / fRendering.getBytesPerCharacter(); + + int x = col * getCellWidth() + fRendering.getCellPadding(); + int y = row * getCellHeight() + fRendering.getCellPadding(); + + return new Point(x, y); + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_DETERMINE_CELL_LOCATION"), e); //$NON-NLS-1$ + return null; + } + } + + @Override + protected int getNumberOfBytesRepresentedByColumn() + { + return fRendering.getBytesPerRow(); + } + + @Override + protected void positionCaret(int x, int y) + { + try + { + BigInteger cellAddress = getCellAddressAt(x, y); + if(cellAddress != null) + { + Point cellPosition = getCellLocation(cellAddress); + + int offset = x - cellPosition.x; + int x2 = offset / getCellCharacterWidth(); + + if(x2 >= this.getCellCharacterCount()) + { + cellAddress = cellAddress.add(BigInteger.valueOf(this.getNumberOfBytesRepresentedByColumn())); + x2 = 0; + cellPosition = getCellLocation(cellAddress); + } + + fCaret.setLocation(cellPosition.x + x2 * getCellCharacterWidth(), cellPosition.y); + + this.fCaretAddress = cellAddress; + this.fSubCellCaretPosition = x2; + setCaretAddress(fCaretAddress); + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$ + } + } + + @Override + protected void paint(PaintEvent pe) + { + super.paint(pe); + + GC gc = pe.gc; + + FontMetrics fontMetrics = gc.getFontMetrics(); + int textHeight = fontMetrics.getHeight(); + int cellHeight = textHeight + (fRendering.getCellPadding() * 2); + final int memBytesPerCol = fRendering.getFPDataType().getByteLength(); + + try + { + BigInteger start = fRendering.getViewportStartAddress(); + + for(int index = 0; index < this.getBounds().height / cellHeight; index++) + { + BigInteger memAddress = start.add(BigInteger.valueOf(index * fRendering.getColumnCount() * memBytesPerCol)); + gc.setForeground(fRendering.getFPRendering().getColorText()); + + // Highlight the selected addresses if necessary; otherwise use the standard foreground/background colors + + if (fRendering.getSelection().isSelected(memAddress)) + { + gc.setBackground(fRendering.getFPRendering().getColorSelection()); + gc.fillRectangle(fRendering.getCellPadding() * 2, cellHeight * index, getCellWidth(), cellHeight); + gc.setForeground(fRendering.getFPRendering().getColorBackground()); + } + else + { + gc.setBackground(fRendering.getFPRendering().getColorBackground()); + gc.fillRectangle(fRendering.getCellPadding() * 2, cellHeight * index, getCellWidth(), cellHeight); + // Allow subclass to override this method to do its own coloring + applyCustomColor(gc); + } + + gc.drawText(fRendering.getAddressString(memAddress), + fRendering.getCellPadding() * 2, cellHeight * index + fRendering.getCellPadding()); + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_PAINT"), e); //$NON-NLS-1$ + } + } + + // Allow subclass to override this method to do its own coloring + protected void applyCustomColor(GC gc) + { + gc.setForeground(fRendering.getFPRendering().getColorText()); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDataPane.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDataPane.java new file mode 100644 index 00000000000..2ee7bce1ced --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDataPane.java @@ -0,0 +1,399 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class FPDataPane extends FPAbstractPane +{ + public FPDataPane(Rendering parent) + { + super(parent); + } + + // Returns the representation of the given memory bytes as a scientific notation string + + protected String bytesToSciNotation(FPMemoryByte[] bytes) + { + return fRendering.sciNotationString(bytes, fRendering.getFPDataType(), fRendering.isDisplayLittleEndian()); + } + + // Cell editing: Accumulate text entry characters, replacing or inserting them at the current cursor position + + @Override + protected void editCell(BigInteger cellAddress, int subCellPosition, char character) + { + try + { + // Switch to cell edit mode if not we're not currently in the middle of an edit + + if (!fRendering.isEditingCell()) + { + // Calculate the memory address from the cell address + + BigInteger vpStart = fRendering.getViewportStartAddress(); + BigInteger colChars = BigInteger.valueOf(fRendering.getCharsPerColumn()); + BigInteger dtBytes = BigInteger.valueOf(fRendering.getFPDataType().getByteLength()); + BigInteger memoryAddress = vpStart.add(((cellAddress.subtract(vpStart)).divide(colChars)).multiply(dtBytes)); + + if (!fRendering.insertMode()) + { + // Overstrike/overwrite mode: Enter cell-edit mode; start with the current cell contents. + + fRendering.startCellEditing(cellAddress, memoryAddress, bytesToSciNotation(fRendering.getBytes(cellAddress, fRendering.getFPDataType().getByteLength()))); + } + else + { + // Insert/Replace mode: Clear the current cell contents; start + // with a blank string. Move the caret to the start of the cell. + + fRendering.startCellEditing(cellAddress, memoryAddress, FPutilities.fillString(fRendering.getCharsPerColumn(), ' ')); + + subCellPosition = 0; + Point cellCoordinates = getCellLocation(cellAddress); + positionCaret(cellCoordinates.x, cellCoordinates.y); + fCaret.setVisible(true); + } + } + + // Validate the current string: Only one decimal point and exponent character ('e' or 'E') is allowed. Number + // signs may be present up to two times - once for the number and once for the exponent, and may occur at the + // very beginning of a number or immediately after the exponent character. If an entry violates a rule, do not + // echo the character (implicitly, through replacement and re-paint) and do not advance the cursor. + + String cellString = fRendering.getEditBuffer().toString().toLowerCase(); + + // Check to see if a second decimal point or exponent was entered + + if ((character == '.' && FPutilities.countMatches(cellString, ".") > 0 && cellString.indexOf('.') != subCellPosition) || //$NON-NLS-1$ + (character == 'e' && FPutilities.countMatches(cellString, "e") > 0 && cellString.indexOf('e') != subCellPosition)) //$NON-NLS-1$ + return; + + // Check to see if more than two number signs have been entered + + if ((character == '+' && FPutilities.countMatches(cellString, "+") > 1) || //$NON-NLS-1$ + (character == '-' && FPutilities.countMatches(cellString, "-") > 1)) //$NON-NLS-1$ + return; + + // We've passed the previous checks: Make the character substitution, if possible. + // Advance the cursor as long as we're inside the column. Re-paint the view. + + if (subCellPosition < fRendering.getEditBuffer().length()) + fRendering.getEditBuffer().setCharAt(subCellPosition, character); + + if (subCellPosition < fRendering.getCharsPerColumn()) + advanceCursor(); + + redraw(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + // Returns cell width, in pixels + + @Override + protected int getCellWidth() + { + return getCellCharacterCount() * getCellCharacterWidth() + (fRendering.getCellPadding() * 2); + } + + @Override + protected int getCellCharacterCount() + { + return fRendering.getCharsPerColumn(); + } + + @Override + public Point computeSize(int wHint, int hHint) + { + return new Point(fRendering.getColumnCount() * getCellWidth() + fRendering.getRenderSpacing(), 100); + } + + private BigInteger getCellAddressAt(int x, int y) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); + + int col = x / getCellWidth(); + int row = y / getCellHeight(); + + if (col >= fRendering.getColumnCount()) + return null; + + address = address.add(BigInteger.valueOf(row * fRendering.getColumnCount() * fRendering.getFPDataType().getByteLength())); + address = address.add(BigInteger.valueOf(col * fRendering.getFPDataType().getByteLength())); + + return address; + } + + // Return a Point representing the cell address + + @Override + protected Point getCellLocation(BigInteger cellAddress) + { + try + { + BigInteger address = fRendering.getViewportStartAddress(); + + int cellOffset = cellAddress.subtract(address).intValue(); + cellOffset *= fRendering.getAddressableSize(); + + int row = cellOffset / (fRendering.getColumnCount() * fRendering.getFPDataType().getByteLength()); + cellOffset -= row * fRendering.getColumnCount() * fRendering.getFPDataType().getByteLength(); + int col = cellOffset / fRendering.getFPDataType().getByteLength(); + + int x = col * getCellWidth() + fRendering.getCellPadding(); + int y = row * getCellHeight() + fRendering.getCellPadding(); + + return new Point(x, y); + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_DETERMINE_CELL_LOCATION"), e); //$NON-NLS-1$ + return null; + } + } + + @Override + protected void positionCaret(int x, int y) + { + try + { + BigInteger cellAddress = getCellAddressAt(x, y); + + if (cellAddress != null) + { + Point cellPosition = getCellLocation(cellAddress); + int offset = x - cellPosition.x; + int subCellCharacterPosition = offset / getCellCharacterWidth(); + + if (subCellCharacterPosition == this.getCellCharacterCount()) + { + cellAddress = cellAddress.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + subCellCharacterPosition = 0; + cellPosition = getCellLocation(cellAddress); + } + + fCaret.setLocation(cellPosition.x + subCellCharacterPosition * getCellCharacterWidth(), cellPosition.y); + + this.fCaretAddress = cellAddress; + this.fSubCellCaretPosition = subCellCharacterPosition; + setCaretAddress(fCaretAddress); + } + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$ + } + } + + @Override + protected BigInteger getViewportAddress(int col, int row) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); + address = address.add(BigInteger.valueOf((row * fRendering.getColumnCount() + col) * fRendering.getFPDataType().getByteLength())); + + return address; + } + + @Override + protected void paint(PaintEvent pe) + { + super.paint(pe); + // Allow subclasses to override this method to do their own painting + doPaintData(pe); + } + + // Display text in the cell + + + protected void doPaintData(PaintEvent pe) + { + GC gc = pe.gc; + gc.setFont(fRendering.getFont()); + + int cellHeight = getCellHeight(); + int cellWidth = getCellWidth(); + int boundsHeight = this.getBounds().height; + int columns = fRendering.getColumnCount(); + + int cellX = 0; + int cellY = 0; + + String displayString = FPutilities.fillString(fRendering.getCharsPerColumn(), '.'); + + try + { + BigInteger vpStart = fRendering.getViewportStartAddress(); + BigInteger cellStartAddr = vpStart; + BigInteger memoryAddr = vpStart; + BigInteger cellEndAddr; + + for(int row = 0; row < boundsHeight / cellHeight; row++) + { + for (int column = 0; column < columns; column++) + { + // Set alternating colors for every other column and display the text + // FIXME: There is duplicate code in applyCustomColor() in this class + + if (isOdd(column)) + gc.setForeground(fRendering.getFPRendering().getColorText()); + else + gc.setForeground(fRendering.getFPRendering().getColorTextAlternate()); + + // Calculate the cell starting address and X/Y coordinates + + cellStartAddr = vpStart.add(BigInteger.valueOf((row * fRendering.getColumnCount() + column) * fRendering.getFPDataType().getByteLength())); + cellEndAddr = cellStartAddr.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength()).subtract(BigInteger.ONE)); + + cellX = (cellWidth * column) + fRendering.getCellPadding(); + cellY = (cellHeight * row ) + fRendering.getCellPadding(); + + // Cell editing: If we're in edit mode, change the cell color and then set the + // edit buffer as the string to display. Otherwise, just use the memory contents. + + if (fRendering.isEditingCell() && cellStartAddr.equals(fRendering.getCellEditAddress())) + { + gc.setForeground(fRendering.getFPRendering().getColorEdit()); + FPMemoryByte[] memoryBytes = fRendering.getBytes(cellStartAddr, fRendering.getFPDataType().getByteLength()); + for (FPMemoryByte memoryByte : memoryBytes) + memoryByte.setEdited(true); + applyCustomColor(gc, memoryBytes, column); + displayString = fRendering.getEditBuffer().toString(); + } + else + displayString = bytesToSciNotation(fRendering.getBytes(memoryAddr, fRendering.getFPDataType().getByteLength())); + + // Cell selection + + if (fRendering.getSelection().isSelected(cellStartAddr)) + { + gc.setBackground(fRendering.getFPRendering().getColorSelection()); + gc.fillRectangle(cellX, row * cellHeight, cellWidth, cellHeight); + gc.setForeground(fRendering.getFPRendering().getColorBackground()); + } + else + { + gc.setBackground(fRendering.getFPRendering().getColorBackground()); + gc.fillRectangle(cellX, row * cellHeight, cellWidth, cellHeight); + // Allow subclasses to override this method to do their own coloring + applyCustomColor(gc, fRendering.getBytes(cellStartAddr, fRendering.getFPDataType().getByteLength()), column); + } + + gc.drawText(displayString, cellX, cellY); + + // Move the caret if appropriate + + if (fCaretEnabled) + { + if(cellStartAddr.compareTo(fCaretAddress) <= 0 && cellEndAddr.compareTo(fCaretAddress) >= 0) + { + int x = cellWidth * column + fRendering.getCellPadding() + fSubCellCaretPosition * this.getCellCharacterWidth(); + int y = cellHeight * row + fRendering.getCellPadding(); + fCaret.setLocation(x, y); + } + } + + // For debugging + + if (fRendering.isDebug()) + gc.drawRectangle(cellX, cellY, cellWidth, cellHeight); + + // Increment the memory address by the length of the data type + + memoryAddr = memoryAddr.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + } + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_PAINT"), e); //$NON-NLS-1$ + e.printStackTrace(); + } + } + + // Allow subclasses to override this method to do their own coloring + + protected void applyCustomColor(GC gc, FPMemoryByte bytes[], int col) + { + // Check to see if any byte has been changed and whether we're actually in edit mode + + boolean anyByteEditing = false; + + for (int n = 0; n < bytes.length && !anyByteEditing; n++) + if (bytes[n].isEdited()) anyByteEditing = true; + + anyByteEditing = anyByteEditing && fRendering.isEditingCell(); + + // Even/odd column coloring + + if (isOdd(col)) + gc.setForeground(fRendering.getFPRendering().getColorText()); + else + gc.setForeground(fRendering.getFPRendering().getColorTextAlternate()); + + // Background + + gc.setBackground(fRendering.getFPRendering().getColorBackground()); + + if (anyByteEditing) + { + gc.setForeground(fRendering.getFPRendering().getColorEdit()); + } + else + { + boolean isColored = false; + + for (int index = 0; index < fRendering.getHistoryDepth() && !isColored; index++) + { + // TODO consider adding finer granularity? + + for (int n = 0; n < bytes.length; n++) + { + if (bytes[n].isChanged(index)) + { + if (index == 0) + gc.setForeground(fRendering.getFPRendering().getColorsChanged()[index]); + else + gc.setBackground(fRendering.getFPRendering().getColorsChanged()[index]); + + isColored = true; + break; + } + } + } + } + } + + // Draw a box around the specified cell + + public void highCellBox(BigInteger memoryAddress) + { +// if (fRendering.isDebug()) +// gc.drawRectangle(cellX, cellY, cellWidth, cellHeight); + } + + // Clear the box around the specified cell + + public void clearCellBox(BigInteger memoryAddress) + { + + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDisplayCharacteristics.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDisplayCharacteristics.java new file mode 100644 index 00000000000..4fc155ee9a5 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDisplayCharacteristics.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.Endian; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.Justification; + +public class FPDisplayCharacteristics +{ + private FPDataType dataType; + private Endian endian; + private int displayedPrecision; + private Justification justification; + + // Constructors + + FPDisplayCharacteristics() + { + // Default values + + this.dataType = FPDataType.FLOAT; + this.endian = Endian.LITTLE; + this.displayedPrecision = FPDataType.FLOAT.getDisplayedPrecision(); + this.justification = Justification.LEFT; + } + + public FPDisplayCharacteristics(FPDataType dataType, Endian endian, Justification justification) + { + this.dataType = dataType; + this.endian = endian; + this.justification = justification; + } + + // Getters and Setters + + public FPDataType getDataType() + { + return dataType; + } + + public void setDataType(FPDataType dataType) + { + this.dataType = dataType; + } + + public Endian getEndian() + { + return endian; + } + + public void setEndian(Endian endian) + { + this.endian = endian; + } + + public int getDisplayedPrecision() + { + return displayedPrecision; + } + + public void setDisplayedPrecision(int displayedPrecision) + { + this.displayedPrecision = displayedPrecision; + } + + public Justification getJustification() + { + return justification; + } + + public void setJustification(Justification justification) + { + this.justification = justification; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemoryByte.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemoryByte.java new file mode 100644 index 00000000000..7810d41023f --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemoryByte.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +public interface FPIMemoryByte +{ + public boolean isEdited(); + public void setEdited(boolean edited); +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemorySelection.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemorySelection.java new file mode 100644 index 00000000000..aa3767917ca --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemorySelection.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +public interface FPIMemorySelection +{ + public boolean hasSelection(); + public boolean isSelected(BigInteger address); + public BigInteger getStart(); + public BigInteger getEnd(); + public BigInteger getStartLow(); + public void setStart(BigInteger high, BigInteger low); + public void setEnd(BigInteger high, BigInteger low); + public BigInteger getHigh(); + public BigInteger getLow(); + public void clear(); +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIViewportCache.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIViewportCache.java new file mode 100644 index 00000000000..41846f275b7 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIViewportCache.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.debug.core.DebugException; + +public interface FPIViewportCache { + + public void dispose(); + public void refresh(); + public FPMemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException; + public void archiveDeltas(); + public void setEditedValue(BigInteger address, FPMemoryByte[] bytes); + public void clearEditBuffer(); + public void writeEditBuffer(); + public boolean containsEditedCell(BigInteger address); + // private void queueRequest(BigInteger startAddress, BigInteger endAddress); +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPMemoryByte.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPMemoryByte.java new file mode 100644 index 00000000000..9c5a18ede5a --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPMemoryByte.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.debug.core.model.MemoryByte; + +public class FPMemoryByte extends MemoryByte implements FPIMemoryByte +{ + private boolean isEdited = false; + + private boolean[] changeHistory = new boolean[0]; + + public FPMemoryByte() + { + super(); + } + + public FPMemoryByte(byte byteValue) + { + super(byteValue); + } + + public FPMemoryByte(byte byteValue, byte byteFlags) + { + super(byteValue, byteFlags); + } + + @Override + public boolean isEdited() + { + return isEdited; + } + + @Override + public void setEdited(boolean edited) + { + isEdited = edited; + } + + public boolean isChanged(int historyDepth) + { + return changeHistory.length > historyDepth && changeHistory[historyDepth]; + } + + public void setChanged(int historyDepth, boolean changed) + { + if(historyDepth >= changeHistory.length) + { + boolean newChangeHistory[] = new boolean[historyDepth + 1]; + System.arraycopy(changeHistory, 0, newChangeHistory, 0, changeHistory.length); + changeHistory = newChangeHistory; + } + + changeHistory[historyDepth] = changed; + + if(historyDepth == 0) + this.setChanged(changed); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPPreferenceConstants.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPPreferenceConstants.java new file mode 100644 index 00000000000..661837597d5 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPPreferenceConstants.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.jface.preference.IPreferenceStore; + + +public class FPPreferenceConstants +{ + private FPPreferenceConstants() + { + // Prevent subclassing or instantiation + } + + /** + * Initialize preference default values. + * + * @param store + */ + public static void initializeDefaults(IPreferenceStore store) + { + // Set default values + + store.setDefault(IFPRConstants.ENDIAN_KEY, -1); // -1 = No default set + store.setDefault(IFPRConstants.DATATYPE_KEY, FPDataType.FLOAT.getValue()); + store.setDefault(IFPRConstants.FLOAT_DISP_KEY, 8); + store.setDefault(IFPRConstants.DOUBLE_DISP_KEY, 8); + store.setDefault(IFPRConstants.COLUMN_COUNT_KEY, Rendering.COLUMNS_AUTO_SIZE_TO_FIT); + store.setDefault(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_ALWAYS); + } + + public static class Initializer extends AbstractPreferenceInitializer + { + @Override + public void initializeDefaultPreferences() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + initializeDefaults(store); + } + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRendering.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRendering.java new file mode 100644 index 00000000000..cd4ebafc542 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRendering.java @@ -0,0 +1,1494 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.lang.reflect.Method; +import java.math.BigInteger; + +import org.eclipse.cdt.debug.core.model.provisional.IMemoryRenderingViewportProvider; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.Endian; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.debug.internal.ui.DebugPluginImages; +import org.eclipse.debug.internal.ui.DebugUIMessages; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.memory.IMemoryBlockConnection; +import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.memory.AbstractMemoryRendering; +import org.eclipse.debug.ui.memory.AbstractTableRendering; +import org.eclipse.debug.ui.memory.IMemoryRendering; +import org.eclipse.debug.ui.memory.IMemoryRenderingContainer; +import org.eclipse.debug.ui.memory.IMemoryRenderingSite; +import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering; +import org.eclipse.debug.ui.memory.IResettableMemoryRendering; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.progress.UIJob; + + +/** + * A memory rendering displaying memory in a floating point memory view look and + * feel, optimized for minimal IO traffic. + *

+ * requirements of the debug model implementation: - An IMemoryBlockExtension is + * required. + * + * Since it is not possible to size the memory block to match the size of the + * viewport, memory block change notification is not useful. Such events are + * ignored by this rendering. + */ + +@SuppressWarnings({ "restriction" }) +public class FPRendering extends AbstractMemoryRendering + implements IRepositionableMemoryRendering, IResettableMemoryRendering, IMemoryRenderingViewportProvider, IModelChangedListener +{ + protected Rendering fRendering; + protected Action actionDisplayBigEndian; + protected Action actionDisplayLittleEndian; + protected Action actionDisplayFloatingPoint; + + private IWorkbenchAdapter fWorkbenchAdapter; + private IMemoryBlockConnection fConnection; + + private final static int MAX_MENU_COLUMN_COUNT = 8; + + Action actionFloatingPoint32 = null; + Action actionFloatingPoint64 = null; + + Action actionDisplay4Digits = null; + Action actionDisplay8Digits = null; + Action actionDisplay16Digits = null; + + // Constructor + + public FPRendering(String id) + { + super(id); + + JFaceResources.getFontRegistry().addListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + if (event.getProperty().equals(IInternalDebugUIConstants.FONT_NAME)) + { + FPRendering.this.fRendering.handleFontPreferenceChange(JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME)); + } + } + }); + + this.addPropertyChangeListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + IMemoryRendering sourceRendering = (IMemoryRendering) event.getSource(); + if (!sourceRendering.getMemoryBlock().equals(getMemoryBlock())) + return; + + Object address = event.getNewValue(); + + if (event.getProperty().equals(AbstractTableRendering.PROPERTY_SELECTED_ADDRESS) && address instanceof BigInteger) + { + FPRendering.this.fRendering.ensureVisible((BigInteger) address); + } + } + }); + + FPRenderingPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + disposeColors(); + allocateColors(); + applyPreferences(); + } + }); + + DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + if (event.getProperty().equals(IDebugUIConstants.PREF_PADDED_STR)) + { + if (FPRendering.this.fRendering != null) + { + setRenderingPadding((String) event.getNewValue()); + FPRendering.this.fRendering.redrawPanes(); + } + } + } + }); + } + + static int paddingCounter = 0; + + void setRenderingPadding(String padding) + { + if (padding == null || padding.length() == 0) padding = " "; //$NON-NLS-1$ + FPRendering.this.fRendering.setPaddingString(padding); + } + + protected void logError(String message, Exception e) + { + Status status = new Status(IStatus.ERROR, getRenderingId(), DebugException.INTERNAL_ERROR, message, e); + FPRenderingPlugin.getDefault().getLog().log(status); + } + + BigInteger fBigBaseAddress; // Memory base address + private BigInteger fStartAddress; // Starting address + private BigInteger fEndAddress; // Ending address + private int fAddressableSize; // Memory block size + private int fAddressSize; // Size of address + + /* + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta, org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy) + */ + @Override + public void modelChanged(IModelDelta delta, IModelProxy proxy) + { + /* + * The event model in the traditional renderer is written to expect a suspend first + * which will cause it to save its current data set away in an archive. Then when + * the state change comes through it will compare and refresh showing a difference. + */ + int flags = delta.getFlags(); + if ( ( flags & IModelDelta.STATE ) != 0 ) { + fRendering.handleSuspend(false); + } + + fRendering.handleChange(); + } + + /* + * We use the model proxy which is supplied by the TCF implementation to provide the knowledge of memory + * change notifications. The older backends ( the reference model, Wind River Systems Inc. ) are written + * to generate the Debug Model events. TCF follows the "ModelDelta/IModelProxy" implementation that the + * platform renderers use. So this implementation acts as a shim. If the older Debug Events come in then + * fine. If the newer model deltas come in fine also. + */ + IModelProxy fModel; + + @Override + public void dispose() + { + /* + * We use the UI dispatch thread to protect the proxy information. Even though I believe the + * dispose routine is always called in the UI dispatch thread. I am going to make sure. + */ + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if ( fModel != null ) { + fModel.removeModelChangedListener(FPRendering.this); + fModel.dispose(); + } + }}); + + if(this.fRendering != null) + this.fRendering.dispose(); + disposeColors(); + super.dispose(); + } + + @Override + public void init(final IMemoryRenderingContainer container, final IMemoryBlock block) + { + super.init(container, block); + + /* + * Working with the model proxy must be done on the UI dispatch thread. + */ + final IModelProxyFactory factory = (IModelProxyFactory) DebugPlugin.getAdapter(block, IModelProxyFactory.class ); + if ( factory != null ) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + + /* + * The asynchronous model assumes we have an asynchronous viewer that has an IPresentationContext + * to represent it. The Platform memory subsystem provides a way to create one without a viewewr. + */ + IMemoryRenderingSite site = container.getMemoryRenderingSite(); + MemoryViewPresentationContext context = new MemoryViewPresentationContext(site, container, FPRendering.this); + + /* + * Get a new proxy and perform the initialization sequence so we are known the + * the model provider. + */ + fModel = factory.createModelProxy(block, context); + fModel.installed(null); + fModel.addModelChangedListener(FPRendering.this); + + }}); + } + + try + { + fBigBaseAddress = ((IMemoryBlockExtension) block).getBigBaseAddress(); + } + catch (DebugException de) + { + logError(FPRenderingMessages.getString("FPRendering.FAILURE_RETRIEVE_BASE_ADDRESS"), de); //$NON-NLS-1$ + } + + try + { + fAddressableSize = ((IMemoryBlockExtension) block).getAddressableSize(); + } + catch (DebugException de) + { + fAddressableSize = 1; + } + + try + { + fStartAddress = ((IMemoryBlockExtension) block).getMemoryBlockStartAddress(); + } + catch (DebugException de) + { + fStartAddress = null; + logError(FPRenderingMessages.getString("FPRendering.FAILURE_RETRIEVE_START_ADDRESS"), de); //$NON-NLS-1$ + } + + try + { + fAddressSize = ((IMemoryBlockExtension) block).getAddressSize(); + } + catch (DebugException e) + { + fAddressSize = 0; + } + + BigInteger endAddress; + try + { + endAddress = ((IMemoryBlockExtension) block).getMemoryBlockEndAddress(); + if (endAddress != null) + fEndAddress = endAddress; + } + catch (DebugException e) + { + fEndAddress = null; + } + + if (fEndAddress == null) + { + int addressSize; + try + { + addressSize = ((IMemoryBlockExtension) block).getAddressSize(); + } + catch (DebugException e) + { + addressSize = 4; + } + + endAddress = BigInteger.valueOf(2); + endAddress = endAddress.pow(addressSize * 8); + endAddress = endAddress.subtract(BigInteger.ONE); + fEndAddress = endAddress; + } + + // default to MAX_VALUE if we have trouble getting the end address + if (fEndAddress == null) + fEndAddress = BigInteger.valueOf(Integer.MAX_VALUE); + } + + public BigInteger getBigBaseAddress() + { + return fBigBaseAddress; + } + + public BigInteger getMemoryBlockStartAddress() + { + return fStartAddress; + } + + public BigInteger getMemoryBlockEndAddress() + { + return fEndAddress; + } + + public int getAddressableSize() + { + return fAddressableSize; + } + + public int getAddressSize() + { + return fAddressSize; + } + + @Override + public Control createControl(Composite parent) + { + allocateColors(); + + this.fRendering = new Rendering(parent, this); + + applyPreferences(); + + createMenus(); + + if (actionFloatingPoint32.isChecked()) + actionDisplay16Digits.setEnabled(false); + else + actionDisplay16Digits.setEnabled(true); + + return this.fRendering; + } + + /* + * We are duplicating the reference to the GoToAddress command because it is private in the platform. + * This is not going to change at this point so just live with it. + */ + private static final String ID_GO_TO_ADDRESS_COMMAND = "org.eclipse.debug.ui.command.gotoaddress"; //$NON-NLS-1$ + private AbstractHandler fGoToAddressHandler; + + @Override + public void activated() + { + super.activated(); + + IWorkbench workbench = PlatformUI.getWorkbench(); + ICommandService commandSupport = (ICommandService) workbench.getAdapter(ICommandService.class); + + if (commandSupport != null) + { + Command gotoCommand = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND); + + if (fGoToAddressHandler == null) + { + fGoToAddressHandler = new AbstractHandler() + { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException + { + return null; + } + }; + } + gotoCommand.setHandler(fGoToAddressHandler); + } + } + + @Override + public void deactivated() + { + IWorkbench workbench = PlatformUI.getWorkbench(); + ICommandService commandSupport = (ICommandService) workbench.getAdapter(ICommandService.class); + + if (commandSupport != null) + { + // remove handler + Command command = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND); + command.setHandler(null); + } + + super.deactivated(); + } + + public void setSelection(BigInteger start, BigInteger end) + { + fRendering.getSelection().setStart(start, start); + fRendering.getSelection().setEnd(end, end); + } + + public void gotoAddress(final BigInteger address) + { + this.fRendering.gotoAddress(address); + } + + public void updateRenderingLabels() + { + UIJob job = new UIJob("updateLabels") { //$NON-NLS-1$ + @SuppressWarnings("synthetic-access") + @Override + public IStatus runInUIThread(IProgressMonitor monitor) + { + + // Update tab labels + String fLabel = getLabel(); + firePropertyChangedEvent(new PropertyChangeEvent(FPRendering.this, IBasicPropertyConstants.P_TEXT, null, fLabel)); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(); + } + + private Color colorBackground; + private Color colorChanged; + private Color colorsChanged[] = null; + private Color colorEdit; + private Color colorSelection; + private Color colorText; + private Color colorTextAlternate; + + public void allocateColors() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + colorBackground = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_BACKGROUND)); + colorChanged = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_CHANGED)); + colorEdit = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_EDIT)); + colorSelection = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_SELECTION)); + colorText = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_TEXT)); + + // alternate cell color + Color textColor = getColorText(); + int red = textColor.getRed(); + int green = textColor.getGreen(); + int blue = textColor.getBlue(); + + float scale = store.getInt(FPRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS); + + red = (int) Math.min(red + ((255 - red) / 10) * scale, 255); + green = (int) Math.min(green + ((255 - green) / 10) * scale, 255); + blue = (int) Math.min(blue + ((255 - blue) / 10) * scale, 255); + + colorTextAlternate = new Color(Display.getDefault(), new RGB(red, green, blue)); + } + + public void disposeColors() + { + if (colorBackground != null) colorBackground.dispose(); + colorBackground = null; + + if (colorChanged != null) colorChanged.dispose(); + colorChanged = null; + + if (colorEdit != null) colorEdit.dispose(); + colorEdit = null; + + if (colorSelection != null) colorSelection.dispose(); + colorSelection = null; + + if (colorText != null) colorText.dispose(); + colorText = null; + + if (colorTextAlternate != null) colorTextAlternate.dispose(); + colorTextAlternate = null; + + disposeChangedColors(); + } + + public void applyPreferences() + { + if (fRendering != null && !fRendering.isDisposed()) + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + fRendering.setHistoryDepth(store.getInt(FPRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT)); + fRendering.setBackground(getColorBackground()); + + FPAbstractPane panes[] = fRendering.getRenderingPanes(); + for (int index = 0; index < panes.length; index++) + panes[index].setBackground(getColorBackground()); + + setRenderingPadding(FPRenderingPlugin.getDefault().getPreferenceStore().getString(IDebugUIConstants.PREF_PADDED_STR)); + + fRendering.redrawPanes(); + } + } + + public Color getColorBackground() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (store.getBoolean(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND)) + return Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + + return colorBackground; + } + + public Color getColorChanged() + { + return colorChanged; + } + + private void disposeChangedColors() + { + if (colorsChanged != null) + for (int index = 0; index < colorsChanged.length; index++) + colorsChanged[index].dispose(); + colorsChanged = null; + } + + public Color[] getColorsChanged() + { + if (colorsChanged != null && colorsChanged.length != fRendering.getHistoryDepth()) + { + disposeChangedColors(); + } + + if (colorsChanged == null) + { + colorsChanged = new Color[fRendering.getHistoryDepth()]; + colorsChanged[0] = colorChanged; + int shades = fRendering.getHistoryDepth() + 4; + int red = (255 - colorChanged.getRed()) / shades; + int green = (255 - colorChanged.getGreen()) / shades; + int blue = (255 - colorChanged.getBlue()) / shades; + for (int index = 1; index < fRendering.getHistoryDepth(); index++) + { + colorsChanged[index] = new Color(colorChanged.getDevice(), colorChanged.getRed() + ((shades - index) * red), colorChanged.getGreen() + + ((shades - index) * green), colorChanged.getBlue() + ((shades - index) * blue)); + } + } + + return colorsChanged; + } + + public Color getColorEdit() + { + return colorEdit; + } + + public Color getColorSelection() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (store.getBoolean(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION)) + return Display.getDefault().getSystemColor(SWT.COLOR_LIST_SELECTION); + + return colorSelection; + } + + public Color getColorText() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (store.getBoolean(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT)) + return Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND); + + return colorText; + } + + public Color getColorTextAlternate() + { + return colorTextAlternate; + } + + // Menu creation + + public void createMenus() + { + // Add the menu to each of the rendering panes + + Control[] renderingControls = this.fRendering.getRenderingPanes(); + + for (int index = 0; index < renderingControls.length; index++) + super.createPopupMenu(renderingControls[index]); + + super.createPopupMenu(this.fRendering); + + // Copy + + final Action copyAction = new CopyAction(this.fRendering); + + // Copy address + + final Action copyAddressAction = new Action(FPRenderingMessages.getString("FPRendering.COPY_ADDRESS")) //$NON-NLS-1$ + { + @Override + public void run() + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + FPRendering.this.fRendering.copyAddressToClipboard(); + } + }); + } + }; + + // Reset to base address + + final Action gotoBaseAddressAction = new Action(FPRenderingMessages.getString("FPRendering.RESET_TO_BASE_ADDRESS")) //$NON-NLS-1$ + { + @Override + public void run() + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + FPRendering.this.fRendering.gotoAddress(FPRendering.this.fRendering.fBaseAddress); + } + }); + } + }; + + // Refresh + + final Action refreshAction = new Action(FPRenderingMessages.getString("FPRendering.REFRESH")) //$NON-NLS-1$ + { + @Override + public void run() + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + // For compatibility with DSF update modes (hopefully this will either be replaced + // by an enhanced platform interface or the caching will move out of the data layer) + + try + { + Method m = fRendering.getMemoryBlock().getClass().getMethod("clearCache", new Class[0]); //$NON-NLS-1$ + if (m != null) + m.invoke(fRendering.getMemoryBlock(), new Object[0]); + } + catch (Exception e) + { + } + + FPRendering.this.fRendering.refresh(); + } + }); + } + }; + + // Little Endian + + actionDisplayLittleEndian = new Action(FPRenderingMessages.getString("FPRendering.ENDIAN_LITTLE"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayLittleEndian(true); + setRMCvalue(IFPRConstants.ENDIAN_KEY, Endian.LITTLE.getValue()); + } + }; + + // Big Endian + + actionDisplayBigEndian = new Action(FPRenderingMessages.getString("FPRendering.ENDIAN_BIG"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayLittleEndian(false); + setRMCvalue(IFPRConstants.ENDIAN_KEY, Endian.BIG.getValue()); + } + }; + + // Endian settings + + int endian = getRMCvalue(IFPRConstants.ENDIAN_KEY); + + endian = endian != -1 ? endian : (fRendering.isDisplayLittleEndian() ? Endian.LITTLE.getValue() : Endian.BIG.getValue()); + boolean le = (endian == Endian.LITTLE.getValue()); + + fRendering.setDisplayLittleEndian(le); + actionDisplayLittleEndian.setChecked(le); + actionDisplayBigEndian.setChecked(!le); + + // Float + + boolean dtFloat = getRMCvalue(IFPRConstants.DATATYPE_KEY) == FPDataType.FLOAT.getValue(); + this.fRendering.setFPDataType(dtFloat ? FPDataType.FLOAT : FPDataType.DOUBLE); + + actionFloatingPoint32 = new Action(FPRenderingMessages.getString("FPRendering.FLOATING_POINT_32"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayedPrecision(getRMCvalue(IFPRConstants.FLOAT_DISP_KEY)); + fRendering.setFPDataType(FPDataType.FLOAT); + setRMCvalue(IFPRConstants.DATATYPE_KEY, FPDataType.FLOAT.getValue()); + setSelections(); + } + }; + + // Double + + actionFloatingPoint64 = new Action(FPRenderingMessages.getString("FPRendering.FLOATING_POINT_64"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayedPrecision(getRMCvalue(IFPRConstants.DOUBLE_DISP_KEY)); + fRendering.setFPDataType(FPDataType.DOUBLE); + setRMCvalue(IFPRConstants.DATATYPE_KEY, FPDataType.DOUBLE.getValue()); + setSelections(); + } + }; + + // Displayed precision: 4 digits + + int savedPrecision = getDisplayedPrecision(); + + actionDisplay4Digits = new Action(FPRenderingMessages.getString("FPRendering.DISPLAYED_PRECISION_4"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setDisplayedPrecision(4); + setDisplayedPrecision(4); + } + }; + + if (savedPrecision == 4) + { + FPRendering.this.fRendering.setDisplayedPrecision(4); + actionDisplay4Digits.setChecked(savedPrecision == 4); + } + + // Displayed precision: 8 digits + + actionDisplay8Digits = new Action(FPRenderingMessages.getString("FPRendering.DISPLAYED_PRECISION_8"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setDisplayedPrecision(8); + setDisplayedPrecision(8); + } + }; + + if (savedPrecision == 8) + { + FPRendering.this.fRendering.setDisplayedPrecision(8); + actionDisplay8Digits.setChecked(savedPrecision == 8); + } + + // Displayed precision: 16 digits (doubles only) + + actionDisplay16Digits = new Action(FPRenderingMessages.getString("FPRendering.DISPLAYED_PRECISION_16"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setDisplayedPrecision(16); + setDisplayedPrecision(16); + } + }; + + if (savedPrecision == 16) + { + FPRendering.this.fRendering.setDisplayedPrecision(16); + actionDisplay16Digits.setChecked(savedPrecision == 16); + } + + // Set RMC selections based on datatype and displayed precision settings in effect + + setSelections(); + + // Columns + + int savedColumnCount = getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY); + + final Action displayColumnCountAuto = new Action(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT_AUTO"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setColumnsSetting(Rendering.COLUMNS_AUTO_SIZE_TO_FIT); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, Rendering.COLUMNS_AUTO_SIZE_TO_FIT); + } + }; + + boolean autoMode = savedColumnCount == Rendering.COLUMNS_AUTO_SIZE_TO_FIT; + displayColumnCountAuto.setChecked(autoMode); + + final Action[] displayColumnCounts = new Action[MAX_MENU_COLUMN_COUNT]; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT; index++, j *= 2) + { + final int finali = j; + displayColumnCounts[index] = new Action(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT_" + finali), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setColumnsSetting(finali); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, finali); + } + }; + displayColumnCounts[index].setChecked(fRendering.getColumnsSetting() == finali); + } + + // Set/clear column count selections as appropriate + + int countValue = getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY); + + for (int index = 0; index < MAX_MENU_COLUMN_COUNT; index++) + displayColumnCounts[index].setChecked(countValue != Rendering.COLUMNS_AUTO_SIZE_TO_FIT && (countValue == (1 << index))); + + fRendering.setColumnsSetting(getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY)); + + final Action displayColumnCountCustomValue = new Action("", IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + } + }; + + final Action displayColumnCountCustom = new Action(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT_CUSTOM"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + InputDialog inputDialog = new InputDialog + ( + fRendering.getShell(), "Set Column Count", "Please enter column count", "", new IInputValidator() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + { + @Override + public String isValid(String input) + { + try + { + int index = Integer.parseInt(input); + + if (index <= 0) + return "Please enter a positive integer"; //$NON-NLS-1$ + + if (index > 200) + return "Please enter a positive integer not greater than 200"; //$NON-NLS-1$ + } + catch (NumberFormatException x) + { + return "Please enter a positive integer"; //$NON-NLS-1$ + } + + return null; + } + } + ); + + if (inputDialog.open() != Window.OK) + { + this.setChecked(false); + int currentColumnSetting = FPRendering.this.fRendering.getColumnsSetting(); + + if (currentColumnSetting == Rendering.COLUMNS_AUTO_SIZE_TO_FIT) + displayColumnCountAuto.setChecked(true); + else + { + boolean currentCountIsCustom = true; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT && currentCountIsCustom; index++, j *= 2) + { + currentCountIsCustom = (j != fRendering.getColumnsSetting()); + if (j == fRendering.getColumnsSetting()) + displayColumnCounts[index].setChecked(true); + } + + if (currentCountIsCustom) + displayColumnCountCustomValue.setChecked(true); + } + + return; + } + + int newColumnCount = -1; + + try + { + newColumnCount = Integer.parseInt(inputDialog.getValue()); + } + catch (NumberFormatException x) + { + assert false; + } + + boolean customIsOneOfStandardListChoices = false; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT; index++, j *= 2) + { + if (newColumnCount == j) + { + customIsOneOfStandardListChoices = true; + FPRendering.this.fRendering.setColumnsSetting(newColumnCount); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, newColumnCount); + this.setChecked(false); + displayColumnCountCustomValue.setChecked(false); + displayColumnCounts[index].setChecked(true); + break; + } + } + + if (!customIsOneOfStandardListChoices) + { + FPRendering.this.fRendering.setColumnsSetting(newColumnCount); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, newColumnCount); + this.setChecked(false); + + displayColumnCountCustomValue.setChecked(true); + displayColumnCountCustomValue.setText(Integer.valueOf(fRendering.getColumnsSetting()).toString()); + } + } + }; + + // Check for a custom value: If we're not in "Auto Fill" mode, check for standard column sizes. + // If none of the standard sizes were entered, then it's a custom value; set it and display it. + + boolean customColumnCountSet = true; + countValue = getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY); + + if (countValue != Rendering.COLUMNS_AUTO_SIZE_TO_FIT) + { + for (int index = 0; index < MAX_MENU_COLUMN_COUNT; index++) + { + // If the column count is one of the standard values, set flag to false and exit the loop + + if (countValue == (1 << index)) + { + customColumnCountSet = false; + break; + } + } + + if (customColumnCountSet) + { + FPRendering.this.fRendering.setColumnsSetting(countValue); + displayColumnCountCustomValue.setChecked(true); + displayColumnCountCustomValue.setText(Integer.valueOf(fRendering.getColumnsSetting()).toString()); + } + } + + // Add the right-mouse-click (RMC) context menu items + + getPopupMenuManager().addMenuListener(new IMenuListener() + { + @Override + public void menuAboutToShow(IMenuManager manager) + { + manager.add(new Separator()); + + MenuManager sub = new MenuManager(FPRenderingMessages.getString("FPRendering.PANES")); //$NON-NLS-1$ + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.ENDIAN")); //$NON-NLS-1$ + sub.add(actionDisplayBigEndian); + sub.add(actionDisplayLittleEndian); + manager.add(sub); + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.NUMBER_TYPE")); //$NON-NLS-1$ + sub.add(actionFloatingPoint32); + sub.add(actionFloatingPoint64); + manager.add(sub); + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.PRECISION")); //$NON-NLS-1$ + sub.add(actionDisplay4Digits); + sub.add(actionDisplay8Digits); + sub.add(actionDisplay16Digits); + manager.add(sub); + +// TODO: Add separator for FP group here: manager.add(new Separator()); + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT")); //$NON-NLS-1$ + sub.add(displayColumnCountAuto); + + for (int index = 0; index < displayColumnCounts.length; index++) + sub.add(displayColumnCounts[index]); + + boolean currentCountIsCustom = fRendering.getColumnsSetting() != 0; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT && currentCountIsCustom; index++, j *= 2) + currentCountIsCustom = (j != fRendering.getColumnsSetting()); + + if (currentCountIsCustom) + sub.add(displayColumnCountCustomValue); + + sub.add(displayColumnCountCustom); + manager.add(sub); + + // Update modes + + int updateMode = getRMCvalue(IFPRConstants.UPDATEMODE_KEY); + + final Action updateAlwaysAction = new Action(FPRenderingMessages.getString("FPRendering.UPDATE_ALWAYS"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setUpdateMode(Rendering.UPDATE_ALWAYS); + setRMCvalue(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_ALWAYS); + } + }; + updateAlwaysAction.setChecked(updateMode == Rendering.UPDATE_ALWAYS); + + final Action updateOnBreakpointAction = new Action(FPRenderingMessages.getString("FPRendering.UPDATE_ON_BREAKPOINT"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setUpdateMode(Rendering.UPDATE_ON_BREAKPOINT); + setRMCvalue(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_ON_BREAKPOINT); + } + }; + updateOnBreakpointAction.setChecked(updateMode == Rendering.UPDATE_ON_BREAKPOINT); + + final Action updateManualAction = new Action(FPRenderingMessages.getString("FPRendering.UPDATE_MANUAL"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setUpdateMode(Rendering.UPDATE_MANUAL); + setRMCvalue(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_MANUAL); + } + }; + updateManualAction.setChecked(updateMode == Rendering.UPDATE_MANUAL); + + // Add menu + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.UPDATEMODE")); //$NON-NLS-1$ + sub.add(updateAlwaysAction); + sub.add(updateOnBreakpointAction); + sub.add(updateManualAction); + manager.add(sub); + manager.add(new Separator()); + + BigInteger start = fRendering.getSelection().getStart(); + BigInteger end = fRendering.getSelection().getEnd(); + copyAction.setEnabled(start != null && end != null); + + manager.add(copyAction); + manager.add(copyAddressAction); + + manager.add(gotoBaseAddressAction); + manager.add(refreshAction); + manager.add(new Separator()); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + }); + } + + // Set/clear selections as appropriate + + public void setSelections() + { + if (actionDisplay4Digits == null || actionDisplay8Digits == null || actionDisplay16Digits == null) return; + + // Enable/disable and set/clear menu RMC elements based on currently selected datatype + + boolean dtFloat = FPRendering.this.fRendering.getFPDataType() == FPDataType.FLOAT; + + actionDisplay16Digits.setEnabled(!dtFloat); + actionFloatingPoint32.setChecked(dtFloat); + actionFloatingPoint64.setChecked(!dtFloat); + + // Set/clear RMC elements based on displayed precision + + int displayedPrecision = getRMCvalue(dtFloat ? IFPRConstants.FLOAT_DISP_KEY : IFPRConstants.DOUBLE_DISP_KEY); + + actionDisplay4Digits.setChecked (displayedPrecision == 4); + actionDisplay8Digits.setChecked (displayedPrecision == 8); + actionDisplay16Digits.setChecked(displayedPrecision == 16); + } + + + @Override + public Control getControl() + { + return this.fRendering; + } + + // Selection is terminology for caret position + + @Override + public BigInteger getSelectedAddress() + { + FPIMemorySelection selection = fRendering.getSelection(); + if (selection == null || selection.getStart() == null) + return fRendering.getCaretAddress(); + + return selection.getStartLow(); + } + + @Override + public MemoryByte[] getSelectedAsBytes() + { + try + { + // default to the caret address and the cell count size + BigInteger startAddr = fRendering.getCaretAddress(); + int byteCount = fRendering.getCharsPerColumn(); + + // Now see if there's a selection + FPIMemorySelection selection = fRendering.getSelection(); + if (selection != null && selection.getStart() != null) + { + // The implementation is such that just having a caret somewhere (without multiple cells + // being selected) constitutes a selection, except for when the rendering is in its initial + // state, i.e. just because we get here doesn't mean the user has selected more than one cell. + + startAddr = getSelectedAddress(); + + if (selection.getHigh() != null) + byteCount = selection.getHigh().subtract(selection.getLow()).intValue() * fRendering.getAddressableSize(); + } + + return fRendering.getViewportCache().getBytes(startAddr, byteCount); + + } + catch (DebugException de) + { + return new MemoryByte[0]; + } + } + + @Override + public void goToAddress(final BigInteger address) throws DebugException + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + fRendering.gotoAddress(address); + } + }); + } + + protected void setTargetMemoryLittleEndian(boolean littleEndian) + { + // Once we actually read memory we can determine the endianess and need to set these actions accordingly. + actionDisplayBigEndian.setChecked(!littleEndian); + actionDisplayLittleEndian.setChecked(littleEndian); + + // When target endian changes, force display endian to track. User can then change display endian if desired. + fRendering.setDisplayLittleEndian(littleEndian); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) + */ + @Override + public Object getAdapter(Class adapter) + { + if (adapter == IWorkbenchAdapter.class) + { + if (this.fWorkbenchAdapter == null) + { + this.fWorkbenchAdapter = new IWorkbenchAdapter() + { + @Override + public Object[] getChildren(Object o) + { + return new Object[0]; + } + + @Override + public ImageDescriptor getImageDescriptor(Object object) + { + return null; + } + + @Override + public String getLabel(Object o) + { + return FPRenderingMessages.getString("FPRendering.RENDERING_NAME"); //$NON-NLS-1$ + } + + @Override + public Object getParent(Object o) + { + return null; + } + }; + } + return this.fWorkbenchAdapter; + } + + if (adapter == IMemoryBlockConnection.class) + { + if (fConnection == null) + { + fConnection = new IMemoryBlockConnection() + { + @Override + public void update() + { + // update UI asynchronously + Display display = FPRenderingPlugin.getDefault().getWorkbench().getDisplay(); + display.asyncExec(new Runnable() + { + @Override + public void run() + { + try + { + if (fBigBaseAddress != FPRendering.this.fRendering.getMemoryBlock().getBigBaseAddress()) + { + fBigBaseAddress = FPRendering.this.fRendering.getMemoryBlock().getBigBaseAddress(); + FPRendering.this.fRendering.gotoAddress(fBigBaseAddress); + } + FPRendering.this.fRendering.refresh(); + } + catch (DebugException e) + { + } + } + }); + } + }; + } + + return fConnection; + } + + return super.getAdapter(adapter); + } + + @Override + public void resetRendering() throws DebugException + { + fRendering.gotoAddress(fRendering.fBaseAddress); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.debug.internal.core.model.provisional. + * IMemoryRenderingViewportProvider#getViewportAddress() + */ + @Override + public BigInteger getViewportAddress() + { + return fRendering.getViewportStartAddress(); + } + + // Persistence methods + + void setDisplayedPrecision(int precision) + { + // Save the appropriate displayed precision value, based on data type, in the store + + if (FPRendering.this.fRendering.getFPDataType() == FPDataType.FLOAT) + setRMCvalue(IFPRConstants.FLOAT_DISP_KEY, precision); + else + setRMCvalue(IFPRConstants.DOUBLE_DISP_KEY, precision); + } + + private int getDisplayedPrecision() + { + // Retrieve the persisted data value from the store + + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + FPDataType dataType = FPRendering.this.fRendering.getFPDataType(); + + if (store != null) + return store.getInt(dataType == FPDataType.FLOAT ? IFPRConstants.FLOAT_DISP_KEY : IFPRConstants.DOUBLE_DISP_KEY); + + // If there's nothing persisted, return the default precision for data type + + return dataType == FPDataType.FLOAT ? FPDataType.FLOAT.getDisplayedPrecision() : FPDataType.DOUBLE.getDisplayedPrecision(); + } + + void setRMCvalue(String key, int value) + { + // Save the specified key and int value + + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + if (store != null) store.setValue(key, value); + } + + int getRMCvalue(String key) + { + // Return the value for the specified key + + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + return (store != null) ? store.getInt(key) : 0; + } +} + +// Copy class + +class CopyAction extends Action +{ + // TODO for the sake of large copies, this action should probably read in + // blocks on a Job. + + private Rendering fRendering; + private int fType = DND.CLIPBOARD; + + public CopyAction(Rendering rendering) + { + this(rendering, DND.CLIPBOARD); + } + + @SuppressWarnings("restriction") // using platform's labels and images; acceptable build risk + public CopyAction(Rendering rendering, int clipboardType) + { + super(); + fType = clipboardType; + fRendering = rendering; + setText(DebugUIMessages.CopyViewToClipboardAction_title); + setToolTipText(DebugUIMessages.CopyViewToClipboardAction_tooltip); + setImageDescriptor(DebugPluginImages + .getImageDescriptor(IInternalDebugUIConstants.IMG_ELCL_COPY_VIEW_TO_CLIPBOARD)); + setHoverImageDescriptor(DebugPluginImages + .getImageDescriptor(IInternalDebugUIConstants.IMG_LCL_COPY_VIEW_TO_CLIPBOARD)); + setDisabledImageDescriptor(DebugPluginImages + .getImageDescriptor(IInternalDebugUIConstants.IMG_DLCL_COPY_VIEW_TO_CLIPBOARD)); + } + + @Override + public void run() + { + Clipboard clip = null; + final String PANE_SPACING = " "; //$NON-NLS-1$ + + try + { + clip = new Clipboard(fRendering.getDisplay()); + + BigInteger start = fRendering.getSelection().getStart(); + BigInteger end = fRendering.getSelection().getEnd(); + + if (end == null) return; // End will be null when there is nothing selected + + if (start.compareTo(end) > 0) + { + // Swap start and end + + BigInteger bigI = end; + end = start; + start = bigI; + } + + final FPDataType numberType = fRendering.getFPDataType(); + final int bytesPerColumn = numberType.getByteLength(); + final boolean isLittleEndian = fRendering.isTargetLittleEndian(); + final int columns = fRendering.getColumnCount(); + BigInteger lengthToRead = end.subtract(start); + + int rows = lengthToRead.divide(BigInteger.valueOf(columns * (fRendering.getFPDataType().getByteLength()))).intValue(); + + if (rows * columns * bytesPerColumn < lengthToRead.intValue()) rows++; + + StringBuffer buffer = new StringBuffer(); + + for (int row = 0; row < rows; row++) + { + BigInteger rowAddress = start.add(BigInteger.valueOf(row * columns * bytesPerColumn)); + + if (fRendering.getPaneVisible(Rendering.PANE_ADDRESS)) + { + buffer.append(fRendering.getAddressString(rowAddress)); + buffer.append(PANE_SPACING); + } + + if (fRendering.getPaneVisible(Rendering.PANE_DATA)) + { + for(int col = 0; col < columns; col++) + { + BigInteger cellAddress = rowAddress.add(BigInteger.valueOf(col * bytesPerColumn)); + + if (cellAddress.compareTo(end) < 0) + { + try + { + FPMemoryByte bytes[] = fRendering.getBytes(cellAddress, bytesPerColumn); + buffer.append(fRendering.sciNotationString(bytes, numberType, isLittleEndian)); + } + catch(DebugException de) + { + fRendering + .logError( + FPRenderingMessages + .getString("FPRendering.FAILURE_COPY_OPERATION"), de); //$NON-NLS-1$ + return; + } + } + else + { + for(int i = fRendering.getCharsPerColumn(); i > 0; i--) + buffer.append(' '); + } + + if (col != columns - 1) + buffer.append(' '); + } + } + + if (fRendering.getPaneVisible(Rendering.PANE_DATA)) + buffer.append(PANE_SPACING); + + buffer.append("\n"); //$NON-NLS-1$ + } + + if (buffer.length() > 0) + { + TextTransfer plainTextTransfer = TextTransfer.getInstance(); + clip.setContents(new Object[] { buffer.toString() }, new Transfer[] { plainTextTransfer }, fType); + } + } + finally + { + if (clip != null) + { + clip.dispose(); + } + } + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingMessages.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingMessages.java new file mode 100644 index 00000000000..88ab53aa05b --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingMessages.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class FPRenderingMessages +{ + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.ui.memory.floatingpoint.messages"; //$NON-NLS-1$ + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + private FPRenderingMessages() + { + } + + public static String getString(String key) + { + // TODO Auto-generated method stub + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch(MissingResourceException e) + { + return '!' + key + '!'; + } + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPlugin.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPlugin.java new file mode 100644 index 00000000000..54f6842d8bf --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPlugin.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +public class FPRenderingPlugin extends AbstractUIPlugin +{ + public static final String PLUGIN_ID = "org.eclipse.cdt.debug.ui.memory.floatingpoint"; //$NON-NLS-1$ + + private static FPRenderingPlugin plugin; + + public FPRenderingPlugin() + { + super(); + } + + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + + /** + * Returns the shared instance. + */ + public static FPRenderingPlugin getDefault() + { + return plugin; + } + + /** + * Returns the unique identifier for this plugin. + */ + public static String getUniqueIdentifier() + { + return PLUGIN_ID; + } + + /** + * Returns the workbench's display. + */ + public static Display getStandardDisplay() + { + return PlatformUI.getWorkbench().getDisplay(); + } + + /** + * Returns the currently active workbench window shell or null + * if none. + * + * @return the currently active workbench window shell or null + */ + public static Shell getShell() + { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + + if (window == null) + { + IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); + if (windows.length > 0) + { + return windows[0].getShell(); + } + } + else + { + return window.getShell(); + } + return null; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceAction.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceAction.java new file mode 100644 index 00000000000..ac158b1e6d9 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceAction.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.preference.IPreferenceNode; +import org.eclipse.jface.preference.IPreferencePage; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.preference.PreferenceManager; +import org.eclipse.jface.preference.PreferenceNode; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.actions.ActionDelegate; + +public class FPRenderingPreferenceAction extends ActionDelegate implements IViewActionDelegate +{ + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + @Override + public void run(IAction action) + { + IPreferencePage page = new FPRenderingPreferencePage(); + showPreferencePage("org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPreferencePage", page); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + @Override + public void init(IViewPart view) + { + } + + protected void showPreferencePage(String id, IPreferencePage page) + { + final IPreferenceNode targetNode = new PreferenceNode(id, page); + + PreferenceManager manager = new PreferenceManager(); + manager.addToRoot(targetNode); + final PreferenceDialog dialog = new PreferenceDialog(FPRenderingPlugin.getShell(), manager); + final boolean[] result = new boolean[] { false }; + BusyIndicator.showWhile(FPRenderingPlugin.getStandardDisplay(), new Runnable() + { + @Override + public void run() + { + dialog.create(); + dialog.setMessage(targetNode.getLabelText()); + result[0] = (dialog.open() == Window.OK); + } + }); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceConstants.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceConstants.java new file mode 100644 index 00000000000..1fc4a93670f --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceConstants.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +/** + * Constant definitions for plug-in preferences + */ +public class FPRenderingPreferenceConstants +{ + public static final String MEM_COLOR_CHANGED = "memoryColorChanged"; //$NON-NLS-1$ + public static final String MEM_USE_GLOBAL_BACKGROUND = "memUseGlobalBackground"; //$NON-NLS-1$ + public static final String MEM_COLOR_BACKGROUND = "memoryColorBackground"; //$NON-NLS-1$ + public static final String MEM_COLOR_EDIT = "memoryColorEdit"; //$NON-NLS-1$ + public static final String MEM_COLOR_TEXT = "memoryColorText"; //$NON-NLS-1$ + public static final String MEM_USE_GLOBAL_SELECTION = "memUseGlobalSelection"; //$NON-NLS-1$ + public static final String MEM_COLOR_SELECTION = "memoryColorSelection"; //$NON-NLS-1$ + public static final String MEM_USE_GLOBAL_TEXT = "memUseGlobalText"; //$NON-NLS-1$ + public static final String MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS = "memoryColorScaleTextAlternate"; //$NON-NLS-1$ + public static final String MEM_EDIT_BUFFER_SAVE = "memoryEditBufferSave"; //$NON-NLS-1$ + public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY = "saveOnEnterCancelOnFocusLost"; //$NON-NLS-1$ + public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_OR_FOCUS_LOST = "saveOnEnterOrFocusLost"; //$NON-NLS-1$ + public static final String MEM_HISTORY_TRAILS_COUNT = "memoryHistoryTrailsCount"; //$NON-NLS-1$ +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceInitializer.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceInitializer.java new file mode 100644 index 00000000000..7cbcbed5e3f --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceInitializer.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; + +/** + * Class used to initialize default preference values. + */ +public class FPRenderingPreferenceInitializer extends AbstractPreferenceInitializer +{ + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer# + * initializeDefaultPreferences() + */ + @Override + public void initializeDefaultPreferences() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + store.setDefault(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT, true); + store.setDefault(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND, true); + store.setDefault(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION, true); + + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_CHANGED, "255,0,0"); //$NON-NLS-1$ + + Color systemSelection = Display.getDefault().getSystemColor(SWT.COLOR_LIST_SELECTION); + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_SELECTION, systemSelection.getRed() + "," + systemSelection.getGreen() + "," //$NON-NLS-1$ //$NON-NLS-2$ + + systemSelection.getBlue()); + + store.setDefault(FPRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS, "5"); //$NON-NLS-1$ + + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_EDIT, "0,255,0"); //$NON-NLS-1$ + + Color systemText = Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND); + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_TEXT, systemText.getRed() + "," + systemText.getGreen() + "," + systemText.getBlue()); //$NON-NLS-1$ //$NON-NLS-2$ + + Color systemBackground = Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_BACKGROUND, systemBackground.getRed() + "," + systemBackground.getGreen() + "," //$NON-NLS-1$ //$NON-NLS-2$ + + systemBackground.getBlue()); + + store.setDefault(FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE, FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY); + + store.setDefault(FPRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT, "1"); //$NON-NLS-1$ + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferencePage.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferencePage.java new file mode 100644 index 00000000000..716596f25a4 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferencePage.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ColorFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.jface.preference.ScaleFieldEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.PlatformUI; + +/** + * This class represents a preference page that is contributed to the + * Preferences dialog. By subclassing FieldEditorPreferencePage, we + * can use the field support built into JFace that allows us to create a page + * that is small and knows how to save, restore and apply itself. + *

+ * This page is used to modify preferences only. They are stored in the + * preference store that belongs to the main plug-in class. That way, + * preferences can be accessed directly via the preference store. + */ + +public class FPRenderingPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage +{ + public FPRenderingPreferencePage() + { + super(GRID); + setPreferenceStore(FPRenderingPlugin.getDefault().getPreferenceStore()); + setDescription("Floating Point Memory Rendering"); //$NON-NLS-1$ + } + + @Override + public void createControl(Composite parent) + { + super.createControl(parent); + PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), FPRenderingPlugin.getUniqueIdentifier() + ".FPRenderingPreferencePage_context"); //$NON-NLS-1$ + } + + /** + * Creates the field editors. Field editors are abstractions of the common + * GUI blocks needed to manipulate various types of preferences. Each field + * editor knows how to save and restore itself. + */ + @Override + public void createFieldEditors() + { + addField(new BooleanFieldEditor(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT, "Use Global Te&xt Color", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_TEXT, "&Text Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ScaleFieldEditor(FPRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS, "Brighten Alternate Cells", getFieldEditorParent(), 0, 8, 1, 1)); //$NON-NLS-1$ + addField(new BooleanFieldEditor(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND, "Use Global B&ackground Color", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_BACKGROUND, "&Background Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_CHANGED, "&Changed Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_EDIT, "&Edit Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new BooleanFieldEditor(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION, "Use Global Se&lection Color", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_SELECTION, "&Selection Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new RadioGroupFieldEditor(FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE, "Edit Buffer", 1, new String[][] //$NON-NLS-1$ + { { "Save on E&nter, Cancel on Focus Lost", "saveOnEnterCancelOnFocusLost" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "Save on Enter or Focus L&ost", "saveOnEnterOrFocusLost" } }, getFieldEditorParent())); //$NON-NLS-1$ //$NON-NLS-2$ + addField(new ScaleFieldEditor(FPRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT, "History &Trail Levels", getFieldEditorParent(), 1, 10, 1, 1)); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + @Override + public void init(IWorkbench workbench) + { + } + +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingTypeDelegate.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingTypeDelegate.java new file mode 100644 index 00000000000..8a71b83a252 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingTypeDelegate.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.ui.memory.IMemoryRendering; +import org.eclipse.debug.ui.memory.IMemoryRenderingTypeDelegate; + +public class FPRenderingTypeDelegate implements IMemoryRenderingTypeDelegate +{ + @Override + public IMemoryRendering createRendering(String id) throws CoreException + { + return new FPRendering(id); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPutilities.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPutilities.java new file mode 100644 index 00000000000..c59bd5d5e4b --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPutilities.java @@ -0,0 +1,492 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Arrays; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.UIJob; + +public class FPutilities +{ + private static final int BYTE_MASK = 0xFF; + + // ANSI C "Smallest" and "largest" negative and positive float and double values + + public static final float floatNegMax = -3.40282347E+38f; // Largest negative float value; farthest from zero + public static final float floatNegMin = -1.17549435E-38f; // Smallest negative float value; closest to zero + public static final float floatPosMax = 1.17549435E+38f; // Largest positive float value; farthest from zero + public static final float floatPosMin = 3.40282347E-38f; // Smallest positive float value; closest to zero + + public static final double doubleNegMax = -1.7976931348623157E+308; // Largest positive double value + public static final double doubleNegMin = -2.2250738585072014E-308; // Smallest positive double value + public static final double doublePosMax = 1.7976931348623157E+308; // Largest positive double value + public static final double doublePosMin = 2.2250738585072014E-308; // Smallest positive double value + + public enum FPDataType + { + // Value (for persisteance), Bitsize of type, Number of internal precision decimal digits, Default displayed precision + + FLOAT ( 10, 32, 7, 8), // C/C++ single-precision "float" + DOUBLE ( 20, 64, 15, 8), // C/C++ double-precision "double" + FLOAT_80 ( 30, 80, 19, 16), // Extended precision + FLOAT_96 ( 40, 96, 0, 0), // TODO: unknown internal decimal digit precision; C/C++ extended-precision "long double" + + // Future work + + FLOAT_128 (50, 128, 33, 16), // TODO: known values, but not currently implmented + FLOAT_256 (60, 256, 0, 0), // TODO: unknown internal decimal digit precision + FLOAT_512 (70, 512, 0, 0); // TODO: unknown internal decimal digit precision + + // Member variables + + private int value; + private int bitsize; + private int decimalPrecision; + private int displayedPrecision; + + // Constructor + + private FPDataType(int value, int bitSize, int precisionDigits, int defaultDisplayPrecision) + { + this.value = value; + this.bitsize = bitSize; + this.decimalPrecision = precisionDigits; + this.displayedPrecision = defaultDisplayPrecision; + } + + // Getters + + public int getValue() { return value; } + public int getBitsize() { return bitsize; } + public int getDecimalPrecision() { return decimalPrecision; } + public int getDisplayedPrecision() { return displayedPrecision; } + public int getInternalPrecision() { return decimalPrecision; } + + public int getByteLength() + { + return bitsize/Byte.SIZE; + } + } + + // Byte ordering + + public enum Endian + { + // Value + + LITTLE (10), + BIG (20); + + // Member variables + + private int value; + + // Constructor + + private Endian(int value) + { + this.value = value; + } + + // Getters + + public int getValue() { return value; } + } + + // Justification (latent support) + + public enum Justification + { + LEFT, + RIGHT, + CENTER; + } + + // Convert raw float bits to a byte array + + public static byte[] rawFloatBitsToByteArray(int floatBits) + { + int byteCount = Integer.SIZE/Byte.SIZE; + byte[] result = new byte[byteCount]; + + for (int index = 0; index < byteCount; index++) + { + int offset = (result.length - 1 - index) * 8; + result[index] = (byte) ((floatBits >>> offset) & BYTE_MASK); + } + + return result; + } + + // Convert raw double bits to a byte array + + public static byte[] rawDoubleBitsToByteArray(long doubleBits) + { + int byteCount = Long.SIZE/Byte.SIZE; + byte[] result = new byte[byteCount]; + + for (int index = 0; index < byteCount; index++) + { + int offset = (result.length - 1 - index) * 8; + result[index] = (byte) ((doubleBits >>> offset) & BYTE_MASK); + } + + return result; + } + + // Return a byte array that is in reverse order of the passed-in array parameter + + public static byte[] reverseByteOrder(byte[] byteArray) + { + if (byteArray.length == 0) return new byte[0]; + + byte tempByte = 0; + byte[] reversedByteArray = new byte[byteArray.length]; + + // Copy the array that is passed in to the array that will be returned + + System.arraycopy(byteArray, 0, reversedByteArray, 0, byteArray.length); + + // Reverse the bytes + + for(int start = 0, end = reversedByteArray.length - 1; start < end; ++start, --end) + { + tempByte = reversedByteArray[start]; + reversedByteArray[start] = reversedByteArray[end]; + reversedByteArray[end] = tempByte; + } + + return reversedByteArray; + } + + // Convert a representation of a float or double in a byte array to a scientific notation string (Should we use BigDecimal here???) + + public static String byteArrayToSciNotation(FPDataType dt, boolean isLittleEndian, FPMemoryByte[] memByteArray, int maxDisplayDigits) throws ArithmeticException + { + int displayedDigits = 8; + + // If the byte array is not a 32-bit float or 64-bit double, throw an exception. + + if (memByteArray.length != (FPDataType.FLOAT.getByteLength()) && + memByteArray.length != (FPDataType.DOUBLE.getByteLength())) + throw new ArithmeticException("Conversion of the floating point number cannot be performed; invalid data type or byte array length."); //$NON-NLS-1$ + + // Create and initialize a DecimalFormat object for scientific notation. Specify a space + // for the preceding plus-sign, which lines up the first significant digit, decimal point + // and exponent character. Define the symbol strings for "Not a Number" and "Infinity." + + DecimalFormat df = new DecimalFormat("0.0E0"); //$NON-NLS-1$ + df.setPositivePrefix(" "); //$NON-NLS-1$ + + DecimalFormatSymbols dfSymbols = new DecimalFormatSymbols(); + dfSymbols.setNaN(" "+ FPRenderingMessages.getString("FPRendering.NAN")); //$NON-NLS-1$ //$NON-NLS-2$ + dfSymbols.setInfinity(FPRenderingMessages.getString("FPRendering.INFINITY")); //$NON-NLS-1$ + df.setDecimalFormatSymbols(dfSymbols); + + // Set the integer and fraction digits for normalized scientific notation. + + df.setMinimumIntegerDigits(1); + df.setMaximumIntegerDigits(1); + + if (dt == FPDataType.FLOAT) + displayedDigits = Math.min(maxDisplayDigits, FPDataType.FLOAT.getInternalPrecision()); + + if (dt == FPDataType.DOUBLE) + displayedDigits = Math.min(maxDisplayDigits, FPDataType.DOUBLE.getInternalPrecision()); + + df.setMinimumFractionDigits(displayedDigits - 1); + df.setMaximumFractionDigits(displayedDigits - 1); + + // Convert the byte array to a scientific notation floating point number string (only floats and doubles currently supported) + + ByteOrder byteOrder = isLittleEndian ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; + + return df.format(dt == FPDataType.FLOAT ? + ByteBuffer.wrap(memoryBytesToByteArray(memByteArray)).order(byteOrder).getFloat() : + ByteBuffer.wrap(memoryBytesToByteArray(memByteArray)).order(byteOrder).getDouble()); + } + + // Convert a floating point string to a byte array (*** only 'floats' and 'doubles' currently supported ***) + + public static byte[] floatingStringToByteArray(FPDataType dt, String valueString, int dataTypeBitCount) throws NumberFormatException + { + // Remove whitespace and check for non-zero length + valueString = valueString.trim().replaceAll(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + + if (valueString.length() != 0) + { + // Float handling + + if (dt == FPDataType.FLOAT || FPDataType.FLOAT.getBitsize() == dataTypeBitCount) + { + // Convert the string to a float. Check the range. Convert to byte array. + + float floatValue = new Float(valueString).floatValue(); + floatValue = floatLimitCheck(floatValue); + return rawFloatBitsToByteArray(Float.floatToRawIntBits(floatValue)); + } + + // Double handling + + if (dt == FPDataType.DOUBLE || FPDataType.DOUBLE.getBitsize() == dataTypeBitCount) + { + // Convert the string to a double. Check the range. Convert to byte array. + + double doubleValue = new Double(valueString).doubleValue(); + doubleValue = doubleLimitCheck(doubleValue); + return rawDoubleBitsToByteArray(Double.doubleToRawLongBits(doubleValue)); + } + } + + return new byte[0]; + } + + // Convert from an FPMemoryByte array to a byte array + + public static byte[] memoryBytesToByteArray(FPMemoryByte[] memoryByteArray) + { + byte[] byteArray = new byte[memoryByteArray.length]; + + for (int index = 0; index < memoryByteArray.length; index++) + byteArray[index] = memoryByteArray[index].getValue(); + + return byteArray; + } + + // Convert from a byte array to a MemoryByte array + + public static FPMemoryByte[] byteArrayToMemoryBytes(Endian endian, byte[] byteArray) + { + FPMemoryByte[] memoryBytes = new FPMemoryByte[byteArray.length]; + + for (int index = 0; index < byteArray.length; index++) + { + memoryBytes[index] = new FPMemoryByte(); + memoryBytes[index].setBigEndian(endian == Endian.BIG); + memoryBytes[index].setValue(byteArray[index]); + } + + return memoryBytes; + } + + // Check the character for being valid for number entry, both standard and scientific notation + + public static boolean validEditCharacter(char character) + { + return (character >= '0' && character <= '9') || + character == '+' || character == '-' || + character == 'e' || character == 'E' || + character == '.' || character == ' '; + } + + // Validate floating point number string + + public static boolean isValidFormat(String string) + { + // Rules: + // - A minimum of one digit preceding the optional exponent character is required. + // - Allowable characters: 0-9, a decimal point, '+' and '-' number + // signs, exponent characters 'e' and 'E', and spaces. + // + // Strings may also have: + // - One [optional] decimal point + // - A maximum of two [optional] number signs (one before the number and one after the exponent character) + // - Only one [optional] exponent character is allowed + + boolean digit = false; + char[] charArray = string.toCharArray(); + + // Phase I check: + + String scientificNotationPattern = "^[-+]??(\\d++[.]\\d*?|[.]?\\d+?|\\d+(?=[eE]))([eE][-+]??\\d++)?$"; //$NON-NLS-1$ + + if (!Pattern.matches(scientificNotationPattern, string)) + return false; + + // Phase II check + + for (int index = 0; index < string.length(); index++) + { + // Check for a digit + + if (charArray[index] >= '0' && charArray[index] <= '9') + digit = true; + + // Make sure it's a valid/allowable character + + if (!validEditCharacter(charArray[index])) + return false; + + // Only one decimal point and exponent character is allowed + + if (FPutilities.countMatches(string.toLowerCase(), ".") > 1 || FPutilities.countMatches(string.toLowerCase(), "e") > 1) //$NON-NLS-1$ //$NON-NLS-2$ + return false; + + // Number signs are only allowed in the first position and following the exponent character. + + if (((charArray[index] == '+' || charArray[index] == '-') && index != 0) && + (charArray[index-1] != 'e' && charArray[index-1] != 'E')) + return false; + + // Decimal points are not allowed after the exponent character + + int eIndex = string.toLowerCase().indexOf('e'); + + if (charArray[index] == '.' && eIndex != -1 && eIndex < index) + return false; + } + + return digit; + } + + // Return a string of the specified length filled with the specified character + + public static String fillString(int length, char character) + { + if (length < 1) return ""; //$NON-NLS-1$ + char[] charArray = new char[length]; + Arrays.fill(charArray, character); + return new String(charArray); + } + + // Count the 'subString' matches in 'string' + + public static int countMatches(String string, String subString) + { + if (string.length() == 0 || subString.length() == 0) return 0; + + int count = 0; + int index = 0; + + while ((index = string.indexOf(subString, index)) != -1) + { + count++; + index += subString.length(); + } + + return count; + } + + // Print out a stack trace; useful for UI operations where stopping at a breakpoint causes button press context to be lost + + public static void stackTrace(int depth) + { + int offset = 3; // Ignore frames contributed to the stack based on call to this method + if (depth == 0) depth = 4; // Default depth if zero supplied + + // Get the stack frames for the current thread; start at the offset + + StackTraceElement[] seArray = Thread.currentThread().getStackTrace(); + + if (seArray.length > offset) + { + System.out.println("Displaying " + depth + " of " + seArray.length + " stack trace elements"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + for (int index = offset; index < Math.min(depth + offset, seArray.length + offset); index++) + System.out.println(" " + seArray[index].getClassName() + "." + seArray[index].getMethodName() + ": line " + seArray[index].getLineNumber()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + else + System.out.println("No stack frames to display"); //$NON-NLS-1$ + } + + // Pop up a message inside the UI thread + + public static void popupMessage(final String title, final String errorText, final Status status) + { + UIJob job = new UIJob("Floating Point Renderer") //$NON-NLS-1$ + { + // Notify the user of some condition via a pop-up box. + + @Override + public IStatus runInUIThread(IProgressMonitor monitor) + { + ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), title, errorText, status); + return Status.OK_STATUS; + } + }; + + job.setSystem(true); + job.schedule(); + } + + // Check float range. Returns -Infinity, the original value or +Infinity + + public static float floatLimitCheck(float floatValue) + { + if (floatValue != 0.0f && floatValue != Float.NEGATIVE_INFINITY && floatValue != Float.POSITIVE_INFINITY) + { + if (floatValue < 0) + { + if (Float.compare(floatValue, floatNegMax) < 0 || Float.compare(floatValue, floatNegMin) > 0) + return Float.NEGATIVE_INFINITY; + } + else + { + if (Float.compare(floatValue, floatPosMin) < 0 || Float.compare(floatValue, floatPosMax) > 0) + return Float.POSITIVE_INFINITY; + } + } + + return floatValue; + } + + // Check double range. Returns a value of RangeCheck + + public static double doubleLimitCheck(double doubleValue) + { + if (doubleValue != 0.0 && doubleValue != Double.NEGATIVE_INFINITY && doubleValue != Double.POSITIVE_INFINITY) + { + if (doubleValue < 0) + { + if (Double.compare(doubleValue, doubleNegMax) < 0 || Double.compare(doubleValue, doubleNegMin) > 0) + return Double.NEGATIVE_INFINITY; + } + else + { + if (Double.compare(doubleValue, doublePosMin) < 0 || Double.compare(doubleValue, doublePosMax) > 0) + return Double.POSITIVE_INFINITY; + } + } + + return doubleValue; + } + + // Convert a BigInteger to a hex String and return only the ending number of specified digits. + + public static String bi2HexStr(BigInteger bi, int lastDigits) + { + final int PAD_LENGTH = 12; + String base16 = bi.toString(16); + base16 = fillString(PAD_LENGTH - base16.length(), '0') + base16; + return "0x" + base16.substring(PAD_LENGTH - lastDigits).toUpperCase(); //$NON-NLS-1$ + } + + // Convert a BigInteger to a decimal String and return only the ending number of + // specified digits. For example: bi2HexStr(239248506, 5) = "48506" + + public static String bi2DecStr(BigInteger bi, int lastDigits) + { + final int PAD_LENGTH = 12; + String base10 = bi.toString(); + base10 = fillString(PAD_LENGTH - base10.length(), '0') + base10; + return base10.substring(PAD_LENGTH - lastDigits); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/IFPRConstants.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/IFPRConstants.java new file mode 100644 index 00000000000..2d65cfead84 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/IFPRConstants.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +public interface IFPRConstants +{ + public final String ENDIAN_KEY = FPRenderingPlugin.PLUGIN_ID + ".endian"; // Endianness key //$NON-NLS-1$ + public final String DATATYPE_KEY = FPRenderingPlugin.PLUGIN_ID + ".dataType"; // Currently-selected data type //$NON-NLS-1$ + public final String FLOAT_DISP_KEY = FPRenderingPlugin.PLUGIN_ID + ".floatDispPrec"; // 32-bit floating point data type displayed precision //$NON-NLS-1$ + public final String DOUBLE_DISP_KEY = FPRenderingPlugin.PLUGIN_ID + ".doubleDispPrec"; // 64-bit floating point data type displayed precision //$NON-NLS-1$ + public final String COLUMN_COUNT_KEY = FPRenderingPlugin.PLUGIN_ID + ".columns"; // Number of columns to display //$NON-NLS-1$ + public final String UPDATEMODE_KEY = FPRenderingPlugin.PLUGIN_ID + ".updateMode"; // Renderer update mode //$NON-NLS-1$ +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/Rendering.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/Rendering.java new file mode 100644 index 00000000000..bf6ba9cdecd --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/Rendering.java @@ -0,0 +1,2297 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; +import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressComposite; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.UIJob; + + +@SuppressWarnings("restriction") +public class Rendering extends Composite implements IDebugEventSetListener +{ + // The IMemoryRendering parent + + private FPRendering fParent; + + // Controls + + protected FPAddressPane fAddressPane; + protected FPDataPane fDataPane; + private GoToAddressComposite fAddressBar; + protected Control fAddressBarControl; + private Selection fSelection = new Selection(); + + // Internal management + + BigInteger fViewportAddress = null; // Default visibility for performance + BigInteger fMemoryBlockStartAddress = null; // Starting address + BigInteger fMemoryBlockEndAddress = null; // Ending address + protected BigInteger fBaseAddress = null; // Base address + protected int fColumnCount = 0; // Auto calculate can be disabled by user, making this user settable + protected int fBytesPerRow = 0; // Number of bytes per row are displayed + int fScrollSelection = 0; // Scroll selection + private BigInteger fCaretAddress = null; // Caret/cursor position + private boolean fCellEditState = false; // Cell editing mode: 'true' = currently editing a cell; 'false' = not editing a cell + private BigInteger cellEditAddress = null; // The address of the cell currently being edited + private BigInteger memoryAddress = null; // The memory address associated with the cell that currently being edited + private StringBuffer fEditBuffer = null; // Character buffer used during editing + static boolean initialDisplayModeSet = false; // Initial display mode been set to the same endianness as the target + + // Constants used to identify the panes + + public final static int PANE_ADDRESS = 1; + public final static int PANE_DATA = 2; + + // Decimal precision used when converting between scroll units and number of memory + // rows. Calculations do not need to be exact; two decimal places is good enough. + + static private final MathContext SCROLL_CONVERSION_PRECISION = new MathContext(2); + + // Constants used to identify text, maybe java should be queried for all available sets + + public final static int TEXT_ISO_8859_1 = 1; + public final static int TEXT_USASCII = 2; + public final static int TEXT_UTF8 = 3; + protected final static int TEXT_UTF16 = 4; + + // Internal constants + + public final static int COLUMNS_AUTO_SIZE_TO_FIT = 0; + + // View internal settings + + private int fCellPadding = 2; + private int fPaneSpacing = 16; + private String fPaddingString = " "; //$NON-NLS-1$ + + // Flag whether the memory cache is dirty + + private boolean fCacheDirty = false; + + // Update modes + + public final static int UPDATE_ALWAYS = 1; + public final static int UPDATE_ON_BREAKPOINT = 2; + public final static int UPDATE_MANUAL = 3; + public int fUpdateMode = UPDATE_ALWAYS; + + // Constants for cell-width calculations + + private static final int DECIMAL_POINT_SIZE = 1; + private static final int SIGN_SIZE = 1; + private static final int EXPONENT_CHARACTER_SIZE = 1; + private static final int EXPONENT_VALUE_SIZE = 3; + + // User settings + + private FPDataType fFPDataType = FPDataType.FLOAT; // Default to float data type + private int fDisplayedPrecision = 8; // The default number of digits of displayed precision + private int fCharsPerColumn = charsPerColumn(); // Figure out the initial cell-width size + private int fColumnsSetting = COLUMNS_AUTO_SIZE_TO_FIT; // Default column setting + private boolean fIsTargetLittleEndian = true; // Default target endian setting + private boolean fIsDisplayLittleEndian = true; // Default display endian setting + private boolean fEditInserMode = false; // Insert mode: true = replace existing number, false = overstrike + + // Constructors + + public Rendering(Composite parent, FPRendering renderingParent) + { + super(parent, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.H_SCROLL | SWT.V_SCROLL); + this.setFont(JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME)); // TODO: internal? + this.fParent = renderingParent; + + // Initialize the viewport start + + if (fParent.getMemoryBlock() != null) + { + fViewportAddress = fParent.getMemoryBlockStartAddress(); + + // The viewport address will be null if memory may be retrieved at any + // address less than this memory block's base. If so use the base address. + + if (fViewportAddress == null) + fViewportAddress = fParent.getBigBaseAddress(); + + fBaseAddress = fViewportAddress; + } + + // Instantiate the panes, TODO default visibility from state or plugin.xml? + + this.fAddressPane = createAddressPane(); + this.fDataPane = createDataPane(); + + fAddressBar = new GoToAddressComposite(); + fAddressBarControl = fAddressBar.createControl(parent); + Button button = fAddressBar.getButton(IDialogConstants.OK_ID); + + if (button != null) + { + button.addSelectionListener(new SelectionAdapter() + { + + @Override + public void widgetSelected(SelectionEvent e) + { + doGoToAddress(); + } + }); + + button = fAddressBar.getButton(IDialogConstants.CANCEL_ID); + if (button != null) + { + button.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + setVisibleAddressBar(false); + } + }); + } + } + + fAddressBar.getExpressionWidget().addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetDefaultSelected(SelectionEvent e) + { + doGoToAddress(); + } + }); + + fAddressBar.getExpressionWidget().addKeyListener(new KeyAdapter() + { + @Override + public void keyPressed(KeyEvent e) + { + if (e.keyCode == SWT.ESC) + setVisibleAddressBar(false); + super.keyPressed(e); + } + }); + + this.fAddressBarControl.setVisible(false); + + getHorizontalBar().addSelectionListener(createHorizontalBarSelectionListener()); + getVerticalBar().addSelectionListener(createVerticalBarSelectinListener()); + + this.addPaintListener(new PaintListener() + { + @Override + public void paintControl(PaintEvent pe) + { + pe.gc.setBackground(Rendering.this.getFPRendering().getColorBackground()); + pe.gc.fillRectangle(0, 0, Rendering.this.getBounds().width, Rendering.this.getBounds().height); + } + }); + + setLayout(); + + this.addControlListener(new ControlListener() + { + @Override + public void controlMoved(ControlEvent ce) + { + } + + @Override + public void controlResized(ControlEvent ce) + { + packColumns(); + } + }); + + DebugPlugin.getDefault().addDebugEventListener(this); + } + + // Determine how many characters are allowed in the column + + private int charsPerColumn() + { + return fDisplayedPrecision + DECIMAL_POINT_SIZE + SIGN_SIZE + EXPONENT_CHARACTER_SIZE + EXPONENT_VALUE_SIZE + fCellPadding; + } + + // Establish the visible layout of the view + + protected void setLayout() + { + this.setLayout(new Layout() + { + @Override + public void layout(Composite composite, boolean changed) + { + int xOffset = 0; + + if (Rendering.this.getHorizontalBar().isVisible()) + xOffset = Rendering.this.getHorizontalBar().getSelection(); + + int x = xOffset * -1; + int y = 0; + + if (fAddressBarControl.isVisible()) + { + fAddressBarControl.setBounds(0, 0, Rendering.this.getBounds().width, fAddressBarControl.computeSize(100, 30).y); // FIXME + // y = fAddressBarControl.getBounds().height; + } + + if (fAddressPane.isPaneVisible()) + { + fAddressPane.setBounds(x, y, fAddressPane.computeSize(0, 0).x, Rendering.this.getBounds().height - y); + x = fAddressPane.getBounds().x + fAddressPane.getBounds().width; + } + + if (fDataPane.isPaneVisible()) + { + fDataPane.setBounds(x, y, fDataPane.computeSize(0, 0).x, Rendering.this.getBounds().height - y); + x = fDataPane.getBounds().x + fDataPane.getBounds().width; + } + + ScrollBar horizontal = Rendering.this.getHorizontalBar(); + + horizontal.setVisible(true); + horizontal.setMinimum(0); + horizontal.setMaximum(fDataPane.getBounds().x + fDataPane.getBounds().width + xOffset); + @SuppressWarnings("unused") + int temp = horizontal.getMaximum(); + horizontal.setThumb(getClientArea().width); + horizontal.setPageIncrement(40); // TODO ? + horizontal.setIncrement(20); // TODO ? + } + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) + { + return new Point(100, 100); // dummy data + } + }); + } + + // Handles for the caret/cursor movement keys + + protected void handleDownArrow() + { + fViewportAddress = fViewportAddress.add(BigInteger.valueOf(getAddressableCellsPerRow())); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected void handleUpArrow() + { + fViewportAddress = fViewportAddress.subtract(BigInteger.valueOf(getAddressableCellsPerRow())); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected void handlePageDown() + { + fViewportAddress = fViewportAddress.add(BigInteger.valueOf(getAddressableCellsPerRow() * (Rendering.this.getRowCount() - 1))); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected void handlePageUp() + { + fViewportAddress = fViewportAddress.subtract(BigInteger.valueOf(getAddressableCellsPerRow() * (Rendering.this.getRowCount() - 1))); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected SelectionListener createHorizontalBarSelectionListener() + { + return new SelectionListener() + { + @Override + public void widgetSelected(SelectionEvent se) + { + Rendering.this.layout(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent se) + { + // Do nothing + } + }; + } + + protected SelectionListener createVerticalBarSelectinListener() + { + return new SelectionListener() + { + @Override + public void widgetSelected(SelectionEvent se) + { + switch (se.detail) + { + case SWT.ARROW_DOWN: + handleDownArrow(); + break; + + case SWT.PAGE_DOWN: + handlePageDown(); + break; + + case SWT.ARROW_UP: + handleUpArrow(); + break; + + case SWT.PAGE_UP: + handlePageUp(); + break; + + case SWT.SCROLL_LINE: + // See: BUG 203068 selection event details broken on GTK < 2.6 + + default: + { + if (getVerticalBar().getSelection() == getVerticalBar().getMinimum()) + { + // Set view port start address to the start address of the Memory Block + fViewportAddress = Rendering.this.getMemoryBlockStartAddress(); + } + else if (getVerticalBar().getSelection() == getVerticalBar().getMaximum()) + { + // The view port end address should be less or equal to the the end address of the Memory Block + // Set view port address to be bigger than the end address of the Memory Block for now + // and let ensureViewportAddressDisplayable() to figure out the correct view port start address + fViewportAddress = Rendering.this.getMemoryBlockEndAddress(); + } + else + { + // Figure out the delta, ignore events with no delta + int deltaScroll = getVerticalBar().getSelection() - fScrollSelection; + if (deltaScroll == 0) break; + BigInteger deltaRows = scrollbar2rows(deltaScroll); + BigInteger newAddress = fViewportAddress.add(BigInteger.valueOf(getAddressableCellsPerRow()).multiply(deltaRows)); + fViewportAddress = newAddress; + } + + ensureViewportAddressDisplayable(); + + // Update tooltip; FIXME conversion from slider to scrollbar + // getVerticalBar().setToolTipText(Rendering.this.getAddressString(fViewportAddress)); + + // Update the addresses in the Address pane. + + if (fAddressPane.isPaneVisible()) + fAddressPane.redraw(); + + redrawPanes(); + + break; + } + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent se) + { + // do nothing + } + }; + } + + protected FPAddressPane createAddressPane() + { + return new FPAddressPane(this); + } + + protected FPDataPane createDataPane() + { + return new FPDataPane(this); + } + + public FPRendering getFPRendering() // TODO rename + { + return fParent; + } + + protected void setCaretAddress(BigInteger address) + { + fCaretAddress = address; + } + + protected BigInteger getCaretAddress() + { + // Return the caret address if it has been set. Otherwise return the viewport address. + // When the rendering is first created, the caret is unset until the user clicks somewhere + // in the rendering. It also reset (unset) when the user gives us a new viewport address + + return (fCaretAddress != null) ? fCaretAddress : fViewportAddress; + } + + void doGoToAddress() + { + try + { + BigInteger address = fAddressBar.getGoToAddress(this.getMemoryBlockStartAddress(), this.getCaretAddress()); + getFPRendering().gotoAddress(address); + setVisibleAddressBar(false); + } + catch (NumberFormatException e1) + { + // FIXME log? + } + } + + // Ensure that all addresses displayed are within the addressable range + protected void ensureViewportAddressDisplayable() + { + if (fViewportAddress.compareTo(Rendering.this.getMemoryBlockStartAddress()) < 0) + { + fViewportAddress = Rendering.this.getMemoryBlockStartAddress(); + } + else if (getViewportEndAddress().compareTo(getMemoryBlockEndAddress().add(BigInteger.ONE)) > 0) + { + fViewportAddress = getMemoryBlockEndAddress().subtract(BigInteger.valueOf(getAddressableCellsPerRow() * getRowCount() - 1)); + } + + setScrollSelection(); + } + + public FPIMemorySelection getSelection() + { + return fSelection; + } + + protected int getHistoryDepth() + { + return fViewportCache.getHistoryDepth(); + } + + protected void setHistoryDepth(int depth) + { + fViewportCache.setHistoryDepth(depth); + } + + public void logError(String message, Exception e) + { + Status status = new Status(IStatus.ERROR, fParent.getRenderingId(), DebugException.INTERNAL_ERROR, message, e); + FPRenderingPlugin.getDefault().getLog().log(status); + } + + public void handleFontPreferenceChange(Font font) + { + setFont(font); + + Control controls[] = this.getRenderingPanes(); + for (int index = 0; index < controls.length; index++) + controls[index].setFont(font); + + packColumns(); + layout(true); + } + + public void setPaddingString(String padding) + { + fPaddingString = padding; + refresh(); + } + + public char getPaddingCharacter() + { + return fPaddingString.charAt(0); // use only the first character + } + + static int suspendCount = 0; + + @Override + public void handleDebugEvents(DebugEvent[] events) + { + if (this.isDisposed()) return; + + boolean isChangeOnly = false; + boolean isSuspend = false; + boolean isBreakpointHit = false; + + for (int index = 0; index < events.length; index++) + { + if (events[0].getSource() instanceof IDebugElement) + { + final int kind = events[index].getKind(); + final int detail = events[index].getDetail(); + final IDebugElement source = (IDebugElement) events[index].getSource(); + + /* + * We have to make sure we are comparing memory blocks here. It pretty much is now the + * case that the IDebugTarget is always null. Almost no one in the Embedded Space is + * using anything but CDT/DSF or CDT/TCF at this point. The older CDI stuff will still + * be using the old Debug Model API. But this will generate the same memory block and + * a legitimate IDebugTarget which will match properly. + */ + if( source.equals( getMemoryBlock() ) && source.getDebugTarget() == getMemoryBlock().getDebugTarget() ) + { + if ((detail & DebugEvent.BREAKPOINT) != 0) isBreakpointHit = true; + + if (kind == DebugEvent.SUSPEND) + { + handleSuspendEvent(detail); + isSuspend = true; + } + else if (kind == DebugEvent.CHANGE) + { + handleChangeEvent(); + isChangeOnly = true; + } + } + } + } + + if (isSuspend) + handleSuspend(isBreakpointHit); + else if (isChangeOnly) + handleChange(); + } + + protected void handleSuspend(boolean isBreakpointHit) + { + if (getUpdateMode() == UPDATE_ALWAYS || (getUpdateMode() == UPDATE_ON_BREAKPOINT && isBreakpointHit)) + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + archiveDeltas(); + refresh(); + } + }); + } + } + + protected void handleChange() + { + if (getUpdateMode() == UPDATE_ALWAYS) + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + refresh(); + } + }); + } + } + + protected void handleSuspendEvent(int detail) + { + } + + protected void handleChangeEvent() + { + } + + // Return true to enable development debug print statements + + public boolean isDebug() + { + return false; + } + + protected IMemoryBlockExtension getMemoryBlock() + { + IMemoryBlock block = fParent.getMemoryBlock(); + if (block != null) + return (IMemoryBlockExtension) block.getAdapter(IMemoryBlockExtension.class); + + return null; + } + + public BigInteger getBigBaseAddress() + { + return fParent.getBigBaseAddress(); + } + + public int getAddressableSize() + { + return fParent.getAddressableSize(); + } + + protected FPIViewportCache getViewportCache() + { + return fViewportCache; + } + + public FPMemoryByte[] getBytes(BigInteger address, int bytes) throws DebugException + { + return getViewportCache().getBytes(address, bytes); + } + + // Default visibility for performance + + ViewportCache fViewportCache = new ViewportCache(); + + private interface Request + { + } + + class ViewportCache extends Thread implements FPIViewportCache + { + class ArchiveDeltas implements Request + { + } + + class AddressPair implements Request + { + BigInteger startAddress; + BigInteger endAddress; + + public AddressPair(BigInteger start, BigInteger end) + { + startAddress = start; + endAddress = end; + } + + @Override + public boolean equals(Object obj) + { + if (obj == null) + return false; + if (obj instanceof AddressPair) + { + return ((AddressPair) obj).startAddress.equals(startAddress) && ((AddressPair) obj).endAddress.equals(endAddress); + } + + return false; + } + + @Override + public int hashCode() { + return super.hashCode() + startAddress.hashCode() + endAddress.hashCode(); + } + + } + + class MemoryUnit implements Cloneable + { + BigInteger start; + + BigInteger end; + + FPMemoryByte[] bytes; + + @Override + public MemoryUnit clone() + { + MemoryUnit b = new MemoryUnit(); + + b.start = this.start; + b.end = this.end; + b.bytes = new FPMemoryByte[this.bytes.length]; + for (int index = 0; index < this.bytes.length; index++) + b.bytes[index] = new FPMemoryByte(this.bytes[index].getValue()); + + return b; + } + + public boolean isValid() + { + return this.start != null && this.end != null && this.bytes != null; + } + } + + @SuppressWarnings("hiding") + private HashMap fEditBuffer = new HashMap(); + private boolean fDisposed = false; + private Object fLastQueued = null; + private Vector fQueue = new Vector(); + protected MemoryUnit fCache = null; + protected MemoryUnit fHistoryCache[] = new MemoryUnit[0]; + protected int fHistoryDepth = 0; + + public ViewportCache() + { + start(); + } + + @Override + public void dispose() + { + fDisposed = true; + synchronized (fQueue) + { + fQueue.notify(); + } + } + + public int getHistoryDepth() + { + return fHistoryDepth; + } + + public void setHistoryDepth(int depth) + { + fHistoryDepth = depth; + fHistoryCache = new MemoryUnit[fHistoryDepth]; + } + + @Override + public void refresh() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + if (fCache != null) + { + queueRequest(fViewportAddress, getViewportEndAddress()); + } + } + + @Override + public void archiveDeltas() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + if (fCache != null) + { + queueRequestArchiveDeltas(); + } + } + + private void queueRequest(BigInteger startAddress, BigInteger endAddress) + { + AddressPair pair = new AddressPair(startAddress, endAddress); + queue(pair); + } + + private void queueRequestArchiveDeltas() + { + ArchiveDeltas archive = new ArchiveDeltas(); + queue(archive); + } + + private void queue(Object element) + { + synchronized (fQueue) + { + if (!(fQueue.size() > 0 && element.equals(fLastQueued))) + { + fQueue.addElement(element); + fLastQueued = element; + } + fQueue.notify(); + } + } + + @Override + public void run() + { + while (!fDisposed) + { + AddressPair pair = null; + boolean archiveDeltas = false; + synchronized (fQueue) + { + if (fQueue.size() > 0) + { + Request request = (Request) fQueue.elementAt(0); + Class type = request.getClass(); + + while (fQueue.size() > 0 && type.isInstance(fQueue.elementAt(0))) + { + request = (Request) fQueue.elementAt(0); + fQueue.removeElementAt(0); + } + + if (request instanceof ArchiveDeltas) + archiveDeltas = true; + else if (request instanceof AddressPair) + pair = (AddressPair) request; + } + } + + if (archiveDeltas) + { + for (int i = fViewportCache.getHistoryDepth() - 1; i > 0; i--) + fHistoryCache[i] = fHistoryCache[i - 1]; + + fHistoryCache[0] = fCache.clone(); + } + else if (pair != null) + { + populateCache(pair.startAddress, pair.endAddress); + } + else + { + synchronized (fQueue) + { + try + { + if (fQueue.isEmpty()) + { + fQueue.wait(); + } + } catch (Exception e) + { + // do nothing + } + } + } + } + } + + // Cache memory necessary to paint viewport + // TODO: user setting to buffer +/- x lines + // TODO: reuse existing cache? probably only a minor performance gain + + private void populateCache(final BigInteger startAddress, final BigInteger endAddress) + { + try + { + IMemoryBlockExtension memoryBlock = getMemoryBlock(); + + BigInteger lengthInBytes = endAddress.subtract(startAddress); + BigInteger addressableSize = BigInteger.valueOf(getAddressableSize()); + + long units = lengthInBytes.divide(addressableSize) + .add(lengthInBytes.mod(addressableSize).compareTo(BigInteger.ZERO) > 0 ? BigInteger.ONE : BigInteger.ZERO).longValue(); + + // CDT (and maybe other backends) will call setValue() on these MemoryBlock objects. We + // don't want this to happen, because it interferes with this rendering's own change history. + // Ideally, we should strictly use the back end change notification and history, but it is + // only guaranteed to work for bytes within the address range of the MemoryBlock. + + MemoryByte readBytes[] = memoryBlock.getBytesFromAddress(startAddress, units); + FPMemoryByte cachedBytes[] = new FPMemoryByte[readBytes.length]; + + for (int index = 0; index < readBytes.length; index++) + cachedBytes[index] = new FPMemoryByte(readBytes[index].getValue(), readBytes[index].getFlags()); + + // Derive the target endian from the read MemoryBytes. + + if (cachedBytes.length > 0) + if (cachedBytes[0].isEndianessKnown()) + setTargetLittleEndian(!cachedBytes[0].isBigEndian()); + + // The first time we execute this method, set the display endianness to the target endianness. + + if (!initialDisplayModeSet) + { + setDisplayLittleEndian(isTargetLittleEndian()); + initialDisplayModeSet = true; + } + + // Re-order bytes within unit to be a sequential byte stream if the endian is already little + + if (isTargetLittleEndian()) + { + // There isn't an order when the unit size is one, so skip for performance + + if (addressableSize.compareTo(BigInteger.ONE) != 0) + { + int unitSize = addressableSize.intValue(); + FPMemoryByte cachedBytesAsByteSequence[] = new FPMemoryByte[cachedBytes.length]; + for (int unit = 0; unit < units; unit++) + { + for (int unitbyte = 0; unitbyte < unitSize; unitbyte++) + { + cachedBytesAsByteSequence[unit * unitSize + unitbyte] = cachedBytes[unit * unitSize + unitSize - unitbyte]; + } + } + cachedBytes = cachedBytesAsByteSequence; + } + } + + final FPMemoryByte[] cachedBytesFinal = cachedBytes; + + fCache = new MemoryUnit(); + fCache.start = startAddress; + fCache.end = endAddress; + fCache.bytes = cachedBytesFinal; + + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + // Generate deltas + + for (int historyIndex = 0; historyIndex < getHistoryDepth(); historyIndex++) + { + if (fHistoryCache[historyIndex] != null && fHistoryCache[historyIndex].isValid()) + { + BigInteger maxStart = startAddress.max(fHistoryCache[historyIndex].start); + BigInteger minEnd = endAddress.min(fHistoryCache[historyIndex].end).subtract(BigInteger.ONE); + + BigInteger overlapLength = minEnd.subtract(maxStart); + if (overlapLength.compareTo(BigInteger.valueOf(0)) > 0) + { + // there is overlap + + int offsetIntoOld = maxStart.subtract(fHistoryCache[historyIndex].start).intValue(); + int offsetIntoNew = maxStart.subtract(startAddress).intValue(); + + for (int i = overlapLength.intValue(); i >= 0; i--) + { + cachedBytesFinal[offsetIntoNew + i].setChanged(historyIndex, + cachedBytesFinal[offsetIntoNew + i].getValue() != fHistoryCache[historyIndex].bytes[offsetIntoOld + i] + .getValue()); + } + + // There are several scenarios where the history cache must be updated from the data cache, so that when a + // cell is edited the font color changes appropriately. The following code deals with the different cases. + + if (historyIndex != 0) continue; + + int dataStart = fCache.start.intValue(); + int dataEnd = fCache.end.intValue(); + int dataLength = fCache.bytes.length; + + int historyStart = fHistoryCache[0].start.intValue(); + int historyEnd = fHistoryCache[0].end.intValue(); + int historyLength = fHistoryCache[0].bytes.length; + + // Case 1: The data cache is smaller than the history cache; the data cache's + // address range is fully covered by the history cache. Do nothing. + + if ((dataStart >= historyStart) && (dataEnd <= historyEnd)) + continue; + + // Case 2: The data and history cache's do not overlap at all + + if (((dataStart < historyStart) && (dataEnd < historyStart)) || (dataStart > historyEnd)) + { + // Create a new history cache: Copy the data cache bytes to the history cache + + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fCache.start; + newHistoryCache.end = fCache.end; + int newHistoryCacheSize = fCache.bytes.length; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + for (int index = 0; index < newHistoryCacheSize; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + fHistoryCache[0] = newHistoryCache; + + continue; + } + + // Case 3: The data cache starts at a lower address than the history cache, but overlaps the history cache + + if ((dataStart < historyStart) && ((dataEnd >= historyStart) && (dataEnd <= historyEnd))) + { + // Create a new history cache with the missing data from the main cache and append the old history to it. + + int missingDataByteCount = historyStart - dataStart; + int historyCacheSize = historyLength; + int newHistoryCacheSize = missingDataByteCount + historyLength; + + if (missingDataByteCount <= 0 && historyCacheSize <= 0) break; + + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fCache.start; + newHistoryCache.end = fHistoryCache[0].end; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + // Copy the missing bytes from the beginning of the main cache to the history cache. + + for (int index = 0; index < missingDataByteCount; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + // Copy the remaining bytes from the old history cache to the new history cache + + for (int index = 0; index < historyCacheSize; index++) + newHistoryCache.bytes[index + missingDataByteCount] = + new FPMemoryByte(fHistoryCache[0].bytes[index].getValue()); + + fHistoryCache[0] = newHistoryCache; + + continue; + } + + // Case 4: The data cache starts at a higher address than the history cache + + if (((dataStart >= historyStart) && (dataStart <= historyEnd)) && (dataEnd > historyEnd)) + { + // Append the missing main cache bytes to the history cache. + + int missingDataByteCount = dataEnd - historyEnd; + int historyCacheSize = historyEnd - historyStart; + int newHistoryCacheSize = missingDataByteCount + historyLength; + + if (missingDataByteCount > 0 && historyCacheSize > 0) + { + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fHistoryCache[0].start; + newHistoryCache.end = fCache.end; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + // Copy the old history bytes to the new history cache + + System.arraycopy(fHistoryCache[0].bytes, 0, newHistoryCache.bytes, 0, historyLength); + + // Copy the bytes from the main cache that are not in the history cache to the end of the new history cache. + + for (int index = 0; index < missingDataByteCount; index++) + { + int srcIndex = dataLength - missingDataByteCount + index; + int dstIndex = historyLength + index; + newHistoryCache.bytes[dstIndex] = new FPMemoryByte(fCache.bytes[srcIndex].getValue()); + } + + fHistoryCache[0] = newHistoryCache; + + continue; + } + } + + // Case 5 - The data cache is greater than the history cache and fully covers it + + if (dataStart < historyStart && dataEnd > historyEnd) + { + int start = 0; + int end = 0; + + // Create a new history cache to reflect the entire data cache + + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fCache.start; + newHistoryCache.end = fCache.end; + int newHistoryCacheSize = fCache.bytes.length; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + int topByteCount = historyStart - dataStart; + int bottomByteCount = dataEnd - historyEnd; + + // Copy the bytes from the beginning of the data cache to the new history cache + + for (int index = 0; index < topByteCount; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + // Copy the old history cache bytes to the new history cache + + start = topByteCount; + end = topByteCount + historyLength; + + for (int index = start; index < end; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + // Copy the bytes from the end of the data cache to the new history cache + + start = topByteCount + historyLength; + end = topByteCount + historyLength + bottomByteCount; + + for (int index = start; index < end; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + fHistoryCache[0] = newHistoryCache; + + continue; + } + } + } + } + + // If the history does not exist, populate the history with the just populated + // cache. This solves the use case of (1) connect to target; (2) edit memory + // before the first suspend debug event; (3) paint differences in changed color. + + if (fHistoryCache[0] == null) + fHistoryCache[0] = fCache.clone(); + + Rendering.this.redrawPanes(); + } + }); + + } + catch (Exception e) + { + // User can scroll to any memory, whether it's valid on the target or not. It doesn't make + // much sense to fill up the Eclipse error log with such "failures." So, comment out for now. + // logError(FPRenderingMessages.getString("FAILURE_READ_MEMORY"), e); //$NON-NLS-1$ + } + } + + // Bytes will be fetched from cache + + @Override + public FPMemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + if (containsEditedCell(address)) // Cell size cannot be switched during an edit + return getEditedMemory(address); + + boolean contains = false; + if (fCache != null && fCache.start != null) + { + // See if all of the data requested is in the cache + + BigInteger dataEnd = address.add(BigInteger.valueOf(bytesRequested)); + + if (fCache.start.compareTo(address) <= 0 && fCache.end.compareTo(dataEnd) >= 0 && fCache.bytes.length > 0) + contains = true; + } + + if (contains) + { + int offset = address.subtract(fCache.start).intValue(); + FPMemoryByte bytes[] = new FPMemoryByte[bytesRequested]; + + for (int index = 0; index < bytes.length; index++) + bytes[index] = fCache.bytes[offset + index]; + + return bytes; + } + + FPMemoryByte bytes[] = new FPMemoryByte[bytesRequested]; + + for (int index = 0; index < bytes.length; index++) + { + bytes[index] = new FPMemoryByte(); + bytes[index].setReadable(false); + } + + fViewportCache.queueRequest(fViewportAddress, getViewportEndAddress()); + + return bytes; + } + + @Override + public boolean containsEditedCell(BigInteger address) + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + return fEditBuffer.containsKey(address); + } + + public FPMemoryByte[] getEditedMemory(BigInteger address) + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + return fEditBuffer.get(address); + } + + @Override + public void clearEditBuffer() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + fEditBuffer.clear(); + Rendering.this.redrawPanes(); + } + + @Override + public void writeEditBuffer() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + Set keySet = fEditBuffer.keySet(); + Iterator iterator = keySet.iterator(); + + while (iterator.hasNext()) + { + BigInteger address = iterator.next(); + FPMemoryByte[] bytes = fEditBuffer.get(address); + + byte byteValue[] = new byte[bytes.length]; + + for (int index = 0; index < bytes.length; index++) + byteValue[index] = bytes[index].getValue(); + + try + { + IMemoryBlockExtension block = getMemoryBlock(); + BigInteger offset = address.subtract(block.getBigBaseAddress()); + block.setValue(offset, byteValue); + } + catch (Exception e) + { + MemoryViewUtil.openError(FPRenderingMessages.getString("FAILURE_WRITE_MEMORY"), "", e); //$NON-NLS-1$ //$NON-NLS-2$ + logError(FPRenderingMessages.getString("FAILURE_WRITE_MEMORY"), e); //$NON-NLS-1$ + } + } + + clearEditBuffer(); + } + + @Override + public void setEditedValue(BigInteger address, FPMemoryByte[] bytes) + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + fEditBuffer.put(address, bytes); + Rendering.this.redrawPanes(); + } + } + + public void setVisibleAddressBar(boolean visible) + { + fAddressBarControl.setVisible(visible); + if (visible) + { + String selectedStr = "0x" + getCaretAddress().toString(16); //$NON-NLS-1$ + Text text = fAddressBar.getExpressionWidget(); + text.setText(selectedStr); + text.setSelection(0, text.getCharCount()); + fAddressBar.getExpressionWidget().setFocus(); + } + + layout(true); + layoutPanes(); + } + + public void setDirty(boolean needRefresh) + { + fCacheDirty = needRefresh; + } + + public boolean isDirty() + { + return fCacheDirty; + } + + @Override + public void dispose() + { + DebugPlugin.getDefault().removeDebugEventListener(this); + if (fViewportCache != null) + { + fViewportCache.dispose(); + fViewportCache = null; + } + super.dispose(); + } + + class Selection implements FPIMemorySelection + { + private BigInteger fStartHigh = null; + private BigInteger fStartLow = null; + + private BigInteger fEndHigh = null; + private BigInteger fEndLow = null; + + @Override + public void clear() + { + fEndHigh = fEndLow = fStartHigh = fStartLow = null; + redrawPanes(); + } + + @Override + public boolean hasSelection() + { + return fStartHigh != null && fStartLow != null && fEndHigh != null && fEndLow != null; + } + + @Override + public boolean isSelected(BigInteger address) + { + // Do we have valid start and end addresses? + + if (getEnd() == null || getStart() == null) return false; + + // If end is greater than start + + if (getEnd().compareTo(getStart()) >= 0) + { + // If address is greater-than-or-equal-to start and less then end, return true + if (address.compareTo(getStart()) >= 0 && address.compareTo(getEnd()) < 0) return true; + } + + // If start is greater than end + + else if (getStart().compareTo(getEnd()) >= 0) + { + // If address is greater-than-or-equal-to zero and less than start, return true + if (address.compareTo(getEnd()) >= 0 && address.compareTo(getStart()) < 0) return true; + } + + return false; + } + + // Set selection start + + @Override + public void setStart(BigInteger high, BigInteger low) + { + if (high == null && low == null) + { + if (fStartHigh != null && fStartLow != null) + { + fStartHigh = null; + fStartLow = null; + redrawPanes(); + } + + return; + } + + boolean changed = false; + + if (fStartHigh == null || !high.equals(fStartHigh)) + { + fStartHigh = high; + changed = true; + } + + if (fStartLow == null || !low.equals(fStartLow)) + { + fStartLow = low; + changed = true; + } + + if (changed) redrawPanes(); + } + + // Set selection end + + @Override + public void setEnd(BigInteger high, BigInteger low) + { + if (high == null && low == null) + { + if (fEndHigh != null && fEndLow != null) + { + fEndHigh = null; + fEndLow = null; + redrawPanes(); + } + + return; + } + + boolean changed = false; + + if (fEndHigh == null || !high.equals(fEndHigh)) + { + fEndHigh = high; + changed = true; + } + + if (fEndLow == null || !low.equals(fEndLow)) + { + fEndLow = low; + changed = true; + } + + if (changed) redrawPanes(); + } + + @Override + public BigInteger getHigh() + { + if (!hasSelection()) return null; + return getStart().max(getEnd()); + } + + @Override + public BigInteger getLow() + { + if (!hasSelection()) return null; + return getStart().min(getEnd()); + } + + @Override + public BigInteger getStart() + { + // If there is no start, return null + if (fStartHigh == null) return null; + + // If there is no end, return the high address of the start + if (fEndHigh == null) return fStartHigh; + + // If Start High/Low equal End High/Low, return a low start and high end + if (fStartHigh.equals(fEndHigh) && fStartLow.equals(fEndLow)) return fStartLow; + + BigInteger differenceEndToStartHigh = fEndHigh.subtract(fStartHigh).abs(); + BigInteger differenceEndToStartLow = fEndHigh.subtract(fStartLow).abs(); + + // Return the start high or start low based on which creates a larger selection + if (differenceEndToStartHigh.compareTo(differenceEndToStartLow) > 0) + return fStartHigh; + + return fStartLow; + } + + @Override + public BigInteger getStartLow() + { + return fStartLow; + } + + @Override + public BigInteger getEnd() + { + // If there is no end, return null + if (fEndHigh == null) return null; + + // *** Temporary for debugging *** + + if (fStartHigh == null || fStartLow == null) + { + return null; + } + + // If Start High/Low equal End High/Low, return a low start and high end + if (fStartHigh.equals(fEndHigh) && fStartLow.equals(fEndLow)) return fStartHigh; + + BigInteger differenceStartToEndHigh = fStartHigh.subtract(fEndHigh).abs(); + BigInteger differenceStartToEndLow = fStartHigh.subtract(fEndLow).abs(); + + // Return the start high or start low based on which creates a larger selection + if (differenceStartToEndHigh.compareTo(differenceStartToEndLow) >= 0) + return fEndHigh; + + return fEndLow; + } + } + + public void setPaneVisible(int pane, boolean visible) + { + switch (pane) + { + case PANE_ADDRESS: + fAddressPane.setPaneVisible(visible); + break; + case PANE_DATA: + fDataPane.setPaneVisible(visible); + break; + } + + fireSettingsChanged(); + layoutPanes(); + } + + public boolean getPaneVisible(int pane) + { + switch (pane) + { + case PANE_ADDRESS: + return fAddressPane.isPaneVisible(); + case PANE_DATA: + return fDataPane.isPaneVisible(); + default: + return false; + } + } + + protected void packColumns() + { + int availableWidth = Rendering.this.getSize().x; + + if (fAddressPane.isPaneVisible()) + { + availableWidth -= fAddressPane.computeSize(0, 0).x; + availableWidth -= Rendering.this.getRenderSpacing() * 2; + } + + int combinedWidth = 0; + + if (fDataPane.isPaneVisible()) combinedWidth += fDataPane.getCellWidth(); + + if (getColumnsSetting() == Rendering.COLUMNS_AUTO_SIZE_TO_FIT) + { + if (combinedWidth == 0) + fColumnCount = 0; + else + { + fColumnCount = availableWidth / combinedWidth; + if (fColumnCount == 0) fColumnCount = 1; // Paint one column even if only part can show in view + } + } + else + fColumnCount = getColumnsSetting(); + + try + { + // Update the number of bytes per row; the max/min scroll range and the current thumbnail position. + + fBytesPerRow = getCharsPerColumn() * getColumnCount(); + getVerticalBar().setMinimum(1); + + // scrollbar maximum range is Integer.MAX_VALUE. + + getVerticalBar().setMaximum(getMaxScrollRange().min(BigInteger.valueOf(Integer.MAX_VALUE)).intValue()); + getVerticalBar().setIncrement(1); + getVerticalBar().setPageIncrement(this.getRowCount() - 1); + + // FIXME: conversion of slider to scrollbar + // fScrollBar.setToolTipText(Rendering.this.getAddressString(fViewportAddress)); + + setScrollSelection(); + } + catch (Exception e) + { + // FIXME precautionary + } + + Rendering.this.redraw(); + Rendering.this.redrawPanes(); + } + + public FPAbstractPane[] getRenderingPanes() + { + return new FPAbstractPane[] { fAddressPane, fDataPane }; + } + + public int getCellPadding() + { + return fCellPadding; + } + + protected int getRenderSpacing() + { + return fPaneSpacing; + } + + public void refresh() + { + if (!this.isDisposed()) + { + if (this.isVisible() && getViewportCache() != null) + { + getViewportCache().refresh(); + } + else + { + setDirty(true); + fParent.updateRenderingLabels(); + } + } + } + + protected void archiveDeltas() + { + this.getViewportCache().archiveDeltas(); + } + + public void gotoAddress(BigInteger address) + { + // Ensure that the GoTo address is within the addressable range + + if ((address.compareTo(this.getMemoryBlockStartAddress()) < 0) || (address.compareTo(this.getMemoryBlockEndAddress()) > 0)) + return; + + fViewportAddress = address; + + // Reset the caret and selection state (no caret and no selection) + + fCaretAddress = null; + fSelection = new Selection(); + + redrawPanes(); + } + + public void setViewportStartAddress(BigInteger newAddress) + { + fViewportAddress = newAddress; + } + + public BigInteger getViewportStartAddress() + { + return fViewportAddress; + } + + public BigInteger getViewportEndAddress() + { + return fViewportAddress.add(BigInteger.valueOf(this.getBytesPerRow() * getRowCount() / getAddressableSize())); + } + + public String getAddressString(BigInteger address) + { + StringBuffer addressString = new StringBuffer(address.toString(16).toUpperCase()); + + for (int chars = getAddressBytes() * 2 - addressString.length(); chars > 0; chars--) + addressString.insert(0, '0'); + + addressString.insert(0, "0x"); //$NON-NLS-1$ + + return addressString.toString(); + } + + protected int getAddressBytes() + { + return fParent.getAddressSize(); + } + + public Control getAddressBarControl() + { + return fAddressBarControl; + } + + public int getColumnCount() + { + return fColumnCount; + } + + public int getColumnsSetting() + { + return fColumnsSetting; + } + + protected void setBytesPerRow(int count) + { + fBytesPerRow = count; + } + + protected void setColumnCount(int count) + { + fColumnCount = count; + } + + public void setColumnsSetting(int columns) + { + if (fColumnsSetting != columns) + { + fColumnsSetting = columns; + fireSettingsChanged(); + layoutPanes(); + } + } + + protected void ensureVisible(BigInteger address) + { + BigInteger viewportStart = this.getViewportStartAddress(); + BigInteger viewportEnd = this.getViewportEndAddress(); + + boolean isAddressBeforeViewportStart = address.compareTo(viewportStart) < 0; + boolean isAddressAfterViewportEnd = address.compareTo(viewportEnd) > 0; + + if (isAddressBeforeViewportStart || isAddressAfterViewportEnd) gotoAddress(address); + } + + protected int getRowCount() + { + int rowCount = 0; + Control panes[] = getRenderingPanes(); + for (int i = 0; i < panes.length; i++) + if (panes[i] instanceof FPAbstractPane) + rowCount = Math.max(rowCount, ((FPAbstractPane) panes[i]).getRowCount()); + + return rowCount; + } + + protected int getBytesPerRow() + { + return fBytesPerRow; + } + + protected int getAddressableCellsPerRow() + { + return getBytesPerRow() / getAddressableSize(); + } + + public int getAddressesPerColumn() + { + return this.getCharsPerColumn() / getAddressableSize(); + } + + /** + * @return Set current scroll selection + */ + protected void setScrollSelection() + { + BigInteger selection = getViewportStartAddress().divide(BigInteger.valueOf(getAddressableCellsPerRow())); + + fScrollSelection = rows2scrollbar(selection); + getVerticalBar().setSelection(fScrollSelection); + } + + /** + * compute the maximum scrolling range. + * + * @return number of lines that rendering can display + */ + private BigInteger getMaxScrollRange() + { + BigInteger difference = getMemoryBlockEndAddress().subtract(getMemoryBlockStartAddress()).add(BigInteger.ONE); + BigInteger maxScrollRange = difference.divide(BigInteger.valueOf(getAddressableCellsPerRow())); + if (maxScrollRange.multiply(BigInteger.valueOf(getAddressableCellsPerRow())).compareTo(difference) != 0) + maxScrollRange = maxScrollRange.add(BigInteger.ONE); + + // Support targets with an addressable size greater than 1 + + maxScrollRange = maxScrollRange.divide(BigInteger.valueOf(getAddressableSize())); + return maxScrollRange; + } + + /** + * The scroll range is limited by SWT. Because it can be less than the number + * of rows (of memory) that we need to display, we need an arithmetic mapping. + * + * @return ratio this function returns how many rows a scroll bar unit + * represents. The number will be some fractional value, up to but + * not exceeding the value 1. I.e., when the scroll range exceeds + * the row range, we use a 1:1 mapping. + */ + private final BigDecimal getScrollRatio() + { + BigInteger maxRange = getMaxScrollRange(); + if (maxRange.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) + { + return new BigDecimal(maxRange).divide(BigDecimal.valueOf(Integer.MAX_VALUE), SCROLL_CONVERSION_PRECISION); + } + + return BigDecimal.ONE; + } + + /** + * Convert memory row units to scroll bar units. The scroll range is limited + * by SWT. Because it can be less than the number of rows (of memory) that + * we need to display, we need an arithmetic mapping. + * + * @param rows + * units of memory + * @return scrollbar units + */ + private int rows2scrollbar(BigInteger rows) + { + return new BigDecimal(rows).divide(getScrollRatio(), SCROLL_CONVERSION_PRECISION).intValue(); + } + + /** + * Convert scroll bar units to memory row units. The scroll range is limited + * by SWT. Because it can be less than the number of rows (of memory) that + * we need to display, we need an arithmetic mapping. + * + * @param scrollbarUnits + * scrollbar units + * @return number of rows of memory + */ + BigInteger scrollbar2rows(int scrollbarUnits) + { + return getScrollRatio().multiply(BigDecimal.valueOf(scrollbarUnits), SCROLL_CONVERSION_PRECISION).toBigInteger(); + } + + /** + * @return start address of the memory block + */ + protected BigInteger getMemoryBlockStartAddress() + { + if (fMemoryBlockStartAddress == null) + fMemoryBlockStartAddress = fParent.getMemoryBlockStartAddress(); + if (fMemoryBlockStartAddress == null) + fMemoryBlockStartAddress = BigInteger.ZERO; + + return fMemoryBlockStartAddress; + } + + /** + * @return end address of the memory block + */ + protected BigInteger getMemoryBlockEndAddress() + { + if (fMemoryBlockEndAddress == null) + fMemoryBlockEndAddress = fParent.getMemoryBlockEndAddress(); + + return fMemoryBlockEndAddress; + } + + public FPDataType getFPDataType() + { + return fFPDataType; + } + + public void setFPDataType(FPDataType numberType) + { + if (fFPDataType == numberType) return; + + fFPDataType = numberType; + fireSettingsChanged(); + layoutPanes(); + } + + public int getUpdateMode() + { + return fUpdateMode; + } + + public void setUpdateMode(int fUpdateMode) + { + this.fUpdateMode = fUpdateMode; + } + + protected String getCharacterSet(int mode) + { + switch (mode) + { + case Rendering.TEXT_UTF8: + return "UTF8"; //$NON-NLS-1$ + + case Rendering.TEXT_UTF16: + return "UTF16"; //$NON-NLS-1$ + + case Rendering.TEXT_USASCII: + return "US-ASCII"; //$NON-NLS-1$ + + case Rendering.TEXT_ISO_8859_1: + default: + return "ISO-8859-1"; //$NON-NLS-1$ + } + } + + public int getBytesPerCharacter() + { + return 1; + } + + public boolean isTargetLittleEndian() + { + return fIsTargetLittleEndian; + } + + public void setTargetLittleEndian(boolean littleEndian) + { + if (fIsTargetLittleEndian == littleEndian) return; + + fParent.setTargetMemoryLittleEndian(littleEndian); + fIsTargetLittleEndian = littleEndian; + + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + fireSettingsChanged(); + layoutPanes(); + } + }); + } + + public boolean isDisplayLittleEndian() + { + return fIsDisplayLittleEndian; + } + + public void setDisplayLittleEndian(boolean isLittleEndian) + { + if (fIsDisplayLittleEndian == isLittleEndian) return; + fIsDisplayLittleEndian = isLittleEndian; + fireSettingsChanged(); + + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + layoutPanes(); + } + }); + } + + public int getCharsPerColumn() + { + return fCharsPerColumn; + } + + public int getDisplayedPrecision() + { + return fDisplayedPrecision; + } + + // Set the number of precision digits that are displayed in the view + + public void setDisplayedPrecision(int displayedPrecision) + { + if (fDisplayedPrecision != displayedPrecision) + { + fDisplayedPrecision = displayedPrecision; + fCharsPerColumn = charsPerColumn(); + fireSettingsChanged(); + layoutPanes(); + } + } + + protected void redrawPane(int paneId) + { + if (!isDisposed() && this.isVisible()) + { + FPAbstractPane pane = null; + + if (paneId == Rendering.PANE_ADDRESS) + { + pane = fAddressPane; + } + else if (paneId == Rendering.PANE_DATA) + { + pane = fDataPane; + } + + if (pane != null && pane.isPaneVisible()) + { + pane.redraw(); + pane.setRowCount(); + if (pane.isFocusControl()) pane.updateTheCaret(); + } + } + + fParent.updateRenderingLabels(); + } + + protected void redrawPanes() + { + if (!isDisposed() && this.isVisible()) + { + if (fAddressPane.isPaneVisible()) + { + fAddressPane.redraw(); + fAddressPane.setRowCount(); + if (fAddressPane.isFocusControl()) fAddressPane.updateTheCaret(); + } + + if (fDataPane.isPaneVisible()) + { + fDataPane.redraw(); + fDataPane.setRowCount(); + if (fDataPane.isFocusControl()) fDataPane.updateTheCaret(); + } + } + + fParent.updateRenderingLabels(); + } + + void layoutPanes() + { + packColumns(); + layout(true); + + redraw(); + redrawPanes(); + } + + void fireSettingsChanged() + { + fAddressPane.settingsChanged(); + fDataPane.settingsChanged(); + } + + protected void copyAddressToClipboard() + { + Clipboard clip = null; + + try + { + clip = new Clipboard(getDisplay()); + + String addressString = "0x" + getCaretAddress().toString(16); //$NON-NLS-1$ + + TextTransfer plainTextTransfer = TextTransfer.getInstance(); + clip.setContents(new Object[] { addressString }, new Transfer[] { plainTextTransfer }); + } + finally + { + if (clip != null) + { + clip.dispose(); + } + } + } + + // Given an array of bytes, the data type and endianness, return a scientific notation string representation + + public String sciNotationString(FPMemoryByte byteArray[], FPDataType fpDataType, boolean isLittleEndian) + { + StringBuffer textString = null; + + // Check the byte array for readability + + for (int index = 0; index < byteArray.length; index++) + if (!byteArray[index].isReadable()) + return FPutilities.fillString(fCharsPerColumn, '?'); + + // Convert the byte array to a floating point value and check to see if it's within the range + // of the data type. If the valid range is exceeded, set string to "-Infinity" or "Infinity". + + ByteOrder byteOrder = isLittleEndian ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; + + if (fpDataType == FPDataType.FLOAT) + { + float floatValue = ByteBuffer.wrap(FPutilities.memoryBytesToByteArray(byteArray)).order(byteOrder).getFloat(); + floatValue = FPutilities.floatLimitCheck(floatValue); + + if (floatValue == Float.NEGATIVE_INFINITY) + textString = new StringBuffer("-Infinity"); //$NON-NLS-1$ + + if (floatValue == Float.POSITIVE_INFINITY) + textString = new StringBuffer(" Infinity"); //$NON-NLS-1$ + } + + if (fpDataType == FPDataType.DOUBLE) + { + double doubleValue = ByteBuffer.wrap(FPutilities.memoryBytesToByteArray(byteArray)).order(byteOrder).getDouble(); + doubleValue = FPutilities.doubleLimitCheck(doubleValue); + + if (doubleValue == Double.NEGATIVE_INFINITY) + textString = new StringBuffer("-Infinity"); //$NON-NLS-1$ + + if (doubleValue == Double.POSITIVE_INFINITY) + textString = new StringBuffer(" Infinity"); //$NON-NLS-1$ + } + + // If we do not already have a StringBuffer value, Convert the value to + // a string. In any case, pad the string with spaces to the cell width. + + if (textString == null) + textString = new StringBuffer(FPutilities.byteArrayToSciNotation(fpDataType, isLittleEndian, byteArray, fDisplayedPrecision)); + + return (textString.append(FPutilities.fillString(fCharsPerColumn - textString.length(), getPaddingCharacter()))).toString(); + } + + // Convert the floating point edit buffer string to a byte array and update memory + + public void convertAndUpdateCell(BigInteger memoryAddress, String editBuffer) + { + if (editBuffer != null && editBuffer.length() > 0) + { + // Convert the edit buffer string to byte arrays + + byte[] targetByteArray = new byte[getFPDataType().getByteLength()]; + + targetByteArray = FPutilities.floatingStringToByteArray(getFPDataType(), editBuffer, getFPDataType().getBitsize()); + + // If we're in little endian mode, reverse the bytes, which is required + // due to lower-level internal conversion when written to memory. + + if (fIsDisplayLittleEndian) + targetByteArray = FPutilities.reverseByteOrder(targetByteArray); + + FPMemoryByte[] newMemoryBytes = new FPMemoryByte[targetByteArray.length]; + + for (int index = 0; index < targetByteArray.length; index++) + { + newMemoryBytes[index] = new FPMemoryByte(targetByteArray[index]); + newMemoryBytes[index].setBigEndian(!isTargetLittleEndian()); + newMemoryBytes[index].setEdited(true); + newMemoryBytes[index].setChanged(true); + } + + // Apply the change and make it visible in the view + + getViewportCache().setEditedValue(memoryAddress, newMemoryBytes); + getViewportCache().writeEditBuffer(); + redraw(); + } + else + { + // The edit buffer string is null or has a zero length. + + final String errorText = NLS.bind(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TEXT"), ""); //$NON-NLS-1$ //$NON-NLS-2$ + + try + { + // Restore the previous value + setEditBuffer(new StringBuffer(fDataPane.bytesToSciNotation(getBytes(fCaretAddress, getFPDataType().getByteLength())))); + } + catch (DebugException e) + { + e.printStackTrace(); + } + + // Put together the pop-up window components and show the user the error + + String statusString = FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_STATUS"); //$NON-NLS-1$ + Status status = new Status(IStatus.ERROR, FPRenderingPlugin.getUniqueIdentifier(), statusString); + FPutilities.popupMessage(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TITLE"), errorText, status); //$NON-NLS-1$ + } + } + + // Getter/setter for Insert Mode state + + public void setInsertMode(boolean insertMode) + { + this.fEditInserMode = insertMode; + } + + public boolean insertMode() + { + return fEditInserMode; + } + + // Getter/setter for cell edit state: true = we're in cell edit mode; false = we're not in cell edit mode + + public boolean isEditingCell() + { + return fCellEditState; + } + + public void setEditingCell(boolean state) + { + this.fCellEditState = state; + } + + // Getter/setter for the address of the cell currently being edited + + public BigInteger getCellEditAddress() + { + return cellEditAddress; + } + + public void setCellEditAddress(BigInteger cellEditAddress) + { + this.cellEditAddress = cellEditAddress; + } + + // Getter/Setter for the memory address of the cell currently being edited + + public BigInteger getMemoryAddress() + { + return memoryAddress; + } + + public void setMemoryAddress(BigInteger memoryAddress) + { + this.memoryAddress = memoryAddress; + } + + // Getter/setter for storing the raw/uninterpreted/not-converted-to-scientific-notation text entry string + + public StringBuffer getEditBuffer() + { + return fEditBuffer; + } + + public void setEditBuffer(StringBuffer cellChars) + { + this.fEditBuffer = cellChars; + } + + // Enter cell-edit mode + + public void startCellEditing(BigInteger cellAddress, BigInteger memoryAddress, String editString) + { + setEditBuffer(new StringBuffer(editString)); + setCellEditAddress(cellAddress); + setMemoryAddress(memoryAddress); + setEditingCell(true); + } + + // Exit cell-edit mode + + public void endCellEditing() + { + setEditingCell(false); + setCellEditAddress(null); + setMemoryAddress(null); + setEditBuffer(null); + + } + + // Floating point number edit mode status-line display: 'true' = display edit mode, 'false' clear edit mode + + public void displayEditModeIndicator(final boolean indicatorON) + { + UIJob job = new UIJob("FP Renderer Edit Indicator") //$NON-NLS-1$ + { + @Override + public IStatus runInUIThread(IProgressMonitor monitor) + { + String statusLineMessage; + IViewPart viewInstance = null; + + if (indicatorON) + { + // Construct the edit mode message + statusLineMessage = NLS.bind(FPRenderingMessages.getString("FPRendering.EDIT_MODE"), //$NON-NLS-1$ + (insertMode() ? FPRenderingMessages.getString("FPRendering.EDIT_MODE_INSERT") : //$NON-NLS-1$ + FPRenderingMessages.getString("FPRendering.EDIT_MODE_OVERWRITE"))); //$NON-NLS-1$ + } + else + { + // 'null' = clear the message + statusLineMessage = null; + } + + // Get the window and page references + + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) return Status.OK_STATUS; + + IWorkbenchPage page = window.getActivePage(); + if (page == null) return Status.OK_STATUS; + + // Update (or clear) the Workbench status line when the Memory and Memory Browser views are in focus + + viewInstance = page.findView("org.eclipse.debug.ui.MemoryView"); // TODO: programmatically retrieve ID //$NON-NLS-1$ + + if (viewInstance != null) + viewInstance.getViewSite().getActionBars().getStatusLineManager().setMessage(statusLineMessage); + + viewInstance = page.findView("org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser"); // TODO: programmatically retrieve ID //$NON-NLS-1$ + + if (viewInstance != null) + viewInstance.getViewSite().getActionBars().getStatusLineManager().setMessage(statusLineMessage); + + return Status.OK_STATUS; + } + }; + + job.setSystem(true); + job.schedule(); + } + + // Calculate memory address from the cell address + + public BigInteger cellToMemoryAddress(BigInteger cellAddress) + { + BigInteger vpStart = getViewportStartAddress(); + BigInteger colChars = BigInteger.valueOf(getCharsPerColumn()); + BigInteger dtBytes = BigInteger.valueOf(getFPDataType().getByteLength()); + + return vpStart.add(((cellAddress.subtract(vpStart)).divide(colChars)).multiply(dtBytes)); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/messages.properties b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/messages.properties new file mode 100644 index 00000000000..eba849c7373 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/messages.properties @@ -0,0 +1,68 @@ +############################################################################### +# Copyright (c) 2009, 2012 Wind River 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 +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Wind River Systems - initial API and implementation +############################################################################### + +FPRendering.ADDRESS=Address +FPRendering.CALLED_ON_NON_DISPATCH_THREAD=Called on non-dispatch thread +FPRendering.COLUMN_COUNT=Columns +FPRendering.COLUMN_COUNT_AUTO=Auto Size to Fill +FPRendering.COLUMN_COUNT_1=1 +FPRendering.COLUMN_COUNT_2=2 +FPRendering.COLUMN_COUNT_4=4 +FPRendering.COLUMN_COUNT_8=8 +FPRendering.COLUMN_COUNT_16=16 +FPRendering.COLUMN_COUNT_32=32 +FPRendering.COLUMN_COUNT_64=64 +FPRendering.COLUMN_COUNT_128=128 +FPRendering.COLUMN_COUNT_CUSTOM=Custom ... +FPRendering.COPY_ADDRESS=Copy Address +FPRendering.DATA=Data +FPRendering.DISPLAYED_PRECISION_4=Four (4) significant digits +FPRendering.DISPLAYED_PRECISION_8=Eight (8) significant digits +FPRendering.DISPLAYED_PRECISION_16=Sixteen (16) significant digits +FPRendering.EDIT_MODE=Editing: {0} +FPRendering.EDIT_MODE_INSERT=Replace existing value +FPRendering.EDIT_MODE_OVERWRITE=Overwrite number (in-place) +FPRendering.ENDIAN=Endian +FPRendering.ENDIAN_BIG=Big +FPRendering.ENDIAN_LITTLE=Little +FPRendering.ERROR_FPENTRY_POPUP_TEXT="{0}" is an invalid floating point number.\rThe previous value has been restored. +FPRendering.ERROR_FPENTRY_POPUP_TITLE=Floating point number error +FPRendering.ERROR_FPENTRY_STATUS=Invalid floating point number +FPRendering.FAILURE_APPEND_SELECTION=Failed to append selection. +FPRendering.FAILURE_COPY_OPERATION=Failed copy operation. +FPRendering.FAILURE_DETERMINE_ADDRESS_SIZE=Failed to determine address size. +FPRendering.FAILURE_DETERMINE_CELL_LOCATION=Failed to determine cell location. +FPRendering.FAILURE_PAINT=Failed to paint. +FPRendering.FAILURE_POSITION_CURSOR=Failed to position cursor. +FPRendering.FAILURE_READ_MEMORY=Failed reading memory. +FPRendering.FAILURE_RETRIEVE_BASE_ADDRESS=Failure in retrieving base address. +FPRendering.FAILURE_RETRIEVE_START_ADDRESS=Failure in retrieving start address. +FPRendering.FAILURE_START_SELECTION=Failed to start selection. +FPRendering.FAILURE_WRITE_MEMORY=Error writing memory. +FPRendering.FLOATING_POINT_32=32-bit Single Precision +FPRendering.FLOATING_POINT_64=64-bit Double Precision +FPRendering.GO_TO_ADDRESS=Go To Address +FPRendering.INFINITY=Infinity +FPRendering.ISO-8859-1=ISO-8859-1 +FPRendering.NUMBER_TYPE=Floating Point Type +FPRendering.NAN=NaN +FPRendering.PANES=Panes +FPRendering.PRECISION=Displayed Precision +FPRendering.REFRESH=Refresh +FPRendering.RENDERING_NAME=Floating Point +FPRendering.RESET_TO_BASE_ADDRESS=Reset To Base Address +FPRendering.UPDATE_ALWAYS=Always +FPRendering.UPDATE_MANUAL=Manual +FPRendering.UPDATE_ON_BREAKPOINT=On Breakpoint +FPRendering.UPDATEMODE=Update Mode +FPRendering.USASCII=US-ASCII +FPRendering.UTF16=UTF-16 +FPRendering.UTF8=UTF-8l \ No newline at end of file diff --git a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties index b9b90abb371..fe3740d2c43 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties +++ b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties @@ -24,7 +24,7 @@ providerName=Eclipse CDT updateSiteName=Eclipse CDT update site # "description" property - description of the feature -description=Additional features for debug Memory View - traditional rendering, Find/Replace, Import/Export. Source code. +description=Additional features for debug Memory View - traditional rendering, floating-point rendering, Find/Replace, Import/Export. Source code. # "licenseURL" property - URL of the "Feature License" # do not translate value - just change to point to a locale-specific HTML page diff --git a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml index e23ed14c442..c64eb902375 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml +++ b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml @@ -31,6 +31,13 @@ version="0.0.0" unpack="false"/> + + CDT Parent - 0.14.1 - 0.14.0 + 0.16.0 + 0.16.0 3.8 http://download.eclipse.org/eclipse/updates/${platform-version} R20110523182458 @@ -134,6 +134,7 @@ util/org.eclipse.cdt.util-feature memory/org.eclipse.cdt.debug.ui.memory.memorybrowser + memory/org.eclipse.cdt.debug.ui.memory.floatingpoint memory/org.eclipse.cdt.debug.ui.memory.search memory/org.eclipse.cdt.debug.ui.memory.traditional memory/org.eclipse.cdt.debug.ui.memory.transport diff --git a/releng/org.eclipse.cdt.repo/pom.xml b/releng/org.eclipse.cdt.repo/pom.xml index 0332b98495d..bdbc29dbf49 100644 --- a/releng/org.eclipse.cdt.repo/pom.xml +++ b/releng/org.eclipse.cdt.repo/pom.xml @@ -27,7 +27,9 @@ http://maven.eclipse.org/nexus/content/repositories/public - + + ${project.artifactId} + production diff --git a/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/WinDiscoveredPathInfo.java b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/WinDiscoveredPathInfo.java index dade707297a..c2cd6721e0b 100644 --- a/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/WinDiscoveredPathInfo.java +++ b/windows/org.eclipse.cdt.msw.build/src/org/eclipse/cdt/msw/build/WinDiscoveredPathInfo.java @@ -35,6 +35,13 @@ public class WinDiscoveredPathInfo implements IDiscoveredPathInfo { symbols.put("__unaligned", ""); symbols.put("__uptr", ""); symbols.put("__w64", ""); + + // Redefine some things so that the CDT parser can handle them, until there is a VC specific parser + symbols.put("__forceinline", "__inline"); + symbols.put("__int8", "char"); + symbols.put("__int16", "short"); + symbols.put("__int32", "int"); + symbols.put("__int64", "long long"); } public IPath[] getIncludePaths() { diff --git a/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF b/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF index 9aad2e6548b..7b2d9a4e6f9 100644 --- a/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF +++ b/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.make.xlc.core;singleton:=true -Bundle-Version: 5.2.0.qualifier +Bundle-Version: 5.2.100.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Require-Bundle: org.eclipse.cdt.make.core, diff --git a/xlc/org.eclipse.cdt.make.xlc.core/pom.xml b/xlc/org.eclipse.cdt.make.xlc.core/pom.xml index 62046bd7090..4c20ec74233 100644 --- a/xlc/org.eclipse.cdt.make.xlc.core/pom.xml +++ b/xlc/org.eclipse.cdt.make.xlc.core/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 5.2.0-SNAPSHOT + 5.2.100-SNAPSHOT org.eclipse.cdt.make.xlc.core eclipse-plugin diff --git a/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java b/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java index d22938913a4..cc9d46ba316 100644 --- a/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java +++ b/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 IBM Corporation and others. + * Copyright (c) 2007, 2012 IBM Corporation 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 @@ -1400,7 +1400,10 @@ public class PerFileXLCScannerInfoCollector implements IScannerInfoCollector3, I if (projectSymbols != null) { for (String symbol : projectSymbols) { - symbols.put(symbol, "1"); //$NON-NLS-1$ + if (symbol.matches("_Builtin")) //$NON-NLS-1$ + symbols.put(symbol,""); //$NON-NLS-1$ + else + symbols.put(symbol, "1"); //$NON-NLS-1$ } } } diff --git a/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/XlCSpecsConsoleParser.java b/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/XlCSpecsConsoleParser.java index 6df289d3a18..189788aaced 100644 --- a/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/XlCSpecsConsoleParser.java +++ b/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/XlCSpecsConsoleParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 IBM Corporation and others. + * Copyright (c) 2006, 2012 IBM Corporation 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 @@ -24,9 +24,12 @@ import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; import org.eclipse.cdt.make.xlc.core.activator.Activator; +import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CProjectNature; /** * Parses output of ppuxlc -E -v specs.c or ppuxlc -E -v specs.cpp command @@ -47,8 +50,12 @@ public class XlCSpecsConsoleParser implements IScannerInfoConsoleParser { final Pattern includePattern = Pattern .compile("-(?:qgcc_c_stdinc|qc_stdinc|qgcc_cpp_stdinc|qcpp_stdinc)=(.*)"); //$NON-NLS-1$ + final Pattern C_includePattern = Pattern.compile("-(?:qgcc_c_stdinc|qc_stdinc)=(.*)"); //$NON-NLS-1$ + final Pattern CXX_includePattern = Pattern.compile("-(?:qgcc_cpp_stdinc|qcpp_stdinc)=(.*)"); //$NON-NLS-1$ + // xlC compiler constants protected final static String [] compilerConstants = { + "_Builtin", //$NON-NLS-1$ "__IBMCPP__", //$NON-NLS-1$ "__xlC__", //$NON-NLS-1$ "__IBMC__", //$NON-NLS-1$ @@ -61,7 +68,18 @@ public class XlCSpecsConsoleParser implements IScannerInfoConsoleParser { protected List symbols = new ArrayList(); - protected List includes = new ArrayList(); + protected List includes = new ArrayList(); + protected List c_includes = new ArrayList(); + protected List cpp_includes = new ArrayList(); + + boolean c_lang; // if language is C only search for the C include paths from the XL Compiler, otherwise get the C++ ones. + public boolean isC_lang() { + return c_lang; + } + + public void setC_lang(boolean c_lang) { + this.c_lang = c_lang; + } /* * (non-Javadoc) @@ -77,6 +95,20 @@ public class XlCSpecsConsoleParser implements IScannerInfoConsoleParser { IScannerInfoCollector collector, IMarkerGenerator markerGenerator) { this.fProject = project; this.fCollector = collector; + + try { + if (project.hasNature(CCProjectNature.CC_NATURE_ID)) { + // use C++ pattern + c_lang = false; + } + else { + // use C pattern + c_lang = true; + } + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } /* @@ -119,7 +151,7 @@ public class XlCSpecsConsoleParser implements IScannerInfoConsoleParser { } else { // if it is not a symbol, check to see if it is an // include - Matcher includeMatcher = includePattern.matcher(args[i]); + Matcher includeMatcher = c_lang ? C_includePattern.matcher(args[i]) : CXX_includePattern.matcher(args[i]); if (includeMatcher.matches()) { // if it is a set of include paths, split it String[] includePaths = includeMatcher.group(1).split(