1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Merge remote-tracking branch 'cdt/master' into sd90

This commit is contained in:
Andrew Gvozdev 2013-01-06 06:16:54 -05:00
commit 303a22a13e
125 changed files with 4271 additions and 1855 deletions

View file

@ -221,7 +221,7 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser
// appending fileName to cwd should yield file path
filePath = cwd.append(fileName);
}
if (!filePath.toString().equalsIgnoreCase(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()))) {
if (!filePath.toOSString().equalsIgnoreCase(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()))) {
// must be the cwd is wrong
// check if file name starts with ".."
if (fileName.startsWith("..")) { //$NON-NLS-1$

View file

@ -18,6 +18,7 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext;
import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set;
import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
@ -106,6 +107,7 @@ public class CfgScannerConfigProfileManagerTests extends BaseTestCase {
Assert.isTrue("dummyFile".equals(scbi.getBuildOutputFilePath()));
// Test restore defaults
ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(fProject, false);
scbis.applyInfo(cic, null);
// Save the project description
CoreModel.getDefault().setProjectDescription(fProject, prjDesc);

View file

@ -563,7 +563,7 @@ public class ConfigurationDataProvider extends CConfigurationDataProvider implem
private static List<ILanguageSettingsProvider> getDefaultLanguageSettingsProviders(IConfiguration cfg) {
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
String[] ids = cfg.getDefaultLanguageSettingsProviderIds();
String[] ids = cfg != null ? cfg.getDefaultLanguageSettingsProviderIds() : null;
if (ids != null) {
for (String id : ids) {
ILanguageSettingsProvider provider = null;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Gil Barash
* Copyright (c) 2010, 2013 Gil Barash
* 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
@ -116,7 +116,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
if (str.toLowerCase().contains(fNoBreakComment.toLowerCase()))
continue;
}
reportProblem(curr, prevCase);
reportProblem(curr);
}
}
}
@ -159,7 +159,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
}
}
private void reportProblem(IASTStatement curr, IASTStatement prevCase) {
private void reportProblem(IASTStatement curr) {
reportProblem(ER_ID, getProblemLocationAtEndOfNode(curr));
}
@ -218,7 +218,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
super.initPreferences(problem);
addPreference(problem, PARAM_NO_BREAK_COMMENT, CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
DEFAULT_NO_BREAK_COMMENT);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.TRUE);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.FALSE);
addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, Boolean.FALSE);
}

View file

@ -29,34 +29,22 @@ public class CaseBreakQuickFixTest extends QuickFixTestCase {
// break;
// }
//}
public void testMiddleCase() throws Exception {
public void testSimpleCase() throws Exception {
loadcode(getAboveComment());
String result = runQuickFixOneFile();
assertContainedIn("break;\tcase 2:", result);
}
//void func() {
// int a;
// switch(a) {
// case 1:
// hello();
// }
//}
public void testLastCase() throws Exception {
loadcode(getAboveComment());
String result = runQuickFixOneFile();
assertContainedIn("break;\t}", result);
}
//void func() {
// int a;
// switch(a) {
// case 1: {
// hello();
// }
// default:
// }
//}
public void testLastCaseComp() throws Exception {
public void testCompositeStatementCase() throws Exception {
loadcode(getAboveComment());
String result = runQuickFixOneFile();
assertContainedIn("hello();\t\tbreak;", result);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2011 Alena Laskavaia
* Copyright (c) 2009, 2013 Alena Laskavaia
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -417,9 +417,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
IProblem problem = resourceProfile.findProblem(p.getId());
if (problem == null)
throw new IllegalArgumentException(p.getId() + " is not registered"); //$NON-NLS-1$
if (!problem.isEnabled())
return false;
if (checker instanceof AbstractCheckerWithProblemPreferences) {
if (problem.isEnabled() && checker instanceof AbstractCheckerWithProblemPreferences) {
LaunchModeProblemPreference pref =
((AbstractCheckerWithProblemPreferences) checker).getLaunchModePreference(problem);
if (pref.isRunningInMode(mode)) {

View file

@ -11,31 +11,17 @@
*******************************************************************************/
package org.eclipse.cdt.codan.internal.core;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.codan.core.model.CheckerLaunchMode;
import org.eclipse.cdt.codan.core.model.IChecker;
import org.eclipse.cdt.codan.core.model.ICheckerInvocationContext;
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemProfile;
import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
/**
@ -45,7 +31,6 @@ public class CodanRunner {
/** Do not instantiate. All methods are static */
private CodanRunner() {}
/**
* Runs all checkers that support "run as you type" mode.
*
@ -135,71 +120,4 @@ public class CodanRunner {
monitor.done();
}
}
public static void asynchronouslyRemoveMarkersForDisabledProblems(final IResource resource) {
Job job = new Job(Messages.CodanRunner_Update_markers) {
@Override
protected IStatus run(IProgressMonitor monitor) {
removeMarkersForDisabledProblems(resource, monitor);
return Status.OK_STATUS;
}
};
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
job.setRule(ruleFactory.markerRule(resource));
job.setSystem(true);
job.schedule();
}
public static void removeMarkersForDisabledProblems(IResource resource, IProgressMonitor monitor) {
CheckersRegistry chegistry = CheckersRegistry.getInstance();
Set<String> markerTypes = new HashSet<String>();
for (IChecker checker : chegistry) {
Collection<IProblem> problems = chegistry.getRefProblems(checker);
for (IProblem problem : problems) {
markerTypes.add(problem.getMarkerType());
}
}
try {
removeMarkersForDisabledProblems(chegistry, markerTypes, resource, monitor);
} catch (CoreException e) {
CodanCorePlugin.log(e);
}
}
private static void removeMarkersForDisabledProblems(CheckersRegistry chegistry,
Set<String> markerTypes, IResource resource, IProgressMonitor monitor) throws CoreException {
if (!resource.isAccessible()) {
return;
}
IResource[] children = null;
if (resource instanceof IContainer) {
children = ((IContainer) resource).members();
}
int numChildren = children == null ? 0 : children.length;
int childWeight = 10;
SubMonitor progress = SubMonitor.convert(monitor, 1 + numChildren * childWeight);
IProblemProfile resourceProfile = null;
for (String markerType : markerTypes) {
IMarker[] markers = resource.findMarkers(markerType, false, IResource.DEPTH_ZERO);
for (IMarker marker : markers) {
String problemId = (String) marker.getAttribute(ICodanProblemMarker.ID);
if (resourceProfile == null) {
resourceProfile = chegistry.getResourceProfile(resource);
}
IProblem problem = resourceProfile.findProblem(problemId);
if (problem != null && !problem.isEnabled()) {
marker.delete();
}
}
}
progress.worked(1);
if (children != null) {
for (IResource child : children) {
if (monitor.isCanceled())
return;
removeMarkersForDisabledProblems(chegistry, markerTypes, child,
progress.newChild(childWeight));
}
}
}
}

View file

@ -26,7 +26,6 @@ class Messages extends NLS {
public static String CodanApplication_Usage;
public static String CodanApplication_verbose_option;
public static String CodanRunner_Code_analysis_on;
public static String CodanRunner_Update_markers;
static {
NLS.initializeMessages(Messages.class.getName(), Messages.class);

View file

@ -18,4 +18,3 @@ CodanApplication_Options=Options:
CodanApplication_all_option= -all - run on all projects in workspace
CodanApplication_verbose_option= -verbose - print verbose build information
CodanRunner_Code_analysis_on=Code analysis on {0}
CodanRunner_Update_markers=Updating error markers

View file

@ -66,7 +66,7 @@ class CodanPartListener implements IPartListener2 {
}
}
private void processResource(final IResource resource, final CheckerLaunchMode launchMode) {
private static void processResource(final IResource resource, final CheckerLaunchMode launchMode) {
if (resource != null) {
Job job = new Job(NLS.bind(Messages.Startup_AnalyzingFile, resource.getName())) {
@Override

View file

@ -1,5 +1,9 @@
#Sun Feb 27 22:29:21 EST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
@ -18,6 +22,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
@ -25,12 +30,15 @@ org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
@ -39,20 +47,31 @@ org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warni
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=error
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
@ -65,7 +84,8 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin
org.eclipse.jdt.core.compiler.problem.unusedImport=error
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled

View file

@ -5,17 +5,18 @@ Bundle-SymbolicName: org.eclipse.cdt.codan.ui; singleton:=true
Bundle-Version: 3.2.0.qualifier
Bundle-Activator: org.eclipse.cdt.codan.internal.ui.CodanUIActivator
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.ui.workbench.texteditor,
org.eclipse.cdt.codan.core,
org.eclipse.jface.text,
org.eclipse.ui.ide,
Require-Bundle: org.eclipse.cdt.codan.core,
org.eclipse.cdt.core,
org.eclipse.cdt.ui,
org.eclipse.core.filesystem,
org.eclipse.core.resources,
org.eclipse.core.runtime,
org.eclipse.jface.text,
org.eclipse.ui,
org.eclipse.ui.console,
org.eclipse.ui.editors
org.eclipse.ui.editors,
org.eclipse.ui.ide,
org.eclipse.ui.workbench.texteditor
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.codan.internal.ui;x-friends:="org.eclipse.cdt.codan.ui.cxx",

View file

@ -30,6 +30,7 @@ public class CodanUIMessages extends NLS {
public static String CodanPreferencePage_MessageLabel;
public static String CodanPreferencePage_NoInfo;
public static String CodanPreferencePage_Parameters;
public static String CodanPreferencePage_Update_markers;
public static String ProblemsTreeEditor_NameColumn;
public static String ProblemsTreeEditor_Problems;
public static String ProblemsTreeEditor_SeverityColumn;

View file

@ -22,6 +22,7 @@ CodanPreferencePage_Info=Info
CodanPreferencePage_MessageLabel=Message:
CodanPreferencePage_NoInfo=No description
CodanPreferencePage_Parameters=Parameters:
CodanPreferencePage_Update_markers=Updating error markers
CustomizeProblemComposite_LaunchingTab=Launching
CustomizeProblemComposite_TabParameters=Preferences
CustomizeProblemComposite_TabScope=Scope

View file

@ -8,23 +8,49 @@
* Contributors:
* Alena Laskavaia - initial API and implementation
* Alex Ruiz (Google)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.codan.internal.ui.preferences;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.codan.core.CodanRuntime;
import org.eclipse.cdt.codan.core.model.CheckerLaunchMode;
import org.eclipse.cdt.codan.core.model.IChecker;
import org.eclipse.cdt.codan.core.model.ICheckersRegistry;
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemProfile;
import org.eclipse.cdt.codan.internal.core.CheckersRegistry;
import org.eclipse.cdt.codan.internal.core.CodanRunner;
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
import org.eclipse.cdt.codan.internal.ui.CodanUIMessages;
import org.eclipse.cdt.codan.internal.ui.dialogs.CustomizeProblemDialog;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
import org.eclipse.cdt.ui.ICEditor;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.ResourcesPlugin;
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.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
@ -42,8 +68,13 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
/**
@ -163,7 +194,7 @@ public class CodanPreferencePage extends FieldEditorOverlayPage implements IWork
if (resource == null) {
resource = ResourcesPlugin.getWorkspace().getRoot();
}
CodanRunner.asynchronouslyRemoveMarkersForDisabledProblems(resource);
asynchronouslyUpdateMarkers(resource);
}
return success;
}
@ -215,4 +246,111 @@ public class CodanPreferencePage extends FieldEditorOverlayPage implements IWork
private boolean hasSelectedProblems() {
return selectedProblems != null && !selectedProblems.isEmpty();
}
private static void asynchronouslyUpdateMarkers(final IResource resource) {
final Set<IFile> filesToUpdate = new HashSet<IFile>();
final IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow active = workbench.getActiveWorkbenchWindow();
final IWorkbenchPage page = active.getActivePage();
// Get the files open C/C++ editors.
for (IEditorReference partRef : page.getEditorReferences()) {
IEditorPart editor = partRef.getEditor(false);
if (editor instanceof ICEditor) {
IFile file = (IFile) editor.getEditorInput().getAdapter(IFile.class);
if (file != null && resource.getFullPath().isPrefixOf(file.getFullPath())) {
filesToUpdate.add(file);
}
}
}
Job job = new Job(CodanUIMessages.CodanPreferencePage_Update_markers) {
@Override
protected IStatus run(IProgressMonitor monitor) {
final SubMonitor submonitor = SubMonitor.convert(monitor, 1 + 2 * filesToUpdate.size());
removeMarkersForDisabledProblems(resource, submonitor.newChild(1));
if (filesToUpdate.isEmpty())
return Status.OK_STATUS;
// Run checkers on the currently open files to update the problem markers.
for (final IFile file : filesToUpdate) {
ITranslationUnit tu = CoreModelUtil.findTranslationUnit(file);
if (tu != null) {
tu = CModelUtil.toWorkingCopy(tu);
ASTProvider.getASTProvider().runOnAST(
tu, ASTProvider.WAIT_ACTIVE_ONLY, submonitor.newChild(1),
new ASTRunnable() {
@Override
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
if (ast != null) {
CodanRunner.runInEditor(ast, file, submonitor.newChild(1));
} else {
CodanRunner.processResource(file, CheckerLaunchMode.RUN_ON_FILE_OPEN,
submonitor.newChild(1));
}
return Status.OK_STATUS;
}
});
}
}
return Status.OK_STATUS;
}
};
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
job.setRule(ruleFactory.markerRule(resource));
job.setSystem(true);
job.schedule();
}
private static void removeMarkersForDisabledProblems(IResource resource, IProgressMonitor monitor) {
CheckersRegistry chegistry = CheckersRegistry.getInstance();
Set<String> markerTypes = new HashSet<String>();
for (IChecker checker : chegistry) {
Collection<IProblem> problems = chegistry.getRefProblems(checker);
for (IProblem problem : problems) {
markerTypes.add(problem.getMarkerType());
}
}
try {
removeMarkersForDisabledProblems(chegistry, markerTypes, resource, monitor);
} catch (CoreException e) {
CodanUIActivator.log(e);
}
}
private static void removeMarkersForDisabledProblems(CheckersRegistry chegistry,
Set<String> markerTypes, IResource resource, IProgressMonitor monitor) throws CoreException {
if (!resource.isAccessible()) {
return;
}
IResource[] children = null;
if (resource instanceof IContainer) {
children = ((IContainer) resource).members();
}
int numChildren = children == null ? 0 : children.length;
int childWeight = 10;
SubMonitor progress = SubMonitor.convert(monitor, 1 + numChildren * childWeight);
IProblemProfile resourceProfile = null;
for (String markerType : markerTypes) {
IMarker[] markers = resource.findMarkers(markerType, false, IResource.DEPTH_ZERO);
for (IMarker marker : markers) {
String problemId = (String) marker.getAttribute(ICodanProblemMarker.ID);
if (resourceProfile == null) {
resourceProfile = chegistry.getResourceProfile(resource);
}
IProblem problem = resourceProfile.findProblem(problemId);
if (problem != null && !problem.isEnabled()) {
marker.delete();
}
}
}
progress.worked(1);
if (children != null) {
for (IResource child : children) {
if (monitor.isCanceled())
return;
removeMarkersForDisabledProblems(chegistry, markerTypes, child,
progress.newChild(childWeight));
}
}
}
}

View file

@ -15,7 +15,6 @@ import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.codan.core.param.FileScopeProblemPreference;
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
import org.eclipse.cdt.codan.internal.ui.CodanUIMessages;
import org.eclipse.cdt.codan.internal.ui.dialogs.ExclusionInclusionEntryDialog;
import org.eclipse.cdt.codan.internal.ui.widgets.BasicElementLabels;
@ -33,7 +32,6 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
@ -43,7 +41,6 @@ import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
public class FileScopePreferencePage extends PreferencePage {
private ListDialogField<String> fInclusionPatternList;
@ -106,18 +103,13 @@ public class FileScopePreferencePage extends PreferencePage {
}
private static class ExclusionInclusionLabelProvider extends LabelProvider {
private Image fElementImage;
public ExclusionInclusionLabelProvider(String descriptorPath) {
if (descriptorPath != null) {
ImageDescriptor d = CodanUIActivator.getImageDescriptor(descriptorPath);
}
fElementImage = null; // XXX
}
@Override
public Image getImage(Object element) {
return fElementImage;
return null;
}
@Override
@ -126,10 +118,11 @@ public class FileScopePreferencePage extends PreferencePage {
}
}
private ListDialogField<String> createListContents(FileScopeProblemPreference entryToEdit, String key, String label, String descriptor,
String[] buttonLabels) {
private ListDialogField<String> createListContents(FileScopeProblemPreference entryToEdit,
String key, String label, String descriptor, String[] buttonLabels) {
ExclusionPatternAdapter adapter = new ExclusionPatternAdapter();
ListDialogField<String> patternList = new ListDialogField<String>(adapter, buttonLabels, new ExclusionInclusionLabelProvider(descriptor));
ListDialogField<String> patternList =
new ListDialogField<String>(adapter, buttonLabels, new ExclusionInclusionLabelProvider(descriptor));
patternList.setDialogFieldListener(adapter);
patternList.setLabelText(label);
patternList.enableButton(IDX_EDIT, false);
@ -265,12 +258,6 @@ public class FileScopePreferencePage extends PreferencePage {
return getPattern(fInclusionPatternList);
}
/*
* @see org.eclipse.jface.window.Window#configureShell(Shell)
*/
protected void configureShell(Shell newShell) {
}
private void addMultipleEntries(ListDialogField<String> field) {
String title, message;
if (isExclusion(field)) {
@ -280,7 +267,8 @@ public class FileScopePreferencePage extends PreferencePage {
title = CodanUIMessages.ExclusionInclusionDialog_ChooseInclusionPattern_title;
message = CodanUIMessages.ExclusionInclusionDialog_ChooseInclusionPattern_description;
}
IPath[] res = ExclusionInclusionEntryDialog.chooseExclusionPattern(getShell(), fCurrSourceFolder, title, message, null, true);
IPath[] res = ExclusionInclusionEntryDialog.chooseExclusionPattern(getShell(),
fCurrSourceFolder, title, message, null, true);
if (res != null) {
for (int i = 0; i < res.length; i++) {
field.addElement(res[i].toString());

View file

@ -587,8 +587,8 @@ public class AST2BaseTest extends BaseTestCase {
return problemBinding;
}
public <T extends IBinding> T assertNonProblemOnFirstIdentifier(String section, Class<T> type, Class... cs) {
return assertNonProblem(section, getIdentifierLength(section), type, cs);
public <T extends IBinding> T assertNonProblemOnFirstIdentifier(String section, Class... cs) {
return assertNonProblem(section, getIdentifierLength(section), cs);
}
public IBinding assertNonProblemOnFirstIdentifier(String section) {
@ -678,7 +678,7 @@ public class AST2BaseTest extends BaseTestCase {
return selector.findImplicitName(offset, len);
}
public <T extends IASTNode> T assertNode(String context, String nodeText, Class<T> type, Class... cs) {
public <T extends IASTNode> T assertNode(String context, String nodeText, Class... cs) {
if (context == null) {
context = contents;
}
@ -688,11 +688,11 @@ public class AST2BaseTest extends BaseTestCase {
assertTrue("Node \"" + nodeText + "\" not found", nodeOffset >= 0);
IASTNodeSelector selector = tu.getNodeSelector(null);
IASTNode node = selector.findNode(offset + nodeOffset, nodeText.length());
return assertType(node, type, cs);
return assertType(node, cs);
}
public <T extends IASTNode> T assertNode(String nodeText, Class<T> type, Class... cs) {
return assertNode(contents, nodeText, type, cs);
public <T extends IASTNode> T assertNode(String nodeText, Class... cs) {
return assertNode(contents, nodeText, cs);
}
private String renderProblemID(int i) {
@ -713,31 +713,30 @@ public class AST2BaseTest extends BaseTestCase {
return "Unknown problem ID";
}
public <T extends IBinding> T assertNonProblem(String section, int len, Class<T> type, Class... cs) {
public <T extends IBinding> T assertNonProblem(String section, int len, Class... cs) {
if (len <= 0)
len += section.length();
IBinding binding= binding(section, len);
assertTrue("ProblemBinding for name: " + section.substring(0, len),
!(binding instanceof IProblemBinding));
return assertType(binding, type, cs);
return assertType(binding, cs);
}
public <T extends IBinding> T assertNonProblem(String section, Class<T> type, Class... cs) {
return assertNonProblem(section, section.length(), type, cs);
public <T extends IBinding> T assertNonProblem(String section, Class... cs) {
return assertNonProblem(section, section.length(), cs);
}
public <T extends IBinding> T assertNonProblem(String context, String name, Class<T> type, Class... cs) {
public <T extends IBinding> T assertNonProblem(String context, String name, Class... cs) {
IBinding binding= binding(context, name);
assertTrue("ProblemBinding for name: " + name, !(binding instanceof IProblemBinding));
return assertType(binding, type, cs);
return assertType(binding, cs);
}
public <T, U extends T> U assertType(T obj, Class<U> type, Class... cs) {
assertInstance(obj, type);
public <T, U extends T> U assertType(T obj, Class... cs) {
for (Class c : cs) {
assertInstance(obj, c);
}
return type.cast(obj);
return (U) obj;
}
private IBinding binding(String section, int len) {

View file

@ -261,6 +261,7 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals(defNames.length, j);
}
@Override
protected void assertSameType(IType first, IType second){
assertNotNull(first);
assertNotNull(second);
@ -8404,6 +8405,7 @@ public class AST2CPPTests extends AST2BaseTest {
// }
// struct A {};
// A a;
// auto c(a);
// auto b = a;
// const auto *p = &b, q = "";
// static auto d = 0.0;
@ -8417,6 +8419,8 @@ public class AST2CPPTests extends AST2BaseTest {
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPVariable b= bh.assertNonProblem("b =", 1);
assertEquals("A", ASTTypeUtil.getType(b.getType()));
ICPPVariable c= bh.assertNonProblem("c(a)", "c");
assertEquals("A", ASTTypeUtil.getType(c.getType()));
ICPPVariable p= bh.assertNonProblem("p =", 1);
assertEquals("const A *", ASTTypeUtil.getType(p.getType()));
ICPPVariable q= bh.assertNonProblem("q =", 1);
@ -10079,4 +10083,42 @@ public class AST2CPPTests extends AST2BaseTest {
helper.assertNonProblemOnFirstIdentifier("fint({vbool");
helper.assertNonProblemOnFirstIdentifier("fint({vchar");
}
// namespace std {
// struct string {};
// struct exception {};
// }
// void f(){}
//
// int problemA(int i) {
// return i ? throw 7 : i;
// }
// int problemB(int i) {
// return i ? throw std::string{} : i;
// }
// void ploblemC(int i) {
// return i ? throw std::exception() : throw 3;
// }
// void ploblemD(int i) {
// return i ? throw std::exception() : f();
// }
// std::string ploblemE(int i) {
// return i ? throw 3 : "a";
// }
// std::string ploblemF(int i) {
// return (i<2 ? throw 2 : "x") ? (i>2 ? throw 3 : "d") : (i>22 ? throw 4 : "e");
// }
// auto ploblemG(int i) ->decltype(i ? throw 3 : "d"){
// return i ? throw 3 : "d" ;
// }
// void fine1(int i) {
// return i ? f() : f();
// }
// std::string fine2(int i) {
// return i ? "a" : "b";
// }
public void testThrowExpressionInConditional_396663() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
}

View file

@ -4692,7 +4692,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// a= b ? : c;
// }
public void testOmittedPositiveExpression_Bug212905() throws Exception {
public void testOmittedPositiveExpression_212905() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -4703,7 +4703,7 @@ public class AST2Tests extends AST2BaseTest {
// static __inline__ __u32 f(int x) {
// return x;
// }
public void testRedefinedGCCKeywords_Bug226112() throws Exception {
public void testRedefinedGCCKeywords_226112() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4711,7 +4711,7 @@ public class AST2Tests extends AST2BaseTest {
// int foo asm ("myfoo") __attribute__((__used__)), ff asm("ss") = 2;
// extern void func () asm ("FUNC") __attribute__((__used__));
public void testASMLabels_Bug226121() throws Exception {
public void testASMLabels_226121() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4720,7 +4720,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// ({1;}) != 0;
// }
public void testCompoundStatementExpression_Bug226274() throws Exception {
public void testCompoundStatementExpression_226274() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4730,7 +4730,7 @@ public class AST2Tests extends AST2BaseTest {
// __typeof__(count) a= 1;
// int ret0 = ((__typeof__(count)) 1);
// }
public void testTypeofUnaryExpression_Bug226492() throws Exception {
public void testTypeofUnaryExpression_226492() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4739,7 +4739,7 @@ public class AST2Tests extends AST2BaseTest {
// void test(int count) {
// typeof(count==1) a= 1;
// }
public void testTypeofExpression_Bug226492() throws Exception {
public void testTypeofExpression_226492() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4748,7 +4748,7 @@ public class AST2Tests extends AST2BaseTest {
// void func() {
// typeof(__attribute__((regparm(3)))void (*)(int *)) a;
// }
public void testTypeofExpressionWithAttribute_Bug226492() throws Exception {
public void testTypeofExpressionWithAttribute_226492() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4759,7 +4759,7 @@ public class AST2Tests extends AST2BaseTest {
// case 1 ... 3: break;
// }
// }
public void testCaseRange_Bug211882() throws Exception {
public void testCaseRange_211882() throws Exception {
final String code = getAboveComment();
{
IASTTranslationUnit tu = parseAndCheckBindings(code, ParserLanguage.C, true);
@ -4786,7 +4786,7 @@ public class AST2Tests extends AST2BaseTest {
// typedef int* TIntPtr;
// int x(int (int * a));
// int x(int(TIntPtr));
public void testInfiniteRecursion_Bug269052() throws Exception {
public void testInfiniteRecursion_269052() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4803,7 +4803,7 @@ public class AST2Tests extends AST2BaseTest {
}
// struct __attribute__((declspec)) bla;
public void testAttributeInElaboratedTypeSpecifier_Bug227085() throws Exception {
public void testAttributeInElaboratedTypeSpecifier_227085() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4811,14 +4811,14 @@ public class AST2Tests extends AST2BaseTest {
// struct X;
// void test(struct X* __restrict result);
public void testRestrictReference_Bug227110() throws Exception {
public void testRestrictReference_227110() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP, true);
}
// char buf[256];
// int x= sizeof(buf)[0];
public void testSizeofUnaryWithParenthesis_Bug227122() throws Exception {
public void testSizeofUnaryWithParenthesis_227122() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -4833,7 +4833,7 @@ public class AST2Tests extends AST2BaseTest {
// void test1() {
// X* it = buffer == 0 ? new (buffer) X : 0;
// }
public void testPlacementNewInConditionalExpression_Bug227104() throws Exception {
public void testPlacementNewInConditionalExpression_227104() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
@ -4910,7 +4910,7 @@ public class AST2Tests extends AST2BaseTest {
// void function2() {
// function1(); // ref
// }
public void testOutOfOrderResolution_Bug232300() throws Exception {
public void testOutOfOrderResolution_232300() throws Exception {
String code= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang);
@ -4924,7 +4924,7 @@ public class AST2Tests extends AST2BaseTest {
// #define foo __typeof__((int*)0 - (int*)0)
// typedef foo ptrdiff_t;
public void testRedefinePtrdiff_Bug230895() throws Exception {
public void testRedefinePtrdiff_230895() throws Exception {
String code= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang);
@ -4958,7 +4958,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// checkLong(__builtin_expect(1, 1));
// }
public void testReturnTypeOfBuiltin_Bug234309() throws Exception {
public void testReturnTypeOfBuiltin_234309() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -4967,7 +4967,7 @@ public class AST2Tests extends AST2BaseTest {
// typedef void VOID;
// VOID func(VOID) {
// }
public void testTypedefVoid_Bug221567() throws Exception {
public void testTypedefVoid_221567() throws Exception {
String code= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang);
@ -4999,7 +4999,7 @@ public class AST2Tests extends AST2BaseTest {
// printf(str(this is a // this should go away
// string));
// }
public void testCommentInExpansion_Bug84276() throws Exception {
public void testCommentInExpansion_84276() throws Exception {
IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment());
IASTFunctionDefinition func= (IASTFunctionDefinition) tu.getDeclarations()[0];
@ -5014,7 +5014,7 @@ public class AST2Tests extends AST2BaseTest {
// int f3(int (tint));
// int f4(int (identifier));
// int f5(int *(tint[10]));
public void testParamWithFunctionType_Bug84242() throws Exception {
public void testParamWithFunctionType_84242() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(comment, lang);
@ -5038,7 +5038,7 @@ public class AST2Tests extends AST2BaseTest {
// class C { };
// void f1(int(C)) { }
public void testParamWithFunctionTypeCpp_Bug84242() throws Exception {
public void testParamWithFunctionTypeCpp_84242() throws Exception {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
IFunction f= ba.assertNonProblem("f1", 2, IFunction.class);
@ -5047,7 +5047,7 @@ public class AST2Tests extends AST2BaseTest {
// int (*f1(int par))[5] {};
// int (*f1 (int par))[5];
public void testFunctionReturningPtrToArray_Bug216609() throws Exception {
public void testFunctionReturningPtrToArray_216609() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), lang);
@ -5122,7 +5122,7 @@ public class AST2Tests extends AST2BaseTest {
// int a,b;
// { b; a; int a; }
// }
public void testLocalVariableResolution_Bug235831() throws Exception {
public void testLocalVariableResolution_235831() throws Exception {
final String comment= getAboveComment();
final boolean[] isCpps= {false, true};
for (ParserLanguage lang: ParserLanguage.values()) {
@ -5138,7 +5138,7 @@ public class AST2Tests extends AST2BaseTest {
}
// int foo(int (*ptr) (int, int));
public void testComplexParameterBinding_Bug214482() throws Exception {
public void testComplexParameterBinding_214482() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang: ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(comment, lang);
@ -5216,7 +5216,7 @@ public class AST2Tests extends AST2BaseTest {
// foux= 0;
// foux= 1;
// }
public void testSwitchWithoutCompound_Bug105334() throws Exception {
public void testSwitchWithoutCompound_105334() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parse(comment, lang);
@ -5251,7 +5251,7 @@ public class AST2Tests extends AST2BaseTest {
// a*a*(t)+a*a*a // a,a,*,t,a,unary+,cast,*,a,*,a,*
// (typeof a)(t)-a // typeof a,t,a,unary-,cast,cast
// (typeof a)(a)-a // typeof a,a,cast,a,-
public void testBinaryVsCastAmbiguities_Bug237057() throws Exception {
public void testBinaryVsCastAmbiguities_237057() throws Exception {
CharSequence[] input= getContents(2);
String code= input[0].toString();
String[] samples= input[1].toString().split("\n");
@ -5291,7 +5291,7 @@ public class AST2Tests extends AST2BaseTest {
// (t)(a)+1 // t,a,cast,1,+
// (f)(a)+1 // f,a,(),1,+
// (t)(t)+1 // t,t,1,unary+,cast,cast
public void testCastVsFunctionCallAmbiguities_Bug237057() throws Exception {
public void testCastVsFunctionCallAmbiguities_237057() throws Exception {
CharSequence[] input= getContents(2);
String code= input[0].toString();
String[] samples= input[1].toString().split("\n");
@ -5488,13 +5488,13 @@ public class AST2Tests extends AST2BaseTest {
// int x;
// } spinlock_t;
// spinlock_t _lock = (spinlock_t) { };
public void testCompoundInitializer_bug145387() throws Exception {
public void testCompoundInitializer_145387() throws Exception {
// valid in C99, not in C++.
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
}
// enum __declspec(uuid("uuid")) bla { a, b};
public void testDeclspecInEnumSpecifier_bug241203() throws Exception {
public void testDeclspecInEnumSpecifier_241203() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
parseAndCheckBindings(getAboveComment(), lang, true);
}
@ -5523,7 +5523,7 @@ public class AST2Tests extends AST2BaseTest {
// if (__builtin_types_compatible_p(typeof(p), char[])) {
// }
// }
public void testBuiltinTypesCompatible_bug241570() throws Exception {
public void testBuiltinTypesCompatible_241570() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
parseAndCheckBindings(getAboveComment(), lang, true);
}
@ -5533,7 +5533,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// alloc(__func__);
// }
public void testPredefinedFunctionName_Bug247747() throws Exception {
public void testPredefinedFunctionName_247747() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, false);
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, false);
}
@ -5544,7 +5544,7 @@ public class AST2Tests extends AST2BaseTest {
// alloc(__FUNCTION__);
// alloc(__PRETTY_FUNCTION__);
// }
public void testPredefinedFunctionNameGcc_Bug247747() throws Exception {
public void testPredefinedFunctionNameGcc_247747() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true);
}
@ -5552,7 +5552,7 @@ public class AST2Tests extends AST2BaseTest {
// int foo = 42;
// typedef char StupidType;
// StupidType const *bar = (StupidType const*)&foo;
public void testUnusualDeclSpecOrdering_Bug251514() throws Exception {
public void testUnusualDeclSpecOrdering_251514() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP, true);
}
@ -5563,7 +5563,7 @@ public class AST2Tests extends AST2BaseTest {
// #define SEMI_IF ; if
// #define IF_COND if (1)
// void test() {
public void testLeadingSyntax_Bug250251() throws Exception {
public void testLeadingSyntax_250251() throws Exception {
String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code + "if (1) {};}");
@ -5629,7 +5629,7 @@ public class AST2Tests extends AST2BaseTest {
// #define P_BLOCK ){}
// #define IF_COND if (1)
// void test() {
public void testTrailingSyntax_Bug250251() throws Exception {
public void testTrailingSyntax_250251() throws Exception {
String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code + "if (1) {};}");
@ -5693,7 +5693,7 @@ public class AST2Tests extends AST2BaseTest {
// #define SEMI_IF ; if
// #define IF_COND if (1)
// void test() {
public void testSyntax_Bug250251() throws Exception {
public void testSyntax_250251() throws Exception {
String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code + "if (1) {};}");
@ -5751,7 +5751,7 @@ public class AST2Tests extends AST2BaseTest {
// <<
// y;
// }
public void testSyntaxWithNL_Bug280175() throws Exception {
public void testSyntaxWithNL_280175() throws Exception {
String code= getAboveComment();
int offsetX= code.indexOf('x', code.indexOf('x')+1);
int offsetShift= code.indexOf('<');
@ -5819,7 +5819,7 @@ public class AST2Tests extends AST2BaseTest {
// void caller() {
// myfunc("");
// }
public void testReferencesInInitializer_Bug251514() throws Exception {
public void testReferencesInInitializer_251514() throws Exception {
final String code = getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true);
@ -5832,7 +5832,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// const void* p = &"string";
// }
public void testAdressOfStringLiteral_Bug252970() throws Exception {
public void testAdressOfStringLiteral_252970() throws Exception {
final String code = getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
parseAndCheckBindings(code, lang);
@ -5844,7 +5844,7 @@ public class AST2Tests extends AST2BaseTest {
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// };
public void testScalabilityOfLargeTrivialInitializer_Bug253690() throws Exception {
public void testScalabilityOfLargeTrivialInitializer_253690() throws Exception {
sValidateCopy= false;
final int AMOUNT= 250000;
final CharSequence[] input = getContents(3);
@ -5877,7 +5877,7 @@ public class AST2Tests extends AST2BaseTest {
// }
// };
public void testLargeTrivialAggregateInitializer_Bug253690() throws Exception {
public void testLargeTrivialAggregateInitializer_253690() throws Exception {
sValidateCopy= false;
final int AMOUNT= 250000;
final CharSequence[] input = getContents(3);
@ -5916,7 +5916,7 @@ public class AST2Tests extends AST2BaseTest {
// int n= 0;
// int a[]= {0x00, sizeof(n)};
public void testNonTrivialInitializer_Bug253690() throws Exception {
public void testNonTrivialInitializer_253690() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parse(code, lang, false, true, true);
@ -5930,7 +5930,7 @@ public class AST2Tests extends AST2BaseTest {
// void test() {
// const void* p = 1+2;
// }
public void testGetChildren_Bug256127() throws Exception {
public void testGetChildren_256127() throws Exception {
final String code = getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTNode node= parseAndCheckBindings(code, lang);
@ -5976,7 +5976,7 @@ public class AST2Tests extends AST2BaseTest {
// struct s v;
// v.mem = 1;
// }
public void testNestedDeclarator_Bug257540() throws Exception {
public void testNestedDeclarator_257540() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -5990,7 +5990,7 @@ public class AST2Tests extends AST2BaseTest {
// cs foo;
// foo = ((cs) {1.2,1});
// }
public void testCompoundLiterals_Bug258496() throws Exception {
public void testCompoundLiterals_258496() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
@ -5999,7 +5999,7 @@ public class AST2Tests extends AST2BaseTest {
// __thread int i;
// static __thread int j;
// extern __thread int k;
public void testThreadLocalVariables_Bug260387() throws Exception {
public void testThreadLocalVariables_260387() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true);
@ -6009,7 +6009,7 @@ public class AST2Tests extends AST2BaseTest {
// int a,b;
// if ((a)+b);
// }
public void testAmbiguityResolutionInIfCondition_Bug261043() throws Exception {
public void testAmbiguityResolutionInIfCondition_261043() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true);
@ -6025,7 +6025,7 @@ public class AST2Tests extends AST2BaseTest {
// const TInt; // declaration without name
// const a; // declares a;
// };
public void testAmbiguousDeclaration_Bug259373() throws Exception {
public void testAmbiguousDeclaration_259373() throws Exception {
final String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.C, true);
BindingAssertionHelper bh= new BindingAssertionHelper(code, false);
@ -6047,7 +6047,7 @@ public class AST2Tests extends AST2BaseTest {
// pg->glob= 0;
// pl->loc= 1;
// }
public void testLocalVsGlobalStruct_Bug255973() throws Exception {
public void testLocalVsGlobalStruct_255973() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true);
@ -7363,7 +7363,7 @@ public class AST2Tests extends AST2BaseTest {
// sizeof(10); // wrong - getExpressionType returns float
// sizeof(int); // wrong - getExpressionType returns float
// }
public void testTypeOfSizeof_Bug355052() throws Exception {
public void testTypeOfSizeof_355052() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP);
IASTFunctionDefinition a= getDeclaration(tu, 0);
@ -7384,12 +7384,12 @@ public class AST2Tests extends AST2BaseTest {
// typedef int foobar_t;
// foobar_t *a = 0, *b = a;
// }
public void testAmbiguousStatement_Bug360541() throws Exception {
public void testAmbiguousStatement_360541() throws Exception {
parseAndCheckBindings();
}
// typedef int T[sizeof(int)];
public void testSizeofExpression_Bug362464() throws Exception {
public void testSizeofExpression_362464() throws Exception {
String code= getAboveComment();
for (ParserLanguage l : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, l);
@ -7411,4 +7411,13 @@ public class AST2Tests extends AST2BaseTest {
assertEquals("//comment", new String(comment.getComment()));
assertEquals("//comment", comment.getRawSignature());
}
// template<typename T>
// void test(T n) {
// for (__decltype(n + 0) i = 0; i < n; i++) {
// }
// }
public void testGCCDecltype_397227() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
}

View file

@ -6,9 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
* Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
@ -58,20 +58,122 @@ import org.eclipse.core.runtime.CoreException;
public abstract class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBase {
public static class SingleProject extends IndexCPPBindingResolutionTest {
public SingleProject() {setStrategy(new SinglePDOMTestStrategy(true));}
public static TestSuite suite() {return suite(SingleProject.class);}
public SingleProject() { setStrategy(new SinglePDOMTestStrategy(true)); }
public static TestSuite suite() { return suite(SingleProject.class); }
}
public static class ProjectWithDepProj extends IndexCPPBindingResolutionTest {
public ProjectWithDepProj() {setStrategy(new ReferencedProject(true));}
public static TestSuite suite() {return suite(ProjectWithDepProj.class);}
public ProjectWithDepProj() { setStrategy(new ReferencedProject(true)); }
public static TestSuite suite() { return suite(ProjectWithDepProj.class); }
}
public static void addTests(TestSuite suite) {
public static void addTests(TestSuite suite) {
suite.addTest(SingleProject.suite());
suite.addTest(ProjectWithDepProj.suite());
}
/* Assertion helpers */
/* ##################################################################### */
static protected void assertField(
IBinding binding,
String qn,
Class expType,
String expTypeQN) {
assertTrue(binding instanceof ICPPField);
ICPPField field = (ICPPField) binding;
assertQNEquals(qn, field);
assertTrue(expType.isInstance(field.getType()));
if (expTypeQN != null) {
assert(field.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) field.getType();
assertQNEquals(expTypeQN, tyBinding);
}
}
static protected void assertClassTypeBinding(IBinding binding,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(binding instanceof ICPPClassType);
assertClassType((ICPPClassType) binding, qn, key, bases, fields, declaredFields, methods,
declaredMethods, allDeclaredMethods, friends, constructors, nestedClasses);
}
static protected void assertClassType(
IType type,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(type instanceof ICPPClassType);
ICPPClassType classType = (ICPPClassType) type;
assertQNEquals(qn, classType);
assertEquals(key, classType.getKey());
assertEquals(bases, classType.getBases().length);
assertEquals(fields, classType.getFields().length);
assertEquals(declaredFields, classType.getDeclaredFields().length);
assertEquals(methods, classType.getMethods().length);
assertEquals(declaredMethods, classType.getDeclaredMethods().length);
assertEquals(allDeclaredMethods, classType.getAllDeclaredMethods().length);
assertEquals(friends, classType.getFriends().length);
assertEquals(constructors, classType.getConstructors().length);
assertEquals(nestedClasses, classType.getNestedClasses().length);
}
public void assertEnumeration(IBinding binding, String name, String[] enumerators) throws DOMException {
assertTrue(binding instanceof IEnumeration);
assertEquals(name, binding.getName());
IEnumerator[] aEnumerators = ((IEnumeration)binding).getEnumerators();
Set expectedEnumerators = new HashSet();
expectedEnumerators.addAll(Arrays.asList(enumerators));
Set actualEnumerators = new HashSet();
for (IEnumerator enumerator : aEnumerators) {
actualEnumerators.add(enumerator.getName());
}
assertEquals(expectedEnumerators, actualEnumerators);
}
/**
* @param type
* @param cqn
* @param qn may be null
*/
static protected void assertPTM(IType type, String cqn, String qn) {
assertTrue(type instanceof ICPPPointerToMemberType);
ICPPPointerToMemberType ptmt = (ICPPPointerToMemberType) type;
ICPPClassType classType = (ICPPClassType) ptmt.getMemberOfClass();
assertQNEquals(cqn, classType);
if (qn != null) {
assert(ptmt.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) ptmt.getType();
assertQNEquals(qn, tyBinding);
}
}
private void asserValueEquals(IValue initialValue, long i) {
assertNotNull(initialValue);
final Long numericalValue = initialValue.numericalValue();
assertNotNull(numericalValue);
assertEquals(i, numericalValue.longValue());
}
// namespace ns { class A; enum E {E1}; typedef int T; }
//
// class B {
@ -81,7 +183,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// void o(ns::T* a);
// void p(ns::E a);
// };
// namespace ns {
// class A {};
// typedef int T;
@ -91,7 +193,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// using ns::E;
// using ns::T;
// using ns::E1;
//
//
// void B::m(A* a) {}
// void B::n(E* a) {}
// void B::o(T* a) {}
@ -110,7 +212,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
assertInstance(b1, ICPPMethod.class);
assertInstance(b2, ICPPMethod.class);
}
// namespace n { class A{}; class B{}; class C{}; }
// namespace m {
@ -123,7 +225,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
IBinding b0= getBindingFromASTName("C c", 1);
IBinding b1= getBindingFromASTName("D d", 1);
}
// namespace n { class A{}; }
// namespace m {
// using namespace n;
@ -158,7 +260,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
IBinding b4= getBindingFromASTName("CE1", 3);
IBinding b5= getBindingFromASTName("f(2", 1);
}
// namespace a { class A {}; }
// namespace b {
// using a::A;
@ -172,13 +274,13 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
IBinding b0= getBindingFromASTName("A aa", 1);
IBinding b1= getBindingFromASTName("B bb", 1);
}
// namespace header {
// class clh {
// };
// void fh();
// void fh(int a);
//
//
// class cl {
// };
// void f();
@ -186,14 +288,14 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// }
// using header::clh;
// using header::fh;
// #include "header.h"
// namespace source {
// class cls {
// };
// void fs();
// void fs(int a);
//
//
// }
// using header::cl;
// using header::f;
@ -204,10 +306,10 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
//
// void test() {
// fh();
// fh(1);
//
// fh(1);
//
// clh c;
//
//
// f();
// f(1);
// cl c1;
@ -229,18 +331,18 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
b= getBindingFromASTName("cls c2", 3);
}
// int (*f)(int);
// int g(int n){return n;}
// int g(int n, int m){ return n+m; }
// void foo() {
// f= g;
// }
public void testPointerToFunction() throws Exception {
IBinding b0 = getBindingFromASTName("f= g;", 1);
IBinding b0 = getBindingFromASTName("f= g;", 1);
IBinding b1 = getBindingFromASTName("g;", 1);
assertInstance(b0, ICPPVariable.class);
ICPPVariable v0= (ICPPVariable) b0;
assertInstance(v0.getType(), IPointerType.class);
@ -250,7 +352,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
assertInstance(f0.getReturnType(), ICPPBasicType.class);
assertEquals(1, f0.getParameterTypes().length);
assertInstance(f0.getParameterTypes()[0], ICPPBasicType.class);
assertInstance(b1, ICPPFunction.class);
ICPPFunctionType f1= ((ICPPFunction)b1).getType();
assertInstance(f1.getReturnType(), ICPPBasicType.class);
@ -272,7 +374,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// // referencing file
// #include "header.h"
//
//
// C *cp = new C(); /*b0, b1*/
// void references() {
// long l = 5, *lp;
@ -286,12 +388,12 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
public void testPointerToMemberFields() throws IOException, DOMException {
IBinding b0 = getBindingFromASTName("C *cp", 1);
assertClassType((ICPPClassType)b0, "C", ICPPClassType.k_class, 1, 6, 5, 9, 0, 1, 0, 2, 1);
IBinding b1 = getBindingFromASTName("cp = new C()", 2);
assertVariable(b1, "cp", IPointerType.class, null);
IPointerType b1type = (IPointerType) ((ICPPVariable)b1).getType();
assertClassType(b1type.getType(), "C", ICPPClassType.k_class, 1, 6, 5, 9, 0, 1, 0, 2, 1);
IBinding b2 = getBindingFromASTName("cs.*cp->o", 2);
ICPPField field0 = (ICPPField) b2;
assertTrue(field0.getType() instanceof ICPPClassType);
@ -407,9 +509,9 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
IBinding b20 = getBindingFromASTName("func(a);", 4);
IBinding b21 = getBindingFromASTName("a); /*func5*/", 1);
IBinding b22 = getBindingFromASTName("C2 : public", 2);
IBinding b23 = getBindingFromASTName("C {}; /*base*/", 1);
IBinding b23 = getBindingFromASTName("C {}; /*base*/", 1);
IBinding b24 = getBindingFromASTName("S2 : public", 2);
IBinding b25 = getBindingFromASTName("S {}; /*base*/", 1);
IBinding b25 = getBindingFromASTName("S {}; /*base*/", 1);
}
@ -420,14 +522,14 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
//// referencing content
//namespace n1 {
// class TopC {}; struct TopS {}; union TopU {}; enum TopE {TopER1,TopER2};
// short topBasic; void *topPtr;/*A*/ TopC *topCPtr;/*A*/ TopU topFunc(){return *new TopU();}
// short topBasic; void *topPtr;/*A*/ TopC *topCPtr;/*A*/ TopU topFunc(){return *new TopU();}
// class C {
// class TopC {}; struct TopS {}; union TopU {}; enum TopE {TopER1,TopER2};
// short topBasic; void *topPtr;/*B*/ TopC *topCPtr;/*B*/ TopU topFunc(){return *new TopU();}
// void references() {
// ::TopC c; ::TopS s; ::TopU u; ::TopE e = ::TopER1;
// ::topBasic++; ::topPtr = &::topBasic; ::topCPtr = &c; ::topFunc();
// }
// }
// };
//}
public void testSingletonQualifiedName() {
@ -468,26 +570,26 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// }
// namespace n3 { c3::s3::u3::S _s10; }
// namespace n1 { n2::S _s11; }
// namespace n1 { namespace n2 { S _s12; }}
// namespace n1 { namespace n2 { S _s12; }}
public void testQualifiedNamesForStruct() throws DOMException {
IBinding b0 = getBindingFromASTName("S _s0;", 1);
assertTrue(b0.getScope() instanceof ICPPNamespaceScope);
assertTrue(b0.getScope().getParent() instanceof ICPPNamespaceScope);
assertTrue(b0.getScope().getParent().getParent() == null);
assertQNEquals("n1::n2::S", b0);
IBinding b1 = getBindingFromASTName("S _s1;", 1);
assertTrue(b1.getScope() instanceof ICPPNamespaceScope);
assertTrue(b1.getScope().getParent() instanceof ICPPNamespaceScope);
assertTrue(b1.getScope().getParent().getParent() == null);
assertQNEquals("n1::n2::S", b1);
IBinding b2 = getBindingFromASTName("S _s2;", 1);
assertTrue(b2.getScope() instanceof ICPPClassScope);
assertTrue(b2.getScope().getParent() instanceof ICPPClassScope);
assertTrue(b2.getScope().getParent().getParent() == null);
assertQNEquals("c1::c2::S", b2);
IBinding b3 = getBindingFromASTName("S _s3;", 1);
assertQNEquals("c1::c2::S", b3);
IBinding b4 = getBindingFromASTName("S _s4;", 1);
@ -502,7 +604,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
assertQNEquals("n3::c3::s3::u3::S", b8);
IBinding b9 = getBindingFromASTName("S _s9;", 1);
assertQNEquals("n3::c3::s3::u3::S", b9);
IBinding b10 = getBindingFromASTName("S _s10;", 1);
assertTrue(b10.getScope() instanceof ICPPClassScope);
assertTrue(b10.getScope().getParent() instanceof ICPPClassScope);
@ -510,7 +612,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
assertTrue(b10.getScope().getParent().getParent().getParent() instanceof ICPPNamespaceScope);
assertTrue(b10.getScope().getParent().getParent().getParent().getParent() == null);
assertQNEquals("n3::c3::s3::u3::S", b10);
IBinding b11 = getBindingFromASTName("S _s11;", 1);
assertQNEquals("n1::n2::S", b11);
IBinding b12 = getBindingFromASTName("S _s12;", 1);
@ -519,7 +621,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// // header content
// namespace n1 { namespace n2 { union U {}; } }
// class c1 { public: class c2 { public: union U {}; }; };
// class c1 { public: class c2 { public: union U {}; }; };
// struct s1 { struct s2 { union U {}; }; };
// union u1 { struct u2 { union U {}; }; };
// namespace n3 { class c3 { public: struct s3 { union u3 { union U {}; }; }; }; }
@ -535,7 +637,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// }
// namespace n3 { c3::s3::u3::U _u10; }
// namespace n1 { n2::U _u11; }
// namespace n1 { namespace n2 { U _u12; }}
// namespace n1 { namespace n2 { U _u12; }}
public void testQualifiedNamesForUnion() throws DOMException {
IBinding b0 = getBindingFromASTName("U _u0;", 1);
assertQNEquals("n1::n2::U", b0);
@ -583,7 +685,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// }
// namespace n3 { c3::s3::u3::C _c10; }
// namespace n1 { n2::C _c11; }
// namespace n1 { namespace n2 { C _c12; }}
// namespace n1 { namespace n2 { C _c12; }}
public void testQualifiedNamesForClass() throws DOMException {
IBinding b0 = getBindingFromASTName("C _c0;", 1);
assertQNEquals("n1::n2::C", b0);
@ -631,7 +733,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// }
// namespace n3 { c3::s3::u3::Int i10; }
// namespace n1 { n2::Int i11; }
// namespace n1 { namespace n2 { Int i12; }}
// namespace n1 { namespace n2 { Int i12; }}
public void testQualifiedNamesForTypedef() throws DOMException {
IBinding b0 = getBindingFromASTName("Int i0;", 3);
assertQNEquals("n1::n2::Int", b0);
@ -778,7 +880,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// class y { public:
// static int j;
// };
// };
// };
// void method() {
// ::x::y::i++;
// x::y::j++;
@ -818,7 +920,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// (sp,sp)->i/*7*/++; (s,s).i/*8*/++; // IASTExpressionList
// ss.sp->i/*9*/++; ss.s.i/*10*/++; // IASTFieldReference
// ssp->sp->i/*11*/++; ssp->s.i/*12*/++; // IASTFieldReference
// retsptr()->i/*13*/++; rets().i/*14*/++; // IASTFunctionCallExpression
// retsptr()->i/*13*/++; rets().i/*14*/++; // IASTFunctionCallExpression
// sp->i/*15*/++; s.i/*16*/++; // IASTIdExpression
// /* not applicable */ // IASTLiteralExpression
// /* not applicable */ // IASTTypeIdExpression
@ -942,7 +1044,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// void f(int);
// void f(long);
// void f(C); void f(C::i1); void f(C::lp1); void f(C::S1); void f(C::U1); void f(C::E1);
// void f(S); void f(S::i2); void f(S::lp2); void f(S::S2); void f(S::U2); void f(S::E2);
// void f(S); void f(S::i2); void f(S::lp2); void f(S::S2); void f(S::U2); void f(S::E2);
// void f(U); void f(U::i3); void f(U::lp3); void f(U::S3); void f(U::U3); void f(U::E3);
// void f(n::i4); void f(n::lp4); void f(n::S4); void f(n::U4); void f(n::E4);
// void f(E);
@ -962,7 +1064,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// fU = &f;/*14*/ fUi3 = &f;/*15*/ fUlp3 = &f;/*16*/ fUS3 = &f;/*17*/ fUU3 = &f;/*18*/ fUE3 = &f;/*19*/
// fni4 = &f;/*20*/ fnlp4 = &f;/*21*/ fnS4 = &f;/*22*/ fnU4 = &f;/*23*/ fnE4 = &f;/*24*/
// fE = &f;/*25*/
// }
// }
public void testAddressOfOverloadedFunction() throws DOMException {
IBinding b0 = getBindingFromASTName("f;/*0*/", 1);
IBinding b1 = getBindingFromASTName("f;/*1*/", 1);
@ -994,7 +1096,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// struct C {
// int m1(int a);
// int m2(int a) const;
// };
// };
//
// C* func(int (C::*m)(int) const);
// C* func(int (C::*m)(int));
@ -1015,7 +1117,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// void f_int_ptr(int*);
// #include "header.h"
// void ref() {
// void ref() {
// int i = 0;
// const int const_int = 0;
//
@ -1027,7 +1129,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
//
// void f_const_int(const int const_int) {
// f_int_ptr(&const_int); // error
// }
// }
public void testConstIntParameter() {
getBindingFromASTName("f_int(i)", 5);
getBindingFromASTName("f_int(const_int)", 5);
@ -1045,7 +1147,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// void f_int_const_ptr_const(int const*const);
// #include "header.h"
// void ref() {
// void ref() {
// int* int_ptr = 0;
// const int* const_int_ptr = 0;
// int const* int_const_ptr = 0;
@ -1259,7 +1361,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// };
// // referencing content
// struct myStruct;
// struct myStruct;
// union myUnion;
// void test() {
// struct myStruct* u;
@ -1271,13 +1373,13 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
getBindingFromASTName("a= 1", 1);
getBindingFromASTName("b= 1", 1);
}
// namespace x {
// int a(int);
// }
// using namespace x;
// using x::a;
// #include "header.h"
// void test() {
// a(1);
@ -1285,7 +1387,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
public void testLegalConflictWithUsingDeclaration() throws Exception {
getBindingFromASTName("a(1)", 1);
}
// class A {};
// class B {};
// class C {
@ -1294,7 +1396,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// };
// class D : public C {};
// void foo(B b) {}
// class E : public C {};
// void refs() {
// C c;
@ -1307,12 +1409,12 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
public void testUserDefinedConversionOperator_224364() throws Exception {
IBinding ca= getBindingFromASTName("C c;", 1);
assertInstance(ca, ICPPClassType.class);
IBinding foo1= getBindingFromASTName("foo(c)", 3);
IBinding da= getBindingFromASTName("D d", 1);
assertInstance(da, ICPPClassType.class);
IBinding foo2= getBindingFromASTName("foo(d)", 3);
IBinding foo3= getBindingFromASTName("foo(e)", 3);
}
@ -1349,7 +1451,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// class A {};
// }}
// using namespace ns1::ns2;
// #include "header.h"
// A a;
public void testUsingDirectiveWithQualifiedName_269727() throws Exception {
@ -1358,7 +1460,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// void f(int (&v)[1]);
// void f(int (&v)[2]);
// void test() {
// int a[1], b[2];
// f(a); f(b);
@ -1495,7 +1597,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// int a;
// }
// }
// void test() {
// ns::m::a; //1
// ns::a; //2
@ -1511,7 +1613,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// int a;
// }
// }
// namespace ns {
// void test() {
// m::a; //1
@ -1545,7 +1647,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// using namespace out2;
// }
// }
// #include "header.h"
// void test() {
// ::f(1);
@ -1570,7 +1672,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// using namespace out2;
// }
// }
// #include "header.h"
// namespace out {}
// namespace out2 {}
@ -1613,105 +1715,27 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
getBindingFromASTName("f(a)", 1, ICPPFunction.class);
getBindingFromASTName("g(b)", 1, ICPPFunction.class);
}
/* CPP assertion helpers */
/* ##################################################################### */
static protected void assertField(
IBinding binding,
String qn,
Class expType,
String expTypeQN) {
assertTrue(binding instanceof ICPPField);
ICPPField field = (ICPPField) binding;
assertQNEquals(qn, field);
assertTrue(expType.isInstance(field.getType()));
if (expTypeQN != null) {
assert(field.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) field.getType();
assertQNEquals(expTypeQN, tyBinding);
}
}
// namespace ns {
// namespace {
// const char str[] = "";
// }
// }
static protected void assertClassTypeBinding(IBinding binding,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(binding instanceof ICPPClassType);
assertClassType((ICPPClassType) binding, qn, key, bases, fields, declaredFields, methods,
declaredMethods, allDeclaredMethods, friends, constructors, nestedClasses);
}
static protected void assertClassType(
IType type,
String qn,
int key,
int bases,
int fields,
int declaredFields,
int methods,
int declaredMethods,
int allDeclaredMethods,
int friends,
int constructors,
int nestedClasses) {
assertTrue(type instanceof ICPPClassType);
ICPPClassType classType = (ICPPClassType) type;
assertQNEquals(qn, classType);
assertEquals(key, classType.getKey());
assertEquals(bases, classType.getBases().length);
assertEquals(fields, classType.getFields().length);
assertEquals(declaredFields, classType.getDeclaredFields().length);
assertEquals(methods, classType.getMethods().length);
assertEquals(declaredMethods, classType.getDeclaredMethods().length);
assertEquals(allDeclaredMethods, classType.getAllDeclaredMethods().length);
assertEquals(friends, classType.getFriends().length);
assertEquals(constructors, classType.getConstructors().length);
assertEquals(nestedClasses, classType.getNestedClasses().length);
}
public void assertEnumeration(IBinding binding, String name, String[] enumerators) throws DOMException {
assertTrue(binding instanceof IEnumeration);
assertEquals(name, binding.getName());
IEnumerator[] aEnumerators = ((IEnumeration)binding).getEnumerators();
Set expectedEnumerators = new HashSet();
expectedEnumerators.addAll(Arrays.asList(enumerators));
Set actualEnumerators = new HashSet();
for (IEnumerator enumerator : aEnumerators) {
actualEnumerators.add(enumerator.getName());
}
assertEquals(expectedEnumerators, actualEnumerators);
}
/**
* @param type
* @param cqn
* @param qn may be null
*/
static protected void assertPTM(IType type, String cqn, String qn) {
assertTrue(type instanceof ICPPPointerToMemberType);
ICPPPointerToMemberType ptmt = (ICPPPointerToMemberType) type;
ICPPClassType classType = (ICPPClassType) ptmt.getMemberOfClass();
assertQNEquals(cqn, classType);
if (qn != null) {
assert(ptmt.getType() instanceof ICPPBinding);
ICPPBinding tyBinding = (ICPPBinding) ptmt.getType();
assertQNEquals(qn, tyBinding);
}
}
private void asserValueEquals(IValue initialValue, long i) {
assertNotNull(initialValue);
final Long numericalValue = initialValue.numericalValue();
assertNotNull(numericalValue);
assertEquals(i, numericalValue.longValue());
// namespace {
// const char str[] = "";
// }
//
// namespace ns {
//
// void f(const char* s);
//
// void test() {
// f(str);
// }
//
// }
public void testAnonymousNamespaces_392577() throws Exception {
getBindingFromASTName("f(str)", 1, ICPPFunction.class);
}
}

View file

@ -56,7 +56,7 @@ public class DBTest extends BaseTestCase {
@Override
protected void tearDown() throws Exception {
db.close();
if(!db.getLocation().delete()) {
if (!db.getLocation().delete()) {
db.getLocation().deleteOnExit();
}
db= null;
@ -87,15 +87,15 @@ public class DBTest extends BaseTestCase {
try {
new Database(tmp, ChunkCache.getSharedInstance(), 0, false);
fail("A readonly file should not be openable with write-access");
} catch(CoreException ioe) {
} catch (CoreException e) {
// we expect to get a failure here
}
/* check opening a readonly file for read access does not fail */
try {
new Database(tmp, ChunkCache.getSharedInstance(), 0, true);
} catch(CoreException ce) {
fail("A readonly file should be readable by a permanently readonly database "+ce);
} catch (CoreException e) {
fail("A readonly file should be readable by a permanently readonly database "+e);
}
} finally {
tmp.delete(); // this may be pointless on some platforms
@ -104,7 +104,7 @@ public class DBTest extends BaseTestCase {
public void testFreeBlockLinking() throws Exception {
final int realsize = 42;
final int deltas = (realsize+Database.BLOCK_HEADER_SIZE + Database.BLOCK_SIZE_DELTA - 1) / Database.BLOCK_SIZE_DELTA;
final int deltas = (realsize + Database.BLOCK_HEADER_SIZE + Database.BLOCK_SIZE_DELTA - 1) / Database.BLOCK_SIZE_DELTA;
final int blocksize = deltas * Database.BLOCK_SIZE_DELTA;
final int freeDeltas= Database.MIN_BLOCK_DELTAS-deltas;
@ -150,7 +150,6 @@ public class DBTest extends BaseTestCase {
public long getRecord() {
return record;
}
}
public void testStringsInBTree() throws Exception {
@ -194,6 +193,7 @@ public class DBTest extends BaseTestCase {
return string1.compare(string2, true);
}
};
BTree btree = new BTree(db, Database.DATA_AREA, comparator);
for (int i = 0; i < names.length; ++i) {
String name = names[i];
@ -224,8 +224,8 @@ public class DBTest extends BaseTestCase {
assertCMP("", EQ, "", true);
assertCMP("", EQ, "", false);
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH/2, r, true);
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH/2, r, false);
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH / 2, r, true);
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH / 2, r, false);
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH, r, true);
doTrials(1000, 1, ShortString.MAX_BYTE_LENGTH, r, false);
@ -243,13 +243,13 @@ public class DBTest extends BaseTestCase {
public void testLongStringComparison() throws CoreException {
Random r= new Random(314159265);
doTrials(100, ShortString.MAX_BYTE_LENGTH+1, ShortString.MAX_BYTE_LENGTH*2, r, true);
doTrials(100, ShortString.MAX_BYTE_LENGTH+1, ShortString.MAX_BYTE_LENGTH*2, r, false);
doTrials(100, ShortString.MAX_BYTE_LENGTH + 1, ShortString.MAX_BYTE_LENGTH * 2, r, true);
doTrials(100, ShortString.MAX_BYTE_LENGTH + 1, ShortString.MAX_BYTE_LENGTH * 2, r, false);
}
private void doTrials(int n, int min, int max, Random r, boolean caseSensitive) throws CoreException {
long start = System.currentTimeMillis();
for(int i=0; i<n; i++) {
for(int i= 0; i < n; i++) {
String a = randomString(min, max, r);
String b = randomString(min, max, r);
int expected = caseSensitive ? a.compareTo(b) : a.compareToIgnoreCase(b);
@ -262,7 +262,7 @@ public class DBTest extends BaseTestCase {
private String randomString(int min, int max, Random r) {
StringBuffer result = new StringBuffer();
int len = min + r.nextInt(max-min);
for(int i=0; i<len; i++) {
for(int i= 0; i < len; i++) {
result.append(randomChar(r));
}
return result.toString();
@ -317,8 +317,8 @@ public class DBTest extends BaseTestCase {
}
private void assertSignEquals(int a, int b) {
a= a<0 ? -1 : (a>0 ? 1 : 0);
b= b<0 ? -1 : (b>0 ? 1 : 0);
a= a < 0 ? -1 : (a > 0 ? 1 : 0);
b= b < 0 ? -1 : (b > 0 ? 1 : 0);
assertEquals(a, b);
}
}

View file

@ -8,7 +8,6 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests;
import java.util.regex.Pattern;
@ -32,21 +31,20 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
/**
* Tests for verifying whether the PDOM correctly stores information about
* C++ namespaces.
* Tests for verifying whether the PDOM correctly stores information about C++ namespaces.
*
* @author Vivian Kong
*/
public class NamespaceTests extends PDOMTestBase {
protected ICProject project;
protected ICProject project;
protected PDOM pdom;
protected IProgressMonitor NULL_MONITOR = new NullProgressMonitor();
protected IndexFilter INDEX_FILTER = IndexFilter.ALL;
public static Test suite() {
return suite(NamespaceTests.class);
}
@Override
protected void setUp() throws Exception {
if (pdom == null) {
@ -55,7 +53,7 @@ public class NamespaceTests extends PDOMTestBase {
}
pdom.acquireReadLock();
}
@Override
protected void tearDown() throws Exception {
pdom.releaseReadLock();
@ -63,9 +61,9 @@ public class NamespaceTests extends PDOMTestBase {
project.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
}
}
public void testAlias() throws Exception {
/* Find all the namespace */
// Find all the namespace
IBinding[] namespaces = pdom.findBindings(Pattern.compile("namespace1"), false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, namespaces.length);
assertTrue(namespaces[0] instanceof ICPPNamespace);
@ -81,147 +79,136 @@ public class NamespaceTests extends PDOMTestBase {
assertTrue(namespaces[0] instanceof ICPPNamespace);
assertTrue(namespaces[0] instanceof ICPPNamespaceAlias);
ICPPNamespaceAlias namespaceAlias = (ICPPNamespaceAlias) namespaces[0];
//TODO PDOM has no alias information
// TODO PDOM has no alias information
// namespace2 and namespaceAlias should be referencing the same namespace
assertEquals(namespace2, namespaceAlias.getBinding());
}
public void testNested() throws Exception {
/* Find deeply nested namespace */
public void testNested() throws Exception {
// Find deeply nested namespace
Pattern[] patterns = {Pattern.compile("namespace1"), Pattern.compile("namespace2"), Pattern.compile("namespace3")};
IBinding[] namespaces = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, namespaces.length);
assertTrue(namespaces[0] instanceof ICPPNamespace);
}
public void testMemberDefinition() throws Exception {
/* Find the definition of a member declared in a namespace */
public void testMemberDefinition() throws Exception {
// Find the definition of a member declared in a namespace
Pattern[] patterns = {Pattern.compile("namespace1"), Pattern.compile("namespace2"), Pattern.compile("foo")};
IBinding[] members = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, members.length);
assertTrue(members[0] instanceof ICPPFunction);
IName[] decls = pdom.findNames(members[0], IIndex.FIND_DECLARATIONS);
assertEquals(1, decls.length);
IASTFileLocation loc = decls[0].getFileLocation();
assertEquals(offset("namespace.cpp", "void foo()") + 5, loc.getNodeOffset()); //character offset
assertEquals(offset("namespace.cpp", "void foo()") + 5, loc.getNodeOffset()); // character offset
IName[] defs = pdom.findNames(members[0], IIndex.FIND_DEFINITIONS);
assertEquals(1, defs.length);
loc = defs[0].getFileLocation();
assertEquals(offset("namespace.cpp", "::foo()") + 2, loc.getNodeOffset()); //character offset
assertEquals(offset("namespace.cpp", "::foo()") + 2, loc.getNodeOffset()); // character offset
}
public void testExtend() throws Exception {
/* Extending a namespace */
public void testExtend() throws Exception {
// Extending a namespace
IBinding[] namespaces = pdom.findBindings(Pattern.compile("ns1"), false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, namespaces.length);
assertTrue(namespaces[0] instanceof ICPPNamespace);
ICPPNamespace namespace1 = (ICPPNamespace) namespaces[0];
Pattern[] patterns = {Pattern.compile("ns1"), Pattern.compile("c")};
IBinding[] members = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, members.length); //c was added by extending the namespace
assertEquals(1, members.length); // c was added by extending the namespace
}
public void testOverload() throws Exception {
//Function overloading in namespace
// Function overloading in namespace
Pattern[] patterns = {Pattern.compile("ns3"), Pattern.compile("blah")};
IBinding[] functions = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, functions.length);
assertTrue(functions[0] instanceof ICPPFunction);
ICPPFunction function = (ICPPFunction) functions[0];
IName[] defs = pdom.findNames(function, IIndex.FIND_DEFINITIONS);
assertEquals(1, defs.length);
IASTFileLocation loc = defs[0].getFileLocation();
assertEquals(offset("overload.cpp","void blah(char)") + 5, loc.getNodeOffset()); //character offset
assertEquals(offset("overload.cpp", "void blah(char)") + 5, loc.getNodeOffset()); // character offset
IName[] decls = pdom.findNames(function, IIndex.FIND_DECLARATIONS_DEFINITIONS);
assertEquals(1, decls.length);
loc = decls[0].getFileLocation();
assertEquals(offset("overload.cpp","void blah(char)") + 5, loc.getNodeOffset()); //character offset
assertEquals(offset("overload.cpp", "void blah(char)") + 5, loc.getNodeOffset()); // character offset
IName[] refs = pdom.findNames(function, IIndex.FIND_REFERENCES);
assertEquals(1, refs.length);
loc = refs[0].getFileLocation();
assertEquals(offset("overload.cpp","blah('a')"), loc.getNodeOffset()); //character offset
assertEquals(offset("overload.cpp", "blah('a')"), loc.getNodeOffset()); // character offset
}
public void testUnnamed() throws Exception {
// test case for Bugzilla 162226
/* Unnamed Namespace */
public void testUnnamed_162226() throws Exception {
// Unnamed Namespace
IBinding[] functions = pdom.findBindings(Pattern.compile("function1"), true, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, functions.length);
assertTrue(functions[0] instanceof ICPPFunction);
ICPPFunction function = (ICPPFunction) functions[0];
IName[] defs = pdom.findNames(function, IIndex.FIND_DEFINITIONS);
assertEquals(1, defs.length);
IASTFileLocation loc = defs[0].getFileLocation();
assertEquals(offset("unnamed.cpp","void function1()") + 5, loc.getNodeOffset()); //character offset
assertEquals(offset("unnamed.cpp", "void function1()") + 5, loc.getNodeOffset()); // character offset
IName[] decls = pdom.findNames(function, IIndex.FIND_DECLARATIONS_DEFINITIONS);
assertEquals(1, decls.length);
loc = decls[0].getFileLocation();
assertEquals(offset("unnamed.cpp","void function1()") + 5, loc.getNodeOffset()); //character offset
assertEquals(offset("unnamed.cpp", "void function1()") + 5, loc.getNodeOffset()); // character offset
IName[] refs = pdom.findNames(function, IIndex.FIND_REFERENCES);
assertEquals(1, refs.length);
loc = refs[0].getFileLocation();
assertEquals(offset("unnamed.cpp","function1();"), loc.getNodeOffset()); //character offset
assertEquals(offset("unnamed.cpp", "function1();"), loc.getNodeOffset()); // character offset
}
public void testFriend() throws Exception {
/* Friend in namespace - function2 is not in Class1*/
// Bugzilla 162011
public void testFriend_162011() throws Exception {
// Friend in namespace - function2 is not in Class1
IBinding[] functions = pdom.findBindings(Pattern.compile("function2"), false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, functions.length);
assertTrue(functions[0] instanceof ICPPFunction);
ICPPFunction function = (ICPPFunction) functions[0];
IName[] defs = pdom.findNames(function, IIndex.FIND_DEFINITIONS);
assertEquals(1, defs.length);
IASTFileLocation loc = defs[0].getFileLocation();
assertEquals(offset("friend.cpp","void function2(Class1){};") + 5, loc.getNodeOffset()); //character offset
assertEquals(offset("friend.cpp", "void function2(Class1){};") + 5, loc.getNodeOffset()); // character offset
IName[] decls = pdom.findNames(function, IIndex.FIND_DECLARATIONS);
assertEquals(1, decls.length);
loc = decls[0].getFileLocation();
assertEquals(offset("friend.cpp","friend void function2(Class1);") + 12, loc.getNodeOffset()); //character offset
assertEquals(offset("friend.cpp", "friend void function2(Class1);") + 12, loc.getNodeOffset()); // character offset
IName[] refs = pdom.findNames(function, IIndex.FIND_REFERENCES);
assertEquals(1, refs.length);
loc = refs[0].getFileLocation();
assertEquals(offset("friend.cpp","ns4::function2(element)") + 5, loc.getNodeOffset()); //character offset
assertEquals(offset("friend.cpp", "ns4::function2(element)") + 5, loc.getNodeOffset()); // character offset
}
public void testUsingDirective() throws Exception {
//TODO need to test for PDOM? or is it more for compiler?
// TODO need to test for PDOM? or is it more for compiler?
Pattern[] patterns = {Pattern.compile("ns4"), Pattern.compile("element")};
IBinding[] variables = pdom.findBindings(patterns, false, INDEX_FILTER, NULL_MONITOR);
assertEquals(1, variables.length);
assertTrue(variables[0] instanceof ICPPVariable);
ICPPVariable variable1 = (ICPPVariable) variables[0];
IName[] defs = pdom.findNames(variable1, IIndex.FIND_DEFINITIONS);
assertEquals(1, defs.length);
IASTFileLocation loc = defs[0].getFileLocation();
assertEquals(offset("friend.cpp","Class1 element;") + 7, loc.getNodeOffset()); //character offset
assertEquals(offset("friend.cpp", "Class1 element;") + 7, loc.getNodeOffset()); // character offset
IName[] decls = pdom.findNames(variable1, IIndex.FIND_DECLARATIONS);
assertEquals(0, decls.length);
IName[] refs = pdom.findNames(variable1, IIndex.FIND_REFERENCES);
assertEquals(2, refs.length);
assertEquals(2, refs.length);
}
}

View file

@ -70,7 +70,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.internal.core.indexer;x-internal:=true,
org.eclipse.cdt.internal.core.language;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.language.settings.providers;x-internal:=true,
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core,org.eclipse.cdt.debug.ui",
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.debug.core,org.eclipse.cdt.debug.ui,org.eclipse.cdt.codan.ui",
org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui",
org.eclipse.cdt.internal.core.parser;x-internal:=true,
org.eclipse.cdt.internal.core.parser.problem;x-internal:=true,

View file

@ -10,8 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
import java.util.HashMap;
import java.util.Map;
@ -19,23 +17,22 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IOpenable;
import org.eclipse.cdt.internal.core.util.OverflowingLRUCache;
/**
* The cache of C elements to their respective info.
*
*
* This class is similar to the JDT CModelCache class.
*/
public class CModelCache {
public static final int PROJ_CACHE_SIZE = 50;
public static final int FOLDER_CACHE_SIZE = 500;
public static final int PROJ_CACHE_SIZE = 50;
public static final int FOLDER_CACHE_SIZE = 500;
public static final int FILE_CACHE_SIZE = 2000;
public static final int CHILDREN_CACHE_SIZE = FILE_CACHE_SIZE * 20;
/**
* Cache of open projects and roots.
*/
protected Map<ICElement, Object> projectAndRootCache;
/**
* Cache of open containers
*/
@ -50,62 +47,62 @@ public class CModelCache {
* Cache of children of C elements
*/
protected Map<ICElement, Object> childrenCache;
public CModelCache() {
this.projectAndRootCache = new HashMap<ICElement, Object>(PROJ_CACHE_SIZE);
this.folderCache = new HashMap<ICElement, Object>(FOLDER_CACHE_SIZE);
this.fileCache = new ElementCache<Object>(FILE_CACHE_SIZE);
this.childrenCache = new HashMap<ICElement, Object>(CHILDREN_CACHE_SIZE); // average 20 children per openable
}
public double openableFillingRatio() {
return this.fileCache.fillingRatio();
}
/**
* Returns the info for the element.
*/
public Object getInfo(ICElement element) {
switch (element.getElementType()) {
public CModelCache() {
this.projectAndRootCache = new HashMap<ICElement, Object>(PROJ_CACHE_SIZE);
this.folderCache = new HashMap<ICElement, Object>(FOLDER_CACHE_SIZE);
this.fileCache = new ElementCache<Object>(FILE_CACHE_SIZE);
this.childrenCache = new HashMap<ICElement, Object>(CHILDREN_CACHE_SIZE); // average 20 children per openable
}
public double openableFillingRatio() {
return this.fileCache.fillingRatio();
}
/**
* Returns the info for the element.
*/
public Object getInfo(ICElement element) {
switch (element.getElementType()) {
case ICElement.C_MODEL:
case ICElement.C_PROJECT:
return this.projectAndRootCache.get(element);
case ICElement.C_CCONTAINER:
return this.folderCache.get(element);
case ICElement.C_ARCHIVE:
case ICElement.C_BINARY:
case ICElement.C_BINARY:
case ICElement.C_UNIT:
return this.fileCache.get(element);
default:
return this.childrenCache.get(element);
}
}
}
/**
* Returns the info for this element without
* disturbing the cache ordering.
*/
protected Object peekAtInfo(ICElement element) {
switch (element.getElementType()) {
/**
* Returns the info for this element without
* disturbing the cache ordering.
*/
protected Object peekAtInfo(ICElement element) {
switch (element.getElementType()) {
case ICElement.C_MODEL:
case ICElement.C_PROJECT:
return this.projectAndRootCache.get(element);
case ICElement.C_CCONTAINER:
return this.folderCache.get(element);
case ICElement.C_ARCHIVE:
case ICElement.C_BINARY:
case ICElement.C_BINARY:
case ICElement.C_UNIT:
return this.fileCache.peek((IOpenable) element);
default:
return this.childrenCache.get(element);
}
}
}
/**
* Remember the info for the element.
*/
protected void putInfo(ICElement element, Object info) {
switch (element.getElementType()) {
/**
* Remember the info for the element.
*/
protected void putInfo(ICElement element, Object info) {
switch (element.getElementType()) {
case ICElement.C_MODEL:
case ICElement.C_PROJECT:
this.projectAndRootCache.put(element, info);
@ -114,19 +111,20 @@ protected void putInfo(ICElement element, Object info) {
this.folderCache.put(element, info);
break;
case ICElement.C_ARCHIVE:
case ICElement.C_BINARY:
case ICElement.C_BINARY:
case ICElement.C_UNIT:
this.fileCache.put((IOpenable)element, info);
break;
default:
this.childrenCache.put(element, info);
}
}
}
/**
* Removes the info of the element from the cache.
*/
protected void removeInfo(ICElement element) {
switch (element.getElementType()) {
/**
* Removes the info of the element from the cache.
*/
protected void removeInfo(ICElement element) {
switch (element.getElementType()) {
case ICElement.C_MODEL:
case ICElement.C_PROJECT:
this.projectAndRootCache.remove(element);
@ -135,13 +133,12 @@ protected void removeInfo(ICElement element) {
this.folderCache.remove(element);
break;
case ICElement.C_ARCHIVE:
case ICElement.C_BINARY:
case ICElement.C_BINARY:
case ICElement.C_UNIT:
this.fileCache.remove((IOpenable)element);
break;
default:
this.childrenCache.remove(element);
}
}
}
}

View file

@ -6,11 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* An image location explains how a name made it into the translation unit.
* @since 5.0
@ -19,7 +18,6 @@ package org.eclipse.cdt.core.dom.ast;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTImageLocation extends IASTFileLocation {
/**
* The image is part of the code that has not been modified by the preprocessor.
*/
@ -34,8 +32,8 @@ public interface IASTImageLocation extends IASTFileLocation {
final int ARGUMENT_TO_MACRO_EXPANSION= 3;
/**
* Returns the kind of image-location, one of {@link #REGULAR_CODE}, {@link #MACRO_DEFINITION} or
* {@link #ARGUMENT_TO_MACRO_EXPANSION}.
* Returns the kind of image-location, one of {@link #REGULAR_CODE}, {@link #MACRO_DEFINITION}
* or {@link #ARGUMENT_TO_MACRO_EXPANSION}.
*/
public int getLocationKind();
}

View file

@ -57,7 +57,7 @@ public interface IASTName extends IASTNode, IName {
/**
* Get the role of this name. If the name needs to be resolved to determine that and
* <code>allowResolution</code> is set to <code>false</code>, then {@link IASTNameOwner#r_unclear}
* {@code allowResolution} is set to {@code false}, then {@link IASTNameOwner#r_unclear}
* is returned.
*
* @param allowResolution whether or not resolving the name is allowed.
@ -80,21 +80,24 @@ public interface IASTName extends IASTNode, IName {
public ILinkage getLinkage();
/**
* Returns the image location for this name or <code>null</code> if the information is not available.
* Returns the image location for this name or <code>null</code> if the information is not
* available.
* <p>
* An image location can be computed when the name is either found directly in the code, is (part of)
* an argument to a macro expansion or is (part of) a macro definition found in the source code.
* An image location can be computed when the name is either found directly in the code, is
* (part of) an argument to a macro expansion or is (part of) a macro definition found in
* the source code.
* <p>
* The image location is <code>null</code>, when the name consists of multiple tokens (qualified names)
* and the tokens are not found side by side in the code, or if the name is the result of
* a token-paste operation or the name is found in the definition of a built-in macro.
* The image location is <code>null</code>, when the name consists of multiple tokens
* (qualified names) and the tokens are not found side by side in the code, or if the name is
* the result of a token-paste operation or the name is found in the definition of a built-in
* macro.
* @since 5.0
*/
public IASTImageLocation getImageLocation();
/**
* For convenience this method returns the last name of a qualified name or this if this is not a
* qualified name.
* For convenience this method returns the last name of a qualified name or this if this is not
* a qualified name.
* @since 5.1
*/
public IASTName getLastName();

View file

@ -27,19 +27,20 @@ public interface IASTNodeSelector {
IASTName findName(int offset, int length);
/**
* Returns the smallest name enclosing the given range, or <code>null</code> if there is no such node.
* Will not return an implicit name.
* Returns the smallest name enclosing the given range, or <code>null</code> if there is
* no such node. Will not return an implicit name.
*/
IASTName findEnclosingName(int offset, int length);
/**
* Returns the first name contained in the given range, or <code>null</code> if there is no such node.
* Will not return an implicit name.
* Returns the first name contained in the given range, or <code>null</code> if there is
* no such node. Will not return an implicit name.
*/
IASTName findFirstContainedName(int offset, int length);
/**
* Returns the implicit name for the exact given range, or <code>null</code> if there is no such node.
* Returns the implicit name for the exact given range, or <code>null</code> if there is
* no such node.
*
* Note that there can be more than one implicit name in the same location.
* The implicit name's parent can be used to get all the names at the location.
@ -61,41 +62,45 @@ public interface IASTNodeSelector {
/**
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes and children are preferred over their parents.
*/
IASTNode findNode(int offset, int length);
/**
* Returns the smallest node enclosing the given range, or <code>null</code> if there is no such node.
* Returns the smallest node enclosing the given range, or <code>null</code> if there is
* no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes nodes and children are preferred over their parents.
*/
IASTNode findEnclosingNode(int offset, int length);
/**
* Returns the smallest node strictly enclosing the given range, or <code>null</code> if there is no such node.
* Returns the smallest node strictly enclosing the given range, or <code>null</code> if there
* is no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes nodes and children are preferred over their parents.
* @since 5.3
*/
IASTNode findStrictlyEnclosingNode(int offset, int length);
/**
* Returns the first node contained in the given range, or <code>null</code> if there is no such node.
* Returns the first node contained in the given range, or <code>null</code> if there is
* no such node.
* <p>
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion}) are preferred
* over c/c++-nodes nodes and children are preferred over their parents.
* For nodes with the same location, macro-expansions ({@link IASTPreprocessorMacroExpansion})
* are preferred over c/c++-nodes nodes and children are preferred over their parents.
*/
IASTNode findFirstContainedNode(int offset, int length);
/**
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
* <p>
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or the name for
* an expansion. Rather than that the expansion itself is searched for a matching node.
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or
* the name for an expansion. Rather than that the expansion itself is searched for a matching
* node.
* @since 5.1
*/
IASTNode findNodeInExpansion(int offset, int length);
@ -103,17 +108,20 @@ public interface IASTNodeSelector {
/**
* Returns the smallest node enclosing the range, or <code>null</code> if there is no such node.
* <p>
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or the name for
* an expansion. Rather than that the expansion itself is searched for a matching node.
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or
* the name for an expansion. Rather than that the expansion itself is searched for a matching
* node.
* @since 5.1
*/
IASTNode findEnclosingNodeInExpansion(int offset, int length);
/**
* Returns the first node contained in the given expansion, or <code>null</code> if there is no such node.
* Returns the first node contained in the given expansion, or <code>null</code> if there is
* no such node.
* <p>
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or the name for
* an expansion. Rather than that the expansion itself is searched for a matching node.
* The method never returns a macro expansion ({@link IASTPreprocessorMacroExpansion}) or
* the name for an expansion. Rather than that the expansion itself is searched for a matching
* node.
* @since 5.1
*/
IASTNode findFirstContainedNodeInExpansion(int offset, int length);

View file

@ -6,18 +6,17 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* John Camelon (IBM Rational Software) - Initial API and implementation
* John Camelon (IBM Rational Software) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* This node represents a null statement. ';'
* This node represents a null statement, ';'
*
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTNullStatement extends IASTStatement {
/**
* @since 5.1
*/

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@ -20,9 +20,9 @@ package org.eclipse.cdt.core.dom.ast;
public interface IASTPreprocessorMacroExpansion extends IASTNode {
public static final IASTPreprocessorMacroExpansion[] EMPTY_ARRAY = {};
public static final ASTNodeProperty EXPANSION_NAME=
new ASTNodeProperty("IASTPreprocessorMacroExpansion.EXPANSION_NAME - macro name"); //$NON-NLS-1$
new ASTNodeProperty("IASTPreprocessorMacroExpansion.EXPANSION_NAME - macro name"); //$NON-NLS-1$
public static final ASTNodeProperty NESTED_EXPANSION_NAME=
new ASTNodeProperty("IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME - nested macro name"); //$NON-NLS-1$
new ASTNodeProperty("IASTPreprocessorMacroExpansion.NESTED_EXPANSION_NAME - nested macro name"); //$NON-NLS-1$
/**
* Returns the macro definition used for the expansion.

View file

@ -254,24 +254,22 @@ public interface IASTTranslationUnit extends IASTDeclarationListOwner, IFileNomi
/**
* Return the set of files that have been skipped because they have been part of the index
* prior to creating this AST, or <code>null</code> if not available.
* Applies only, if AST was created with an index and the option to skip headers found in the
* index.
* Applies only, if AST was created with an index and the option to skip headers found in
* the index.
* @since 5.1
*/
IIndexFileSet getIndexFileSet();
/**
* Return the set of files in the index that are superseded by this AST,
* or <code>null</code> if not available.
* Applies only, if AST was created with an index.
* Return the set of files in the index that are superseded by this AST, or <code>null</code>
* if not available. Applies only, if AST was created with an index.
* @since 5.3
*/
IIndexFileSet getASTFileSet();
/**
* In case the AST was created in a way that supports comment parsing,
* all comments of the translation unit are returned. Otherwise an
* empty array will be supplied.
* In case the AST was created in a way that supports comment parsing, all comments of
* the translation unit are returned. Otherwise an empty array will be supplied.
*
* @return <code>IASTComment[]</code>
* @since 4.0

View file

@ -66,6 +66,7 @@ public abstract class GNUScannerExtensionConfiguration extends AbstractScannerEx
addKeyword(GCCKeywords.cp__CONST, IToken.t_const);
addKeyword(GCCKeywords.cp__CONST__, IToken.t_const);
addKeyword(GCCKeywords.cp__DECLSPEC, IGCCToken.t__declspec);
addKeyword(GCCKeywords.cp__DECLTYPE, IToken.t_decltype);
addKeyword(GCCKeywords.cp__INLINE, IToken.t_inline);
addKeyword(GCCKeywords.cp__INLINE__, IToken.t_inline);
addKeyword(GCCKeywords.cp__RESTRICT, IToken.t_restrict);

View file

@ -19,39 +19,41 @@ package org.eclipse.cdt.core.parser;
*/
@SuppressWarnings("nls")
public class GCCKeywords {
public static final String TYPEOF = "typeof";
public static final String __ALIGNOF__ = "__alignof__";
public static final String __ATTRIBUTE__ = "__attribute__";
public static final String __DECLSPEC = "__declspec";
public static final String TYPEOF = "typeof";
public static final String __ALIGNOF__ = "__alignof__";
public static final String __ATTRIBUTE__ = "__attribute__";
public static final String __DECLSPEC = "__declspec";
/** @since 5.5 */
public static final String __DECLTYPE = "__decltype";
/** @since 5.5 */
public static final String __INT128 = "__int128";
/** @since 5.5 */
public static final String __FLOAT128 = "__float128";
public static final char[]
public static final char[]
cpTYPEOF = TYPEOF.toCharArray(),
cp__ALIGNOF__ = __ALIGNOF__.toCharArray(),
cp__ATTRIBUTE__ = __ATTRIBUTE__.toCharArray(),
cp__DECLSPEC = __DECLSPEC.toCharArray(),
cp__ALIGNOF = "__alignof".toCharArray(),
cp__ATTRIBUTE = "__attribute".toCharArray(),
cp__ASM= "__asm".toCharArray(),
cp__ASM__= "__asm__".toCharArray(),
cp__CONST= "__const".toCharArray(),
cp__CONST__= "__const__".toCharArray(),
cp__INLINE= "__inline".toCharArray(),
cp__INLINE__= "__inline__".toCharArray(),
cp__RESTRICT= "__restrict".toCharArray(),
cp__RESTRICT__= "__restrict__".toCharArray(),
cp__VOLATILE= "__volatile".toCharArray(),
cp__VOLATILE__= "__volatile__".toCharArray(),
cp__SIGNED= "__signed".toCharArray(),
cp__SIGNED__= "__signed__".toCharArray(),
cp__TYPEOF= "__typeof".toCharArray(),
cp__ALIGNOF = "__alignof".toCharArray(),
cp__ATTRIBUTE = "__attribute".toCharArray(),
cp__ASM= "__asm".toCharArray(),
cp__ASM__= "__asm__".toCharArray(),
cp__CONST= "__const".toCharArray(),
cp__CONST__= "__const__".toCharArray(),
cp__INLINE= "__inline".toCharArray(),
cp__INLINE__= "__inline__".toCharArray(),
cp__RESTRICT= "__restrict".toCharArray(),
cp__RESTRICT__= "__restrict__".toCharArray(),
cp__VOLATILE= "__volatile".toCharArray(),
cp__VOLATILE__= "__volatile__".toCharArray(),
cp__SIGNED= "__signed".toCharArray(),
cp__SIGNED__= "__signed__".toCharArray(),
cp__TYPEOF= "__typeof".toCharArray(),
cp__TYPEOF__= "__typeof__".toCharArray();
/** @since 5.3 */
public static final char[]
public static final char[]
cp__has_nothrow_assign= "__has_nothrow_assign".toCharArray(),
cp__has_nothrow_copy= "__has_nothrow_copy".toCharArray(),
cp__has_nothrow_constructor= "__has_nothrow_constructor".toCharArray(),
@ -70,7 +72,8 @@ public class GCCKeywords {
cp__is_union= "__is_union".toCharArray();
/** @since 5.5 */
public static final char[]
public static final char[]
cp__DECLTYPE= __DECLTYPE.toCharArray(),
cp__float128= __FLOAT128.toCharArray(),
cp__int128= __INT128.toCharArray(),
cp__is_literal_type= "__is_literal_type".toCharArray(),

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2009, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Thomas Corbat
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -69,9 +70,18 @@ public interface ITypeMarshalBuffer {
ISerializableEvaluation unmarshalEvaluation() throws CoreException;
ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException;
int getByte() throws CoreException;
int getShort() throws CoreException;
int getInt() throws CoreException;
long getLong() throws CoreException;
int getFixedInt() throws CoreException;
/**
* Reads a 32-bit integer stored in the variable length base-128 encoding.
*/
public int getInt() throws CoreException;
/**
* Reads a 64-bit integer stored in the variable length base-128 encoding.
*/
public long getLong() throws CoreException;
char[] getCharArray() throws CoreException;
void marshalType(IType type) throws CoreException;
@ -80,8 +90,53 @@ public interface ITypeMarshalBuffer {
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException;
void putByte(byte data);
void putShort(short data);
void putInt(int data);
void putLong(long data);
void putFixedInt(int data);
/**
* Writes a 32-bit integer in the variable length base-128 encoding. Each byte, except the last
* byte, has the most significant bit set this indicates that there are further bytes to come.
* The lower 7 bits of each byte are used to store the two-complement representation of
* the number in groups of 7 bits, least significant group first.
*
* <p>Here is number of bytes depending on the encoded value:
* <pre>
* Value Number of bytes
* [0,127] 1
* [128,16383] 2
* [16384,2097151] 3
* [2097152,268435455] 4
* [268435456,Integer.MAX_VALUE] 5
* negative 5
* </pre>
*
* @param value the value to write
*/
public void putInt(int value);
/**
* Writes a 64-bit integer in the variable length base-128 encoding. Each byte, except the last
* byte, has the most significant bit set this indicates that there are further bytes to come.
* The lower 7 bits of each byte are used to store the two-complement representation of
* the number in groups of 7 bits, least significant group first.
*
* <p>Here is number of bytes depending on the encoded value:
* <pre>
* Value Number of bytes
* [0,127] 1
* [128,16383] 2
* [16384,2097151] 3
* [2097152,268435455] 4
* [268435456,2^35-1] 5
* [2^35,2^42-1] 6
* [2^42,2^49-1] 7
* [2^49,2^56-1] 8
* [2^56,2^63-1] 9
* negative 10
* </pre>
*
* @param value the value to write
*/
public void putLong(long value);
void putCharArray(char[] data);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -28,11 +29,11 @@ public class ProblemFunctionType extends ProblemType implements ICPPFunctionType
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
buffer.putByte((byte) (ITypeMarshalBuffer.PROBLEM_TYPE | ITypeMarshalBuffer.FLAG1));
buffer.putShort((short) getID());
buffer.putInt(getID());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
return new ProblemFunctionType(buffer.getShort());
return new ProblemFunctionType(buffer.getInt());
}
@Override

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* Copyright (c) 2010, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -56,13 +57,13 @@ public class ProblemType implements IProblemType, ISerializableType {
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.PROBLEM_TYPE);
buffer.putShort((short) getID());
buffer.putInt(getID());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
return ProblemFunctionType.unmarshal(firstByte, buffer);
return new ProblemType(buffer.getShort());
return new ProblemType(buffer.getInt());
}
}

View file

@ -154,12 +154,12 @@ public class Value implements IValue {
Long num= numericalValue();
if (num != null) {
long lv= num;
if (lv >= Integer.MIN_VALUE && lv <= Integer.MAX_VALUE) {
if (lv >= 0) {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG2));
buf.putInt((int) lv);
buf.putLong(lv);
} else {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG3));
buf.putLong(lv);
buf.putLong(-lv);
}
} else if (fFixedValue != null) {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG4));
@ -177,18 +177,13 @@ public class Value implements IValue {
return null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
return Value.UNKNOWN;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
int val= buf.getInt();
return Value.create(val);
}
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
long val= buf.getLong();
return Value.create(val);
}
if ((firstByte & ITypeMarshalBuffer.FLAG4) != 0) {
char[] fixedValue = buf.getCharArray();
return new Value(fixedValue, null);
}
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0)
return Value.create(buf.getLong());
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0)
return Value.create(-buf.getLong());
if ((firstByte & ITypeMarshalBuffer.FLAG4) != 0)
return new Value(buf.getCharArray(), null);
ISerializableEvaluation eval= buf.unmarshalEvaluation();
if (eval instanceof ICPPEvaluation)
return new Value(null, (ICPPEvaluation) eval);

View file

@ -1,12 +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, 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:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -161,7 +162,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.ARRAY_TYPE;
int flags= 0;
short nval= -1;
long nval= -1;
IValue val= null;
if (isConst()) flags |= 0x01;
@ -178,9 +179,8 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
firstByte |= ITypeMarshalBuffer.FLAG2;
Long num= val.numericalValue();
if (num != null) {
long l= num;
if (l >= 0 && l <= Short.MAX_VALUE) {
nval= (short) l;
nval= num;
if (nval >= 0) {
firstByte |= ITypeMarshalBuffer.FLAG3;
}
}
@ -190,7 +190,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
buffer.putByte((byte) flags);
}
if (nval >= 0) {
buffer.putShort(nval);
buffer.putLong(nval);
} else if (val != null) {
buffer.marshalValue(val);
}
@ -200,11 +200,11 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int flags= 0;
IValue value= null;
if ( (firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
flags= buffer.getByte();
}
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
value = Value.create(buffer.getShort());
value = Value.create(buffer.getLong());
} else if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
value = buffer.unmarshalValue();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -87,7 +88,7 @@ public class CFunctionType implements IFunctionType, ISerializableType {
} else {
firstByte |= ITypeMarshalBuffer.FLAG4;
buffer.putByte((byte) firstByte);
buffer.putShort((short) len);
buffer.putInt(len);
}
buffer.marshalType(returnType);
@ -99,7 +100,7 @@ public class CFunctionType implements IFunctionType, ISerializableType {
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len;
if (((firstByte & ITypeMarshalBuffer.FLAG4) != 0)) {
len= buffer.getShort();
len= buffer.getInt();
} else {
len= (firstByte & (ITypeMarshalBuffer.FLAG4-1))/ITypeMarshalBuffer.FLAG1;
}

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -23,9 +23,8 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/**
* Initializer list in parenthesis.
*/
public class CPPASTConstructorInitializer extends ASTNode implements ICPPASTConstructorInitializer,
IASTAmbiguityParent {
public class CPPASTConstructorInitializer extends ASTNode
implements ICPPASTConstructorInitializer, IASTAmbiguityParent {
private IASTInitializerClause[] fArguments;
public CPPASTConstructorInitializer() {
@ -51,11 +50,7 @@ public class CPPASTConstructorInitializer extends ASTNode implements ICPPASTCons
}
}
CPPASTConstructorInitializer copy = new CPPASTConstructorInitializer(args);
copy.setOffsetAndLength(this);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
return copy(copy, style);
}
@Override

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -122,9 +123,9 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy
Long num= val.numericalValue();
if (num != null) {
long lnum= num;
if (lnum >= 0 && lnum <= Short.MAX_VALUE) {
if (lnum >= 0) {
buffer.putByte((byte) (firstByte | ITypeMarshalBuffer.FLAG1));
buffer.putShort((short) lnum);
buffer.putLong(lnum);
buffer.marshalType(getType());
return;
}
@ -137,7 +138,7 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IValue value= null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
value = Value.create(buffer.getShort());
value = Value.create(buffer.getLong());
} else if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
value = buffer.unmarshalValue();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* Copyright (c) 2005, 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
@ -230,15 +230,16 @@ public class CPPDeferredClassInstance extends CPPUnknownBinding implements ICPPD
int firstByte= ITypeMarshalBuffer.DEFERRED_CLASS_INSTANCE;
buffer.putByte((byte) firstByte);
buffer.marshalBinding(fClassTemplate);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPTemplateArgument arg : fArguments) {
buffer.marshalTemplateArgument(arg);
}
}
public static ICPPDeferredClassInstance unmarshal(IIndexFragment fragment, int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
public static ICPPDeferredClassInstance unmarshal(IIndexFragment fragment, int firstByte,
ITypeMarshalBuffer buffer) throws CoreException {
IBinding template= buffer.unmarshalBinding();
int argcount= buffer.getShort() & 0xffff;
int argcount= buffer.getInt();
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
for (int i = 0; i < argcount; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others.
* Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -140,29 +141,17 @@ public class CPPFunctionType implements ICPPFunctionType, ISerializableType {
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (takesVarArgs()) firstByte |= ITypeMarshalBuffer.FLAG3;
int len= (parameters.length & 0xffff);
if (len > 0xff) {
firstByte |= ITypeMarshalBuffer.FLAG4;
buffer.putByte((byte) firstByte);
buffer.putShort((short) len);
} else {
buffer.putByte((byte) firstByte);
buffer.putByte((byte) len);
}
buffer.putByte((byte) firstByte);
buffer.putInt(parameters.length);
buffer.marshalType(returnType);
for (int i = 0; i < len; i++) {
for (int i = 0; i < parameters.length; i++) {
buffer.marshalType(parameters[i]);
}
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len;
if (((firstByte & ITypeMarshalBuffer.FLAG4) != 0)) {
len= buffer.getShort();
} else {
len= buffer.getByte();
}
int len= buffer.getInt();
IType rt= buffer.unmarshalType();
IType[] pars= new IType[len];
for (int i = 0; i < pars.length; i++) {

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Niefer (IBM Corporation) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Niefer (IBM Corporation) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -40,29 +40,34 @@ import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.model.ASTStringUtil;
import org.eclipse.core.runtime.PlatformObject;
public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPInternalBinding {
public static class CPPNamespaceProblem extends ProblemBinding implements ICPPNamespace, ICPPNamespaceScope{
public static class CPPNamespaceProblem extends ProblemBinding implements ICPPNamespace, ICPPNamespaceScope {
public CPPNamespaceProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg);
}
@Override
public ICPPNamespaceScope getNamespaceScope() {
return this;
}
@Override
public IBinding[] getMemberBindings() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public void addUsingDirective(ICPPUsingDirective usingDirective) {
}
@Override
public ICPPUsingDirective[] getUsingDirectives() {
return ICPPUsingDirective.EMPTY_ARRAY;
}
@Override
public ICPPNamespaceScope[] getInlineNamespaces() {
return ICPPNamespaceScope.EMPTY_NAMESPACE_SCOPE_ARRAY;
@ -79,28 +84,22 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
namespaceDefinitions = new IASTName[] { nsDef.getName() };
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations()
*/
@Override
public IASTNode[] getDeclarations() {
return namespaceDefinitions;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDefinition()
*/
@Override
public IASTNode getDefinition() {
return (tu != null) ? tu : (IASTNode) namespaceDefinitions[0];
return tu != null ? tu : (IASTNode) namespaceDefinitions[0];
}
static private class NamespaceCollector extends ASTVisitor {
private ICPPASTNamespaceDefinition namespaceDef = null;
private IASTName[] namespaces = null;
public NamespaceCollector(ICPPASTNamespaceDefinition ns ) {
private ICPPASTNamespaceDefinition namespaceDef;
private IASTName[] namespaces;
public NamespaceCollector(ICPPASTNamespaceDefinition ns) {
shouldVisitNamespaces = true;
shouldVisitDeclarations = true;
this.namespaceDef = ns;
@ -127,39 +126,41 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
namespaces = ArrayUtil.append(IASTName.class, namespaces, namespace.getName());
return PROCESS_SKIP;
}
@Override
public int visit(IASTDeclaration declaration) {
if (declaration instanceof ICPPASTLinkageSpecification)
return PROCESS_CONTINUE;
return PROCESS_SKIP;
}
public IASTName[] getNamespaces() {
return ArrayUtil.trim(IASTName.class, namespaces);
}
}
static private class NamespaceMemberCollector extends ASTVisitor {
public ObjectSet<IBinding> members = new ObjectSet<IBinding>(8);
public NamespaceMemberCollector() {
shouldVisitNamespaces = true;
shouldVisitDeclarators = true;
shouldVisitDeclSpecifiers = true;
shouldVisitDeclarations = true;
}
@Override
public int visit(IASTDeclarator declarator) {
while(declarator.getNestedDeclarator() != null)
declarator = declarator.getNestedDeclarator();
IBinding binding = declarator.getName().resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding))
members.put(binding);
return PROCESS_SKIP;
}
@Override
public int visit(IASTDeclSpecifier declSpec) {
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
@ -172,7 +173,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
if (parent instanceof IASTSimpleDeclaration) {
if (((IASTSimpleDeclaration)parent).getDeclarators().length > 0)
return PROCESS_SKIP;
IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
if (binding != null && !(binding instanceof IProblemBinding))
members.put(binding);
@ -181,6 +182,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
}
return PROCESS_SKIP;
}
@Override
public int visit(ICPPASTNamespaceDefinition namespace) {
IBinding binding = namespace.getName().resolveBinding();
@ -188,6 +190,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
members.put(binding);
return PROCESS_SKIP;
}
@Override
public int visit(IASTDeclaration declaration) {
if (declaration instanceof ICPPASTUsingDeclaration) {
@ -201,6 +204,7 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
return PROCESS_CONTINUE;
}
}
private void findAllDefinitions(ICPPASTNamespaceDefinition namespaceDef) {
NamespaceCollector collector = new NamespaceCollector(namespaceDef);
namespaceDef.getTranslationUnit().accept(collector);
@ -210,115 +214,68 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
namespaceDefinition.setBinding(this);
}
}
public IASTName[] getNamespaceDefinitions() {
return namespaceDefinitions;
}
/**
* @param unit
*/
public CPPNamespace(CPPASTTranslationUnit unit) {
tu = unit;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace#getNamespaceScope()
*/
@Override
public ICPPNamespaceScope getNamespaceScope() {
if (scope == null) {
if (tu != null)
if (tu != null) {
scope = (ICPPNamespaceScope) tu.getScope();
else
} else {
scope = new CPPNamespaceScope(namespaceDefinitions[0].getParent());
}
}
return scope;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
@Override
public String getName() {
return new String(getNameCharArray());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
@Override
public char[] getNameCharArray() {
return tu != null ? CharArrayUtils.EMPTY_CHAR_ARRAY : namespaceDefinitions[0].getSimpleID();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
@Override
public IScope getScope() {
return tu != null ? null : CPPVisitor.getContainingScope(namespaceDefinitions[0]);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return tu != null ? (IASTNode) tu : namespaceDefinitions[0];
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getFullyQualifiedName()
*/
public String[] getFullyQualifiedName() {
return CPPVisitor.getQualifiedName(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getFullyQualifiedNameCharArray()
*/
public char[][] getFullyQualifiedNameCharArray() {
return CPPVisitor.getQualifiedNameCharArray(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedName()
*/
@Override
public String[] getQualifiedName() {
return CPPVisitor.getQualifiedName(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedNameCharArray()
*/
@Override
public char[][] getQualifiedNameCharArray() {
return CPPVisitor.getQualifiedNameCharArray(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#isGloballyQualified()
*/
@Override
public boolean isGloballyQualified() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
@Override
public void addDefinition(IASTNode node) {
if (!(node instanceof IASTName))
return;
IASTName name = (IASTName) node;
if (namespaceDefinitions == null) {
namespaceDefinitions = new IASTName[] { name };
return;
}
if (namespaceDefinitions.length > 0 && ((ASTNode)name).getOffset() < ((ASTNode)namespaceDefinitions[0]).getOffset()) {
namespaceDefinitions = ArrayUtil.prepend(IASTName.class, namespaceDefinitions, name);
} else {
@ -326,9 +283,6 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
@Override
public void addDeclaration(IASTNode node) {
addDefinition(node);
@ -370,11 +324,17 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
public String toString() {
String[] names = getQualifiedName();
if (names.length == 0) {
return "<unnamed namespace>"; //$NON-NLS-1$
return "<global namespace>"; //$NON-NLS-1$
}
return ASTStringUtil.join(names, String.valueOf(Keywords.cpCOLONCOLON));
StringBuilder buf = new StringBuilder();
for (String name : names) {
if (buf.length() != 0)
buf.append(Keywords.cpCOLONCOLON);
buf.append(name.isEmpty() ? "<anonymous>" : name); //$NON-NLS-1$
}
return buf.toString();
}
@Override
public IBinding getOwner() {
if (namespaceDefinitions != null && namespaceDefinitions.length > 0) {

View file

@ -80,8 +80,8 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace
private void initUsingDirectives() {
if (fUsingDirectives == null) {
fUsingDirectives= new ArrayList<ICPPUsingDirective>(1);
// Insert a using directive for every inline namespace found in the index
for (ICPPInternalNamespaceScope inline: getIndexInlineNamespaces()) {
// Insert a using directive for every inline namespace found in the index.
for (ICPPInternalNamespaceScope inline : getIndexInlineNamespaces()) {
if (!(inline instanceof CPPNamespaceScope)) {
fUsingDirectives.add(new InlineNamespaceDirective(this, inline));
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2010 Google, Inc and others.
* Copyright (c) 2008, 2012 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
@ -86,7 +86,7 @@ public class CPPUnknownClassInstance extends CPPUnknownMemberClass implements IC
buffer.putByte((byte) firstByte);
buffer.marshalType(getOwnerType());
buffer.putCharArray(getNameCharArray());
buffer.putShort((short) arguments.length);
buffer.putInt(arguments.length);
for (ICPPTemplateArgument arg : arguments) {
buffer.marshalTemplateArgument(arg);
}
@ -95,7 +95,7 @@ public class CPPUnknownClassInstance extends CPPUnknownMemberClass implements IC
public static ICPPUnknownMemberClassInstance unmarshal(IIndexFragment fragment, int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IType owner= buffer.unmarshalType();
char[] name = buffer.getCharArray();
int argcount= buffer.getShort() & 0xffff;
int argcount= buffer.getInt();
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
for (int i = 0; i < argcount; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2012 IBM Corporation and others.
* Copyright (c) 2002, 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
@ -942,7 +942,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
lt1= LT(1);
if (lt1 != IToken.tCOLON && lt1 != IToken.tCOMMA)
stopWithNextOperator= true;
break;
} else if (allowBraceInitializer && LT(1) == IToken.tLBRACE) {
// Brace initializer
expr= bracedInitList(true);
@ -2058,7 +2057,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
List<ICPPASTTemplateParameter> parms= outerTemplateParameterList();
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
if (LT(1) != IToken.tEOC) {
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
}
IASTDeclaration d = declaration(option);
ICPPASTTemplateDeclaration templateDecl = nodeFactory.newTemplateDeclaration(d);
setRange(templateDecl, offset, calculateEndOffset(d));

View file

@ -126,7 +126,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
@Override
public void putShort(short value) {
public void putFixedInt(int value) {
appendSeparator();
fBuffer.append(value);
}
@ -192,7 +192,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
@Override
public int getShort() throws CoreException {
public int getFixedInt() throws CoreException {
throw new UnsupportedOperationException();
}

View file

@ -663,7 +663,9 @@ public class CPPTemplates {
IBinding owner = template.getOwner();
ICPPClassSpecialization within = getSpecializationContext(owner);
IType instantiatedType = instantiateType(aliasedType, parameterMap, -1, within, id);
return new CPPAliasTemplateInstance(id.toCharArray(), aliasTemplate, instantiatedType);
StringBuilder buf= new StringBuilder();
buf.append(id.getSimpleID()).append(ASTTypeUtil.getArgumentListString(args, false));
return new CPPAliasTemplateInstance(buf.toString().toCharArray(), aliasTemplate, instantiatedType);
}
// Class template.

View file

@ -2038,6 +2038,10 @@ public class CPPVisitor extends ASTQueries {
IASTInitializer initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof ICPPASTConstructorInitializer) {
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initClause).getArguments();
if (arguments.length == 1)
autoInitClause = (ICPPASTInitializerClause) arguments[0];
} else if (initClause instanceof ICPPASTInitializerClause) {
autoInitClause= (ICPPASTInitializerClause) initClause;
}

View file

@ -300,7 +300,7 @@ public class EvalBinding extends CPPEvaluation {
// function and the parameter position instead.
buffer.putByte((byte) (ITypeMarshalBuffer.EVAL_BINDING | ITypeMarshalBuffer.FLAG1));
buffer.marshalBinding(parameterOwner);
buffer.putShort((short) getFunctionParameterPosition());
buffer.putInt(getFunctionParameterPosition());
} else {
buffer.putByte(firstByte);
buffer.marshalBinding(fBinding);
@ -311,7 +311,7 @@ public class EvalBinding extends CPPEvaluation {
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
ICPPFunction parameterOwner= (ICPPFunction) buffer.unmarshalBinding();
int parameterPosition= buffer.getShort();
int parameterPosition= buffer.getInt();
IType type= buffer.unmarshalType();
return new EvalBinding(parameterOwner, parameterPosition, type);
} else {

View file

@ -155,14 +155,14 @@ public class EvalComma extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_COMMA);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -143,9 +143,11 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
ICPPEvaluation eval = computeForFunctionCall(Value.MAX_RECURSION_DEPTH, point);
if (eval instanceof EvalFixed)
return ((EvalFixed) eval).getValue();
eval = new EvalFixed(getTypeOrFunctionSet(point), PRVALUE, eval.getValue(point));
if (eval != this) {
if (eval instanceof EvalFixed)
return ((EvalFixed) eval).getValue();
eval = new EvalFixed(getTypeOrFunctionSet(point), PRVALUE, eval.getValue(point));
}
return Value.create(eval);
}
@ -168,14 +170,14 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_FUNCTION_CALL);
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -110,12 +110,12 @@ public class EvalFunctionSet extends CPPEvaluation {
firstByte |= ITypeMarshalBuffer.FLAG2;
buffer.putByte((byte) firstByte);
buffer.putShort((short) bindings.length);
buffer.putInt(bindings.length);
for (ICPPFunction binding : bindings) {
buffer.marshalBinding(binding);
}
if (args != null) {
buffer.putShort((short) args.length);
buffer.putInt(args.length);
for (ICPPTemplateArgument arg : args) {
buffer.marshalTemplateArgument(arg);
}
@ -124,14 +124,14 @@ public class EvalFunctionSet extends CPPEvaluation {
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean addressOf= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
int bindingCount= buffer.getShort();
int bindingCount= buffer.getInt();
ICPPFunction[] bindings= new ICPPFunction[bindingCount];
for (int i = 0; i < bindings.length; i++) {
bindings[i]= (ICPPFunction) buffer.unmarshalBinding();
}
ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -151,7 +151,7 @@ public class EvalID extends CPPEvaluation {
buffer.putCharArray(fName);
buffer.marshalBinding(fNameOwner);
if (fTemplateArgs != null) {
buffer.putShort((short) fTemplateArgs.length);
buffer.putInt(fTemplateArgs.length);
for (ICPPTemplateArgument arg : fTemplateArgs) {
buffer.marshalTemplateArgument(arg);
}
@ -166,7 +166,7 @@ public class EvalID extends CPPEvaluation {
IBinding nameOwner= buffer.unmarshalBinding();
ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();

View file

@ -87,14 +87,14 @@ public class EvalInitList extends CPPEvaluation {
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_INIT_LIST);
buffer.putShort((short) fClauses.length);
buffer.putInt(fClauses.length);
for (ICPPEvaluation arg : fClauses) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
int len= buffer.getInt();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -123,7 +123,7 @@ public class EvalTypeId extends CPPEvaluation {
buffer.putByte((byte) firstByte);
buffer.marshalType(fInputType);
if (includeValue) {
buffer.putShort((short) fArguments.length);
buffer.putInt(fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
@ -134,7 +134,7 @@ public class EvalTypeId extends CPPEvaluation {
IType type= buffer.unmarshalType();
ICPPEvaluation[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
int len= buffer.getShort();
int len= buffer.getInt();
args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
/**
@ -18,7 +17,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
* @since 5.0
*/
public interface ILocationCtx {
/**
* If this is a file context the filename of this context is returned,
* otherwise the filename of the first enclosing context that is a file context is returned.

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
@ -23,20 +23,19 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.internal.core.dom.parser.ASTNodeSpecification;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
/**
* Interface between the ast and the location-resolver for resolving offsets.
* Interface between the AST and the location-resolver for resolving offsets.
* @since 5.0
*/
public interface ILocationResolver {
/**
* Introduces the ast translation unit to the location resolver. Must be called before any tokens from the
* scanner are obtained.
* Introduces the AST translation unit to the location resolver. Must be called before any
* tokens from the scanner are obtained.
*/
void setRootNode(IASTTranslationUnit tu);
@ -103,15 +102,17 @@ public interface ILocationResolver {
/**
* Returns the smallest file location, that encloses the given global range. In case the range
* spans over multiple files, the files are mapped to include statements until all of them are
* found in the same file. So the resulting location contains the include directives that actually
* cause the range to be part of the AST.
* found in the same file. So the resulting location contains the include directives that
* actually cause the range to be part of the AST.
* @param offset sequence number as stored in the ASTNodes.
* @param length
*/
IASTFileLocation getMappedFileLocation(int offset, int length);
/**
* Returns an array of locations. This is a sequence of file locations and macro-expansion locations.
* Returns an array of locations. This is a sequence of file locations and macro-expansion
* locations.
*
* @param offset sequence number as stored in the ast nodes.
* @param length
* @return and array of locations.
@ -124,8 +125,8 @@ public interface ILocationResolver {
IASTImageLocation getImageLocation(int offset, int length);
/**
* Returns the sequence-number for the given file-path and offset, or <code>-1</code> if this file
* is not part of the translation-unit.
* Returns the sequence-number for the given file-path and offset, or <code>-1</code> if this
* file is not part of the translation-unit.
* @param filePath a file path or <code>null</code> to specify the root of the translation unit.
* @param fileOffset an offset into the source of the file, or <code>-1</code>.
*/
@ -158,7 +159,8 @@ public interface ILocationResolver {
boolean isPartOfSourceFile(int sequenceNumber);
/**
* Same as {@link #getMappedFileLocation(int, int)} for the given array of consecutive node locations.
* Same as {@link #getMappedFileLocation(int, int)} for the given array of consecutive node
* locations.
*/
IASTFileLocation flattenLocations(IASTNodeLocation[] nodeLocations);

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
@ -15,13 +15,13 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
/**
* Information needed for computing image-locations. An image location exists for a name and describes where the name
* came from. This can be: source code, macro-expansion, parameter to macro-expansion or synthetic.
* Information needed for computing image-locations. An image location exists for a name and
* describes where the name came from. This can be: source code, macro-expansion, parameter to
* macro-expansion or synthetic.
*
* @since 5.0
*/
public abstract class ImageLocationInfo {
public static final ImageLocationInfo[] NO_LOCATION_INFOS= {};
int fTokenOffsetInExpansion= -1;
@ -33,6 +33,7 @@ public abstract class ImageLocationInfo {
private final ObjectStyleMacro fMacro;
private final int fOffset;
private final int fEndOffset;
public MacroImageLocationInfo(ObjectStyleMacro macro, int offset, int endOffset) {
fMacro= macro;
fOffset= offset;
@ -66,14 +67,16 @@ public abstract class ImageLocationInfo {
public static class ParameterImageLocationInfo extends ImageLocationInfo {
public int fSequenceNumber;
public int fSequenceEndNumber;
public ParameterImageLocationInfo(int sequenceNumber, int sequenceEndNumber) {
fSequenceNumber= sequenceNumber;
fSequenceEndNumber= sequenceEndNumber;
}
@Override
public IASTImageLocation createLocation(LocationMap lm, ImageLocationInfo upto) {
int sequenceEnd= ((ParameterImageLocationInfo) upto).fSequenceEndNumber;
IASTFileLocation loc= lm.getMappedFileLocation(fSequenceNumber, sequenceEnd-fSequenceNumber);
IASTFileLocation loc= lm.getMappedFileLocation(fSequenceNumber, sequenceEnd - fSequenceNumber);
if (loc != null) {
return new ASTImageLocation(IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION,
loc.getFileName(), loc.getNodeOffset(), loc.getNodeLength());

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;

View file

@ -7,7 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
@ -19,7 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit.IDependencyTree.IASTIncl
/**
* Various location contexts which are suitable for interpreting local offsets. These offsets are
* converted in a global sequence-number to make all ast nodes comparable with each other.
* converted in a global sequence-number to make all AST nodes comparable with each other.
* @since 5.0
*/
abstract class LocationCtx implements ILocationCtx {
@ -29,11 +29,13 @@ abstract class LocationCtx implements ILocationCtx {
*/
final int fSequenceNumber;
/**
* The offset of the denotation of this context in the parent's source. This is no sequence number.
* The offset of the denotation of this context in the parent's source. This is no sequence
* number.
*/
final int fOffsetInParent;
/**
* The end-offset of the denotation of this context in the parent's source. This is no sequence number.
* The end-offset of the denotation of this context in the parent's source. This is no sequence
* number.
*/
final int fEndOffsetInParent;
@ -46,40 +48,41 @@ abstract class LocationCtx implements ILocationCtx {
parent.addChild(this);
}
}
@Override
public String getFilePath() {
return fParent.getFilePath();
}
@Override
final public ILocationCtx getParent() {
return fParent;
}
/**
* Returns the amount of sequence numbers occupied by this context including its children.
*/
public abstract int getSequenceLength();
/**
* Converts an offset within this context to the sequence number. In case there are child-contexts
* behind the given offset, you need to set checkChildren to <code>true</code>.
* Converts an offset within this context to the sequence number. In case there are
* child-contexts behind the given offset, you need to set checkChildren to <code>true</code>.
*/
public int getSequenceNumberForOffset(int offset, boolean checkChildren) {
return fSequenceNumber+offset;
}
/**
* When a child-context is finished it reports its total sequence length, such that offsets in this
* context can be converted to sequence numbers.
* When a child-context is finished it reports its total sequence length, such that offsets in
* this context can be converted to sequence numbers.
*/
public void addChildSequenceLength(int childLength) {
assert false;
}
/**
* Returns the line number for an offset within this context. Not all contexts support line numbers,
* so this may return 0.
* Returns the line number for an offset within this context. Not all contexts support line
* numbers, so this may return 0.
*/
public int getLineNumber(int offset) {
return 0;
@ -109,7 +112,7 @@ abstract class LocationCtx implements ILocationCtx {
}
/**
* Returns the minimal file location containing the specified sequence number range, assuming
* Returns the minimal file location containing the specified sequence number range, assuming
* that it is contained in this context.
*/
public ASTFileLocation findMappedFileLocation(int sequenceNumber, int length) {
@ -124,8 +127,8 @@ abstract class LocationCtx implements ILocationCtx {
}
/**
* Returns the sequence of file locations spanning the given range.
* Assumes that the range starts within this context.
* 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<IASTNodeLocation> sofar);
@ -136,7 +139,8 @@ abstract class LocationCtx implements ILocationCtx {
}
/**
* Support for the dependency tree, returns inclusion statement that created this context, or <code>null</code>.
* Support for the dependency tree, returns inclusion statement that created this context,
* or <code>null</code>.
*/
@Override
public ASTInclusionStatement getInclusionStatement() {

View file

@ -35,7 +35,8 @@ class LocationCtxContainer extends LocationCtx {
private AbstractCharArray fSource;
private int[] fLineOffsets;
public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source, int parentOffset, int parentEndOffset, int sequenceNumber) {
public LocationCtxContainer(LocationCtxContainer parent, AbstractCharArray source,
int parentOffset, int parentEndOffset, int sequenceNumber) {
super(parent, parentOffset, parentEndOffset, sequenceNumber);
fSource= source;
}

View file

@ -79,7 +79,7 @@ class LocationCtxMacroExpansion extends LocationCtx {
if (length == 0) {
return null;
}
final int end= offset+length;
final int end= offset + length;
int nextToCheck= offset;
ImageLocationInfo firstInfo= null;
ImageLocationInfo lastInfo= null;

View file

@ -7,7 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
@ -45,22 +45,22 @@ public class MacroDefinitionParser {
*/
static class TokenParameterReference extends TokenWithImage {
private final int fIndex;
public TokenParameterReference(int type, int idx, Object source, int offset, int endOffset, char[] name) {
super(type, source, offset, endOffset, name);
fIndex= idx;
}
public int getIndex() {
return fIndex;
}
@Override
public String toString() {
return "[" + fIndex + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public static char[] getExpansion(AbstractCharArray expansionImage, int offset, int endOffset) {
TokenList tl= new TokenList();
Lexer lex= new Lexer(expansionImage, offset, endOffset, new LexerOptions(), ILexerLog.NULL, null);
@ -83,7 +83,7 @@ public class MacroDefinitionParser {
buf.append(t.getCharImage());
endOffset= t.getEndOffset();
}
final int length= buf.length();
final int length= buf.length();
final char[] expansion= new char[length];
buf.getChars(0, length, expansion, 0);
return expansion;
@ -93,10 +93,10 @@ public class MacroDefinitionParser {
private int fExpansionOffset;
private int fExpansionEndOffset;
private Token fNameToken;
MacroDefinitionParser() {
}
/**
* In case the name was successfully parsed, the name token is returned.
* Otherwise the return value is undefined.
@ -105,10 +105,10 @@ public class MacroDefinitionParser {
return fNameToken;
}
/**
/**
* Parses an entire macro definition. Name must be the next token of the lexer.
*/
public ObjectStyleMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log)
public ObjectStyleMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log)
throws OffsetLimitReachedException, InvalidMacroDefinitionException {
final Token name = parseName(lexer);
final AbstractCharArray source= lexer.getInput();
@ -122,10 +122,10 @@ public class MacroDefinitionParser {
return new FunctionStyleMacro(nameChars, paramList, fHasVarArgs, fExpansionOffset, fExpansionEndOffset, replacement, source);
}
/**
/**
* Parses a macro definition without the replacement. Name must be the next token of the lexer.
*/
public PreprocessorMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log, final char[] replacement)
public PreprocessorMacro parseMacroDefinition(final Lexer lexer, final ILexerLog log, final char[] replacement)
throws InvalidMacroDefinitionException, OffsetLimitReachedException {
final Token name = parseName(lexer);
@ -135,14 +135,14 @@ public class MacroDefinitionParser {
if (replacementToken.getType() != IToken.tEND_OF_INPUT) {
throw new InvalidMacroDefinitionException(nameChars, replacementToken.getOffset(), replacementToken.getEndOffset());
}
if (paramList == null) {
if (paramList == null) {
return new ObjectStyleMacro(nameChars, replacement);
}
return new FunctionStyleMacro(nameChars, paramList, fHasVarArgs, replacement);
}
/**
/**
* Parses a macro definition basically checking for var-args.
*/
public static PreprocessorMacro parseMacroDefinition(final char[] name, char[][] paramList, final char[] replacement) {
@ -152,7 +152,7 @@ public class MacroDefinitionParser {
if (length > 0) {
char[] lastParam= paramList[length-1];
final int lpl = lastParam.length;
switch(lpl) {
switch (lpl) {
case 0: case 1: case 2:
break;
case 3:
@ -176,8 +176,8 @@ public class MacroDefinitionParser {
}
}
}
if (paramList == null) {
if (paramList == null) {
return new ObjectStyleMacro(name, replacement);
}
return new FunctionStyleMacro(name, paramList, hasVarargs, replacement);
@ -195,11 +195,11 @@ public class MacroDefinitionParser {
fNameToken= name;
return name;
}
private char[][] parseParamList(Lexer lex, final Token name) throws OffsetLimitReachedException, InvalidMacroDefinitionException {
final Token lparen= lex.nextToken();
fHasVarArgs= FunctionStyleMacro.NO_VAARGS;
if (lparen.getType() != IToken.tLPAREN || name.getEndOffset() != lparen.getOffset()) {
if (lparen.getType() != IToken.tLPAREN || name.getEndOffset() != lparen.getOffset()) {
return null;
}
ArrayList<char[]> paramList= new ArrayList<char[]>();
@ -224,7 +224,7 @@ public class MacroDefinitionParser {
paramList.add(Keywords.cVA_ARGS);
next= lex.nextToken();
break;
case IToken.tRPAREN:
if (next == null) {
next= param;
@ -255,10 +255,10 @@ public class MacroDefinitionParser {
Token needAnotherToken= null;
Token candidate= lexer.currentToken();
fExpansionOffset= fExpansionEndOffset= candidate.getOffset();
fExpansionOffset= fExpansionEndOffset= candidate.getOffset();
loop: while(true) {
switch(candidate.getType()) {
switch (candidate.getType()) {
case IToken.tCOMPLETION:
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, candidate);
case IToken.tEND_OF_INPUT:
@ -266,18 +266,16 @@ public class MacroDefinitionParser {
break loop;
case IToken.tIDENTIFIER:
if (paramList != null) {
// convert the parameters to special tokens
// Convert the parameters to special tokens.
final char[] image = candidate.getCharImage();
int idx= CharArrayUtils.indexOf(image, paramList);
if (idx >= 0) {
candidate= new TokenParameterReference(CPreprocessor.tMACRO_PARAMETER, idx, lexer.getSource(), candidate.getOffset(), candidate.getEndOffset(), paramList[idx]);
needParam= false;
}
else {
} else {
if (needParam) {
log.handleProblem(IProblem.PREPROCESSOR_MACRO_PASTING_ERROR, name, fExpansionOffset, candidate.getEndOffset());
}
else if (CharArrayUtils.equals(Keywords.cVA_ARGS, image)) {
} else if (CharArrayUtils.equals(Keywords.cVA_ARGS, image)) {
log.handleProblem(IProblem.PREPROCESSOR_INVALID_VA_ARGS, null, fExpansionOffset, candidate.getEndOffset());
}
needParam= false;

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
@ -35,9 +35,9 @@ public class MacroExpander {
private static final class AbortMacroExpansionException extends Exception {}
private static final int ORIGIN = OffsetLimitReachedException.ORIGIN_MACRO_EXPANSION;
private static final TokenList EMPTY_TOKEN_LIST = new TokenList();
private static final TokenList EMPTY_TOKEN_LIST = new TokenList();
/**
/**
* Marks the beginning and the end of the scope of a macro expansion. Necessary to properly
* handle recursive expansions and to figure out whether spaces are required during a stringify
* operation across such boundaries.
@ -56,7 +56,7 @@ public class MacroExpander {
public char[] getCharImage() {
return CharArrayUtils.EMPTY;
}
@Override
public String toString() {
return "{" + (fIsStart ? '+' : '-') + fMacro.getName() + '}'; //$NON-NLS-1$
@ -70,8 +70,8 @@ public class MacroExpander {
}
}
}
/**
/**
* Combines a list of tokens with the preprocessor to form the input for macro expansion.
*/
private class TokenSource extends TokenList {
@ -112,7 +112,7 @@ public class MacroExpander {
if (fLexer != null) {
t= fLexer.currentToken();
while(t.getType() == Lexer.tNEWLINE) {
while (t.getType() == Lexer.tNEWLINE) {
t= fLexer.nextToken();
}
return t.getType() == IToken.tLPAREN;
@ -131,25 +131,26 @@ public class MacroExpander {
private boolean fCompletionMode;
private int fStartOffset;
private int fEndOffset;
// for using the expander to track expansions
private String fFixedCurrentFilename;
private int fFixedLineNumber;
private char[] fFixedInput;
private ScannerContext fReportMacros;
private boolean fReportUndefined;
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary, LocationMap locationMap, LexerOptions lexOptions) {
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary,
LocationMap locationMap, LexerOptions lexOptions) {
fDictionary= macroDictionary;
fLocationMap= locationMap;
fDefinitionParser= new MacroDefinitionParser();
fLexOptions= lexOptions;
fLog= log;
}
/**
/**
* Expects that the identifier has been consumed, stores the result in the list provided.
* @param scannerContext
* @param scannerContext
*/
public TokenList expand(ITokenSequence lexer, final int ppOptions,
PreprocessorMacro macro, Token identifier, boolean completionMode,
@ -161,16 +162,16 @@ public class MacroExpander {
} else {
fReportMacros= null;
}
fImplicitMacroExpansions.clear();
fImageLocationInfos.clear();
fStartOffset= identifier.getOffset();
fEndOffset= identifier.getEndOffset();
fCompletionMode= completionMode;
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden= new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
// setup input sequence
TokenSource input= new TokenSource(lexer);
TokenList firstExpansion= new TokenList();
@ -185,8 +186,8 @@ public class MacroExpander {
result= expandAll(input, forbidden, protectDefined, null);
} catch (CompletionInMacroExpansionException e) {
// for content assist in macro expansions, we return the list of tokens of the
// parameter at the current cursor position and hope that they make sense if
// For content assist in macro expansions, we return the list of tokens of the
// parameter at the current cursor position and hope that they make sense if
// they are inserted at the position of the expansion.
// For a better solution one would have to perform the expansion with artificial
// parameters and then check where the completion token ends up in the expansion.
@ -201,7 +202,8 @@ public class MacroExpander {
* Method for tracking macro expansions.
* @since 5.0
*/
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath, int lineNumber, boolean protectDefinedConstructs) {
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath,
int lineNumber, boolean protectDefinedConstructs) {
fImplicitMacroExpansions.clear();
fImageLocationInfos.clear();
fFixedInput= beforeExpansion.toCharArray();
@ -209,7 +211,7 @@ public class MacroExpander {
fFixedLineNumber= lineNumber;
fReportMacros= null;
Lexer lexer= new Lexer(fFixedInput, fLexOptions, fLog, this);
try {
tracker.start(fFixedInput);
Token identifier= lexer.nextToken();
@ -227,7 +229,8 @@ public class MacroExpander {
fStartOffset= identifier.getOffset();
fEndOffset= identifier.getEndOffset();
fCompletionMode= false;
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden= new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden=
new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
// setup input sequence
TokenSource input= new TokenSource(lexer);
@ -243,21 +246,21 @@ public class MacroExpander {
} catch (OffsetLimitReachedException e) {
}
}
/**
* Expects that the identifier of the macro expansion has been consumed. Expands the macro consuming
* tokens from the input (to read the parameters) and stores the resulting tokens together
* with boundary markers in the result token list.
* Returns the last token of the expansion.
* @throws AbortMacroExpansionException
* Expects that the identifier of the macro expansion has been consumed. Expands the macro
* consuming tokens from the input (to read the parameters) and stores the resulting tokens
* together with boundary markers in the result token list.
* @return the last token of the expansion.
* @throws AbortMacroExpansionException
*/
private Token expandOne(Token lastConsumed, PreprocessorMacro macro,
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input, TokenList result,
MacroExpansionTracker tracker)
private Token expandOne(Token lastConsumed, PreprocessorMacro macro,
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input,
TokenList result, MacroExpansionTracker tracker)
throws OffsetLimitReachedException {
if (fReportMacros != null)
fReportMacros.significantMacro(macro);
if (macro.isFunctionStyle()) {
final int paramCount = macro.getParameterPlaceholderList().length;
final TokenSource[] argInputs= new TokenSource[paramCount];
@ -268,13 +271,13 @@ public class MacroExpander {
try {
lastConsumed= parseArguments(input, (FunctionStyleMacro) macro, forbidden, argInputs, tracker);
} catch (AbortMacroExpansionException e) {
// ignore this macro expansion
// Ignore this macro expansion.
for (TokenSource argInput : argInputs) {
executeScopeMarkers(argInput, forbidden);
if (tracker != null) {
tracker.setExpandedMacroArgument(null);
}
}
}
if (tracker != null) {
if (tracker.isRequestedStep()) {
tracker.storeFunctionStyleMacroReplacement(macro, new TokenList(), result);
@ -285,13 +288,13 @@ public class MacroExpander {
}
return null;
}
TokenList[] clonedArgs= new TokenList[paramCount];
TokenList[] expandedArgs= new TokenList[paramCount];
for (int i = 0; i < paramCount; i++) {
final TokenSource argInput = argInputs[i];
final boolean needCopy= paramUsage.get(2*i);
final boolean needExpansion = paramUsage.get(2*i+1);
final boolean needCopy= paramUsage.get(2 * i);
final boolean needExpansion = paramUsage.get(2 * i + 1);
clonedArgs[i]= needCopy ? argInput.cloneTokens() : EMPTY_TOKEN_LIST;
expandedArgs[i]= needExpansion ? expandAll(argInput, forbidden, false, tracker) : EMPTY_TOKEN_LIST;
if (!needExpansion) {
@ -339,11 +342,11 @@ public class MacroExpander {
private void executeScopeMarkers(TokenSource input, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
Token t= input.removeFirst();
while(t != null) {
while (t != null) {
if (t.getType() == CPreprocessor.tSCOPE_MARKER) {
((ExpansionBoundary) t).execute(forbidden);
}
t= input.removeFirst();
t= input.removeFirst();
}
}
@ -353,8 +356,8 @@ public class MacroExpander {
boolean protect= false;
Token l= null;
Token t= input.removeFirst();
while(t != null) {
switch(t.getType()) {
while (t != null) {
switch (t.getType()) {
case CPreprocessor.tSCOPE_MARKER:
((ExpansionBoundary) t).execute(forbidden);
break;
@ -392,7 +395,7 @@ public class MacroExpander {
addSpacemarker(l, t, replacement); // start expansion
replacement.append(new ExpansionBoundary(macro, true));
Token last= expandOne(t, macro, forbidden, input, replacement, tracker);
Token last= expandOne(t, macro, forbidden, input, replacement, tracker);
replacement.append(new ExpansionBoundary(macro, false));
addSpacemarker(last, input.first(), replacement); // end expansion
@ -401,12 +404,12 @@ public class MacroExpander {
break;
case IToken.tLPAREN:
case CPreprocessor.tNOSPACE:
case CPreprocessor.tSPACE:
case CPreprocessor.tSPACE:
result.append(t);
break;
default:
protect= false;
result.append(t);
result.append(t);
break;
}
l= t;
@ -415,6 +418,14 @@ public class MacroExpander {
return result;
}
private void addImageLocationInfo(int offset, Token t) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
}
private ImageLocationInfo createImageLocationInfo(Token t) {
if (fLocationMap != null) {
final Object s= t.fSource;
@ -447,24 +458,26 @@ public class MacroExpander {
}
target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
}
/**
* Expects that the identifier has been consumed.
*/
private Token parseArguments(TokenSource input, FunctionStyleMacro macro, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden,
TokenSource[] result, MacroExpansionTracker tracker) throws OffsetLimitReachedException, AbortMacroExpansionException {
private Token parseArguments(TokenSource input, FunctionStyleMacro macro,
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden,
TokenSource[] result, MacroExpansionTracker tracker)
throws OffsetLimitReachedException, AbortMacroExpansionException {
final int argCount= macro.getParameterPlaceholderList().length;
final boolean hasVarargs= macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS;
final int requiredArgs= hasVarargs ? argCount-1 : argCount;
final int requiredArgs= hasVarargs ? argCount - 1 : argCount;
int idx= 0;
int nesting= -1;
for (int i = 0; i < result.length; i++) {
result[i]= new TokenSource(null);
}
boolean missingRParenthesis= false;
boolean tooManyArgs= false;
boolean isFirstOfArg= true;
Token lastToken= null;
TokenList spaceMarkers= new TokenList();
@ -475,8 +488,8 @@ public class MacroExpander {
break loop;
}
if (tracker != null) {
switch(t.getType()) {
case IToken.tEND_OF_INPUT:
switch (t.getType()) {
case IToken.tEND_OF_INPUT:
case IToken.tCOMPLETION:
case CPreprocessor.tSCOPE_MARKER:
case Lexer.tNEWLINE:
@ -487,7 +500,7 @@ public class MacroExpander {
}
}
lastToken= t;
switch(t.getType()) {
switch (t.getType()) {
case IToken.tEND_OF_INPUT:
assert nesting >= 0;
if (fCompletionMode) {
@ -504,28 +517,28 @@ public class MacroExpander {
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
}
throw new OffsetLimitReachedException(ORIGIN, t);
case Lexer.tNEWLINE:
continue loop;
case IToken.tLPAREN:
// the first one sets nesting to zero.
// The first one sets nesting to zero.
if (++nesting == 0) {
continue;
}
break;
case IToken.tRPAREN:
assert nesting >= 0;
if (--nesting < 0) {
break loop;
}
break;
case IToken.tCOMMA:
assert nesting >= 0;
if (nesting == 0) {
if (idx < argCount-1) { // next argument
if (idx < argCount - 1) { // Next argument.
isFirstOfArg= true;
spaceMarkers.clear();
idx++;
@ -536,7 +549,7 @@ public class MacroExpander {
}
}
break;
case CPreprocessor.tSCOPE_MARKER:
if (argCount == 0) {
((ExpansionBoundary) t).execute(forbidden);
@ -544,14 +557,14 @@ public class MacroExpander {
result[idx].append(t);
}
continue loop;
case CPreprocessor.tSPACE:
case CPreprocessor.tNOSPACE:
if (!isFirstOfArg) {
spaceMarkers.append(t);
}
continue loop;
default:
assert nesting >= 0;
}
@ -564,34 +577,33 @@ public class MacroExpander {
isFirstOfArg= false;
}
if (missingRParenthesis) {
handleProblem(IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, macro.getNameCharArray());
throw new AbortMacroExpansionException();
}
if (tooManyArgs) {
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
} else if (idx+1 < requiredArgs) {
} else if (idx + 1 < requiredArgs) {
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
}
return lastToken;
}
private void handleProblem(int problemID, char[] arg) {
fLog.handleProblem(problemID, arg, fStartOffset, fEndOffset);
}
private void replaceArgs(PreprocessorMacro macro, TokenList[] args, TokenList[] expandedArgs, TokenList result) {
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
Token l= null;
Token n;
Token pasteArg1= null;
for (Token t= replacement.first(); t != null; l=t, t=n) {
Token n;
Token pasteArg1= null;
for (Token t= replacement.first(); t != null; l= t, t= n) {
n= (Token) t.getNext();
switch(t.getType()) {
switch (t.getType()) {
case CPreprocessor.tMACRO_PARAMETER:
int idx= ((TokenParameterReference) t).getIndex();
if (idx < args.length) { // be defensive
@ -610,7 +622,7 @@ public class MacroExpander {
}
}
break;
case IToken.tPOUND:
addSpacemarker(l, t, result); // start stringify
StringBuilder buf= new StringBuilder();
@ -624,19 +636,19 @@ public class MacroExpander {
n= (Token) n.getNext();
}
buf.append('"');
final int length= buf.length();
final int length= buf.length();
final char[] image= new char[length];
buf.getChars(0, length, image, 0);
Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image);
if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify
pasteArg1= generated;
pasteArg1= generated;
} else {
result.append(generated);
addSpacemarker(t, n, result); // end stringify
}
break;
case IToken.tPOUNDPOUND:
Token pasteArg2= null;
TokenList rest= null;
@ -660,7 +672,7 @@ public class MacroExpander {
idx= -1;
pasteArg2= n;
}
t= n;
n= (Token) n.getNext();
final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND);
@ -672,7 +684,7 @@ public class MacroExpander {
generated= pasteArg1;
if (rest == null)
rest= new TokenList();
rest.prepend(pasteArg2);
spaceDef0= generated;
spaceDef1= pasteArg2;
@ -703,15 +715,15 @@ public class MacroExpander {
}
}
break;
case IToken.tCOMMA:
if (isKind(n, IToken.tPOUNDPOUND)) {
final Token nn= (Token) n.getNext();
if (isKind(nn, CPreprocessor.tMACRO_PARAMETER)) {
idx= ((TokenParameterReference) nn).getIndex();
// check for gcc-extension preventing the paste operation
if (idx == args.length-1 && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
if (idx == args.length - 1 && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
!isKind(nn.getNext(), IToken.tPOUNDPOUND)) {
final Token nnn= (Token) nn.getNext();
TokenList arg= clone(expandedArgs[idx]);
@ -729,14 +741,14 @@ public class MacroExpander {
break;
}
}
addSpacemarker(l, t, result);
pasteArg1= t;
} else {
result.append(t);
}
break;
default:
if (isKind(n, IToken.tPOUNDPOUND)) {
addSpacemarker(l, t, result); // start token paste
@ -748,64 +760,64 @@ public class MacroExpander {
}
}
}
private boolean isKind(final IToken t, final int kind) {
return t!=null && t.getType() == kind;
return t != null && t.getType() == kind;
}
private BitSet getParamUsage(PreprocessorMacro macro) {
final BitSet result= new BitSet();
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions, this);
Token l= null;
Token n;
for (Token t= replacement.first(); t != null; l=t, t=n) {
Token n;
for (Token t= replacement.first(); t != null; l= t, t= n) {
n= (Token) t.getNext();
switch(t.getType()) {
switch (t.getType()) {
case CPreprocessor.tMACRO_PARAMETER:
int idx= 2*((TokenParameterReference) t).getIndex();
int idx= 2 * ((TokenParameterReference) t).getIndex();
if (!isKind(n, IToken.tPOUNDPOUND)) {
idx++;
}
result.set(idx);
break;
case IToken.tPOUND:
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
idx= ((TokenParameterReference) n).getIndex();
result.set(2*idx);
result.set(2 * idx);
t= n; n= (Token) n.getNext();
}
break;
case IToken.tPOUNDPOUND:
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
idx= ((TokenParameterReference) n).getIndex();
// gcc-extension
if (isKind(l, IToken.tCOMMA) && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
idx == macro.getParameterPlaceholderList().length-1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) {
result.set(2*idx+1);
idx == macro.getParameterPlaceholderList().length - 1 && !isKind(n.getNext(), IToken.tPOUNDPOUND)) {
result.set(2 * idx + 1);
} else {
result.set(2*idx);
result.set(2 * idx);
}
t= n; n= (Token) n.getNext();
}
break;
}
}
}
return result;
}
private void objStyleTokenPaste(PreprocessorMacro macro, TokenList result) {
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
Token l= null;
Token n;
Token pasteArg1= null;
for (Token t= replacement.first(); t != null; l=t, t=n) {
Token n;
Token pasteArg1= null;
for (Token t= replacement.first(); t != null; l= t, t= n) {
n= (Token) t.getNext();
switch(t.getType()) {
switch (t.getType()) {
case IToken.tPOUNDPOUND:
if (pasteArg1 != null) {
Token pasteArg2= null;
@ -813,7 +825,7 @@ public class MacroExpander {
pasteArg2= n;
n= (Token) n.getNext();
}
t= tokenpaste(pasteArg1, pasteArg2, macro);
if (t != null) {
if (isKind(n, IToken.tPOUNDPOUND)) {
@ -825,7 +837,7 @@ public class MacroExpander {
}
}
break;
default:
if (isKind(n, IToken.tPOUNDPOUND)) {
addSpacemarker(l, t, result); // start token paste
@ -857,7 +869,7 @@ public class MacroExpander {
final char[] image2= arg2.getCharImage();
final int l1 = image1.length;
final int l2 = image2.length;
final char[] image= new char[l1+l2];
final char[] image= new char[l1 + l2];
System.arraycopy(image1, 0, image, 0, l1);
System.arraycopy(image2, 0, image, l1, l2);
Lexer lex= new Lexer(image, fLexOptions, ILexerLog.NULL, null);
@ -882,13 +894,13 @@ public class MacroExpander {
Token l= null;
Token n;
boolean space= false;
for (; t != null; l=t, t=n) {
for (; t != null; l= t, t= n) {
n= (Token) t.getNext();
if (!space && hasImplicitSpace(l, t)) {
buf.append(' ');
space= true;
}
switch(t.getType()) {
switch (t.getType()) {
case IToken.tSTRING:
case IToken.tLSTRING:
case IToken.tUTF16STRING:
@ -906,7 +918,7 @@ public class MacroExpander {
}
space= false;
break;
case CPreprocessor.tSPACE:
if (!space && l != null && n != null) {
buf.append(' ');
@ -916,7 +928,7 @@ public class MacroExpander {
case CPreprocessor.tNOSPACE:
break;
default:
buf.append(t.getCharImage());
space= false;
@ -924,7 +936,7 @@ public class MacroExpander {
}
}
}
public IASTName[] clearImplicitExpansions() {
IASTName[] result= fImplicitMacroExpansions.toArray(new IASTName[fImplicitMacroExpansions.size()]);
fImplicitMacroExpansions.clear();
@ -941,25 +953,17 @@ public class MacroExpander {
final boolean createImageLocations= fLexOptions.fCreateImageLocations;
int offset= 0;
Token l= null;
for (Token t= replacement.first(); t!=null; t= (Token) t.getNext()) {
switch(t.getType()) {
for (Token t= replacement.first(); t != null; t= (Token) t.getNext()) {
switch (t.getType()) {
case CPreprocessor.tEXPANDED_IDENTIFIER:
t.setType(IToken.tIDENTIFIER);
if (createImageLocations) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
addImageLocationInfo(offset, t);
}
break;
case IToken.tIDENTIFIER:
if (createImageLocations) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
addImageLocationInfo(offset, t);
}
break;
@ -970,16 +974,22 @@ public class MacroExpander {
continue;
case IToken.tCOMPLETION:
// we need to preserve the length of the completion token.
t.setOffset(offset, offset+t.getLength());
// We need to preserve the length of the completion token.
t.setOffset(offset, offset + t.getLength());
t.setNext(null);
return;
default:
if (createImageLocations && t.fSource instanceof CPreprocessor) {
addImageLocationInfo(offset, t);
}
break;
}
t.setOffset(offset, ++offset);
l= t;
}
}
int getCurrentLineNumber() {
if (fFixedInput != null) {
return fFixedLineNumber + countNewlines(fFixedInput);
@ -992,7 +1002,7 @@ public class MacroExpander {
private int countNewlines(char[] input) {
int nl= 0;
for (int i = 0; i < input.length && i<fEndOffset; i++) {
for (int i = 0; i < input.length && i < fEndOffset; i++) {
if (input[i] == '\n') {
nl++;
}

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
@ -30,12 +30,12 @@ public class MacroExpansionStep implements IMacroExpansionStep {
fMacroDefinition= def;
fMacroLocation= macroLoc;
}
@Override
public String getCodeBeforeStep() {
return fBefore;
}
@Override
public String getCodeAfterStep() {
StringBuilder result= new StringBuilder();
@ -49,7 +49,7 @@ public class MacroExpansionStep implements IMacroExpansionStep {
result.append(fBefore, offset, fBefore.length());
return result.toString();
}
@Override
public IMacroBinding getExpandedMacro() {
return fMacroDefinition;

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.ArrayList;
@ -35,7 +35,7 @@ public class MacroExpansionTracker {
}
private final int fStepToTrack;
private int fStepCount;
private String fPreStep;
private ReplaceEdit fReplacement;
@ -58,14 +58,14 @@ public class MacroExpansionTracker {
public boolean isDone() {
return fStepCount > fStepToTrack;
}
/**
* Returns whether we are currently looking at the requested step.
*/
public boolean isRequestedStep() {
return fStepCount == fStepToTrack;
}
/**
* Returns the total amount of steps encountered so far.
*/
@ -79,7 +79,7 @@ public class MacroExpansionTracker {
public String getCodeBeforeStep() {
return fPreStep;
}
/**
* Returns the replacement that represents the change by the step that was tracked.
*/
@ -116,8 +116,7 @@ public class MacroExpansionTracker {
toString(result, lexInput, replacementText, replacementText, replacementText);
fPreStep= new String(lexInput);
fReplacement= new ReplaceEdit(0, endOffset, replacementText.toString());
}
else {
} else {
// the regular case the result contains the text before the step
StringBuilder before= new StringBuilder();
StringBuilder replace= new StringBuilder();
@ -133,7 +132,7 @@ public class MacroExpansionTracker {
fReplacement= new ReplaceEdit(offset, replace.length(), fReplacementText);
}
}
/**
* There was no macro at the beginning of the input.
*/
@ -141,8 +140,9 @@ public class MacroExpansionTracker {
fPreStep= new String(fInput);
fReplacement= new ReplaceEdit(0, 0, ""); //$NON-NLS-1$
}
private void toString(TokenList tokenList, char[] rootInput, StringBuilder before, StringBuilder replace, StringBuilder after) {
private void toString(TokenList tokenList, char[] rootInput, StringBuilder before,
StringBuilder replace, StringBuilder after) {
StringBuilder buf= before;
Token t= tokenList.first();
if (t == null) {
@ -150,17 +150,16 @@ public class MacroExpansionTracker {
}
Token l= null;
Token n;
for (; t != null; l=t, t=n) {
for (; t != null; l= t, t= n) {
n= (Token) t.getNext();
if (l != null && MacroExpander.hasImplicitSpace(l, t)) {
char[] input= getInputForSource(l.fSource, rootInput);
if (input == null) {
buf.append(' ');
}
else {
} else {
final int from = l.getEndOffset();
final int to = t.getOffset();
buf.append(input, from, to-from);
buf.append(input, from, to - from);
}
}
if (t == fReplaceFrom) {
@ -169,8 +168,7 @@ public class MacroExpansionTracker {
char[] input= getInputForSource(t.fSource, rootInput);
if (input == null) {
buf.append(t.getCharImage());
}
else {
} else {
buf.append(input, t.getOffset(), t.getLength());
}
if (t == fReplaceTo) {
@ -178,7 +176,7 @@ public class MacroExpansionTracker {
}
}
}
private char[] getInputForSource(Object source, char[] rootInput) {
if (source instanceof MacroExpander) {
return rootInput;
@ -199,7 +197,7 @@ public class MacroExpansionTracker {
public void startFunctionStyleMacro(Token identifier) {
fMacroStack.add(new MacroInfo(identifier));
}
/**
* All tokens defining a function-style macro expansion are reported.
*/
@ -237,14 +235,14 @@ public class MacroExpansionTracker {
* Append the current function-style macro with the arguments substituted.
*/
public void appendFunctionStyleMacro(TokenList result) {
MacroInfo minfo= fMacroStack.getLast();
MacroInfo minfo= fMacroStack.getLast();
boolean active= true;
int nesting= -1;
int pcount= 0;
Token n;
Token l= null;
for (Token t = minfo.fMacroCall.first(); t != null; l=t, t=n) {
for (Token t = minfo.fMacroCall.first(); t != null; l= t, t= n) {
n = (Token) t.getNext();
switch (t.getType()) {
case IToken.tLPAREN:
@ -300,7 +298,7 @@ public class MacroExpansionTracker {
result.append(t);
}
break;
default:
if (active) {
result.append(t);
@ -324,7 +322,8 @@ public class MacroExpansionTracker {
* @param replacement the replacement
* @param result a list to store the macro in.
*/
public void storeObjectStyleMacroReplacement(PreprocessorMacro macro, Token identifier, TokenList replacement, TokenList result) {
public void storeObjectStyleMacroReplacement(PreprocessorMacro macro, Token identifier,
TokenList replacement, TokenList result) {
fMacroDefinition= macro;
fReplaceFrom= fReplaceTo= identifier;
result.append(identifier);

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
* Sergey Prigogin (Google) - initial API and implementation
*
* Based on lookup3.c, by Bob Jenkins {@link "http://burtleburtle.net/bob/c/lookup3.c"}
*
@ -44,7 +44,6 @@
* mixing with 12*3 instructions on 3 integers than you can with 3 instructions
* on 1 byte), but shoehorning those bytes into integers efficiently is messy.
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
/**

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.parser.IToken;
@ -48,7 +48,7 @@ public class Token implements IToken, Cloneable {
@Override
final public int getLength() {
return fEndOffset-fOffset;
return fEndOffset - fOffset;
}
@Override
@ -56,7 +56,6 @@ public class Token implements IToken, Cloneable {
return fNextToken;
}
@Override
final public void setType(int kind) {
fKind= kind;
@ -73,8 +72,8 @@ public class Token implements IToken, Cloneable {
}
public void shiftOffset(int shift) {
fOffset+= shift;
fEndOffset+= shift;
fOffset += shift;
fEndOffset += shift;
}
@Override
@ -86,7 +85,7 @@ public class Token implements IToken, Cloneable {
public String toString() {
return getImage();
}
@Override
final public boolean isOperator() {
return TokenUtil.isOperator(fKind);

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
class TokenList {
@ -17,7 +17,8 @@ class TokenList {
final Token removeFirst() {
final Token first= fFirst;
if (first == fLast) {
fFirst= fLast= null;
fFirst= null;
fLast= null;
return first;
}
fFirst= (Token) first.getNext();
@ -26,38 +27,38 @@ class TokenList {
public final void append(Token t) {
if (fFirst == null) {
fFirst= fLast= t;
}
else {
fFirst= t;
fLast= t;
} else {
fLast.setNext(t);
fLast= t;
}
t.setNext(null);
}
public final void appendAll(TokenList tl) {
final Token t= tl.first();
if (t != null) {
if (fFirst == null) {
fFirst= tl.fFirst;
}
else {
} else {
fLast.setNext(tl.fFirst);
}
fLast= tl.fLast;
}
tl.fFirst= tl.fLast= null;
tl.fFirst= null;
tl.fLast= null;
}
public final void appendAllButLast(TokenList tl) {
Token t= tl.first();
if (t != null) {
for (Token n= (Token) t.getNext(); n != null; t=n, n= (Token) n.getNext()) {
for (Token n= (Token) t.getNext(); n != null; t= n, n= (Token) n.getNext()) {
append(t);
}
}
}
public final void prepend(Token t) {
final Token first= t;
if (first != null) {
@ -81,7 +82,7 @@ class TokenList {
}
}
}
public final TokenList cloneTokens() {
TokenList result= new TokenList();
for (Token t= fFirst; t != null; t= (Token) t.getNext()) {
@ -110,8 +111,7 @@ class TokenList {
fLast= null;
}
}
}
else {
} else {
final Token r= (Token) l.getNext();
if (r != null) {
l.setNext(r.getNext());
@ -124,19 +124,20 @@ class TokenList {
void cutAfter(Token l) {
if (l == null) {
fFirst= fLast= null;
}
else {
fFirst= null;
fLast= null;
} else {
l.setNext(null);
fLast= l;
}
}
public void clear() {
fFirst= fLast= null;
fFirst= null;
fLast= null;
}
public boolean isEmpty() {
return fFirst==null;
return fFirst == null;
}
}

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.parser.IGCCToken;
@ -20,7 +20,7 @@ public class TokenUtil {
private static final char[] SPACE = {' '};
private static final char[] IMAGE_POUND_POUND = "##".toCharArray(); //$NON-NLS-1$
private static final char[] IMAGE_POUND = "#".toCharArray(); //$NON-NLS-1$
private static final char[] DIGRAPH_LBRACE= "<%".toCharArray(); //$NON-NLS-1$
private static final char[] DIGRAPH_RBRACE= "%>".toCharArray(); //$NON-NLS-1$
private static final char[] DIGRAPH_LBRACKET= "<:".toCharArray(); //$NON-NLS-1$
@ -40,7 +40,7 @@ public class TokenUtil {
case IToken.tSHIFTL: case IToken.tSHIFTLASSIGN:
case IToken.tSHIFTR: case IToken.tSHIFTRASSIGN:
case IToken.tXOR: case IToken.tXORASSIGN:
// logical operations
case IToken.tNOT: case IToken.tAND: case IToken.tOR:
@ -52,25 +52,25 @@ public class TokenUtil {
case IToken.tPLUS: case IToken.tPLUSASSIGN:
case IToken.tSTAR: case IToken.tSTARASSIGN:
case IGCCToken.tMAX: case IGCCToken.tMIN:
// comparison
case IToken.tEQUAL: case IToken.tNOTEQUAL:
case IToken.tGT: case IToken.tGTEQUAL:
case IToken.tLT: case IToken.tLTEQUAL:
// other
case IToken.tASSIGN: case IToken.tCOMMA:
return true;
}
return false;
}
public static char[] getImage(int type) {
switch (type) {
case IToken.tPOUND: return IMAGE_POUND;
case IToken.tPOUNDPOUND: return IMAGE_POUND_POUND;
case IToken.tCOLONCOLON: return Keywords.cpCOLONCOLON;
case IToken.tPOUNDPOUND: return IMAGE_POUND_POUND;
case IToken.tCOLONCOLON: return Keywords.cpCOLONCOLON;
case IToken.tCOLON: return Keywords.cpCOLON;
case IToken.tSEMI: return Keywords.cpSEMI;
case IToken.tCOMMA: return Keywords.cpCOMMA;
@ -120,34 +120,33 @@ public class TokenUtil {
case IToken.tDOT: return Keywords.cpDOT;
case IToken.tDIVASSIGN: return Keywords.cpDIVASSIGN;
case IToken.tDIV: return Keywords.cpDIV;
case IGCCToken.tMIN: return Keywords.cpMIN;
case IGCCToken.tMAX: return Keywords.cpMAX;
case CPreprocessor.tSPACE: return SPACE;
case CPreprocessor.tSPACE: return SPACE;
case CPreprocessor.tNOSPACE: return CharArrayUtils.EMPTY;
default:
return CharArrayUtils.EMPTY;
return CharArrayUtils.EMPTY;
}
}
public static char[] getDigraphImage(int type) {
switch (type) {
case IToken.tPOUND: return DIGRAPH_POUND;
case IToken.tPOUNDPOUND: return DIGRAPH_POUNDPOUND;
case IToken.tPOUNDPOUND: return DIGRAPH_POUNDPOUND;
case IToken.tLBRACKET: return DIGRAPH_LBRACKET;
case IToken.tRBRACKET: return DIGRAPH_RBRACKET;
case IToken.tLBRACE: return DIGRAPH_LBRACE;
case IToken.tRBRACE: return DIGRAPH_RBRACE;
default:
assert false: type;
return CharArrayUtils.EMPTY;
return CharArrayUtils.EMPTY;
}
}
/**
* Returns the last token in the given token list.
* @throws NullPointerException if the argument is null
@ -156,8 +155,7 @@ public class TokenUtil {
IToken last;
do {
last = tokenList;
} while((tokenList = tokenList.getNext()) != null);
} while ((tokenList = tokenList.getNext()) != null);
return last;
}
}

View file

@ -228,10 +228,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 136.0 - Extended CPPTemplateTypeArgument to include the original type, bug 392278.
* 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.
*/
private static final int MIN_SUPPORTED_VERSION= version(138, 0);
private static final int MAX_SUPPORTED_VERSION= version(138, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(138, 0);
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 int version(int major, int minor) {
return (major << 16) + minor;

View file

@ -38,34 +38,34 @@ import com.ibm.icu.text.MessageFormat;
*
* @author Doug Schaefer
*/
/*
/*
* The file encapsulated is divided into Chunks of size CHUNK_SIZE, and a table of contents
* mapping chunk index to chunk address is maintained. Chunk structure exists only conceptually -
* it is not a structure that appears in the file.
*
*
* ===== The first chunk is used by Database itself for house-keeping purposes and has structure
*
*
* offset content
* _____________________________
* 0 | version number
* INT_SIZE | pointer to head of linked list of blocks of size MIN_BLOCK_DELTAS*BLOCK_SIZE_DELTA
* .. | ...
* INT_SIZE * m (1) | pointer to head of linked list of blocks of size (m+MIN_BLOCK_DELTAS) * BLOCK_SIZE_DELTA
* DATA_AREA | undefined (PDOM stores its own house-keeping data in this area)
*
* INT_SIZE * m (1) | pointer to head of linked list of blocks of size (m+MIN_BLOCK_DELTAS) * BLOCK_SIZE_DELTA
* DATA_AREA | undefined (PDOM stores its own house-keeping data in this area)
*
* (1) where 2 <= m <= CHUNK_SIZE/BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 1
*
*
* ===== block structure
*
*
* offset content
* _____________________________
* 0 | size of block (negative indicates in use, positive unused) (2 bytes)
* PREV_OFFSET | pointer to prev block (of same size) (only in free blocks)
* NEXT_OFFSET | pointer to next block (of same size) (only in free blocks)
*
*
*/
public class Database {
// public for tests only, you shouldn't need these
// Public for tests only, you shouldn't need these.
public static final int INT_SIZE = 4;
public static final int CHUNK_SIZE = 1024 * 4;
public static final int OFFSET_IN_CHUNK_MASK= CHUNK_SIZE-1;
@ -73,27 +73,28 @@ public class Database {
public static final int BLOCK_SIZE_DELTA_BITS = 3;
public static final int BLOCK_SIZE_DELTA= 1 << BLOCK_SIZE_DELTA_BITS;
public static final int MIN_BLOCK_DELTAS = 2; // a block must at least be 2 + 2*4 bytes to link the free blocks.
public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE / BLOCK_SIZE_DELTA;
public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS * BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE;
public static final int PTR_SIZE = 4; // size of a pointer in the database in bytes
public static final int MAX_BLOCK_DELTAS = CHUNK_SIZE / BLOCK_SIZE_DELTA;
public static final int MAX_MALLOC_SIZE = MAX_BLOCK_DELTAS * BLOCK_SIZE_DELTA - BLOCK_HEADER_SIZE;
public static final int PTR_SIZE = 4; // size of a pointer in the database in bytes
// The lower bound for TYPE_SIZE is 1 + PTR_SIZE, but a slightly larger space for types stored
// inline produces in a slightly smaller overall database size.
public static final int TYPE_SIZE = 2 + PTR_SIZE; // size of a type in the database in bytes
public static final int VALUE_SIZE = TYPE_SIZE; // size of a value in the database in bytes
public static final int EVALUATION_SIZE = TYPE_SIZE; // size of an evaluation in the database in bytes
public static final int ARGUMENT_SIZE = TYPE_SIZE; // size of a template argument in the database in bytes
public static final long MAX_DB_SIZE= ((long) 1 << (Integer.SIZE + BLOCK_SIZE_DELTA_BITS));
public static final int VERSION_OFFSET = 0;
public static final int DATA_AREA = (CHUNK_SIZE / BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 2) * INT_SIZE;
private static final int BLOCK_PREV_OFFSET = BLOCK_HEADER_SIZE;
private static final int BLOCK_NEXT_OFFSET = BLOCK_HEADER_SIZE + INT_SIZE;
private final File fLocation;
private final boolean fReadOnly;
private RandomAccessFile fFile;
private boolean fExclusiveLock; // necessary for any write operation
private boolean fLocked; // necessary for any operation.
private boolean fExclusiveLock; // Necessary for any write operation.
private boolean fLocked; // Necessary for any operation.
private boolean fIsMarkedIncomplete;
private int fVersion;
@ -102,15 +103,15 @@ public class Database {
private int fChunksUsed;
private int fChunksAllocated;
private ChunkCache fCache;
private long malloced;
private long freed;
private long cacheHits;
private long cacheMisses;
/**
* Construct a new Database object, creating a backing file if necessary.
* @param location the local file path for the database
* @param location the local file path for the database
* @param cache the cache to be used optimization
* @param version the version number to store in the database (only applicable for new databases)
* @param openReadOnly whether this Database object will ever need writing to
@ -122,10 +123,10 @@ public class Database {
fReadOnly= openReadOnly;
fCache= cache;
openFile();
int nChunksOnDisk = (int) (fFile.length() / CHUNK_SIZE);
fHeaderChunk= new Chunk(this, 0);
fHeaderChunk.fLocked= true; // never makes it into the cache, needed to satisfy assertions
fHeaderChunk.fLocked= true; // Never makes it into the cache, needed to satisfy assertions.
if (nChunksOnDisk <= 0) {
fVersion= version;
fChunks= new Chunk[1];
@ -140,7 +141,7 @@ public class Database {
throw new CoreException(new DBStatus(e));
}
}
private void openFile() throws FileNotFoundException {
fFile = new RandomAccessFile(fLocation, fReadOnly ? "r" : "rw"); //$NON-NLS-1$ //$NON-NLS-2$
}
@ -154,7 +155,7 @@ public class Database {
} catch (ClosedChannelException e) {
// Bug 219834 file may have be closed by interrupting a thread during an I/O operation.
reopen(e, ++retries);
}
}
} while (true);
}
@ -167,7 +168,7 @@ public class Database {
} catch (ClosedChannelException e) {
// Bug 219834 file may have be closed by interrupting a thread during an I/O operation.
reopen(e, ++retries);
}
}
}
}
@ -188,17 +189,17 @@ public class Database {
while (position < size) {
nRead = from.transferTo(position, 4096 * 16, target);
if (nRead == 0) {
break; // Should not happen
break; // Should not happen.
} else {
position+= nRead;
}
}
}
public int getVersion() {
return fVersion;
}
public void setVersion(int version) throws CoreException {
assert fExclusiveLock;
fHeaderChunk.putInt(VERSION_OFFSET, version);
@ -212,28 +213,28 @@ public class Database {
public void clear(int version) throws CoreException {
assert fExclusiveLock;
removeChunksFromCache();
fVersion= version;
// clear the first chunk.
// Clear the first chunk.
fHeaderChunk.clear(0, CHUNK_SIZE);
// chunks have been removed from the cache, so we may just reset the array of chunks.
// Chunks have been removed from the cache, so we may just reset the array of chunks.
fChunks = new Chunk[] {null};
fChunksUsed = fChunksAllocated = fChunks.length;
try {
fHeaderChunk.flush(); // zero out header chunk
fFile.getChannel().truncate(CHUNK_SIZE); // truncate database
fHeaderChunk.flush(); // Zero out header chunk.
fFile.getChannel().truncate(CHUNK_SIZE); // Truncate database.
} catch (IOException e) {
CCorePlugin.log(e);
}
malloced = freed = 0;
/*
* This is for debugging purposes in order to simulate having a very large PDOM database.
* This is for debugging purposes in order to simulate having a very large PDOM database.
* This will set aside the specified number of chunks.
* Nothing uses these chunks so subsequent allocations come after these fillers.
* The special function createNewChunks allocates all of these chunks at once.
* 524288 for a file starting at 2G
* 8388608 for a file starting at 32G
*
*
*/
long setasideChunks = Long.getLong("org.eclipse.cdt.core.parser.pdom.dense.recptr.setaside.chunks", 0); //$NON-NLS-1$
if (setasideChunks != 0) {
@ -254,17 +255,17 @@ public class Database {
}
}
}
/**
* Return the Chunk that contains the given offset.
* @throws CoreException
* @throws CoreException
*/
public Chunk getChunk(long offset) throws CoreException {
if (offset < CHUNK_SIZE) {
return fHeaderChunk;
}
long long_index = offset / CHUNK_SIZE;
assert long_index < Integer.MAX_VALUE;
assert long_index < Integer.MAX_VALUE;
synchronized (fCache) {
assert fLocked;
@ -293,17 +294,17 @@ public class Database {
/**
* Allocate a block out of the database.
*/
*/
public long malloc(final int datasize) throws CoreException {
assert fExclusiveLock;
assert datasize >=0 && datasize <= MAX_MALLOC_SIZE;
assert datasize >= 0 && datasize <= MAX_MALLOC_SIZE;
int needDeltas= (datasize + BLOCK_HEADER_SIZE + BLOCK_SIZE_DELTA - 1) / BLOCK_SIZE_DELTA;
if (needDeltas < MIN_BLOCK_DELTAS) {
needDeltas= MIN_BLOCK_DELTAS;
}
// Which block size
// Which block size.
long freeblock = 0;
int useDeltas;
for (useDeltas= needDeltas; useDeltas <= MAX_BLOCK_DELTAS; useDeltas++) {
@ -311,11 +312,11 @@ public class Database {
if (freeblock != 0)
break;
}
// get the block
// Get the block.
Chunk chunk;
if (freeblock == 0) {
// allocate a new chunk
// Allocate a new chunk.
freeblock= createNewChunk();
useDeltas = MAX_BLOCK_DELTAS;
chunk = getChunk(freeblock);
@ -323,25 +324,25 @@ public class Database {
chunk = getChunk(freeblock);
removeBlock(chunk, useDeltas*BLOCK_SIZE_DELTA, freeblock);
}
final int unusedDeltas = useDeltas-needDeltas;
if (unusedDeltas >= MIN_BLOCK_DELTAS) {
// Add in the unused part of our block
// Add in the unused part of our block.
addBlock(chunk, unusedDeltas*BLOCK_SIZE_DELTA, freeblock + needDeltas*BLOCK_SIZE_DELTA);
useDeltas= needDeltas;
}
// Make our size negative to show in use
// Make our size negative to show in use.
final int usedSize= useDeltas*BLOCK_SIZE_DELTA;
chunk.putShort(freeblock, (short) -usedSize);
// Clear out the block, lots of people are expecting this
// Clear out the block, lots of people are expecting this.
chunk.clear(freeblock + BLOCK_HEADER_SIZE, usedSize-BLOCK_HEADER_SIZE);
malloced+= usedSize;
return freeblock + BLOCK_HEADER_SIZE;
}
private long createNewChunk() throws CoreException {
assert fExclusiveLock;
synchronized (fCache) {
@ -402,37 +403,37 @@ public class Database {
return (long) (oldLen + numChunks - 1) * CHUNK_SIZE;
}
}
private long getFirstBlock(int blocksize) throws CoreException {
assert fLocked;
return fHeaderChunk.getFreeRecPtr((blocksize/BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 1) * INT_SIZE);
}
private void setFirstBlock(int blocksize, long block) throws CoreException {
assert fExclusiveLock;
fHeaderChunk.putFreeRecPtr((blocksize/BLOCK_SIZE_DELTA - MIN_BLOCK_DELTAS + 1) * INT_SIZE, block);
}
private void removeBlock(Chunk chunk, int blocksize, long block) throws CoreException {
assert fExclusiveLock;
long prevblock = chunk.getFreeRecPtr(block + BLOCK_PREV_OFFSET);
long nextblock = chunk.getFreeRecPtr(block + BLOCK_NEXT_OFFSET);
if (prevblock != 0) {
putFreeRecPtr(prevblock + BLOCK_NEXT_OFFSET, nextblock);
} else { // we were the head
} else { // We were the head.
setFirstBlock(blocksize, nextblock);
}
if (nextblock != 0)
putFreeRecPtr(nextblock + BLOCK_PREV_OFFSET, prevblock);
}
private void addBlock(Chunk chunk, int blocksize, long block) throws CoreException {
assert fExclusiveLock;
// Mark our size
chunk.putShort(block, (short) blocksize);
// Add us to the head of the list
// Add us to the head of the list.
long prevfirst = getFirstBlock(blocksize);
chunk.putFreeRecPtr(block + BLOCK_PREV_OFFSET, 0);
chunk.putFreeRecPtr(block + BLOCK_NEXT_OFFSET, prevfirst);
@ -440,21 +441,22 @@ public class Database {
putFreeRecPtr(prevfirst + BLOCK_PREV_OFFSET, block);
setFirstBlock(blocksize, block);
}
/**
* Free an allocated block.
*
*
* @param offset
*/
public void free(long offset) throws CoreException {
assert fExclusiveLock;
// TODO - look for opportunities to merge blocks
// TODO Look for opportunities to merge blocks
long block = offset - BLOCK_HEADER_SIZE;
Chunk chunk = getChunk(block);
int blocksize = - chunk.getShort(block);
if (blocksize < 0) {
// already freed
throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0, "Already Freed", new Exception())); //$NON-NLS-1$
// Already freed.
throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0,
"Already freed", new Exception())); //$NON-NLS-1$
}
addBlock(chunk, blocksize, block);
freed += blocksize;
@ -463,31 +465,31 @@ public class Database {
public void putByte(long offset, byte value) throws CoreException {
getChunk(offset).putByte(offset, value);
}
public byte getByte(long offset) throws CoreException {
return getChunk(offset).getByte(offset);
}
public void putInt(long offset, int value) throws CoreException {
getChunk(offset).putInt(offset, value);
}
public int getInt(long offset) throws CoreException {
return getChunk(offset).getInt(offset);
}
public void putRecPtr(long offset, long value) throws CoreException {
getChunk(offset).putRecPtr(offset, value);
}
public long getRecPtr(long offset) throws CoreException {
return getChunk(offset).getRecPtr(offset);
}
private void putFreeRecPtr(long offset, long value) throws CoreException {
getChunk(offset).putFreeRecPtr(offset, value);
}
private long getFreeRecPtr(long offset) throws CoreException {
return getChunk(offset).getFreeRecPtr(offset);
}
@ -495,15 +497,15 @@ public class Database {
public void put3ByteUnsignedInt(long offset, int value) throws CoreException {
getChunk(offset).put3ByteUnsignedInt(offset, value);
}
public int get3ByteUnsignedInt(long offset) throws CoreException {
return getChunk(offset).get3ByteUnsignedInt(offset);
}
public void putShort(long offset, short value) throws CoreException {
getChunk(offset).putShort(offset, value);
}
public short getShort(long offset) throws CoreException {
return getChunk(offset).getShort(offset);
}
@ -511,7 +513,7 @@ public class Database {
public void putLong(long offset, long value) throws CoreException {
getChunk(offset).putLong(offset, value);
}
public long getLong(long offset) throws CoreException {
return getChunk(offset).getLong(offset);
}
@ -523,7 +525,7 @@ public class Database {
public char getChar(long offset) throws CoreException {
return getChunk(offset).getChar(offset);
}
public void clearBytes(long offset, int byteCount) throws CoreException {
getChunk(offset).clear(offset, byteCount);
}
@ -557,14 +559,14 @@ public class Database {
} else {
bytelen= 2 * len;
}
if (bytelen > ShortString.MAX_BYTE_LENGTH) {
return new LongString(this, chars, useBytes);
} else {
return new ShortString(this, chars, useBytes);
}
}
private boolean useBytes(char[] chars) {
for (char c : chars) {
if ((c & 0xff00) != 0)
@ -581,7 +583,7 @@ public class Database {
}
return new ShortString(this, offset);
}
/**
* For debugging purposes, only.
*/
@ -602,19 +604,19 @@ public class Database {
System.out.println("Block size: " + bs + "=" + count); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
* Closes the database.
* Closes the database.
* <p>
* The behavior of any further calls to the Database is undefined
* @throws CoreException
* @throws CoreException
*/
public void close() throws CoreException {
assert fExclusiveLock;
flush();
removeChunksFromCache();
// chunks have been removed from the cache, so we are fine
// Chunks have been removed from the cache, so we are fine.
fHeaderChunk.clear(0, CHUNK_SIZE);
fHeaderChunk.fDirty= false;
fChunks= new Chunk[] { null };
@ -625,7 +627,7 @@ public class Database {
throw new CoreException(new DBStatus(e));
}
}
/**
* This method is public for testing purposes only.
*/
@ -639,7 +641,7 @@ public class Database {
void releaseChunk(final Chunk chunk) {
if (!chunk.fLocked) {
fChunks[chunk.fSequenceNumber]= null;
}
}
}
/**
@ -662,7 +664,7 @@ public class Database {
public void setLocked(boolean val) {
fLocked= val;
}
public void giveUpExclusiveLock(final boolean flush) throws CoreException {
if (fExclusiveLock) {
try {
@ -671,16 +673,16 @@ public class Database {
for (int i= 1; i < fChunksUsed; i++) {
Chunk chunk= fChunks[i];
if (chunk != null) {
if (chunk.fCacheIndex < 0) {
// locked chunk that has been removed from cache.
if (chunk.fCacheIndex < 0) {
// Locked chunk that has been removed from cache.
if (chunk.fDirty) {
dirtyChunks.add(chunk); // keep in fChunks until it is flushed.
dirtyChunks.add(chunk); // Keep in fChunks until it is flushed.
} else {
chunk.fLocked= false;
fChunks[i]= null;
}
} else if (chunk.fLocked) {
// locked chunk, still in cache.
// Locked chunk, still in cache.
if (chunk.fDirty) {
if (flush) {
dirtyChunks.add(chunk);
@ -689,19 +691,19 @@ public class Database {
chunk.fLocked= false;
}
} else {
assert !chunk.fDirty; // dirty chunks must be locked.
assert !chunk.fDirty; // Dirty chunks must be locked.
}
}
}
}
// also handles header chunk
// Also handles header chunk.
flushAndUnlockChunks(dirtyChunks, flush);
} finally {
fExclusiveLock= false;
}
}
}
public void flush() throws CoreException {
assert fLocked;
if (fExclusiveLock) {
@ -713,7 +715,7 @@ public class Database {
return;
}
// be careful as other readers may access chunks concurrently
// Be careful as other readers may access chunks concurrently.
ArrayList<Chunk> dirtyChunks= new ArrayList<Chunk>();
synchronized (fCache) {
for (int i= 1; i < fChunksUsed ; i++) {
@ -724,7 +726,7 @@ public class Database {
}
}
// also handles header chunk
// Also handles header chunk.
flushAndUnlockChunks(dirtyChunks, true);
}
@ -742,7 +744,7 @@ public class Database {
}
}
// only after the chunks are flushed we may unlock and release them.
// Only after the chunks are flushed we may unlock and release them.
synchronized (fCache) {
for (Chunk chunk : dirtyChunks) {
chunk.fLocked= false;
@ -762,7 +764,7 @@ public class Database {
}
}
}
private void markFileIncomplete() throws CoreException {
if (!fIsMarkedIncomplete) {
fIsMarkedIncomplete= true;
@ -778,11 +780,11 @@ public class Database {
public void resetCacheCounters() {
cacheHits= cacheMisses= 0;
}
public long getCacheHits() {
return cacheHits;
}
public long getCacheMisses() {
return cacheMisses;
}

View file

@ -33,7 +33,7 @@ import org.eclipse.core.runtime.CoreException;
/**
* For marshalling types to byte arrays.
*/
public class TypeMarshalBuffer implements ITypeMarshalBuffer {
public final class TypeMarshalBuffer implements ITypeMarshalBuffer {
public static final byte[] EMPTY= { 0, 0, 0, 0, 0, 0 };
public static final byte NULL_TYPE= 0;
public static final byte INDIRECT_TYPE= (byte) -1;
@ -69,6 +69,11 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
return fPos;
}
public void setPosition(int pos) {
assert 0 <= pos && pos <= fPos;
fPos = pos;
}
public byte[] getBuffer() {
return fBuffer;
}
@ -257,23 +262,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
}
@Override
public void putShort(short value) {
request(2);
fBuffer[fPos++]= (byte) (value >> 8);
fBuffer[fPos++]= (byte) (value);
}
@Override
public int getShort() throws CoreException {
if (fPos + 2 > fBuffer.length)
throw unmarshallingError();
final int byte1 = 0xff & fBuffer[fPos++];
final int byte2 = 0xff & fBuffer[fPos++];
return (((byte1 << 8) | (byte2 & 0xff)));
}
@Override
public void putInt(int value) {
public void putFixedInt(int value) {
request(4);
fPos += 4;
int p= fPos;
@ -284,7 +273,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
}
@Override
public int getInt() throws CoreException {
public int getFixedInt() throws CoreException {
if (fPos + 4 > fBuffer.length)
throw unmarshallingError();
int result= 0;
@ -295,35 +284,48 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
return result;
}
@Override
public void putInt(int value) {
do {
int b = value & 0x7F;
value >>>= 7;
if (value != 0)
b |= 0x80;
putByte((byte) b);
} while (value != 0);
}
@Override
public void putLong(long value) {
request(8);
fPos += 8;
int p= fPos;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value);
do {
int b = (int) value & 0x7F;
value >>>= 7;
if (value != 0)
b |= 0x80;
putByte((byte) b);
} while (value != 0);
}
@Override
public int getInt() throws CoreException {
int b = getByte();
int value = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = getByte();
value |= (b & 0x7F) << shift;
}
return value;
}
@Override
public long getLong() throws CoreException {
if (fPos + 8 > fBuffer.length)
throw unmarshallingError();
long result= 0;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
result |= fBuffer[fPos++] & 0xff;
return result;
int b = getByte();
long value = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = getByte();
value |= (b & 0x7F) << shift;
}
return value;
}
private void putRecordPointer(long record) {
@ -344,19 +346,19 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
@Override
public void putCharArray(char[] chars) {
putShort((short) chars.length);
putInt(chars.length);
for (char c : chars) {
putShort((short) c);
putInt(c & 0xFFFF);
}
}
@Override
public char[] getCharArray() throws CoreException {
int len= getShort();
char[] expr= new char[len];
for (int i = 0; i < expr.length; i++) {
expr[i]= (char) getShort();
int len= getInt();
char[] chars= new char[len];
for (int i = 0; i < chars.length; i++) {
chars[i]= (char) getInt();
}
return expr;
return chars;
}
}

View file

@ -60,7 +60,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
* link time. These are generally global symbols specific to a given language.
*/
public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage, IIndexBindingConstants {
// record offsets
// Record offsets.
private static final int ID_OFFSET = PDOMNamedNode.RECORD_SIZE + 0;
private static final int NEXT_OFFSET = PDOMNamedNode.RECORD_SIZE + 4;
private static final int INDEX_OFFSET = PDOMNamedNode.RECORD_SIZE + 8;
@ -71,7 +71,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
protected static final int RECORD_SIZE = PDOMNamedNode.RECORD_SIZE + 20;
protected static final long[] FILE_LOCAL_REC_DUMMY = new long[]{0};
// node types
// Node types
protected static final int LINKAGE= 0; // special one for myself
private BTree fMacroIndex= null; // No need for volatile, all fields of BTree are final.
@ -447,12 +447,14 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
if (len > 0) {
if (len <= maxInlineSize) {
db.putBytes(offset, buf.getBuffer(), len);
} else {
} else {
db.putByte(offset, TypeMarshalBuffer.INDIRECT_TYPE);
long chainOffset = offset + 1;
buf.putInt(len);
int lenSize = buf.getPosition() - len;
int bufferPos = 0;
while (bufferPos < len) {
int chunkLength = len - bufferPos + 2;
int chunkLength = bufferPos == 0 ? len + lenSize : len - bufferPos;
boolean chainingRequired = false;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
@ -460,36 +462,52 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
}
long ptr = db.malloc(chunkLength);
db.putRecPtr(chainOffset, ptr);
db.putShort(ptr, (short) len);
int pos = 2;
if (bufferPos == 0) {
// Write length.
db.putBytes(ptr, buf.getBuffer(), len, lenSize);
ptr += lenSize;
chunkLength -= lenSize;
}
if (chainingRequired) {
// Reserve space for the chaining pointer.
chainOffset = ptr + 2; pos += Database.PTR_SIZE;
chainOffset = ptr;
ptr += Database.PTR_SIZE;
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.putBytes(ptr + pos, buf.getBuffer(), bufferPos, chunkLength);
db.putBytes(ptr, buf.getBuffer(), bufferPos, chunkLength);
bufferPos += chunkLength;
}
buf.setPosition(len); // Restore buffer position.
}
}
}
private byte[] loadLinkedSerializedData(final Database db, long offset) throws CoreException {
long ptr= db.getRecPtr(offset);
int len= db.getShort(ptr) & 0xffff;
// Read the length in variable-length base-128 encoding, see ITypeMarshalBuffer.putInt(int).
int pos = 0;
int b = db.getByte(ptr + pos++);
int len = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = db.getByte(ptr + pos++);
len |= (b & 0x7F) << shift;
}
byte[] data= new byte[len];
int bufferPos = 0;
while (bufferPos < len) {
int chunkLength = len - bufferPos + 2;
int pos = 2;
long chunkPtr = ptr;
int chunkLength = len + pos - bufferPos;
long chunkPtr = ptr + pos;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
ptr= db.getRecPtr(chunkPtr);
chunkPtr += Database.PTR_SIZE;
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.getBytes(chunkPtr + pos, data, bufferPos, chunkLength);
chunkLength -= pos;
db.getBytes(chunkPtr, data, bufferPos, chunkLength);
bufferPos += chunkLength;
pos = 0;
}
return data;
}
@ -497,18 +515,26 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
private void deleteSerializedData(Database db, long offset, int maxInlineSize) throws CoreException {
byte firstByte= db.getByte(offset);
if (firstByte == TypeMarshalBuffer.INDIRECT_TYPE) {
long ptr= db.getRecPtr(offset + 1);
int len= db.getShort(ptr) & 0xffff;
long chunkPtr= db.getRecPtr(offset + 1);
long ptr = chunkPtr;
// Read the length in variable-length base-128 encoding, see ITypeMarshalBuffer.putInt(int).
int b = db.getByte(ptr++);
int len = b & 0x7F;
for (int shift = 7; (b & 0x80) != 0; shift += 7) {
b = db.getByte(ptr++);
len |= (b & 0x7F) << shift;
}
len += ptr - chunkPtr;
while (len > 0) {
int chunkLength = len + 2;
int pos = 2;
long chunkPtr = ptr;
int chunkLength = len;
if (chunkLength > Database.MAX_MALLOC_SIZE) {
chunkLength = Database.MAX_MALLOC_SIZE;
ptr= db.getRecPtr(chunkPtr + pos); pos += Database.PTR_SIZE;
ptr= db.getRecPtr(ptr);
chunkLength -= Database.PTR_SIZE;
}
chunkLength -= pos;
db.free(chunkPtr);
chunkPtr = ptr;
len -= chunkLength;
}
}

View file

@ -60,7 +60,8 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
private volatile ICPPTemplateParameter[] params; // Cached template parameters.
public PDOMCPPClassTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template) throws CoreException, DOMException {
public PDOMCPPClassTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template)
throws CoreException, DOMException {
super(linkage, parent, template);
final Database db = getDB();
@ -127,7 +128,8 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
}
}
private void updateTemplateParameters(PDOMLinkage linkage, ICPPTemplateParameter[] newParams) throws CoreException, DOMException {
private void updateTemplateParameters(PDOMLinkage linkage, ICPPTemplateParameter[] newParams)
throws CoreException, DOMException {
final Database db = getDB();
long rec= db.getRecPtr(record + PARAMETERS);
IPDOMCPPTemplateParameter[] allParams;
@ -167,7 +169,7 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
if (additionalPars > 0 || reorder) {
params= null;
IPDOMCPPTemplateParameter[] newAllParams= new IPDOMCPPTemplateParameter[allParams.length+additionalPars];
IPDOMCPPTemplateParameter[] newAllParams= new IPDOMCPPTemplateParameter[allParams.length + additionalPars];
for (int j = 0; j < newParamLength; j++) {
int idx= result[j];
if (idx >= 0) {

View file

@ -1057,7 +1057,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
IBinding owner= binding.getOwner();
if (owner instanceof ICPPNamespace) {
if (owner.getNameCharArray().length == 0) {
IASTNode node= ASTInternal.getDeclaredInSourceFileOnly(getPDOM(), owner, false, glob);
IASTNode node= ASTInternal.getDeclaredInSourceFileOnly(getPDOM(), binding, false, glob);
if (node != null) {
file= wpdom.getFileForASTNode(getLinkageID(), node);
}

View file

@ -50,7 +50,6 @@ import org.eclipse.core.runtime.CoreException;
*/
class PDOMCPPNamespace extends PDOMCPPBinding
implements ICPPNamespace, ICPPNamespaceScope, IIndexScope {
private static final int INDEX_OFFSET = PDOMCPPBinding.RECORD_SIZE;
private static final int FIRST_NAMESPACE_CHILD_OFFSET = INDEX_OFFSET + Database.PTR_SIZE;
private static final int NEXT_NAMESPACE_SIBBLING_OFFSET = FIRST_NAMESPACE_CHILD_OFFSET + Database.PTR_SIZE;

View file

@ -37,10 +37,10 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
protected static final int ANNOTATIONS = VALUE_OFFSET + Database.VALUE_SIZE; // byte
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = ANNOTATIONS + 1;
public PDOMCPPVariable(PDOMLinkage linkage, PDOMNode parent, IVariable variable) throws CoreException {
super(linkage, parent, variable.getNameCharArray());
// Find the type record
Database db = getDB();
setType(parent.getLinkage(), variable.getType());
@ -73,11 +73,11 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
protected byte encodeFlags(IVariable variable) {
return PDOMCPPAnnotation.encodeAnnotation(variable);
}
public PDOMCPPVariable(PDOMLinkage linkage, long record) {
super(linkage, record);
}
@Override
protected int getRecordSize() {
return RECORD_SIZE;
@ -87,11 +87,11 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
public int getNodeType() {
return IIndexCPPBindingConstants.CPPVARIABLE;
}
@Override
public boolean isMutable() {
// ISO/IEC 14882:2003 7.1.1.8
return false;
return false;
}
@Override
@ -103,7 +103,7 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
return null;
}
}
@Override
public IValue getInitialValue() {
try {
@ -146,4 +146,4 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
}
return 0;
}
}
}

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -22,7 +22,7 @@ import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
/**
* Collects methods to store an argument list in the database
* Collects methods to store an argument list in the database.
*/
public class PDOMTemplateParameterArray {
/**
@ -30,12 +30,12 @@ public class PDOMTemplateParameterArray {
* @return the record by which the arguments can be referenced.
*/
public static long putArray(final Database db, IPDOMCPPTemplateParameter[] params) throws CoreException {
final short len= (short) Math.min(params.length, (Database.MAX_MALLOC_SIZE-2)/8);
final long block= db.malloc(2+8*len);
final short len= (short) Math.min(params.length, (Database.MAX_MALLOC_SIZE - 2) / 8);
final long block= db.malloc(2 + 8 * len);
long p= block;
db.putShort(p, len); p+=2;
for (int i=0; i<len; i++, p+=4) {
db.putShort(p, len); p += 2;
for (int i= 0; i < len; i++, p += 4) {
final IPDOMCPPTemplateParameter elem= params[i];
db.putRecPtr(p, elem == null ? 0 : elem.getRecord());
}
@ -50,15 +50,15 @@ public class PDOMTemplateParameterArray {
final Database db= linkage.getDB();
final short len= db.getShort(rec);
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/8);
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE - 2) / 8);
if (len == 0) {
return IPDOMCPPTemplateParameter.EMPTY_ARRAY;
}
rec+=2;
rec += 2;
IPDOMCPPTemplateParameter[] result= new IPDOMCPPTemplateParameter[len];
for (int i=0; i<len; i++) {
final long nodeRec= db.getRecPtr(rec); rec+=4;
for (int i= 0; i < len; i++) {
final long nodeRec= db.getRecPtr(rec); rec += 4;
result[i]= nodeRec == 0 ? null : (IPDOMCPPTemplateParameter) linkage.getNode(nodeRec);
}
return result;
@ -67,7 +67,8 @@ public class PDOMTemplateParameterArray {
/**
* Creates template parameters in the pdom
*/
public static IPDOMCPPTemplateParameter[] createPDOMTemplateParameters(PDOMLinkage linkage, PDOMNode parent, ICPPTemplateParameter[] origParams) throws CoreException, DOMException {
public static IPDOMCPPTemplateParameter[] createPDOMTemplateParameters(PDOMLinkage linkage,
PDOMNode parent, ICPPTemplateParameter[] origParams) throws CoreException, DOMException {
IPDOMCPPTemplateParameter[] params= new IPDOMCPPTemplateParameter[origParams.length];
for (int i = 0; i < origParams.length; i++) {
params[i]= createPDOMTemplateParameter(linkage, parent, origParams[i]);
@ -78,7 +79,8 @@ public class PDOMTemplateParameterArray {
/**
* Creates a template parameter in the pdom
*/
public static IPDOMCPPTemplateParameter createPDOMTemplateParameter(PDOMLinkage linkage, PDOMNode parent, ICPPTemplateParameter origParam) throws CoreException, DOMException {
public static IPDOMCPPTemplateParameter createPDOMTemplateParameter(PDOMLinkage linkage,
PDOMNode parent, ICPPTemplateParameter origParam) throws CoreException, DOMException {
IPDOMCPPTemplateParameter param= null;
if (origParam instanceof ICPPTemplateNonTypeParameter) {
param= new PDOMCPPTemplateNonTypeParameter(linkage, parent, (ICPPTemplateNonTypeParameter) origParam);

View file

@ -66,6 +66,7 @@ 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.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
@ -143,6 +144,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.formatter.align.Alignment;
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
@ -232,6 +234,28 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
}
private static class TokenRange {
private int offset;
private int endOffset;
TokenRange(int offset, int endOffset) {
this.offset = offset;
this.endOffset = endOffset;
}
int getOffset() {
return offset;
}
int getEndOffset() {
return endOffset;
}
int getLength() {
return endOffset - offset;
}
}
/**
* Formats a trailing semicolon.
* @see #formatList(List, ListOptions, boolean, boolean, Runnable)
@ -360,6 +384,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
private final Scribe scribe;
private boolean fInsideFor;
private boolean fInsideMacroArguments;
private boolean fExpectSemicolonAfterDeclaration= true;
private MultiStatus fStatus;
@ -540,97 +565,79 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (fileLocation != null) {
scribe.printRaw(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
}
fileLocation = macroExpansion.getFileLocation();
scribe.printNextToken(Token.tLPAREN);
IMacroBinding binding = (IMacroBinding) name.resolveBinding();
if (preferences.insert_space_after_opening_paren_in_method_invocation) {
scribe.space();
List<Object> arguments = getMacroArguments(binding.getParameterList().length);
final ListOptions options= new ListOptions(preferences.alignment_for_arguments_in_method_invocation);
options.fSeparatorToken = Token.tCOMMA;
options.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation;
options.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation;
options.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_invocation;
options.fSpaceBeforeSeparator= preferences.insert_space_before_comma_in_method_invocation_arguments;
options.fSpaceAfterSeparator= preferences.insert_space_after_comma_in_method_invocation_arguments;
options.fTieBreakRule = Alignment.R_OUTERMOST;
fInsideMacroArguments = true;
try {
formatList(arguments, options, true, false, scribe.takeTailFormatter());
} finally {
fInsideMacroArguments = false;
}
final int continuationIndentation = preferences.continuation_indentation;
Alignment listAlignment = scribe.createAlignment(
Alignment.MACRO_ARGUMENTS,
preferences.alignment_for_arguments_in_method_invocation,
Alignment.R_OUTERMOST,
binding.getParameterList().length,
getCurrentPosition(),
continuationIndentation,
false);
scribe.enterAlignment(listAlignment);
boolean ok = false;
do {
try {
int fragment = 0;
scribe.alignFragment(listAlignment, fragment);
int parenLevel= 0;
boolean done = false;
while (!done) {
boolean hasWhitespace= scribe.printComment();
int token = peekNextToken();
switch (token) {
case Token.tLPAREN:
++parenLevel;
scribe.printNextToken(token, hasWhitespace);
break;
case Token.tRPAREN:
if (parenLevel > 0) {
--parenLevel;
scribe.printNextToken(token, hasWhitespace);
} else {
if (preferences.insert_space_before_closing_paren_in_method_invocation) {
scribe.space();
}
scribe.printNextToken(token);
done = true;
}
break;
case Token.tCOMMA:
if (parenLevel == 0 && preferences.insert_space_before_comma_in_method_invocation_arguments) {
scribe.space();
}
scribe.printNextToken(token);
if (parenLevel == 0) {
if (preferences.insert_space_after_comma_in_method_invocation_arguments) {
scribe.space();
}
scribe.printComment();
++fragment;
if (fragment < listAlignment.fragmentCount) {
scribe.alignFragment(listAlignment, fragment);
}
}
break;
case Token.tSTRING:
case Token.tLSTRING:
case Token.tRSTRING:
boolean needSpace= hasWhitespace;
while (true) {
scribe.printNextToken(token, needSpace);
if (peekNextToken() != token) {
break;
}
scribe.printCommentPreservingNewLines();
needSpace= true;
}
break;
case Token.tBADCHAR:
// Avoid infinite loop if something bad happened.
scribe.exitAlignment(listAlignment, true);
return;
default:
scribe.printNextToken(token, hasWhitespace);
}
}
/**
* Scans macro expansion arguments starting from the current position and returns a list of
* arguments where each argument is represented either by a {@link IASTNode} or, if not
* possible, by a {@link TokenRange}.
*/
private List<Object> getMacroArguments(int expectedNumberOfArguments) {
List<TokenRange> argumentRanges = new ArrayList<TokenRange>(expectedNumberOfArguments);
TokenRange currentArgument = null;
localScanner.resetTo(getCurrentPosition(), scribe.scannerEndPosition);
localScanner.getNextToken(); // Skip the opening parenthesis.
int parenLevel = 0;
int token;
while ((token = localScanner.getNextToken()) != Token.tBADCHAR) {
int tokenOffset = localScanner.getCurrentTokenStartPosition();
if (parenLevel == 0 && (token == Token.tCOMMA || token == Token.tRPAREN)) {
if (currentArgument != null) {
argumentRanges.add(currentArgument);
currentArgument = null;
} else {
argumentRanges.add(new TokenRange(tokenOffset, tokenOffset));
}
int token = peekNextToken();
if (token == Token.tSEMI) {
scribe.printNextToken(token);
scribe.startNewLine();
if (token == Token.tRPAREN)
break;
} else {
int tokenEndOffset = localScanner.getCurrentPosition();
if (currentArgument == null) {
currentArgument = new TokenRange(tokenOffset, tokenEndOffset);
} else {
currentArgument.endOffset = tokenEndOffset;
}
switch (token) {
case Token.tLPAREN:
++parenLevel;
break;
case Token.tRPAREN:
if (parenLevel > 0)
--parenLevel;
break;
}
ok = true;
} catch (AlignmentException e) {
scribe.redoAlignment(e);
}
} while (!ok);
scribe.exitAlignment(listAlignment, true);
}
List<Object> arguments = new ArrayList<Object>(argumentRanges.size());
IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
for (TokenRange argument : argumentRanges) {
IASTNode node = nodeSelector.findNodeInExpansion(argument.getOffset(), argument.getLength());
if (node != null) {
arguments.add(node);
} else {
arguments.add(argument);
}
}
return arguments;
}
@Override
@ -2077,15 +2084,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
/**
* Format a given list of elements according alignment options.
*
* @param elements the elements to format
* @param elements the elements to format, which can be either {@link IASTNode}s or
* {@link TokenRange}s.
* @param options formatting options
* @param encloseInParen indicates whether the list should be enclosed in parentheses
* @param addEllipsis indicates whether ellipsis should be added after the last element
* @param tailFormatter formatter for the trailing text that should be kept together with
* the last element of the list.
*/
private void formatList(List<? extends IASTNode> elements, ListOptions options,
boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) {
private void formatList(List<?> elements, ListOptions options, boolean encloseInParen,
boolean addEllipsis, Runnable tailFormatter) {
if (encloseInParen)
scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
@ -2118,22 +2126,26 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
try {
int i;
for (i = 0; i < elementsLength; i++) {
final IASTNode node= elements.get(i);
final Object element = elements.get(i);
if (i < elementsLength - 1) {
scribe.setTailFormatter(
new TrailingTokenFormatter(options.fSeparatorToken,
findTokenAfterNode(options.fSeparatorToken, node),
findTokenAfterNodeOrTokenRange(options.fSeparatorToken, element),
options.fSpaceBeforeSeparator,
options.fSpaceAfterSeparator));
} else {
scribe.setTailFormatter(tailFormatter);
}
scribe.alignFragment(alignment, i);
if (node instanceof ICPPASTConstructorChainInitializer) {
// Constructor chain initializer is a special case.
visit((ICPPASTConstructorChainInitializer) node);
if (element instanceof IASTNode) {
if (element instanceof ICPPASTConstructorChainInitializer) {
// Constructor chain initializer is a special case.
visit((ICPPASTConstructorChainInitializer) element);
} else {
((IASTNode) element).accept(this);
}
} else {
node.accept(this);
formatTokenRange((TokenRange) element);
}
if (i < elementsLength - 1) {
scribe.runTailFormatter();
@ -2163,6 +2175,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
}
private void formatTokenRange(TokenRange tokenRange) {
scribe.restartAtOffset(tokenRange.getOffset());
while (getCurrentPosition() < tokenRange.getEndOffset()) {
boolean hasWhitespace= scribe.printComment();
int token = peekNextToken();
scribe.printNextToken(token, hasWhitespace);
}
}
private int visit(ICPPASTTryBlockStatement node) {
scribe.printNextToken(Token.t_try, scribe.printComment());
final IASTStatement tryBody= node.getTryBody();
@ -3782,18 +3803,23 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
IASTNodeLocation[] locations= node.getNodeLocations();
if (locations.length == 0) {
} else if (locations[0] instanceof IASTMacroExpansionLocation) {
} else if (!fInsideMacroArguments && locations[0] instanceof IASTMacroExpansionLocation) {
IASTMacroExpansionLocation location = (IASTMacroExpansionLocation) locations[0];
if (locations.length <= 2 && node instanceof IASTStatement) {
IASTPreprocessorMacroExpansion macroExpansion = location.getExpansion();
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
IASTFileLocation nodeLocation = node.getFileLocation();
IASTFileLocation nodeLocation = getFileLocation(node);
if (macroLocation.getNodeOffset() >= getCurrentPosition() &&
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
locations.length == 2 && isSemicolonLocation(locations[1])) &&
isFunctionStyleMacroExpansion(macroExpansion)) {
if (locations.length == 2 && isSemicolonLocation(locations[1])) {
scribe.setTailFormatter(
new TrailingTokenFormatter(Token.tSEMI, locations[1].getNodeOffset(),
preferences.insert_space_before_semicolon, false));
}
formatFunctionStyleMacroExpansion(macroExpansion);
return false;
}
@ -3808,12 +3834,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return false;
}
} else {
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
scribe.restartAtOffset(fileLocation.getNodeOffset());
}
return true;
}
private IASTFileLocation getFileLocation(IASTNode node) {
return fInsideMacroArguments ? ((ASTNode) node).getImageLocation() : node.getFileLocation();
}
/**
* Formatting of node is complete. Undo skip region if any.
*
@ -3824,7 +3854,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return;
}
if (scribe.skipRange()) {
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
if (fileLocation != null) {
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
scribe.restartAtOffset(nodeEndOffset);
@ -3845,7 +3875,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (node instanceof IASTProblemHolder || node instanceof IASTTranslationUnit) {
return;
}
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
if (fileLocation == null) {
return;
}
@ -3881,7 +3911,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private void skipNode(IASTNode node) {
final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation fileLocation= getFileLocation(node);
if (fileLocation != null && fileLocation.getNodeLength() > 0) {
final int endOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
final int currentOffset= getCurrentPosition();
@ -3893,7 +3923,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private void skipToNode(IASTNode node) {
final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation fileLocation= getFileLocation(node);
if (fileLocation != null) {
final int startOffset= fileLocation.getNodeOffset();
final int currentOffset= getCurrentPosition();
@ -3905,7 +3935,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private void skipNonWhitespaceToNode(IASTNode node) {
final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation fileLocation= getFileLocation(node);
if (fileLocation != null) {
final int startOffset= fileLocation.getNodeOffset();
final int nextTokenOffset= getNextTokenOffset();
@ -3985,18 +4015,22 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
}
private static boolean startsWithMacroExpansion(IASTNode node) {
private boolean startsWithMacroExpansion(IASTNode node) {
if (fInsideMacroArguments)
return false;
IASTNodeLocation[] locations= node.getNodeLocations();
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
locations[0] instanceof IASTMacroExpansionLocation) {
IASTFileLocation expansionLocation= locations[0].asFileLocation();
IASTFileLocation fileLocation= node.getFileLocation();
IASTFileLocation fileLocation= getFileLocation(node);
return expansionLocation.getNodeOffset() == fileLocation.getNodeOffset();
}
return false;
}
private static boolean endsWithMacroExpansion(IASTNode node) {
private boolean endsWithMacroExpansion(IASTNode node) {
if (fInsideMacroArguments)
return false;
IASTNodeLocation[] locations= node.getNodeLocations();
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
locations[locations.length - 1] instanceof IASTMacroExpansionLocation) {
@ -4005,13 +4039,17 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return false;
}
private static boolean enclosedInMacroExpansion(IASTNode node) {
private boolean enclosedInMacroExpansion(IASTNode node) {
if (fInsideMacroArguments)
return false;
IASTNodeLocation[] locations= node.getNodeLocations();
return locations.length == 1 && locations[0] instanceof IASTMacroExpansionLocation;
}
private static boolean withinMacroExpansion(IASTNode node, int offset) {
IASTFileLocation loc = node.getFileLocation();
private boolean withinMacroExpansion(IASTNode node, int offset) {
if (fInsideMacroArguments)
return false;
IASTFileLocation loc = getFileLocation(node);
if (loc == null || offset < loc.getNodeOffset() || offset >= loc.getNodeOffset() + loc.getNodeLength()) {
return false;
}
@ -4061,9 +4099,9 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
* normally separated by other tokens this is an indication that they were produced by the same
* macro expansion.
*/
private static boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
IASTFileLocation loc1 = node1.getFileLocation();
IASTFileLocation loc2 = node2.getFileLocation();
private boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
IASTFileLocation loc1 = getFileLocation(node1);
IASTFileLocation loc2 = getFileLocation(node2);
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
}
@ -4073,16 +4111,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
* separated by other tokens this is an indication that they were produced by the same macro
* expansion.
*/
private static boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
private boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
return nodeOffset(node1) == nodeOffset(node2);
}
private static int nodeOffset(IASTNode node) {
return node.getFileLocation().getNodeOffset();
private int nodeOffset(IASTNode node) {
return getFileLocation(node).getNodeOffset();
}
private static int nodeEndOffset(IASTNode node) {
IASTFileLocation loc = node.getFileLocation();
private int nodeEndOffset(IASTNode node) {
IASTFileLocation loc = getFileLocation(node);
return loc.getNodeOffset() + loc.getNodeLength();
}
@ -4407,14 +4445,19 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
}
private int findTokenWithinNode(int tokenType, IASTNode node) {
IASTFileLocation location = node.getFileLocation();
IASTFileLocation location = getFileLocation(node);
int endOffset = location.getNodeOffset() + location.getNodeLength();
return scribe.findToken(tokenType, endOffset);
}
private int findTokenAfterNode(int tokenType, IASTNode node) {
IASTFileLocation location = node.getFileLocation();
int startOffset = location.getNodeOffset() + location.getNodeLength();
private int findTokenAfterNodeOrTokenRange(int tokenType, Object nodeOrTokenRange) {
int startOffset;
if (nodeOrTokenRange instanceof IASTNode) {
IASTFileLocation location = getFileLocation((IASTNode) nodeOrTokenRange);
startOffset = location.getNodeOffset() + location.getNodeLength();
} else {
startOffset = ((TokenRange) nodeOrTokenRange).getEndOffset();
}
return scribe.findToken(tokenType, startOffset, scribe.scannerEndPosition - 1);
}
}

View file

@ -31,9 +31,6 @@ public class Scanner extends SimpleScanner {
setSplitPreprocessor(false);
}
/*
* @see org.eclipse.cdt.internal.formatter.scanner.SimpleScanner#init(java.io.Reader, java.lang.String)
*/
@Override
protected void init(Reader reader, String filename) {
// not allowed
@ -148,7 +145,7 @@ public class Scanner extends SimpleScanner {
do {
getChar();
++diff;
} while(diff < 0);
} while (diff < 0);
} else if (diff == 0) {
// no-op
} else if (diff > fTokenBuffer.length()) {

View file

@ -51,7 +51,6 @@ import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings;
public class AbstractSemanticHighlightingTest extends TestCase {
protected static class SemanticHighlightingTestSetup extends TestSetup {
private ICProject fCProject;
private final String fTestFilename;
private File fExternalFile;

View file

@ -1765,7 +1765,6 @@ public class CodeFormatterTest extends BaseUITestCase {
// }
//#endif
//}
public void testMacroAsFunctionArguments_Bug253039() throws Exception {
assertFormatterResult();
}
@ -1901,6 +1900,33 @@ public class CodeFormatterTest extends BaseUITestCase {
assertFormatterResult();
}
//#define MACRO(a,b) f(a,b)
//void f(bool b, int i);
//int function_with_loooooooooooooooong_name();
//int another_function_with_loooooong_name();
//
//void test(){
// MACRO("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=="bbbbbbbbbbbbbbbbbbbbbbbbbbb",function_with_loooooooooooooooong_name()+another_function_with_loooooong_name());
//}
//#define MACRO(a,b) f(a,b)
//void f(bool b, int i);
//int function_with_loooooooooooooooong_name();
//int another_function_with_loooooong_name();
//
//void test() {
// MACRO("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
// == "bbbbbbbbbbbbbbbbbbbbbbbbbbb",
// function_with_loooooooooooooooong_name()
// + another_function_with_loooooong_name());
//}
public void testMacroArguments() throws Exception {
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
Integer.toString(Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_ON_COLUMN));
assertFormatterResult();
}
//bool member __attribute__ ((__unused__)) = false;
//bool member __attribute__ ((__unused__)) = false;
@ -2892,7 +2918,7 @@ public class CodeFormatterTest extends BaseUITestCase {
//void f() {
// if (1) {
// }
// IF(1>0);
// IF(1 > 0);
//}
public void testMacroAfterCompoundStatement_Bug356690() throws Exception {
assertFormatterResult();

View file

@ -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
@ -96,8 +96,8 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
fCFile= null;
super.tearDown();
}
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, int compareType) throws Exception {
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, boolean filterResults, int compareType) throws Exception {
if (CTestPlugin.getDefault().isDebugging()) {
System.out.println("\n\n\n\n\nTesting "+this.getClass().getName());
}
@ -116,10 +116,12 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
long endTime= System.currentTimeMillis();
assertTrue(results != null);
if(isTemplate) {
results= filterResultsKeepTemplates(results);
} else {
results= filterResults(results, isCode);
if (filterResults) {
if (isTemplate) {
results= filterResultsKeepTemplates(results);
} else {
results= filterResults(results, isCode);
}
}
String[] resultStrings= toStringArray(results, compareType);
Arrays.sort(expected);
@ -160,6 +162,10 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
}
}
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, int compareType) throws Exception {
assertContentAssistResults(offset, length, expected, isCompletion, isTemplate, true, compareType);
}
protected void assertContentAssistResults(int offset, String[] expected, boolean isCompletion, int compareType) throws Exception {
assertContentAssistResults(offset, 0, expected, isCompletion, false, compareType);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2012 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 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
@ -1374,4 +1374,10 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= { "foo;" };
assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS);
}
// template <typen/*cursor*/
public void testTemplateDeclaration_Bug397288() throws Exception {
final String[] expected= { "typename" };
assertContentAssistResults(fCursorOffset, 0, expected, true, false, false, COMPARE_REP_STRINGS);
}
}

View file

@ -10,7 +10,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.corext.codemanipulation;x-internal:=true,
org.eclipse.cdt.internal.corext.fix;x-internal:=true,
org.eclipse.cdt.internal.corext.template.c;x-internal:=true,
org.eclipse.cdt.internal.corext.util;x-internal:=true,
org.eclipse.cdt.internal.corext.util;x-friends:="org.eclipse.cdt.codan.ui",
org.eclipse.cdt.internal.ui;x-friends:="org.eclipse.cdt.debug.edc.tests",
org.eclipse.cdt.internal.ui.actions;x-internal:=true,
org.eclipse.cdt.internal.ui.browser.opentype;x-internal:=true,
@ -22,7 +22,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.ui.dialogs;x-internal:=true,
org.eclipse.cdt.internal.ui.dialogs.cpaths;x-internal:=true,
org.eclipse.cdt.internal.ui.dnd;x-internal:=true,
org.eclipse.cdt.internal.ui.editor;x-friends:="org.eclipse.cdt.codan.ui.cxx",
org.eclipse.cdt.internal.ui.editor;x-friends:="org.eclipse.cdt.codan.ui,org.eclipse.cdt.codan.ui.cxx",
org.eclipse.cdt.internal.ui.editor.asm;x-internal:=true,
org.eclipse.cdt.internal.ui.filters;x-internal:=true,
org.eclipse.cdt.internal.ui.help;x-internal:=true,
@ -65,7 +65,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.ui.viewsupport;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.classwizard;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.dialogfields;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.dialogfields;x-friends:="org.eclipse.cdt.codan.ui",
org.eclipse.cdt.internal.ui.wizards.filewizard;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.folderwizard;x-internal:=true,
org.eclipse.cdt.internal.ui.wizards.indexwizards;x-internal:=true,

View file

@ -5,6 +5,7 @@ anchor,,
arg,,
attention,,
author,,
authors,,
b,,
brief,,
bug,,
@ -12,12 +13,15 @@ c,,
callgraph,,
callergraph,,
category,,
cite,,
class,,
code,,
cond,,
condnot,,
copybrief,,
copydetails,,
copydoc,,
copyright,,
date,,
def,,
defgroup,,
@ -36,15 +40,18 @@ endcond,,
enddot,,
endhtmlonly,,
endif,,
endinternal,,
endlatexonly,,
endlink,,
endmanonly,,
endmsc,,
endrtfonly,,
endverbatim,,
endxmlonly,,
enum,,
example,,
exception,,
extends,,
f$,,
f[,,
f],,
@ -59,6 +66,7 @@ htmlonly,,
if,,
ifnot,,
image,,
implements,,
include,,
includelineno,,
ingroup,,
@ -73,6 +81,7 @@ mainpage,,
manonly,,
memberof,,
msc,,
mscfile,,
n,,
name,,
namespace,,
@ -96,24 +105,34 @@ protocol,,
public,,
publicsection,,
ref,,
related,,
relates,,
relatedalso,,
relatesalso,,
remark,,
remarks,,
result,,
return,,
returns,,
retval,,
rtfonly,,
sa,,
section,,
see,,
short,,
showinitializer,,
since,,
skip,,
skipline,,
snippet,,
struct,,
subpage,,
subsection,,
subsubsection,,
tableofcontents,,
test,,
throw,,
throws,,
todo,,
tparam,,
typedef,,
@ -127,12 +146,15 @@ warning,,
weakgroup,,
xmlonly,,
xrefitem,,
&,,
$,,
@,,
\,,
&,,
~,,
<,,
>,,
#,,
%,,
",,
",,
.,,
::,,
Can't render this file because it contains an unexpected character in line 160 and column 5.

View file

@ -13,7 +13,6 @@
* Sergey Prigogin (Google)
* Tomasz Wesolowski
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
@ -27,7 +26,6 @@ import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
* @noextend This interface is not intended to be extended by clients.
*/
public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinitionIds {
/**
* Action definition ID of the source -> toggle comment action
* (value <code>"org.eclipse.cdt.ui.edit.text.c.toggle.comment"</code>).

View file

@ -1,15 +1,14 @@
/*******************************************************************************
* Copyright (c) 2000, 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) 2000, 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:
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems) - Adapted for CDT
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import java.util.ArrayList;
@ -42,12 +41,10 @@ import org.eclipse.cdt.internal.ui.text.CSourceViewerScalableConfiguration;
* @since 4.0
*/
public class SemanticHighlightingManager implements IPropertyChangeListener {
/**
* Highlighting style.
*/
public static class HighlightingStyle {
/** Text attribute */
private TextAttribute fTextAttribute;
/** Enabled state */
@ -96,7 +93,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
* Highlighted Positions.
*/
public static class HighlightedPosition extends Position {
/** Highlighting of the position */
private HighlightingStyle fStyle;
@ -169,9 +165,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#setLength(int)
*/
@Override
public void setLength(int length) {
synchronized (fLock) {
@ -179,9 +172,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#setOffset(int)
*/
@Override
public void setOffset(int offset) {
synchronized (fLock) {
@ -189,9 +179,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#delete()
*/
@Override
public void delete() {
synchronized (fLock) {
@ -199,9 +186,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
}
/*
* @see org.eclipse.jface.text.Position#undelete()
*/
@Override
public void undelete() {
synchronized (fLock) {
@ -314,14 +298,16 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Install the semantic highlighting on the given source viewer infrastructure. No reconciliation will be performed.
* Installs the semantic highlighting on the given source viewer infrastructure.
* No reconciliation will be performed.
*
* @param sourceViewer the source viewer
* @param colorManager the color manager
* @param preferenceStore the preference store
* @param hardcodedRanges the hard-coded ranges to be highlighted
*/
public void install(CSourceViewer sourceViewer, IColorManager colorManager, IPreferenceStore preferenceStore, HighlightedRange[][] hardcodedRanges) {
public void install(CSourceViewer sourceViewer, IColorManager colorManager,
IPreferenceStore preferenceStore, HighlightedRange[][] hardcodedRanges) {
fHardcodedRanges= hardcodedRanges;
install(null, sourceViewer, colorManager, preferenceStore);
}
@ -383,7 +369,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Uninstall the semantic highlighting
* Uninstalls the semantic highlighting
*/
public void uninstall() {
disable();
@ -402,7 +388,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Disable semantic highlighting.
* Disables semantic highlighting.
*/
private void disable() {
if (fReconciler != null) {
@ -427,7 +413,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Initialize semantic highlightings.
* Initializes semantic highlightings.
*/
protected void initializeHighlightings() {
fSemanticHighlightings= SemanticHighlightings.getSemanticHighlightings();
@ -460,7 +446,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Dispose the semantic highlightings.
* Disposes the semantic highlightings.
*/
protected void disposeHighlightings() {
for (int i= 0, n= fSemanticHighlightings.length; i < n; i++)
@ -470,9 +456,6 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
fHighlightings= null;
}
/*
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
@Override
public void propertyChange(PropertyChangeEvent event) {
handlePropertyChangeEvent(event);
@ -626,7 +609,7 @@ public class SemanticHighlightingManager implements IPropertyChangeListener {
}
/**
* Force refresh of highlighting.
* Forces refresh of highlighting.
*/
public void refresh() {
if (fReconciler != null) {

View file

@ -9,7 +9,6 @@
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems) - Adapted for CDT
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import java.util.ArrayList;
@ -37,7 +36,6 @@ import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.Highlighte
import org.eclipse.cdt.internal.ui.editor.SemanticHighlightingManager.HighlightingStyle;
import org.eclipse.cdt.internal.ui.text.CPresentationReconciler;
/**
* Semantic highlighting presenter - UI thread implementation.
* Cloned from JDT.
@ -45,12 +43,10 @@ import org.eclipse.cdt.internal.ui.text.CPresentationReconciler;
* @since 4.0
*/
public class SemanticHighlightingPresenter implements ITextPresentationListener, ITextInputListener, IDocumentListener {
/**
* Semantic highlighting position updater.
*/
private class HighlightingPositionUpdater implements IPositionUpdater {
/** The position category. */
private final String fCategory;
@ -63,12 +59,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
fCategory= category;
}
/*
* @see org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.text.DocumentEvent)
*/
@Override
public void update(DocumentEvent event) {
int eventOffset= event.getOffset();
int eventOldLength= event.getLength();
int eventEnd= eventOffset + eventOldLength;
@ -77,10 +69,10 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
Position[] positions= event.getDocument().getPositions(fCategory);
for (int i= 0; i != positions.length; i++) {
HighlightedPosition position= (HighlightedPosition) positions[i];
// Also update deleted positions because they get deleted by the background thread and removed/invalidated only in the UI runnable
// Also update deleted positions because they get deleted by the background
// thread and removed/invalidated only in the UI runnable.
// if (position.isDeleted())
// continue;
@ -88,18 +80,19 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
int length= position.getLength();
int end= offset + length;
if (offset > eventEnd)
if (offset > eventEnd) {
updateWithPrecedingEvent(position, event);
else if (end < eventOffset)
} else if (end < eventOffset) {
updateWithSucceedingEvent(position, event);
else if (offset <= eventOffset && end >= eventEnd)
} else if (offset <= eventOffset && end >= eventEnd) {
updateWithIncludedEvent(position, event);
else if (offset <= eventOffset)
} else if (offset <= eventOffset) {
updateWithOverEndEvent(position, event);
else if (end >= eventEnd)
} else if (end >= eventEnd) {
updateWithOverStartEvent(position, event);
else
} else {
updateWithIncludingEvent(position, event);
}
}
} catch (BadPositionCategoryException e) {
// ignore and return
@ -107,7 +100,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event precedes the position.
* Updates the given position with the given event. The event precedes the position.
*
* @param position The position
* @param event The event
@ -121,7 +114,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event succeeds the position.
* Updates the given position with the given event. The event succeeds the position.
*
* @param position The position
* @param event The event
@ -130,7 +123,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event is included by the position.
* Updates the given position with the given event. The event is included by the position.
*
* @param position The position
* @param event The event
@ -151,9 +144,9 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
int includedLength= 0;
while (includedLength < eventNewLength && Character.isJavaIdentifierPart(newText.charAt(includedLength)))
includedLength++;
if (includedLength == eventNewLength)
if (includedLength == eventNewLength) {
position.setLength(length + deltaLength);
else {
} else {
int newLeftLength= eventOffset - offset + includedLength;
int excludedLength= eventNewLength;
@ -176,7 +169,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event overlaps with the end of the position.
* Updates the given position with the given event. The event overlaps with the end of
* the position.
*
* @param position The position
* @param event The event
@ -194,7 +188,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Update the given position with the given event. The event overlaps with the start of the position.
* Updates the given position with the given event. The event overlaps with the start of
* the position.
*
* @param position The position
* @param event The event
@ -353,12 +348,14 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Invalidate the presentation of the positions based on the given added positions and the existing deleted positions.
* Also unregisters the deleted positions from the document and patches the positions of this presenter.
* Invalidates the presentation of the positions based on the given added positions and
* the existing deleted positions. Also unregisters the deleted positions from the document
* and patches the positions of this presenter.
* <p>
* NOTE: Indirectly called from background thread by UI runnable.
* </p>
* @param textPresentation the text presentation or <code>null</code>, if the presentation should computed in the UI thread
* @param textPresentation the text presentation or <code>null</code>, if the presentation
* should computed in the UI thread
* @param addedPositions the added positions
* @param removedPositions the removed positions
*/
@ -398,7 +395,8 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
List<HighlightedPosition> newPositions= new ArrayList<HighlightedPosition>(newSize);
HighlightedPosition position= null;
HighlightedPosition addedPosition= null;
for (int i= 0, j= 0, n= oldPositions.size(), m= addedPositions.length; i < n || position != null || j < m || addedPosition != null;) {
for (int i= 0, j= 0, n= oldPositions.size(), m= addedPositions.length;
i < n || position != null || j < m || addedPosition != null;) {
// loop variant: i + j < old(i + j)
// a) find the next non-deleted Position from the old list
@ -489,7 +487,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Insert the given position in <code>fPositions</code>, s.t. the offsets remain in linear order.
* Inserts the given position in <code>fPositions</code>, s.t. the offsets remain in linear order.
*
* @param position The position for insertion
*/
@ -540,13 +538,11 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
return j;
}
/*
* @see org.eclipse.jface.text.ITextPresentationListener#applyTextPresentation(org.eclipse.jface.text.TextPresentation)
*/
@Override
public void applyTextPresentation(TextPresentation textPresentation) {
IRegion region= textPresentation.getExtent();
int i= computeIndexAtOffset(fPositions, region.getOffset()), n= computeIndexAtOffset(fPositions, region.getOffset() + region.getLength());
int i= computeIndexAtOffset(fPositions, region.getOffset());
int n= computeIndexAtOffset(fPositions, region.getOffset() + region.getLength());
if (n - i > 2) {
List<StyleRange> ranges= new ArrayList<StyleRange>(n - i);
for (; i < n; i++) {
@ -566,9 +562,6 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
}
/*
* @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
@Override
public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
setCanceled(true);
@ -576,25 +569,16 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
resetState();
}
/*
* @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
@Override
public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
manageDocument(newInput);
}
/*
* @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
*/
@Override
public void documentAboutToBeChanged(DocumentEvent event) {
setCanceled(true);
}
/*
* @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
*/
@Override
public void documentChanged(DocumentEvent event) {
}
@ -664,7 +648,7 @@ public class SemanticHighlightingPresenter implements ITextPresentationListener,
}
/**
* Uninstall this presenter.
* Uninstalls this presenter.
*/
public void uninstall() {
setCanceled(true);

View file

@ -81,7 +81,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
@Override
public int visit(IASTTranslationUnit tu) {
// visit macro definitions
// Visit macro definitions.
IASTPreprocessorMacroDefinition[] macroDefs= tu.getMacroDefinitions();
for (IASTPreprocessorMacroDefinition macroDef : macroDefs) {
if (macroDef.isPartOfTranslationUnitFile()) {
@ -90,7 +90,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
fMinLocation= -1;
// visit macro expansions
// Visit macro expansions.
IASTPreprocessorMacroExpansion[] macroExps= tu.getMacroExpansions();
for (IASTPreprocessorMacroExpansion macroExp : macroExps) {
if (macroExp.isPartOfTranslationUnitFile()) {
@ -104,7 +104,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
fMinLocation= -1;
// visit ordinary code
// Visit ordinary code.
return super.visit(tu);
}
@ -130,9 +130,6 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
return PROCESS_CONTINUE;
}
/*
* @see org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor#visit(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition)
*/
@Override
public int visit(ICPPASTNamespaceDefinition namespace) {
if (!namespace.isPartOfTranslationUnitFile()) {
@ -172,7 +169,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
SemanticHighlighting semanticHighlighting= fJobSemanticHighlightings[i];
if (fJobHighlightings[i].isEnabled() && semanticHighlighting.consumes(fToken)) {
if (node instanceof IASTName) {
addNameLocation((IASTName)node, fJobHighlightings[i]);
addNameLocation((IASTName) node, fJobHighlightings[i]);
} else {
addNodeLocation(node.getFileLocation(), fJobHighlightings[i]);
}
@ -197,14 +194,14 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
int offset= imageLocation.getNodeOffset();
if (offset >= fMinLocation) {
int length= imageLocation.getNodeLength();
if (offset > -1 && length > 0) {
if (offset >= 0 && length > 0) {
fMinLocation= offset + length;
addPosition(offset, length, highlightingStyle);
}
}
}
} else {
// Fallback in case no image location available
// Fallback in case no image location available.
IASTNodeLocation[] nodeLocations= name.getNodeLocations();
if (nodeLocations.length == 1 && !(nodeLocations[0] instanceof IASTMacroExpansionLocation)) {
addNodeLocation(nodeLocations[0], highlightingStyle);
@ -213,7 +210,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Add the a location range for the given highlighting.
* Adds the a location range for the given highlighting.
*
* @param nodeLocation The node location
* @param highlighting The highlighting
@ -233,7 +230,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Add a position with the given range and highlighting iff it does not exist already.
* Adds a position with the given range and highlighting iff it does not exist already.
*
* @param offset The range offset
* @param length The range length
@ -290,11 +287,20 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
*/
private boolean fIsReconciling= false;
/** The semantic highlighting presenter - cache for background thread, only valid during {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)} */
/**
* The semantic highlighting presenter - cache for background thread, only valid during
* {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)}
*/
protected SemanticHighlightingPresenter fJobPresenter;
/** Semantic highlightings - cache for background thread, only valid during {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)} */
/**
* Semantic highlightings - cache for background thread, only valid during
* {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)}
*/
protected SemanticHighlighting[] fJobSemanticHighlightings;
/** Highlightings - cache for background thread, only valid during {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)} */
/**
* Highlightings - cache for background thread, only valid during
* {@link #reconciled(IASTTranslationUnit, boolean, IProgressMonitor)}
*/
private HighlightingStyle[] fJobHighlightings;
@Override
@ -304,7 +310,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
@Override
public void reconciled(IASTTranslationUnit ast, boolean force, IProgressMonitor progressMonitor) {
// Ensure at most one thread can be reconciling at any time
// Ensure at most one thread can be reconciling at any time.
synchronized (fReconcileLock) {
if (fIsReconciling)
return;
@ -359,7 +365,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Start reconciling positions.
* Starts reconciling positions.
*/
protected void startReconcilingPositions() {
fJobPresenter.addAllPositions(fRemovedPositions);
@ -367,7 +373,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Reconcile positions based on the AST.
* Reconciles positions based on the AST.
*
* @param ast the AST
* @param visitor the AST visitor
@ -392,7 +398,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Update the presentation.
* Updates the presentation.
*
* @param textPresentation the text presentation
* @param addedPositions the added positions
@ -452,7 +458,7 @@ public class SemanticHighlightingReconciler implements ICReconcilingListener {
}
/**
* Uninstalsl this reconciler from the editor
* Uninstalls this reconciler from the editor
*/
public void uninstall() {
if (fPresenter != null)

View file

@ -67,7 +67,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
* @since 4.0
*/
public class SemanticHighlightings {
private static final RGB RGB_BLACK = new RGB(0, 0, 0);
/**

View file

@ -29,7 +29,7 @@ public final class SemanticToken {
/** Binding */
private IBinding fBinding;
/** Is the binding resolved? */
private boolean fIsBindingResolved= false;
private boolean fIsBindingResolved;
/** AST root */
private IASTTranslationUnit fRoot;
@ -69,7 +69,7 @@ public final class SemanticToken {
}
/**
* Update this token with the given AST node.
* Updates this token with the given AST node.
* <p>
* NOTE: Allowed to be used by {@link SemanticHighlightingReconciler} only.
* </p>

View file

@ -9,7 +9,6 @@
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems) - Adapted for CDT
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
import org.eclipse.jface.text.IDocument;
@ -17,7 +16,6 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.presentation.PresentationReconciler;
/**
* Presentation reconciler, adding functionality for operation without a viewer.
* Cloned from JDT.
@ -25,7 +23,6 @@ import org.eclipse.jface.text.presentation.PresentationReconciler;
* @since 4.0
*/
public class CPresentationReconciler extends PresentationReconciler {
/** Last used document */
private IDocument fLastDocument;

View file

@ -32,9 +32,7 @@ import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension {
private ITextEditor fEditor;
private IWorkingCopyManager fManager;
private IProgressMonitor fProgressMonitor;
@ -46,32 +44,20 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
fManager= CUIPlugin.getDefault().getWorkingCopyManager();
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
*/
@Override
public void setDocument(IDocument document) {
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion, org.eclipse.jface.text.IRegion)
*/
@Override
public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
// only called for incremental reconciler
}
/*
* @see IReconcilingStrategyExtension#setProgressMonitor(IProgressMonitor)
*/
@Override
public void setProgressMonitor(IProgressMonitor monitor) {
fProgressMonitor= monitor;
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
*/
@Override
public void reconcile(IRegion region) {
reconcile(false);
@ -91,10 +77,11 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
forced= workingCopy.isConsistent();
ast= workingCopy.reconcile(computeAST, true, fProgressMonitor);
}
} catch (OperationCanceledException oce) {
} catch (OperationCanceledException e) {
// document was modified while parsing
} catch (CModelException e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK,
"Error in CDT UI during reconcile", e); //$NON-NLS-1$
CUIPlugin.log(status);
} finally {
if (computeAST) {
@ -117,8 +104,9 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
if (canceled) {
aboutToBeReconciled();
}
} catch(Exception e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$
} catch (Exception e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK,
"Error in CDT UI during reconcile", e); //$NON-NLS-1$
CUIPlugin.log(status);
} finally {
if (index != null) {
@ -129,9 +117,6 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
}
}
/*
* @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
*/
@Override
public void initialReconcile() {
reconcile(true);
@ -143,5 +128,4 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
((ICReconcilingListener)fEditor).aboutToBeReconciled();
}
}
}

View file

@ -164,6 +164,9 @@ public class GdbConnectCommand extends AbstractDebugCommand implements IConnectH
fRequestMonitor.cancel();
} else if (result instanceof IProcessExtendedInfo[] || result instanceof String) {
fRequestMonitor.setData(result);
} else if (result instanceof Integer) {
// This is the case where the user typed in a pid number directly
fRequestMonitor.setData(new IProcessExtendedInfo[] { new ProcessInfo((Integer)result, "")}); //$NON-NLS-1$
} else {
fRequestMonitor.setStatus(NO_PID_STATUS);
}
@ -231,8 +234,10 @@ public class GdbConnectCommand extends AbstractDebugCommand implements IConnectH
protected void handleSuccess() {
// Store the path of the binary so we can use it again for another process
// with the same name. Only do this on success, to avoid being stuck with
// a path that is invalid
fProcessNameToBinaryMap.put(fProcName, finalBinaryPath);
// a path that is invalid.
if (fProcName != null && !fProcName.isEmpty()) {
fProcessNameToBinaryMap.put(fProcName, finalBinaryPath);
}
fRm.done();
};
});

View file

@ -8,6 +8,7 @@
* Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation
* Grzegorz Kuligowski - Cannot cast to type that contain commas (bug 393474)
* Marc Khouzam (Ericsson) - Support for glob-expressions for local variables (bug 394408)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -44,7 +45,6 @@ import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMData;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IGDBPatternMatchingExpressions;
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIRegisters.MIRegisterDMC;
import org.eclipse.cdt.dsf.service.AbstractDsfService;
@ -57,80 +57,65 @@ import com.ibm.icu.text.MessageFormat;
/**
* Expressions service added as a layer above the standard Expressions service.
* This layer allows to support group-expressions and glob-pattern matching.
* Group-expressions give the user the ability to create a comma-separated
* list of expressions in a single entry.
* This layer allows to support expression-groups and glob-pattern matching.
* Expression-groups give the user the ability to create a separated list
* of expressions in a single entry.
* Glob-patterns are a way to specify a set of expressions that match the
* pattern.
* @since 4.2
*/
public class GDBPatternMatchingExpressions extends AbstractDsfService implements IGDBPatternMatchingExpressions, ICachingService {
public class GDBPatternMatchingExpressions extends AbstractDsfService implements IMIExpressions, ICachingService {
/**
* A regex representing each character that can be used to separate
* the different expressions contained in a group-expression.
* n the different expressions contained in an expression-group.
* The [] are not part the characters, but are used in the regex format.
* Note that we don't allow a space separator because spaces are valid within
* an expression (e.g., i + 1).
* We also don't allow a comma because they are used in templates (bug 393474)
* We also don't allow a comma because they are used in C/C++ templates (bug 393474)
* Furthermore, commas are used within array-index matches as well.
*/
private final static String GROUP_EXPRESSION_SEPARATORS_REGEXP = "[;]"; //$NON-NLS-1$
private final static String EXPRESSION_GROUP_SEPARATORS_REGEXP = "[;]"; //$NON-NLS-1$
private final static String REGISTER_PREFIX = "$"; //$NON-NLS-1$
private final static String GLOB_EXPRESSION_PREFIX = "="; //$NON-NLS-1$
/**
* This regular expression describes the supported content of an array index range.
* Valid range formats are are numbers, possibly separated by - and/or ,.
* E.g, "23-56" or "32" or "23, 45-67, 12-15"
*/
private static final String ARRAY_INDEX_RANGE_REGEXP = "^*\\d+(\\s*-\\s*\\d+)?(\\s*,\\s*\\d+(\\s*-\\s*\\d+)?)*$";//$NON-NLS-1$
/**
* A group-expression is an expression that requires expansion into a (potentially empty)
* list of sub-expressions. Using a group-expression allows the user to create groups
* An expression-group is an expression that requires expansion into a (potentially empty)
* list of sub-expressions. Using an expression-group allows the user to create groups
* of expressions very quickly.
*
* We support two aspects for group-expressions:
* We support two aspects for expression-goups:
* 1- The glob syntax (http://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html)
* This allows to user to specify glob-patterns to match different expressions.
* 2- Comma-separated expressions, each potentially using the glob-syntax
* 2- Separated expressions, each potentially using the glob-syntax
*/
protected static class GroupExpressionDMC implements IExpressionDMContext {
protected static class ExpressionGroupDMC implements IExpressionGroupDMContext {
/**
* The expression context, as created by the main Expression service.
* We delegate the handling of the expression to it.
*/
private IExpressionDMContext fExprDelegate;
/**
* The set of expressions making up the group expression.
* This list is the result of splitting the original expression
* and then trimming each resulting expression.
*/
private List<String> fExpressionsInGroup = null;
public GroupExpressionDMC(IExpressionDMContext exprDmc) {
public ExpressionGroupDMC(IExpressionDMContext exprDmc) {
fExprDelegate = exprDmc;
}
protected IExpressionDMContext getExprDelegate() {
return fExprDelegate;
}
@Override
public String getExpression() {
return fExprDelegate.getExpression();
}
/**
* Returns an array representing the different expressions
* that make up this group-expression.
*/
public List<String> getExpressionsInGroup() {
if (fExpressionsInGroup == null) {
// Split the list
String[] splitExpressions = getExpression().split(GROUP_EXPRESSION_SEPARATORS_REGEXP);
// Remove any extra whitespace from each resulting expression,
// and ignore any empty expressions.
fExpressionsInGroup = new ArrayList<String>(splitExpressions.length);
for (String expr : splitExpressions) {
expr = expr.trim();
if (!expr.isEmpty()) {
fExpressionsInGroup.add(expr);
}
}
}
return fExpressionsInGroup;
}
@Override
public String getSessionId() {
return fExprDelegate.getSessionId();
@ -150,25 +135,30 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof GroupExpressionDMC)) return false;
if (!(obj instanceof ExpressionGroupDMC)) return false;
return ((GroupExpressionDMC)obj).fExprDelegate.equals(fExprDelegate);
return ((ExpressionGroupDMC)obj).fExprDelegate.equals(fExprDelegate);
}
@Override
public int hashCode() {
return fExprDelegate.hashCode();
}
@Override
public String toString() {
return "Group: " + getExprDelegate().toString(); //$NON-NLS-1$
}
}
/**
* The model data interface for group-expressions
* The model data interface for expression-groups
*/
protected static class GroupExpressionDMData implements IExpressionDMDataExtension {
protected static class ExpressionGroupDMData implements IExpressionDMDataExtension {
private final String fRelativeExpression;
private final int fNumChildren;
public GroupExpressionDMData(String expr, int numChildren) {
public ExpressionGroupDMData(String expr, int numChildren) {
assert expr != null;
fRelativeExpression = expr;
@ -218,8 +208,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof GroupExpressionDMData)) return false;
return fRelativeExpression.equals(((GroupExpressionDMData)other).fRelativeExpression);
if (!(other instanceof ExpressionGroupDMData)) return false;
return fRelativeExpression.equals(((ExpressionGroupDMData)other).fRelativeExpression);
}
@Override
@ -229,18 +219,18 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public String toString() {
return "GroupExpr: " + fRelativeExpression; //$NON-NLS-1$
return "ExprGroup: " + fRelativeExpression; //$NON-NLS-1$
}
}
/**
* The base expression service to which we delegate all non-group-expression logic.
* The base expression service to which we delegate all non-expression-group logic.
*/
private IMIExpressions fDelegate;
public GDBPatternMatchingExpressions(DsfSession session, IExpressions delegate) {
public GDBPatternMatchingExpressions(DsfSession session, IMIExpressions delegate) {
super(session);
fDelegate = (IMIExpressions)delegate;
fDelegate = delegate;
}
@Override
@ -290,8 +280,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
IExpressionDMContext expressionDmc = fDelegate.createExpression(ctx, expression);
if (isGroupExpression(expression)) {
return new GroupExpressionDMC(expressionDmc);
if (isExpressionGroup(expression)) {
return new ExpressionGroupDMC(expressionDmc);
} else {
return expressionDmc;
}
@ -299,19 +289,19 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public ICastedExpressionDMContext createCastedExpression(IExpressionDMContext context, CastInfo castInfo) {
// Cannot cast a GroupExpression
assert (!(context instanceof GroupExpressionDMC));
// Cannot cast an expression-group
assert (!(context instanceof IExpressionGroupDMContext));
return fDelegate.createCastedExpression(context, castInfo);
}
@Override
public void getExpressionDataExtension(final IExpressionDMContext dmc, final DataRequestMonitor<IExpressionDMDataExtension> rm) {
if (dmc instanceof GroupExpressionDMC) {
if (dmc instanceof IExpressionGroupDMContext) {
getSubExpressionCount(dmc, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
rm.done(new GroupExpressionDMData(((GroupExpressionDMC)dmc).getExpression(), getData()));
rm.done(new ExpressionGroupDMData(((IExpressionGroupDMContext)dmc).getExpression(), getData()));
}
});
return;
@ -323,11 +313,11 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getExpressionData(final IExpressionDMContext dmc, final DataRequestMonitor<IExpressionDMData> rm) {
if (dmc instanceof GroupExpressionDMC) {
if (dmc instanceof IExpressionGroupDMContext) {
getSubExpressionCount(dmc, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
rm.done(new GroupExpressionDMData(((GroupExpressionDMC)dmc).getExpression(), getData()));
rm.done(new ExpressionGroupDMData(((IExpressionGroupDMContext)dmc).getExpression(), getData()));
}
});
return;
@ -338,8 +328,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm) {
// A GroupExpression does not have an address
if (dmc instanceof GroupExpressionDMC) {
// An expression-group does not have an address
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(new IExpressionDMLocation() {
@Override
public IAddress getAddress() {
@ -362,8 +352,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm) {
if (exprCtx instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)exprCtx, -1, -1, rm);
if (exprCtx instanceof IExpressionGroupDMContext) {
matchExpressionGroup((IExpressionGroupDMContext)exprCtx, -1, -1, rm);
} else {
fDelegate.getSubExpressions(exprCtx, rm);
}
@ -371,8 +361,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, DataRequestMonitor<IExpressionDMContext[]> rm) {
if (exprCtx instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)exprCtx, startIndex, length, rm);
if (exprCtx instanceof IExpressionGroupDMContext) {
matchExpressionGroup((IExpressionGroupDMContext)exprCtx, startIndex, length, rm);
} else {
fDelegate.getSubExpressions(exprCtx, startIndex, length, rm);
}
@ -380,8 +370,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressionCount(IExpressionDMContext dmc, final DataRequestMonitor<Integer> rm) {
if (dmc instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
if (dmc instanceof IExpressionGroupDMContext) {
matchExpressionGroup((IExpressionGroupDMContext)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().length);
@ -394,10 +384,10 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void getSubExpressionCount(IExpressionDMContext dmc, int maxNumberOfChildren, final DataRequestMonitor<Integer> rm) {
if (dmc instanceof GroupExpressionDMC) {
// No need to worry about maxNumberOfChildren for the case of a group-expression, since there won't be
if (dmc instanceof IExpressionGroupDMContext) {
// No need to worry about maxNumberOfChildren for the case of an expression-group, since there won't be
// a very large amount of them.
matchGroupExpression((GroupExpressionDMC)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
matchExpressionGroup((IExpressionGroupDMContext)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().length);
@ -415,8 +405,8 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void canWriteExpression(IExpressionDMContext dmc, DataRequestMonitor<Boolean> rm) {
// A GroupExpression's value cannot be modified
if (dmc instanceof GroupExpressionDMC) {
// An expression-group's value cannot be modified
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(false);
return;
}
@ -426,15 +416,15 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void writeExpression(IExpressionDMContext dmc, String expressionValue, String formatId, RequestMonitor rm) {
// A GroupExpression's value cannot be modified
assert !(dmc instanceof GroupExpressionDMC);
// An expression-group's value cannot be modified
assert !(dmc instanceof IExpressionGroupDMContext);
fDelegate.writeExpression(dmc, expressionValue, formatId, rm);
}
@Override
public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
//For a group expression, we only show the NATURAL format
if (dmc instanceof GroupExpressionDMC) {
// For an expression-group, we only show the NATURAL format
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(new String[] { IFormattedValues.NATURAL_FORMAT });
return;
}
@ -444,15 +434,15 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) {
// No special handling for GroupExpressions
// No special handling for expression-groups
return fDelegate.getFormattedValueContext(dmc, formatId);
}
@Override
public void getFormattedExpressionValue(FormattedValueDMContext dmc, final DataRequestMonitor<FormattedValueDMData> rm) {
GroupExpressionDMC groupExpr = DMContexts.getAncestorOfType(dmc, GroupExpressionDMC.class);
if (groupExpr != null) {
getSubExpressionCount(groupExpr, new ImmediateDataRequestMonitor<Integer>(rm) {
IExpressionGroupDMContext exprGroup = DMContexts.getAncestorOfType(dmc, IExpressionGroupDMContext.class);
if (exprGroup != null) {
getSubExpressionCount(exprGroup, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
int numChildren = getData();
@ -475,9 +465,9 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
@Override
public void safeToAskForAllSubExpressions(IExpressionDMContext dmc, DataRequestMonitor<Boolean> rm) {
// Always safe to ask for all sub-expression of a group expression, since we don't expect large
// amounts of children
if (dmc instanceof GroupExpressionDMC) {
// Always safe to ask for all sub-expression of an expression-group,
// since we don't expect large amounts of children
if (dmc instanceof IExpressionGroupDMContext) {
rm.done(true);
return;
}
@ -493,81 +483,162 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
}
/**
* Verify if we are dealing with a group expression.
* Verify if we are dealing with an expression-group.
* @param expr The expression to verify
* @return True if expr is a group expression. A group
* expression is either a comma-separated list of
* @return True if expr is an expression-group. An
* expression-group is either a separated list of
* expressions, or an expression using a glob-pattern
*/
protected boolean isGroupExpression(String expr) {
// First check for a comma separated list of expression
protected boolean isExpressionGroup(String expr) {
// First check for a separated list of expression
// We want to re-use the regex that defines our separators, and we need to check
// if the expression contains that regex. I didn't find a method that
// checks if a string contains a regex, so instead we all any character before
// checks if a string contains a regex, so instead we add any character before
// and after the regex, which achieves what we want.
// Note that checking if expr.split(regex) is bigger than 1, will not notice
// Note that checking if (expr.split(regex) > 1), will not notice
// an expression that has a separator only at the end.
if (expr.matches(".*" + GROUP_EXPRESSION_SEPARATORS_REGEXP +".*")) { //$NON-NLS-1$ //$NON-NLS-2$
// We are dealing with a group expression.
if (expr.matches(".*" + EXPRESSION_GROUP_SEPARATORS_REGEXP +".*")) { //$NON-NLS-1$ //$NON-NLS-2$
// We are dealing with a group of expressions.
// It may not be a valid one, but it is one nonetheless.
return true;
}
// Not a comma-separated list. Check if we are dealing with a glob-pattern.
return isGlobPattern(expr);
// Not a list. Check if we are dealing with a glob-pattern.
return isGlobExpression(expr);
}
/**
* Verify if we are dealing with a glob-pattern.
* We support the expression * which will match all local variables.
* We support glob-patterns for registers (must start with $)
* We support the expression '*' which will match all local variables
* as well as the expression '$*' which will match all registers.
* We support glob-patterns for any expression starting with '='
*
* @param expr The expression to verify
* @return True if expr is a glob-pattern we support.
*/
protected boolean isGlobPattern(String expr) {
protected boolean isGlobExpression(String expr) {
// Get rid of useless whitespace
expr = expr.trim();
// We support the glob-pattern '*' to indicate all local variables
if (expr.equals("*")) { //$NON-NLS-1$
// and $* for all registers
if (expr.equals("*") || expr.equals("$*")) { //$NON-NLS-1$ //$NON-NLS-2$
return true;
}
// We only support glob-expressions for registers at this time
if (expr.startsWith("$")) { //$NON-NLS-1$
// see: 'man glob'
if (expr.indexOf('*') != -1 || expr.indexOf('?') != -1 || expr.indexOf('[') != -1) {
return true;
}
// Glob-expressions must start with '='
if (expr.startsWith(GLOB_EXPRESSION_PREFIX)) {
return true;
}
return false;
}
/**
* Find all expressions that match the specified group-expression.
* This method retains the order of the expressions in the group-expression, to show them
* in the same order as the one specified by the user. The match of each expression in the group
* is sorted alphabetically however.
* Verify if the glob-pattern represents a register.
*
* @param groupExprDmc The group-expression context for which we want the matches (sub-expressions)
* @param expr The glob-pattern that may be a register-pattern
* @return True if expr follows the rules of an register-pattern
*/
protected boolean isRegisterPattern(String expr) {
// Get rid of useless whitespace
expr = expr.trim();
if (expr.startsWith(REGISTER_PREFIX)) {
return true;
}
return false;
}
/**
* Verify if the glob-pattern should be handled as an array index range.
* When dealing with variables (on contrast to registers), the [] will
* map to array indices instead of ranges within the array name.
* For example =array[1-2] will map to array[1] and array[2] instead of
* array1 and array2.
*
* If the range contains non-digits, the matching will not be handled
* as array indices.
*
* @param expr The glob-pattern that may be an array-pattern
* @return True if expr follows the rules of an array-pattern
*/
protected boolean isArrayPattern(String expr) {
// Get rid of useless whitespace
expr = expr.trim();
int openBracketIndex = expr.indexOf('[');
// There must be an open bracket and it cannot be in the first position
// (as we need some indication of the array name before the brackets)
if (openBracketIndex < 1) {
return false;
}
// We don't support any characters after the closing bracket
// since we don't support any operations on an expression-group.
if (!expr.endsWith("]")) { //$NON-NLS-1$
return false;
}
// We have a match for a variable which uses brackets.
// Check if the indices are integer ranges (using - or commas).
try {
Pattern pattern = Pattern.compile(ARRAY_INDEX_RANGE_REGEXP, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(expr.substring(openBracketIndex+1, expr.length()-1));
if (!matcher.find()) {
return false;
}
} catch(Exception e) {
// If the user put an invalid pattern, we just ignore it
return false;
}
return true;
}
/**
* Split the expression-group into a list of individual expression strings.
*/
protected List<String> splitExpressionsInGroup(IExpressionGroupDMContext groupDmc) {
// Split the list of expressions
String[] splitExpressions = groupDmc.getExpression().split(EXPRESSION_GROUP_SEPARATORS_REGEXP);
// Remove any extra whitespace from each resulting expression,
// and ignore any empty expressions.
List<String> expressions = new ArrayList<String>(splitExpressions.length);
for (String expr : splitExpressions) {
expr = expr.trim();
if (!expr.isEmpty()) {
expressions.add(expr);
}
}
return expressions;
}
/**
* Find all expressions that match the specified expression-group.
* This method retains the order of the expressions in the expression-group, to show them
* in the same order as the one specified by the user. The matches of each expression within the group
* are sorted alphabetically however.
*
* @param exprGroupDmc The expression-group context for which we want the matches (sub-expressions)
* @param startIndex The beginning of the range of matches (-1 means all matches)
* @param length The length of the range of matches (-1 means all matches)
* @param rm RequestMonitor that will contain the range of found matches.
*/
protected void matchGroupExpression(final GroupExpressionDMC groupExprDmc, int startIndex, int length,
protected void matchExpressionGroup(final IExpressionGroupDMContext exprGroupDmc, int startIndex, int length,
final DataRequestMonitor<IExpressionDMContext[]> rm) {
// First separate the group into different expressions.
// We need to create a new list, as we will modify it during our processing.
final List<String> exprList = new ArrayList<String>(groupExprDmc.getExpressionsInGroup());
final List<String> exprList = new ArrayList<String>(splitExpressionsInGroup(exprGroupDmc));
// List to store the final result, which is all the sub-expressions of this group
final ArrayList<IExpressionDMContext> subExprList = new ArrayList<IExpressionDMContext>();
final int startIndex1 = (startIndex < 0) ? 0 : startIndex;
final int length1 = (length < 0) ? Integer.MAX_VALUE : length;
matchExpressionList(exprList, subExprList, groupExprDmc, new ImmediateRequestMonitor(rm) {
matchExpressionList(exprList, subExprList, exprGroupDmc, new ImmediateRequestMonitor(rm) {
@Override
protected void handleSuccess() {
// It would be nice to allow identical elements, so that the user
@ -608,9 +679,9 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
// and sort the result alphabetically in that case.
String expr = exprList.remove(0);
if (isGlobPattern(expr)) {
IExpressionDMContext exprDmc = createExpression(parentDmc, expr);
matchGlobExpression(exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
IExpressionDMContext exprDmc = createExpression(parentDmc, expr);
if (exprDmc instanceof IExpressionGroupDMContext) {
matchGlobExpression((IExpressionGroupDMContext)exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
@Override
protected void handleSuccess() {
List<IExpressionDMContext> matches = getData();
@ -618,6 +689,31 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
Collections.sort(matches, new Comparator<IExpressionDMContext>() {
@Override
public int compare(IExpressionDMContext o1, IExpressionDMContext o2) {
// For elements of the same array, we need to sort by index
if (isArrayPattern(o1.getExpression()) && isArrayPattern(o2.getExpression())) {
// Extract the array names and the array indices specification.
// The regex used will remove both [ and ]
String[] arrayExprParts1 = o1.getExpression().split("[\\[\\]]"); //$NON-NLS-1$
assert arrayExprParts1 != null && arrayExprParts1.length == 2;
String[] arrayExprParts2 = o2.getExpression().split("[\\[\\]]"); //$NON-NLS-1$
assert arrayExprParts2 != null && arrayExprParts2.length == 2;
// Compare array names
if (arrayExprParts1[0].compareTo(arrayExprParts2[0]) == 0) {
// We are dealing with the same array
try {
int arrayIndex1 = Integer.parseInt(arrayExprParts1[1]);
int arrayIndex2 = Integer.parseInt(arrayExprParts2[1]);
if (arrayIndex1 == arrayIndex2) return 0;
if (arrayIndex1 > arrayIndex2) return 1;
return -1;
} catch (NumberFormatException e) {
// Invalid array index. Fall-back to sorting lexically.
}
}
}
return o1.getExpression().compareTo(o2.getExpression());
}
});
@ -629,7 +725,7 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
});
} else {
// Just a normal expression
subExprList.add(createExpression(parentDmc, expr));
subExprList.add(exprDmc);
// Match the next expression from the list
matchExpressionList(exprList, subExprList, parentDmc, rm);
}
@ -639,63 +735,96 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
* Find all expressions that match the specified glob-pattern.
*
* @param exprDmc The expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the matches.
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchGlobExpression(final IExpressionDMContext exprDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final String fullExpr = exprDmc.getExpression().trim();
protected void matchGlobExpression(final IExpressionGroupDMContext exprDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
String fullExpr = exprDmc.getExpression().trim();
if (fullExpr.equals("*")) { //$NON-NLS-1$
matchLocals(exprDmc, rm);
return;
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
// Currently, we only support glob-expressions for registers, so
// we only need to match the glob-expression with register names.
// We should not arrive here if we are not handling a register
assert fullExpr.startsWith("$"); //$NON-NLS-1$
if (isRegisterPattern(fullExpr)) {
matchRegisters(exprDmc, rm);
} else {
if (!isArrayPattern(fullExpr)) {
matchLocals(exprDmc, rm);
} else {
// If we are dealing with an expression that could represent an array, we must
// try to match arrays and non-arrays. The reason is that a pattern such as
// =a[1-2] can be a valid match for both a[1], a[2] and a1, a2.
matchArrays(exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
@Override
protected void handleSuccess() {
final List<IExpressionDMContext> exprList =
getData() != null ? getData() : new ArrayList<IExpressions.IExpressionDMContext>();
matchLocals(exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
@Override
protected void handleSuccess() {
if (getData() != null) {
exprList.addAll(getData());
}
rm.done(exprList);
}
});
}
});
}
}
}
/**
* Find all registers that match the specified glob-pattern.
*
* @param globDmc The glob-expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchRegisters(final IExpressionGroupDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final IRegisters registerService = getServicesTracker().getService(IRegisters.class);
if (registerService == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Register service unavailable", null)); //$NON-NLS-1$
return;
}
registerService.getRegisterGroups(exprDmc, new ImmediateDataRequestMonitor<IRegisterGroupDMContext[]>(rm) {
registerService.getRegisterGroups(globDmc, new ImmediateDataRequestMonitor<IRegisterGroupDMContext[]>(rm) {
@Override
protected void handleSuccess() {
registerService.getRegisters(
new CompositeDMContext(new IDMContext[] { getData()[0], exprDmc } ),
new ImmediateDataRequestMonitor<IRegisterDMContext[]>(rm) {
@Override
protected void handleSuccess() {
assert getData() instanceof MIRegisterDMC[];
ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>();
for (MIRegisterDMC register : (MIRegisterDMC[])getData()) {
String potentialMatch = "$"+register.getName(); //$NON-NLS-1$
if (globMatches(fullExpr, potentialMatch)) {
matches.add(createExpression(exprDmc, potentialMatch));
}
}
new CompositeDMContext(new IDMContext[] { getData()[0], globDmc } ),
new ImmediateDataRequestMonitor<IRegisterDMContext[]>(rm) {
@Override
protected void handleSuccess() {
assert getData() instanceof MIRegisterDMC[];
ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>();
String fullExpr = globDmc.getExpression().trim();
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
for (MIRegisterDMC register : (MIRegisterDMC[])getData()) {
String potentialMatch = REGISTER_PREFIX + register.getName();
if (globMatches(fullExpr, potentialMatch)) {
matches.add(createExpression(globDmc, potentialMatch));
}
}
rm.done(matches);
}
});
rm.done(matches);
}
});
}
});
}
/**
* Find all local variables that match the specified glob-pattern.
* We currently only support matching all local variables using the '*' pattern.
*
* @param globDmc The glob-expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the matches.
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchLocals(final IExpressionDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
// We only support '*' for local variables at this time
assert globDmc.getExpression().equals("*"); //$NON-NLS-1$
protected void matchLocals(final IExpressionGroupDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final IStack stackService = getServicesTracker().getService(IStack.class);
if (stackService == null) {
@ -715,45 +844,239 @@ public class GDBPatternMatchingExpressions extends AbstractDsfService implements
IVariableDMContext[] localsDMCs = getData();
final IVariableDMData[] localsDMData = new IVariableDMData[localsDMCs.length];
final CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm) {
final CountingRequestMonitor varNameCRM = new CountingRequestMonitor(getExecutor(), rm) {
@Override
public void handleSuccess() {
ArrayList<IExpressionDMContext> expressionDMCs = new ArrayList<IExpressionDMContext>(localsDMData.length);
ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>(localsDMData.length);
String fullExpr = globDmc.getExpression().trim();
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
for (IVariableDMData localDMData : localsDMData) {
expressionDMCs.add(createExpression(globDmc, localDMData.getName()));
String potentialMatch = localDMData.getName();
if (globMatches(fullExpr, potentialMatch)) {
matches.add(createExpression(globDmc, potentialMatch));
}
}
rm.done(expressionDMCs);
rm.done(matches);
}
};
int countRM = 0;
// Get all the names of the variables
int count = 0;
for (int index=0; index < localsDMCs.length; index++) {
final int finalIndex = index;
stackService.getVariableData(localsDMCs[finalIndex], new ImmediateDataRequestMonitor<IVariableDMData>(crm) {
stackService.getVariableData(localsDMCs[finalIndex], new ImmediateDataRequestMonitor<IVariableDMData>(varNameCRM) {
@Override
public void handleSuccess() {
localsDMData[finalIndex] = getData();
crm.done();
varNameCRM.done();
}
});
countRM++;
count++;
}
crm.setDoneCount(countRM);
varNameCRM.setDoneCount(count);
}
});
}
/**
* Find all arrays elements that match the specified glob-pattern.
*
* @param globDmc The glob-expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the unsorted matches.
*/
protected void matchArrays(final IExpressionGroupDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final IStack stackService = getServicesTracker().getService(IStack.class);
if (stackService == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Stack service unavailable", null)); //$NON-NLS-1$
return;
}
IFrameDMContext frameCtx = DMContexts.getAncestorOfType(globDmc, IFrameDMContext.class);
if (frameCtx == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Stack frame unavailable", null)); //$NON-NLS-1$
return;
}
String fullExpr = globDmc.getExpression().trim();
if (fullExpr.startsWith(GLOB_EXPRESSION_PREFIX)) {
// Strip the leading '=' and any extra spaces
fullExpr = fullExpr.substring(1).trim();
}
// Extract the array name and the array index specification.
// The regex used will remove both [ and ]
String[] arrayExprParts = fullExpr.split("[\\[\\]]"); //$NON-NLS-1$
assert arrayExprParts != null && arrayExprParts.length == 2;
if (arrayExprParts == null || arrayExprParts.length < 2) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Error parsing array expression", null)); //$NON-NLS-1$
return;
}
final String arrayName = arrayExprParts[0].trim();
final String arrayIndexSpec = arrayExprParts[1].trim();
stackService.getLocals(frameCtx, new ImmediateDataRequestMonitor<IVariableDMContext[]>(rm) {
@Override
protected void handleSuccess() {
IVariableDMContext[] localsDMCs = getData();
final IVariableDMData[] localsDMData = new IVariableDMData[localsDMCs.length];
final CountingRequestMonitor varNameCRM = new CountingRequestMonitor(getExecutor(), rm) {
@Override
public void handleSuccess() {
final ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>();
final CountingRequestMonitor elementMatchesCRM = new CountingRequestMonitor(getExecutor(), rm) {
@Override
public void handleSuccess() {
rm.done(matches);
}
};
int count = 0;
for (IVariableDMData localDMData : localsDMData) {
final String potentialMatch = localDMData.getName();
if (globMatches(arrayName, potentialMatch)) {
// We have a variable that matches the name part of the array.
// Let's create the matching elements if that variable is an array.
createPotentialArrayMatches(createExpression(globDmc, potentialMatch), arrayIndexSpec,
new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(elementMatchesCRM){
@Override
protected void handleSuccess() {
if (getData() != null) {
matches.addAll(getData());
}
elementMatchesCRM.done();
}
});
count++;
}
}
elementMatchesCRM.setDoneCount(count);
}
};
// Get all the names of the variables
int count = 0;
for (int index=0; index < localsDMCs.length; index++) {
final int finalIndex = index;
stackService.getVariableData(localsDMCs[finalIndex], new ImmediateDataRequestMonitor<IVariableDMData>(varNameCRM) {
@Override
public void handleSuccess() {
localsDMData[finalIndex] = getData();
varNameCRM.done();
}
});
count++;
}
varNameCRM.setDoneCount(count);
}
});
}
/**
* Creates requested array elements if exprDmc is indeed an array.
*
* @param exprDmc The potential array expression to be used
* @param indexSpec The specification of the element indices
* @param rm The list of created element expressions.
* If exprDmc is not an array, the list will be empty but not null.
*/
protected void createPotentialArrayMatches(final IExpressionDMContext exprDmc, final String indexSpec,
final DataRequestMonitor<List<IExpressionDMContext>> rm) {
// We check if the variable is an array or not. If it is an array,
// we create the elements based on the specified indices.
// If it is not an array, we don't need to handle it in this method
getExpressionData(exprDmc, new ImmediateDataRequestMonitor<IExpressionDMData>(rm) {
@Override
protected void handleCompleted() {
boolean isArray =
isSuccess() &&
getData().getBasicType().equals(IExpressionDMData.BasicType.array);
final ArrayList<IExpressionDMContext> elements = new ArrayList<IExpressionDMContext>();
if (isArray) {
// we must now create the elements based on the indices
List<IExpressionDMContext> indicesDmcs =
createArrayIndicesExpression(exprDmc, indexSpec);
if (indicesDmcs != null) {
elements.addAll(indicesDmcs);
}
}
rm.done(elements);
}
});
}
/**
* Create all the expressions characterizing the specified arrayDmc and
* indexSpec pattern.
*
* @param arrayDmc The expression context that represents the array itself
* @param indexSpec A string describing the range of indexes to be used.
* Valid range formats are described by {@code ARRAY_INDEX_RANGE_REGEXP}
* The string should not contain the index [] characters.
* @return A list of expression contexts representing all the different
* array elements possible using the name of the array and indexSpec.
* If the indexSpec is invalid (e.g, 3-2) it will be used as-is which
* could be a valid expression (i.e., the index 3-2=1 in this case)
*/
protected List<IExpressionDMContext> createArrayIndicesExpression(IExpressionDMContext arrayDmc, String indexSpec) {
ArrayList<IExpressionDMContext> expressionDMCs = new ArrayList<IExpressionDMContext>();
String arrayName = arrayDmc.getExpression();
IDMContext parentDmc = arrayDmc.getParents()[0];
// First split the indexRange by comma
String[] ranges = indexSpec.split(","); //$NON-NLS-1$
for (String range : ranges) {
// Get rid of any useless spaces
range = range.trim();
// Try to split the range with the - separator
String[] rangeNumbers = range.split("-");//$NON-NLS-1$
if (rangeNumbers.length == 2) {
try {
int lowIndex = Integer.parseInt(rangeNumbers[0]);
int highIndex = Integer.parseInt(rangeNumbers[1]);
if (lowIndex <= highIndex) {
for (int i = lowIndex; i <= highIndex; i++) {
expressionDMCs.add(createExpression(parentDmc, arrayName + "[" + i + "]")); //$NON-NLS-1$ //$NON-NLS-2$
}
continue;
}
} catch (NumberFormatException e) {
// Ignore and fall back on using range as-is below
}
}
// Leave range as-is, which could be a single digit, or some non-expected expression
expressionDMCs.add(createExpression(parentDmc, arrayName + "[" + range + "]")); //$NON-NLS-1$ //$NON-NLS-2$
}
return expressionDMCs;
}
/**
* Verify if the potentialMatch variable matches the glob-pattern.
*
* @param globPattern The glob-pattern to match
* @param potentialMatch The string that must match globPattern.
* @return True of potentialMatch does match globPattern.
* @return True if potentialMatch does match globPattern.
*/
protected boolean globMatches(String globPattern, String potentialMatch) {
// Convert the glob-pattern into java regex to do the matching
// Convert the glob-pattern into java regex to do the matching
boolean inBrackets = false;
char[] patternArray = globPattern.toCharArray();

View file

@ -10,6 +10,7 @@
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
* John Dallaway - GDB 7.x MI thread details field ignored (Bug 325556)
* Marc Khouzam (Ericsson) - Make each thread an IDisassemblyDMContext (bug 352748)
* Andy Jin (QNX) - Not output thread osId as a string when it is null (Bug 397039)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -774,13 +775,20 @@ public class GDBProcesses_7_0 extends AbstractDsfService
if (getData().getThreadList().length != 0) {
MIThread thread = getData().getThreadList()[0];
if (thread.getThreadId().equals(threadDmc.getId())) {
String id = thread.getOsId();
String id = ""; //$NON-NLS-1$
if (thread.getOsId() != null) {
id = thread.getOsId();
}
// append thread details (if any) to the thread ID
// as for GDB 6.x with CLIInfoThreadsInfo#getOsId()
final String details = thread.getDetails();
if (details != null && details.length() > 0) {
id += " (" + details + ")"; //$NON-NLS-1$ //$NON-NLS-2$
if (!id.isEmpty()) id += " "; //$NON-NLS-1$
id += "(" + details + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
// We must indicate and empty id by using null
if (id.isEmpty()) id = null;
threadData = new MIThreadDMData("", id); //$NON-NLS-1$
}
}

Some files were not shown because too many files have changed in this diff Show more