diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java index 820df07aac7..3dca63cf0c0 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CygpathTranslator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2013 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 @@ -20,8 +20,14 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager; import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICProjectDescription; +import org.eclipse.cdt.internal.core.Cygwin; +import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.utils.CygPath; import org.eclipse.cdt.utils.ICygwinToolsFactroy; import org.eclipse.core.resources.IProject; @@ -32,125 +38,135 @@ import org.eclipse.core.runtime.Platform; /** * Use binary parser's 'cygpath' command to translate cygpaths to absolute paths. + * Note that this class does not support build configurations. * * @author vhirsl */ public class CygpathTranslator { - /** Default Cygwin root dir */ - private static final String DEFAULT_CYGWIN_ROOT= "C:\\cygwin"; //$NON-NLS-1$ - // private static final String CYGPATH_ERROR_MESSAGE = "CygpathTranslator.NotAvailableErrorMessage"; //$NON-NLS-1$ - private CygPath cygPath = null; - private boolean isAvailable = false; - - public CygpathTranslator(IProject project) { - try { - ICConfigExtensionReference[] parserRef = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project); - for (int i = 0; i < parserRef.length; i++) { - try { - IBinaryParser parser = CoreModelUtil.getBinaryParser(parserRef[i]); - ICygwinToolsFactroy cygwinToolFactory = (ICygwinToolsFactroy) parser.getAdapter(ICygwinToolsFactroy.class); - if (cygwinToolFactory != null) { - cygPath = cygwinToolFactory.getCygPath(); - if (cygPath != null) { - isAvailable = true; - break; - } - } - } catch (ClassCastException e) { - } - } - // No CygPath specified in BinaryParser page or not supported. - // Hoping that cygpath is on the path. - if (cygPath == null && Platform.getOS().equals(Platform.OS_WIN32)) { - if (new File(DEFAULT_CYGWIN_ROOT).exists()) { - cygPath = new CygPath(DEFAULT_CYGWIN_ROOT + "\\bin\\cygpath.exe"); //$NON-NLS-1$ - } else { - cygPath = new CygPath("cygpath"); //$NON-NLS-1$ - } - isAvailable = cygPath.getFileName("test").equals("test"); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - catch (CoreException e) { - } - catch (IOException e) { - isAvailable = false; - // Removing markers. if cygpath isn't in your path then you aren't using cygwin. - // Then why are we calling this.... -// scMarkerGenerator.addMarker(project, -1, -// MakeMessages.getString(CYGPATH_ERROR_MESSAGE), -// IMarkerGenerator.SEVERITY_WARNING, null); - } - } - - public static List translateIncludePaths(IProject project, List sumIncludes) { - // first check if cygpath translation is needed at all - boolean translationNeeded = false; - if (Platform.getOS().equals(Platform.OS_WIN32)) { - for (Iterator i = sumIncludes.iterator(); i.hasNext(); ) { + private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ + + private CygPath cygPath = null; + + public CygpathTranslator(IProject project) { + try { + ICConfigExtensionReference[] parserRef = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project); + for (int i = 0; i < parserRef.length; i++) { + try { + IBinaryParser parser = CoreModelUtil.getBinaryParser(parserRef[i]); + ICygwinToolsFactroy cygwinToolFactory = (ICygwinToolsFactroy) parser.getAdapter(ICygwinToolsFactroy.class); + if (cygwinToolFactory != null) { + cygPath = cygwinToolFactory.getCygPath(); + } + } catch (ClassCastException e) { + } + } + } + catch (CoreException e) { + } + } + + public static List translateIncludePaths(IProject project, List sumIncludes) { + // first check if cygpath translation is needed at all + boolean translationNeeded = false; + if (Platform.getOS().equals(Platform.OS_WIN32)) { + for (Iterator i = sumIncludes.iterator(); i.hasNext(); ) { String include = i.next(); if (include.startsWith("/")) { //$NON-NLS-1$ translationNeeded = true; break; } } - } - if (!translationNeeded) { - return sumIncludes; - } - - CygpathTranslator cygpath = new CygpathTranslator(project); - - List translatedIncludePaths = new ArrayList(); - for (Iterator i = sumIncludes.iterator(); i.hasNext(); ) { - String includePath = i.next(); - IPath realPath = new Path(includePath); - // only allow native pathes if they have a device prefix - // to avoid matches on the current drive, e.g. /usr/bin = C:\\usr\\bin - if (realPath.getDevice() != null && realPath.toFile().exists()) { - translatedIncludePaths.add(includePath); - } - else { - String translatedPath = includePath; - if (cygpath.isAvailable) { - try { - translatedPath = cygpath.cygPath.getFileName(includePath); - } - catch (IOException e) { - TraceUtil.outputError("CygpathTranslator unable to translate path: ", includePath); //$NON-NLS-1$ - } - } else if (realPath.segmentCount() >= 2) { - // try default conversions - // /cygdrive/x/ --> X:\ - if ("cygdrive".equals(realPath.segment(0))) { //$NON-NLS-1$ - String drive= realPath.segment(1); - if (drive.length() == 1) { - translatedPath= realPath.removeFirstSegments(2).makeAbsolute().setDevice(drive.toUpperCase() + ':').toOSString(); - } - } - } - if (!translatedPath.equals(includePath)) { - // Check if the translated path exists - if (new File(translatedPath).exists()) { - translatedIncludePaths.add(translatedPath); - } - else if (cygpath.isAvailable) { - // TODO VMIR for now add even if it does not exist - translatedIncludePaths.add(translatedPath); - } - else { - translatedIncludePaths.add(includePath); - } - } - else { - // TODO VMIR for now add even if it does not exist - translatedIncludePaths.add(translatedPath); - } - } - } - if (cygpath.cygPath != null) { - cygpath.cygPath.dispose(); - } - return translatedIncludePaths; - } + } + if (!translationNeeded) { + return sumIncludes; + } + + CygpathTranslator cygpath = new CygpathTranslator(project); + boolean useCygPathExtension = cygpath.cygPath != null; + boolean useCygwinFromPath = !useCygPathExtension; + + String envPath = null; + if (useCygwinFromPath) { + IEnvironmentVariableManager mngr = CCorePlugin.getDefault().getBuildEnvironmentManager(); + ICProjectDescription prjDes = CCorePlugin.getDefault().getProjectDescription(project, false); + if (prjDes != null) { + // we don't know for sure which configuration needs to be used here, so betting on "DefaultSettingConfiguration" + // considering that scanner discovery uses "DefaultSettingConfiguration" rather than "Active" configuration, + // see org.eclipse.cdt.build.core.scannerconfig.ScannerConfigBuilder.build(CfgInfoContext context, ...) + ICConfigurationDescription cfgDes = prjDes.getDefaultSettingConfiguration(); + IEnvironmentVariable envVar = mngr.getVariable(ENV_PATH, cfgDes, true); + if (envVar != null) { + envPath = envVar.getValue(); + } + } + if (envPath == null) { + IEnvironmentVariable envVar = mngr.getVariable(ENV_PATH, null, true); + if (envVar != null) { + envPath = envVar.getValue(); + } + } + + useCygwinFromPath = Cygwin.isAvailable(envPath); + } + + List translatedIncludePaths = new ArrayList(); + for (Iterator i = sumIncludes.iterator(); i.hasNext(); ) { + String includePath = i.next(); + IPath realPath = new Path(includePath); + // only allow native pathes if they have a device prefix + // to avoid matches on the current drive, e.g. /usr/bin = C:\\usr\\bin + if (realPath.getDevice() != null && realPath.toFile().exists()) { + translatedIncludePaths.add(includePath); + } + else { + String translatedPath = includePath; + + if (useCygPathExtension) { + try { + translatedPath = cygpath.cygPath.getFileName(includePath); + } + catch (IOException e) { + TraceUtil.outputError("CygpathTranslator unable to translate path: ", includePath); //$NON-NLS-1$ + } + } else if (useCygwinFromPath) { + try { + translatedPath = Cygwin.cygwinToWindowsPath(includePath, envPath); + } catch (Exception e) { + MakeCorePlugin.log(e); + } + } else if (realPath.segmentCount() >= 2) { + // try default conversions + // /cygdrive/x/ --> X:\ + if ("cygdrive".equals(realPath.segment(0))) { //$NON-NLS-1$ + String drive= realPath.segment(1); + if (drive.length() == 1) { + translatedPath= realPath.removeFirstSegments(2).makeAbsolute().setDevice(drive.toUpperCase() + ':').toOSString(); + } + } + } + if (!translatedPath.equals(includePath)) { + // Check if the translated path exists + if (new File(translatedPath).exists()) { + translatedIncludePaths.add(translatedPath); + } + else if (useCygPathExtension || useCygwinFromPath) { + // TODO VMIR for now add even if it does not exist + translatedIncludePaths.add(translatedPath); + } + else { + translatedIncludePaths.add(includePath); + } + } + else { + // TODO VMIR for now add even if it does not exist + translatedIncludePaths.add(translatedPath); + } + } + } + if (useCygPathExtension) { + cygpath.cygPath.dispose(); + } + return translatedIncludePaths; + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java index 1df00d08f76..13f87f2dcb1 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.managedbuilder.core.tests; -import java.io.File; -import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.Properties; @@ -24,7 +22,6 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoProvider; -import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsScannerInfoProvider; import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; @@ -201,26 +198,6 @@ public class ManagedBuildCoreTests20 extends TestCase { } - /** - * Convert path to OS specific representation - */ - private String toOSLocation(String path) { - File file = new File(path); - try { - path = file.getCanonicalPath(); - } catch (IOException e) { - } - - return path; - } - - /** - * Convert path to OS specific representation - */ - private String toOSString(String path) { - return new Path(path).toOSString(); - } - /** * The purpose of this test is to exercise the build path info interface. * To get to that point, a new project/config has to be created in the test @@ -241,38 +218,18 @@ public class ManagedBuildCoreTests20 extends TestCase { } //These are the expected path settings - IPath buildCWD = project.getLocation().append("Sub Config"); + final String[] expectedPaths = new String[5]; - final String[] expectedPaths; - if (new Path("C:\\home\\tester/include").isAbsolute()) { - // Windows - expectedPaths = new String[] { - toOSLocation("/usr/include"), - toOSLocation("/opt/gnome/include"), - toOSLocation("C:\\home\\tester/include"), - // relative paths from MBS will make 3 entries - project.getLocation().append("includes").toOSString(), - buildCWD.append("includes").toOSString(), - toOSString("includes"), - "/usr/gnu/include", // Not converted to OS string due to being flagged as ICSettingEntry.RESOLVED - }; - } else { - // Unix - expectedPaths = new String[] { - toOSLocation("/usr/include"), - toOSLocation("/opt/gnome/include"), - // on unix "C:\\home\\tester/include" is relative path - // looks like nonsense but has to be this way as MBS converts entry to keep "Sub Config/C:\\home\\tester/include" in its storage - project.getLocation().append("Sub Config/C:\\home\\tester/include").toOSString(), - buildCWD.append("Sub Config/C:\\home\\tester/include").toOSString(), - toOSString("Sub Config/C:\\home\\tester/include"), - // relative paths from MBS will make 3 entries - project.getLocation().append("includes").toOSString(), - buildCWD.append("includes").toOSString(), - toOSString("includes"), - "/usr/gnu/include", // Not converted to OS string due to being flagged as ICSettingEntry.RESOLVED - }; - } + // This first path is a built-in, so it will not be manipulated by build manager + expectedPaths[0] = (new Path("/usr/include")).toOSString(); + expectedPaths[1] = (new Path("/opt/gnome/include")).toOSString(); + IPath path = new Path("C:\\home\\tester/include"); + if(path.isAbsolute()) // for win32 path is treated as absolute + expectedPaths[2] = path.toOSString(); + else // for Linux path is relative + expectedPaths[2] = project.getLocation().append("Sub Config").append(path).toOSString(); + expectedPaths[3] = project.getLocation().append( "includes" ).toOSString(); + expectedPaths[4] = (new Path("/usr/gnu/include")).toOSString(); // Create a new managed project based on the sub project type IProjectType projType = ManagedBuildManager.getExtensionProjectType("test.sub"); @@ -324,7 +281,6 @@ public class ManagedBuildCoreTests20 extends TestCase { // Find the first IScannerInfoProvider that supplies build info for the project IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project); assertNotNull(provider); - assertTrue(provider instanceof LanguageSettingsScannerInfoProvider); // Now subscribe (note that the method will be called after a change provider.subscribe(project, new IScannerInfoChangeListener () { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableManagerToolChain.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableManagerToolChain.java new file mode 100644 index 00000000000..5072fc95c50 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/envvar/EnvironmentVariableManagerToolChain.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2012, 2012 Andrew Gvozdev 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: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.internal.envvar; + +import org.eclipse.cdt.core.cdtvariables.ICdtVariable; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.internal.core.cdtvariables.DefaultVariableContextInfo; +import org.eclipse.cdt.internal.core.cdtvariables.EnvironmentVariableSupplier; +import org.eclipse.cdt.internal.core.cdtvariables.ICoreVariableContextInfo; +import org.eclipse.cdt.internal.core.envvar.DefaultEnvironmentContextInfo; +import org.eclipse.cdt.internal.core.envvar.EnvVarDescriptor; +import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager; +import org.eclipse.cdt.internal.core.envvar.ICoreEnvironmentVariableSupplier; +import org.eclipse.cdt.internal.core.envvar.IEnvironmentContextInfo; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; +import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; +import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; +import org.eclipse.cdt.utils.cdtvariables.ICdtVariableSupplier; +import org.eclipse.cdt.utils.cdtvariables.IVariableContextInfo; + + +/** + * Helper class to resolve environment variables directly from toolchain. The intention is + * to use that in New Project Wizard scenarios when no configuration is available yet. + */ +public class EnvironmentVariableManagerToolChain extends EnvironmentVariableManager { + private static EnvironmentVariableManagerToolChain fInstance = null; + + /** + * Basically, converter from IEnvironmentVariable to ICdtVariable (build macros) which + * is used by EnvironmentVariableManager implementation to resolve variables/macros. + */ + private final class CoreVariableContextInfoToolChain implements ICoreVariableContextInfo { + public final static int CONTEXT_TOOLCHAIN = 1009; // arbitrary value different from ICoreVariableContextInfo.CONTEXT_XXX + + private final IToolChain toolChain; + private final IConfigurationEnvironmentVariableSupplier mbsSupplier; + + private CoreVariableContextInfoToolChain(IToolChain toolChain) { + this.toolChain = toolChain; + this.mbsSupplier = toolChain.getEnvironmentVariableSupplier(); + } + + @Override + public ICdtVariableSupplier[] getSuppliers() { + ICdtVariableSupplier sup = new ICdtVariableSupplier() { + @Override + public ICdtVariable getVariable(String macroName, IVariableContextInfo context) { + IEnvironmentVariable var = mbsSupplier.getVariable(macroName, null, ManagedBuildManager.getEnvironmentVariableProvider()); + return EnvironmentVariableSupplier.getInstance().createBuildMacro(var); + } + @Override + public ICdtVariable[] getVariables(IVariableContextInfo context) { + IEnvironmentVariable[] vars = mbsSupplier.getVariables(null, ManagedBuildManager.getEnvironmentVariableProvider()); + if (vars != null) { + ICdtVariable[] cdtVars = new ICdtVariable[vars.length]; + for (int i = 0; i < vars.length; i++) { + cdtVars[i] = EnvironmentVariableSupplier.getInstance().createBuildMacro(vars[i]); + } + } + return null; + } + + }; + return new ICdtVariableSupplier[] { sup }; + } + + @Override + public IVariableContextInfo getNext() { + return new DefaultVariableContextInfo(ICoreVariableContextInfo.CONTEXT_WORKSPACE, null); + } + + @Override + public int getContextType() { + return CONTEXT_TOOLCHAIN; + } + + @Override + public Object getContextData() { + return toolChain; + } + } + + private final class EnvironmentContextInfoToolChain implements IEnvironmentContextInfo { + private final IToolChain toolChain; + + private EnvironmentContextInfoToolChain(IToolChain toolChain) { + this.toolChain = toolChain; + } + + @Override + public IEnvironmentContextInfo getNext() { + return new DefaultEnvironmentContextInfo(null); + } + + @Override + public ICoreEnvironmentVariableSupplier[] getSuppliers() { + final IConfigurationEnvironmentVariableSupplier cevSupplier = toolChain.getEnvironmentVariableSupplier(); + + ICoreEnvironmentVariableSupplier toolchainSupplier = new ICoreEnvironmentVariableSupplier() { + @Override + public IEnvironmentVariable getVariable(String name, Object context) { + IEnvironmentVariableProvider provider = ManagedBuildManager.getEnvironmentVariableProvider(); + return cevSupplier.getVariable(name, null, provider); + } + @Override + public IEnvironmentVariable[] getVariables(Object context) { + return cevSupplier.getVariables(null, ManagedBuildManager.getEnvironmentVariableProvider()); + } + @Override + public boolean appendEnvironment(Object context) { + // Arbitrary value, it did not appear being used in tested scenarios + return false; + } + }; + return new ICoreEnvironmentVariableSupplier[] { EnvironmentVariableManagerToolChain.fUserSupplier, toolchainSupplier }; + } + + @Override + public Object getContext() { + return toolChain; + } + } + + public static EnvironmentVariableManagerToolChain getDefault() { + if (fInstance == null) + fInstance = new EnvironmentVariableManagerToolChain(); + return fInstance; + } + + @Override + public IEnvironmentContextInfo getContextInfo(Object level) { + if (level instanceof IToolChain) { + return new EnvironmentContextInfoToolChain((IToolChain) level); + } + + return super.getContextInfo(level); + } + + @Override + protected int getMacroContextTypeFromContext(Object context) { + if (context instanceof IToolChain) { + return CoreVariableContextInfoToolChain.CONTEXT_TOOLCHAIN; + } + + return super.getMacroContextTypeFromContext(context); + } + + @Override + public ICoreVariableContextInfo getMacroContextInfoForContext(Object context) { + if (context instanceof IToolChain) { + return new CoreVariableContextInfoToolChain((IToolChain) context); + } + + return super.getMacroContextInfoForContext(context); + } + + /** + * Get environment variable value from toolchain definition. + * + * @param name - name of the variable. + * @param toolChain - toolchain. + * @param resolveMacros - {@code true} to expand macros, {@code false} otherwise. + * + * @return value of the variable. + */ + public IEnvironmentVariable getVariable(String name, IToolChain toolChain, boolean resolveMacros) { + if (name == null || name.isEmpty()) + return null; + + IEnvironmentContextInfo info = getContextInfo(toolChain); + EnvVarDescriptor var = EnvironmentVariableManagerToolChain.getVariable(name,info,true); + + if (var != null && var.getOperation() != IEnvironmentVariable.ENVVAR_REMOVE) { + return resolveMacros ? calculateResolvedVariable(var,info) : var; + } + return null; + } + + /** + * Get environment variable value resolved in context of configuration. + * If no configuration available use toolchain definition. + * + * @param name - name of the variable. + * @param toolChain - toolchain. + * @param resolveMacros - {@code true} to expand macros, {@code false} otherwise. + * + * @return value of the variable. + */ + public String getVariableInConfigurationContext(String name, IToolChain toolChain, boolean resolveMacros) { + if (toolChain == null) { + return null; + } + + IConfiguration cfg = toolChain.getParent(); + ICConfigurationDescription cfgDescription = cfg != null ? ManagedBuildManager.getDescriptionForConfiguration(cfg) : null; + + IEnvironmentVariable var = null; + if (cfgDescription != null) { + var = getVariable(name, cfgDescription, resolveMacros); + } else { + var = getVariable(name, toolChain, resolveMacros); + } + + String value = var != null ? var.getValue() : null; + return value; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java index 8f2b5b7e781..f3e5dc9e034 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 Intel Corporation and others. + * Copyright (c) 2005, 2013 Intel 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 @@ -9,6 +9,7 @@ * Intel Corporation - Initial API and implementation * Enrico Ehrich - http://bugs.eclipse.org/233866 * Marc-Andre Laperle - fix for Cygwin GCC is Not detected (bug 303900) + * Andrew Gvozdev - changes to recognize $CYGWIN_HOME *******************************************************************************/ package org.eclipse.cdt.managedbuilder.gnu.cygwin; @@ -19,9 +20,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; -import org.eclipse.cdt.core.settings.model.util.CDataUtil; +import org.eclipse.cdt.internal.core.Cygwin; import org.eclipse.cdt.managedbuilder.core.IBuildPathResolver; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; @@ -30,40 +30,35 @@ import org.eclipse.cdt.utils.PathUtil; import org.eclipse.cdt.utils.WindowsRegistry; import org.eclipse.cdt.utils.spawner.ProcessFactory; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; /** * @noextend This class is not intended to be subclassed by clients. */ public class CygwinPathResolver implements IBuildPathResolver { - private static final String DEFAULT_ROOT = "C:\\cygwin"; //$NON-NLS-1$ - private static final String TOOL = "/cygpath -w -p "; //$NON-NLS-1$ - private static final char BS = '\\'; - private static final char SLASH = '/'; + private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ + private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$ + private static final String DELIMITER_WIN = ";"; //$NON-NLS-1$ + private static final String PROPERTY_OS_NAME = "os.name"; //$NON-NLS-1$ - private static final String PROPERTY_OS_VALUE = "windows";//$NON-NLS-1$ - private static final String SP = " "; //$NON-NLS-1$ - private static final String REGISTRY_KEY_SETUP = "SOFTWARE\\Cygwin\\setup"; //$NON-NLS-1$ - private static final String REGISTRY_KEY_SETUP_WIN64 = "SOFTWARE\\Wow6432Node\\Cygwin\\setup"; //$NON-NLS-1$ + private static final String OS_WINDOWS = "windows";//$NON-NLS-1$ + private static final char SLASH = '/'; + private static final char BACKSLASH = '\\'; + + private static final String CYGPATH_PATH_LIST_TO_WINDOWS = "cygpath -w -p "; //$NON-NLS-1$ + // note that in Cygwin 1.7 the mount point storage has been moved out of the registry private static final String REGISTRY_KEY_MOUNTS = "SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\"; //$NON-NLS-1$ private static final String PATH_NAME = "native"; //$NON-NLS-1$ - private static final String SSLASH = "/"; //$NON-NLS-1$ - private static final String BSLASH = "\\\\"; //$NON-NLS-1$ private static final String BINPATTERN = "/usr/bin"; //$NON-NLS-1$ private static final String BINPATTERN_ALTERNATE = "/bin"; //$NON-NLS-1$ private static final String ETCPATTERN = "/etc"; //$NON-NLS-1$ - private static final String ROOTPATTERN = SSLASH; - private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$ - private static final String DELIMITER_WIN = ";"; //$NON-NLS-1$ + private static final String GCC_VERSION_CMD = "gcc --version"; //$NON-NLS-1$ private static final String MINGW_SPECIAL = "mingw "; //$NON-NLS-1$ private static final String CYGWIN_SPECIAL = "cygwin "; //$NON-NLS-1$ - private static String envPathValueCached = null; - private static String binCygwin = null; - private static String rootCygwin = null; - private static String etcCygwin = null; - @Override public String[] resolveBuildPaths(int pathType, String variableName, String variableValue, IConfiguration configuration) { if(!isWindows()) { @@ -72,58 +67,66 @@ public class CygwinPathResolver implements IBuildPathResolver { return variableValue.split(DELIMITER_WIN); } - String[] result = variableValue.split(DELIMITER_UNIX); - String exePath = getBinPath(); - if (exePath == null) { - return result; // no changes - } - File file = new File(exePath); - if (!file.exists() || !file.isDirectory()) { - return result; // no changes - } - String s = exePath + TOOL + variableValue; - String[] lines = exec(s, configuration); + String[] lines = executeInConfigurationContext(CYGPATH_PATH_LIST_TO_WINDOWS + variableValue, configuration); if (lines != null && lines.length > 0) { - result = lines[0].replace(BS,SLASH).split(DELIMITER_WIN); + String pathList = lines[0].replace(BACKSLASH, SLASH); + return pathList.split(DELIMITER_WIN); } - return result; + + return variableValue.split(DELIMITER_UNIX); } /** - * returns "/etc" path in Windows format + * @return "/etc" path in Windows format for workspace. + * @deprecated. Deprecated as of CDT 8.2. Note that Cygwin root path in general may depend on configuration. * * If you use this do not cache results to ensure user preferences are accounted for. * Please rely on internal caching. */ + @Deprecated public static String getEtcPath() { - findPaths(); + String etcCygwin = getPathFromRoot(ETCPATTERN); + // Try to find the paths in SOFTWARE\\Cygnus Solutions + if(etcCygwin == null) { + etcCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ETCPATTERN, PATH_NAME); + } return etcCygwin; } /** - * returns "/usr/bin" path in Windows format + * @return "/usr/bin" path in Windows format for workspace. + * @deprecated. Deprecated as of CDT 8.2. Note that Cygwin root path in general may depend on configuration. * * If you use this do not cache results to ensure user preferences are accounted for. * Please rely on internal caching. */ + @Deprecated public static String getBinPath() { - findPaths(); + String binCygwin = getPathFromRoot(BINPATTERN); + if(binCygwin == null) { + binCygwin = getPathFromRoot(BINPATTERN_ALTERNATE); + } + // Try to find the paths in SOFTWARE\\Cygnus Solutions + if(binCygwin == null) { + binCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + BINPATTERN, PATH_NAME); + } return binCygwin; } /** - * returns Cygwin root ("/") path in Windows format + * @return Cygwin root ("/") path in Windows format for workspace. + * @deprecated. Deprecated as of CDT 8.2. Note that Cygwin root path in general may depend on configuration. * * If you use this do not cache results to ensure user preferences are accounted for. * Please rely on internal caching. */ + @Deprecated public static String getRootPath() { - findPaths(); - return rootCygwin; + return Cygwin.getCygwinHome(); } public static boolean isWindows() { - return (System.getProperty(PROPERTY_OS_NAME).toLowerCase().startsWith(PROPERTY_OS_VALUE)); + return (System.getProperty(PROPERTY_OS_NAME).toLowerCase().startsWith(OS_WINDOWS)); } /** @@ -136,146 +139,117 @@ public class CygwinPathResolver implements IBuildPathResolver { */ private static String readValueFromRegistry(String key, String name) { WindowsRegistry registry = WindowsRegistry.getRegistry(); - if (null != registry) { - String s = registry.getCurrentUserValue(key, name); - if(s == null) - s = registry.getLocalMachineValue(key, name); - - if (s != null) - return (s.replaceAll(BSLASH, SSLASH)); - } - return null; - } - - /** - * Returns the absolute path of the pattern by - * simply appending the pattern to the root - * - * @param pattern The pattern to find - * @return The absolute path to the pattern or null if pattern is not found - */ - private static String getValueFromRoot(String pattern) { - if (rootCygwin != null) { - String path = rootCygwin + pattern; - File file = new File(path); - if (file.exists() && file.isDirectory()) - return (path.replaceAll(BSLASH, SSLASH)); - else - return null; - } - - return null; - } - - /** - * Returns the absolute path to cygwin's root - * - * @return The absolute path to cygwin's root or null if not found - */ - private static String findRoot(String paths) { - String rootValue = null; - - // 1. Look in PATH values. Look for bin\cygwin1.dll - IPath location = PathUtil.findProgramLocation("cygwin1.dll", paths); //$NON-NLS-1$ - if (location!=null) { - rootValue = location.removeLastSegments(2).toOSString(); - } - - // 2. Try to find the root dir in SOFTWARE\Cygwin\setup - if(rootValue == null) { - rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP, "rootdir"); //$NON-NLS-1$ - } - - // 3. Try to find the root dir in SOFTWARE\Wow6432Node\Cygwin\setup - if(rootValue == null) { - rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP_WIN64, "rootdir"); //$NON-NLS-1$ - } - - // 4. Try to find the root dir in SOFTWARE\Cygnus Solutions - if (rootValue == null) { - rootValue = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ROOTPATTERN, PATH_NAME); - } - - // 5. Try the default Cygwin install dir - if(rootValue == null) { - File file = new File(DEFAULT_ROOT); - if (file.exists() && file.isDirectory()) - rootValue = DEFAULT_ROOT; - } - - if(rootValue != null) - rootValue = rootValue.replaceAll(BSLASH, SSLASH); - - return rootValue; - } - - /** - * Finds Cygwin's paths and sets corresponding properties. - */ - private static synchronized void findPaths() { - if (!isWindows()) { - return; - } - - IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable("PATH", null, true); //$NON-NLS-1$ - String envPathValue = varPath != null ? varPath.getValue() : null; - - if (CDataUtil.objectsEqual(envPathValue, envPathValueCached)) { - return; - } - - etcCygwin = null; - binCygwin = null; - rootCygwin = null; - - rootCygwin = findRoot(envPathValue); - - // 1. Try to find the paths by appending the patterns to the root dir - etcCygwin = getValueFromRoot(ETCPATTERN); - binCygwin = getValueFromRoot(BINPATTERN); - if(binCygwin == null) - binCygwin = getValueFromRoot(BINPATTERN_ALTERNATE); - - // 2. Try to find the paths in SOFTWARE\\Cygnus Solutions - if(etcCygwin == null) - etcCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ETCPATTERN, PATH_NAME); - if(binCygwin == null) - binCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + BINPATTERN, PATH_NAME); - - envPathValueCached = envPathValue; - } - - private static String[] exec(String cmd, IConfiguration cfg) { - try { - IEnvironmentVariable vars[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true); - String env[] = new String[vars.length]; - for(int i = 0; i < env.length; i++) { - env[i] = vars[i].getName() + "="; //$NON-NLS-1$ - String value = vars[i].getValue(); - if(value != null) - env[i] += value; + if (registry != null) { + String value = registry.getCurrentUserValue(key, name); + if (value == null) { + value = registry.getLocalMachineValue(key, name); } - Process proc = ProcessFactory.getFactory().exec(cmd.split(SP), env); - if (proc != null) { + if (value != null) { + return value.replace(BACKSLASH, SLASH); + } + } + return null; + } - InputStream ein = proc.getInputStream(); - BufferedReader d1 = new BufferedReader(new InputStreamReader(ein)); - ArrayList ls = new ArrayList(10); - String s; - while ((s = d1.readLine() ) != null ) { - ls.add(s); + /** + * Returns the absolute path of the pattern by simply appending the relativePath to the root. + * + * @param relativePath - the pattern to find. + * @return The absolute path to the pattern or {@code null} if path does not exist. + */ + private static String getPathFromRoot(String relativePath) { + String rootCygwin = Cygwin.getCygwinHome(); + if (rootCygwin != null) { + String path = rootCygwin + relativePath; + File file = new File(path); + if (file.exists() && file.isDirectory()) { + return path.replace(BACKSLASH, SLASH); + } + } + return null; + } + + /** + * Resolve and return full path to program in context of configuration. + * + * @param program - program to resolve. + * @param cfg - configuration context. + * @return absolute path to program. + */ + private static String resolveProgram(String program, IConfiguration cfg) { + String envPathValue = null; + try { + IEnvironmentVariable envPathVar = ManagedBuildManager.getEnvironmentVariableProvider().getVariable(ENV_PATH, cfg, true); + if (envPathVar != null) { + envPathValue = envPathVar.getValue(); + IPath progPath = PathUtil.findProgramLocation(program, envPathValue); + if (progPath != null) { + program = progPath.toOSString(); + } + // this resolves cygwin symbolic links + program = Cygwin.cygwinToWindowsPath(program, envPathValue); + } + } catch (Exception e) { + GnuUIPlugin.getDefault().log(new Status(IStatus.WARNING, GnuUIPlugin.PLUGIN_ID, "Problem trying to find program [" + program + "] in $PATH=[" + envPathValue + "]", e)); + } + return program; + } + + /** + * Return environment in envp format, see {@link Runtime#exec(String, String[])}. + * + * @param cfg - configuration. + * @return environment as array of strings in format name=value. + */ + private static String[] getEnvp(IConfiguration cfg) { + IEnvironmentVariable vars[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true); + String envp[] = new String[vars.length]; + for(int i = 0; i < envp.length; i++) { + envp[i] = vars[i].getName() +'='; + String value = vars[i].getValue(); + if(value != null) + envp[i] += value; + } + return envp; + } + + /** + * Execute command taking in account configuration environment. + * + * @param cmd - command to execute. + * @param cfg - configuration context. + * @return command output as string array. + */ + private static String[] executeInConfigurationContext(String cmd, IConfiguration cfg) { + String[] args = cmd.split(" "); //$NON-NLS-1$ + args[0] = resolveProgram(args[0], cfg); + + String[] result = null; + try { + String[] envp = getEnvp(cfg); + Process proc = ProcessFactory.getFactory().exec(args, envp); + if (proc != null) { + InputStream ein = proc.getInputStream(); + try { + BufferedReader d1 = new BufferedReader(new InputStreamReader(ein)); + ArrayList ls = new ArrayList(10); + String s; + while ((s = d1.readLine()) != null ) { + ls.add(s); + } + result = ls.toArray(new String[0]); + } finally { + ein.close(); } - ein.close(); - return ls.toArray(new String[0]); } } catch (IOException e) { - GnuUIPlugin.getDefault().log(e); + GnuUIPlugin.getDefault().log(new Status(IStatus.ERROR, GnuUIPlugin.PLUGIN_ID, "Error executing program [" +cmd + "]", e)); } - return null; + return result; } public static boolean isMinGW(IConfiguration cfg) { - String versionInfo[] = exec(GCC_VERSION_CMD, cfg); + String versionInfo[] = executeInConfigurationContext(GCC_VERSION_CMD, cfg); if(versionInfo != null) { for(int i = 0; i < versionInfo.length; i++) { if(versionInfo[i].indexOf(MINGW_SPECIAL) != -1) diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java index ae08fcf841d..5b659ead2d2 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java @@ -1,33 +1,38 @@ /******************************************************************************* - * Copyright (c) 2005, 2011 Intel Corporation and others. + * Copyright (c) 2005, 2012 Intel 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: - * Intel Corporation - Initial API and implementation + * Intel Corporation - Initial API and implementation + * Andrew Gvozdev - Ability to use different Cygwin versions in different cfg *******************************************************************************/ package org.eclipse.cdt.managedbuilder.gnu.cygwin; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.internal.core.Cygwin; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider; import org.eclipse.cdt.managedbuilder.internal.envvar.BuildEnvVar; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; /** * @noextend This class is not intended to be subclassed by clients. */ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfigurationEnvironmentVariableSupplier { - private static final String PATH = "PATH"; //$NON-NLS-1$ - private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$ - private static final String PROPERTY_DELIMITER = "path.separator"; //$NON-NLS-1$ - private static final String PROPERTY_OSNAME = "os.name"; //$NON-NLS-1$ + private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ + private static final String ENV_LANG = "LANG"; //$NON-NLS-1$ + private static final String ENV_LC_ALL = "LC_ALL"; //$NON-NLS-1$ + private static final String ENV_LC_MESSAGES = "LC_MESSAGES"; //$NON-NLS-1$ - private static final String LANG = "LANG"; //$NON-NLS-1$ - private static final String LC_ALL = "LC_ALL"; //$NON-NLS-1$ - private static final String LC_MESSAGES = "LC_MESSAGES"; //$NON-NLS-1$ + private static final String PROPERTY_OSNAME = "os.name"; //$NON-NLS-1$ + private static final String BACKSLASH = java.io.File.separator; @Override public IBuildEnvironmentVariable getVariable(String variableName, IConfiguration configuration, IEnvironmentVariableProvider provider) { @@ -39,19 +44,33 @@ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfiguration return null; } - if (variableName.equalsIgnoreCase(PATH)) { - String p = CygwinPathResolver.getBinPath(); - if (p != null) { - return new BuildEnvVar(PATH, p.replace('/','\\'), IBuildEnvironmentVariable.ENVVAR_PREPEND, System.getProperty(PROPERTY_DELIMITER, DELIMITER_UNIX)); + if (variableName.equalsIgnoreCase(ENV_PATH)) { + @SuppressWarnings("nls") + String path = "${" + Cygwin.ENV_CYGWIN_HOME + "}" + BACKSLASH + "bin"; + return new BuildEnvVar(ENV_PATH, path, IBuildEnvironmentVariable.ENVVAR_PREPEND); + + } else if (variableName.equals(Cygwin.ENV_CYGWIN_HOME)) { + String home = Cygwin.getCygwinHome(); + // If the variable is not defined still show it in the environment variables list as a hint to user + if (home == null) { + home = ""; //$NON-NLS-1$ } - } else if (variableName.equalsIgnoreCase(LANG)) { + IPath homePath = new Path(home); + IEnvironmentVariable varCygwinHome = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(Cygwin.ENV_CYGWIN_HOME, null, false); + if (varCygwinHome == null || (!homePath.equals(new Path(varCygwinHome.getValue())))) { + // Contribute if the variable does not already come from workspace environment + return new BuildEnvVar(Cygwin.ENV_CYGWIN_HOME, homePath.toOSString()); + } + return null; + + } else if (variableName.equalsIgnoreCase(ENV_LANG)) { // Workaround for not being able to select encoding for CDT console -> change codeset to Latin1 - String langValue = System.getenv(LANG); + String langValue = System.getenv(ENV_LANG); if (langValue == null || langValue.length() == 0) { - langValue = System.getenv(LC_ALL); + langValue = System.getenv(ENV_LC_ALL); } if (langValue == null || langValue.length() == 0) { - langValue = System.getenv(LC_MESSAGES); + langValue = System.getenv(ENV_LC_MESSAGES); } if (langValue != null && langValue.length() > 0) { // langValue is [language[_territory][.codeset][@modifier]], i.e. "en_US.UTF-8@dict" @@ -61,21 +80,17 @@ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfiguration } else { langValue = "C.ISO-8859-1"; //$NON-NLS-1$ } - - return new BuildEnvVar(LANG, langValue); + return new BuildEnvVar(ENV_LANG, langValue); } return null; } @Override public IBuildEnvironmentVariable[] getVariables(IConfiguration configuration, IEnvironmentVariableProvider provider) { - IBuildEnvironmentVariable varLang = getVariable(LANG, configuration, provider); - IBuildEnvironmentVariable varPath = getVariable(PATH, configuration, provider); + IBuildEnvironmentVariable varHome = getVariable(Cygwin.ENV_CYGWIN_HOME, configuration, provider); + IBuildEnvironmentVariable varLang = getVariable(ENV_LANG, configuration, provider); + IBuildEnvironmentVariable varPath = getVariable(ENV_PATH, configuration, provider); - if (varPath != null) { - return new IBuildEnvironmentVariable[] {varLang, varPath}; - } else { - return new IBuildEnvironmentVariable[] {varLang}; - } + return new IBuildEnvironmentVariable[] {varHome, varLang, varPath}; } } diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java index a2d2050338a..9a2fd648827 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 Intel Corporation and others. + * Copyright (c) 2005, 2013 Intel 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 @@ -7,85 +7,28 @@ * * Contributors: * Intel Corporation - Initial API and implementation + * Andrew Gvozdev - Ability to use different Cygwin versions in different configurations *******************************************************************************/ package org.eclipse.cdt.managedbuilder.gnu.cygwin; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; - -import org.eclipse.cdt.core.settings.model.util.CDataUtil; +import org.eclipse.cdt.internal.core.Cygwin; import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported; import org.eclipse.cdt.managedbuilder.core.IToolChain; +import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManagerToolChain; import org.osgi.framework.Version; /** * This class implements the IManagedIsToolChainSupported for the Gnu Cygwin tool-chain - * The class is NOT used currently, because currently the gnu cygwin tool-chain - * is intended to be used not only with Cygwin, but with MinGW also, and there is no - * correct way of determining whether the appropriate packages are installed for MinGW. - * - * For the future MBS/CDT versions we might create the separate tool-chain/configuration/project-type - * for the MinGW and define a set of converters using the tool-chain converter mechanism that MBS will provide, - * that would convert the CygWin to the MinGW projects/tool-chains, and vice a versa. * * @noextend This class is not intended to be subclassed by clients. */ public class IsGnuCygwinToolChainSupported implements IManagedIsToolChainSupported { - private static final String[] CHECKED_NAMES = {"gcc", "binutils", "make"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ - private static String etcCygwinCached = null; - private static boolean toolchainIsSupported = false; - - /** - * @since 8.0 - */ @Override public boolean isSupported(IToolChain toolChain, Version version, String instance) { - String etcCygwin = CygwinPathResolver.getEtcPath(); - if (CDataUtil.objectsEqual(etcCygwin, etcCygwinCached)) { - return toolchainIsSupported; - } - - toolchainIsSupported = etcCygwin != null && arePackagesInstalled(etcCygwin); - etcCygwinCached = etcCygwin; - - return toolchainIsSupported; + String envPath = EnvironmentVariableManagerToolChain.getDefault().getVariableInConfigurationContext(ENV_PATH, toolChain, true); + return Cygwin.isAvailable(envPath); } - /** - * Returns true if all required packages are installed, see CHECKED_NAMES for a list of packages. Cygwin - * maintains a list of packages in /etc/setup/installed.db so we look for packages in this file. - * - * @param etcCygwin the absolute path of /etc containing /setup/installed.db - * @return true if the packages specified in CHECKED_NAMES are installed - */ - private boolean arePackagesInstalled(String etcCygwin) { - boolean arePackagesInstalled = false; - File file = new File(etcCygwin + "/setup/installed.db"); //$NON-NLS-1$ - try { - BufferedReader data = new BufferedReader(new FileReader(file)); - - // All required package names should be found - boolean[] found = new boolean[CHECKED_NAMES.length]; - String s; - while ((s = data.readLine()) != null ) { - for (int j = 0; j < CHECKED_NAMES.length; j++) { - if (s.startsWith(CHECKED_NAMES[j])) { - found[j] = true; - } - } - } - arePackagesInstalled = true; - for (int j = 0; j < CHECKED_NAMES.length; j++) { - arePackagesInstalled &= found[j]; - } - data.close(); - } catch (FileNotFoundException e) { - } catch (IOException e) { - } - return arePackagesInstalled; - } } diff --git a/codan/org.eclipse.cdt.codan.core.test/pom.xml b/codan/org.eclipse.cdt.codan.core.test/pom.xml index ee202abfb79..1f00466e914 100644 --- a/codan/org.eclipse.cdt.codan.core.test/pom.xml +++ b/codan/org.eclipse.cdt.codan.core.test/pom.xml @@ -24,7 +24,7 @@ true - -Xms256m -Xmx512m -XX:MaxPermSize=256M + -ea -Xms256m -Xmx512m -XX:MaxPermSize=256M **/AutomatedIntegrationSuite.* diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index 5f28ad59cf6..eb2d81fa18e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 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 @@ -9,6 +9,7 @@ * Devin Steffler (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -6060,14 +6061,14 @@ public class AST2CPPSpecTest extends AST2SpecTestBase { BindingAssertionHelper bh= new BindingAssertionHelper(code, true); ICPPTemplateInstance inst; inst= bh.assertNonProblem("f1(v)", 2); - assertEquals("<20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("f1<20>(v)", -3); - assertEquals("<20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); bh.assertProblem("f2(v)", 2); inst= bh.assertNonProblem("f2<10>(v)", -3); - assertEquals("<10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("f3(v)", 2); - assertEquals("<10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); } // template class A { }; @@ -6086,9 +6087,9 @@ public class AST2CPPSpecTest extends AST2SpecTestBase { ICPPTemplateInstance inst; bh.assertProblem("g(a1)", 1); inst= bh.assertNonProblem("g<0>(a1)", -4); - assertEquals("<0>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("f(a1, a2)", 1); - assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); } // template class A { @@ -6134,9 +6135,9 @@ public class AST2CPPSpecTest extends AST2SpecTestBase { ICPPTemplateInstance inst; bh.assertProblem("f(a)", 1); inst= bh.assertNonProblem("f<1>(a)", -3); - assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("g(b)", 1); - assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); } // template void f(void(*)(T,int)); 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 b7f7c8bee72..ef945c40951 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 @@ -13,6 +13,7 @@ * Sergey Prigogin (Google) * Thomas Corbat (IFS) * Nathan Ridge + * Marc-Andre Laperle *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -128,6 +129,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod; @@ -7480,6 +7482,14 @@ public class AST2CPPTests extends AST2TestBase { BindingAssertionHelper ba= getAssertionHelper(); ba.assertProblem("enum_name", 9); } + + // struct MyStruct { + // enum MyEnum {}; + // MyStruct(MyEnum value) {} + // }; + public void testEnumRedefinitionInStruct_385144() throws Exception { + parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); + } // class CL { // typedef int x; @@ -10125,4 +10135,64 @@ public class AST2CPPTests extends AST2TestBase { parseAndCheckBindings(getAboveComment(), CPP, true); } + // template + // T bar(); + // struct S { + // void waldo(); + // }; + // int main() { + // auto L = [](S s) { return s; }; + // typedef decltype(L) lambda_type; + // decltype(bar()(S())) v; + // v.waldo(); + // } + public void testDecltypeWithConstantLambda_397494() throws Exception { + parseAndCheckBindings(); + } + + // template + // struct enable_if { + // }; + // template <> + // struct enable_if { + // typedef void type; + // }; + // struct base {}; + // struct derived : base {}; + // typedef enable_if<__is_base_of(base, derived)>::type T; + public void testIsBaseOf_399353() throws Exception { + parseAndCheckBindings(getAboveComment(), CPP, true); + } + + // template struct B{}; + // template <> + // struct B { + // void waldo(); + // }; + // typedef char& one; + // int main() { + // B b; + // b.waldo(); + // } + public void testSizeofReference_397342() throws Exception { + parseAndCheckBindings(); + } + + // struct A { + // char a[100]; + // }; + // struct B { + // A& b; + // }; + // A* p; + public void testSizeofStructWithReferenceField_397342() throws Exception { + BindingAssertionHelper bh = getAssertionHelper(); + IASTName nameB = bh.findName("B"); + IASTName namep = bh.findName("p"); + ICPPClassType B = (ICPPClassType) nameB.resolveBinding(); + IPointerType ptrToA = (IPointerType) ((ICPPVariable) namep.resolveBinding()).getType(); + long pointerSize = SizeofCalculator.getSizeAndAlignment(ptrToA, namep).size; + long BSize = SizeofCalculator.getSizeAndAlignment(B, nameB).size; + assertEquals(pointerSize, BSize); + } } 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 c06be8560cc..31e4ef589b2 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 @@ -4405,6 +4405,17 @@ public class AST2TemplateTests extends AST2TestBase { parseAndCheckBindings(); } + // template + // void foo(A); + // template + // void foo(A, B...); + // int main() { + // foo(0); + // } + public void testFunctionTemplatePartialOrdering_388805() throws Exception { + parseAndCheckBindings(); + } + // template class CT {}; // template class CTI {}; // @@ -4830,6 +4841,25 @@ public class AST2TemplateTests extends AST2TestBase { ub= bh.assertNonProblem("f(h(args...) + args...)", 1); } + // template + // struct contains_waldo; + // template <> + // struct contains_waldo<> { + // static const bool value = false; + // }; + // template + // struct contains_waldo { + // static const bool value = contains_waldo::value; + // }; + // int main() { + // bool b1 = contains_waldo::value; + // bool b2 = contains_waldo::value; + // bool b2 = contains_waldo::value; + // } + public void testRecursiveVariadicTemplate_397828() throws Exception { + parseAndCheckBindings(); + } + // struct Test { // void Update() {} // }; @@ -7021,7 +7051,7 @@ public class AST2TemplateTests extends AST2TestBase { // void test() { // int x = C::id; // } - public void _testDependentEnumValue_389009() throws Exception { + public void testDependentEnumValue_389009() throws Exception { BindingAssertionHelper ah = getAssertionHelper(); IEnumerator binding = ah.assertNonProblem("C::id", "id"); IValue value = binding.getValue(); @@ -7029,4 +7059,110 @@ public class AST2TemplateTests extends AST2TestBase { assertNotNull(num); assertEquals(1, num.longValue()); } + + // template struct A {}; + // template void foo(A); + // int main() { + // foo(A<0>()); + // } + public void testVariadicNonTypeTemplateParameter_382074() throws Exception { + parseAndCheckBindings(); + } + + // template + // struct ice_or { + // static const bool value = false; + // }; + // template + // struct is_foo { + // static const bool value = false; + // }; + // template + // struct contains_foo { + // static const bool value = ice_or::value...>::value; + // }; + // template + // struct meta; + // struct S { void bar(); }; + // template <> + // struct meta { + // typedef S type; + // }; + // int main() { + // meta::value>::type t; + // t.bar(); + // } + public void testVariadicNonTypeTemplateParameter_399039() throws Exception { + parseAndCheckBindings(); + } + + // template + // struct common_type; + // template + // struct common_type { + // typedef int type; + // }; + // template + // struct common_type { + // typedef int type; + // }; + // typedef common_type::type type; + public void testClassTemplateSpecializationPartialOrdering_398044a() throws Exception { + parseAndCheckBindings(); + } + + // template + // class A; + // template + // class A { + // }; + // template + // class A { + // }; + // int main() { + // A mf; + // } + public void testClassTemplateSpecializationPartialOrdering_398044b() throws Exception { + parseAndCheckBindings(); + } + + // template + // struct meta { + // static const bool value = 1; + // }; + // template + // struct enable_if {}; + // template <> + // struct enable_if { + // typedef void type; + // }; + // template + // struct pair { + // template ::value>::type> + // pair(int); + // }; + // void push_back(pair&&); + // void push_back(const pair&); + // void test() { + // push_back(0); + // } + public void testRegression_399142() throws Exception { + parseAndCheckBindings(); + } + + // template + // struct A { + // struct impl { + // static T x; + // }; + // static const int value = sizeof(impl::x); + // }; + // template struct W {}; + // template <> struct W<1> { typedef int type; }; + // int main() { + // W::value>::type w; + // } + public void testDependentExpressionInvolvingFieldInNestedClass_399362() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java index afb76a90c9d..54928023f80 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java @@ -110,6 +110,7 @@ public class AST2TestBase extends BaseTestCase { map.put("__SIZEOF_SHORT__", "2"); map.put("__SIZEOF_INT__", "4"); map.put("__SIZEOF_LONG__", "8"); + map.put("__SIZEOF_POINTER__", "8"); return map; } @@ -118,6 +119,7 @@ public class AST2TestBase extends BaseTestCase { map.put("__SIZEOF_SHORT__", "2"); map.put("__SIZEOF_INT__", "4"); map.put("__SIZEOF_LONG__", "8"); + map.put("__SIZEOF_POINTER__", "8"); return map; } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index a0863b741a4..096032fb9ab 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -57,9 +57,11 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTNullStatement; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; @@ -7426,4 +7428,29 @@ public class AST2Tests extends AST2TestBase { public void testNoRawStringInPlainC_397127() throws Exception { parseAndCheckBindings(getAboveComment(), C, true); } + + // #define X + // int a=X-1;X + public void testMacroReferences_399394() throws Exception { + IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment()); + assertEquals(2, countMacroRefs(tu)); + + IASTSimpleDeclaration decl= getDeclaration(tu, 0); + assertEquals(1, countMacroRefs(decl)); + + IASTEqualsInitializer init= (IASTEqualsInitializer) decl.getDeclarators()[0].getInitializer(); + assertEquals(1, countMacroRefs(init)); + + IASTUnaryExpression expr= (IASTUnaryExpression) init.getInitializerClause(); + assertEquals(0, countMacroRefs(expr)); + } + + private int countMacroRefs(IASTNode node) { + int count = 0; + for (IASTNodeLocation loc : node.getNodeLocations()) { + if (loc instanceof IASTMacroExpansionLocation) + count++; + } + return count; + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 2c1033ffc30..54d2e340f7a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -23,12 +23,14 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; 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.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; @@ -2063,6 +2065,27 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa checkBindings(); } + // template + // struct B { + // enum { value = 1 }; + // }; + // + // template + // struct C { + // enum { id = B::value }; + // }; + + // void test() { + // int x = C::id; + // } + public void testDependentEnumValue_389009() throws Exception { + IEnumerator binding = getBindingFromASTName("id;", 2, IEnumerator.class); + IValue value = binding.getValue(); + Long num = value.numericalValue(); + assertNotNull(num); + assertEquals(1, num.longValue()); + } + // template // struct A { // typedef U type1; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java index b1ba0f5c4e4..92ef9cf4046 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 Symbian Software Systems and others. + * Copyright (c) 2007, 2013 Symbian 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 @@ -7,13 +7,13 @@ * * Contributors: * Andrew Ferguson (Symbian) - Initial implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -46,6 +46,56 @@ import org.eclipse.core.runtime.Path; * Tests the behavior of the IIndex API when dealing with multiple projects */ public class IndexCompositeTests extends BaseTestCase { + /* + * Convenience class for setting up projects. + */ + private static class ProjectBuilder { + private final String name; + private final boolean cpp; + private List dependencies = new ArrayList(); + private Map path2content = new HashMap(); + + ProjectBuilder(String name, boolean cpp) { + this.name = name; + this.cpp = cpp; + } + + ProjectBuilder addDependency(IProject project) { + dependencies.add(project); + return this; + } + + ProjectBuilder addFile(String relativePath, CharSequence content) { + path2content.put(relativePath, content.toString()); + return this; + } + + ICProject create() throws Exception { + ICProject result = cpp ? + CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER) : + CProjectHelper.createCProject(name, "bin", IPDOMManager.ID_NO_INDEXER); + + IFile lastFile= null; + for (Map.Entry entry : path2content.entrySet()) { + lastFile= TestSourceReader.createFile(result.getProject(), new Path(entry.getKey()), entry.getValue()); + } + + IProjectDescription desc = result.getProject().getDescription(); + desc.setReferencedProjects(dependencies.toArray(new IProject[dependencies.size()])); + result.getProject().setDescription(desc, new NullProgressMonitor()); + + IIndexManager indexManager = CCorePlugin.getIndexManager(); + indexManager.setIndexerId(result, IPDOMManager.ID_FAST_INDEXER); + if (lastFile != null) { + // Call reindex explicitly since setting indexer ID doesn't trigger reindexing. + indexManager.reindex(result); + IIndex index= indexManager.getIndex(result); + TestSourceReader.waitUntilFileIsIndexed(index, lastFile, INDEXER_TIMEOUT_SEC * 1000); + } + BaseTestCase.waitForIndexer(result); + return result; + } + } public static Test suite() { return suite(IndexCompositeTests.class); @@ -101,8 +151,9 @@ public class IndexCompositeTests extends BaseTestCase { setIndex(cprojA, REFD); assertBCount(1, 1); setIndex(cprojA, BOTH); assertBCount(2, 2); } finally { - for (ICProject project : projects) + for (ICProject project : projects) { project.getProject().delete(true, true, new NullProgressMonitor()); + } } } @@ -175,7 +226,6 @@ public class IndexCompositeTests extends BaseTestCase { assertNamespaceXMemberCount(5); assertFieldCount("C1", 1); - setIndex(cprojB, NONE); assertBCount(gBC, aBC); assertNamespaceXMemberCount(2); @@ -195,7 +245,6 @@ public class IndexCompositeTests extends BaseTestCase { assertBCount(gABC, aABC); assertNamespaceXMemberCount(5); assertFieldCount("C1", 1); - setIndex(cprojA, NONE); assertBCount(gABC, aABC); @@ -217,8 +266,9 @@ public class IndexCompositeTests extends BaseTestCase { assertNamespaceXMemberCount(5); assertFieldCount("C1", 1); } finally { - for (ICProject project : projects) + for (ICProject project : projects) { project.getProject().delete(true, true, new NullProgressMonitor()); + } } } @@ -259,7 +309,6 @@ public class IndexCompositeTests extends BaseTestCase { ICProject cprojC = pb.create(); projects.add(cprojC); - /* A C | * \ / | Depends On / References * B V @@ -278,7 +327,6 @@ public class IndexCompositeTests extends BaseTestCase { final int gAB= gA + gB - 1, aAB= aA + aB - 1; final int gABC= gA + gBC - 1, aABC= aA + aBC - 1; - setIndex(cprojC, NONE); assertBCount(gBC, aBC); assertNamespaceXMemberCount(3); @@ -318,8 +366,9 @@ public class IndexCompositeTests extends BaseTestCase { assertBCount(gABC, aABC); assertNamespaceXMemberCount(4); } finally { - for (ICProject project : projects) + for (ICProject project : projects) { project.getProject().delete(true, true, new NullProgressMonitor()); + } } } @@ -415,8 +464,9 @@ public class IndexCompositeTests extends BaseTestCase { assertBCount(gABC, aABC); assertNamespaceXMemberCount(4); } finally { - for (ICProject project : projects) + for (ICProject project : projects) { project.getProject().delete(true, true, new NullProgressMonitor()); + } } } @@ -438,13 +488,13 @@ public class IndexCompositeTests extends BaseTestCase { private void assertNamespaceXMemberCount(int count) throws CoreException, DOMException { IBinding[] bindings = index.findBindings(Pattern.compile("X"), true, FILTER, new NullProgressMonitor()); assertEquals(1, bindings.length); - assertEquals(count, ((ICPPNamespace)bindings[0]).getMemberBindings().length); + assertEquals(count, ((ICPPNamespace) bindings[0]).getMemberBindings().length); } private void assertFieldCount(String qnPattern, int count) throws CoreException, DOMException { IBinding[] bindings = index.findBindings(Pattern.compile(qnPattern), true, FILTER, new NullProgressMonitor()); assertEquals(1, bindings.length); - assertEquals(count, ((ICompositeType)bindings[0]).getFields().length); + assertEquals(count, ((ICompositeType) bindings[0]).getFields().length); } private void setIndex(ICProject project, int options) throws CoreException, InterruptedException { @@ -463,53 +513,3 @@ public class IndexCompositeTests extends BaseTestCase { super.tearDown(); } } - -/* - * Convenience class for setting up projects. - */ -class ProjectBuilder { - private static final int INDEXER_TIMEOUT_SEC = 10; - private final String name; - private final boolean cpp; - private List dependencies = new ArrayList(); - private Map path2content = new HashMap(); - - ProjectBuilder(String name, boolean cpp) { - this.name = name; - this.cpp = cpp; - } - - ProjectBuilder addDependency(IProject project) { - dependencies.add(project); - return this; - } - - ProjectBuilder addFile(String relativePath, CharSequence content) { - path2content.put(relativePath, content.toString()); - return this; - } - - ICProject create() throws Exception { - ICProject result = cpp ? - CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER) : - CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER); - - IFile lastFile= null; - for (Iterator i = path2content.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = (Map.Entry) i.next(); - lastFile= TestSourceReader.createFile(result.getProject(), new Path((String)entry.getKey()), (String) entry.getValue()); - } - - IProjectDescription desc = result.getProject().getDescription(); - desc.setReferencedProjects((IProject[]) dependencies.toArray(new IProject[dependencies.size()])); - result.getProject().setDescription(desc, new NullProgressMonitor()); - - CCorePlugin.getIndexManager().setIndexerId(result, IPDOMManager.ID_FAST_INDEXER); - if (lastFile != null) { - IIndex index= CCorePlugin.getIndexManager().getIndex(result); - TestSourceReader.waitUntilFileIsIndexed(index, lastFile, INDEXER_TIMEOUT_SEC * 1000); - } - BaseTestCase.waitForIndexer(result); - return result; - } -} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java index 80faf0f2e50..0fd42ab7ded 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java @@ -240,7 +240,8 @@ public class IndexUpdateTests extends IndexTestBase { for (int i = 0; i < nchars.length; i++) { nchars[i]= names[i].toCharArray(); } - return fIndex.findBindings(nchars, IndexFilter.ALL_DECLARED, npm())[0]; + IIndexBinding[] bindings = fIndex.findBindings(nchars, IndexFilter.ALL_DECLARED, npm()); + return bindings.length > 0 ? bindings[0] : null; } private String msg() { @@ -256,7 +257,6 @@ public class IndexUpdateTests extends IndexTestBase { // short globalVar; // register int globalVar; - public void testGlobalCppVariable() throws Exception { setupFile(3, true); checkCppVariable("globalVar", INT, new String[]{}); @@ -345,7 +345,6 @@ public class IndexUpdateTests extends IndexTestBase { // struct my_struct {int fField;}; // struct my_struct {short fField;}; - public void testCField() throws Exception { setupFile(2, false); checkVariable("my_struct::fField", INT, new String[]{}); @@ -402,7 +401,6 @@ public class IndexUpdateTests extends IndexTestBase { checkModifier(modifiers, PRIVATE, visibility == ICPPMember.v_private); } - // class MyClass {int method(int a, int b);}; // class MyClass {short method(int a, int b);}; @@ -422,7 +420,6 @@ public class IndexUpdateTests extends IndexTestBase { // class MyClass {int method(char a){};}; // class MyClass {virtual int method(char a) = 0;}; - public void testCppMethod() throws Exception { setupFile(10, true); checkCppMethod("MyClass::method", new String[] {INT, INT, INT}, new String[]{PRIVATE}); @@ -453,7 +450,6 @@ public class IndexUpdateTests extends IndexTestBase { // #include "header.h" // char MyClass::method(int a, int b); - public void testFixedCppMethod() throws Exception { setupHeader(3, true); checkCppMethod("MyClass::method", new String[] {INT, INT, INT}, new String[]{PROTECTED}); @@ -493,7 +489,6 @@ public class IndexUpdateTests extends IndexTestBase { // class MyClass {protected: MyClass(char a, int b);}; // class MyClass {private: MyClass(char a, int b);}; - public void testCppConstructor() throws Exception { setupFile(6, true); checkCppConstructor("MyClass::MyClass", new String[] {"", INT, INT}, new String[]{PRIVATE}); @@ -587,7 +582,8 @@ public class IndexUpdateTests extends IndexTestBase { } checkCppConstructor((ICPPConstructor) ctors[0], new String[]{"", constRefType}, m2); - IIndexBinding[] assignmentOps= fIndex.findBindings(new char[][]{nchars, "operator =".toCharArray()}, IndexFilter.ALL_DECLARED_OR_IMPLICIT, npm()); + IIndexBinding[] assignmentOps= fIndex.findBindings( + new char[][] {nchars, "operator =".toCharArray() }, IndexFilter.ALL_DECLARED_OR_IMPLICIT, npm()); count= 0; for (int i = 0; i < assignmentOps.length; i++) { IIndexBinding assignmentOp= assignmentOps[i]; @@ -717,7 +713,6 @@ public class IndexUpdateTests extends IndexTestBase { } } - // class myType { // int a; // }; @@ -1183,7 +1178,6 @@ public class IndexUpdateTests extends IndexTestBase { } } - // void funcTypeDeletion(int); // #include "header.h" diff --git a/core/org.eclipse.cdt.core.tests/pom.xml b/core/org.eclipse.cdt.core.tests/pom.xml index 9c6c3c90e40..7f57c786ad6 100644 --- a/core/org.eclipse.cdt.core.tests/pom.xml +++ b/core/org.eclipse.cdt.core.tests/pom.xml @@ -32,7 +32,7 @@ ${tycho-version} false - -Xms256m -Xmx512m -XX:MaxPermSize=256M + -ea -Xms256m -Xmx512m -XX:MaxPermSize=256M **/AutomatedIntegrationSuite.* diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java index d458b04a10a..251313e5c27 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java @@ -1,14 +1,14 @@ /******************************************************************************* - * Copyright (c) 2005, 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) 2005, 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 Corporation - initial API and implementation - * Markus Schorn (Wind River Systems) - * Norbert Ploett (Siemens AG) + * Contributors: + * IBM Corporation - initial API and implementation + * Markus Schorn (Wind River Systems) + * Norbert Ploett (Siemens AG) *******************************************************************************/ package org.eclipse.cdt.core.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 31837885a06..a9fe225934b 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Andrew Gvozdev and others. + * Copyright (c) 2009, 2013 Andrew Gvozdev 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 @@ -23,6 +23,8 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.internal.core.LocalProjectScope; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsExtensionManager; import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer; +import org.eclipse.cdt.internal.core.language.settings.providers.ScannerInfoExtensionLanguageSettingsProvider; +import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.service.prefs.BackingStoreException; @@ -42,6 +44,8 @@ public class ScannerDiscoveryLegacySupport { public static final String USER_LANGUAGE_SETTINGS_PROVIDER_ID = "org.eclipse.cdt.ui.UserLanguageSettingsProvider"; //$NON-NLS-1$ /** ID of MBS language settings provider (from org.eclipse.cdt.managedbuilder.core) */ public static final String MBS_LANGUAGE_SETTINGS_PROVIDER_ID = "org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"; //$NON-NLS-1$ + /** ID of ScannerInfo language settings provider wrapping ScannerInfoProvider defined by org.eclipse.cdt.core.ScannerInfoProvider extension point */ + private static final String SI_LANGUAGE_SETTINGS_PROVIDER_ID = "org.eclipse.cdt.core.LegacyScannerInfoLanguageSettingsProvider"; //$NON-NLS-1$ private static String DISABLE_LSP_PREFERENCE = "language.settings.providers.disabled"; //$NON-NLS-1$ // the default for project needs to be "disabled" - for legacy projects to be open with old SD enabled for MBS provider @@ -156,15 +160,60 @@ public class ScannerDiscoveryLegacySupport { } /** - * Return list containing MBS and User provider. Used to initialize for unaware tool-chains (backward compatibility). + * Return list containing User provider and one of wrapper providers to support legacy projects (backward compatibility). + * + * @noreference This is internal helper method to support compatibility with previous versions + * which is not intended to be referenced by clients. + * @since 5.5 + */ + public static String[] getDefaultProviderIdsLegacy(ICConfigurationDescription cfgDescription) { + boolean useScannerInfoProviderExtension = new ScannerInfoExtensionLanguageSettingsProvider().getScannerInfoProvider(cfgDescription) != null; + if (useScannerInfoProviderExtension) { + return new String[] {USER_LANGUAGE_SETTINGS_PROVIDER_ID, SI_LANGUAGE_SETTINGS_PROVIDER_ID}; + } + if (CProjectDescriptionManager.getInstance().isNewStyleCfg(cfgDescription)) { + return new String[] {USER_LANGUAGE_SETTINGS_PROVIDER_ID, MBS_LANGUAGE_SETTINGS_PROVIDER_ID}; + } + return null; + + } + + /** + * Checks if the provider is applicable for configuration from backward compatibility point of view + * + * @noreference This is internal helper method to support compatibility with previous versions + * which is not intended to be referenced by clients. + * @since 5.5 + */ + public static boolean isProviderCompatible(String providerId, ICConfigurationDescription cfgDescription) { + if (cfgDescription != null) { + boolean useScannerInfoProviderExtension = new ScannerInfoExtensionLanguageSettingsProvider().getScannerInfoProvider(cfgDescription) != null; + if (SI_LANGUAGE_SETTINGS_PROVIDER_ID.equals(providerId)) { + return useScannerInfoProviderExtension; + } + + if (MBS_LANGUAGE_SETTINGS_PROVIDER_ID.equals(providerId)) { + boolean isNewStyleCfg = CProjectDescriptionManager.getInstance().isNewStyleCfg(cfgDescription); + return !useScannerInfoProviderExtension && isNewStyleCfg; + } + } + + return true; + } + + /** + * Return list containing User and MBS providers. Used to initialize older MBS tool-chains (backward compatibility). + * + * @noreference This is internal helper method to support compatibility with previous versions + * which is not intended to be referenced by clients. */ public static List getDefaultProvidersLegacy() { List providers = new ArrayList(2); - ILanguageSettingsProvider provider = LanguageSettingsExtensionManager.getExtensionProviderCopy((ScannerDiscoveryLegacySupport.USER_LANGUAGE_SETTINGS_PROVIDER_ID), false); + ILanguageSettingsProvider provider = LanguageSettingsExtensionManager.getExtensionProviderCopy((USER_LANGUAGE_SETTINGS_PROVIDER_ID), false); if (provider != null) { providers.add(provider); } - providers.add(LanguageSettingsProvidersSerializer.getWorkspaceProvider(ScannerDiscoveryLegacySupport.MBS_LANGUAGE_SETTINGS_PROVIDER_ID)); + providers.add(LanguageSettingsProvidersSerializer.getWorkspaceProvider(MBS_LANGUAGE_SETTINGS_PROVIDER_ID)); return providers; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java index 25797a7adbd..f7dda7b3f10 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsManager; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.resources.IPathEntryStore; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSetting; @@ -1253,11 +1254,12 @@ public class CoreModel { if(des != null){ ICConfigurationDescription indexCfg = des.getDefaultSettingConfiguration(); if(indexCfg != null){ - if(!mngr.isNewStyleCfg(indexCfg)){ + if (!mngr.isNewStyleCfg(indexCfg)) { return oldIsScannerInformationEmpty(resource); } - if (indexCfg instanceof ILanguageSettingsProvidersKeeper) { + if (ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project) && + indexCfg instanceof ILanguageSettingsProvidersKeeper) { List languageIds = LanguageSettingsManager.getLanguages(resource, indexCfg); for (String langId : languageIds) { List entries = LanguageSettingsManager.getSettingEntriesByKind(indexCfg, resource, langId, diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingEntry.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingEntry.java index 759e0e18b42..2dfdc007014 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingEntry.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingEntry.java @@ -38,7 +38,8 @@ public interface ICSettingEntry { /** * Flag {@code LOCAL} is used during creation of {@link IIncludeEntry} * to indicate that an include path is not a system path. - * It does not appear it is used anywhere else. + * "System" path is denoted by angle brackets as in #include + * "Local" path is denoted by quotes as in #include "x.h" */ int LOCAL = 1 << 2; 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 b9e6a1bf2b6..04f3d1251fd 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Andrew Gvozdev and others. + * Copyright (c) 2009, 2013 Andrew Gvozdev 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 @@ -82,7 +82,7 @@ public class LanguageSettingsProvidersSerializer { public static final String JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE = "CDT_JOB_FAMILY_SERIALIZE_LANGUAGE_SETTINGS_WORKSPACE"; //$NON-NLS-1$ private static final String PREFERENCE_WORSPACE_PROVIDERS_SET = "language.settings.providers.workspace.prefs.toggle"; //$NON-NLS-1$ - private static final String CPROJECT_STORAGE_MODULE = "org.eclipse.cdt.core.LanguageSettingsProviders"; //$NON-NLS-1$ + private static final String CPROJECT_STORAGE_MODULE_LANGUAGE_SETTINGS_PROVIDERS = "org.eclipse.cdt.core.LanguageSettingsProviders"; //$NON-NLS-1$ private static final String STORAGE_WORKSPACE_LANGUAGE_SETTINGS = "language.settings.xml"; //$NON-NLS-1$ private static final String STORAGE_PROJECT_PATH = ".settings/language.settings.xml"; //$NON-NLS-1$ @@ -827,8 +827,13 @@ public class LanguageSettingsProvidersSerializer { public static void serializeLanguageSettings(ICProjectDescription prjDescription) throws CoreException { IProject project = prjDescription.getProject(); try { - // Using side effect of adding the module to the storage - prjDescription.getStorage(CPROJECT_STORAGE_MODULE, true); + // Add the storage module to .cpoject and persist on disk as a side effect of adding + prjDescription.getStorage(CPROJECT_STORAGE_MODULE_LANGUAGE_SETTINGS_PROVIDERS, true); + if (!ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityDefined(project)) { + // set the flag if was not previously set by the user - to the default value + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, + ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityEnabled(project)); + } } catch (CoreException e) { CCorePlugin.log("Internal error while trying to serialize language settings", e); //$NON-NLS-1$ } @@ -1125,7 +1130,9 @@ public class LanguageSettingsProvidersSerializer { public static void loadLanguageSettings(ICProjectDescription prjDescription) { IProject project = prjDescription.getProject(); IFile storeInPrjArea = getStoreInProjectArea(project); - if (storeInPrjArea.exists()) { + boolean isStoreInProjectAreaExist = storeInPrjArea.exists(); + boolean enableLSP = isStoreInProjectAreaExist; + if (isStoreInProjectAreaExist) { Document doc = null; try { doc = XmlUtil.loadXml(storeInPrjArea); @@ -1150,19 +1157,18 @@ public class LanguageSettingsProvidersSerializer { CCorePlugin.log("Can't load preferences from file " + storeInPrjArea.getLocation(), e); //$NON-NLS-1$ } - } else { - // Storage in project area does not exist - ICStorageElement storageElement = null; + } else { // Storage in project area does not exist + ICStorageElement lspStorageModule = null; try { - storageElement = prjDescription.getStorage(CPROJECT_STORAGE_MODULE, false); + lspStorageModule = prjDescription.getStorage(CPROJECT_STORAGE_MODULE_LANGUAGE_SETTINGS_PROVIDERS, false); } catch (CoreException e) { String msg = "Internal error while trying to load language settings"; //$NON-NLS-1$ CCorePlugin.log(msg, e); } - if (storageElement != null) { - // set default providers defined in the tool-chain - for (ICConfigurationDescription cfgDescription : prjDescription.getConfigurations()) { + // set default providers defined in the tool-chain + for (ICConfigurationDescription cfgDescription : prjDescription.getConfigurations()) { + if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) { String[] ids = ((ILanguageSettingsProvidersKeeper) cfgDescription).getDefaultLanguageSettingsProvidersIds(); if (ids != null) { List providers = new ArrayList(ids.length); @@ -1176,23 +1182,16 @@ public class LanguageSettingsProvidersSerializer { ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(providers); } } - - } else { - // Older existing legacy projects unaware of Language Settings Providers and their persistence store - ICConfigurationDescription[] cfgDescriptions = prjDescription.getConfigurations(); - for (ICConfigurationDescription cfgDescription : cfgDescriptions) { - if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) { - ((ILanguageSettingsProvidersKeeper) cfgDescription).setLanguageSettingProviders(ScannerDiscoveryLegacySupport.getDefaultProvidersLegacy()); - } - } - } - - 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); } + enableLSP = lspStorageModule != null; } + + if (!ScannerDiscoveryLegacySupport.isLanguageSettingsProvidersFunctionalityDefined(project)) { + // set the flag if was not previously set by the user + ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(project, enableLSP); + } + } /** diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/ScannerInfoExtensionLanguageSettingsProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/ScannerInfoExtensionLanguageSettingsProvider.java new file mode 100644 index 00000000000..fb2d1e637bc --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/ScannerInfoExtensionLanguageSettingsProvider.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2013, 2013 Andrew Gvozdev 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: + * Andrew Gvozdev - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.language.settings.providers; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.eclipse.cdt.core.AbstractCExtension; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsBaseProvider; +import org.eclipse.cdt.core.parser.IExtendedScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference; +import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; +import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICSettingEntry; +import org.eclipse.cdt.core.settings.model.util.CDataUtil; +import org.eclipse.cdt.core.settings.model.util.CExtensionUtil; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Wrapper class intended to provide backward compatibility with ScannerInfoProvider defined by org.eclipse.cdt.core.ScannerInfoProvider extension point + */ +public class ScannerInfoExtensionLanguageSettingsProvider extends LanguageSettingsBaseProvider { + @Override + public List getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) { + List entries = new ArrayList(); + IScannerInfoProvider scannerInfoProvider = getScannerInfoProvider(cfgDescription); + if (scannerInfoProvider != null) { + IScannerInfo si = scannerInfoProvider.getScannerInformation(rc); + if (si != null) { + if (si instanceof IExtendedScannerInfo) { + addLocalIncludePaths(entries, (IExtendedScannerInfo) si); + } + + addSystemIncludePaths(entries, si); + addDefinedSymbols(entries, si); + + if (si instanceof IExtendedScannerInfo) { + addIncludeFiles(entries, (IExtendedScannerInfo) si); + addMacroFiles(entries, (IExtendedScannerInfo) si); + } + + if (!entries.isEmpty()) { + return LanguageSettingsSerializableStorage.getPooledList(entries); + } + } + } + return null; + } + + /** + * Return ScannerInfoProvider defined in configuration metadata in .cproject. + * + * @param cfgDescription - configuration description. + * @return an instance of ScannerInfoProvider or {@code null}. + */ + public IScannerInfoProvider getScannerInfoProvider(ICConfigurationDescription cfgDescription) { + if (cfgDescription == null) { + return null; + } + + IScannerInfoProvider scannerInfoProvider = null; + ICConfigExtensionReference[] refs = cfgDescription.get(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID); + if (refs != null && refs.length > 0) { + ICConfigExtensionReference ref = refs[0]; + try { + AbstractCExtension cExtension = null; + IConfigurationElement el = CExtensionUtil.getFirstConfigurationElement(ref, "cextension", false); //$NON-NLS-1$ + cExtension = (AbstractCExtension)el.createExecutableExtension("run"); //$NON-NLS-1$ + cExtension.setExtensionReference(ref); + cExtension.setProject(ref.getConfiguration().getProjectDescription().getProject()); + if (cExtension instanceof IScannerInfoProvider) { + scannerInfoProvider = (IScannerInfoProvider) cExtension; + } + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + return scannerInfoProvider; + } + + /** + * Add local include paths to the list of entries. + */ + private void addLocalIncludePaths(List entries, IExtendedScannerInfo esi) { + String[] localIncludePaths = esi.getLocalIncludePath(); + if (localIncludePaths != null) { + for (String path : localIncludePaths) { + entries.add(CDataUtil.createCIncludePathEntry(path, ICSettingEntry.LOCAL)); + } + } + } + + /** + * Add system include paths to the list of entries. + */ + private void addSystemIncludePaths(List entries, IScannerInfo si) { + String[] includePaths = si.getIncludePaths(); + if (includePaths != null) { + for (String path : includePaths) { + entries.add(CDataUtil.createCIncludePathEntry(path, 0)); + } + } + } + + /** + * Add defined macros to the list of entries. + */ + private void addDefinedSymbols(List entries, IScannerInfo si) { + Map definedSymbols = si.getDefinedSymbols(); + if (definedSymbols != null) { + for (Entry entry : new TreeMap(definedSymbols).entrySet()) { + String name = entry.getKey(); + String value = entry.getValue(); + entries.add(CDataUtil.createCMacroEntry(name, value, 0)); + } + } + } + + /** + * Add include files to the list of entries. + */ + private void addIncludeFiles(List entries, IExtendedScannerInfo esi) { + String[] includeFiles = esi.getIncludeFiles(); + if (includeFiles != null) { + for (String path : includeFiles) { + entries.add(CDataUtil.createCIncludeFileEntry(path, 0)); + } + } + } + + /** + * Add macro files to the list of entries. + */ + private void addMacroFiles(List entries, IExtendedScannerInfo esi) { + String[] macroFiles = esi.getMacroFiles(); + if (macroFiles != null) { + for (String path : macroFiles) { + entries.add(CDataUtil.createCMacroFileEntry(path, 0)); + } + } + } +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java index 4682d1838cb..bb1c9b597da 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java @@ -38,6 +38,7 @@ import org.eclipse.cdt.core.model.IPathEntryContainer; import org.eclipse.cdt.core.model.IProjectEntry; import org.eclipse.cdt.core.model.ISourceEntry; import org.eclipse.cdt.core.resources.IPathEntryVariableManager; +import org.eclipse.cdt.utils.UNCPathConverter; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -513,6 +514,9 @@ public class PathEntryUtil { private static boolean isValidExternalPath(IPath path) { if (path != null) { + if (path.isUNC()) { + return true; + } File file = path.toFile(); if (file != null) { return file.exists(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java index a8a881a4b63..61c95fc315d 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java @@ -52,6 +52,7 @@ import javax.xml.transform.stream.StreamResult; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvider; import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsProvidersKeeper; +import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; @@ -1141,7 +1142,15 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { monitor = new NullProgressMonitor(); CConfigurationDataProvider provider = getProvider(des); - return provider.loadConfiguration(des, monitor); + CConfigurationData data = provider.loadConfiguration(des, monitor); + + if (des instanceof ILanguageSettingsProvidersKeeper && ! des.isPreferenceConfiguration()) { + String[] defaultIds = ((ILanguageSettingsProvidersKeeper) des).getDefaultLanguageSettingsProvidersIds(); + if (defaultIds == null) { + ((ILanguageSettingsProvidersKeeper) des).setDefaultLanguageSettingsProvidersIds(ScannerDiscoveryLegacySupport.getDefaultProviderIdsLegacy(des)); + } + } + return data; } CConfigurationData applyData(CConfigurationDescriptionCache des, ICConfigurationDescription baseDescription, CConfigurationData base, SettingsContext context, IProgressMonitor monitor) throws CoreException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java index 42ec1b40b31..5a254287247 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 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 @@ -9,6 +9,7 @@ * Rational Software - initial implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -45,6 +46,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression; /** * This is a utility class to help convert AST elements to Strings corresponding to @@ -182,6 +184,7 @@ public class ASTTypeUtil { private static void appendArgument(ICPPTemplateArgument arg, boolean normalize, StringBuilder buf) { IValue val= arg.getNonTypeValue(); if (val != null) { + appendType(arg.getTypeOfNonTypeValue(), normalize, buf); buf.append(val.getSignature()); } else { IType type = normalize ? arg.getTypeValue() : arg.getOriginalTypeValue(); @@ -408,6 +411,8 @@ public class ASTTypeUtil { IQualifierType qt= (IQualifierType) type; needSpace= appendCVQ(result, needSpace, qt.isConst(), qt.isVolatile(), false); + } else if (type instanceof TypeOfDependentExpression) { + result.append(((TypeOfDependentExpression) type).getSignature()); } else if (type instanceof ISemanticProblem) { result.append('?'); } else if (type != null) { @@ -584,7 +589,7 @@ public class ASTTypeUtil { if (parenthesis == null) { parenthesis= new BitSet(); } - parenthesis.set(postfix.size()-1); + parenthesis.set(postfix.size() - 1); } appendTypeString(tj, normalize, result); needParenthesis= false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFileLocation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFileLocation.java index 4ad690da89d..ef76745892c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFileLocation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFileLocation.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 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, 2009 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: - * Doug Schaefer (IBM) - Initial API and implementation + * Contributors: + * Doug Schaefer (IBM) - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java index 7e976248eb9..47577e3a252 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java @@ -18,9 +18,8 @@ package org.eclipse.cdt.core.dom.ast; public interface IEnumeration extends IBinding, IType { /** * Returns an array of the IEnumerators declared in this enumeration - * @throws DOMException */ - IEnumerator[] getEnumerators() throws DOMException; + IEnumerator[] getEnumerators(); /** * @since 5.2 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumerationSpecialization.java new file mode 100644 index 00000000000..684747193ad --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumerationSpecialization.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; + +/** + * @since 5.5 + */ +public interface ICPPEnumerationSpecialization extends ICPPEnumeration, ICPPSpecialization { + @Override + ICPPEnumeration getSpecializedBinding(); + + /** + * Return a specialized version of the given enumerator. The enumerator must be one + * of the enumerators of the enumeration being specialized. + */ + IEnumerator specializeEnumerator(IEnumerator enumerator); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java index 461a2afa83f..ed5c8c13acc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java @@ -1,15 +1,15 @@ /******************************************************************************* - * Copyright (c) 2005, 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) 2005, 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 - * Markus Schorn (Wind River Systems) - * Anton Leherbauer (Wind River Systems) - * Sergey Prigogin (Google) + * Contributors: + * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Anton Leherbauer (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; 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 92ebd31459a..387da41ee83 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 Google, Inc and others. + * Copyright (c) 2011, 2013 Google, 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 @@ -7,6 +7,7 @@ * * Contributors: * Sergey Prigogin (Google) - initial API and implementation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; @@ -182,7 +183,12 @@ public class SizeofCalculator { if (type instanceof IBasicType) { return sizeAndAlignment((IBasicType) type); } - if (type instanceof IPointerType || type instanceof ICPPReferenceType) { + // [expr.sizeof]/2: "When applied to a reference or a reference type, the + // result is the size of the referenced type." + if (type instanceof ICPPReferenceType) { + return sizeAndAlignment(((ICPPReferenceType) type).getType()); + } + if (type instanceof IPointerType) { if (type instanceof ICPPPointerToMemberType) return null; return sizeof_pointer; @@ -314,14 +320,24 @@ public class SizeofCalculator { if (field.isStatic()) continue; IType fieldType = field.getType(); - SizeAndAlignment info = sizeAndAlignment(fieldType); + SizeAndAlignment info; + // sizeof() on a reference type returns the size of the referenced type. + // However, a reference field in a structure only occupies as much space + // as a pointer. + if (fieldType instanceof ICPPReferenceType) { + info = sizeof_pointer; + } else { + info = sizeAndAlignment(fieldType); + } if (info == null) return null; if (union) { if (size < info.size) size = info.size; } else { - size += info.alignment - (size - 1) % info.alignment - 1 + info.size; + if (size > 0) + size += info.alignment - (size - 1) % info.alignment - 1; + size += info.size; } if (maxAlignment < info.alignment) maxAlignment = info.alignment; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java index e0fdf88dd99..f70277a545b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java @@ -8,6 +8,7 @@ * Contributors: * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; @@ -25,18 +26,17 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; 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.c.ICASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; /** * Binding for enumerations in C. */ public class CEnumeration extends PlatformObject implements IEnumeration, ICInternalBinding { - private IASTName[] declarations = null; private IASTName definition = null; private Long fMinValue; @@ -204,20 +204,7 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte if (fMinValue != null) return fMinValue.longValue(); - long minValue = Long.MAX_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v < minValue) { - minValue = v; - } - } - } - } + long minValue = SemanticUtil.computeMinValue(this); fMinValue= minValue; return minValue; } @@ -227,20 +214,7 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte if (fMaxValue != null) return fMaxValue.longValue(); - long maxValue = Long.MIN_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v > maxValue) { - maxValue = v; - } - } - } - } + long maxValue = SemanticUtil.computeMaxValue(this); fMaxValue= maxValue; return maxValue; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java index 6cd767286e1..1f05eb9f02f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java @@ -1,11 +1,11 @@ /******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html + * 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 + * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * Mike Kucera (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java index 7b702c2bcf5..e6b02b0356c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Symbian Software Systems and others. + * Copyright (c) 2008, 2013 Symbian 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 @@ * Andrew Ferguson (Symbian) - Initial Implementation * Markus Schorn (Wind River Systems) * IBM Corporation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -68,12 +69,18 @@ public class CPPASTAmbiguousTemplateArgument extends ASTAmbiguousNode implements name.setBinding(null); namedTypeSpec.setName(name); } - } else if (node instanceof IASTIdExpression) { - IASTIdExpression id= (IASTIdExpression) node; - final IASTName name = id.getName(); - name.setBinding(null); - id.setName(name); - } + } else { + // Unwrap variadic pack expansion if necessary. + if (node instanceof ICPPASTPackExpansionExpression) + node= ((ICPPASTPackExpansionExpression) node).getPattern(); + + if (node instanceof IASTIdExpression) { + IASTIdExpression id= (IASTIdExpression) node; + final IASTName name = id.getName(); + name.setBinding(null); + id.setName(name); + } + } } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java index 7953101446d..916731241c1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java @@ -1,11 +1,11 @@ /******************************************************************************* - * 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 + * Copyright (c) 2004, 2013 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: + * Contributors: * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ @@ -124,7 +124,7 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr fEvaluation= EvalFixed.INCOMPLETE; } else { IType t1= CPPVisitor.createType(fOperand1); - IType t2= CPPVisitor.createType(fOperand1); + IType t2= CPPVisitor.createType(fOperand2); if (t1 == null || t2 == null) { fEvaluation= EvalFixed.INCOMPLETE; } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java index dad73eb5078..8d363e18898 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java @@ -1,11 +1,11 @@ /******************************************************************************* - * 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 + * 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: + * Contributors: * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java index e3d05cf340f..cbc866f92a6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java @@ -1,13 +1,13 @@ /******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html + * 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 + * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: - * John Camelon (IBM) - Initial API and implementation - * Markus Schorn (Wind River Systems) + * Contributors: + * John Camelon (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java index 9b115f02e50..56695296b2a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2013 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: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation + * Natan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -16,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; @@ -74,7 +76,7 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac } else { type= new CPPParameterPackType(type); } - fEvaluation= new EvalFixed(type, PRVALUE, Value.UNKNOWN); + fEvaluation= new EvalFixed(type, PRVALUE, Value.create(((ICPPASTExpression) fPattern).getEvaluation())); } return fEvaluation; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java index 1d0575f6d22..adb1ad1db1b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java @@ -1,11 +1,11 @@ /******************************************************************************* - * 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 + * 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: + * Contributors: * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java index e42807c2099..da86aab3be9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java @@ -55,16 +55,12 @@ public class CPPASTTemplateId extends CPPASTNameBase implements ICPPASTTemplateI @Override public CPPASTTemplateId copy(CopyStyle style) { - CPPASTTemplateId copy = new CPPASTTemplateId(templateName == null ? - null : templateName.copy(style)); + CPPASTTemplateId copy = + new CPPASTTemplateId(templateName == null ? null : templateName.copy(style)); for (IASTNode arg : getTemplateArguments()) { copy.internalAddTemplateArgument(arg == null ? null : arg.copy(style)); } - copy.setOffsetAndLength(this); - if (style == CopyStyle.withLocations) { - copy.setCopyLocation(this); - } - return copy; + return copy(copy, style); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java index 5e0c71d7bff..5de9d648038 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java @@ -1,13 +1,13 @@ /******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html + * 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 + * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: - * John Camelon (IBM) - Initial API and implementation - * Markus Schorn (Wind River Systems) + * Contributors: + * John Camelon (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java index ff1ade59140..ba3e732e58b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java @@ -1,11 +1,11 @@ /******************************************************************************* - * 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 + * 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: + * Contributors: * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java index 5d45beba891..21c80c020a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java @@ -1,14 +1,15 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2013 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: - * Andrew Niefer (IBM Corporation) - initial API and implementation - * Bryan Wilkinson (QNX) - * Markus Schorn (Wind River Systems) + * Andrew Niefer (IBM Corporation) - initial API and implementation + * Bryan Wilkinson (QNX) + * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -47,8 +48,10 @@ public class CPPBaseClause implements ICPPBase, ICPPInternalBase { public IType getBaseClassType() { if (baseClass == null) { IBinding b = base.getName().resolveBinding(); - if (b instanceof IProblemBinding || ! (b instanceof IType)) { + if (b instanceof IProblemBinding) { baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ((IProblemBinding) b).getID()); + } else if (!(b instanceof IType)) { + baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ISemanticProblem.BINDING_NO_CLASS); } else { baseClass= (IType) b; IType check= getNestedType(baseClass, TDEF); 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 12a06267a49..146430c12ff 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,14 +1,14 @@ /******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html + * 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 + * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: - * Andrew Niefer (IBM Corporation) - initial API and implementation - * Markus Schorn (Wind River Systems) - * Sergey Prigogin (Google) + * 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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java index 14e1902fd42..979cc8fd7b3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java @@ -103,7 +103,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP // Function call operator final IType returnType= getReturnType(); final IType[] parameterTypes= getParameterTypes(); - ft= new CPPFunctionType(returnType, parameterTypes, isMutable(), false, false); + ft= new CPPFunctionType(returnType, parameterTypes, !isMutable(), false, false); ICPPParameter[] params = new ICPPParameter[parameterTypes.length]; for (int i = 0; i < params.length; i++) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java index 1ea5e20d6de..e595d99b1a2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java @@ -9,6 +9,7 @@ * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -29,7 +30,6 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IScope; 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.ICPPASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -42,6 +42,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; /** @@ -220,20 +221,7 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I if (fMinValue != null) return fMinValue.longValue(); - long minValue = Long.MAX_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v < minValue) { - minValue = v; - } - } - } - } + long minValue = SemanticUtil.computeMinValue(this); fMinValue= minValue; return minValue; } @@ -243,20 +231,7 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I if (fMaxValue != null) return fMaxValue.longValue(); - long maxValue = Long.MIN_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v > maxValue) { - maxValue = v; - } - } - } - } + long maxValue = SemanticUtil.computeMaxValue(this); fMaxValue= maxValue; return maxValue; } @@ -278,10 +253,7 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I if (definition == null) { ICPPEnumeration typeInIndex= getIndexBinding(); if (typeInIndex != null) { - try { - return typeInIndex.getEnumerators(); - } catch (DOMException e) { - } + return typeInIndex.getEnumerators(); } return EMPTY_ENUMERATORS; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java new file mode 100644 index 00000000000..8f0c041607d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; + +/** + * Binding for a specialization of an enumeration. + */ +public class CPPEnumerationSpecialization extends CPPSpecialization implements ICPPEnumerationSpecialization { + private IEnumerator[] fEnumerators; + private final IType fFixedType; + + public CPPEnumerationSpecialization(ICPPEnumeration specialized, IBinding owner, + ICPPTemplateParameterMap argumentMap, IType fixedType) { + super(specialized, owner, argumentMap); + fFixedType = fixedType; + } + + public void setEnumerators(IEnumerator[] enumerators) { + fEnumerators = enumerators; + } + + @Override + public ICPPEnumeration getSpecializedBinding() { + return (ICPPEnumeration) super.getSpecializedBinding(); + } + + @Override + public IEnumerator[] getEnumerators() { + return fEnumerators; + } + + @Override + public long getMinValue() { + return SemanticUtil.computeMinValue(this); + } + + @Override + public long getMaxValue() { + return SemanticUtil.computeMaxValue(this); + } + + @Override + public boolean isSameType(IType type) { + if (type == this) + return true; + if (type instanceof ITypedef) + return type.isSameType(this); + if (!(type instanceof ICPPEnumerationSpecialization)) + return false; + ICPPEnumerationSpecialization otherEnumSpec = (ICPPEnumerationSpecialization) type; + return getSpecializedBinding().isSameType(otherEnumSpec.getSpecializedBinding()) + && ((IType) getOwner()).isSameType((IType) otherEnumSpec.getOwner()); + } + + @Override + public boolean isScoped() { + return getSpecializedBinding().isScoped(); + } + + @Override + public IType getFixedType() { + return fFixedType; + } + + @Override + public ICPPScope asScope() { + // TODO(nathanridge): Do we need a CPPEnumSpecializationScope? + return getSpecializedBinding().asScope(); + } + + @Override + public Object clone() { + throw new IllegalArgumentException("Enums must not be cloned"); //$NON-NLS-1$ + } + + @Override + public IEnumerator specializeEnumerator(IEnumerator enumerator) { + // The specialized enumerators are already computed, just need + // to look up the right one. + IEnumerator[] unspecializedEnumerators = getSpecializedBinding().getEnumerators(); + for (int i = 0; i < fEnumerators.length; ++i) { + if (enumerator.equals(unspecializedEnumerators[i])) + return fEnumerators[i]; + } + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java new file mode 100644 index 00000000000..b3c3ca4516e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; + +/** + * Binding for a specialization of an enumerator. + */ +public class CPPEnumeratorSpecialization extends CPPSpecialization implements IEnumerator { + private final IValue fValue; + + public CPPEnumeratorSpecialization(IEnumerator specialized, ICPPEnumerationSpecialization owner, + ICPPTemplateParameterMap argumentMap, IValue value) { + super(specialized, owner, argumentMap); + fValue = value; + } + + @Override + public ICPPEnumerationSpecialization getOwner() { + return (ICPPEnumerationSpecialization) super.getOwner(); + } + + @Override + public IType getType() { + return getOwner(); + } + + @Override + public IValue getValue() { + return fValue; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java index dd10111a8ec..28fad2be5be 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java @@ -1,11 +1,11 @@ /******************************************************************************* - * 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: + * Contributors: * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java index 2f17485600e..1da54960e1f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2011 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 + * Copyright (c) 2011 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: + * Contributors: * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTExplicitTemplateInstantiation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTExplicitTemplateInstantiation.java index b448edc6823..9939dba8dfd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTExplicitTemplateInstantiation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTExplicitTemplateInstantiation.java @@ -1,12 +1,12 @@ /******************************************************************************* - * 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 + * 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: - * IBM - Initial API and implementation + * Contributors: + * IBM - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTPointer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTPointer.java index cedafe070b5..50c8a49de9a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTPointer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GPPASTPointer.java @@ -1,12 +1,12 @@ /******************************************************************************* - * 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 + * 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: - * IBM - Initial API and implementation + * Contributors: + * IBM - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java index 0ed1f673f48..043325baa46 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2012, 2013 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 @@ -8,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -38,23 +39,25 @@ public interface ICPPEvaluation extends ISerializableEvaluation { boolean isValueDependent(); /** - * TODO Add description + * Returns the type of the expression, or a {@code FunctionSetType} if the expression evaluates + * to a function set. * - * @param point determines the scope for name lookups + * @param point the point of instantiation, determines the scope for name lookups */ IType getTypeOrFunctionSet(IASTNode point); /** - * TODO Add description + * Returns the value of the expression. * - * @param point determines the scope for name lookups + * @param point the point of instantiation, determines the scope for name lookups */ IValue getValue(IASTNode point); /** - * TODO Add description + * Returns the category of the expression value. + * @see ValueCategory * - * @param point determines the scope for name lookups + * @param point the point of instantiation, determines the scope for name lookups */ ValueCategory getValueCategory(IASTNode point); @@ -77,16 +80,22 @@ public interface ICPPEvaluation extends ISerializableEvaluation { * * @param parameterMap maps function parameters to their values * @param maxdepth allowed recursion depth - * @param point determines the scope for name lookups + * @param point the point of instantiation, determines the scope for name lookups * @return the computed evaluation */ ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap, int maxdepth, IASTNode point); /** - * Determines size of the template parameter pack. + * Searches the evaluation for a usage of a template parameter which is a parameter pack, + * and returns the number of arguments bound to that parameter pack in the given + * template parameter map. * - * @noreference This method is not intended to be referenced by clients. + * Can also return one of the special values CPPTemplates.PACK_SIZE_DEFER, + * CPPTemplates.PACK_SIZE_FAIL, and CPPTemplates.PACK_SIZE_NOT_FOUND. See their + * declarations for their meanings. + * + * See also {@code CPPTemplates.determinePackSize()}. */ int determinePackSize(ICPPTemplateParameterMap tpMap); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index d1d279b2628..c68c28a7f23 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Google, Inc and others. + * Copyright (c) 2012, 2013 Google, 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 @@ -7,211 +7,23 @@ * * Contributors: * Sergey Prigogin (Google) - initial API and implementation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.IValue; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; -import org.eclipse.cdt.core.parser.util.CharArrayUtils; -import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; -import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; -import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; -import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.core.runtime.CoreException; public abstract class CPPEvaluation implements ICPPEvaluation { - private static class SignatureBuilder implements ITypeMarshalBuffer { - private static final byte NULL_TYPE= 0; - private static final byte UNSTORABLE_TYPE= (byte) -1; - - private final StringBuilder fBuffer; - - /** - * Constructor for input buffer. - */ - public SignatureBuilder() { - fBuffer= new StringBuilder(); - } - - @Override - public String toString() { - return fBuffer.toString(); - } - - public char[] getSignature() { - return CharArrayUtils.extractChars(fBuffer); - } - - @Override - public void marshalBinding(IBinding binding) throws CoreException { - if (binding instanceof ISerializableType) { - ((ISerializableType) binding).marshal(this); - } else if (binding == null) { - putByte(NULL_TYPE); - } else { - appendSeparator(); - if (binding instanceof ICPPBinding) { - if (binding instanceof ICPPTemplateParameter) { - ICPPTemplateParameter param = (ICPPTemplateParameter) binding; - fBuffer.append(param.isParameterPack() ? '*' : '#'); - fBuffer.append(param.getParameterID()); - } else { - fBuffer.append(ASTTypeUtil.getQualifiedName((ICPPBinding) binding)); - } - } else { - fBuffer.append(binding.getNameCharArray()); - } - } - } - - @Override - public void marshalType(IType type) throws CoreException { - if (type instanceof ISerializableType) { - ((ISerializableType) type).marshal(this); - } else if (type == null) { - putByte(NULL_TYPE); - } else if (type instanceof IBinding) { - marshalBinding((IBinding) type); - } else { - assert false : "Cannot serialize " + ASTTypeUtil.getType(type) + " (" + type.getClass().getName() + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - putByte(UNSTORABLE_TYPE); - } - } - - @Override - public void marshalEvaluation(ISerializableEvaluation eval, boolean includeValues) throws CoreException { - if (eval == null) { - putByte(NULL_TYPE); - } else { - eval.marshal(this, includeValues); - } - } - - @Override - public void marshalValue(IValue value) throws CoreException { - if (value instanceof Value) { - ((Value) value).marshall(this); - } else { - putByte(NULL_TYPE); - } - } - - @Override - public void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException { - if (arg.isNonTypeValue()) { - putByte(VALUE); - arg.getNonTypeEvaluation().marshal(this, true); - } else { - marshalType(arg.getTypeValue()); - } - } - - @Override - public void putByte(byte value) { - appendSeparator(); - fBuffer.append(value); - } - - @Override - public void putFixedInt(int value) { - appendSeparator(); - fBuffer.append(value); - } - - @Override - public void putInt(int value) { - appendSeparator(); - fBuffer.append(value); - } - - @Override - public void putLong(long value) { - appendSeparator(); - fBuffer.append(value); - } - - @Override - public void putCharArray(char[] chars) { - appendSeparator(); - for (char c : chars) { - fBuffer.append(c); - } - } - - private void appendSeparator() { - if (fBuffer.length() != 0) - fBuffer.append(' '); - } - - @Override - public IBinding unmarshalBinding() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public IType unmarshalType() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public ISerializableEvaluation unmarshalEvaluation() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public IValue unmarshalValue() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public int getByte() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public CoreException unmarshallingError() { - throw new UnsupportedOperationException(); - } - - @Override - public int getFixedInt() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public int getInt() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public long getLong() throws CoreException { - throw new UnsupportedOperationException(); - } - - @Override - public char[] getCharArray() throws CoreException { - throw new UnsupportedOperationException(); - } - } - CPPEvaluation() { } @@ -246,4 +58,14 @@ public abstract class CPPEvaluation implements ICPPEvaluation { } return args; } + + protected static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset, + ICPPClassSpecialization within, int maxdepth, IASTNode point) { + try { + return CPPTemplates.instantiateBinding(binding, tpMap, packOffset, within, maxdepth, point); + } catch (DOMException e) { + CCorePlugin.log(e); + } + return binding; + } } \ No newline at end of file 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 61f55dfe0fe..a1421067623 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 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 @@ -42,7 +42,6 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; @@ -76,11 +75,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; @@ -119,6 +121,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorSpecialization import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplateSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumerationSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeratorSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionSpecialization; @@ -161,9 +165,23 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMod * type instantiation. */ public class CPPTemplates { + // The three constants below are used as special return values for the various overloads + // of CPPTemplates.determinePackSize() and for ICPPEvaluation.determinePackSize(), which + // search a type, template argument, or value for a usage of a template parameter pack + // and return the number of arguments bound to that parameter pack in an + // ICPPTemplateParameterMap. + + // Used to indicate that the parameter pack is not bound to any arguments in the + // template parameter map. Computation of the pack size needs to be deferred until + // arguments for it become available. static final int PACK_SIZE_DEFER = -1; + + // Used to indicate that two different packs with different sizes were found. static final int PACK_SIZE_FAIL = -2; + + // Used to indicate that no template parameter packs were found. static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; + static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE } /** @@ -837,9 +855,29 @@ public class CPPTemplates { ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) decl; IType type= instantiateType(aliasTemplate.getType(), tpMap, -1, getSpecializationContext(owner), point); spec = new CPPAliasTemplateInstance(decl.getNameCharArray(), aliasTemplate, type); - } else if (decl instanceof IEnumeration || decl instanceof IEnumerator) { - // TODO(sprigogin): Deal with a case when an enumerator value depends on a template parameter. - spec = decl; + } else if (decl instanceof ICPPEnumeration) { + ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPEnumeration enumeration = (ICPPEnumeration) decl; + IType fixedType = instantiateType(enumeration.getFixedType(), tpMap, -1, within, point); + CPPEnumerationSpecialization specializedEnumeration = + new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType); + IEnumerator[] enumerators = enumeration.getEnumerators(); + IEnumerator[] specializedEnumerators = new IEnumerator[enumerators.length]; + for (int i = 0; i < enumerators.length; ++i) { + IEnumerator enumerator = enumerators[i]; + IValue specializedValue = + instantiateValue(enumerator.getValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); + specializedEnumerators[i] = + new CPPEnumeratorSpecialization(enumerator, specializedEnumeration, tpMap, specializedValue); + } + specializedEnumeration.setEnumerators(specializedEnumerators); + spec = specializedEnumeration; + } else if (decl instanceof IEnumerator) { + IEnumerator enumerator = (IEnumerator) decl; + ICPPEnumeration enumeration = (ICPPEnumeration) enumerator.getOwner(); + ICPPEnumerationSpecialization enumSpec = + (ICPPEnumerationSpecialization) owner.specializeMember(enumeration, point); + spec = enumSpec.specializeEnumerator(enumerator); } else if (decl instanceof ICPPUsingDeclaration) { IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates(); List result= new ArrayList(); @@ -1290,6 +1328,53 @@ public class CPPTemplates { } } + public static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset, + ICPPClassSpecialization within, int maxdepth, IASTNode point) throws DOMException { + if (binding instanceof ICPPClassTemplate) { + binding = createDeferredInstance((ICPPClassTemplate) binding); + } + + if (binding instanceof ICPPUnknownBinding) { + return resolveUnknown((ICPPUnknownBinding) binding, tpMap, packOffset, within, point); + } else if (binding instanceof IEnumerator + || binding instanceof ICPPMethod + || binding instanceof ICPPField + || binding instanceof ICPPEnumeration + || binding instanceof ICPPClassType) { + IBinding owner = binding.getOwner(); + if (!(owner instanceof ICPPSpecialization)) { + owner = instantiateBinding(owner, tpMap, packOffset, within, maxdepth, point); + } + if (binding instanceof IEnumerator) { + if (owner instanceof ICPPEnumerationSpecialization) { + return ((ICPPEnumerationSpecialization) owner).specializeEnumerator((IEnumerator) binding); + } + } else { + if (owner instanceof ICPPClassSpecialization) { + return ((ICPPClassSpecialization) owner).specializeMember(binding, point); + } + } + } else if (binding instanceof CPPFunctionInstance) { + // TODO(nathanridge): + // Maybe we should introduce a CPPDeferredFunctionInstance and have things that can return + // a dependent CPPFunctionInstance (like instantiateForAddressOfFunction) return that when + // appropriate? + CPPFunctionInstance origInstance = (CPPFunctionInstance) binding; + ICPPTemplateArgument[] origArgs = origInstance.getTemplateArguments(); + ICPPTemplateArgument[] newArgs = instantiateArguments(origArgs, tpMap, packOffset, within, point, false); + if (origArgs != newArgs) { + CPPTemplateParameterMap newMap = instantiateArgumentMap(origInstance.getTemplateParameterMap(), + tpMap, packOffset, within, point); + IType newType = instantiateType(origInstance.getType(), tpMap, packOffset, within, point); + IType[] newExceptionSpecs = instantiateTypes(origInstance.getExceptionSpecification(), + tpMap, packOffset, within, point); + return new CPPFunctionInstance((ICPPFunction) origInstance.getTemplateDefinition(), origInstance.getOwner(), + newMap, newArgs, (ICPPFunctionType) newType, newExceptionSpecs); + } + } + return binding; + } + public static IType resolveTemplateTypeParameter(final ICPPTemplateParameter tpar, ICPPTemplateParameterMap tpMap, int packOffset, IASTNode point) { ICPPTemplateArgument arg= null; @@ -1958,13 +2043,34 @@ public class CPPTemplates { return arg; } + private static ICPPFunctionType getFunctionTypeIgnoringParametersWithDefaults(ICPPFunction function) { + ICPPParameter[] parameters = function.getParameters(); + IType[] parameterTypes = new IType[parameters.length]; + int i; + for (i = 0; i < parameters.length; ++i) { + ICPPParameter parameter = parameters[i]; + if (!parameter.hasDefaultValue()) { + parameterTypes[i] = parameter.getType(); + } else { + break; + } + } + ICPPFunctionType originalType = function.getType(); + if (i == parameters.length) // no parameters with default arguments + return originalType; + return new CPPFunctionType(originalType.getReturnType(), ArrayUtil.trim(parameterTypes), + originalType.isConst(), originalType.isVolatile(), originalType.takesVarArgs()); + } + private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point) throws DOMException { ICPPFunction transF1 = transferFunctionTemplate(f1, point); if (transF1 == null) return -1; final ICPPFunctionType ft2 = f2.getType(); - final ICPPFunctionType transFt1 = transF1.getType(); + // Ignore parameters with default arguments in the transformed function template + // as per [temp.func.order] p5. + final ICPPFunctionType transFt1 = getFunctionTypeIgnoringParametersWithDefaults(transF1); IType[] pars; IType[] args; switch(mode) { @@ -2118,8 +2224,6 @@ public class CPPTemplates { final ICPPTemplateParameter[] tpars2 = f2.getTemplateParameters(); final ICPPTemplateArgument[] targs1 = f1.getTemplateArguments(); final ICPPTemplateArgument[] targs2 = f2.getTemplateArguments(); - if (targs1.length != targs2.length) - return false; // Transfer arguments of specialization 1 final int tpars1Len = tpars1.length; @@ -2129,22 +2233,17 @@ public class CPPTemplates { final ICPPTemplateParameter param = tpars1[i]; final ICPPTemplateArgument arg = uniqueArg(param); args[i]= arg; - transferMap.put(param, arg); + if (param.isParameterPack()) { + transferMap.put(param, new ICPPTemplateArgument[] { arg }); + } else { + transferMap.put(param, arg); + } } final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point, false); // Deduce arguments for specialization 2 final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2); - if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point)) - return false; - - // Compare - for (int i = 0; i < targs2.length; i++) { - ICPPTemplateArgument transferredArg2= instantiateArgument(targs2[i], deductionMap, -1, null, point); - if (!transferredArg2.isSameValue(transferredArgs1[i])) - return false; - } - return true; + return TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point); } static boolean isValidType(IType t) { @@ -2226,6 +2325,9 @@ public class CPPTemplates { pType= instantiateType(pType, map, -1, null, point); } + if (argType instanceof ICPPParameterPackType) { + argType = ((ICPPParameterPackType) argType).getType(); + } if (argType instanceof ICPPUnknownType) { return new CPPTemplateNonTypeArgument(arg.getNonTypeValue(), pType); } @@ -2378,7 +2480,8 @@ public class CPPTemplates { if (arg.isTypeValue()) return isDependentType(arg.getTypeValue()); - return arg.getNonTypeEvaluation().isValueDependent(); + ICPPEvaluation evaluation = arg.getNonTypeEvaluation(); + return evaluation.isTypeDependent() || evaluation.isValueDependent(); } public static boolean containsDependentType(List ts) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 8afc1bf3d89..f5762cf74ef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2012 IBM Corporation and others. + * Copyright (c) 2004, 2013 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 @@ -12,6 +12,7 @@ * Sergey Prigogin (Google) * Thomas Corbat (IFS) * Nathan Ridge + * Marc-Andre Laperle *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -405,6 +406,9 @@ public class CPPVisitor extends ASTQueries { IBinding binding = scope.getBinding(name, false); if (binding instanceof CPPEnumeration) { CPPEnumeration e= (CPPEnumeration) binding; + if (name.equals(e.getDefinition())) { + return e; + } if (e.isScoped() == specifier.isScoped()) { IType ft2= e.getFixedType(); if (fixedType == ft2 || (fixedType != null && fixedType.isSameType(ft2))) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index a4419e5c668..d8567779e1e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2012, 2013 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 @@ -25,10 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; @@ -241,20 +238,14 @@ public class EvalBinding extends CPPEvaluation { } if (binding instanceof ICPPTemplateNonTypeParameter) { IType type= ((ICPPTemplateNonTypeParameter) binding).getType(); - if (CPPTemplates.isDependentType(type)) - return new TypeOfDependentExpression(this); return prvalueType(type); } if (binding instanceof IVariable) { final IType type = ((IVariable) binding).getType(); - if (CPPTemplates.isDependentType(type)) - return new TypeOfDependentExpression(this); return SemanticUtil.mapToAST(glvalueType(type), point); } if (binding instanceof IFunction) { final IFunctionType type = ((IFunction) binding).getType(); - if (CPPTemplates.isDependentType(type)) - return new TypeOfDependentExpression(this); return SemanticUtil.mapToAST(type, point); } return ProblemType.UNKNOWN_FOR_EXPRESSION; @@ -325,55 +316,26 @@ public class EvalBinding extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - IBinding binding = getBinding(); - if (binding instanceof IEnumerator) { - IEnumerator enumerator = (IEnumerator) binding; - IType originalType = enumerator.getType(); - IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point); - IValue originalValue = enumerator.getValue(); - IValue value = CPPTemplates.instantiateValue(originalValue, tpMap, packOffset, within, maxdepth, point); - // TODO(sprigogin): Not sure if following condition is correct. - if (type != originalType || value != originalValue) - return new EvalFixed(type, ValueCategory.PRVALUE, value); - } else if (binding instanceof ICPPTemplateNonTypeParameter) { - ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) binding); + IBinding origBinding = getBinding(); + if (origBinding instanceof ICPPTemplateNonTypeParameter) { + ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) origBinding); if (argument != null && argument.isNonTypeValue()) { return argument.getNonTypeEvaluation(); } // TODO(sprigogin): Do we need something similar for pack expansion? - } else if (binding instanceof ICPPUnknownBinding) { - binding = resolveUnknown((ICPPUnknownBinding) binding, tpMap, packOffset, within, point); - } else if (binding instanceof ICPPMethod) { - IBinding owner = binding.getOwner(); - if (owner instanceof ICPPClassTemplate) { - owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), - tpMap, packOffset, within, point); - } - if (owner instanceof ICPPClassSpecialization) { - binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner, - binding, point); - } - } else if (binding instanceof ICPPField) { - IBinding owner = binding.getOwner(); - if (owner instanceof ICPPClassTemplate) { - owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), - tpMap, packOffset, within, point); - } - if (owner instanceof ICPPClassSpecialization) { - binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner, - binding, point); - } - } else if (binding instanceof ICPPParameter) { - ICPPParameter parameter = (ICPPParameter) binding; - IType originalType = parameter.getType(); - IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point); - if (originalType != type) { - return new EvalFixed(type, ValueCategory.LVALUE, Value.create(this)); + } else if (origBinding instanceof ICPPParameter) { + ICPPParameter parameter = (ICPPParameter) origBinding; + IType origType = parameter.getType(); + IType instantiatedType = CPPTemplates.instantiateType(origType, tpMap, packOffset, within, point); + if (origType != instantiatedType) { + return new EvalFixed(instantiatedType, ValueCategory.LVALUE, Value.create(this)); } + } else { + IBinding instantiatedBinding = instantiateBinding(origBinding, tpMap, packOffset, within, maxdepth, point); + if (instantiatedBinding != origBinding) + return new EvalBinding(instantiatedBinding, null); } - if (binding == fBinding) - return this; - return new EvalBinding(binding, getFixedType()); + return this; } @Override 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 74760703536..61c5c7883af 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 @@ -360,8 +360,13 @@ public class EvalID extends CPPEvaluation { @Override public int determinePackSize(ICPPTemplateParameterMap tpMap) { int r = fFieldOwner != null ? fFieldOwner.determinePackSize(tpMap) : CPPTemplates.PACK_SIZE_NOT_FOUND; - for (ICPPTemplateArgument arg : fTemplateArgs) { - r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap)); + if (fNameOwner instanceof ICPPUnknownBinding) { + r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize((ICPPUnknownBinding) fNameOwner, tpMap)); + } + if (fTemplateArgs != null) { + for (ICPPTemplateArgument arg : fTemplateArgs) { + r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap)); + } } return r; } 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 5431c752d7c..a5d91072c07 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2012 IBM Corporation and others. + * Copyright (c) 2004, 2013 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 @@ -11,6 +11,7 @@ * Bryan Wilkinson (QNX) * Andrew Ferguson (Symbian) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -33,12 +34,15 @@ import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +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.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.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; @@ -49,7 +53,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -663,49 +666,46 @@ public class SemanticUtil { return -1; } - public static boolean containsUniqueTypeForParameterPack(IType type) { - if (type instanceof ICPPFunctionType) { - final ICPPFunctionType ft = (ICPPFunctionType) type; - if (containsUniqueTypeForParameterPack(ft.getReturnType())) - return true; - - for (IType pt : ft.getParameterTypes()) { - if (containsUniqueTypeForParameterPack(pt)) - return true; - } - return false; - } - - if (type instanceof ICPPPointerToMemberType) { - if (containsUniqueTypeForParameterPack(((ICPPPointerToMemberType) type).getMemberOfClass())) - return true; - } - - if (type instanceof IBinding) { - IBinding owner = ((IBinding) type).getOwner(); - if (owner instanceof IType) { - if (containsUniqueTypeForParameterPack((IType) owner)) - return true; - } - } - - if (type instanceof ICPPTemplateInstance) { - ICPPTemplateArgument[] args = ((ICPPTemplateInstance) type).getTemplateArguments(); - for (ICPPTemplateArgument arg : args) { - if (containsUniqueTypeForParameterPack(arg.getTypeValue())) - return true; - } - } - - if (type instanceof ITypeContainer) { - final ITypeContainer tc = (ITypeContainer) type; - final IType nestedType= tc.getType(); - return containsUniqueTypeForParameterPack(nestedType); - } - + public static boolean isUniqueTypeForParameterPack(IType type) { if (type instanceof UniqueType) { return ((UniqueType) type).isForParameterPack(); } return false; } + + public static long computeMaxValue(IEnumeration enumeration) { + long maxValue = Long.MIN_VALUE; + IEnumerator[] enumerators = enumeration.getEnumerators(); + for (IEnumerator enumerator : enumerators) { + IValue value = enumerator.getValue(); + if (value != null) { + Long val = value.numericalValue(); + if (val != null) { + long v = val.longValue(); + if (v > maxValue) { + maxValue = v; + } + } + } + } + return maxValue; + } + + public static long computeMinValue(IEnumeration enumeration) { + long minValue = Long.MAX_VALUE; + IEnumerator[] enumerators = enumeration.getEnumerators(); + for (IEnumerator enumerator : enumerators) { + IValue value = enumerator.getValue(); + if (value != null) { + Long val = value.numericalValue(); + if (val != null) { + long v = val.longValue(); + if (v < minValue) { + minValue = v; + } + } + } + } + return minValue; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SignatureBuilder.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SignatureBuilder.java new file mode 100644 index 00000000000..7ec523e7b46 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SignatureBuilder.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2012, 2013 Google, 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; + +import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; +import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.core.runtime.CoreException; + +class SignatureBuilder implements ITypeMarshalBuffer { + private static final byte NULL_TYPE= 0; + private static final byte UNSTORABLE_TYPE= (byte) -1; + + private final StringBuilder fBuffer; + + /** + * Constructor for input buffer. + */ + public SignatureBuilder() { + fBuffer= new StringBuilder(); + } + + @Override + public String toString() { + return fBuffer.toString(); + } + + public char[] getSignature() { + return CharArrayUtils.extractChars(fBuffer); + } + + @Override + public void marshalBinding(IBinding binding) throws CoreException { + if (binding instanceof ISerializableType) { + ((ISerializableType) binding).marshal(this); + } else if (binding == null) { + putByte(NULL_TYPE); + } else { + appendSeparator(); + if (binding instanceof ICPPBinding) { + if (binding instanceof ICPPTemplateParameter) { + ICPPTemplateParameter param = (ICPPTemplateParameter) binding; + fBuffer.append(param.isParameterPack() ? '*' : '#'); + fBuffer.append(param.getParameterID()); + } else { + fBuffer.append(ASTTypeUtil.getQualifiedName((ICPPBinding) binding)); + } + } else { + fBuffer.append(binding.getNameCharArray()); + } + } + } + + @Override + public void marshalType(IType type) throws CoreException { + if (type instanceof ISerializableType) { + ((ISerializableType) type).marshal(this); + } else if (type == null) { + putByte(NULL_TYPE); + } else if (type instanceof IBinding) { + marshalBinding((IBinding) type); + } else { + assert false : "Cannot serialize " + ASTTypeUtil.getType(type) + " (" + type.getClass().getName() + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + putByte(UNSTORABLE_TYPE); + } + } + + @Override + public void marshalEvaluation(ISerializableEvaluation eval, boolean includeValues) throws CoreException { + if (eval == null) { + putByte(NULL_TYPE); + } else { + eval.marshal(this, includeValues); + } + } + + @Override + public void marshalValue(IValue value) throws CoreException { + if (value instanceof Value) { + ((Value) value).marshall(this); + } else { + putByte(NULL_TYPE); + } + } + + @Override + public void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException { + if (arg.isNonTypeValue()) { + putByte(VALUE); + arg.getNonTypeEvaluation().marshal(this, true); + } else { + marshalType(arg.getTypeValue()); + } + } + + @Override + public void putByte(byte value) { + appendSeparator(); + fBuffer.append(value); + } + + @Override + public void putFixedInt(int value) { + appendSeparator(); + fBuffer.append(value); + } + + @Override + public void putInt(int value) { + appendSeparator(); + fBuffer.append(value); + } + + @Override + public void putLong(long value) { + appendSeparator(); + fBuffer.append(value); + } + + @Override + public void putCharArray(char[] chars) { + appendSeparator(); + for (char c : chars) { + fBuffer.append(c); + } + } + + private void appendSeparator() { + if (fBuffer.length() != 0) + fBuffer.append(' '); + } + + @Override + public IBinding unmarshalBinding() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public IType unmarshalType() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public ISerializableEvaluation unmarshalEvaluation() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public IValue unmarshalValue() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public int getByte() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public CoreException unmarshallingError() { + throw new UnsupportedOperationException(); + } + + @Override + public int getFixedInt() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public int getInt() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public long getLong() throws CoreException { + throw new UnsupportedOperationException(); + } + + @Override + public char[] getCharArray() throws CoreException { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file 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 4233824ebbd..8d33b882c8d 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2013 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 @@ -8,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -36,7 +37,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; -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; @@ -431,7 +431,7 @@ public class TemplateArgumentDeduction { deduct.incPackOffset(); } else { if (j >= fnParCount) - return result; + return -1; par= fnPars[j]; if (par instanceof ICPPParameterPackType) { @@ -606,15 +606,37 @@ public class TemplateArgumentDeduction { final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map, IASTNode point) throws DOMException { TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(pars, null, map, 0); - final int len= a.length; - if (p == null || p.length != len) { + if (p == null) { return false; } - for (int j= 0; j < len; j++) { - if (!deduct.fromTemplateArgument(p[j], a[j], point)) { - return false; + boolean containsPackExpansion= false; + for (int j= 0; j < p.length; j++) { + if (p[j].isPackExpansion()) { + deduct = new TemplateArgumentDeduction(deduct, a.length - j); + containsPackExpansion= true; + if (j != p.length - 1) { + return false; // A pack expansion must be the last argument to the specialization. + } + ICPPTemplateArgument pattern = p[j].getExpansionPattern(); + for (int i= j; i < a.length; i++) { + if (i != j) + deduct.incPackOffset(); + if (!deduct.fromTemplateArgument(pattern, a[i], point)) { + return false; + } + } + break; + } else { + if (j >= a.length) { + return false; // Not enough arguments. + } + if (!deduct.fromTemplateArgument(p[j], a[j], point)) { + return false; + } } } + if (!containsPackExpansion && p.length < a.length) + return false; // Too many arguments. return verifyDeduction(pars, map, false, point); } @@ -636,16 +658,8 @@ public class TemplateArgumentDeduction { deducedArg= tpar.getDefaultValue(); if (deducedArg != null) { deducedArg= CPPTemplates.instantiateArgument(deducedArg, tpMap, -1, null, point); - if (deducedArg != null) { - if (deducedArg instanceof CPPTemplateTypeArgument) { - CPPTemplateTypeArgument deducedTypeArg = (CPPTemplateTypeArgument) deducedArg; - if (!(deducedTypeArg.getTypeValue() instanceof ISemanticProblem)) { - tpMap.put(tpar, deducedArg); - } - } else { - // TODO: Check for problems in non-type or template template parameters? - tpMap.put(tpar, deducedArg); - } + if (CPPTemplates.isValidArgument(deducedArg)) { + tpMap.put(tpar, deducedArg); } } } @@ -957,7 +971,7 @@ public class TemplateArgumentDeduction { return false; return fDeducedArgs.putPackElement(parID, fPackOffset, arg, fPackSize); } - if (SemanticUtil.containsUniqueTypeForParameterPack(arg.getTypeValue())) + if (SemanticUtil.isUniqueTypeForParameterPack(arg.getTypeValue())) return false; fDeducedArgs.put(parID, arg); return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java index 6fdd5259adc..d77e3e96595 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2012, 2013 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 @@ -7,9 +7,11 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; @@ -48,6 +50,17 @@ public class TypeOfDependentExpression implements ICPPUnknownType, ISerializable } } + public char[] getSignature() { + SignatureBuilder buf = new SignatureBuilder(); + try { + marshal(buf); + } catch (CoreException e) { + CCorePlugin.log(e); + return new char[] { '?' }; + } + return buf.getSignature(); + } + @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { buffer.putByte(ITypeMarshalBuffer.DEPENDENT_EXPRESSION_TYPE); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java index 7aab87f9d8d..a56f3d3318f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Symbian Software Systems and others. + * Copyright (c) 2007, 2013 Symbian 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 @@ * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) * Thomas Corbat (IFS) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.index; @@ -62,4 +63,6 @@ public interface IIndexCPPBindingConstants { int CPP_USING_DECLARATION_SPECIALIZATION= IIndexBindingConstants.LAST_CONSTANT + 49; int CPP_UNKNOWN_METHOD = IIndexBindingConstants.LAST_CONSTANT + 50; int CPP_TEMPLATE_ALIAS = IIndexBindingConstants.LAST_CONSTANT + 51; + int CPP_ENUMERATION_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 52; + int CPP_ENUMERATOR_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 53; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java index a08ab1bb058..6b6416b7c5b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.c; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; @@ -25,7 +24,7 @@ class CompositeCEnumeration extends CompositeCBinding implements IEnumeration, I } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { IEnumerator[] result = ((IEnumeration)rbinding).getEnumerators(); for (int i= 0; i < result.length; i++) result[i] = (IEnumerator) cf.getCompositeBinding((IIndexFragmentBinding) result[i]); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java index dbae723aa2f..21835141616 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; @@ -27,7 +26,7 @@ class CompositeCPPEnumeration extends CompositeCPPBinding implements ICPPEnumera } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { IEnumerator[] result = ((IEnumeration)rbinding).getEnumerators(); for (int i= 0; i < result.length; i++) result[i] = (IEnumerator) cf.getCompositeBinding((IIndexFragmentBinding) result[i]); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java index a9de019b08e..456eec950f4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java @@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.parser; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -159,26 +158,15 @@ public class InternalParserUtil extends ParserFactory { IFileStore store = EFS.getStore(file.getLocationURI()); IFileInfo fileInfo = store.fetchInfo(); input= file.getContents(true); - if (!(input instanceof FileInputStream)) { - /* - * In general, non-local file-systems will not use FileInputStream. - * Instead make a cached copy of the file and open an input stream to that. - */ - File fileCache = store.toLocalFile(EFS.CACHE, null); + if (input instanceof FileInputStream) { try { - input = new FileInputStream(fileCache); - } catch (FileNotFoundException e) { - CCorePlugin.log(e); - return null; - } - } - try { - return createFileContent(path, file.getCharset(), input, - fileInfo.getLastModified(), fileInfo.getLength(), fileReadTime); - } finally { - try { - input.close(); - } catch (IOException e) { + return createFileContent(path, null, file.getCharset(), input, + fileInfo.getLastModified(), fileInfo.getLength(), fileReadTime); + } finally { + try { + input.close(); + } catch (IOException e) { + } } } } catch (CoreException e) { @@ -193,18 +181,19 @@ public class InternalParserUtil extends ParserFactory { CCorePlugin.log(e); break; } - return null; } + return null; } /** * Creates a code reader for an external location, normalizing path to * canonical path. */ - public static InternalFileContent createExternalFileContent(String externalLocation, String encoding) { + public static InternalFileContent createExternalFileContent(final String externalLocation, String encoding) { long fileReadTime = System.currentTimeMillis(); File includeFile = null; String path = null; + String localPath = null; if (!UNCPathConverter.isUNC(externalLocation)) { includeFile = new File(externalLocation); // Use the canonical path so that in case of non-case-sensitive OSs @@ -216,6 +205,7 @@ public class InternalParserUtil extends ParserFactory { IFileStore store = EFS.getStore(UNCPathConverter.getInstance().toURI(externalLocation)); includeFile = store.toLocalFile(EFS.CACHE, null); path = externalLocation; + localPath = includeFile.getAbsolutePath(); } catch (CoreException e) { } } @@ -230,7 +220,7 @@ public class InternalParserUtil extends ParserFactory { return null; } try { - return createFileContent(path, encoding, in, timestamp, fileSize, fileReadTime); + return createFileContent(path, localPath, encoding, in, timestamp, fileSize, fileReadTime); } finally { try { in.close(); @@ -241,10 +231,13 @@ public class InternalParserUtil extends ParserFactory { return null; } - private static InternalFileContent createFileContent(String path, String charset, InputStream in, + private static InternalFileContent createFileContent(String path, String localPath, String charset, InputStream in, long fileTimestamp, long fileSize, long fileReadTime) { + if (localPath == null) { + localPath = path; + } try { - AbstractCharArray chars= FileCharArray.create(path, charset, in); + AbstractCharArray chars= FileCharArray.create(localPath, charset, in); if (chars == null) return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContentProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContentProvider.java index 1899ef3bc29..ff79a122a88 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContentProvider.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/InternalFileContentProvider.java @@ -28,6 +28,10 @@ import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.parser.IMacroDictionary; import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent.InclusionKind; +import org.eclipse.cdt.utils.UNCPathConverter; +import org.eclipse.core.filesystem.EFS; +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.runtime.CoreException; /** * Internal implementation of the file content providers @@ -49,7 +53,16 @@ public abstract class InternalFileContentProvider extends IncludeFileContentProv /** * Checks whether the specified inclusion exists. */ - public boolean getInclusionExists(String path) { + public boolean getInclusionExists(final String path) { + if (UNCPathConverter.isUNC(path)) { + try { + IFileStore store = EFS.getStore(UNCPathConverter.getInstance().toURI(path)); + return store.fetchInfo().exists(); + } catch (CoreException e) { + return false; + } + } + return new File(path).exists(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtx.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtx.java index fee6a0479b0..3c62af24107 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtx.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtx.java @@ -130,7 +130,7 @@ abstract class LocationCtx implements ILocationCtx { * Returns the sequence of file locations spanning the given range. * Assumes that the range starts within this context. */ - public abstract boolean collectLocations(int sequenceNumber, int length, ArrayList sofar); + public abstract void collectLocations(int sequenceNumber, int length, ArrayList sofar); /** * Support for the dependency tree, add inclusion statements found in this context. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxContainer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxContainer.java index 6323e537149..4e11a04c5fe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxContainer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxContainer.java @@ -32,7 +32,7 @@ class LocationCtxContainer extends LocationCtx { private int fChildSequenceLength; private ArrayList fChildren; - private AbstractCharArray fSource; + private final AbstractCharArray fSource; private int[] fLineOffsets; public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source, @@ -138,47 +138,55 @@ class LocationCtxContainer extends LocationCtx { } @Override - public boolean collectLocations(int sequenceNumber, final int length, ArrayList locations) { + public void collectLocations(int sequenceNumber, final int length, ArrayList locations) { + if (length < 1) + return; + final int endSequenceNumber= sequenceNumber + length; if (fChildren != null) { int childIdx= Math.max(0, findChildIdxLessOrEqualThan(sequenceNumber, false)); for (; childIdx < fChildren.size(); childIdx++) { final LocationCtx child= fChildren.get(childIdx); - // create the location between start and the child + // Create the location between start and the child if (sequenceNumber < child.fSequenceNumber) { - // compute offset backwards from the child's offset + // Compute offset backwards from the child's offset in this location final int offset= child.fEndOffsetInParent - (child.fSequenceNumber - sequenceNumber); - // it the child is not affected, we are done. + + // Requested range ends before the child. if (endSequenceNumber <= child.fSequenceNumber) { addFileLocation(offset, endSequenceNumber - sequenceNumber, locations); - return true; + return; } - if (offset < child.fOffsetInParent) + + final int gapLen = child.fOffsetInParent - offset; + if (gapLen > 0) addFileLocation(offset, child.fOffsetInParent - offset, locations); + sequenceNumber= child.fSequenceNumber; + assert sequenceNumber < endSequenceNumber; } - // let the child create locations + // Let the child create locations final int childEndSequenceNumber= child.fSequenceNumber + child.getSequenceLength(); - if (sequenceNumber < childEndSequenceNumber) { - if (child.collectLocations(sequenceNumber, endSequenceNumber - sequenceNumber, locations)) { - return true; - } + if (sequenceNumber < childEndSequenceNumber + || (sequenceNumber == childEndSequenceNumber && !locations.isEmpty())) { + child.collectLocations(sequenceNumber, endSequenceNumber - sequenceNumber, locations); sequenceNumber= childEndSequenceNumber; + if (sequenceNumber >= endSequenceNumber) + return; } } } - // create the location after the last child. + // Create the location after the last child. final int myEndNumber = fSequenceNumber + getSequenceLength(); final int offset= fSource.getLength() - (myEndNumber - sequenceNumber); if (endSequenceNumber <= myEndNumber) { addFileLocation(offset, endSequenceNumber - sequenceNumber, locations); - return true; + } else { + addFileLocation(offset, fSource.getLength() - offset, locations); } - addFileLocation(offset, fSource.getLength() - offset, locations); - return false; } private ArrayList addFileLocation(int offset, int length, ArrayList sofar) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java index d94e229e8fb..90bba002862 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationCtxMacroExpansion.java @@ -25,7 +25,7 @@ class LocationCtxMacroExpansion extends LocationCtx { private final LocationMap fLocationMap; private final int fLength; private final ImageLocationInfo[] fLocationInfos; - private ASTMacroReferenceName fExpansionName; + private final ASTMacroReferenceName fExpansionName; public LocationCtxMacroExpansion(LocationMap map, LocationCtxContainer parent, int parentOffset, int parentEndOffset, int sequenceNumber, int length, ImageLocationInfo[] imageLocations, ASTMacroReferenceName expansionName) { @@ -45,17 +45,15 @@ class LocationCtxMacroExpansion extends LocationCtx { } @Override - public boolean collectLocations(int start, int length, ArrayList locations) { + public void collectLocations(int start, int length, ArrayList locations) { final int offset= start - fSequenceNumber; assert offset >= 0 && length >= 0; if (offset + length <= fLength) { locations.add(new ASTMacroExpansionLocation(this, offset, length)); - return true; + } else { + locations.add(new ASTMacroExpansionLocation(this, offset, fLength-offset)); } - - locations.add(new ASTMacroExpansionLocation(this, offset, fLength-offset)); - return false; } public ASTMacroExpansion getExpansion() { 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 c042cd8cf51..03c11be0d0c 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 @@ -229,10 +229,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 137.0 - Fixed serialization of very large types and template arguments, bug 392278. * 138.0 - Constexpr functions, bug 395238. * 139.0 - More efficient and robust storage of types and template arguments, bug 395243. + * 140.0 - Enumerators with dependent values, bug 389009. */ - private static final int MIN_SUPPORTED_VERSION= version(139, 0); - private static final int MAX_SUPPORTED_VERSION= version(139, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(139, 0); + private static final int MIN_SUPPORTED_VERSION= version(140, 0); + private static final int MAX_SUPPORTED_VERSION= version(140, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(140, 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/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java index d320edec18a..0ea282443f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java @@ -309,7 +309,7 @@ public class PDOMASTAdapter { } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { return fDelegate.getEnumerators(); } @@ -507,7 +507,7 @@ public class PDOMASTAdapter { } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { return ((IEnumeration) fDelegate).getEnumerators(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java index 2c0fe31c7e5..41c821468c4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java @@ -6,10 +6,10 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation - * IBM Corporation - * Andrew Ferguson (Symbian) - * Markus Schorn (Wind River Systems) + * QNX - Initial API and implementation + * IBM Corporation + * Andrew Ferguson (Symbian) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; @@ -24,7 +24,6 @@ import org.eclipse.core.runtime.CoreException; /** * @author Doug Schaefer - * */ public abstract class PDOMNamedNode extends PDOMNode { /** @@ -104,7 +103,6 @@ public abstract class PDOMNamedNode extends PDOMNode { fName= nameCharArray; } - @Override public void delete(PDOMLinkage linkage) throws CoreException { final Database db = getDB(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java index 19b7e2b5c5a..807886f84a1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2010, 2013 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: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -23,7 +24,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; */ public interface IPDOMCPPEnumType extends ICPPEnumeration, IPDOMBinding, IIndexType { /** - * Return the scope name, for use in {@link IScope#getScopeName()} + * Returns the scope name, for use in {@link IScope#getScopeName()} */ IIndexName getScopeName(); @@ -33,5 +34,5 @@ public interface IPDOMCPPEnumType extends ICPPEnumeration, IPDOMBinding, IIndexT /** * Called by the scope to access the enumerators. */ - void loadEnumerators(CharArrayMap map); + void loadEnumerators(CharArrayMap map); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java new file mode 100644 index 00000000000..ff2f767d2e1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2013 Google, 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; + +/** + * Interface for a c++ enumerator stored in the index. + */ +public interface IPDOMCPPEnumerator extends IEnumerator, IPDOMBinding { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java index 25f34538a52..f892e243acd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java @@ -65,7 +65,7 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { @Override public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) { try { - CharArrayMap map= getBindingMap(fBinding); + CharArrayMap map= getBindingMap(fBinding); return map.get(name.toCharArray()); } catch (CoreException e) { CCorePlugin.log(e); @@ -81,7 +81,7 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { @Override public IBinding[] getBindings(ScopeLookupData lookup) { try { - CharArrayMap map= getBindingMap(fBinding); + CharArrayMap map= getBindingMap(fBinding); if (lookup.isPrefixLookup()) { final List result= new ArrayList(); final char[] nc= lookup.getLookupKey(); @@ -135,36 +135,36 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { return fBinding.hashCode(); } - private static CharArrayMap getBindingMap(IPDOMCPPEnumType enumeration) throws CoreException { + private static CharArrayMap getBindingMap(IPDOMCPPEnumType enumeration) throws CoreException { final Long key= enumeration.getRecord() + PDOMCPPLinkage.CACHE_MEMBERS; final PDOM pdom = enumeration.getPDOM(); @SuppressWarnings("unchecked") - Reference> cached= (Reference>) pdom.getCachedResult(key); - CharArrayMap map= cached == null ? null : cached.get(); + Reference> cached= (Reference>) pdom.getCachedResult(key); + CharArrayMap map= cached == null ? null : cached.get(); if (map == null) { // there is no cache, build it: - map= new CharArrayMap(); + map= new CharArrayMap(); enumeration.loadEnumerators(map); pdom.putCachedResult(key, new SoftReference>(map)); } return map; } - public static void updateCache(PDOMCPPEnumeration enumType, PDOMCPPEnumerator enumItem) { + public static void updateCache(IPDOMCPPEnumType enumType, IPDOMCPPEnumerator enumItem) { final Long key= enumType.getRecord() + PDOMCPPLinkage.CACHE_MEMBERS; final PDOM pdom = enumType.getPDOM(); @SuppressWarnings("unchecked") - Reference> cached= (Reference>) pdom.getCachedResult(key); - CharArrayMap map= cached == null ? null : cached.get(); + Reference> cached= (Reference>) pdom.getCachedResult(key); + CharArrayMap map= cached == null ? null : cached.get(); if (map != null) { map.put(enumType.getNameCharArray(), enumItem); } } - public static IEnumerator[] getEnumerators(PDOMCPPEnumeration enumType) { + public static IEnumerator[] getEnumerators(IPDOMCPPEnumType enumType) { try { - CharArrayMap map = getBindingMap(enumType); + CharArrayMap map = getBindingMap(enumType); List result= new ArrayList(); for (IEnumerator value : map.values()) { if (IndexFilter.ALL_DECLARED.acceptBinding(value)) { @@ -179,10 +179,10 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { return new IEnumerator[0]; } - public static void acceptViaCache(PDOMCPPEnumeration enumType, IPDOMVisitor visitor) { + public static void acceptViaCache(IPDOMCPPEnumType enumType, IPDOMVisitor visitor) { try { - CharArrayMap map = getBindingMap(enumType); - for (PDOMCPPEnumerator enumItem : map.values()) { + CharArrayMap map = getBindingMap(enumType); + for (IPDOMCPPEnumerator enumItem : map.values()) { visitor.visit(enumItem); visitor.leave(enumItem); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java index 33cc375ef8f..1c8c7b53f6a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java @@ -114,7 +114,7 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD if (node instanceof PDOMCPPEnumerator) { PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); list.addMember(node); - PDOMCPPEnumScope.updateCache(this, (PDOMCPPEnumerator) node); + PDOMCPPEnumScope.updateCache(this, (IPDOMCPPEnumerator) node); } } @@ -218,14 +218,14 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD } @Override - public void loadEnumerators(final CharArrayMap map) { + public void loadEnumerators(final CharArrayMap map) { try { PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); list.accept(new IPDOMVisitor() { @Override public boolean visit(IPDOMNode node) throws CoreException { - if (node instanceof PDOMCPPEnumerator) { - final PDOMCPPEnumerator item = (PDOMCPPEnumerator) node; + if (node instanceof IPDOMCPPEnumerator) { + final IPDOMCPPEnumerator item = (IPDOMCPPEnumerator) node; map.put(item.getNameCharArray(), item); } return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java new file mode 100644 index 00000000000..e4e9d451bc0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2013 Google, 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.parser.util.CharArrayMap; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * Enumeration specialization in the index. + */ +class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization + implements IPDOMCPPEnumType, IPDOMMemberOwner, ICPPEnumerationSpecialization { + private static final int OFFSET_ENUMERATOR_LIST = PDOMCPPSpecialization.RECORD_SIZE; + private static final int OFFSET_MIN_VALUE= OFFSET_ENUMERATOR_LIST + Database.PTR_SIZE; + private static final int OFFSET_MAX_VALUE= OFFSET_MIN_VALUE + 8; + private static final int OFFSET_FIXED_TYPE = OFFSET_MAX_VALUE + 8; + private static final int OFFSET_FLAGS = OFFSET_FIXED_TYPE + Database.TYPE_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = OFFSET_FLAGS + 1; + + private Long fMinValue; // No need for volatile, all fields of Long are final. + private Long fMaxValue; // No need for volatile, all fields of Long are final. + private volatile IType fFixedType= ProblemBinding.NOT_INITIALIZED; + private PDOMCPPEnumScope fScope; // No need for volatile, all fields of PDOMCPPEnumScope are final. + + public PDOMCPPEnumerationSpecialization(PDOMLinkage linkage, PDOMNode parent, + ICPPEnumeration enumeration, PDOMBinding specialized) throws CoreException { + super(linkage, parent, (ICPPSpecialization) enumeration, specialized); + storeProperties(enumeration); + } + + public PDOMCPPEnumerationSpecialization(PDOMLinkage linkage, long record) { + super(linkage, record); + } + + @Override + public ICPPEnumeration getSpecializedBinding() { + return (ICPPEnumeration) super.getSpecializedBinding(); + } + + @Override + public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { + storeProperties((ICPPEnumeration) newBinding); + } + + private void storeProperties(ICPPEnumeration enumeration) throws CoreException { + final Database db= getDB(); + db.putByte(record + OFFSET_FLAGS, enumeration.isScoped() ? (byte) 1 : (byte) 0); + + getLinkage().storeType(record + OFFSET_FIXED_TYPE, enumeration.getFixedType()); + + if (enumeration instanceof ICPPInternalBinding) { + if (((ICPPInternalBinding) enumeration).getDefinition() != null) { + final long minValue = enumeration.getMinValue(); + final long maxValue = enumeration.getMaxValue(); + db.putLong(record + OFFSET_MIN_VALUE, minValue); + db.putLong(record + OFFSET_MAX_VALUE, maxValue); + fMinValue= minValue; + fMaxValue= maxValue; + } + } + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_ENUMERATION_SPECIALIZATION; + } + + @Override + public IEnumerator[] getEnumerators() { + return PDOMCPPEnumScope.getEnumerators(this); + } + + @Override + public void accept(IPDOMVisitor visitor) throws CoreException { + PDOMCPPEnumScope.acceptViaCache(this, visitor); + } + + @Override + public void addChild(PDOMNode node) throws CoreException { + if (node instanceof IPDOMCPPEnumerator) { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); + list.addMember(node); + PDOMCPPEnumScope.updateCache(this, (IPDOMCPPEnumerator) node); + } + } + + @Override + public boolean mayHaveChildren() { + return true; + } + + @Override + public boolean isSameType(IType type) { + if (type instanceof ITypedef) { + return type.isSameType(this); + } + + if (type instanceof PDOMNode) { + PDOMNode node= (PDOMNode) type; + if (node.getPDOM() == getPDOM()) { + return node.getRecord() == getRecord(); + } + } + + if (type instanceof IEnumeration) { + IEnumeration etype= (IEnumeration) type; + char[] nchars = etype.getNameCharArray(); + if (nchars.length == 0) { + nchars= ASTTypeUtil.createNameForAnonymous(etype); + } + if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) + return false; + + return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); + } + return false; + } + + @Override + public long getMinValue() { + if (fMinValue != null) { + return fMinValue.longValue(); + } + long minValue= 0; + try { + minValue= getDB().getLong(record + OFFSET_MIN_VALUE); + } catch (CoreException e) { + } + fMinValue= minValue; + return minValue; + } + + @Override + public long getMaxValue() { + if (fMaxValue != null) { + return fMaxValue.longValue(); + } + long maxValue= 0; + try { + maxValue= getDB().getLong(record + OFFSET_MAX_VALUE); + } catch (CoreException e) { + } + fMaxValue= maxValue; + return maxValue; + } + + @Override + public Object clone() { + throw new IllegalArgumentException("Enums must not be cloned"); //$NON-NLS-1$ + } + + @Override + public boolean isScoped() { + try { + return getDB().getByte(record + OFFSET_FLAGS) != 0; + } catch (CoreException e) { + return false; + } + } + + @Override + public IType getFixedType() { + if (fFixedType == ProblemBinding.NOT_INITIALIZED) { + fFixedType= loadFixedType(); + } + return fFixedType; + } + + private IType loadFixedType() { + try { + return getLinkage().loadType(record + OFFSET_FIXED_TYPE); + } catch (CoreException e) { + CCorePlugin.log(e); + return null; + } + } + + @Override + public ICPPScope asScope() { + if (fScope == null) { + fScope= new PDOMCPPEnumScope(this); + } + return fScope; + } + + @Override + public void loadEnumerators(final CharArrayMap map) { + try { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); + list.accept(new IPDOMVisitor() { + @Override + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof IPDOMCPPEnumerator) { + final IPDOMCPPEnumerator item = (IPDOMCPPEnumerator) node; + map.put(item.getNameCharArray(), item); + } + return true; + } + @Override + public void leave(IPDOMNode node) {} + }); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + + @Override + public IEnumerator specializeEnumerator(IEnumerator enumerator) { + // The specialized enumerators are already computed, just need to look up the right one. + IEnumerator[] unspecializedEnumerators = getSpecializedBinding().getEnumerators(); + for (int i = 0; i < unspecializedEnumerators.length; ++i) { + if (enumerator.equals(unspecializedEnumerators[i])) { + IEnumerator[] enumerators = getEnumerators(); + return i < enumerators.length ? enumerators[i] : enumerator; + } + } + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java index b449b88b6ab..3e28624a9cd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java @@ -1,13 +1,14 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 QNX Software Systems and others. + * Copyright (c) 2006, 2013 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: - * Doug Schaefer (QNX) - Initial API and implementation - * Markus Schorn (Wind River Systems) + * Doug Schaefer (QNX) - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -19,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -26,11 +28,11 @@ import org.eclipse.core.runtime.CoreException; /** * Binding for a c++ enumerator in the index. */ -class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator { +class PDOMCPPEnumerator extends PDOMCPPBinding implements IPDOMCPPEnumerator { private static final int VALUE= PDOMCPPBinding.RECORD_SIZE; @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = VALUE + 4; + protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE; public PDOMCPPEnumerator(PDOMLinkage linkage, PDOMNode parent, IEnumerator enumerator) throws CoreException { @@ -55,11 +57,10 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator { private void storeValue(IEnumerator enumerator) throws CoreException { IValue value= enumerator.getValue(); if (value != null) { - Long val= value.numericalValue(); - getDB().putInt(record + VALUE, val == null ? -1 : val.intValue()); + getLinkage().storeValue(record + VALUE, value); } } - + @Override public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { if (newBinding instanceof IEnumerator) @@ -77,8 +78,7 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator { @Override public IValue getValue() { try { - int val= getDB().getInt(record + VALUE); - return Value.create(val); + return getLinkage().loadValue(record + VALUE); } catch (CoreException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java new file mode 100644 index 00000000000..2044ee6b535 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2013 Google, 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * Binding for a specialization of an enumerator in the index. + */ +class PDOMCPPEnumeratorSpecialization extends PDOMCPPSpecialization implements IPDOMCPPEnumerator { + private static final int VALUE= PDOMCPPSpecialization.RECORD_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE; + + public PDOMCPPEnumeratorSpecialization(PDOMLinkage linkage, PDOMNode parent, + IEnumerator enumerator, PDOMBinding specialized) throws CoreException { + super(linkage, parent, (ICPPSpecialization) enumerator, specialized); + storeValue(enumerator); + } + + public PDOMCPPEnumeratorSpecialization(PDOMLinkage linkage, long record) { + super(linkage, record); + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_ENUMERATOR_SPECIALIZATION; + } + + private void storeValue(IEnumerator enumerator) throws CoreException { + IValue value= enumerator.getValue(); + if (value != null) { + getLinkage().storeValue(record + VALUE, value); + } + } + + @Override + public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { + if (newBinding instanceof IEnumerator) + storeValue((IEnumerator) newBinding); + } + + @Override + public IType getType() { + IIndexFragmentBinding owner = getOwner(); + if (owner instanceof IType) + return (IType) owner; + return null; + } + + @Override + public IValue getValue() { + try { + return getLinkage().loadValue(record + VALUE); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return Value.UNKNOWN; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 80eeb687946..656dfb02abd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 QNX Software Systems and others. + * Copyright (c) 2005, 2013 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 @@ -534,6 +534,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { result= new PDOMCPPTypedefSpecialization(this, parent, (ITypedef) special, orig); } else if (special instanceof ICPPUsingDeclaration) { result= new PDOMCPPUsingDeclarationSpecialization(this, parent, (ICPPUsingDeclaration) special, orig); + } else if (special instanceof ICPPEnumeration) { + result= new PDOMCPPEnumerationSpecialization(this, parent, (ICPPEnumeration) special, orig); + } else if (special instanceof IEnumerator) { + result= new PDOMCPPEnumeratorSpecialization(this, parent, (IEnumerator) special, orig); } return result; @@ -893,6 +897,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return new PDOMCPPUsingDeclarationSpecialization(this, record); case CPP_TEMPLATE_ALIAS: return new PDOMCPPAliasTemplate(this, record); + case CPP_ENUMERATION_SPECIALIZATION: + return new PDOMCPPEnumerationSpecialization(this, record); + case CPP_ENUMERATOR_SPECIALIZATION: + return new PDOMCPPEnumeratorSpecialization(this, record); } assert false : "nodeid= " + nodeType; //$NON-NLS-1$ return null; diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties index 05f9ed7440a..46e1547c2f1 100644 --- a/core/org.eclipse.cdt.core/plugin.properties +++ b/core/org.eclipse.cdt.core/plugin.properties @@ -132,4 +132,5 @@ CProjectStorageType.separatefile.name = Xml Storage (Separate Files) scannerInfoProvider2.name = Scanner Info Provider efsExtensionProvider.name = EFSExtensionProvider refreshExclusionFactory.name = Refresh Exclusion Factory -uncPathConverter.name = UNC Path Converter \ No newline at end of file +uncPathConverter.name = UNC Path Converter +ScannerInfoExtensionLanguageSettingsProvider.name=Contributed ScannerInfo Entries diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml index 7cd1e698f09..bb1125caabd 100644 --- a/core/org.eclipse.cdt.core/plugin.xml +++ b/core/org.eclipse.cdt.core/plugin.xml @@ -2,7 +2,7 @@ - + @@ -268,7 +268,7 @@ - + @@ -806,5 +806,13 @@ factoryClass="org.eclipse.cdt.internal.core.resources.ResourceExclusionFactory"> + + + + diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java index 90b06448c56..c46cce79acc 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CConventions.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2001, 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 - * http://www.eclipse.org/legal/epl-v10.html + * Copyright (c) 2001, 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 + * http://www.eclipse.org/legal/epl-v10.html * - * Contributors: + * Contributors: * Rational Software - initial implementation * Sergey Prigogin (Google) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/EFSFileStorage.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/EFSFileStorage.java index 9b497dac7dc..73f696e7d3d 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/EFSFileStorage.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/EFSFileStorage.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 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) 2008, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.resources; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java index e0b770d87c9..bd878b12cd7 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Cygwin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2012 Andrew Gvozdev and others. + * Copyright (c) 2012, 2013 Andrew Gvozdev 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 @@ -11,24 +11,74 @@ package org.eclipse.cdt.internal.core; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.util.Collections; +import java.util.Map; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.utils.PathUtil; +import org.eclipse.cdt.utils.WindowsRegistry; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; /** * A collection of cygwin-related utilities. */ public class Cygwin { + public static final String ENV_CYGWIN_HOME = "CYGWIN_HOME"; //$NON-NLS-1$ + private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ - private static IPath findCygpathLocation(String envPath) { - return PathUtil.findProgramLocation("cygpath", envPath); //$NON-NLS-1$ + private static final String CYGPATH = "cygpath"; //$NON-NLS-1$ + private static final String DEFAULT_ROOT = "C:\\cygwin"; //$NON-NLS-1$ + private static final String CYGWIN_DLL = "cygwin1.dll"; //$NON-NLS-1$ + private static final String REGISTRY_KEY_SETUP = "SOFTWARE\\Cygwin\\setup"; //$NON-NLS-1$ + private static final String REGISTRY_KEY_SETUP_WIN64 = "SOFTWARE\\Wow6432Node\\Cygwin\\setup"; //$NON-NLS-1$ + // note that in Cygwin 1.7 the mount point storage has been moved out of the registry + private static final String REGISTRY_KEY_MOUNTS = "SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\"; //$NON-NLS-1$ + private static final String PATH_NAME = "native"; //$NON-NLS-1$ + private static final String ROOTPATTERN = "/"; //$NON-NLS-1$ + private static final char SLASH = '/'; + private static final char BACKSLASH = '\\'; + + private static final boolean isWindowsPlatform = Platform.getOS().equals(Platform.OS_WIN32); + + private static String envPathValueCached = null; + private static String envCygwinHomeValueCached = null; + private static String cygwinLocation = null; + private static boolean isCygwinLocationCached = false; + + private final static Map cygpathLocationCache = Collections.synchronizedMap(new LRUCache(1,20)); + private final static Map translatedPathsCache = Collections.synchronizedMap(new LRUCache(10,500)); + + /** + * Find location of "cygpath" utility on the file system. + */ + private static String findCygpathLocation(String envPath) { + if (envPath == null) { + // $PATH from user preferences + IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_PATH, null, true); + if (varPath != null) { + envPath = varPath.getValue(); + } + } + + String cygpathLocation = cygpathLocationCache.get(envPath); + if (cygpathLocation == null) { + IPath loc = PathUtil.findProgramLocation(CYGPATH, envPath); + cygpathLocation = loc != null ? loc.toOSString() : null; + cygpathLocationCache.put(envPath, cygpathLocation); + } + return cygpathLocation; } /** * Check if cygwin path conversion utilities are available in the path. + * Tells whether cygwin is installed in the path. * * @param envPath - list of directories to search for cygwin utilities separated * by path separator (format of environment variable $PATH) @@ -36,22 +86,60 @@ public class Cygwin { * @return {@code true} if cygwin is available, {@code false} otherwise. */ public static boolean isAvailable(String envPath) { - return Platform.getOS().equals(Platform.OS_WIN32) && findCygpathLocation(envPath) != null; + return isWindowsPlatform && findCygpathLocation(envPath) != null; } /** * Check if cygwin path conversion utilities are available in $PATH. + * Tells whether cygwin is installed in the path. * * @return {@code true} if cygwin is available, {@code false} otherwise. */ public static boolean isAvailable() { - return Platform.getOS().equals(Platform.OS_WIN32) && findCygpathLocation(null) != null; + return isWindowsPlatform && findCygpathLocation(null) != null; + } + + /** + * Run program (assuming cygpath) and return the translated path which is the first line of output. + */ + private static String runCygpath(String[] args) throws IOException { + String command = getCommand(args); + String translatedPath = translatedPathsCache.get(command); + if (translatedPath == null) { + Process cygpathProcess = Runtime.getRuntime().exec(args); + BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpathProcess.getInputStream())); + String firstLine = null; + try { + firstLine = stdout.readLine(); + } finally { + stdout.close(); + } + if (firstLine == null) { + throw new IOException("Unable read output from command=[" + command + "]"); //$NON-NLS-1$ //$NON-NLS-2$ + } + translatedPath = firstLine.trim(); + translatedPathsCache.put(command, translatedPath); + } + + return translatedPath; + } + + /** + * Construct a command from arguments array. + */ + private static String getCommand(String[] args) { + String command = ""; //$NON-NLS-1$ + for (String arg : args) { + command = command + arg + ' '; + } + return command.trim(); } /** * Conversion from Cygwin path to Windows path. + * Note that there is no need to cache results, they are already cached internally. * - * @param cygwinPath - Cygwin path. + * @param cygwinPath - cygwin path. * @param envPath - list of directories to search for cygwin utilities separated * by path separator (format of environment variable $PATH). * @return Windows style converted path. Note that that also converts cygwin links to their targets. @@ -63,31 +151,24 @@ public class Cygwin { if (cygwinPath == null || cygwinPath.trim().length() == 0) return cygwinPath; - if (!Platform.getOS().equals(Platform.OS_WIN32)) { - // Don't run this on non-windows platforms + if (!isWindowsPlatform) { throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$ } - IPath cygpathLocation = findCygpathLocation(envPath); + String cygpathLocation = findCygpathLocation(envPath); if (cygpathLocation == null) { - throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path."); //$NON-NLS-1$ + throw new UnsupportedOperationException(CYGPATH + " is not in the system search path."); //$NON-NLS-1$ } - String[] args = {cygpathLocation.toOSString(), "-w", cygwinPath}; //$NON-NLS-1$ - Process cygpathProcess = Runtime.getRuntime().exec(args); - BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpathProcess.getInputStream())); - - String windowsPath = stdout.readLine(); - if (windowsPath == null) { - throw new IOException("Unexpected output from Cygwin utility cygpath."); //$NON-NLS-1$ - } - return windowsPath.trim(); + String windowsPath = runCygpath(new String[] {cygpathLocation, "-w", cygwinPath}); //$NON-NLS-1$ + return windowsPath; } /** * Conversion from Cygwin path to Windows path. + * Note that there is no need to cache results, they are already cached internally. * - * @param cygwinPath - Cygwin path. + * @param cygwinPath - cygwin path. * @return Windows style converted path. Note that that also converts cygwin links to their targets. * * @throws UnsupportedOperationException if Cygwin is unavailable. @@ -99,6 +180,7 @@ public class Cygwin { /** * Conversion from Windows path to Cygwin path. + * Note that there is no need to cache results, they are already cached internally. * * @param windowsPath - Windows path. * @param envPath - list of directories to search for cygwin utilities (value of environment variable $PATH). @@ -111,28 +193,22 @@ public class Cygwin { if (windowsPath == null || windowsPath.trim().length() == 0) return windowsPath; - if (!Platform.getOS().equals(Platform.OS_WIN32)) { - // Don't run this on non-windows platforms + if (!isWindowsPlatform) { throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$ } - IPath cygpathLocation = findCygpathLocation(envPath); + + String cygpathLocation = findCygpathLocation(envPath); if (cygpathLocation == null) { - throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path."); //$NON-NLS-1$ + throw new UnsupportedOperationException(CYGPATH + " is not in the system search path."); //$NON-NLS-1$ } - String[] args = {cygpathLocation.toOSString(), "-u", windowsPath}; //$NON-NLS-1$ - Process cygpath = Runtime.getRuntime().exec(args); - BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpath.getInputStream())); - - String cygwinPath = stdout.readLine(); - if (cygwinPath == null) { - throw new IOException("Unexpected output from Cygwin utility cygpath."); //$NON-NLS-1$ - } - return cygwinPath.trim(); + String cygwinPath = runCygpath(new String[] {cygpathLocation, "-u", windowsPath}); //$NON-NLS-1$ + return cygwinPath; } /** * Conversion from Windows path to Cygwin path. + * Note that there is no need to cache results, they are already cached internally. * * @param windowsPath - Windows path. * @return Cygwin style converted path. @@ -143,4 +219,114 @@ public class Cygwin { public static String windowsToCygwinPath(String windowsPath) throws IOException, UnsupportedOperationException { return windowsToCygwinPath(windowsPath, null); } + + /** + * Find location where Cygwin is installed. A number of locations is being checked, + * such as environment variable $CYGWIN_HOME, $PATH, Windows registry et al. + *

+ * If you use this do not cache results to ensure user preferences are accounted for. + * Please rely on internal caching. + * + * @return Location of Cygwin root folder "/" on file system in Windows format. + */ + public static String getCygwinHome() { + if (!isWindowsPlatform) { + return null; + } + + IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_PATH, null, true); + String envPathValue = varPath != null ? varPath.getValue() : null; + IEnvironmentVariable varCygwinHome = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_CYGWIN_HOME, null, true); + String envCygwinHomeValue = varCygwinHome != null ? varCygwinHome.getValue() : null; + + // isCygwinLocationCached is used to figure fact of caching when all cached objects are null + if (isCygwinLocationCached && CDataUtil.objectsEqual(envPathValue, envPathValueCached) && CDataUtil.objectsEqual(envCygwinHomeValue, envCygwinHomeValueCached)) { + return cygwinLocation; + } + + cygwinLocation = findCygwinRoot(envPathValue, envCygwinHomeValue); + + envPathValueCached = envPathValue; + envCygwinHomeValueCached = envCygwinHomeValue; + isCygwinLocationCached = true; + + return cygwinLocation; + } + + /** + * Reads required value from registry. Looks in both + * HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE + * + * @param key Registry key + * @param name Registry value to read + * @return corresponding string value or null if nothing found + */ + private static String readValueFromRegistry(String key, String name) { + WindowsRegistry registry = WindowsRegistry.getRegistry(); + if (registry != null) { + String s = registry.getCurrentUserValue(key, name); + if(s == null) { + s = registry.getLocalMachineValue(key, name); + } + + if (s != null) { + return (s.replace(BACKSLASH, SLASH)); + } + } + return null; + } + + /** + * @return The absolute path to cygwin's root or null if not found + */ + private static String findCygwinRoot(String envPathValue, String envCygwinHomeValue) { + String rootValue = null; + + // Check $CYGWIN_HOME + if (envCygwinHomeValue != null && !envCygwinHomeValue.isEmpty()) { + IPath location = new Path(envCygwinHomeValue + "/bin/" + CYGWIN_DLL); //$NON-NLS-1$ + if (location.toFile().exists()) { + // get rootValue from "rootValue\bin\cygwin1.dll" + rootValue = location.removeLastSegments(2).toOSString(); + } + } + + // Look in PATH values. Look for cygwin1.dll + if(rootValue == null) { + IPath location = PathUtil.findProgramLocation(CYGWIN_DLL, envPathValue); + if (location != null) { + // get rootValue from "rootValue\bin\cygwin1.dll" + rootValue = location.removeLastSegments(2).toOSString(); + } + } + + // Try to find the root dir in SOFTWARE\Cygwin\setup + if(rootValue == null) { + rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP, "rootdir"); //$NON-NLS-1$ + } + + // Try to find the root dir in SOFTWARE\Wow6432Node\Cygwin\setup + if(rootValue == null) { + rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP_WIN64, "rootdir"); //$NON-NLS-1$ + } + + // Try to find the root dir in SOFTWARE\Cygnus Solutions + if (rootValue == null) { + rootValue = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ROOTPATTERN, PATH_NAME); + } + + // Try the default Cygwin install dir + if(rootValue == null) { + File file = new File(DEFAULT_ROOT); + if (file.exists() && file.isDirectory()) + rootValue = DEFAULT_ROOT; + } + + if(rootValue != null) { + rootValue = rootValue.replace(BACKSLASH, SLASH); + } + + return rootValue; + } + } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/LRUCache.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/LRUCache.java new file mode 100644 index 00000000000..817613c6406 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/LRUCache.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2013 Andrew Gvozdev 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: + * Andrew Gvozdev - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core; + +import java.util.LinkedHashMap; +import java.util.Map.Entry; + +/** + * A simple cache with limited number of items in the cache. LRUCache discards the Least Recently Used items first. + * Based on {@link LinkedHashMap}. Note that {@link LinkedHashMap} has built-in facility to support cache like that + * which is described in its JavaDoc. + */ +public class LRUCache extends LinkedHashMap { + private int fLimit; + + /** + * Constructs an empty LRUCache with the specified limit on the number of items in the cache. + * + * @param limit - the maximum number of items to keep in the cache. + */ + public LRUCache(int limit) { + super(limit, 0.75f, true); + fLimit= limit; + } + + /** + * Constructs an empty LRUCache with the specified initial capacity and limit on the number of items in the cache. + * + * @param initialCapacity - initial capacity. + * @param limit - the maximum number of items to keep in the cache. + */ + public LRUCache(int initialCapacity, int limit) { + super(initialCapacity, 0.75f, true); + fLimit= limit; + } + + @Override + protected boolean removeEldestEntry(Entry eldest) { + return size() >= fLimit; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java index 12d2f9b2674..1f73055e719 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/CommandLineUtil.java @@ -1,13 +1,13 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 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 + * Copyright (c) 2008, 2009 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: - * QNX Software Systems - initial API and implementation - * Markus Schorn (Wind River Systems) + * Contributors: + * QNX Software Systems - initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.utils; diff --git a/core/org.eclipse.cdt.ui.tests/pom.xml b/core/org.eclipse.cdt.ui.tests/pom.xml index 626db878fe4..e6222b56a22 100644 --- a/core/org.eclipse.cdt.ui.tests/pom.xml +++ b/core/org.eclipse.cdt.ui.tests/pom.xml @@ -32,7 +32,7 @@ ${tycho-version} true - -Xms256m -Xmx512m -XX:MaxPermSize=256M + -ea -Xms256m -Xmx512m -XX:MaxPermSize=256M **/AutomatedSuite.* diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java index 9a1efb93186..29c78c5e609 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java @@ -1,13 +1,14 @@ /******************************************************************************* - * 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, 2013 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 - * Markus Schorn (Wind River Systems) + * Contributors: + * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.selection; @@ -75,7 +76,6 @@ import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction; * @author dsteffle */ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { - private static final String INDEX_FILE_ID = "2946365241"; //$NON-NLS-1$ static NullProgressMonitor monitor; static IWorkspace workspace; @@ -1205,4 +1205,23 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { assertEquals(offsetV, ((ASTNode) decl).getOffset()); } + // template + // struct A { + // struct S { + // void foo(); + // }; + // void test() { + // S s; + // s.foo(); + // } + // }; + public void testBug399142() throws Exception { + String code = getAboveComment(); + IFile file = importFile("testBug399142.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("s.foo()") + 2; + IASTNode decl = testF3(file, offset); + assertTrue(decl instanceof IASTName); + } + } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java index 55dec936572..be1b165c749 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CSelectionTestsNoIndexer.java @@ -1,13 +1,13 @@ /******************************************************************************* - * 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 - * Markus Schorn (Wind River Systems) + * Contributors: + * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.selection; diff --git a/core/org.eclipse.cdt.ui/.settings/.api_filters b/core/org.eclipse.cdt.ui/.settings/.api_filters index 6d77fc00926..55723afdab0 100644 --- a/core/org.eclipse.cdt.ui/.settings/.api_filters +++ b/core/org.eclipse.cdt.ui/.settings/.api_filters @@ -4,7 +4,7 @@ - + diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index 1d46a1d536b..f06ce79399a 100644 --- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true -Bundle-Version: 5.5.0.qualifier +Bundle-Version: 5.6.0.qualifier Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 97111894d01..3ad091cf1eb 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -648,4 +648,6 @@ RefreshExclusionContributorExtensionPoint = Refresh Exclusion Contributor newProjectWizard.name = C/C++ Project (prototype) projectTypePages = Project Type Pages +semanticHighlightingExtensionPoint = Semantic Highlighting Extension Point + UserSettingEntries.name = CDT User Setting Entries diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 830d60d2f2f..f2135dbd9a1 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -29,6 +29,7 @@ + diff --git a/core/org.eclipse.cdt.ui/pom.xml b/core/org.eclipse.cdt.ui/pom.xml index f50cfd9479d..b3981b4c87a 100644 --- a/core/org.eclipse.cdt.ui/pom.xml +++ b/core/org.eclipse.cdt.ui/pom.xml @@ -11,7 +11,7 @@ ../../pom.xml - 5.5.0-SNAPSHOT + 5.6.0-SNAPSHOT org.eclipse.cdt.ui eclipse-plugin diff --git a/core/org.eclipse.cdt.ui/schema/semanticHighlighting.exsd b/core/org.eclipse.cdt.ui/schema/semanticHighlighting.exsd new file mode 100644 index 00000000000..f5960fd03c8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/schema/semanticHighlighting.exsd @@ -0,0 +1,245 @@ + + + + + + + + + This extension point allows extensions to contribute to the semantic highlighting. +<p> +Extensions specify the priority of the highlighting, which determines the order in which the highlighting is invoked. +</p> +<p> +This extension point supports the <code>enablement</code> tag. Properties to test on are: +<dl> +<li>projectNatures: type Collection; all project natures of the current project</li> +<li>languageId: type String; the result if ILanguage.getId on the token's ITranslationUnit</li> +</dl> +</p> +<p> +Contributed highlightings will be visible in the Code tree of the 'C/C++ - Editor - Syntax Colouring' preference page. +</p> + + + + + + + + + + + + + + + + + + + a fully qualified identifier of the target extension point + + + + + + + an optional identifier of the extension instance + + + + + + + an optional name of the extension instance + + + + + + + + + + + + + + + + + + a unique identifier for the Quick Fix processor + + + + + + + a localized name of the Quick Fix processor + + + + + + + + + + The name of the class that implements this Semantic Highlighting. The +class must be public and implement +<samp>org.eclipse.cdt.ui.text.ISemanticHighlighter</samp> +with a public 0-argument constructor. + + + + + + + + + + The priority determines the order in which highlightings are given the opportunity to highlight a token. Lower values are more important. + +The priorities of the built-in highlightings are available in org.eclipse.cdt.internal.ui.editor.SemanticHighlightings.loadBuiltInSemanticHighlightings. + + + + + + + A key to uniquely identify the highlighting's settings in the preference store. + + + + + + + The name that is displayed for the highlighter in the Preferences window. + + + + + + + + + + The default text color of the contributed highlighting. The value must be the integer RGB values (0-255) separated by commas. E.g., "127,0,85". Defaults to "0,0,0" (black). + + + + + + + false by default + + + + + + + false by default + + + + + + + false by default + + + + + + + false by default + + + + + + + false by default + + + + + + + + + + + + 8.2 + + + + + + + + + The following is an example of a Semantic Highligher contribution: + +<p> +<pre> +<extension + point="org.eclipse.cdt.ui.semanticHighlighting" + name="%extensionName" + id="com.example.ui.semanticHighlightings"> + <semanticHighlighting + id="com.example.ui.keywordHighlighting" + priority="5" + class="com.example.internal.ui.ExampleHighlighting" + preferenceKey="example-keywords" + displayName="%exampleHighlighting.displayName" + defaultTextColor="127,0,85" + defaultBold="true" + defaultEnabled="true"> + <enablement> + <with variable="projectNatures"> + <iterate operator="or"> + <equals value="org.eclipse.cdt.core.ccnature"/> + </iterate> + </with> + <with variable="languageId"> + <or> + <equals value="org.eclipse.cdt.core.g++"/> + <equals value="org.eclipse.cdt.core.gcc"/> + </or> + </with> + </enablement> + </semanticHighlighting> +</extension> +</pre> +</p> + + + + + + + + + The contributed class must implement <code>org.eclipse.cdt.ui.text.ISemanticHighlighter</code> + + + + + + + + + + Copyright (c) 2013 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 + + + + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.java index 04425a71de7..ffa1711cdfa 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/CorextMessages.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 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, 2008 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 Rational Software - Initial API and implementation + * Contributors: + * IBM Rational Software - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.corext; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java index 188c3aaa7b1..8df7383de33 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/codemanipulation/AddIncludesOperation.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 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) 2000, 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: + * Contributors: * IBM Corporation - initial API and implementation * QNX Software Systems * Sergey Prigogin (Google) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java index e506fbfdd7d..43c3420facf 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2005, 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) 2005, 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: + * Contributors: * IBM Corporation - initial API and implementation * QNX Software System * Markus Schorn (Wind River Systems) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java index b68ebfdb6cf..65fdc01a89c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/ActionMessages.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2001, 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 + * Copyright (c) 2001, 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: + * Contributors: * Rational Software - initial implementation * Sergey Prigogin (Google) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ContributedSemanticHighlighting.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ContributedSemanticHighlighting.java new file mode 100644 index 00000000000..ada16913806 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ContributedSemanticHighlighting.java @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2013 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 + */ + +package org.eclipse.cdt.internal.ui.editor; + +import java.util.Arrays; + +import org.eclipse.core.expressions.EvaluationContext; +import org.eclipse.core.expressions.EvaluationResult; +import org.eclipse.core.expressions.Expression; +import org.eclipse.core.expressions.ExpressionConverter; +import org.eclipse.core.expressions.ExpressionTagNames; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.jface.resource.DataFormatException; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.swt.graphics.RGB; + +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.text.ISemanticHighlighter; +import org.eclipse.cdt.ui.text.ISemanticToken; + +public class ContributedSemanticHighlighting extends SemanticHighlighting { + + /** + * The configuration element needs to be cached until the class is instantiated. Instantiation is deferred + * to avoid loading the contributing plugin when the highlighter is not actually needed. + */ + private IConfigurationElement configurationElement; + private Boolean fStatus = null; + private ISemanticHighlighter semanticHighlighter; + + private final Expression enablementExpression; + + private final int priority; + private final String id; + private final String preferenceKey; + private final String displayName; + + private final RGB defaultTextColor; + private final boolean defaultBold; + private final boolean defaultItalic; + private final boolean defaultStrikethrough; + private final boolean defaultUnderline; + private final boolean defaultEnabled; + + private static final String Attr_Class = "class"; //$NON-NLS-1$ + private static final String Attr_Priority = "priority"; //$NON-NLS-1$ + + private static final String Attr_PrefKey = "preferenceKey"; //$NON-NLS-1$ + private static final String Attr_DisplayName = "displayName"; //$NON-NLS-1$ + private static final String Attr_DefaultTextColor = "defaultTextColor"; //$NON-NLS-1$ + private static final String Attr_DefaultBold = "defaultBold"; //$NON-NLS-1$ + + private static final String Attr_DefaultItalic = "defaultItalic"; //$NON-NLS-1$ + private static final String Attr_DefaultStrikethrough = "defaultStrikethrough"; //$NON-NLS-1$ + private static final String Attr_DefaultUnderline = "defaultUnderline"; //$NON-NLS-1$ + private static final String Attr_DefaultEnabled = "defaultEnabled"; //$NON-NLS-1$ + + private static final String Var_projectNature = "projectNatures"; //$NON-NLS-1$ + private static final String Var_languageId = "languageId"; //$NON-NLS-1$ + private static final int Default_Priority = 1000; + + public ContributedSemanticHighlighting(IConfigurationElement element) { + configurationElement = element; + + // required + id = element.getDeclaringExtension().getNamespaceIdentifier() + '.' + + element.getDeclaringExtension().getSimpleIdentifier(); + + int pri = Default_Priority; + String priStr = element.getAttribute(Attr_Priority); + if (priStr != null) + try { + pri = Integer.parseInt(priStr); + } catch (NumberFormatException e) { + CUIPlugin.log("Error in priority attribute of " + id + " was " + priStr, e); //$NON-NLS-1$ //$NON-NLS-2$ + } + priority = pri; + + Expression expr = null; + IConfigurationElement[] children = element.getChildren(ExpressionTagNames.ENABLEMENT); + switch (children.length) { + case 0: + fStatus = Boolean.TRUE; + break; + case 1: + try { + ExpressionConverter parser = ExpressionConverter.getDefault(); + expr = parser.perform(children[0]); + } catch (CoreException e) { + CUIPlugin.log("Error in enablement expression of " + id, e); //$NON-NLS-1$ + } + break; + default: + CUIPlugin.logError("Too many enablement expressions for " + id); //$NON-NLS-1$ + fStatus = Boolean.FALSE; + break; + } + enablementExpression = expr; + + preferenceKey = element.getAttribute(Attr_PrefKey); + displayName = element.getAttribute(Attr_DisplayName); + + // optional + defaultTextColor = getRGBAttribute(element, id, Attr_DefaultTextColor); + defaultBold = Boolean.parseBoolean(element.getAttribute(Attr_DefaultBold)); + defaultItalic = Boolean.parseBoolean(element.getAttribute(Attr_DefaultItalic)); + defaultStrikethrough = Boolean.parseBoolean(element.getAttribute(Attr_DefaultStrikethrough)); + defaultUnderline = Boolean.parseBoolean(element.getAttribute(Attr_DefaultUnderline)); + defaultEnabled = Boolean.parseBoolean(element.getAttribute(Attr_DefaultEnabled)); + } + + public String getId() { + return id; + } + + public int getPriority() { + return priority; + } + + private static RGB getRGBAttribute(IConfigurationElement element, String extensionId, String key) { + String val = element.getAttribute(key); + if (val != null) + try { + return StringConverter.asRGB(val); + } catch (DataFormatException e) { + CUIPlugin + .log("Error in " + Attr_DefaultTextColor + " attribute of " + extensionId + ' ' + val + " is not a RGB value", e); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + // black by default + return new RGB(0, 0, 0); + } + + private ISemanticHighlighter createSemanticHighlighter() { + + // only one try at creating the class + if (configurationElement == null) + return null; + + IConfigurationElement element = configurationElement; + configurationElement = null; + + try { + return (ISemanticHighlighter) element.createExecutableExtension(Attr_Class); + } catch (CoreException e) { + CUIPlugin.log("Error in class attribute of " + id, e); //$NON-NLS-1$ + } + + return null; + } + + @Override + public String getPreferenceKey() { + return preferenceKey; + } + + @Override + public RGB getDefaultDefaultTextColor() { + return defaultTextColor; + } + + @Override + public boolean isBoldByDefault() { + return defaultBold; + } + + @Override + public boolean isItalicByDefault() { + return defaultItalic; + } + + @Override + public boolean isStrikethroughByDefault() { + return defaultStrikethrough; + } + + @Override + public boolean isUnderlineByDefault() { + return defaultUnderline; + } + + @Override + public boolean isEnabledByDefault() { + return defaultEnabled; + } + + @Override + public String getDisplayName() { + return displayName; + } + + @Override + public boolean requiresImplicitNames() { + return false; + } + + private boolean matches(ITranslationUnit tu) { + + // if the enablement expression is missing or structurally invalid, then return immediately + if (fStatus != null) + return fStatus.booleanValue(); + + if (enablementExpression != null) + try { + EvaluationContext evalContext = new EvaluationContext(null, tu); + + ICProject cProject = tu.getCProject(); + String[] natures = cProject.getProject().getDescription().getNatureIds(); + evalContext.addVariable(Var_projectNature, Arrays.asList(natures)); + + ILanguage language = tu.getLanguage(); + if( language != null ) + evalContext.addVariable(Var_languageId, language.getId()); + + return enablementExpression.evaluate(evalContext) == EvaluationResult.TRUE; + } catch (CoreException e) { + CUIPlugin.log("Error while evaluating enablement expression for " + id, e); //$NON-NLS-1$ + } + + fStatus = Boolean.FALSE; + return false; + } + + /** + * Return the contributed ISemanticHighlighter if the receiver should be applied to the specified TU and + * null otherwise. + */ + private ISemanticHighlighter getSemanticHighlighter(ITranslationUnit tu) { + if (!matches(tu)) + return null; + + if (semanticHighlighter == null) + synchronized (this) { + if (semanticHighlighter == null) { + semanticHighlighter = createSemanticHighlighter(); + } + } + + return semanticHighlighter; + } + + @Override + public boolean consumes(ISemanticToken token) { + if (token == null) + return false; + + IASTTranslationUnit astTU = token.getRoot(); + if (astTU == null) + return false; + + ITranslationUnit tu = astTU.getOriginatingTranslationUnit(); + if (tu == null) + return false; + + ISemanticHighlighter highlighter = getSemanticHighlighter(tu); + if (highlighter == null) + return false; + + return highlighter.consumes(token); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java index a58b7463bc6..b6d72dc3562 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlighting.java @@ -17,11 +17,12 @@ import org.eclipse.swt.graphics.RGB; import org.eclipse.ui.PlatformUI; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.text.ISemanticToken; /** * Semantic highlighting. * Cloned from JDT. - * + * * @since 4.0 */ public abstract class SemanticHighlighting { @@ -81,9 +82,9 @@ public abstract class SemanticHighlighting { * @return the display name */ public abstract String getDisplayName(); - + /** - * Indicates that the highlighting needs to visit implicit names + * Indicates that the highlighting needs to visit implicit names * (e.g. overloaded operators) */ public boolean requiresImplicitNames() { @@ -100,7 +101,7 @@ public abstract class SemanticHighlighting { * @param token the semantic token for a {@link org.eclipse.cdt.core.dom.ast.IASTName} * @return true iff the semantic highlighting consumes the semantic token */ - public abstract boolean consumes(SemanticToken token); + public abstract boolean consumes(ISemanticToken token); private String getThemeColorKey() { return CUIPlugin.PLUGIN_ID + "." + getPreferenceKey() + "Highlighting"; //$NON-NLS-1$//$NON-NLS-2$ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java index e3df7aedf1e..5e6da1c7d65 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java @@ -11,7 +11,11 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.editor; +import java.util.Map; +import java.util.TreeMap; + import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; @@ -56,6 +60,7 @@ import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexName; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.text.ISemanticToken; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; @@ -228,7 +233,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -279,7 +284,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -330,7 +335,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTImplicitName) return false; @@ -407,7 +412,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -461,7 +466,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTImplicitName) return false; @@ -514,7 +519,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTImplicitName) return false; @@ -585,7 +590,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTImplicitName) return false; @@ -638,7 +643,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -698,7 +703,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -774,7 +779,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -836,7 +841,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IBinding binding= token.getBinding(); if (binding instanceof IParameter) { return true; @@ -880,7 +885,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IBinding binding= token.getBinding(); @@ -927,7 +932,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof ICPPASTQualifiedName || node instanceof ICPPASTTemplateId) { return false; @@ -977,7 +982,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IBinding binding= token.getBinding(); @@ -1024,7 +1029,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IBinding binding= token.getBinding(); if (binding instanceof IMacroBinding) { IASTName name= (IASTName)token.getNode(); @@ -1071,7 +1076,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IBinding binding= token.getBinding(); if (binding instanceof IMacroBinding) { IASTName name= (IASTName)token.getNode(); @@ -1118,7 +1123,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -1169,7 +1174,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IBinding binding= token.getBinding(); if (binding instanceof ICPPNamespace) { return true; @@ -1213,7 +1218,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IBinding binding= token.getBinding(); if (binding instanceof ILabel) { return true; @@ -1257,7 +1262,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -1313,7 +1318,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node.getTranslationUnit().isBasedOnIncompleteIndex()) { // Do not highlight problems is the AST is unreliable. @@ -1370,7 +1375,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node= token.getNode(); if (node instanceof IASTName) { IASTName name= (IASTName) node; @@ -1459,7 +1464,7 @@ public class SemanticHighlightings { } @Override - public boolean consumes(SemanticToken token) { + public boolean consumes(ISemanticToken token) { IASTNode node = token.getNode(); // So far we only have implicit names for overloaded operators and destructors, // so this works. @@ -1545,36 +1550,106 @@ public class SemanticHighlightings { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + semanticHighlighting.getPreferenceKey() + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ENABLED_SUFFIX; } + private static class Key implements Comparable { + public final int priority; + public final String id; + + public Key(int priority) { + this(priority, null); + } + + public Key(int priority, String id) { + this.priority = priority; + this.id = id; + } + + @Override + public int compareTo(Key o) { + if (priority < o.priority) + return -1; + if (o.priority < priority) + return 1; + + if (id == null) + return o.id == null ? 0 : -1; + + return o.id == null ? 1 : id.compareTo(o.id); + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append(priority); + if (id != null) { + str.append(' '); + str.append(id); + } + + return str.toString(); + } + } + + private static void loadBuiltInSemanticHighlightings(Map highlightings) { + + highlightings.put(new Key(10), new MacroReferenceHighlighting()); // before all others! + highlightings.put(new Key(20), new ProblemHighlighting()); + highlightings.put(new Key(30), new ExternalSDKHighlighting()); + highlightings.put(new Key(40), new ClassHighlighting()); + highlightings.put(new Key(50), new StaticFieldHighlighting()); + highlightings.put(new Key(60), new FieldHighlighting()); // after all other fields + highlightings.put(new Key(70), new MethodDeclarationHighlighting()); + highlightings.put(new Key(80), new StaticMethodInvocationHighlighting()); + highlightings.put(new Key(90), new ParameterVariableHighlighting()); // before local variables + highlightings.put(new Key(100), new LocalVariableDeclarationHighlighting()); + highlightings.put(new Key(110), new LocalVariableHighlighting()); + highlightings.put(new Key(120), new GlobalVariableHighlighting()); + highlightings.put(new Key(130), new TemplateParameterHighlighting()); // before template arguments! + highlightings.put(new Key(140), new OverloadedOperatorHighlighting()); // before both method and function + highlightings.put(new Key(150), new MethodHighlighting()); // before types to get ctors + highlightings.put(new Key(160), new EnumHighlighting()); + highlightings.put(new Key(170), new MacroDefinitionHighlighting()); + highlightings.put(new Key(180), new FunctionDeclarationHighlighting()); + highlightings.put(new Key(190), new FunctionHighlighting()); + highlightings.put(new Key(200), new TypedefHighlighting()); + highlightings.put(new Key(210), new NamespaceHighlighting()); + highlightings.put(new Key(220), new LabelHighlighting()); + highlightings.put(new Key(230), new EnumeratorHighlighting()); + } + + private static final String ExtensionPoint = "semanticHighlighting"; //$NON-NLS-1$ + + private static SemanticHighlighting[] loadSemanticHighlightings() { + + Map highlightings = new TreeMap(); + + // load the built-in highlightings + loadBuiltInSemanticHighlightings(highlightings); + + // load the extensions + IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor( + CUIPlugin.getPluginId(), ExtensionPoint); + for (IConfigurationElement element : elements) { + ContributedSemanticHighlighting contributedHighlighting = new ContributedSemanticHighlighting( + element); + + Key key = new Key(contributedHighlighting.getPriority(), contributedHighlighting.getId()); + highlightings.put(key, contributedHighlighting); + } + + return highlightings.values().toArray(new SemanticHighlighting[highlightings.size()]); + } + + private static final Object SemanticHighlightingsLock = new Object(); + /** * @return The semantic highlightings, the order defines the precedence of matches, the first match wins. */ public static SemanticHighlighting[] getSemanticHighlightings() { if (fgSemanticHighlightings == null) - fgSemanticHighlightings= new SemanticHighlighting[] { - new MacroReferenceHighlighting(), // before all others! - new ProblemHighlighting(), - new ExternalSDKHighlighting(), - new ClassHighlighting(), - new StaticFieldHighlighting(), - new FieldHighlighting(), // after all other fields - new MethodDeclarationHighlighting(), - new StaticMethodInvocationHighlighting(), - new ParameterVariableHighlighting(), // before local variables - new LocalVariableDeclarationHighlighting(), - new LocalVariableHighlighting(), - new GlobalVariableHighlighting(), - new TemplateParameterHighlighting(), // before template arguments! - new OverloadedOperatorHighlighting(), // before both method and function - new MethodHighlighting(), // before types to get ctors - new EnumHighlighting(), - new MacroDefinitionHighlighting(), - new FunctionDeclarationHighlighting(), - new FunctionHighlighting(), - new TypedefHighlighting(), - new NamespaceHighlighting(), - new LabelHighlighting(), - new EnumeratorHighlighting(), - }; + synchronized (SemanticHighlightingsLock) { + if (fgSemanticHighlightings == null) + fgSemanticHighlightings = loadSemanticHighlightings(); + } return fgSemanticHighlightings; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticToken.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticToken.java index 6b34458aae0..03b8e5136de 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticToken.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticToken.java @@ -15,14 +15,15 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.ui.text.ISemanticToken; /** * Semantic token. * Cloned from JDT. - * + * * @since 4.0 */ -public final class SemanticToken { +public final class SemanticToken implements ISemanticToken { /** AST node */ private IASTNode fNode; @@ -38,26 +39,29 @@ public final class SemanticToken { /** * @return Returns the binding, can be null. */ + @Override public IBinding getBinding() { if (!fIsBindingResolved) { fIsBindingResolved= true; if (fNode instanceof IASTName) fBinding= ((IASTName) fNode).resolveBinding(); } - + return fBinding; } /** * @return the AST node */ + @Override public IASTNode getNode() { return fNode; } - + /** * @return the AST root */ + @Override public IASTTranslationUnit getRoot() { if (!fIsRootResolved) { fIsRootResolved= true; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java index 078e30ce016..41ada730f5f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/language/settings/providers/LanguageSettingsProviderTab.java @@ -378,9 +378,9 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab { tableProvidersViewer.refresh(); tableProvidersViewer.setChecked(newProvider, isChecked); tableProviders.setSelection(pos); - tableProvidersViewer.refresh(newProvider); saveCheckedProviders(); + tableProvidersViewer.refresh(newProvider); } /** @@ -460,8 +460,8 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab { replaceSelectedProvider(newProvider); // will refresh and save checked providers createOptionsPage(newProvider); } else { - tableProvidersViewer.refresh(checkedProvider); saveCheckedProviders(); + tableProvidersViewer.refresh(checkedProvider); // option page is reused } @@ -483,7 +483,7 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab { } else { // Toggle to configuration-owned provider newProvider = getInitialProvider(id); - if(newProvider == null) { + if(newProvider == null || LanguageSettingsManager.isWorkspaceProvider(newProvider)) { try { ILanguageSettingsProvider rawProvider = LanguageSettingsManager.getRawProvider(provider); if (rawProvider instanceof ILanguageSettingsEditableProvider) { @@ -926,7 +926,7 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab { for (ILanguageSettingsProvider provider : allAvailableProvidersSet) { String id = provider.getId(); - if (!idsList.contains(id)) { + if (!idsList.contains(id) && ScannerDiscoveryLegacySupport.isProviderCompatible(id, cfgDescription)) { providers.add(provider); idsList.add(id); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java index 7e26e3a295c..92044bf3e66 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/newui/LanguageSettingsImages.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.cdt.ui.CDTSharedImages; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.utils.UNCPathConverter; /** * Helper class to provide unified images for {@link ICLanguageSettingEntry}. @@ -168,6 +169,8 @@ public class LanguageSettingsImages { IPath path = new Path(entry.getValue()); IResource rc = ResourcesPlugin.getWorkspace().getRoot().findMember(path); exists = (rc !=null) && rc.isAccessible(); + } else if (UNCPathConverter.isUNC(entry.getName())) { + return true; } else { String pathname = entry.getName(); java.io.File file = new java.io.File(pathname); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java index 84d2f2b45a1..6ed0dd248b2 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CEditorPreferencePage.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2005, 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 + * Copyright (c) 2005, 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: + * Contributors: * IBM Corporation - initial API and implementation * QNX Software System * Anton Leherbauer (Wind River Systems) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCodeScanner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCodeScanner.java index 7fa89c33b88..e965de83e0e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCodeScanner.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCodeScanner.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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) 2000, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * QNX Software System * Anton Leherbauer (Wind River Systems) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCommentScanner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCommentScanner.java index 4686f48201a..08e2ab9926f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCommentScanner.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CCommentScanner.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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) 2000, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * Anton Leherbauer (Wind River Systems) * Andrew Ferguson (Symbian) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TaskTagRule.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TaskTagRule.java index 2f59f9a7e7c..484e6fd6edf 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TaskTagRule.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TaskTagRule.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 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 + * Copyright (c) 2000, 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: + * Contributors: * IBM Corporation - initial API and implementation * Anton Leherbauer (Wind River Systems) * Sergey Prigogin (Google) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TokenStore.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TokenStore.java index 5f7e3a2eb41..cd88a165a6e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TokenStore.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/TokenStore.java @@ -1,18 +1,17 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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) 2000, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * QNX Software System * Andrew Ferguson (Symbian) - refactored to TokenStore (previously part of AbstractCScanner) *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; - import java.util.HashMap; import java.util.Map; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CHoverMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CHoverMessages.properties index cb14e7af8f7..e0c0d601d9e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CHoverMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CHoverMessages.properties @@ -1,16 +1,15 @@ ############################################################################### -# Copyright (c) 2000, 2009 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) 2000, 2009 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: +# Contributors: # IBM Corporation - initial API and implementation # Anton Leherbauer (Wind River Systems) # Sergey Prigogin (Google) ############################################################################### - AbstractAnnotationHover_action_configureAnnotationPreferences= Configure Annotation Preferences AbstractAnnotationHover_message_singleQuickFix= 1 quick fix available: AbstractAnnotationHover_message_multipleQuickFix= {0} quick fixes available: diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.java index 6b2f81c6450..b3caefb4215 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 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) 2000, 2008 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: + * Contributors: * IBM Corporation - initial API and implementation * Sergey Prigogin (Google) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.properties index 0c35c4b4fa0..1a8afd5ce5c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/CorrectionMessages.properties @@ -1,11 +1,11 @@ ############################################################################### -# Copyright (c) 2000, 2008 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) 2000, 2008 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: +# Contributors: # IBM Corporation - initial API and implementation # Sergey Prigogin (Google) ############################################################################### diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/ASTRewriteCorrectionProposal.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/ASTRewriteCorrectionProposal.java index a92164cea93..4ec95dee6fc 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/ASTRewriteCorrectionProposal.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/correction/proposals/ASTRewriteCorrectionProposal.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 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) 2000, 2008 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: + * Contributors: * IBM Corporation - initial API and implementation * Sergey Prigogin (Google) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CSpellingEngine.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CSpellingEngine.java index 7627cb04c8b..66a1d596c58 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CSpellingEngine.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CSpellingEngine.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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) 2000, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * Sergey Prigogin (Google) * Andrew Ferguson (Symbian) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CoreSpellingProblem.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CoreSpellingProblem.java index 74f4de2fdcb..8abd4996359 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CoreSpellingProblem.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/CoreSpellingProblem.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 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) 2005, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * Sergey Prigogin (Google) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/engine/AbstractSpellDictionary.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/engine/AbstractSpellDictionary.java index 8145d331956..bd20c15c579 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/engine/AbstractSpellDictionary.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/spelling/engine/AbstractSpellDictionary.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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) 2000, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * Sergey Prigogin (Google) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java index 5ab9c6dc2c2..814f1506258 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2013 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 @@ -19,8 +19,6 @@ import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.cdt.core.dom.IName; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; @@ -39,7 +37,7 @@ import org.eclipse.cdt.internal.core.model.ext.ICElementHandle; import org.eclipse.cdt.internal.ui.viewsupport.IndexUI; class THGraph { - private static final ICElement[] NO_MEMBERS = new ICElement[0]; + private static final ICElement[] NO_MEMBERS = {}; private THGraphNode fInputNode= null; private HashSet fRootNodes= new HashSet(); private HashSet fLeaveNodes= new HashSet(); @@ -251,25 +249,22 @@ class THGraph { private void addMembers(IIndex index, THGraphNode graphNode, IBinding binding) throws CoreException { if (graphNode.getMembers(false) == null) { ArrayList memberList= new ArrayList(); - try { - if (binding instanceof ICPPClassType) { - ICPPClassType ct= (ICPPClassType) binding; - IBinding[] members= ct.getDeclaredFields(); - addMemberElements(index, members, memberList); - members= ct.getDeclaredMethods(); - addMemberElements(index, members, memberList); - } else if (binding instanceof ICompositeType) { - ICompositeType ct= (ICompositeType) binding; - IBinding[] members= ct.getFields(); - addMemberElements(index, members, memberList); - } else if (binding instanceof IEnumeration) { - IEnumeration ct= (IEnumeration) binding; - IBinding[] members= ct.getEnumerators(); - addMemberElements(index, members, memberList); - } - } catch (DOMException e) { - // Problem bindings should not be reported to the log. + if (binding instanceof ICPPClassType) { + ICPPClassType ct= (ICPPClassType) binding; + IBinding[] members= ct.getDeclaredFields(); + addMemberElements(index, members, memberList); + members= ct.getDeclaredMethods(); + addMemberElements(index, members, memberList); + } else if (binding instanceof ICompositeType) { + ICompositeType ct= (ICompositeType) binding; + IBinding[] members= ct.getFields(); + addMemberElements(index, members, memberList); + } else if (binding instanceof IEnumeration) { + IEnumeration ct= (IEnumeration) binding; + IBinding[] members= ct.getEnumerators(); + addMemberElements(index, members, memberList); } + if (memberList.isEmpty()) { graphNode.setMembers(NO_MEMBERS); } else { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java index 16a99815bc2..43aee483a21 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2003, 2013 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) 2003, 2013 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: + * Contributors: * QNX Software Systems - Initial implementation * Sergey Prigogin (Google) *******************************************************************************/ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java index 50c5f56d629..200467ba02c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java @@ -2219,7 +2219,7 @@ public class PreferenceConstants { * the workspace setting should be taken. Note that passing {@code null} should be avoided. * @param defaultValue The default value if not specified in the preferences. * @return Returns the current value of the preference. - * @since 5.5 + * @since 5.6 */ public static String getPreference(String key, ICProject project, String defaultValue) { return getPreferenceNode(key, project).get(key, defaultValue); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractPage.java index 61270ae07d4..cf9f9f73299 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractPage.java @@ -979,8 +979,11 @@ implements } protected void cfgChanged(ICConfigurationDescription _cfgd) { - CConfigurationStatus st = _cfgd.getConfigurationStatus(); + if (st.getCode() == CConfigurationStatus.TOOLCHAIN_NOT_SUPPORTED) { + // Re-check, maybe user got the problem fixed + st = _cfgd.getConfigurationData().getStatus(); + } if (errPane != null && errMessage != null) { if (st.isOK()) { errPane.setVisible(false); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ManageConfigDialog.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ManageConfigDialog.java index 8ed8a840392..ba1cb6126e4 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ManageConfigDialog.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/ManageConfigDialog.java @@ -276,11 +276,17 @@ public class ManageConfigDialog extends Dialog { for (int i=0; i 0) table.select(0); + if (table.getItemCount() > 0) { + table.select(0); + } table.setFocus(); updateButtons(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/UIMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/UIMessages.java index c5554d4b578..f252923ef7a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/UIMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/UIMessages.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 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, 2009 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 + * Contributors: + * IBM - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.ui.newui; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/AbstractCScanner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/AbstractCScanner.java index 945e4493b31..a91291d6f46 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/AbstractCScanner.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/AbstractCScanner.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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) 2000, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * QNX Software System * Andrew Ferguson (Symbian) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ISemanticHighlighter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ISemanticHighlighter.java new file mode 100644 index 00000000000..0c2d3a169bb --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ISemanticHighlighter.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 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 + */ + +package org.eclipse.cdt.ui.text; + + +/** + * Interface that must be implemented by contributors to the org.eclipse.cdt.ui.semanticHighlighting extension + * point. + * + * @since 5.6 + */ +public interface ISemanticHighlighter { + /** + * Returns true iff the semantic highlighting consumes the semantic token. + *

+ * NOTE: Implementors are not allowed to keep a reference on the token or on any object retrieved from the + * token. + *

+ * + * @param token + * the semantic token for a {@link org.eclipse.cdt.core.dom.ast.IASTName} + * @return true iff the semantic highlighting consumes the semantic token + */ + public boolean consumes(ISemanticToken token); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ISemanticToken.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ISemanticToken.java new file mode 100644 index 00000000000..239f43f1340 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ISemanticToken.java @@ -0,0 +1,27 @@ +package org.eclipse.cdt.ui.text; + +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; + +/** + * An interface for accessing details of the token that is being highlighted. + * + * @since 5.6 + */ +public interface ISemanticToken { + /** + * @return Returns the binding, can be null. + */ + public IBinding getBinding(); + + /** + * @return the AST node + */ + public IASTNode getNode(); + + /** + * @return the AST root + */ + public IASTTranslationUnit getRoot(); +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/TaskTagRule.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/TaskTagRule.java index 98f830aa25c..e2395b3922a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/TaskTagRule.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/TaskTagRule.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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) 2000, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * Anton Leherbauer (Wind River Systems) * Sergey Prigogin (Google) diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java index e75c80e840c..b9904b6cd32 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CDebugModelPresentation.java @@ -89,10 +89,13 @@ import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.ISourcePresentation; import org.eclipse.debug.ui.IValueDetailListener; import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IEditorInput; @@ -105,7 +108,7 @@ import com.ibm.icu.text.MessageFormat; /** * @see IDebugModelPresentation */ -public class CDebugModelPresentation extends LabelProvider implements IDebugModelPresentation { +public class CDebugModelPresentation extends LabelProvider implements IDebugModelPresentation, IColorProvider { public final static String DISPLAY_FULL_PATHS = "DISPLAY_FULL_PATHS"; //$NON-NLS-1$ @@ -194,6 +197,14 @@ public class CDebugModelPresentation extends LabelProvider implements IDebugMode } if ( file != null ) return new FileEditorInput( file ); + // There is no file associated with this breakpoint. See if another editor is available from an adapter + ISourcePresentation srcPres = (ISourcePresentation) Platform.getAdapterManager().getAdapter(b, ISourcePresentation.class); + if ( srcPres != null ) { + IEditorInput editor = srcPres.getEditorInput(b); + if ( editor != null ) { + return editor; + } + } } if ( element instanceof FileStorage || element instanceof LocalFileStorage ) { return new ExternalEditorInput( ((IStorage) element).getFullPath() ); @@ -220,7 +231,20 @@ public class CDebugModelPresentation extends LabelProvider implements IDebugMode if ( input != null ) { IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry(); IEditorDescriptor descriptor = registry.getDefaultEditor( input.getName() ); - id = (descriptor != null) ? descriptor.getId() : CUIPlugin.EDITOR_ID; + id = CUIPlugin.EDITOR_ID; + if ( descriptor != null ) { + id = descriptor.getId(); + } + else if ( element instanceof ICBreakpoint ) { + // There is no associated editor ID for this breakpoint, see if an alternative can be supplied from an adapter. + ISourcePresentation sourcePres = (ISourcePresentation) Platform.getAdapterManager().getAdapter(element, ISourcePresentation.class); + if ( sourcePres != null ) { + String lid = sourcePres.getEditorId(input, element); + if ( lid != null ) { + id = lid; + } + } + } } return id; } @@ -797,4 +821,21 @@ public class CDebugModelPresentation extends LabelProvider implements IDebugMode return MessageFormat.format( string, (Object[]) args ); } + @Override + public Color getForeground(Object element) { + IColorProvider colorProv = (IColorProvider) Platform.getAdapterManager().getAdapter(element, IColorProvider.class); + if ( colorProv != null ) { + return colorProv.getForeground(element); + } + return null; + } + + @Override + public Color getBackground(Object element) { + IColorProvider colorProv = (IColorProvider) Platform.getAdapterManager().getAdapter(element, IColorProvider.class); + if ( colorProv != null ) { + return colorProv.getBackground(element); + } + return null; + } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/ReverseToggleCommandHandler.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/ReverseToggleCommandHandler.java index dd917d98ddc..64f1a4e5cc3 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/ReverseToggleCommandHandler.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/ReverseToggleCommandHandler.java @@ -124,6 +124,12 @@ public class ReverseToggleCommandHandler extends DebugCommandHandler implements return adapter; } + /* + * (non-Javadoc) + * @see org.eclipse.debug.ui.actions.DebugCommandHandler#postExecute(org.eclipse.debug.core.IRequest, java.lang.Object[]) + * + * We keep this logic for users that may not do the refresh themselves. + */ @Override protected void postExecute(IRequest request, Object[] targets) { super.postExecute(request, targets); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointPropertyDialogAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointPropertyDialogAction.java index 16883079cf1..461c050d625 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointPropertyDialogAction.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/CBreakpointPropertyDialogAction.java @@ -16,10 +16,13 @@ import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.internal.ui.breakpoints.CBreakpointContext; import org.eclipse.core.runtime.Assert; import org.eclipse.debug.ui.contexts.IDebugContextProvider; +import org.eclipse.jface.preference.IPreferenceNode; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.window.IShellProvider; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.SelectionProviderAction; @@ -56,10 +59,7 @@ public class CBreakpointPropertyDialogAction extends SelectionProviderAction { private IDebugContextProvider fDebugContextProvider; - /** - * The id of the page to open up on. - */ - private String fInitialPageId = "org.eclipse.cdt.debug.ui.propertypages.breakpoint.common"; //$NON-NLS-1$ + private static final String PAGE_ID_COMMON = "org.eclipse.cdt.debug.ui.propertypages.breakpoint.common"; //$NON-NLS-1$ public CBreakpointPropertyDialogAction(IShellProvider shell, ISelectionProvider selectionProvider, IDebugContextProvider debugContextProvider) { super(selectionProvider, WorkbenchMessages.PropertyDialog_text); @@ -133,7 +133,6 @@ public class CBreakpointPropertyDialogAction extends SelectionProviderAction { return true; } - /* (non-Javadoc) * @see org.eclipse.jface.action.IAction#run() */ @@ -143,8 +142,31 @@ public class CBreakpointPropertyDialogAction extends SelectionProviderAction { PreferenceDialog dialog = createDialog(bpContext); if (dialog != null) { + TreeViewer viewer = dialog.getTreeViewer(); + if (viewer != null) { + viewer.setComparator(new ViewerComparator() { + @Override + public int category(Object element) { + if (element instanceof IPreferenceNode) { + IPreferenceNode node = (IPreferenceNode)element; + if ( PAGE_ID_COMMON.equals(node.getId()) ) { + return 0; + } else if (node.getSubNodes() == null || node.getSubNodes().length == 0) { + // Pages without children (not categories) + return super.category(element) + 1; + } + } + // Categories last. + return super.category(element) + 2; + } + }); + // Expand all categories + viewer.expandToLevel(TreeViewer.ALL_LEVELS); + } + dialog.open(); } + } } @@ -168,7 +190,7 @@ public class CBreakpointPropertyDialogAction extends SelectionProviderAction { if (ss.isEmpty()) return null; - return PreferencesUtil.createPropertyDialogOn(fShellProvider.getShell(), bpContext, fInitialPageId, null, null); + return PreferencesUtil.createPropertyDialogOn(fShellProvider.getShell(), bpContext, null, null, null); } diff --git a/doc/org.eclipse.cdt.doc.isv/.gitignore b/doc/org.eclipse.cdt.doc.isv/.gitignore index 9cd5171a1a3..1ff9a2b1348 100644 --- a/doc/org.eclipse.cdt.doc.isv/.gitignore +++ b/doc/org.eclipse.cdt.doc.isv/.gitignore @@ -1,3 +1,4 @@ .metadata cdtconvert.txt reference +/doc.bin.log diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.settings/.api_filters b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.settings/.api_filters new file mode 100644 index 00000000000..e70d7175758 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/.settings/.api_filters @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/META-INF/MANIFEST.MF index b761cf5ccf9..7b35047f936 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/META-INF/MANIFEST.MF +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/META-INF/MANIFEST.MF @@ -18,8 +18,8 @@ Require-Bundle: org.eclipse.ui, Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Import-Package: com.ibm.icu.text -Export-Package: org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui, - org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions, - org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model, - org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view, - org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils +Export-Package: org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui;x-internal:=true, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.actions;x-internal:=true, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.model;x-internal:=true, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view;x-internal:=true, + org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.utils;x-internal:=true diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizer.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizer.java index f3f7ac3e792..f9ea96ac601 100755 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizer.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizer.java @@ -8,6 +8,7 @@ * Contributors: * William R. Swanson (Tilera Corporation) - initial API and implementation * IBM Corporation + * Marc Dumais (Ericsson) - Bug 399281 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; @@ -705,10 +706,11 @@ public class MulticoreVisualizer extends GraphicCanvasVisualizer protected void setCanvasModel(VisualizerModel model) { final VisualizerModel model_f = model; GUIUtils.exec(new Runnable() { @Override public void run() { - m_canvas.setModel(model_f); - - // Update the canvas's selection from the current workbench selection. - updateCanvasSelectionInternal(); + if(m_canvas != null) { + m_canvas.setModel(model_f); + // Update the canvas's selection from the current workbench selection. + updateCanvasSelectionInternal(); + } }}); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java index 291a5a95a8d..093501c1cb4 100755 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerCanvas.java @@ -11,6 +11,7 @@ * Marc Dumais (Ericsson) - Bug 396184 * Marc Dumais (Ericsson) - Bug 396200 * Marc Dumais (Ericsson) - Bug 396293 + * Marc Dumais (Ericsson) - Bug 399281 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; @@ -303,7 +304,9 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas */ public void requestUpdate() { GUIUtils.exec(new Runnable() { @Override public void run() { - m_updateTimer.start(); + if (m_updateTimer != null) { + m_updateTimer.start(); + } }}); } @@ -867,7 +870,9 @@ public class MulticoreVisualizerCanvas extends GraphicCanvas /** Removes external listener for selection change events. */ @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { - m_selectionManager.removeSelectionChangedListener(listener); + if (m_selectionManager != null) { + m_selectionManager.removeSelectionChangedListener(listener); + } } /** Raises selection changed event. */ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerEventListener.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerEventListener.java index cacb15f641b..bd8e70615a7 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerEventListener.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.multicorevisualizer.ui/src/org/eclipse/cdt/dsf/gdb/multicorevisualizer/internal/ui/view/MulticoreVisualizerEventListener.java @@ -7,6 +7,7 @@ * * Contributors: * Marc Khouzam (Ericsson) - initial API and implementation + * Marc Dumais (Ericsson) - Bug 400231 *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.multicorevisualizer.internal.ui.view; @@ -187,7 +188,10 @@ public class MulticoreVisualizerEventListener { fVisualizer.getModel().markThreadExited(tid); - fVisualizer.getMulticoreVisualizerCanvas().requestUpdate(); + MulticoreVisualizerCanvas canvas = fVisualizer.getMulticoreVisualizerCanvas(); + if (canvas != null) { + canvas.requestUpdate(); + } } } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF index 8d3a7df5824..0e79e45f0b2 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/META-INF/MANIFEST.MF @@ -23,7 +23,9 @@ Require-Bundle: org.eclipse.ui, org.eclipse.jface.text;bundle-version="3.4.0", org.eclipse.ui.editors;bundle-version="3.4.0", org.eclipse.core.filesystem;bundle-version="1.2.0", - org.eclipse.cdt.launch;bundle-version="6.1.0" + org.eclipse.cdt.launch;bundle-version="6.1.0", + org.eclipse.debug.core, + org.eclipse.core.resources Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: org.eclipse.cdt.dsf.gdb.internal.ui;x-internal:=true, diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbReverseToggleCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbReverseToggleCommand.java index dd236ed83d0..d02a5008215 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbReverseToggleCommand.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbReverseToggleCommand.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Ericsson and others. + * Copyright (c) 2009, 2013 Ericsson 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,7 @@ * * Contributors: * Ericsson - initial API and implementation + * Marc Khouzam (Ericsson) - Listen for IReverseModeChangedDMEvent (Bug 399163) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.commands; @@ -16,6 +17,7 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.debug.core.model.IReverseToggleHandler; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.Query; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; @@ -24,15 +26,23 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl; +import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl.IReverseModeChangedDMEvent; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.IRequest; import org.eclipse.debug.core.commands.AbstractDebugCommand; import org.eclipse.debug.core.commands.IDebugCommandRequest; import org.eclipse.debug.core.commands.IEnabledStateRequest; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.progress.WorkbenchJob; +import org.eclipse.ui.services.IEvaluationService; /** * Command that toggles the Reverse Debugging feature @@ -42,13 +52,33 @@ import org.eclipse.debug.core.commands.IEnabledStateRequest; public class GdbReverseToggleCommand extends AbstractDebugCommand implements IReverseToggleHandler { private final DsfExecutor fExecutor; private final DsfServicesTracker fTracker; + private final DsfSession fSession; public GdbReverseToggleCommand(DsfSession session) { fExecutor = session.getExecutor(); fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId()); + fSession = session; + try { + fExecutor.execute(new DsfRunnable() { + @Override + public void run() { + fSession.addServiceEventListener(GdbReverseToggleCommand.this, null); + } + }); + } catch(RejectedExecutionException e) {} } public void dispose() { + try { + fExecutor.execute(new DsfRunnable() { + @Override + public void run() { + fSession.removeServiceEventListener(GdbReverseToggleCommand.this); + } + }); + } catch (RejectedExecutionException e) { + // Session already gone. + } fTracker.dispose(); } @@ -195,4 +225,30 @@ public class GdbReverseToggleCommand extends AbstractDebugCommand implements IRe return false; } + + /** + * @noreference This method is not intended to be referenced by clients. + */ + @DsfServiceEventHandler + public void eventDispatched(IReverseModeChangedDMEvent e) { + new WorkbenchJob("") { //$NON-NLS-1$ + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + // Request re-evaluation of property "org.eclipse.cdt.debug.ui.isReverseDebuggingEnabled" to update + // visibility of reverse stepping commands. + IEvaluationService exprService = (IEvaluationService) PlatformUI.getWorkbench().getService(IEvaluationService.class); + if (exprService != null) { + exprService.requestEvaluation("org.eclipse.cdt.debug.ui.isReverseDebuggingEnabled"); //$NON-NLS-1$ + } + // Refresh reverse toggle commands with the new state of reverse enabled. + // This is in order to keep multiple toggle actions in UI in sync. + ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + if (commandService != null) { + commandService.refreshElements("org.eclipse.cdt.debug.ui.command.reverseToggle", null); //$NON-NLS-1$ + } + + return Status.OK_STATUS; + } + }.schedule(); + } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbUncallCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbUncallCommand.java index 6087a96b686..c0c89fd2251 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbUncallCommand.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/commands/GdbUncallCommand.java @@ -7,6 +7,7 @@ * * Contributors: * Ericsson - initial API and implementation + * Marc Khouzam (Ericsson) - Instruction-level step-return does not make sense (bug 399123) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.ui.commands; @@ -26,7 +27,6 @@ public class GdbUncallCommand extends GdbAbstractReverseStepCommand implements I @Override protected final StepType getStepType() { - boolean instructionSteppingEnabled = getSteppingMode() != null && getSteppingMode().isInstructionSteppingEnabled(); - return instructionSteppingEnabled ? StepType.INSTRUCTION_STEP_RETURN : StepType.STEP_RETURN; + return StepType.STEP_RETURN; } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/SessionOSData.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/SessionOSData.java index bfcbed340ea..7784f92f91d 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/SessionOSData.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/osview/SessionOSData.java @@ -27,6 +27,8 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2.IResourceClass; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2.IResourcesInformation; import org.eclipse.cdt.dsf.mi.service.IMIRunControl; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServicesTracker; @@ -48,7 +50,7 @@ public class SessionOSData { private IGDBHardwareAndOS2 fHardwareOs; private ICommandControlDMContext fContext; - private IGDBHardwareAndOS2.IResourceClass[] fResourceClasses = new IGDBHardwareAndOS2.IResourceClass[0]; + private IResourceClass[] fResourceClasses = new IResourceClass[0]; private Map fExistingData = new HashMap(); private Map fTimestamp = new HashMap(); @@ -100,7 +102,7 @@ public class SessionOSData { { fWaitingForSession = false; fFetchingClasses = true; - fHardwareOs.getResourceClasses(fContext, new DataRequestMonitor(fSession.getExecutor(), null) { + fHardwareOs.getResourceClasses(fContext, new DataRequestMonitor(fSession.getExecutor(), null) { @Override @ConfinedToDsfExecutor("fExecutor") protected void handleCompleted() { @@ -145,7 +147,7 @@ public class SessionOSData { fTracker.dispose(); } - public IGDBHardwareAndOS2.IResourceClass[] getResourceClasses() + public IResourceClass[] getResourceClasses() { return fResourceClasses; } @@ -202,7 +204,7 @@ public class SessionOSData { @Override public void run() { - fHardwareOs.getResourcesInformation(fContext, resourceClass, new DataRequestMonitor(executor, null) { + fHardwareOs.getResourcesInformation(fContext, resourceClass, new DataRequestMonitor(executor, null) { @Override @ConfinedToDsfExecutor("fExecutor") diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF index 5c2b5640892..875fd3ece60 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.cdt.debug.core, org.eclipse.core.variables, org.eclipse.cdt.launch;bundle-version="6.1.0", - org.eclipse.cdt.gdb;bundle-version="7.0.0" + org.eclipse.cdt.gdb;bundle-version="7.0.0", + org.eclipse.core.resources Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: org.eclipse.cdt.dsf.gdb, diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_0.java index 0a03927b29c..c910204f01e 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/FinalLaunchSequence_7_0.java @@ -43,7 +43,6 @@ public class FinalLaunchSequence_7_0 extends FinalLaunchSequence { private IGDBControl fCommandControl; private CommandFactory fCommandFactory; - private DsfServicesTracker fTracker; private DsfSession fSession; public FinalLaunchSequence_7_0(DsfSession session, Map attributes, RequestMonitorWithProgress rm) { @@ -76,9 +75,10 @@ public class FinalLaunchSequence_7_0 extends FinalLaunchSequence { */ @Execute public void stepInitializeFinalLaunchSequence_7_0(RequestMonitor rm) { - fTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSession.getId()); + DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSession.getId()); + fCommandControl = tracker.getService(IGDBControl.class); + tracker.dispose(); - fCommandControl = fTracker.getService(IGDBControl.class); if (fCommandControl == null) { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot obtain control service", null)); //$NON-NLS-1$ rm.done(); @@ -96,8 +96,6 @@ public class FinalLaunchSequence_7_0 extends FinalLaunchSequence { */ @RollBack("stepInitializeFinalLaunchSequence_7_0") public void rollBackInitializeFinalLaunchSequence_7_0(RequestMonitor rm) { - if (fTracker != null) fTracker.dispose(); - fTracker = null; rm.done(); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBMemory_7_6.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBMemory_7_6.java new file mode 100644 index 00000000000..3c4dd5475e2 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBMemory_7_6.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.service; + +import java.util.Hashtable; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.IMemory; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.debug.service.command.IEventListener; +import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.mi.service.IMIProcesses; +import org.eclipse.cdt.dsf.mi.service.MIMemory; +import org.eclipse.cdt.dsf.mi.service.command.output.MIConst; +import org.eclipse.cdt.dsf.mi.service.command.output.MINotifyAsyncOutput; +import org.eclipse.cdt.dsf.mi.service.command.output.MIOOBRecord; +import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput; +import org.eclipse.cdt.dsf.mi.service.command.output.MIResult; +import org.eclipse.cdt.dsf.mi.service.command.output.MIValue; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.utils.Addr64; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * Memory service that uses the enhancements from GDB 7.6: + * =memory-changed MI event + * + * @since 4.2 + */ +public class GDBMemory_7_6 extends GDBMemory_7_0 implements IEventListener { + + private ICommandControlService fConnection; + + public GDBMemory_7_6(DsfSession session) { + super(session); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new ImmediateRequestMonitor(requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(final RequestMonitor requestMonitor) { + register(new String[] { MIMemory.class.getName(), + IMemory.class.getName(), + GDBMemory_7_0.class.getName(), + GDBMemory_7_6.class.getName()}, + new Hashtable()); + + fConnection = getServicesTracker().getService(ICommandControlService.class); + if (fConnection == null) { + requestMonitor.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "CommandControl Service is not available")); //$NON-NLS-1$ + return; + } + fConnection.addEventListener(this); + + requestMonitor.done(); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + fConnection.removeEventListener(this); + unregister(); + super.shutdown(requestMonitor); + } + + @Override + public void eventReceived(Object output) { + if (output instanceof MIOutput) { + MIOOBRecord[] records = ((MIOutput)output).getMIOOBRecords(); + for (MIOOBRecord r : records) { + if (r instanceof MINotifyAsyncOutput) { + MINotifyAsyncOutput notifyOutput = (MINotifyAsyncOutput)r; + String asyncClass = notifyOutput.getAsyncClass(); + // These events have been added with GDB 7.6 + if ("memory-changed".equals(asyncClass)) { //$NON-NLS-1$ + String groupId = null; + String addr = null; + int length = 0; + + MIResult[] results = notifyOutput.getMIResults(); + for (int i = 0; i < results.length; i++) { + String var = results[i].getVariable(); + MIValue val = results[i].getMIValue(); + if (var.equals("thread-group")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + groupId = ((MIConst)val).getString(); + } + } else if (var.equals("addr")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + addr = ((MIConst)val).getString(); + } + } else if (var.equals("len")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + try { + String lenStr = ((MIConst)val).getString().trim(); + if (lenStr.startsWith("0x")) { //$NON-NLS-1$ + length = Integer.parseInt(lenStr.substring(2), 16); + } else { + length = Integer.parseInt(lenStr); + } + } catch (NumberFormatException e) { + assert false; + } + } + } else if (var.equals("type")) { //$NON-NLS-1$ + if (val instanceof MIConst) { + if ("code".equals(((MIConst)val).getString())) { //$NON-NLS-1$ + } + } + } + } + + IMIProcesses procService = getServicesTracker().getService(IMIProcesses.class); + if (procService != null && groupId != null && addr != null && length > 0) { + IContainerDMContext containerDmc = + procService.createContainerContextFromGroupId(fConnection.getContext(), groupId); + + // Now refresh our memory cache, it case it contained this address. Don't have + // it send the potential IMemoryChangedEvent as we will send it ourselves (see below). + final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(containerDmc, IMemoryDMContext.class); + final IAddress address = new Addr64(addr); + // The length returned by GDB is in bytes, while the memory cache expects + // a count of number of addresses of 8 bytes. + int count = length/8 + 1; + getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, 1, count, false, + new RequestMonitor(getExecutor(), null) { + @Override + protected void handleCompleted() { + // Only once the memory cache is updated, we send the IMemoryChangedEvent. If we were to do it + // earlier, the memory view may not show the updated value. + // + // We must always send this event when GDB reports a memory change because it can mean that + // an expression or register has changed, and therefore we must notify the different views + // and services of it. We cannot rely on this event to be sent by the memory cache after being + // refreshed, because if the memory cache does not contain this address, it will not send + // the event. + getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, new IAddress[] { address }), getProperties()); + } + }); + } + } + } + } + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java index eb6abfb6adf..f5f8f1b8055 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Wind River Systems and others. + * Copyright (c) 2008, 2013 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 @@ -11,6 +11,7 @@ * Ericsson - Version 7.0 * Nokia - create and use backend service. * Ericsson - Added IReverseControl support + * Marc Khouzam (Ericsson) - Added IReverseModeChangedDMEvent (Bug 399163) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -21,6 +22,7 @@ import java.util.Hashtable; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; @@ -52,6 +54,22 @@ import org.eclipse.core.runtime.Status; public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunControl { + /** @since 4.2 */ + protected static class GdbReverseModeChangedDMEvent extends AbstractDMEvent + implements IReverseModeChangedDMEvent { + private boolean fIsEnabled; + + public GdbReverseModeChangedDMEvent(ICommandControlDMContext context, boolean enabled) { + super(context); + fIsEnabled = enabled; + } + + @Override + public boolean isReverseModeEnabled() { + return fIsEnabled; + } + } + private static class RunToLineActiveOperation { private IMIExecutionDMContext fThreadContext; private int fBpId; @@ -75,6 +93,7 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro public boolean shouldSkipBreakpoints() { return fSkipBreakpoints; } } + private IMICommandControl fCommandControl; private IGDBBackend fGdb; private IMIProcesses fProcService; private CommandFactory fCommandFactory; @@ -111,7 +130,8 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro fGdb = getServicesTracker().getService(IGDBBackend.class); fProcService = getServicesTracker().getService(IMIProcesses.class); - fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory(); + fCommandControl = getServicesTracker().getService(IMICommandControl.class); + fCommandFactory = fCommandControl.getCommandFactory(); if (fGdb.getSessionType() == SessionType.CORE) { // No execution for core files, so no support for reverse @@ -628,6 +648,10 @@ public class GDBRunControl_7_0 extends MIRunControl implements IReverseRunContro /** @since 2.0 */ public void setReverseModeEnabled(boolean enabled) { - fReverseModeEnabled = enabled; + if (fReverseModeEnabled != enabled) { + fReverseModeEnabled = enabled; + getSession().dispatchEvent(new GdbReverseModeChangedDMEvent(fCommandControl.getContext(), fReverseModeEnabled), + getProperties()); + } } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_6.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_6.java new file mode 100644 index 00000000000..0e5a3cc3c7a --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_6.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson 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: + * Marc Khouzam (Ericsson) - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.gdb.service; + + +import java.util.Hashtable; + +import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.service.IRunControl; +import org.eclipse.cdt.dsf.debug.service.IRunControl2; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControl; +import org.eclipse.cdt.dsf.debug.service.command.IEventListener; +import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.mi.service.IMIRunControl; +import org.eclipse.cdt.dsf.mi.service.MIRunControl; +import org.eclipse.cdt.dsf.mi.service.command.output.MINotifyAsyncOutput; +import org.eclipse.cdt.dsf.mi.service.command.output.MIOOBRecord; +import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * @since 4.2 + */ +public class GDBRunControl_7_6 extends GDBRunControl_7_0 implements IEventListener { + + private ICommandControl fCommandControl; + + public GDBRunControl_7_6(DsfSession session) { + super(session); + } + + @Override + public void initialize(final RequestMonitor requestMonitor) { + super.initialize( + new ImmediateRequestMonitor(requestMonitor) { + @Override + public void handleSuccess() { + doInitialize(requestMonitor); + }}); + } + + private void doInitialize(final RequestMonitor requestMonitor) { + + fCommandControl = getServicesTracker().getService(ICommandControl.class); + + if (fCommandControl == null) { + requestMonitor.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Service is not available")); //$NON-NLS-1$ + return; + } + + fCommandControl.addEventListener(this); + + register(new String[]{IRunControl.class.getName(), + IRunControl2.class.getName(), + IMIRunControl.class.getName(), + MIRunControl.class.getName(), + GDBRunControl_7_0.class.getName(), + GDBRunControl_7_6.class.getName(), + IReverseRunControl.class.getName()}, + new Hashtable()); + requestMonitor.done(); + } + + @Override + public void shutdown(final RequestMonitor requestMonitor) { + if (fCommandControl != null) { + fCommandControl.removeEventListener(this); + } + unregister(); + super.shutdown(requestMonitor); + } + + @Override + public void eventReceived(Object output) { + if (output instanceof MIOutput) { + MIOOBRecord[] records = ((MIOutput)output).getMIOOBRecords(); + for (MIOOBRecord r : records) { + if (r instanceof MINotifyAsyncOutput) { + MINotifyAsyncOutput notifyOutput = (MINotifyAsyncOutput)r; + String asyncClass = notifyOutput.getAsyncClass(); + // These events have been added with GDB 7.6 + if ("record-started".equals(asyncClass) || //$NON-NLS-1$ + "record-stopped".equals(asyncClass)) { //$NON-NLS-1$ + + boolean enable = "record-started".equals(asyncClass); //$NON-NLS-1$ + setReverseModeEnabled(enable); + } + } + } + } + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java index c1a2647d4c0..d01fcd6e7de 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GdbDebugServicesFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2012 Ericsson and others. + * Copyright (c) 2008, 2013 Ericsson 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 @@ -12,6 +12,7 @@ * Marc Khouzam (Ericsson) - Support for GDB 7.4 (Bug 367788) * Marc Khouzam (Ericsson) - Include IGDBHardware service for the multicore visualizer (Bug 335027) * Vladimir Prus (Mentor Graphics) - Support for OS resources. + * Marc Khouzam (Ericsson) - Support for GDB 7.6 memory service *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -67,6 +68,8 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { public static final String GDB_7_4_VERSION = "7.4"; //$NON-NLS-1$ /** @since 4.2*/ public static final String GDB_7_5_VERSION = "7.5"; //$NON-NLS-1$ + /** @since 4.2*/ + public static final String GDB_7_6_VERSION = "7.5.50"; //$NON-NLS-1$ private final String fVersion; @@ -172,6 +175,10 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { @Override protected IMemory createMemoryService(DsfSession session) { + if (GDB_7_6_VERSION.compareTo(fVersion) <= 0) { + return new GDBMemory_7_6(session); + } + if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) { return new GDBMemory_7_0(session); } @@ -208,6 +215,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { @Override protected IRunControl createRunControlService(DsfSession session) { + if (GDB_7_6_VERSION.compareTo(fVersion) <= 0) { + return new GDBRunControl_7_6(session); + } if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) { return new GDBRunControl_7_0(session); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IReverseRunControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IReverseRunControl.java index 6751d3f4ee3..3d03793bc9c 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IReverseRunControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IReverseRunControl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Ericsson and others. + * Copyright (c) 2009, 2013 Ericsson 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,27 +7,94 @@ * * Contributors: * Ericsson - Initial API and implementation + * Marc Khouzam (Ericsson) - Added IReverseModeChangedDMEvent (Bug 399163) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; /** + * This interface provides access to controlling and monitoring the reverse execution + * state of a process being debugged. + * * @since 2.0 */ public interface IReverseRunControl { + /** + * Indicates that the enablement of reverse debugging has changed. + * + * @since 4.2 + */ + interface IReverseModeChangedDMEvent extends IDMEvent { + /** + * @return the new state of reverse mode. + */ + boolean isReverseModeEnabled(); + }; + + /** + * Establish if a reverse-resume operation is allowed on the specified context. + * + * @param context The thread or process on which the reverse operation will apply + * @param rm Will contain the result of the operation, true or false, not null. + */ void canReverseResume(IExecutionDMContext context, DataRequestMonitor rm); + + /** + * Perform a reverse-resume operation on the specified context. + * + * @param context The thread or process on which the reverse operation will apply + */ void reverseResume(IExecutionDMContext context, RequestMonitor requestMonitor); + + /** + * Returns whether a reverse-step operation is on-going for the specified context. + * + * @param context The thread or process on which the reverse operation will apply + * @return True if a reverse-steop operation is on-going, false otherwise. + */ boolean isReverseStepping(IExecutionDMContext context); + + /** + * Establish if a reverse-step operation is allowed on the specified context. + * + * @param context The thread or process on which the reverse operation will apply + * @param rm Will contain the result of the operation, true or false, not null. + */ void canReverseStep(IExecutionDMContext context, StepType stepType, DataRequestMonitor rm); + + /** + * Perform a reverse-step operation on the specified context with the specified step type. + * + * @param context The thread or process on which the reverse operation will apply + * @param stepType The step type to be used for the operation + */ void reverseStep(IExecutionDMContext context, StepType stepType, RequestMonitor requestMonitor); + /** + * Establish if it is possible to enable reverse debugging. + * + * @param rm Will contain the result of the operation, true or false, not null. + */ void canEnableReverseMode(ICommandControlDMContext context, DataRequestMonitor rm); + + /** + * Establish if reverse debugging is enabled. + * + * @param rm Will contain the result of the operation, true or false, not null. + */ void isReverseModeEnabled(ICommandControlDMContext context, DataRequestMonitor rm); + + /** + * Enable or disable reverse debugging based on the enable parameter. + * + * @param enable True if reverse debugging should enabled, false for disabled. + */ void enableReverseMode(ICommandControlDMContext context, boolean enable, RequestMonitor rm); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java index f75beaa1628..67cc4f3da5f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java @@ -34,6 +34,7 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.ICachingService; import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent; import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress; import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.cdt.dsf.debug.service.IMemory; @@ -92,7 +93,8 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer // Map of memory caches private Map fMemoryCaches; - private MIMemoryCache getMemoryCache(IMemoryDMContext memoryDMC) { + /** @since 4.2 */ + protected MIMemoryCache getMemoryCache(IMemoryDMContext memoryDMC) { MIMemoryCache cache = fMemoryCaches.get(memoryDMC); if (cache == null) { cache = new MIMemoryCache(); @@ -490,12 +492,19 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer } } - /** - * @nooverride This method is not intended to be re-implemented or extended by clients. - * @noreference This method is not intended to be referenced by clients. - */ - @DsfServiceEventHandler + /** + * @deprecated Replaced by the generic {@link #eventDispatched(IExpressionChangedDMEvent)} + */ + @Deprecated public void eventDispatched(ExpressionChangedEvent e) { + } + + /** + * @noreference This method is not intended to be referenced by clients. + * @since 4.2 + */ + @DsfServiceEventHandler + public void eventDispatched(IExpressionChangedDMEvent e) { // Get the context and expression service handle final IExpressionDMContext context = e.getDMContext(); @@ -518,7 +527,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer address = new Addr64(expAddress.getValue()); final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class); - getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, 1, count, + getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, 1, count, true, new RequestMonitor(getExecutor(), null)); } }); @@ -629,7 +638,8 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer // MIMemoryCache /////////////////////////////////////////////////////////////////////////// - private class MIMemoryCache { + /** @since 4.2 */ + protected class MIMemoryCache { // The memory cache data structure private SortedMemoryBlockList fMemoryBlockList; @@ -965,10 +975,12 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer * @param offset * @param word_size * @param count + * @param sendMemoryEvent Indicates if a IMemoryChangedEvent should be sent if the memory cache has changed. * @param rm */ public void refreshMemory(final IMemoryDMContext memoryDMC, final IAddress address, - final long offset, final int word_size, final int count, final RequestMonitor rm) + final long offset, final int word_size, final int count, final boolean sendMemoryEvent, + final RequestMonitor rm) { // Check if we already cache part of this memory area (which means it // is used by a memory service client that will have to be updated) @@ -983,16 +995,10 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer rm.done(); return; } - - // Prepare the data for the MemoryChangedEvent - final IAddress[] addresses = new IAddress[count]; - for (int i = 0; i < count; i++) { - addresses[i] = address.add(i); - } // Read the corresponding memory block fCommandCache.reset(); - readMemoryBlock(memoryDMC, address, 0, 1, count, + readMemoryBlock(memoryDMC, address, offset, word_size, count, new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleSuccess() { @@ -1006,8 +1012,15 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer } } if (blocksDiffer) { - updateMemoryCache(address, count, newBlock); - getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties()); + updateMemoryCache(address.add(offset), count, newBlock); + if (sendMemoryEvent) { + // Send the MemoryChangedEvent + final IAddress[] addresses = new IAddress[count]; + for (int i = 0; i < count; i++) { + addresses[i] = address.add(offset + i); + } + getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties()); + } } rm.done(); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInfoOsInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInfoOsInfo.java index 9c9f5191812..abb4337cc1d 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInfoOsInfo.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInfoOsInfo.java @@ -14,9 +14,8 @@ package org.eclipse.cdt.dsf.mi.service.command.output; import java.util.ArrayList; import java.util.List; -import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2; -import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; -import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2.IResourceClass; +import org.eclipse.cdt.dsf.gdb.service.IGDBHardwareAndOS2.IResourcesInformation; /** * Example output: @@ -63,7 +62,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput; public class MIInfoOsInfo extends MIInfo { // The fields below are used for response with list of classes. - private IGDBHardwareAndOS2.IResourceClass[] resourceClasses; + private IResourceClass[] resourceClasses; // The below fields are used only for data with specific resource class private String[] columnNames; @@ -79,9 +78,9 @@ public class MIInfoOsInfo extends MIInfo { } } - public IGDBHardwareAndOS2.IResourcesInformation getResourcesInformation() + public IResourcesInformation getResourcesInformation() { - return new IGDBHardwareAndOS2.IResourcesInformation() { + return new IResourcesInformation() { @Override public String[][] getContent() { return content; } @@ -91,14 +90,14 @@ public class MIInfoOsInfo extends MIInfo { }; } - public IGDBHardwareAndOS2.IResourceClass[] getResourceClasses() + public IResourceClass[] getResourceClasses() { return resourceClasses; } private void parseResourceClasses() { - List classes = new ArrayList(); + List classes = new ArrayList(); MITuple table = (MITuple)get(getMIOutput(), "OSDataTable"); //$NON-NLS-1$ @@ -109,7 +108,7 @@ public class MIInfoOsInfo extends MIInfo { final String id = getString(row.getMIResults()[0]); final String description = getString(row.getMIResults()[2]); - classes.add(new IGDBHardwareAndOS2.IResourceClass() { + classes.add(new IResourceClass() { @Override public String getId() { return id; } @@ -120,7 +119,7 @@ public class MIInfoOsInfo extends MIInfo { }); } - resourceClasses = classes.toArray(new IGDBHardwareAndOS2.IResourceClass[classes.size()]); + resourceClasses = classes.toArray(new IResourceClass[classes.size()]); } private void parseResourcesInformation() diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/data/launch/src/ConsoleSyncTestApp.cc b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/data/launch/src/ConsoleSyncTestApp.cc new file mode 100644 index 00000000000..2e858e5dd12 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/data/launch/src/ConsoleSyncTestApp.cc @@ -0,0 +1,15 @@ +#include + +int testMemoryChanges() { + int i = 8; + + return i; +} + +int main() { + printf("Running ConsoleSyncTestApp\n"); + + testMemoryChanges(); + + return 0; +} diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/SyncUtil.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/SyncUtil.java index fb078685198..c6b5f0c0e84 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/SyncUtil.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/framework/SyncUtil.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.dsf.debug.service.IExpressions; import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.cdt.dsf.debug.service.IFormattedValues; import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData; import org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext; import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext; @@ -432,6 +433,26 @@ public class SyncUtil { return fSession.getExecutor().submit(callable).get(); } + public static String getExpressionValue(final IExpressionDMContext exprDmc, final String format) + throws Throwable { + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + FormattedValueDMContext valueDmc = fExpressions.getFormattedValueContext(exprDmc, format); + fExpressions.getFormattedExpressionValue(valueDmc, + new ImmediateDataRequestMonitor(rm) { + @Override + protected void handleSuccess() { + rm.done(getData().getFormattedValue()); + } + }); + } + }; + + fSession.getExecutor().execute(query); + return query.get(); + } + public static FormattedValueDMContext getFormattedValue( final IFormattedValues service, final IFormattedDataDMContext dmc, final String formatId) throws Throwable { diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchUtilsTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchUtilsTest.java index 7b912de703e..798eb125af8 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchUtilsTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchUtilsTest.java @@ -10,17 +10,17 @@ *******************************************************************************/ package org.eclipse.cdt.tests.dsf.gdb.tests; +import static org.junit.Assert.assertEquals; + import java.util.HashMap; import java.util.Map; -import junit.framework.TestCase; - import org.eclipse.cdt.dsf.gdb.launching.LaunchUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; -public class LaunchUtilsTest extends TestCase { +public class LaunchUtilsTest { @Before public void init() { @@ -31,7 +31,7 @@ public class LaunchUtilsTest extends TestCase { } @Test - public void testGetGDBVersionFromText() { + public void tesetGDBVersionFromText() { Map versions = new HashMap(10); versions.put("GNU gdb 6.8.50.20080730", "6.8.50.20080730"); diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/GDBConsoleSynchronizingTest_7_6.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/GDBConsoleSynchronizingTest_7_6.java new file mode 100644 index 00000000000..14eeaa21486 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/GDBConsoleSynchronizingTest_7_6.java @@ -0,0 +1,482 @@ +/******************************************************************************* + * Copyright (c) 2013 Ericsson 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: + * Marc Khouzam (Ericsson) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_6; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.debug.service.IExpressions; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress; +import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.cdt.dsf.debug.service.IFormattedValues; +import org.eclipse.cdt.dsf.debug.service.IMemory; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl; +import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; +import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl; +import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl.IReverseModeChangedDMEvent; +import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; +import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner; +import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase; +import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil; +import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin; +import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants; +import org.eclipse.debug.core.model.MemoryByte; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * This test case verifies that different commands issued from the + * GDB console cause proper updating within the CDT views. + */ +@RunWith(BackgroundRunner.class) +public class GDBConsoleSynchronizingTest_7_6 extends BaseTestCase { + + final static private int DEFAULT_TIMEOUT = 1000; + final static private TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS; + + private DsfSession fSession; + private DsfServicesTracker fServicesTracker; + private IGDBControl fCommandControl; + private IMemory fMemoryService; + private IExpressions fExprService; + private IRunControl fRunControl; + + private List> fEventsReceived = new ArrayList>(); + + @Override + protected void setGdbVersion() { + setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_6); + } + + @Override + protected void setLaunchAttributes() { + super.setLaunchAttributes(); + + setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "data/launch/bin/ConsoleSyncTestApp.exe"); + } + + @Override + public void doBeforeTest() throws Exception { + super.doBeforeTest(); + + fSession = getGDBLaunch().getSession(); + Runnable runnable = new Runnable() { + @Override + public void run() { + fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId()); + Assert.assertTrue(fServicesTracker != null); + + fCommandControl = fServicesTracker.getService(IGDBControl.class); + Assert.assertTrue(fCommandControl != null); + + fMemoryService = fServicesTracker.getService(IMemory.class); + Assert.assertTrue(fMemoryService != null); + + fExprService = fServicesTracker.getService(IExpressions.class); + Assert.assertTrue(fExprService != null); + + fRunControl = fServicesTracker.getService(IRunControl.class); + Assert.assertTrue(fRunControl != null); + + // Register to breakpoint events + fSession.addServiceEventListener(GDBConsoleSynchronizingTest_7_6.this, null); + } + }; + fSession.getExecutor().submit(runnable).get(); + } + + @Override + public void doAfterTest() throws Exception { + Runnable runnable = new Runnable() { + @Override + public void run() { + fSession.removeServiceEventListener(GDBConsoleSynchronizingTest_7_6.this); + } + }; + fSession.getExecutor().submit(runnable).get(); + fEventsReceived.clear(); + fServicesTracker.dispose(); + super.doAfterTest(); + } + + ////////////////////////////////////////////////////////////////////////////////////// + // Start of tests + ////////////////////////////////////////////////////////////////////////////////////// + + /** + * This test verifies that setting a variable from the console + * using the set command will properly trigger a DSF event to + * indicate the change. This test makes sure the value that + * changes is in the memory cache also. + */ + @Test + public void testSettingVariableWithSetWithMemory() throws Throwable { + MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testMemoryChanges"); + + final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); + final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, "i"); + + // Read the memory that will change first, or else there will be no event for it + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + fExprService.getExpressionAddressData(exprDmc, rm); + } + }; + + fSession.getExecutor().execute(query); + IExpressionDMAddress data = query.get(); + + IMemoryDMContext memoryDmc = DMContexts.getAncestorOfType(frameDmc, IMemoryDMContext.class); + readMemory(memoryDmc, data.getAddress(), 1); + + fEventsReceived.clear(); + + final String newValue = "100"; + queueConsoleCommand("set variable i=" + newValue); + + IMemoryChangedEvent memoryEvent = waitForEvent(IMemoryChangedEvent.class); + assertEquals(1, memoryEvent.getAddresses().length); + assertEquals(data.getAddress(), memoryEvent.getAddresses()[0]); + + // Now verify the memory service knows the new memory value + MemoryByte[] memory = readMemory(memoryDmc, data.getAddress(), 1); + assertEquals(newValue, Byte.toString(memory[0].getValue())); + + // Now verify the expressions service knows the new value + String exprValue = SyncUtil.getExpressionValue(exprDmc, IFormattedValues.DECIMAL_FORMAT); + assertEquals(newValue, exprValue); + } + + /** + * This test verifies that setting a variable from the console + * using the set command will properly trigger a DSF event to + * indicate the change, when the address is not in the memory cache. + */ + @Test + public void testSettingVariableWithSet() throws Throwable { + MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testMemoryChanges"); + + final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); + final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, "i"); + + // Read the memory that will change first, or else there will be no event for it + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + fExprService.getExpressionAddressData(exprDmc, rm); + } + }; + + fSession.getExecutor().execute(query); + IExpressionDMAddress data = query.get(); + + fEventsReceived.clear(); + + final String newValue = "100"; + queueConsoleCommand("set variable i=" + newValue); + + IMemoryChangedEvent memoryEvent = waitForEvent(IMemoryChangedEvent.class); + assertEquals(1, memoryEvent.getAddresses().length); + assertEquals(data.getAddress(), memoryEvent.getAddresses()[0]); + + // Now verify the memory service knows the new memory value + IMemoryDMContext memoryDmc = DMContexts.getAncestorOfType(frameDmc, IMemoryDMContext.class); + MemoryByte[] memory = readMemory(memoryDmc, data.getAddress(), 1); + assertEquals(newValue, Byte.toString(memory[0].getValue())); + + // Now verify the expressions service knows the new value + String exprValue = SyncUtil.getExpressionValue(exprDmc, IFormattedValues.DECIMAL_FORMAT); + assertEquals(newValue, exprValue); + } + + /** + * This test verifies that setting a variable from the console + * using the print command will properly trigger a DSF event + * to indicate the change. + */ + @Test + public void testSettingVariableWithPrint() throws Throwable { + MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testMemoryChanges"); + + final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); + final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, "i"); + + // Read the memory that will change first, or else there will be no event for it + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + fExprService.getExpressionAddressData(exprDmc, rm); + } + }; + + fSession.getExecutor().execute(query); + IExpressionDMAddress data = query.get(); + + fEventsReceived.clear(); + + final String newValue = "100"; + queueConsoleCommand("print i=" + newValue); + + IMemoryChangedEvent memoryEvent = waitForEvent(IMemoryChangedEvent.class); + assertEquals(1, memoryEvent.getAddresses().length); + assertEquals(data.getAddress(), memoryEvent.getAddresses()[0]); + + // Now verify the memory service knows the new memory value + IMemoryDMContext memoryDmc = DMContexts.getAncestorOfType(frameDmc, IMemoryDMContext.class); + MemoryByte[] memory = readMemory(memoryDmc, data.getAddress(), 1); + assertEquals(newValue, Byte.toString(memory[0].getValue())); + + // Now verify the expressions service knows the new value + String exprValue = SyncUtil.getExpressionValue(exprDmc, IFormattedValues.DECIMAL_FORMAT); + assertEquals(newValue, exprValue); + } + + /** + * This test verifies that setting a memory location from the + * console will properly trigger a DSF event to indicate the change. + */ + @Test + public void testSettingMemory() throws Throwable { + MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testMemoryChanges"); + + final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0); + final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, "i"); + + // Read the memory that will change first, or else there will be no event for it + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + fExprService.getExpressionAddressData(exprDmc, rm); + } + }; + + fSession.getExecutor().execute(query); + IExpressionDMAddress data = query.get(); + + fEventsReceived.clear(); + + final String newValue = "100"; + queueConsoleCommand("set {int}&i=" + newValue); + + IMemoryChangedEvent memoryEvent = waitForEvent(IMemoryChangedEvent.class); + assertEquals(1, memoryEvent.getAddresses().length); + assertEquals(data.getAddress(), memoryEvent.getAddresses()[0]); + + // Now verify the memory service knows the new memory value + IMemoryDMContext memoryDmc = DMContexts.getAncestorOfType(frameDmc, IMemoryDMContext.class); + MemoryByte[] memory = readMemory(memoryDmc, data.getAddress(), 1); + assertEquals(newValue, Byte.toString(memory[0].getValue())); + + // Now verify the expressions service knows the new value + String exprValue = SyncUtil.getExpressionValue(exprDmc, IFormattedValues.DECIMAL_FORMAT); + assertEquals(newValue, exprValue); + } + + /** + * This test verifies that enabling reverse debugging from the + * console will properly trigger a DSF event to indicate the change and + * will be processed by the service. + */ + @Test + public void testEnableRecord() throws Throwable { + assertTrue("Reverse debugging is not supported", fRunControl instanceof IReverseRunControl); + final IReverseRunControl reverseService = (IReverseRunControl)fRunControl; + + SyncUtil.runToLocation("testMemoryChanges"); + + // check starting state + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm); + } + }; + + fSession.getExecutor().execute(query); + Boolean enabled = query.get(); + assertTrue("Reverse debugging should not be enabled", !enabled); + + fEventsReceived.clear(); + + queueConsoleCommand("record"); + + // Wait for the event + IReverseModeChangedDMEvent event = waitForEvent(IReverseModeChangedDMEvent.class); + assertEquals(true, event.isReverseModeEnabled()); + + // Check the service + query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm); + } + }; + fSession.getExecutor().execute(query); + enabled = query.get(); + assertTrue("Reverse debugging should be enabled", enabled); + } + + /** + * This test verifies that disabling reverse debugging from the + * console will properly trigger a DSF event to indicate the change and + * will be processed by the service. + */ + @Test + public void testDisableRecord() throws Throwable { + assertTrue("Reverse debugging is not supported", fRunControl instanceof IReverseRunControl); + final IReverseRunControl reverseService = (IReverseRunControl)fRunControl; + + SyncUtil.runToLocation("testMemoryChanges"); + + fEventsReceived.clear(); + + // check starting state + Query query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + reverseService.enableReverseMode(fCommandControl.getContext(), true, + new ImmediateRequestMonitor(rm) { + @Override + protected void handleSuccess() { + reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm); + } + }); + } + }; + + fSession.getExecutor().execute(query); + Boolean enabled = query.get(); + assertTrue("Reverse debugging should be enabled", enabled); + + // Wait for the event to avoid confusing it with the next one + IReverseModeChangedDMEvent event = waitForEvent(IReverseModeChangedDMEvent.class); + assertEquals(true, event.isReverseModeEnabled()); + fEventsReceived.clear(); + + queueConsoleCommand("record stop"); + + // Wait for the event + event = waitForEvent(IReverseModeChangedDMEvent.class); + assertEquals(false, event.isReverseModeEnabled()); + + // Check the service + query = new Query() { + @Override + protected void execute(final DataRequestMonitor rm) { + reverseService.isReverseModeEnabled(fCommandControl.getContext(), rm); + } + }; + fSession.getExecutor().execute(query); + enabled = query.get(); + assertTrue("Reverse debugging should not be enabled", !enabled); + } + + ////////////////////////////////////////////////////////////////////////////////////// + // End of tests + ////////////////////////////////////////////////////////////////////////////////////// + + @DsfServiceEventHandler + public void eventDispatched(IDMEvent e) { + synchronized(this) { + fEventsReceived.add(e); + notifyAll(); + } + } + + private MemoryByte[] readMemory(final IMemoryDMContext dmc, final IAddress address, final int count) + throws Throwable + { + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fMemoryService.getMemory(dmc, address, 0, 1, count, rm); + } + }; + fSession.getExecutor().execute(query); + return query.get(DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT); + } + + private void queueConsoleCommand(String command) throws Throwable { + queueConsoleCommand(command, DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT); + } + + private void queueConsoleCommand(final String command, int timeout, TimeUnit unit) throws Throwable { + Query query = new Query() { + @Override + protected void execute(DataRequestMonitor rm) { + fCommandControl.queueCommand( + fCommandControl.getCommandFactory().createMIInterpreterExecConsole( + fCommandControl.getContext(), + command), + rm); + } + }; + fSession.getExecutor().execute(query); + query.get(timeout, unit); + } + + private > V waitForEvent(Class eventType) throws Exception { + return waitForEvent(eventType, DEFAULT_TIMEOUT); + } + + @SuppressWarnings("unchecked") + private > V waitForEvent(Class eventType, int timeout) throws Exception { + IDMEvent event = getEvent(eventType); + if (event == null) { + synchronized(this) { + try { + wait(timeout); + } + catch (InterruptedException ex) { + } + } + event = getEvent(eventType); + if (event == null) { + throw new Exception(String.format("Timed out waiting for '%s' to occur.", eventType.getName())); + } + } + return (V)event; + } + + @SuppressWarnings("unchecked") + private synchronized > V getEvent(Class eventType) { + for (IDMEvent e : fEventsReceived) { + if (eventType.isAssignableFrom(e.getClass())) { + fEventsReceived.remove(e); + return (V)e; + } + } + return null; + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_7_6.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_7_6.java index 983dc915d30..0e364d79885 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_7_6.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_7_6.java @@ -48,6 +48,7 @@ import org.junit.runners.Suite; GDBMultiNonStopRunControlTest_7_6.class, Suite_Sessionless_Tests.class, GDBConsoleBreakpointsTest_7_6.class, + GDBConsoleSynchronizingTest_7_6.class, /* Add your test class here */ }) diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_Remote_7_6.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_Remote_7_6.java index aa3edd8421e..fc54dbfa84f 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_Remote_7_6.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_6/Suite_Remote_7_6.java @@ -49,6 +49,7 @@ import org.junit.runners.Suite; Suite_Sessionless_Tests.class, GDBConsoleBreakpointsTest_7_6.class, TraceFileTest_7_6.class, + GDBConsoleSynchronizingTest_7_6.class, /* Add your test class here */ }) diff --git a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF index 25dadc0dba0..3050f5a8653 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF @@ -18,7 +18,9 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.5.0", org.eclipse.ui.ide;bundle-version="3.5.0", org.eclipse.cdt.ui;bundle-version="5.1.0", org.eclipse.core.expressions;bundle-version="3.4.0", - org.eclipse.core.filesystem;bundle-version="1.2.0" + org.eclipse.core.filesystem;bundle-version="1.2.0", + org.eclipse.debug.core, + org.eclipse.core.resources Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.dsf.debug.internal.ui;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.actions;x-internal:=true, diff --git a/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF index 91aa88e256d..62acb0a310a 100644 --- a/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF @@ -9,7 +9,8 @@ Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.debug.core, org.eclipse.cdt.core, - org.eclipse.cdt.debug.core + org.eclipse.cdt.debug.core, + org.eclipse.core.resources Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.dsf.concurrent, org.eclipse.cdt.dsf.datamodel, diff --git a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/editor/AnnotationHover.java b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/editor/AnnotationHover.java index ed2087c56cc..ae91bb7855f 100644 --- a/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/editor/AnnotationHover.java +++ b/dsf/org.eclipse.cdt.examples.dsf.pda.ui/src/org/eclipse/cdt/examples/dsf/pda/ui/editor/AnnotationHover.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 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) 2005, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation * Wind River Systems - adopted to use with DSF @@ -46,5 +46,4 @@ public class AnnotationHover implements IAnnotationHover { } return null; } - } diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java index ee669909627..84d603e782c 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java @@ -21,9 +21,9 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IScope; 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.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; @SuppressWarnings("restriction") @@ -114,38 +114,10 @@ public class C99Enumeration extends PlatformObject implements IC99Binding, IEnum } public long getMinValue() { - long minValue = Long.MAX_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v < minValue) { - minValue = v; - } - } - } - } - return minValue; + return SemanticUtil.computeMinValue(this); } public long getMaxValue() { - long maxValue = Long.MIN_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v > maxValue) { - maxValue = v; - } - } - } - } - return maxValue; + return SemanticUtil.computeMaxValue(this); } } diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java index 99603893503..1fd1a5e0533 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/CPreprocessorAdapter.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2006, 2009 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) 2006, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.lrparser; @@ -25,7 +25,6 @@ import org.eclipse.cdt.core.parser.OffsetLimitReachedException; * TODO move into an internal package */ public class CPreprocessorAdapter { - /** * During content assist the preprocessor may return a completion token * which represents the identifier on which the user invoked content assist. diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GCCLanguage.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GCCLanguage.java index 8fdc058e0ea..da00102ddd7 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GCCLanguage.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GCCLanguage.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2006, 2009 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) 2006, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.lrparser.gnu; @@ -31,7 +31,6 @@ import org.eclipse.cdt.internal.core.dom.lrparser.gcc.GCCParser; * @author Mike Kucera */ public class GCCLanguage extends BaseExtensibleLanguage { - public static final String ID = "org.eclipse.cdt.core.lrparser.gcc"; //$NON-NLS-1$ private static GCCLanguage DEFAULT = new GCCLanguage(); diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GPPLanguage.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GPPLanguage.java index d44bec922c7..09352219234 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GPPLanguage.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/gnu/GPPLanguage.java @@ -1,11 +1,11 @@ /******************************************************************************* - * Copyright (c) 2006, 2009 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) 2006, 2009 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: + * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.lrparser.gnu; diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPRules.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPRules.java index 08e56e52b92..6e6d85fd50d 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPRules.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPRules.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2008 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) 2008 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 Corporation - initial API and implementation + * Contributors: + * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.lrparser.cpp; @@ -18,7 +18,6 @@ public class CPPRules { static Map fRules = new HashMap(); static { - fRules.put(Integer.valueOf(3), "] ::= RightBracket"); fRules.put(Integer.valueOf(4), "] ::= EndOfCompletion"); fRules.put(Integer.valueOf(5), ") ::= RightParen"); diff --git a/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF b/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF index b4ca9e8d545..b014adcf875 100644 --- a/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF +++ b/qt/org.eclipse.cdt.qt.core/META-INF/MANIFEST.MF @@ -11,3 +11,4 @@ Require-Bundle: org.eclipse.core.runtime, Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Bundle-Localization: plugin +Export-Package: org.eclipse.cdt.qt.core diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtKeywords.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtKeywords.java new file mode 100644 index 00000000000..36b2112585d --- /dev/null +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/QtKeywords.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2013 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 + */ + +package org.eclipse.cdt.qt.core; + +/** + * Declares constants related to tokens that are special in Qt applications. + */ +public class QtKeywords +{ + public static final String Q_SIGNALS = "Q_SIGNALS"; + public static final String Q_SLOTS = "Q_SLOTS"; + public static final String SIGNALS = "signals"; + public static final String SLOTS = "slots"; +} diff --git a/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF b/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF index 50e19770980..0e024d23ae1 100644 --- a/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF +++ b/qt/org.eclipse.cdt.qt.ui/META-INF/MANIFEST.MF @@ -1,11 +1,15 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: CDT Qt Support UI -Bundle-SymbolicName: org.eclipse.cdt.qt.ui +Bundle-SymbolicName: org.eclipse.cdt.qt.ui;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.eclipse.cdt.qt.ui.Activator Bundle-Vendor: Eclipse CDT +Bundle-Localization: plugin Require-Bundle: org.eclipse.ui, - org.eclipse.core.runtime + org.eclipse.core.runtime, + org.eclipse.cdt.ui, + org.eclipse.cdt.core, + org.eclipse.cdt.qt.core Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy diff --git a/qt/org.eclipse.cdt.qt.ui/build.properties b/qt/org.eclipse.cdt.qt.ui/build.properties index 34d2e4d2dad..0dc34f7833b 100644 --- a/qt/org.eclipse.cdt.qt.ui/build.properties +++ b/qt/org.eclipse.cdt.qt.ui/build.properties @@ -1,4 +1,6 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - . + .,\ + plugin.xml,\ + plugin.properties diff --git a/qt/org.eclipse.cdt.qt.ui/plugin.properties b/qt/org.eclipse.cdt.qt.ui/plugin.properties new file mode 100644 index 00000000000..5f970b962b6 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.ui/plugin.properties @@ -0,0 +1,8 @@ +# Copyright (c) 2013 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 + +qtHighlighting.extName=Qt Semantic Highlighting +qtHighlighting.displayName=Qt Keywords \ No newline at end of file diff --git a/qt/org.eclipse.cdt.qt.ui/plugin.xml b/qt/org.eclipse.cdt.qt.ui/plugin.xml new file mode 100644 index 00000000000..7d86d31f7c4 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.ui/plugin.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtHighlighting.java b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtHighlighting.java new file mode 100644 index 00000000000..3e53db1afc0 --- /dev/null +++ b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/QtHighlighting.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 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 + */ + +package org.eclipse.cdt.internal.qt.ui; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IMacroBinding; +import org.eclipse.cdt.qt.core.QtKeywords; +import org.eclipse.cdt.ui.text.ISemanticHighlighter; +import org.eclipse.cdt.ui.text.ISemanticToken; + +public class QtHighlighting implements ISemanticHighlighter +{ + @Override + public boolean consumes( ISemanticToken token ) + { + IBinding binding = token.getBinding(); + if( binding instanceof IMacroBinding ) + { + IASTNode node = token.getNode(); + if( node instanceof IASTName && ( (IASTName)node ).isReference() ) + { + String n = binding.getName(); + return QtKeywords.SIGNALS.equals( n ) || QtKeywords.SLOTS.equals( n ) + || QtKeywords.Q_SIGNALS.equals( n ) || QtKeywords.Q_SLOTS.equals( n ); + } + } + + return false; + } +} diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerViewer.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerViewer.java index a9c71c2d1b3..344e3cddf94 100644 --- a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerViewer.java +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/VisualizerViewer.java @@ -7,6 +7,7 @@ * * Contributors: * William R. Swanson (Tilera Corporation) + * Marc Dumais (Ericsson) - Bug 399281 *******************************************************************************/ package org.eclipse.cdt.visualizer.ui; @@ -29,6 +30,8 @@ import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MenuDetectEvent; import org.eclipse.swt.events.MenuDetectListener; import org.eclipse.swt.events.PaintEvent; @@ -97,6 +100,13 @@ public class VisualizerViewer extends PageBook public VisualizerViewer(VisualizerView view, Composite parent) { super(parent, SWT.NONE); initVisualizerViewer(view, parent); + // so we're notified when the widget is disposed + addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + dispose(); + } + }); } /** Dispose method. */ @@ -431,7 +441,9 @@ public class VisualizerViewer extends PageBook /** Removes external listener for selection change events. */ public void removeSelectionChangedListener(ISelectionChangedListener listener) { - m_selectionManager.removeSelectionChangedListener(listener); + if(m_selectionManager != null) { + m_selectionManager.removeSelectionChangedListener(listener); + } } /** Raises selection changed event. */ diff --git a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java index b4f2778cef4..e2112ab95fd 100755 --- a/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java +++ b/visualizer/org.eclipse.cdt.visualizer.ui/src/org/eclipse/cdt/visualizer/ui/canvas/BufferedCanvas.java @@ -7,6 +7,7 @@ * * Contributors: * William R. Swanson (Tilera Corporation) + * Marc Dumais (Ericsson) - Bug 399281 *******************************************************************************/ package org.eclipse.cdt.visualizer.ui.canvas; @@ -68,8 +69,10 @@ public class BufferedCanvas extends Canvas /** Cleans up control. */ protected void cleanupBufferedCanvas() { - removePaintListener(this); - removeControlListener(this); + if(!this.isDisposed()) { + removePaintListener(this); + removeControlListener(this); + } if (m_doubleBuffer != null) { m_doubleBuffer.dispose(); m_doubleBuffer = null;