mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Merge remote-tracking branch 'origin/master' into bug_45203
This commit is contained in:
commit
a205a71148
50 changed files with 1127 additions and 622 deletions
|
@ -221,7 +221,8 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser
|
||||||
// appending fileName to cwd should yield file path
|
// appending fileName to cwd should yield file path
|
||||||
filePath = cwd.append(fileName);
|
filePath = cwd.append(fileName);
|
||||||
}
|
}
|
||||||
if (!filePath.toString().equalsIgnoreCase(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()))) {
|
IPath fileLocation = new Path(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()));
|
||||||
|
if (!filePath.toString().equalsIgnoreCase(fileLocation.toString())) {
|
||||||
// must be the cwd is wrong
|
// must be the cwd is wrong
|
||||||
// check if file name starts with ".."
|
// check if file name starts with ".."
|
||||||
if (fileName.startsWith("..")) { //$NON-NLS-1$
|
if (fileName.startsWith("..")) { //$NON-NLS-1$
|
||||||
|
@ -238,7 +239,7 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser
|
||||||
tPath = tPath.removeFirstSegments(1);
|
tPath = tPath.removeFirstSegments(1);
|
||||||
}
|
}
|
||||||
// get the file path from the file
|
// get the file path from the file
|
||||||
filePath = new Path(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()));
|
filePath = fileLocation;
|
||||||
IPath lastFileSegment = filePath.removeFirstSegments(filePath.segmentCount() - tPath.segmentCount());
|
IPath lastFileSegment = filePath.removeFirstSegments(filePath.segmentCount() - tPath.segmentCount());
|
||||||
if (lastFileSegment.matchingFirstSegments(tPath) == tPath.segmentCount()) {
|
if (lastFileSegment.matchingFirstSegments(tPath) == tPath.segmentCount()) {
|
||||||
cwd = filePath.removeLastSegments(tPath.segmentCount());
|
cwd = filePath.removeLastSegments(tPath.segmentCount());
|
||||||
|
|
|
@ -18,6 +18,7 @@ import junit.framework.TestSuite;
|
||||||
import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext;
|
import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext;
|
||||||
import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set;
|
import org.eclipse.cdt.build.core.scannerconfig.ICfgScannerConfigBuilderInfo2Set;
|
||||||
import org.eclipse.cdt.build.internal.core.scannerconfig2.CfgScannerConfigProfileManager;
|
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.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||||
|
@ -106,6 +107,7 @@ public class CfgScannerConfigProfileManagerTests extends BaseTestCase {
|
||||||
Assert.isTrue("dummyFile".equals(scbi.getBuildOutputFilePath()));
|
Assert.isTrue("dummyFile".equals(scbi.getBuildOutputFilePath()));
|
||||||
|
|
||||||
// Test restore defaults
|
// Test restore defaults
|
||||||
|
ScannerDiscoveryLegacySupport.setLanguageSettingsProvidersFunctionalityEnabled(fProject, false);
|
||||||
scbis.applyInfo(cic, null);
|
scbis.applyInfo(cic, null);
|
||||||
// Save the project description
|
// Save the project description
|
||||||
CoreModel.getDefault().setProjectDescription(fProject, prjDesc);
|
CoreModel.getDefault().setProjectDescription(fProject, prjDesc);
|
||||||
|
|
|
@ -563,7 +563,7 @@ public class ConfigurationDataProvider extends CConfigurationDataProvider implem
|
||||||
|
|
||||||
private static List<ILanguageSettingsProvider> getDefaultLanguageSettingsProviders(IConfiguration cfg) {
|
private static List<ILanguageSettingsProvider> getDefaultLanguageSettingsProviders(IConfiguration cfg) {
|
||||||
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
List<ILanguageSettingsProvider> providers = new ArrayList<ILanguageSettingsProvider>();
|
||||||
String[] ids = cfg.getDefaultLanguageSettingsProviderIds();
|
String[] ids = cfg != null ? cfg.getDefaultLanguageSettingsProviderIds() : null;
|
||||||
if (ids != null) {
|
if (ids != null) {
|
||||||
for (String id : ids) {
|
for (String id : ids) {
|
||||||
ILanguageSettingsProvider provider = null;
|
ILanguageSettingsProvider provider = null;
|
||||||
|
|
|
@ -15,6 +15,9 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.AbstractExecutableExtensionBase;
|
import org.eclipse.cdt.core.AbstractExecutableExtensionBase;
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
|
||||||
|
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
|
||||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsBroadcastingProvider;
|
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsBroadcastingProvider;
|
||||||
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsStorage;
|
import org.eclipse.cdt.core.language.settings.providers.LanguageSettingsStorage;
|
||||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||||
|
@ -26,6 +29,7 @@ import org.eclipse.cdt.core.settings.model.ICPathEntry;
|
||||||
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
|
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
|
||||||
import org.eclipse.cdt.core.settings.model.ICSettingBase;
|
import org.eclipse.cdt.core.settings.model.ICSettingBase;
|
||||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
@ -73,12 +77,24 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase
|
||||||
if (!new Path(pathStr).isAbsolute()) {
|
if (!new Path(pathStr).isAbsolute()) {
|
||||||
// We need to add project-rooted entry for relative path as MBS counts it this way in some UI
|
// We need to add project-rooted entry for relative path as MBS counts it this way in some UI
|
||||||
// The relative entry below also should be added for indexer to resolve from source file locations
|
// The relative entry below also should be added for indexer to resolve from source file locations
|
||||||
IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager();
|
|
||||||
String projectRootedPath = mngr.generateVariableExpression("workspace_loc", rc.getProject().getName()) + Path.SEPARATOR + pathStr; //$NON-NLS-1$
|
ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager();
|
||||||
ICLanguageSettingEntry projectRootedEntry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, projectRootedPath, projectRootedPath, null, entry.getFlags());
|
try {
|
||||||
if (! list.contains(projectRootedEntry)) {
|
// Substitute build/environment variables
|
||||||
list.add(projectRootedEntry);
|
String location = varManager.resolveValue(pathStr, "", null, cfgDescription); //$NON-NLS-1$
|
||||||
|
if (!new Path(location).isAbsolute()) {
|
||||||
|
IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager();
|
||||||
|
String projectRootedPath = mngr.generateVariableExpression("workspace_loc", rc.getProject().getName()) + Path.SEPARATOR + pathStr; //$NON-NLS-1$
|
||||||
|
ICLanguageSettingEntry projectRootedEntry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, projectRootedPath, projectRootedPath, null, entry.getFlags());
|
||||||
|
if (! list.contains(projectRootedEntry)) {
|
||||||
|
list.add(projectRootedEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CdtVariableException e) {
|
||||||
|
// Swallow exceptions but also log them
|
||||||
|
ManagedBuilderCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! list.contains(entry)) {
|
if (! list.contains(entry)) {
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* 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()))
|
if (str.toLowerCase().contains(fNoBreakComment.toLowerCase()))
|
||||||
continue;
|
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));
|
reportProblem(ER_ID, getProblemLocationAtEndOfNode(curr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
|
||||||
super.initPreferences(problem);
|
super.initPreferences(problem);
|
||||||
addPreference(problem, PARAM_NO_BREAK_COMMENT, CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
|
addPreference(problem, PARAM_NO_BREAK_COMMENT, CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
|
||||||
DEFAULT_NO_BREAK_COMMENT);
|
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);
|
addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, Boolean.FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,34 +29,22 @@ public class CaseBreakQuickFixTest extends QuickFixTestCase {
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
public void testMiddleCase() throws Exception {
|
public void testSimpleCase() throws Exception {
|
||||||
loadcode(getAboveComment());
|
loadcode(getAboveComment());
|
||||||
String result = runQuickFixOneFile();
|
String result = runQuickFixOneFile();
|
||||||
assertContainedIn("break;\tcase 2:", result);
|
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() {
|
//void func() {
|
||||||
// int a;
|
// int a;
|
||||||
// switch(a) {
|
// switch(a) {
|
||||||
// case 1: {
|
// case 1: {
|
||||||
// hello();
|
// hello();
|
||||||
// }
|
// }
|
||||||
|
// default:
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
public void testLastCaseComp() throws Exception {
|
public void testCompositeStatementCase() throws Exception {
|
||||||
loadcode(getAboveComment());
|
loadcode(getAboveComment());
|
||||||
String result = runQuickFixOneFile();
|
String result = runQuickFixOneFile();
|
||||||
assertContainedIn("hello();\t\tbreak;", result);
|
assertContainedIn("hello();\t\tbreak;", result);
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* 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());
|
IProblem problem = resourceProfile.findProblem(p.getId());
|
||||||
if (problem == null)
|
if (problem == null)
|
||||||
throw new IllegalArgumentException(p.getId() + " is not registered"); //$NON-NLS-1$
|
throw new IllegalArgumentException(p.getId() + " is not registered"); //$NON-NLS-1$
|
||||||
if (!problem.isEnabled())
|
if (problem.isEnabled() && checker instanceof AbstractCheckerWithProblemPreferences) {
|
||||||
return false;
|
|
||||||
if (checker instanceof AbstractCheckerWithProblemPreferences) {
|
|
||||||
LaunchModeProblemPreference pref =
|
LaunchModeProblemPreference pref =
|
||||||
((AbstractCheckerWithProblemPreferences) checker).getLaunchModePreference(problem);
|
((AbstractCheckerWithProblemPreferences) checker).getLaunchModePreference(problem);
|
||||||
if (pref.isRunningInMode(mode)) {
|
if (pref.isRunningInMode(mode)) {
|
||||||
|
|
|
@ -6938,7 +6938,70 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
// static const int value = sizeof(waldo(f));
|
// static const int value = sizeof(waldo(f));
|
||||||
// };
|
// };
|
||||||
// typedef identity<Int<S<>::value>>::type reference;
|
// typedef identity<Int<S<>::value>>::type reference;
|
||||||
public void _testDependentExpressions_395243() throws Exception {
|
public void testDependentExpressions_395243a() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
// typedef char one;
|
||||||
|
// typedef struct {
|
||||||
|
// char arr[2];
|
||||||
|
// } two;
|
||||||
|
// template <typename T>
|
||||||
|
// struct has_foo_type {
|
||||||
|
// template <typename _Up>
|
||||||
|
// struct wrap_type { };
|
||||||
|
// template <typename U>
|
||||||
|
// static one test(wrap_type<typename U::foo_type>*);
|
||||||
|
// template <typename U>
|
||||||
|
// static two test(...);
|
||||||
|
// static const bool value = sizeof(test<T>(0)) == 1;
|
||||||
|
// };
|
||||||
|
// template <bool>
|
||||||
|
// struct traits;
|
||||||
|
// template <>
|
||||||
|
// struct traits<true> {
|
||||||
|
// typedef int bar_type;
|
||||||
|
// };
|
||||||
|
// struct S {
|
||||||
|
// typedef int foo_type;
|
||||||
|
// };
|
||||||
|
// traits<has_foo_type<S>::value>::bar_type a;
|
||||||
|
public void testDependentExpressions_395243b() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
// template <typename U> U bar(U);
|
||||||
|
// template <typename T> auto waldo(T t) -> decltype(bar(t));
|
||||||
|
// struct S {
|
||||||
|
// void foo() const;
|
||||||
|
// };
|
||||||
|
// struct V {
|
||||||
|
// S arr[5];
|
||||||
|
// };
|
||||||
|
// int main() {
|
||||||
|
// V e;
|
||||||
|
// auto v = waldo(e);
|
||||||
|
// for (auto s : v.arr)
|
||||||
|
// s.foo();
|
||||||
|
// }
|
||||||
|
public void testDependentExpressions_395243c() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
// template <typename> class C {};
|
||||||
|
// template <typename T> int begin(C<T>);
|
||||||
|
// template <typename>
|
||||||
|
// struct A {
|
||||||
|
// class B {
|
||||||
|
// void m();
|
||||||
|
// };
|
||||||
|
// void test() {
|
||||||
|
// B* v[5];
|
||||||
|
// for (auto x : v)
|
||||||
|
// x->m();
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
public void testDependentExpressions_395243d() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7420,4 +7420,9 @@ public class AST2Tests extends AST2BaseTest {
|
||||||
public void testGCCDecltype_397227() throws Exception {
|
public void testGCCDecltype_397227() throws Exception {
|
||||||
parseAndCheckBindings(getAboveComment(), CPP, true);
|
parseAndCheckBindings(getAboveComment(), CPP, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #define macro(R) #R""
|
||||||
|
public void testNoRawStringInPlainC_397127() throws Exception {
|
||||||
|
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,12 @@ public class LexerTests extends BaseTestCase {
|
||||||
private static final LexerOptions NO_DOLLAR = new LexerOptions();
|
private static final LexerOptions NO_DOLLAR = new LexerOptions();
|
||||||
private static final LexerOptions NO_MINMAX = new LexerOptions();
|
private static final LexerOptions NO_MINMAX = new LexerOptions();
|
||||||
private static final LexerOptions SLASH_PERCENT = new LexerOptions();
|
private static final LexerOptions SLASH_PERCENT = new LexerOptions();
|
||||||
|
private static final LexerOptions CPP_OPTIONS = new LexerOptions();
|
||||||
static {
|
static {
|
||||||
NO_DOLLAR.fSupportDollarInIdentifiers= false;
|
NO_DOLLAR.fSupportDollarInIdentifiers= false;
|
||||||
NO_MINMAX.fSupportMinAndMax= false;
|
NO_MINMAX.fSupportMinAndMax= false;
|
||||||
SLASH_PERCENT.fSupportSlashPercentComments= true;
|
SLASH_PERCENT.fSupportSlashPercentComments= true;
|
||||||
|
CPP_OPTIONS.fSupportRawStringLiterals= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String TRIGRAPH_REPLACES_CHARS= "#^[]|{}~\\";
|
static String TRIGRAPH_REPLACES_CHARS= "#^[]|{}~\\";
|
||||||
|
@ -41,7 +43,7 @@ public class LexerTests extends BaseTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Lexer fLexer;
|
private Lexer fLexer;
|
||||||
private TestLexerLog fLog= new TestLexerLog();
|
private final TestLexerLog fLog= new TestLexerLog();
|
||||||
private int fLastEndOffset;
|
private int fLastEndOffset;
|
||||||
|
|
||||||
public LexerTests() {
|
public LexerTests() {
|
||||||
|
@ -576,51 +578,51 @@ public class LexerTests extends BaseTestCase {
|
||||||
|
|
||||||
public void testRawStringLiteral() throws Exception {
|
public void testRawStringLiteral() throws Exception {
|
||||||
String lit= "abc0123\\\"'.:; \\\\ \n\"(";
|
String lit= "abc0123\\\"'.:; \\\\ \n\"(";
|
||||||
init("R\"(" + lit + ")\"");
|
init("R\"(" + lit + ")\"", CPP_OPTIONS);
|
||||||
rstr("", lit);
|
rstr("", lit);
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("LR\"(" + lit + ")\"");
|
init("LR\"(" + lit + ")\"", CPP_OPTIONS);
|
||||||
wrstr("", lit);
|
wrstr("", lit);
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("u8R\"(" + lit + ")\"");
|
init("u8R\"(" + lit + ")\"", CPP_OPTIONS);
|
||||||
utf8rstr("", lit);
|
utf8rstr("", lit);
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("uR\"(" + lit + ")\"");
|
init("uR\"(" + lit + ")\"", CPP_OPTIONS);
|
||||||
utf16rstr("", lit);
|
utf16rstr("", lit);
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("UR\"(" + lit + ")\"");
|
init("UR\"(" + lit + ")\"", CPP_OPTIONS);
|
||||||
utf32rstr("", lit);
|
utf32rstr("", lit);
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("R\"ut");
|
init("R\"ut", CPP_OPTIONS);
|
||||||
problem(IProblem.SCANNER_UNBOUNDED_STRING, "R\"ut");
|
problem(IProblem.SCANNER_UNBOUNDED_STRING, "R\"ut");
|
||||||
token(IToken.tSTRING, "R\"ut");
|
token(IToken.tSTRING, "R\"ut");
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("LR\"(ut");
|
init("LR\"(ut", CPP_OPTIONS);
|
||||||
problem(IProblem.SCANNER_UNBOUNDED_STRING, "LR\"(ut");
|
problem(IProblem.SCANNER_UNBOUNDED_STRING, "LR\"(ut");
|
||||||
token(IToken.tLSTRING, "LR\"(ut");
|
token(IToken.tLSTRING, "LR\"(ut");
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("uR\"p()");
|
init("uR\"p()", CPP_OPTIONS);
|
||||||
problem(IProblem.SCANNER_UNBOUNDED_STRING, "uR\"p()");
|
problem(IProblem.SCANNER_UNBOUNDED_STRING, "uR\"p()");
|
||||||
token(IToken.tUTF16STRING, "uR\"p()");
|
token(IToken.tUTF16STRING, "uR\"p()");
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("UR\"(ut");
|
init("UR\"(ut", CPP_OPTIONS);
|
||||||
problem(IProblem.SCANNER_UNBOUNDED_STRING, "UR\"(ut");
|
problem(IProblem.SCANNER_UNBOUNDED_STRING, "UR\"(ut");
|
||||||
token(IToken.tUTF32STRING, "UR\"(ut");
|
token(IToken.tUTF32STRING, "UR\"(ut");
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("R\"+=(Text)=+\"Text)+=\"");
|
init("R\"+=(Text)=+\"Text)+=\"", CPP_OPTIONS);
|
||||||
rstr("+=", "Text)=+\"Text");
|
rstr("+=", "Text)=+\"Text");
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
init("UR uR LR u8R U8R\"\"");
|
init("UR uR LR u8R U8R\"\"", CPP_OPTIONS);
|
||||||
id("UR"); ws();
|
id("UR"); ws();
|
||||||
id("uR"); ws();
|
id("uR"); ws();
|
||||||
id("LR"); ws();
|
id("LR"); ws();
|
||||||
|
@ -630,7 +632,7 @@ public class LexerTests extends BaseTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRawStringLiteralInInactiveCode() throws Exception {
|
public void testRawStringLiteralInInactiveCode() throws Exception {
|
||||||
init("start\n" + "inactive: Rbla\n" + "#end");
|
init("start\n" + "inactive: Rbla\n" + "#end", CPP_OPTIONS);
|
||||||
id("start");
|
id("start");
|
||||||
nextDirective();
|
nextDirective();
|
||||||
token(IToken.tPOUND);
|
token(IToken.tPOUND);
|
||||||
|
@ -638,7 +640,7 @@ public class LexerTests extends BaseTestCase {
|
||||||
eof();
|
eof();
|
||||||
|
|
||||||
// raw string containing a directive
|
// raw string containing a directive
|
||||||
init("start\n" + "inactive: uR\"(\n#endif\n)\"\n" + "#end");
|
init("start\n" + "inactive: uR\"(\n#endif\n)\"\n" + "#end", CPP_OPTIONS);
|
||||||
id("start");
|
id("start");
|
||||||
nextDirective();
|
nextDirective();
|
||||||
token(IToken.tPOUND);
|
token(IToken.tPOUND);
|
||||||
|
|
|
@ -29,8 +29,8 @@ public abstract class AbstractScannerExtensionConfiguration implements IScannerE
|
||||||
private CharArrayIntMap fAddPreprocessorKeywords;
|
private CharArrayIntMap fAddPreprocessorKeywords;
|
||||||
|
|
||||||
protected static class MacroDefinition implements IMacro {
|
protected static class MacroDefinition implements IMacro {
|
||||||
private char[] fSignature;
|
private final char[] fSignature;
|
||||||
private char[] fExpansion;
|
private final char[] fExpansion;
|
||||||
|
|
||||||
MacroDefinition(char[] signature, char[] expansion) {
|
MacroDefinition(char[] signature, char[] expansion) {
|
||||||
fSignature= signature;
|
fSignature= signature;
|
||||||
|
@ -103,6 +103,14 @@ public abstract class AbstractScannerExtensionConfiguration implements IScannerE
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.5
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportRawStringLiterals() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharArrayIntMap getAdditionalPreprocessorKeywords() {
|
public CharArrayIntMap getAdditionalPreprocessorKeywords() {
|
||||||
return fAddPreprocessorKeywords;
|
return fAddPreprocessorKeywords;
|
||||||
|
|
|
@ -109,4 +109,10 @@ public interface IScannerExtensionConfiguration {
|
||||||
* @see "http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.aix.doc/language_ref/unicode_standard.html"
|
* @see "http://publib.boulder.ibm.com/infocenter/comphelp/v101v121/index.jsp?topic=/com.ibm.xlcpp101.aix.doc/language_ref/unicode_standard.html"
|
||||||
*/
|
*/
|
||||||
public boolean supportUTFLiterals();
|
public boolean supportUTFLiterals();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for C++ raw string literals.
|
||||||
|
* @since 5.5
|
||||||
|
*/
|
||||||
|
public boolean supportRawStringLiterals();
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,4 +113,12 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
|
||||||
public boolean supportMinAndMaxOperators() {
|
public boolean supportMinAndMaxOperators() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.5
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supportRawStringLiterals() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
|
@ -30,19 +29,32 @@ public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFuncti
|
||||||
private static final ICPPFunctionType FUNCTION_TYPE=
|
private static final ICPPFunctionType FUNCTION_TYPE=
|
||||||
new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY);
|
new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY);
|
||||||
|
|
||||||
public static ICPPFunction createForSample(IFunction sample) throws DOMException {
|
/**
|
||||||
if (sample instanceof ICPPConstructor)
|
* Creates a CPPDeferredFunction given a set of overloaded functions
|
||||||
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
|
* (some of which may be templates) that the function might resolve to.
|
||||||
|
* At least one candidate must be provided.
|
||||||
|
* @param candidates a set of overloaded functions, some of which may be templates
|
||||||
|
* @return the constructed CPPDeferredFunction
|
||||||
|
*/
|
||||||
|
public static ICPPFunction createForCandidates(ICPPFunction... candidates) {
|
||||||
|
if (candidates[0] instanceof ICPPConstructor)
|
||||||
|
return new CPPUnknownConstructor(((ICPPConstructor) candidates[0]).getClassOwner(), candidates);
|
||||||
|
|
||||||
final IBinding owner = sample.getOwner();
|
final IBinding owner = candidates[0].getOwner();
|
||||||
return new CPPDeferredFunction(owner, sample.getNameCharArray());
|
return new CPPDeferredFunction(owner, candidates[0].getNameCharArray(), candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final IBinding fOwner;
|
private final IBinding fOwner;
|
||||||
|
private final ICPPFunction[] fCandidates;
|
||||||
|
|
||||||
public CPPDeferredFunction(IBinding owner, char[] name) {
|
public CPPDeferredFunction(IBinding owner, char[] name, ICPPFunction[] candidates) {
|
||||||
super(name);
|
super(name);
|
||||||
fOwner= owner;
|
fOwner= owner;
|
||||||
|
fCandidates = candidates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPFunction[] getCandidates() {
|
||||||
|
return fCandidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,11 +8,13 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Thomas Corbat (IFS)
|
* Thomas Corbat (IFS)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a reference to a constructor (instance), which cannot be resolved because
|
* Represents a reference to a constructor (instance), which cannot be resolved because
|
||||||
|
@ -21,7 +23,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
public class CPPUnknownConstructor extends CPPDeferredFunction implements ICPPConstructor {
|
public class CPPUnknownConstructor extends CPPDeferredFunction implements ICPPConstructor {
|
||||||
|
|
||||||
public CPPUnknownConstructor(ICPPClassType owner) {
|
public CPPUnknownConstructor(ICPPClassType owner) {
|
||||||
super(owner, owner.getNameCharArray());
|
super(owner, owner.getNameCharArray(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CPPUnknownConstructor(ICPPClassType owner, ICPPFunction[] candidates) {
|
||||||
|
super(owner, owner.getNameCharArray(), candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -2057,7 +2057,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ICPPASTTemplateParameter> parms= outerTemplateParameterList();
|
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);
|
IASTDeclaration d = declaration(option);
|
||||||
ICPPASTTemplateDeclaration templateDecl = nodeFactory.newTemplateDeclaration(d);
|
ICPPASTTemplateDeclaration templateDecl = nodeFactory.newTemplateDeclaration(d);
|
||||||
setRange(templateDecl, offset, calculateEndOffset(d));
|
setRange(templateDecl, offset, calculateEndOffset(d));
|
||||||
|
|
|
@ -240,7 +240,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
|
||||||
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
|
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
|
||||||
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
|
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
|
||||||
try {
|
try {
|
||||||
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point);
|
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point, false);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding {
|
||||||
|
|
||||||
public void setToUnknown() {
|
public void setToUnknown() {
|
||||||
if (fName != null) {
|
if (fName != null) {
|
||||||
fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray()));
|
fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray(), fBindings));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Mike Kucera (IBM)
|
* Mike Kucera (IBM)
|
||||||
* Thomas Corbat (IFS)
|
* Thomas Corbat (IFS)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
@ -451,7 +452,7 @@ public class CPPSemantics {
|
||||||
final ASTNodeProperty namePropertyInParent = name.getPropertyInParent();
|
final ASTNodeProperty namePropertyInParent = name.getPropertyInParent();
|
||||||
if (binding == null && data.skippedScope != null) {
|
if (binding == null && data.skippedScope != null) {
|
||||||
if (data.hasFunctionArguments()) {
|
if (data.hasFunctionArguments()) {
|
||||||
binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID());
|
binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID(), null);
|
||||||
} else {
|
} else {
|
||||||
if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) {
|
if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) {
|
||||||
binding= new CPPUnknownMemberClass(data.skippedScope, name.getSimpleID());
|
binding= new CPPUnknownMemberClass(data.skippedScope, name.getSimpleID());
|
||||||
|
@ -2395,7 +2396,7 @@ public class CPPSemantics {
|
||||||
if (viableCount == 1)
|
if (viableCount == 1)
|
||||||
return fns[0];
|
return fns[0];
|
||||||
setTargetedFunctionsToUnknown(argTypes);
|
setTargetedFunctionsToUnknown(argTypes);
|
||||||
return CPPDeferredFunction.createForSample(fns[0]);
|
return CPPDeferredFunction.createForCandidates(fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good
|
IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good
|
||||||
|
@ -2403,7 +2404,7 @@ public class CPPSemantics {
|
||||||
|
|
||||||
// Loop over all functions
|
// Loop over all functions
|
||||||
List<FunctionCost> potentialCosts= null;
|
List<FunctionCost> potentialCosts= null;
|
||||||
IFunction unknownFunction= null;
|
ICPPFunction unknownFunction= null;
|
||||||
final CPPASTTranslationUnit tu = data.getTranslationUnit();
|
final CPPASTTranslationUnit tu = data.getTranslationUnit();
|
||||||
for (ICPPFunction fn : fns) {
|
for (ICPPFunction fn : fns) {
|
||||||
if (fn == null)
|
if (fn == null)
|
||||||
|
@ -2455,7 +2456,7 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
setTargetedFunctionsToUnknown(argTypes);
|
setTargetedFunctionsToUnknown(argTypes);
|
||||||
return CPPDeferredFunction.createForSample(unknownFunction);
|
return CPPDeferredFunction.createForCandidates(fns);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ambiguousFunctions != null) {
|
if (ambiguousFunctions != null) {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Thomas Corbat (IFS)
|
* Thomas Corbat (IFS)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
@ -163,7 +164,6 @@ public class CPPTemplates {
|
||||||
static final int PACK_SIZE_DEFER = -1;
|
static final int PACK_SIZE_DEFER = -1;
|
||||||
static final int PACK_SIZE_FAIL = -2;
|
static final int PACK_SIZE_FAIL = -2;
|
||||||
static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
|
static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
|
||||||
private static final ICPPFunction[] NO_FUNCTIONS = {};
|
|
||||||
static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE }
|
static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -789,7 +789,7 @@ public class CPPTemplates {
|
||||||
ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
|
ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
|
||||||
ICPPTemplateArgument[] args = pspec.getTemplateArguments();
|
ICPPTemplateArgument[] args = pspec.getTemplateArguments();
|
||||||
template= (ICPPClassTemplate) owner.specializeMember(template, point);
|
template= (ICPPClassTemplate) owner.specializeMember(template, point);
|
||||||
args= instantiateArguments(args, tpMap, -1, within, point);
|
args= instantiateArguments(args, tpMap, -1, within, point, false);
|
||||||
spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args);
|
spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
|
@ -1047,10 +1047,15 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates arguments contained in an array.
|
* Instantiates arguments contained in an array. Instantiated arguments are checked for
|
||||||
|
* validity. If the {@code strict} parameter is {@code true}, the method returns {@code null} if
|
||||||
|
* any of the instantiated arguments are invalid. If the {@code strict} parameter is
|
||||||
|
* {@code false}, any invalid instantiated arguments are replaced by the corresponding original
|
||||||
|
* arguments.
|
||||||
*/
|
*/
|
||||||
public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
|
public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
|
||||||
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point)
|
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within,
|
||||||
|
IASTNode point, boolean strict)
|
||||||
throws DOMException {
|
throws DOMException {
|
||||||
// Don't create a new array until it's really needed.
|
// Don't create a new array until it's really needed.
|
||||||
ICPPTemplateArgument[] result = args;
|
ICPPTemplateArgument[] result = args;
|
||||||
|
@ -1066,11 +1071,19 @@ public class CPPTemplates {
|
||||||
} else if (packSize == PACK_SIZE_DEFER) {
|
} else if (packSize == PACK_SIZE_DEFER) {
|
||||||
newArg= origArg;
|
newArg= origArg;
|
||||||
} else {
|
} else {
|
||||||
final int shift = packSize - 1;
|
int shift = packSize - 1;
|
||||||
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
|
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
|
||||||
System.arraycopy(result, 0, newResult, 0, i + resultShift);
|
System.arraycopy(result, 0, newResult, 0, i + resultShift);
|
||||||
for (int j= 0; j < packSize; j++) {
|
for (int j= 0; j < packSize; j++) {
|
||||||
newResult[i + resultShift + j]= instantiateArgument(origArg, tpMap, j, within, point);
|
newArg = instantiateArgument(origArg, tpMap, j, within, point);
|
||||||
|
if (!isValidArgument(newArg)) {
|
||||||
|
if (strict)
|
||||||
|
return null;
|
||||||
|
newResult = result;
|
||||||
|
shift = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
newResult[i + resultShift + j]= newArg;
|
||||||
}
|
}
|
||||||
result= newResult;
|
result= newResult;
|
||||||
resultShift += shift;
|
resultShift += shift;
|
||||||
|
@ -1078,7 +1091,13 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newArg = instantiateArgument(origArg, tpMap, packOffset, within, point);
|
newArg = instantiateArgument(origArg, tpMap, packOffset, within, point);
|
||||||
|
if (!isValidArgument(newArg)) {
|
||||||
|
if (strict)
|
||||||
|
return null;
|
||||||
|
newArg = origArg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != args) {
|
if (result != args) {
|
||||||
result[i + resultShift]= newArg;
|
result[i + resultShift]= newArg;
|
||||||
} else if (newArg != origArg) {
|
} else if (newArg != origArg) {
|
||||||
|
@ -1122,12 +1141,15 @@ public class CPPTemplates {
|
||||||
for (Integer key : positions) {
|
for (Integer key : positions) {
|
||||||
ICPPTemplateArgument arg = orig.getArgument(key);
|
ICPPTemplateArgument arg = orig.getArgument(key);
|
||||||
if (arg != null) {
|
if (arg != null) {
|
||||||
newMap.put(key, instantiateArgument(arg, tpMap, packOffset, within, point));
|
ICPPTemplateArgument newArg = instantiateArgument(arg, tpMap, packOffset, within, point);
|
||||||
|
if (!isValidArgument(newArg))
|
||||||
|
newArg = arg;
|
||||||
|
newMap.put(key, newArg);
|
||||||
} else {
|
} else {
|
||||||
ICPPTemplateArgument[] args = orig.getPackExpansion(key);
|
ICPPTemplateArgument[] args = orig.getPackExpansion(key);
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
try {
|
try {
|
||||||
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point));
|
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point, false));
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
newMap.put(key, args);
|
newMap.put(key, args);
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1233,7 @@ public class CPPTemplates {
|
||||||
final IBinding origClass = classInstance.getSpecializedBinding();
|
final IBinding origClass = classInstance.getSpecializedBinding();
|
||||||
if (origClass instanceof ICPPClassType) {
|
if (origClass instanceof ICPPClassType) {
|
||||||
ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
|
ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
|
||||||
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point);
|
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point, false);
|
||||||
if (newArgs != args) {
|
if (newArgs != args) {
|
||||||
CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within, point);
|
CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within, point);
|
||||||
return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args);
|
return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args);
|
||||||
|
@ -1728,18 +1750,12 @@ public class CPPTemplates {
|
||||||
requireTemplate= false;
|
requireTemplate= false;
|
||||||
|
|
||||||
if (func instanceof ICPPFunctionTemplate) {
|
if (func instanceof ICPPFunctionTemplate) {
|
||||||
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
|
if (containsDependentType(fnArgs))
|
||||||
try {
|
return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)};
|
||||||
if (containsDependentType(fnArgs))
|
|
||||||
return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)};
|
if (requireTemplate && hasDependentArgument(tmplArgs))
|
||||||
|
return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)};
|
||||||
|
|
||||||
if (requireTemplate) {
|
|
||||||
if (hasDependentArgument(tmplArgs))
|
|
||||||
return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)};
|
|
||||||
}
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return NO_FUNCTIONS;
|
|
||||||
}
|
|
||||||
haveTemplate= true;
|
haveTemplate= true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1805,15 +1821,11 @@ public class CPPTemplates {
|
||||||
|
|
||||||
// Extract template arguments and parameter types.
|
// Extract template arguments and parameter types.
|
||||||
if (!checkedForDependentType) {
|
if (!checkedForDependentType) {
|
||||||
try {
|
if (isDependentType(conversionType)) {
|
||||||
if (isDependentType(conversionType)) {
|
inst= CPPDeferredFunction.createForCandidates(functions);
|
||||||
inst= CPPDeferredFunction.createForSample(template);
|
done= true;
|
||||||
done= true;
|
|
||||||
}
|
|
||||||
checkedForDependentType= true;
|
|
||||||
} catch (DOMException e) {
|
|
||||||
return functions;
|
|
||||||
}
|
}
|
||||||
|
checkedForDependentType= true;
|
||||||
}
|
}
|
||||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
|
||||||
try {
|
try {
|
||||||
|
@ -1871,7 +1883,7 @@ public class CPPTemplates {
|
||||||
ICPPTemplateArgument[] args, IASTNode point) {
|
ICPPTemplateArgument[] args, IASTNode point) {
|
||||||
try {
|
try {
|
||||||
if (target != null && isDependentType(target)) {
|
if (target != null && isDependentType(target)) {
|
||||||
return CPPDeferredFunction.createForSample(template);
|
return CPPDeferredFunction.createForCandidates(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template instanceof ICPPConstructor || args == null)
|
if (template instanceof ICPPConstructor || args == null)
|
||||||
|
@ -2061,12 +2073,7 @@ public class CPPTemplates {
|
||||||
|
|
||||||
private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args,
|
private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args,
|
||||||
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
|
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
|
||||||
args = instantiateArguments(args, tpMap, -1, null, point);
|
return instantiateArguments(args, tpMap, -1, null, point, true) != null;
|
||||||
for (ICPPTemplateArgument arg : args) {
|
|
||||||
if (!isValidArgument(arg))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2124,7 +2131,7 @@ public class CPPTemplates {
|
||||||
args[i]= arg;
|
args[i]= arg;
|
||||||
transferMap.put(param, arg);
|
transferMap.put(param, arg);
|
||||||
}
|
}
|
||||||
final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point);
|
final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point, false);
|
||||||
|
|
||||||
// Deduce arguments for specialization 2
|
// Deduce arguments for specialization 2
|
||||||
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
|
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
|
||||||
|
@ -2468,7 +2475,7 @@ public class CPPTemplates {
|
||||||
if (unknown instanceof ICPPUnknownMemberClassInstance) {
|
if (unknown instanceof ICPPUnknownMemberClassInstance) {
|
||||||
ICPPUnknownMemberClassInstance ucli= (ICPPUnknownMemberClassInstance) unknown;
|
ICPPUnknownMemberClassInstance ucli= (ICPPUnknownMemberClassInstance) unknown;
|
||||||
ICPPTemplateArgument[] args0 = ucli.getArguments();
|
ICPPTemplateArgument[] args0 = ucli.getArguments();
|
||||||
ICPPTemplateArgument[] args1 = instantiateArguments(args0, tpMap, packOffset, within, point);
|
ICPPTemplateArgument[] args1 = instantiateArguments(args0, tpMap, packOffset, within, point, false);
|
||||||
if (args0 != args1 || !ot1.isSameType(ot0)) {
|
if (args0 != args1 || !ot1.isSameType(ot0)) {
|
||||||
args1= SemanticUtil.getSimplifiedArguments(args1);
|
args1= SemanticUtil.getSimplifiedArguments(args1);
|
||||||
result= new CPPUnknownClassInstance(ot1, ucli.getNameCharArray(), args1);
|
result= new CPPUnknownClassInstance(ot1, ucli.getNameCharArray(), args1);
|
||||||
|
@ -2486,7 +2493,7 @@ public class CPPTemplates {
|
||||||
result= CPPSemantics.resolveUnknownName(s, unknown, point);
|
result= CPPSemantics.resolveUnknownName(s, unknown, point);
|
||||||
if (unknown instanceof ICPPUnknownMemberClassInstance && result instanceof ICPPTemplateDefinition) {
|
if (unknown instanceof ICPPUnknownMemberClassInstance && result instanceof ICPPTemplateDefinition) {
|
||||||
ICPPTemplateArgument[] args1 = instantiateArguments(
|
ICPPTemplateArgument[] args1 = instantiateArguments(
|
||||||
((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point);
|
((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point, false);
|
||||||
if (result instanceof ICPPClassTemplate) {
|
if (result instanceof ICPPClassTemplate) {
|
||||||
result = instantiate((ICPPClassTemplate) result, args1, point);
|
result = instantiate((ICPPClassTemplate) result, args1, point);
|
||||||
}
|
}
|
||||||
|
@ -2505,7 +2512,7 @@ public class CPPTemplates {
|
||||||
ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
|
ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
|
||||||
ICPPTemplateArgument[] newArgs;
|
ICPPTemplateArgument[] newArgs;
|
||||||
try {
|
try {
|
||||||
newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point);
|
newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point, false);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return e.getProblem();
|
return e.getProblem();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Thomas Corbat (IFS)
|
* Thomas Corbat (IFS)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
@ -2017,11 +2018,13 @@ public class CPPVisitor extends ASTQueries {
|
||||||
IBinding b= implicits[0].getBinding();
|
IBinding b= implicits[0].getBinding();
|
||||||
CPPASTName name= new CPPASTName();
|
CPPASTName name= new CPPASTName();
|
||||||
name.setBinding(b);
|
name.setBinding(b);
|
||||||
|
IASTInitializerClause[] beginCallArguments = new IASTInitializerClause[] { forInit.copy() };
|
||||||
if (b instanceof ICPPMethod && forInit instanceof IASTExpression) {
|
if (b instanceof ICPPMethod && forInit instanceof IASTExpression) {
|
||||||
beginExpr= new CPPASTFunctionCallExpression(
|
beginExpr= new CPPASTFunctionCallExpression(
|
||||||
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS);
|
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()),
|
||||||
|
beginCallArguments);
|
||||||
} else {
|
} else {
|
||||||
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
|
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), beginCallArguments);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
|
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
@ -362,6 +363,13 @@ public class EvalBinding extends CPPEvaluation {
|
||||||
binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
|
binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
|
||||||
binding, point);
|
binding, point);
|
||||||
}
|
}
|
||||||
|
} else if (binding instanceof ICPPParameter) {
|
||||||
|
ICPPParameter parameter = (ICPPParameter) binding;
|
||||||
|
IType originalType = parameter.getType();
|
||||||
|
IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point);
|
||||||
|
if (originalType != type) {
|
||||||
|
return new EvalFixed(type, ValueCategory.LVALUE, Value.create(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (binding == fBinding)
|
if (binding == fBinding)
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
|
@ -145,12 +147,16 @@ public class EvalFunctionSet extends CPPEvaluation {
|
||||||
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
|
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
|
||||||
ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments();
|
ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments();
|
||||||
ICPPTemplateArgument[] arguments = originalArguments;
|
ICPPTemplateArgument[] arguments = originalArguments;
|
||||||
arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point);
|
if (originalArguments != null)
|
||||||
|
arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point);
|
||||||
|
|
||||||
IBinding originalOwner = fFunctionSet.getOwner();
|
IBinding originalOwner = fFunctionSet.getOwner();
|
||||||
IBinding owner = originalOwner;
|
IBinding owner = originalOwner;
|
||||||
if (originalOwner instanceof ICPPUnknownBinding) {
|
if (owner instanceof ICPPUnknownBinding) {
|
||||||
owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point);
|
owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point);
|
||||||
|
} else if (owner instanceof ICPPClassTemplate) {
|
||||||
|
owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner),
|
||||||
|
tpMap, packOffset, within, point);
|
||||||
} else if (owner instanceof IType) {
|
} else if (owner instanceof IType) {
|
||||||
IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
|
IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
|
||||||
if (type instanceof IBinding)
|
if (type instanceof IBinding)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
|
* Nathan Ridge
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
@ -48,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
@ -184,15 +186,6 @@ public class EvalID extends CPPEvaluation {
|
||||||
return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr));
|
return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr));
|
||||||
}
|
}
|
||||||
if (binding instanceof ICPPUnknownBinding) {
|
if (binding instanceof ICPPUnknownBinding) {
|
||||||
IBinding owner = binding.getOwner();
|
|
||||||
if (owner instanceof IProblemBinding)
|
|
||||||
return EvalFixed.INCOMPLETE;
|
|
||||||
|
|
||||||
ICPPEvaluation fieldOwner= null;
|
|
||||||
IType fieldOwnerType= withinNonStaticMethod(expr);
|
|
||||||
if (fieldOwnerType != null) {
|
|
||||||
fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN);
|
|
||||||
}
|
|
||||||
ICPPTemplateArgument[] templateArgs = null;
|
ICPPTemplateArgument[] templateArgs = null;
|
||||||
final IASTName lastName = name.getLastName();
|
final IASTName lastName = name.getLastName();
|
||||||
if (lastName instanceof ICPPASTTemplateId) {
|
if (lastName instanceof ICPPASTTemplateId) {
|
||||||
|
@ -202,6 +195,25 @@ public class EvalID extends CPPEvaluation {
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (binding instanceof CPPDeferredFunction) {
|
||||||
|
CPPDeferredFunction deferredFunction = (CPPDeferredFunction) binding;
|
||||||
|
if (deferredFunction.getCandidates() != null) {
|
||||||
|
CPPFunctionSet functionSet = new CPPFunctionSet(deferredFunction.getCandidates(), templateArgs, null);
|
||||||
|
return new EvalFunctionSet(functionSet, isAddressOf(expr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IBinding owner = binding.getOwner();
|
||||||
|
if (owner instanceof IProblemBinding)
|
||||||
|
return EvalFixed.INCOMPLETE;
|
||||||
|
|
||||||
|
ICPPEvaluation fieldOwner= null;
|
||||||
|
IType fieldOwnerType= withinNonStaticMethod(expr);
|
||||||
|
if (fieldOwnerType != null) {
|
||||||
|
fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr),
|
return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr),
|
||||||
name instanceof ICPPASTQualifiedName, templateArgs);
|
name instanceof ICPPASTQualifiedName, templateArgs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,6 +290,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fLexOptions.fSupportMinAndMax = configuration.supportMinAndMaxOperators();
|
fLexOptions.fSupportMinAndMax = configuration.supportMinAndMaxOperators();
|
||||||
fLexOptions.fSupportSlashPercentComments= configuration.supportSlashPercentComments();
|
fLexOptions.fSupportSlashPercentComments= configuration.supportSlashPercentComments();
|
||||||
fLexOptions.fSupportUTFLiterals = configuration.supportUTFLiterals();
|
fLexOptions.fSupportUTFLiterals = configuration.supportUTFLiterals();
|
||||||
|
fLexOptions.fSupportRawStringLiterals = configuration.supportRawStringLiterals();
|
||||||
fLocationMap= new LocationMap(fLexOptions);
|
fLocationMap= new LocationMap(fLexOptions);
|
||||||
fKeywords= new CharArrayIntMap(40, -1);
|
fKeywords= new CharArrayIntMap(40, -1);
|
||||||
fPPKeywords= new CharArrayIntMap(40, -1);
|
fPPKeywords= new CharArrayIntMap(40, -1);
|
||||||
|
|
|
@ -54,6 +54,7 @@ final public class Lexer implements ITokenSequence {
|
||||||
public boolean fCreateImageLocations= true;
|
public boolean fCreateImageLocations= true;
|
||||||
public boolean fSupportSlashPercentComments= false;
|
public boolean fSupportSlashPercentComments= false;
|
||||||
public boolean fSupportUTFLiterals= true;
|
public boolean fSupportUTFLiterals= true;
|
||||||
|
public boolean fSupportRawStringLiterals= false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
|
@ -73,7 +74,7 @@ final public class Lexer implements ITokenSequence {
|
||||||
|
|
||||||
// the input to the lexer
|
// the input to the lexer
|
||||||
private final AbstractCharArray fInput;
|
private final AbstractCharArray fInput;
|
||||||
private int fStart;
|
private final int fStart;
|
||||||
private int fLimit;
|
private int fLimit;
|
||||||
|
|
||||||
// after phase 3 (newline, trigraph, line-splice)
|
// after phase 3 (newline, trigraph, line-splice)
|
||||||
|
@ -267,12 +268,14 @@ final public class Lexer implements ITokenSequence {
|
||||||
case 'L':
|
case 'L':
|
||||||
switch(d) {
|
switch(d) {
|
||||||
case 'R':
|
case 'R':
|
||||||
markPhase3();
|
if (fOptions.fSupportRawStringLiterals) {
|
||||||
if (nextCharPhase3() == '"') {
|
markPhase3();
|
||||||
nextCharPhase3();
|
if (nextCharPhase3() == '"') {
|
||||||
return rawStringLiteral(start, 3, IToken.tLSTRING);
|
nextCharPhase3();
|
||||||
|
return rawStringLiteral(start, 3, IToken.tLSTRING);
|
||||||
|
}
|
||||||
|
restorePhase3();
|
||||||
}
|
}
|
||||||
restorePhase3();
|
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
nextCharPhase3();
|
nextCharPhase3();
|
||||||
|
@ -288,12 +291,14 @@ final public class Lexer implements ITokenSequence {
|
||||||
if (fOptions.fSupportUTFLiterals) {
|
if (fOptions.fSupportUTFLiterals) {
|
||||||
switch(d) {
|
switch(d) {
|
||||||
case 'R':
|
case 'R':
|
||||||
markPhase3();
|
if (fOptions.fSupportRawStringLiterals) {
|
||||||
if (nextCharPhase3() == '"') {
|
markPhase3();
|
||||||
nextCharPhase3();
|
if (nextCharPhase3() == '"') {
|
||||||
return rawStringLiteral(start, 3, c == 'u' ? IToken.tUTF16STRING : IToken.tUTF32STRING);
|
nextCharPhase3();
|
||||||
|
return rawStringLiteral(start, 3, c == 'u' ? IToken.tUTF16STRING : IToken.tUTF32STRING);
|
||||||
|
}
|
||||||
|
restorePhase3();
|
||||||
}
|
}
|
||||||
restorePhase3();
|
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
nextCharPhase3();
|
nextCharPhase3();
|
||||||
|
@ -306,7 +311,7 @@ final public class Lexer implements ITokenSequence {
|
||||||
markPhase3();
|
markPhase3();
|
||||||
switch (nextCharPhase3()) {
|
switch (nextCharPhase3()) {
|
||||||
case 'R':
|
case 'R':
|
||||||
if (nextCharPhase3() == '"') {
|
if (fOptions.fSupportRawStringLiterals && nextCharPhase3() == '"') {
|
||||||
nextCharPhase3();
|
nextCharPhase3();
|
||||||
return rawStringLiteral(start, 4, IToken.tSTRING);
|
return rawStringLiteral(start, 4, IToken.tSTRING);
|
||||||
}
|
}
|
||||||
|
@ -323,7 +328,7 @@ final public class Lexer implements ITokenSequence {
|
||||||
return identifier(start, 1);
|
return identifier(start, 1);
|
||||||
|
|
||||||
case 'R':
|
case 'R':
|
||||||
if (d == '"') {
|
if (fOptions.fSupportRawStringLiterals && d == '"') {
|
||||||
nextCharPhase3();
|
nextCharPhase3();
|
||||||
return rawStringLiteral(start, 2, IToken.tSTRING);
|
return rawStringLiteral(start, 2, IToken.tSTRING);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -45,22 +45,22 @@ public class MacroDefinitionParser {
|
||||||
*/
|
*/
|
||||||
static class TokenParameterReference extends TokenWithImage {
|
static class TokenParameterReference extends TokenWithImage {
|
||||||
private final int fIndex;
|
private final int fIndex;
|
||||||
|
|
||||||
public TokenParameterReference(int type, int idx, Object source, int offset, int endOffset, char[] name) {
|
public TokenParameterReference(int type, int idx, Object source, int offset, int endOffset, char[] name) {
|
||||||
super(type, source, offset, endOffset, name);
|
super(type, source, offset, endOffset, name);
|
||||||
fIndex= idx;
|
fIndex= idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndex() {
|
public int getIndex() {
|
||||||
return fIndex;
|
return fIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + fIndex + "]"; //$NON-NLS-1$ //$NON-NLS-2$
|
return "[" + fIndex + "]"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char[] getExpansion(AbstractCharArray expansionImage, int offset, int endOffset) {
|
public static char[] getExpansion(AbstractCharArray expansionImage, int offset, int endOffset) {
|
||||||
TokenList tl= new TokenList();
|
TokenList tl= new TokenList();
|
||||||
Lexer lex= new Lexer(expansionImage, offset, endOffset, new LexerOptions(), ILexerLog.NULL, null);
|
Lexer lex= new Lexer(expansionImage, offset, endOffset, new LexerOptions(), ILexerLog.NULL, null);
|
||||||
|
@ -83,7 +83,7 @@ public class MacroDefinitionParser {
|
||||||
buf.append(t.getCharImage());
|
buf.append(t.getCharImage());
|
||||||
endOffset= t.getEndOffset();
|
endOffset= t.getEndOffset();
|
||||||
}
|
}
|
||||||
final int length= buf.length();
|
final int length= buf.length();
|
||||||
final char[] expansion= new char[length];
|
final char[] expansion= new char[length];
|
||||||
buf.getChars(0, length, expansion, 0);
|
buf.getChars(0, length, expansion, 0);
|
||||||
return expansion;
|
return expansion;
|
||||||
|
@ -93,10 +93,10 @@ public class MacroDefinitionParser {
|
||||||
private int fExpansionOffset;
|
private int fExpansionOffset;
|
||||||
private int fExpansionEndOffset;
|
private int fExpansionEndOffset;
|
||||||
private Token fNameToken;
|
private Token fNameToken;
|
||||||
|
|
||||||
MacroDefinitionParser() {
|
MacroDefinitionParser() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In case the name was successfully parsed, the name token is returned.
|
* In case the name was successfully parsed, the name token is returned.
|
||||||
* Otherwise the return value is undefined.
|
* Otherwise the return value is undefined.
|
||||||
|
@ -105,10 +105,10 @@ public class MacroDefinitionParser {
|
||||||
return fNameToken;
|
return fNameToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an entire macro definition. Name must be the next token of the lexer.
|
* 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 {
|
throws OffsetLimitReachedException, InvalidMacroDefinitionException {
|
||||||
final Token name = parseName(lexer);
|
final Token name = parseName(lexer);
|
||||||
final AbstractCharArray source= lexer.getInput();
|
final AbstractCharArray source= lexer.getInput();
|
||||||
|
@ -122,10 +122,10 @@ public class MacroDefinitionParser {
|
||||||
return new FunctionStyleMacro(nameChars, paramList, fHasVarArgs, fExpansionOffset, fExpansionEndOffset, replacement, source);
|
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.
|
* 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 {
|
throws InvalidMacroDefinitionException, OffsetLimitReachedException {
|
||||||
final Token name = parseName(lexer);
|
final Token name = parseName(lexer);
|
||||||
|
|
||||||
|
@ -135,14 +135,14 @@ public class MacroDefinitionParser {
|
||||||
if (replacementToken.getType() != IToken.tEND_OF_INPUT) {
|
if (replacementToken.getType() != IToken.tEND_OF_INPUT) {
|
||||||
throw new InvalidMacroDefinitionException(nameChars, replacementToken.getOffset(), replacementToken.getEndOffset());
|
throw new InvalidMacroDefinitionException(nameChars, replacementToken.getOffset(), replacementToken.getEndOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paramList == null) {
|
if (paramList == null) {
|
||||||
return new ObjectStyleMacro(nameChars, replacement);
|
return new ObjectStyleMacro(nameChars, replacement);
|
||||||
}
|
}
|
||||||
return new FunctionStyleMacro(nameChars, paramList, fHasVarArgs, replacement);
|
return new FunctionStyleMacro(nameChars, paramList, fHasVarArgs, replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a macro definition basically checking for var-args.
|
* Parses a macro definition basically checking for var-args.
|
||||||
*/
|
*/
|
||||||
public static PreprocessorMacro parseMacroDefinition(final char[] name, char[][] paramList, final char[] replacement) {
|
public static PreprocessorMacro parseMacroDefinition(final char[] name, char[][] paramList, final char[] replacement) {
|
||||||
|
@ -176,8 +176,8 @@ public class MacroDefinitionParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paramList == null) {
|
if (paramList == null) {
|
||||||
return new ObjectStyleMacro(name, replacement);
|
return new ObjectStyleMacro(name, replacement);
|
||||||
}
|
}
|
||||||
return new FunctionStyleMacro(name, paramList, hasVarargs, replacement);
|
return new FunctionStyleMacro(name, paramList, hasVarargs, replacement);
|
||||||
|
@ -195,11 +195,11 @@ public class MacroDefinitionParser {
|
||||||
fNameToken= name;
|
fNameToken= name;
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private char[][] parseParamList(Lexer lex, final Token name) throws OffsetLimitReachedException, InvalidMacroDefinitionException {
|
private char[][] parseParamList(Lexer lex, final Token name) throws OffsetLimitReachedException, InvalidMacroDefinitionException {
|
||||||
final Token lparen= lex.nextToken();
|
final Token lparen= lex.nextToken();
|
||||||
fHasVarArgs= FunctionStyleMacro.NO_VAARGS;
|
fHasVarArgs= FunctionStyleMacro.NO_VAARGS;
|
||||||
if (lparen.getType() != IToken.tLPAREN || name.getEndOffset() != lparen.getOffset()) {
|
if (lparen.getType() != IToken.tLPAREN || name.getEndOffset() != lparen.getOffset()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ArrayList<char[]> paramList= new ArrayList<char[]>();
|
ArrayList<char[]> paramList= new ArrayList<char[]>();
|
||||||
|
@ -224,7 +224,7 @@ public class MacroDefinitionParser {
|
||||||
paramList.add(Keywords.cVA_ARGS);
|
paramList.add(Keywords.cVA_ARGS);
|
||||||
next= lex.nextToken();
|
next= lex.nextToken();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tRPAREN:
|
case IToken.tRPAREN:
|
||||||
if (next == null) {
|
if (next == null) {
|
||||||
next= param;
|
next= param;
|
||||||
|
@ -255,7 +255,7 @@ public class MacroDefinitionParser {
|
||||||
Token needAnotherToken= null;
|
Token needAnotherToken= null;
|
||||||
|
|
||||||
Token candidate= lexer.currentToken();
|
Token candidate= lexer.currentToken();
|
||||||
fExpansionOffset= fExpansionEndOffset= candidate.getOffset();
|
fExpansionOffset= fExpansionEndOffset= candidate.getOffset();
|
||||||
|
|
||||||
loop: while(true) {
|
loop: while(true) {
|
||||||
switch (candidate.getType()) {
|
switch (candidate.getType()) {
|
||||||
|
@ -266,18 +266,16 @@ public class MacroDefinitionParser {
|
||||||
break loop;
|
break loop;
|
||||||
case IToken.tIDENTIFIER:
|
case IToken.tIDENTIFIER:
|
||||||
if (paramList != null) {
|
if (paramList != null) {
|
||||||
// convert the parameters to special tokens
|
// Convert the parameters to special tokens.
|
||||||
final char[] image = candidate.getCharImage();
|
final char[] image = candidate.getCharImage();
|
||||||
int idx= CharArrayUtils.indexOf(image, paramList);
|
int idx= CharArrayUtils.indexOf(image, paramList);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
candidate= new TokenParameterReference(CPreprocessor.tMACRO_PARAMETER, idx, lexer.getSource(), candidate.getOffset(), candidate.getEndOffset(), paramList[idx]);
|
candidate= new TokenParameterReference(CPreprocessor.tMACRO_PARAMETER, idx, lexer.getSource(), candidate.getOffset(), candidate.getEndOffset(), paramList[idx]);
|
||||||
needParam= false;
|
needParam= false;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (needParam) {
|
if (needParam) {
|
||||||
log.handleProblem(IProblem.PREPROCESSOR_MACRO_PASTING_ERROR, name, fExpansionOffset, candidate.getEndOffset());
|
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());
|
log.handleProblem(IProblem.PREPROCESSOR_INVALID_VA_ARGS, null, fExpansionOffset, candidate.getEndOffset());
|
||||||
}
|
}
|
||||||
needParam= false;
|
needParam= false;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -35,9 +35,9 @@ public class MacroExpander {
|
||||||
private static final class AbortMacroExpansionException extends Exception {}
|
private static final class AbortMacroExpansionException extends Exception {}
|
||||||
|
|
||||||
private static final int ORIGIN = OffsetLimitReachedException.ORIGIN_MACRO_EXPANSION;
|
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
|
* 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
|
* handle recursive expansions and to figure out whether spaces are required during a stringify
|
||||||
* operation across such boundaries.
|
* operation across such boundaries.
|
||||||
|
@ -56,7 +56,7 @@ public class MacroExpander {
|
||||||
public char[] getCharImage() {
|
public char[] getCharImage() {
|
||||||
return CharArrayUtils.EMPTY;
|
return CharArrayUtils.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{" + (fIsStart ? '+' : '-') + fMacro.getName() + '}'; //$NON-NLS-1$
|
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.
|
* Combines a list of tokens with the preprocessor to form the input for macro expansion.
|
||||||
*/
|
*/
|
||||||
private class TokenSource extends TokenList {
|
private class TokenSource extends TokenList {
|
||||||
|
@ -112,7 +112,7 @@ public class MacroExpander {
|
||||||
|
|
||||||
if (fLexer != null) {
|
if (fLexer != null) {
|
||||||
t= fLexer.currentToken();
|
t= fLexer.currentToken();
|
||||||
while(t.getType() == Lexer.tNEWLINE) {
|
while (t.getType() == Lexer.tNEWLINE) {
|
||||||
t= fLexer.nextToken();
|
t= fLexer.nextToken();
|
||||||
}
|
}
|
||||||
return t.getType() == IToken.tLPAREN;
|
return t.getType() == IToken.tLPAREN;
|
||||||
|
@ -131,14 +131,14 @@ public class MacroExpander {
|
||||||
private boolean fCompletionMode;
|
private boolean fCompletionMode;
|
||||||
private int fStartOffset;
|
private int fStartOffset;
|
||||||
private int fEndOffset;
|
private int fEndOffset;
|
||||||
|
|
||||||
// for using the expander to track expansions
|
// for using the expander to track expansions
|
||||||
private String fFixedCurrentFilename;
|
private String fFixedCurrentFilename;
|
||||||
private int fFixedLineNumber;
|
private int fFixedLineNumber;
|
||||||
private char[] fFixedInput;
|
private char[] fFixedInput;
|
||||||
private ScannerContext fReportMacros;
|
private ScannerContext fReportMacros;
|
||||||
private boolean fReportUndefined;
|
private boolean fReportUndefined;
|
||||||
|
|
||||||
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary,
|
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary,
|
||||||
LocationMap locationMap, LexerOptions lexOptions) {
|
LocationMap locationMap, LexerOptions lexOptions) {
|
||||||
fDictionary= macroDictionary;
|
fDictionary= macroDictionary;
|
||||||
|
@ -147,10 +147,10 @@ public class MacroExpander {
|
||||||
fLexOptions= lexOptions;
|
fLexOptions= lexOptions;
|
||||||
fLog= log;
|
fLog= log;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expects that the identifier has been consumed, stores the result in the list provided.
|
* 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,
|
public TokenList expand(ITokenSequence lexer, final int ppOptions,
|
||||||
PreprocessorMacro macro, Token identifier, boolean completionMode,
|
PreprocessorMacro macro, Token identifier, boolean completionMode,
|
||||||
|
@ -162,16 +162,16 @@ public class MacroExpander {
|
||||||
} else {
|
} else {
|
||||||
fReportMacros= null;
|
fReportMacros= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fImplicitMacroExpansions.clear();
|
fImplicitMacroExpansions.clear();
|
||||||
fImageLocationInfos.clear();
|
fImageLocationInfos.clear();
|
||||||
|
|
||||||
fStartOffset= identifier.getOffset();
|
fStartOffset= identifier.getOffset();
|
||||||
fEndOffset= identifier.getEndOffset();
|
fEndOffset= identifier.getEndOffset();
|
||||||
fCompletionMode= completionMode;
|
fCompletionMode= completionMode;
|
||||||
|
|
||||||
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden= new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
|
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden= new IdentityHashMap<PreprocessorMacro, PreprocessorMacro>();
|
||||||
|
|
||||||
// setup input sequence
|
// setup input sequence
|
||||||
TokenSource input= new TokenSource(lexer);
|
TokenSource input= new TokenSource(lexer);
|
||||||
TokenList firstExpansion= new TokenList();
|
TokenList firstExpansion= new TokenList();
|
||||||
|
@ -186,8 +186,8 @@ public class MacroExpander {
|
||||||
|
|
||||||
result= expandAll(input, forbidden, protectDefined, null);
|
result= expandAll(input, forbidden, protectDefined, null);
|
||||||
} catch (CompletionInMacroExpansionException e) {
|
} catch (CompletionInMacroExpansionException e) {
|
||||||
// For content assist in macro expansions, we return the list of tokens of the
|
// 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
|
// parameter at the current cursor position and hope that they make sense if
|
||||||
// they are inserted at the position of the expansion.
|
// they are inserted at the position of the expansion.
|
||||||
// For a better solution one would have to perform the expansion with artificial
|
// 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.
|
// parameters and then check where the completion token ends up in the expansion.
|
||||||
|
@ -211,7 +211,7 @@ public class MacroExpander {
|
||||||
fFixedLineNumber= lineNumber;
|
fFixedLineNumber= lineNumber;
|
||||||
fReportMacros= null;
|
fReportMacros= null;
|
||||||
Lexer lexer= new Lexer(fFixedInput, fLexOptions, fLog, this);
|
Lexer lexer= new Lexer(fFixedInput, fLexOptions, fLog, this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tracker.start(fFixedInput);
|
tracker.start(fFixedInput);
|
||||||
Token identifier= lexer.nextToken();
|
Token identifier= lexer.nextToken();
|
||||||
|
@ -246,21 +246,21 @@ public class MacroExpander {
|
||||||
} catch (OffsetLimitReachedException e) {
|
} catch (OffsetLimitReachedException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expects that the identifier of the macro expansion has been consumed. Expands the macro
|
* 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
|
* consuming tokens from the input (to read the parameters) and stores the resulting tokens
|
||||||
* together with boundary markers in the result token list.
|
* together with boundary markers in the result token list.
|
||||||
* @return the last token of the expansion.
|
* @return the last token of the expansion.
|
||||||
* @throws AbortMacroExpansionException
|
* @throws AbortMacroExpansionException
|
||||||
*/
|
*/
|
||||||
private Token expandOne(Token lastConsumed, PreprocessorMacro macro,
|
private Token expandOne(Token lastConsumed, PreprocessorMacro macro,
|
||||||
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input,
|
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden, TokenSource input,
|
||||||
TokenList result, MacroExpansionTracker tracker)
|
TokenList result, MacroExpansionTracker tracker)
|
||||||
throws OffsetLimitReachedException {
|
throws OffsetLimitReachedException {
|
||||||
if (fReportMacros != null)
|
if (fReportMacros != null)
|
||||||
fReportMacros.significantMacro(macro);
|
fReportMacros.significantMacro(macro);
|
||||||
|
|
||||||
if (macro.isFunctionStyle()) {
|
if (macro.isFunctionStyle()) {
|
||||||
final int paramCount = macro.getParameterPlaceholderList().length;
|
final int paramCount = macro.getParameterPlaceholderList().length;
|
||||||
final TokenSource[] argInputs= new TokenSource[paramCount];
|
final TokenSource[] argInputs= new TokenSource[paramCount];
|
||||||
|
@ -271,13 +271,13 @@ public class MacroExpander {
|
||||||
try {
|
try {
|
||||||
lastConsumed= parseArguments(input, (FunctionStyleMacro) macro, forbidden, argInputs, tracker);
|
lastConsumed= parseArguments(input, (FunctionStyleMacro) macro, forbidden, argInputs, tracker);
|
||||||
} catch (AbortMacroExpansionException e) {
|
} catch (AbortMacroExpansionException e) {
|
||||||
// ignore this macro expansion
|
// Ignore this macro expansion.
|
||||||
for (TokenSource argInput : argInputs) {
|
for (TokenSource argInput : argInputs) {
|
||||||
executeScopeMarkers(argInput, forbidden);
|
executeScopeMarkers(argInput, forbidden);
|
||||||
if (tracker != null) {
|
if (tracker != null) {
|
||||||
tracker.setExpandedMacroArgument(null);
|
tracker.setExpandedMacroArgument(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tracker != null) {
|
if (tracker != null) {
|
||||||
if (tracker.isRequestedStep()) {
|
if (tracker.isRequestedStep()) {
|
||||||
tracker.storeFunctionStyleMacroReplacement(macro, new TokenList(), result);
|
tracker.storeFunctionStyleMacroReplacement(macro, new TokenList(), result);
|
||||||
|
@ -288,7 +288,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenList[] clonedArgs= new TokenList[paramCount];
|
TokenList[] clonedArgs= new TokenList[paramCount];
|
||||||
TokenList[] expandedArgs= new TokenList[paramCount];
|
TokenList[] expandedArgs= new TokenList[paramCount];
|
||||||
for (int i = 0; i < paramCount; i++) {
|
for (int i = 0; i < paramCount; i++) {
|
||||||
|
@ -342,11 +342,11 @@ public class MacroExpander {
|
||||||
|
|
||||||
private void executeScopeMarkers(TokenSource input, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
|
private void executeScopeMarkers(TokenSource input, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
|
||||||
Token t= input.removeFirst();
|
Token t= input.removeFirst();
|
||||||
while(t != null) {
|
while (t != null) {
|
||||||
if (t.getType() == CPreprocessor.tSCOPE_MARKER) {
|
if (t.getType() == CPreprocessor.tSCOPE_MARKER) {
|
||||||
((ExpansionBoundary) t).execute(forbidden);
|
((ExpansionBoundary) t).execute(forbidden);
|
||||||
}
|
}
|
||||||
t= input.removeFirst();
|
t= input.removeFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ public class MacroExpander {
|
||||||
boolean protect= false;
|
boolean protect= false;
|
||||||
Token l= null;
|
Token l= null;
|
||||||
Token t= input.removeFirst();
|
Token t= input.removeFirst();
|
||||||
while(t != null) {
|
while (t != null) {
|
||||||
switch (t.getType()) {
|
switch (t.getType()) {
|
||||||
case CPreprocessor.tSCOPE_MARKER:
|
case CPreprocessor.tSCOPE_MARKER:
|
||||||
((ExpansionBoundary) t).execute(forbidden);
|
((ExpansionBoundary) t).execute(forbidden);
|
||||||
|
@ -395,7 +395,7 @@ public class MacroExpander {
|
||||||
|
|
||||||
addSpacemarker(l, t, replacement); // start expansion
|
addSpacemarker(l, t, replacement); // start expansion
|
||||||
replacement.append(new ExpansionBoundary(macro, true));
|
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));
|
replacement.append(new ExpansionBoundary(macro, false));
|
||||||
addSpacemarker(last, input.first(), replacement); // end expansion
|
addSpacemarker(last, input.first(), replacement); // end expansion
|
||||||
|
|
||||||
|
@ -404,12 +404,12 @@ public class MacroExpander {
|
||||||
break;
|
break;
|
||||||
case IToken.tLPAREN:
|
case IToken.tLPAREN:
|
||||||
case CPreprocessor.tNOSPACE:
|
case CPreprocessor.tNOSPACE:
|
||||||
case CPreprocessor.tSPACE:
|
case CPreprocessor.tSPACE:
|
||||||
result.append(t);
|
result.append(t);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
protect= false;
|
protect= false;
|
||||||
result.append(t);
|
result.append(t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
l= t;
|
l= t;
|
||||||
|
@ -418,6 +418,14 @@ public class MacroExpander {
|
||||||
return result;
|
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) {
|
private ImageLocationInfo createImageLocationInfo(Token t) {
|
||||||
if (fLocationMap != null) {
|
if (fLocationMap != null) {
|
||||||
final Object s= t.fSource;
|
final Object s= t.fSource;
|
||||||
|
@ -450,26 +458,26 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
|
target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expects that the identifier has been consumed.
|
* Expects that the identifier has been consumed.
|
||||||
*/
|
*/
|
||||||
private Token parseArguments(TokenSource input, FunctionStyleMacro macro,
|
private Token parseArguments(TokenSource input, FunctionStyleMacro macro,
|
||||||
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden,
|
IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden,
|
||||||
TokenSource[] result, MacroExpansionTracker tracker)
|
TokenSource[] result, MacroExpansionTracker tracker)
|
||||||
throws OffsetLimitReachedException, AbortMacroExpansionException {
|
throws OffsetLimitReachedException, AbortMacroExpansionException {
|
||||||
final int argCount= macro.getParameterPlaceholderList().length;
|
final int argCount= macro.getParameterPlaceholderList().length;
|
||||||
final boolean hasVarargs= macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS;
|
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 idx= 0;
|
||||||
int nesting= -1;
|
int nesting= -1;
|
||||||
for (int i = 0; i < result.length; i++) {
|
for (int i = 0; i < result.length; i++) {
|
||||||
result[i]= new TokenSource(null);
|
result[i]= new TokenSource(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean missingRParenthesis= false;
|
boolean missingRParenthesis= false;
|
||||||
boolean tooManyArgs= false;
|
boolean tooManyArgs= false;
|
||||||
|
|
||||||
boolean isFirstOfArg= true;
|
boolean isFirstOfArg= true;
|
||||||
Token lastToken= null;
|
Token lastToken= null;
|
||||||
TokenList spaceMarkers= new TokenList();
|
TokenList spaceMarkers= new TokenList();
|
||||||
|
@ -481,7 +489,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
if (tracker != null) {
|
if (tracker != null) {
|
||||||
switch (t.getType()) {
|
switch (t.getType()) {
|
||||||
case IToken.tEND_OF_INPUT:
|
case IToken.tEND_OF_INPUT:
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
case CPreprocessor.tSCOPE_MARKER:
|
case CPreprocessor.tSCOPE_MARKER:
|
||||||
case Lexer.tNEWLINE:
|
case Lexer.tNEWLINE:
|
||||||
|
@ -509,28 +517,28 @@ public class MacroExpander {
|
||||||
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
|
throw new CompletionInMacroExpansionException(ORIGIN, t, result[idx]);
|
||||||
}
|
}
|
||||||
throw new OffsetLimitReachedException(ORIGIN, t);
|
throw new OffsetLimitReachedException(ORIGIN, t);
|
||||||
|
|
||||||
case Lexer.tNEWLINE:
|
case Lexer.tNEWLINE:
|
||||||
continue loop;
|
continue loop;
|
||||||
|
|
||||||
case IToken.tLPAREN:
|
case IToken.tLPAREN:
|
||||||
// the first one sets nesting to zero.
|
// The first one sets nesting to zero.
|
||||||
if (++nesting == 0) {
|
if (++nesting == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tRPAREN:
|
case IToken.tRPAREN:
|
||||||
assert nesting >= 0;
|
assert nesting >= 0;
|
||||||
if (--nesting < 0) {
|
if (--nesting < 0) {
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tCOMMA:
|
case IToken.tCOMMA:
|
||||||
assert nesting >= 0;
|
assert nesting >= 0;
|
||||||
if (nesting == 0) {
|
if (nesting == 0) {
|
||||||
if (idx < argCount-1) { // next argument
|
if (idx < argCount - 1) { // Next argument.
|
||||||
isFirstOfArg= true;
|
isFirstOfArg= true;
|
||||||
spaceMarkers.clear();
|
spaceMarkers.clear();
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -541,7 +549,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPreprocessor.tSCOPE_MARKER:
|
case CPreprocessor.tSCOPE_MARKER:
|
||||||
if (argCount == 0) {
|
if (argCount == 0) {
|
||||||
((ExpansionBoundary) t).execute(forbidden);
|
((ExpansionBoundary) t).execute(forbidden);
|
||||||
|
@ -549,14 +557,14 @@ public class MacroExpander {
|
||||||
result[idx].append(t);
|
result[idx].append(t);
|
||||||
}
|
}
|
||||||
continue loop;
|
continue loop;
|
||||||
|
|
||||||
case CPreprocessor.tSPACE:
|
case CPreprocessor.tSPACE:
|
||||||
case CPreprocessor.tNOSPACE:
|
case CPreprocessor.tNOSPACE:
|
||||||
if (!isFirstOfArg) {
|
if (!isFirstOfArg) {
|
||||||
spaceMarkers.append(t);
|
spaceMarkers.append(t);
|
||||||
}
|
}
|
||||||
continue loop;
|
continue loop;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert nesting >= 0;
|
assert nesting >= 0;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +581,7 @@ public class MacroExpander {
|
||||||
handleProblem(IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, macro.getNameCharArray());
|
handleProblem(IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, macro.getNameCharArray());
|
||||||
throw new AbortMacroExpansionException();
|
throw new AbortMacroExpansionException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooManyArgs) {
|
if (tooManyArgs) {
|
||||||
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
handleProblem(IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, macro.getNameCharArray());
|
||||||
} else if (idx + 1 < requiredArgs) {
|
} else if (idx + 1 < requiredArgs) {
|
||||||
|
@ -581,18 +589,18 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
return lastToken;
|
return lastToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleProblem(int problemID, char[] arg) {
|
private void handleProblem(int problemID, char[] arg) {
|
||||||
fLog.handleProblem(problemID, arg, fStartOffset, fEndOffset);
|
fLog.handleProblem(problemID, arg, fStartOffset, fEndOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceArgs(PreprocessorMacro macro, TokenList[] args, TokenList[] expandedArgs, TokenList result) {
|
private void replaceArgs(PreprocessorMacro macro, TokenList[] args, TokenList[] expandedArgs, TokenList result) {
|
||||||
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
|
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
|
||||||
|
|
||||||
Token l= null;
|
Token l= null;
|
||||||
Token n;
|
Token n;
|
||||||
Token pasteArg1= null;
|
Token pasteArg1= null;
|
||||||
for (Token t= replacement.first(); t != null; l=t, t=n) {
|
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
||||||
n= (Token) t.getNext();
|
n= (Token) t.getNext();
|
||||||
|
|
||||||
switch (t.getType()) {
|
switch (t.getType()) {
|
||||||
|
@ -614,7 +622,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tPOUND:
|
case IToken.tPOUND:
|
||||||
addSpacemarker(l, t, result); // start stringify
|
addSpacemarker(l, t, result); // start stringify
|
||||||
StringBuilder buf= new StringBuilder();
|
StringBuilder buf= new StringBuilder();
|
||||||
|
@ -628,19 +636,19 @@ public class MacroExpander {
|
||||||
n= (Token) n.getNext();
|
n= (Token) n.getNext();
|
||||||
}
|
}
|
||||||
buf.append('"');
|
buf.append('"');
|
||||||
final int length= buf.length();
|
final int length= buf.length();
|
||||||
final char[] image= new char[length];
|
final char[] image= new char[length];
|
||||||
buf.getChars(0, length, image, 0);
|
buf.getChars(0, length, image, 0);
|
||||||
|
|
||||||
Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image);
|
Token generated= new TokenWithImage(IToken.tSTRING, null, 0, 0, image);
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify
|
if (isKind(n, IToken.tPOUNDPOUND)) { // start token paste, same as start stringify
|
||||||
pasteArg1= generated;
|
pasteArg1= generated;
|
||||||
} else {
|
} else {
|
||||||
result.append(generated);
|
result.append(generated);
|
||||||
addSpacemarker(t, n, result); // end stringify
|
addSpacemarker(t, n, result); // end stringify
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tPOUNDPOUND:
|
case IToken.tPOUNDPOUND:
|
||||||
Token pasteArg2= null;
|
Token pasteArg2= null;
|
||||||
TokenList rest= null;
|
TokenList rest= null;
|
||||||
|
@ -664,7 +672,7 @@ public class MacroExpander {
|
||||||
idx= -1;
|
idx= -1;
|
||||||
pasteArg2= n;
|
pasteArg2= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
t= n;
|
t= n;
|
||||||
n= (Token) n.getNext();
|
n= (Token) n.getNext();
|
||||||
final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND);
|
final boolean pasteNext= isKind(n, IToken.tPOUNDPOUND);
|
||||||
|
@ -676,7 +684,7 @@ public class MacroExpander {
|
||||||
generated= pasteArg1;
|
generated= pasteArg1;
|
||||||
if (rest == null)
|
if (rest == null)
|
||||||
rest= new TokenList();
|
rest= new TokenList();
|
||||||
|
|
||||||
rest.prepend(pasteArg2);
|
rest.prepend(pasteArg2);
|
||||||
spaceDef0= generated;
|
spaceDef0= generated;
|
||||||
spaceDef1= pasteArg2;
|
spaceDef1= pasteArg2;
|
||||||
|
@ -707,15 +715,15 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tCOMMA:
|
case IToken.tCOMMA:
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||||
final Token nn= (Token) n.getNext();
|
final Token nn= (Token) n.getNext();
|
||||||
if (isKind(nn, CPreprocessor.tMACRO_PARAMETER)) {
|
if (isKind(nn, CPreprocessor.tMACRO_PARAMETER)) {
|
||||||
idx= ((TokenParameterReference) nn).getIndex();
|
idx= ((TokenParameterReference) nn).getIndex();
|
||||||
|
|
||||||
// check for gcc-extension preventing the paste operation
|
// 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)) {
|
!isKind(nn.getNext(), IToken.tPOUNDPOUND)) {
|
||||||
final Token nnn= (Token) nn.getNext();
|
final Token nnn= (Token) nn.getNext();
|
||||||
TokenList arg= clone(expandedArgs[idx]);
|
TokenList arg= clone(expandedArgs[idx]);
|
||||||
|
@ -733,14 +741,14 @@ public class MacroExpander {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addSpacemarker(l, t, result);
|
addSpacemarker(l, t, result);
|
||||||
pasteArg1= t;
|
pasteArg1= t;
|
||||||
} else {
|
} else {
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||||
addSpacemarker(l, t, result); // start token paste
|
addSpacemarker(l, t, result); // start token paste
|
||||||
|
@ -752,7 +760,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isKind(final IToken t, final int kind) {
|
private boolean isKind(final IToken t, final int kind) {
|
||||||
return t != null && t.getType() == kind;
|
return t != null && t.getType() == kind;
|
||||||
}
|
}
|
||||||
|
@ -760,9 +768,9 @@ public class MacroExpander {
|
||||||
private BitSet getParamUsage(PreprocessorMacro macro) {
|
private BitSet getParamUsage(PreprocessorMacro macro) {
|
||||||
final BitSet result= new BitSet();
|
final BitSet result= new BitSet();
|
||||||
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions, this);
|
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions, this);
|
||||||
|
|
||||||
Token l= null;
|
Token l= null;
|
||||||
Token n;
|
Token n;
|
||||||
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
||||||
n= (Token) t.getNext();
|
n= (Token) t.getNext();
|
||||||
switch (t.getType()) {
|
switch (t.getType()) {
|
||||||
|
@ -773,7 +781,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
result.set(idx);
|
result.set(idx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tPOUND:
|
case IToken.tPOUND:
|
||||||
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
|
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
|
||||||
idx= ((TokenParameterReference) n).getIndex();
|
idx= ((TokenParameterReference) n).getIndex();
|
||||||
|
@ -781,7 +789,7 @@ public class MacroExpander {
|
||||||
t= n; n= (Token) n.getNext();
|
t= n; n= (Token) n.getNext();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IToken.tPOUNDPOUND:
|
case IToken.tPOUNDPOUND:
|
||||||
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
|
if (isKind(n, CPreprocessor.tMACRO_PARAMETER)) {
|
||||||
idx= ((TokenParameterReference) n).getIndex();
|
idx= ((TokenParameterReference) n).getIndex();
|
||||||
|
@ -795,17 +803,17 @@ public class MacroExpander {
|
||||||
t= n; n= (Token) n.getNext();
|
t= n; n= (Token) n.getNext();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void objStyleTokenPaste(PreprocessorMacro macro, TokenList result) {
|
private void objStyleTokenPaste(PreprocessorMacro macro, TokenList result) {
|
||||||
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
|
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
|
||||||
|
|
||||||
Token l= null;
|
Token l= null;
|
||||||
Token n;
|
Token n;
|
||||||
Token pasteArg1= null;
|
Token pasteArg1= null;
|
||||||
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
for (Token t= replacement.first(); t != null; l= t, t= n) {
|
||||||
n= (Token) t.getNext();
|
n= (Token) t.getNext();
|
||||||
|
|
||||||
|
@ -817,7 +825,7 @@ public class MacroExpander {
|
||||||
pasteArg2= n;
|
pasteArg2= n;
|
||||||
n= (Token) n.getNext();
|
n= (Token) n.getNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
t= tokenpaste(pasteArg1, pasteArg2, macro);
|
t= tokenpaste(pasteArg1, pasteArg2, macro);
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||||
|
@ -829,7 +837,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (isKind(n, IToken.tPOUNDPOUND)) {
|
if (isKind(n, IToken.tPOUNDPOUND)) {
|
||||||
addSpacemarker(l, t, result); // start token paste
|
addSpacemarker(l, t, result); // start token paste
|
||||||
|
@ -910,7 +918,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
space= false;
|
space= false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CPreprocessor.tSPACE:
|
case CPreprocessor.tSPACE:
|
||||||
if (!space && l != null && n != null) {
|
if (!space && l != null && n != null) {
|
||||||
buf.append(' ');
|
buf.append(' ');
|
||||||
|
@ -920,7 +928,7 @@ public class MacroExpander {
|
||||||
|
|
||||||
case CPreprocessor.tNOSPACE:
|
case CPreprocessor.tNOSPACE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
buf.append(t.getCharImage());
|
buf.append(t.getCharImage());
|
||||||
space= false;
|
space= false;
|
||||||
|
@ -928,7 +936,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTName[] clearImplicitExpansions() {
|
public IASTName[] clearImplicitExpansions() {
|
||||||
IASTName[] result= fImplicitMacroExpansions.toArray(new IASTName[fImplicitMacroExpansions.size()]);
|
IASTName[] result= fImplicitMacroExpansions.toArray(new IASTName[fImplicitMacroExpansions.size()]);
|
||||||
fImplicitMacroExpansions.clear();
|
fImplicitMacroExpansions.clear();
|
||||||
|
@ -950,20 +958,12 @@ public class MacroExpander {
|
||||||
case CPreprocessor.tEXPANDED_IDENTIFIER:
|
case CPreprocessor.tEXPANDED_IDENTIFIER:
|
||||||
t.setType(IToken.tIDENTIFIER);
|
t.setType(IToken.tIDENTIFIER);
|
||||||
if (createImageLocations) {
|
if (createImageLocations) {
|
||||||
ImageLocationInfo info= createImageLocationInfo(t);
|
addImageLocationInfo(offset, t);
|
||||||
if (info != null) {
|
|
||||||
info.fTokenOffsetInExpansion= offset;
|
|
||||||
fImageLocationInfos.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IToken.tIDENTIFIER:
|
case IToken.tIDENTIFIER:
|
||||||
if (createImageLocations) {
|
if (createImageLocations) {
|
||||||
ImageLocationInfo info= createImageLocationInfo(t);
|
addImageLocationInfo(offset, t);
|
||||||
if (info != null) {
|
|
||||||
info.fTokenOffsetInExpansion= offset;
|
|
||||||
fImageLocationInfos.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -978,12 +978,18 @@ public class MacroExpander {
|
||||||
t.setOffset(offset, offset + t.getLength());
|
t.setOffset(offset, offset + t.getLength());
|
||||||
t.setNext(null);
|
t.setNext(null);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (createImageLocations && t.fSource instanceof CPreprocessor) {
|
||||||
|
addImageLocationInfo(offset, t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
t.setOffset(offset, ++offset);
|
t.setOffset(offset, ++offset);
|
||||||
l= t;
|
l= t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCurrentLineNumber() {
|
int getCurrentLineNumber() {
|
||||||
if (fFixedInput != null) {
|
if (fFixedInput != null) {
|
||||||
return fFixedLineNumber + countNewlines(fFixedInput);
|
return fFixedLineNumber + countNewlines(fFixedInput);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
|
@ -30,12 +30,12 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
||||||
fMacroDefinition= def;
|
fMacroDefinition= def;
|
||||||
fMacroLocation= macroLoc;
|
fMacroLocation= macroLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCodeBeforeStep() {
|
public String getCodeBeforeStep() {
|
||||||
return fBefore;
|
return fBefore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCodeAfterStep() {
|
public String getCodeAfterStep() {
|
||||||
StringBuilder result= new StringBuilder();
|
StringBuilder result= new StringBuilder();
|
||||||
|
@ -49,7 +49,7 @@ public class MacroExpansionStep implements IMacroExpansionStep {
|
||||||
result.append(fBefore, offset, fBefore.length());
|
result.append(fBefore, offset, fBefore.length());
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IMacroBinding getExpandedMacro() {
|
public IMacroBinding getExpandedMacro() {
|
||||||
return fMacroDefinition;
|
return fMacroDefinition;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -35,7 +35,7 @@ public class MacroExpansionTracker {
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int fStepToTrack;
|
private final int fStepToTrack;
|
||||||
|
|
||||||
private int fStepCount;
|
private int fStepCount;
|
||||||
private String fPreStep;
|
private String fPreStep;
|
||||||
private ReplaceEdit fReplacement;
|
private ReplaceEdit fReplacement;
|
||||||
|
@ -58,14 +58,14 @@ public class MacroExpansionTracker {
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return fStepCount > fStepToTrack;
|
return fStepCount > fStepToTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether we are currently looking at the requested step.
|
* Returns whether we are currently looking at the requested step.
|
||||||
*/
|
*/
|
||||||
public boolean isRequestedStep() {
|
public boolean isRequestedStep() {
|
||||||
return fStepCount == fStepToTrack;
|
return fStepCount == fStepToTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the total amount of steps encountered so far.
|
* Returns the total amount of steps encountered so far.
|
||||||
*/
|
*/
|
||||||
|
@ -79,7 +79,7 @@ public class MacroExpansionTracker {
|
||||||
public String getCodeBeforeStep() {
|
public String getCodeBeforeStep() {
|
||||||
return fPreStep;
|
return fPreStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the replacement that represents the change by the step that was tracked.
|
* Returns the replacement that represents the change by the step that was tracked.
|
||||||
*/
|
*/
|
||||||
|
@ -132,7 +132,7 @@ public class MacroExpansionTracker {
|
||||||
fReplacement= new ReplaceEdit(offset, replace.length(), fReplacementText);
|
fReplacement= new ReplaceEdit(offset, replace.length(), fReplacementText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There was no macro at the beginning of the input.
|
* There was no macro at the beginning of the input.
|
||||||
*/
|
*/
|
||||||
|
@ -140,7 +140,7 @@ public class MacroExpansionTracker {
|
||||||
fPreStep= new String(fInput);
|
fPreStep= new String(fInput);
|
||||||
fReplacement= new ReplaceEdit(0, 0, ""); //$NON-NLS-1$
|
fReplacement= new ReplaceEdit(0, 0, ""); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toString(TokenList tokenList, char[] rootInput, StringBuilder before,
|
private void toString(TokenList tokenList, char[] rootInput, StringBuilder before,
|
||||||
StringBuilder replace, StringBuilder after) {
|
StringBuilder replace, StringBuilder after) {
|
||||||
StringBuilder buf= before;
|
StringBuilder buf= before;
|
||||||
|
@ -176,7 +176,7 @@ public class MacroExpansionTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private char[] getInputForSource(Object source, char[] rootInput) {
|
private char[] getInputForSource(Object source, char[] rootInput) {
|
||||||
if (source instanceof MacroExpander) {
|
if (source instanceof MacroExpander) {
|
||||||
return rootInput;
|
return rootInput;
|
||||||
|
@ -197,7 +197,7 @@ public class MacroExpansionTracker {
|
||||||
public void startFunctionStyleMacro(Token identifier) {
|
public void startFunctionStyleMacro(Token identifier) {
|
||||||
fMacroStack.add(new MacroInfo(identifier));
|
fMacroStack.add(new MacroInfo(identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All tokens defining a function-style macro expansion are reported.
|
* All tokens defining a function-style macro expansion are reported.
|
||||||
*/
|
*/
|
||||||
|
@ -235,7 +235,7 @@ public class MacroExpansionTracker {
|
||||||
* Append the current function-style macro with the arguments substituted.
|
* Append the current function-style macro with the arguments substituted.
|
||||||
*/
|
*/
|
||||||
public void appendFunctionStyleMacro(TokenList result) {
|
public void appendFunctionStyleMacro(TokenList result) {
|
||||||
MacroInfo minfo= fMacroStack.getLast();
|
MacroInfo minfo= fMacroStack.getLast();
|
||||||
boolean active= true;
|
boolean active= true;
|
||||||
int nesting= -1;
|
int nesting= -1;
|
||||||
int pcount= 0;
|
int pcount= 0;
|
||||||
|
@ -298,7 +298,7 @@ public class MacroExpansionTracker {
|
||||||
result.append(t);
|
result.append(t);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (active) {
|
if (active) {
|
||||||
result.append(t);
|
result.append(t);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* 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"}
|
* 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
|
* 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.
|
* on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
@ -48,7 +48,7 @@ public class Token implements IToken, Cloneable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
final public int getLength() {
|
final public int getLength() {
|
||||||
return fEndOffset-fOffset;
|
return fEndOffset - fOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,7 +56,6 @@ public class Token implements IToken, Cloneable {
|
||||||
return fNextToken;
|
return fNextToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
final public void setType(int kind) {
|
final public void setType(int kind) {
|
||||||
fKind= kind;
|
fKind= kind;
|
||||||
|
@ -73,8 +72,8 @@ public class Token implements IToken, Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shiftOffset(int shift) {
|
public void shiftOffset(int shift) {
|
||||||
fOffset+= shift;
|
fOffset += shift;
|
||||||
fEndOffset+= shift;
|
fEndOffset += shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,7 +85,7 @@ public class Token implements IToken, Cloneable {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getImage();
|
return getImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
final public boolean isOperator() {
|
final public boolean isOperator() {
|
||||||
return TokenUtil.isOperator(fKind);
|
return TokenUtil.isOperator(fKind);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
class TokenList {
|
class TokenList {
|
||||||
|
@ -17,7 +17,8 @@ class TokenList {
|
||||||
final Token removeFirst() {
|
final Token removeFirst() {
|
||||||
final Token first= fFirst;
|
final Token first= fFirst;
|
||||||
if (first == fLast) {
|
if (first == fLast) {
|
||||||
fFirst= fLast= null;
|
fFirst= null;
|
||||||
|
fLast= null;
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
fFirst= (Token) first.getNext();
|
fFirst= (Token) first.getNext();
|
||||||
|
@ -26,38 +27,38 @@ class TokenList {
|
||||||
|
|
||||||
public final void append(Token t) {
|
public final void append(Token t) {
|
||||||
if (fFirst == null) {
|
if (fFirst == null) {
|
||||||
fFirst= fLast= t;
|
fFirst= t;
|
||||||
}
|
fLast= t;
|
||||||
else {
|
} else {
|
||||||
fLast.setNext(t);
|
fLast.setNext(t);
|
||||||
fLast= t;
|
fLast= t;
|
||||||
}
|
}
|
||||||
t.setNext(null);
|
t.setNext(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void appendAll(TokenList tl) {
|
public final void appendAll(TokenList tl) {
|
||||||
final Token t= tl.first();
|
final Token t= tl.first();
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
if (fFirst == null) {
|
if (fFirst == null) {
|
||||||
fFirst= tl.fFirst;
|
fFirst= tl.fFirst;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fLast.setNext(tl.fFirst);
|
fLast.setNext(tl.fFirst);
|
||||||
}
|
}
|
||||||
fLast= tl.fLast;
|
fLast= tl.fLast;
|
||||||
}
|
}
|
||||||
tl.fFirst= tl.fLast= null;
|
tl.fFirst= null;
|
||||||
|
tl.fLast= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void appendAllButLast(TokenList tl) {
|
public final void appendAllButLast(TokenList tl) {
|
||||||
Token t= tl.first();
|
Token t= tl.first();
|
||||||
if (t != null) {
|
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);
|
append(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void prepend(Token t) {
|
public final void prepend(Token t) {
|
||||||
final Token first= t;
|
final Token first= t;
|
||||||
if (first != null) {
|
if (first != null) {
|
||||||
|
@ -81,7 +82,7 @@ class TokenList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final TokenList cloneTokens() {
|
public final TokenList cloneTokens() {
|
||||||
TokenList result= new TokenList();
|
TokenList result= new TokenList();
|
||||||
for (Token t= fFirst; t != null; t= (Token) t.getNext()) {
|
for (Token t= fFirst; t != null; t= (Token) t.getNext()) {
|
||||||
|
@ -110,8 +111,7 @@ class TokenList {
|
||||||
fLast= null;
|
fLast= null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
final Token r= (Token) l.getNext();
|
final Token r= (Token) l.getNext();
|
||||||
if (r != null) {
|
if (r != null) {
|
||||||
l.setNext(r.getNext());
|
l.setNext(r.getNext());
|
||||||
|
@ -124,19 +124,20 @@ class TokenList {
|
||||||
|
|
||||||
void cutAfter(Token l) {
|
void cutAfter(Token l) {
|
||||||
if (l == null) {
|
if (l == null) {
|
||||||
fFirst= fLast= null;
|
fFirst= null;
|
||||||
}
|
fLast= null;
|
||||||
else {
|
} else {
|
||||||
l.setNext(null);
|
l.setNext(null);
|
||||||
fLast= l;
|
fLast= l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
fFirst= fLast= null;
|
fFirst= null;
|
||||||
|
fLast= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return fFirst==null;
|
return fFirst == null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.parser.IGCCToken;
|
import org.eclipse.cdt.core.parser.IGCCToken;
|
||||||
|
@ -20,7 +20,7 @@ public class TokenUtil {
|
||||||
private static final char[] SPACE = {' '};
|
private static final char[] SPACE = {' '};
|
||||||
private static final char[] IMAGE_POUND_POUND = "##".toCharArray(); //$NON-NLS-1$
|
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[] IMAGE_POUND = "#".toCharArray(); //$NON-NLS-1$
|
||||||
|
|
||||||
private static final char[] DIGRAPH_LBRACE= "<%".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_RBRACE= "%>".toCharArray(); //$NON-NLS-1$
|
||||||
private static final char[] DIGRAPH_LBRACKET= "<:".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.tSHIFTL: case IToken.tSHIFTLASSIGN:
|
||||||
case IToken.tSHIFTR: case IToken.tSHIFTRASSIGN:
|
case IToken.tSHIFTR: case IToken.tSHIFTRASSIGN:
|
||||||
case IToken.tXOR: case IToken.tXORASSIGN:
|
case IToken.tXOR: case IToken.tXORASSIGN:
|
||||||
|
|
||||||
// logical operations
|
// logical operations
|
||||||
case IToken.tNOT: case IToken.tAND: case IToken.tOR:
|
case IToken.tNOT: case IToken.tAND: case IToken.tOR:
|
||||||
|
|
||||||
|
@ -52,25 +52,25 @@ public class TokenUtil {
|
||||||
case IToken.tPLUS: case IToken.tPLUSASSIGN:
|
case IToken.tPLUS: case IToken.tPLUSASSIGN:
|
||||||
case IToken.tSTAR: case IToken.tSTARASSIGN:
|
case IToken.tSTAR: case IToken.tSTARASSIGN:
|
||||||
case IGCCToken.tMAX: case IGCCToken.tMIN:
|
case IGCCToken.tMAX: case IGCCToken.tMIN:
|
||||||
|
|
||||||
// comparison
|
// comparison
|
||||||
case IToken.tEQUAL: case IToken.tNOTEQUAL:
|
case IToken.tEQUAL: case IToken.tNOTEQUAL:
|
||||||
case IToken.tGT: case IToken.tGTEQUAL:
|
case IToken.tGT: case IToken.tGTEQUAL:
|
||||||
case IToken.tLT: case IToken.tLTEQUAL:
|
case IToken.tLT: case IToken.tLTEQUAL:
|
||||||
|
|
||||||
// other
|
// other
|
||||||
case IToken.tASSIGN: case IToken.tCOMMA:
|
case IToken.tASSIGN: case IToken.tCOMMA:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char[] getImage(int type) {
|
public static char[] getImage(int type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IToken.tPOUND: return IMAGE_POUND;
|
case IToken.tPOUND: return IMAGE_POUND;
|
||||||
case IToken.tPOUNDPOUND: return IMAGE_POUND_POUND;
|
case IToken.tPOUNDPOUND: return IMAGE_POUND_POUND;
|
||||||
case IToken.tCOLONCOLON: return Keywords.cpCOLONCOLON;
|
case IToken.tCOLONCOLON: return Keywords.cpCOLONCOLON;
|
||||||
case IToken.tCOLON: return Keywords.cpCOLON;
|
case IToken.tCOLON: return Keywords.cpCOLON;
|
||||||
case IToken.tSEMI: return Keywords.cpSEMI;
|
case IToken.tSEMI: return Keywords.cpSEMI;
|
||||||
case IToken.tCOMMA: return Keywords.cpCOMMA;
|
case IToken.tCOMMA: return Keywords.cpCOMMA;
|
||||||
|
@ -120,34 +120,33 @@ public class TokenUtil {
|
||||||
case IToken.tDOT: return Keywords.cpDOT;
|
case IToken.tDOT: return Keywords.cpDOT;
|
||||||
case IToken.tDIVASSIGN: return Keywords.cpDIVASSIGN;
|
case IToken.tDIVASSIGN: return Keywords.cpDIVASSIGN;
|
||||||
case IToken.tDIV: return Keywords.cpDIV;
|
case IToken.tDIV: return Keywords.cpDIV;
|
||||||
|
|
||||||
case IGCCToken.tMIN: return Keywords.cpMIN;
|
case IGCCToken.tMIN: return Keywords.cpMIN;
|
||||||
case IGCCToken.tMAX: return Keywords.cpMAX;
|
case IGCCToken.tMAX: return Keywords.cpMAX;
|
||||||
|
|
||||||
case CPreprocessor.tSPACE: return SPACE;
|
case CPreprocessor.tSPACE: return SPACE;
|
||||||
case CPreprocessor.tNOSPACE: return CharArrayUtils.EMPTY;
|
case CPreprocessor.tNOSPACE: return CharArrayUtils.EMPTY;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CharArrayUtils.EMPTY;
|
return CharArrayUtils.EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char[] getDigraphImage(int type) {
|
public static char[] getDigraphImage(int type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case IToken.tPOUND: return DIGRAPH_POUND;
|
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.tLBRACKET: return DIGRAPH_LBRACKET;
|
||||||
case IToken.tRBRACKET: return DIGRAPH_RBRACKET;
|
case IToken.tRBRACKET: return DIGRAPH_RBRACKET;
|
||||||
case IToken.tLBRACE: return DIGRAPH_LBRACE;
|
case IToken.tLBRACE: return DIGRAPH_LBRACE;
|
||||||
case IToken.tRBRACE: return DIGRAPH_RBRACE;
|
case IToken.tRBRACE: return DIGRAPH_RBRACE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert false: type;
|
assert false: type;
|
||||||
return CharArrayUtils.EMPTY;
|
return CharArrayUtils.EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last token in the given token list.
|
* Returns the last token in the given token list.
|
||||||
* @throws NullPointerException if the argument is null
|
* @throws NullPointerException if the argument is null
|
||||||
|
@ -156,8 +155,7 @@ public class TokenUtil {
|
||||||
IToken last;
|
IToken last;
|
||||||
do {
|
do {
|
||||||
last = tokenList;
|
last = tokenList;
|
||||||
} while((tokenList = tokenList.getNext()) != null);
|
} while ((tokenList = tokenList.getNext()) != null);
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ public final class TypeMarshalBuffer implements ITypeMarshalBuffer {
|
||||||
fPos--;
|
fPos--;
|
||||||
IType type = unmarshalType();
|
IType type = unmarshalType();
|
||||||
IType originalType = unmarshalType();
|
IType originalType = unmarshalType();
|
||||||
if (originalType == null)
|
if (originalType == null || originalType == UNSTORABLE_TYPE_PROBLEM)
|
||||||
originalType= type;
|
originalType= type;
|
||||||
return new CPPTemplateTypeArgument(type, originalType);
|
return new CPPTemplateTypeArgument(type, originalType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.IASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
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.IASTNullStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
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.DefaultCodeFormatterConstants;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
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.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
||||||
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
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.
|
* Formats a trailing semicolon.
|
||||||
* @see #formatList(List, ListOptions, boolean, boolean, Runnable)
|
* @see #formatList(List, ListOptions, boolean, boolean, Runnable)
|
||||||
|
@ -360,6 +384,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
private final Scribe scribe;
|
private final Scribe scribe;
|
||||||
|
|
||||||
private boolean fInsideFor;
|
private boolean fInsideFor;
|
||||||
|
private boolean fInsideMacroArguments;
|
||||||
private boolean fExpectSemicolonAfterDeclaration= true;
|
private boolean fExpectSemicolonAfterDeclaration= true;
|
||||||
|
|
||||||
private MultiStatus fStatus;
|
private MultiStatus fStatus;
|
||||||
|
@ -540,97 +565,79 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
scribe.printRaw(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
|
scribe.printRaw(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
|
||||||
}
|
}
|
||||||
fileLocation = macroExpansion.getFileLocation();
|
|
||||||
scribe.printNextToken(Token.tLPAREN);
|
|
||||||
IMacroBinding binding = (IMacroBinding) name.resolveBinding();
|
IMacroBinding binding = (IMacroBinding) name.resolveBinding();
|
||||||
if (preferences.insert_space_after_opening_paren_in_method_invocation) {
|
List<Object> arguments = getMacroArguments(binding.getParameterList().length);
|
||||||
scribe.space();
|
|
||||||
|
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,
|
* Scans macro expansion arguments starting from the current position and returns a list of
|
||||||
Alignment.R_OUTERMOST,
|
* arguments where each argument is represented either by a {@link IASTNode} or, if not
|
||||||
binding.getParameterList().length,
|
* possible, by a {@link TokenRange}.
|
||||||
getCurrentPosition(),
|
*/
|
||||||
continuationIndentation,
|
private List<Object> getMacroArguments(int expectedNumberOfArguments) {
|
||||||
false);
|
List<TokenRange> argumentRanges = new ArrayList<TokenRange>(expectedNumberOfArguments);
|
||||||
scribe.enterAlignment(listAlignment);
|
TokenRange currentArgument = null;
|
||||||
boolean ok = false;
|
localScanner.resetTo(getCurrentPosition(), scribe.scannerEndPosition);
|
||||||
do {
|
localScanner.getNextToken(); // Skip the opening parenthesis.
|
||||||
try {
|
int parenLevel = 0;
|
||||||
int fragment = 0;
|
int token;
|
||||||
scribe.alignFragment(listAlignment, fragment);
|
while ((token = localScanner.getNextToken()) != Token.tBADCHAR) {
|
||||||
int parenLevel= 0;
|
int tokenOffset = localScanner.getCurrentTokenStartPosition();
|
||||||
boolean done = false;
|
if (parenLevel == 0 && (token == Token.tCOMMA || token == Token.tRPAREN)) {
|
||||||
while (!done) {
|
if (currentArgument != null) {
|
||||||
boolean hasWhitespace= scribe.printComment();
|
argumentRanges.add(currentArgument);
|
||||||
int token = peekNextToken();
|
currentArgument = null;
|
||||||
switch (token) {
|
} else {
|
||||||
case Token.tLPAREN:
|
argumentRanges.add(new TokenRange(tokenOffset, tokenOffset));
|
||||||
++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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int token = peekNextToken();
|
if (token == Token.tRPAREN)
|
||||||
if (token == Token.tSEMI) {
|
break;
|
||||||
scribe.printNextToken(token);
|
} else {
|
||||||
scribe.startNewLine();
|
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
|
@Override
|
||||||
|
@ -2077,15 +2084,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
/**
|
/**
|
||||||
* Format a given list of elements according alignment options.
|
* 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 options formatting options
|
||||||
* @param encloseInParen indicates whether the list should be enclosed in parentheses
|
* @param encloseInParen indicates whether the list should be enclosed in parentheses
|
||||||
* @param addEllipsis indicates whether ellipsis should be added after the last element
|
* @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
|
* @param tailFormatter formatter for the trailing text that should be kept together with
|
||||||
* the last element of the list.
|
* the last element of the list.
|
||||||
*/
|
*/
|
||||||
private void formatList(List<? extends IASTNode> elements, ListOptions options,
|
private void formatList(List<?> elements, ListOptions options, boolean encloseInParen,
|
||||||
boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) {
|
boolean addEllipsis, Runnable tailFormatter) {
|
||||||
if (encloseInParen)
|
if (encloseInParen)
|
||||||
scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
|
scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
|
||||||
|
|
||||||
|
@ -2118,22 +2126,26 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
try {
|
try {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < elementsLength; i++) {
|
for (i = 0; i < elementsLength; i++) {
|
||||||
final IASTNode node= elements.get(i);
|
final Object element = elements.get(i);
|
||||||
if (i < elementsLength - 1) {
|
if (i < elementsLength - 1) {
|
||||||
scribe.setTailFormatter(
|
scribe.setTailFormatter(
|
||||||
new TrailingTokenFormatter(options.fSeparatorToken,
|
new TrailingTokenFormatter(options.fSeparatorToken,
|
||||||
findTokenAfterNode(options.fSeparatorToken, node),
|
findTokenAfterNodeOrTokenRange(options.fSeparatorToken, element),
|
||||||
options.fSpaceBeforeSeparator,
|
options.fSpaceBeforeSeparator,
|
||||||
options.fSpaceAfterSeparator));
|
options.fSpaceAfterSeparator));
|
||||||
} else {
|
} else {
|
||||||
scribe.setTailFormatter(tailFormatter);
|
scribe.setTailFormatter(tailFormatter);
|
||||||
}
|
}
|
||||||
scribe.alignFragment(alignment, i);
|
scribe.alignFragment(alignment, i);
|
||||||
if (node instanceof ICPPASTConstructorChainInitializer) {
|
if (element instanceof IASTNode) {
|
||||||
// Constructor chain initializer is a special case.
|
if (element instanceof ICPPASTConstructorChainInitializer) {
|
||||||
visit((ICPPASTConstructorChainInitializer) node);
|
// Constructor chain initializer is a special case.
|
||||||
|
visit((ICPPASTConstructorChainInitializer) element);
|
||||||
|
} else {
|
||||||
|
((IASTNode) element).accept(this);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
node.accept(this);
|
formatTokenRange((TokenRange) element);
|
||||||
}
|
}
|
||||||
if (i < elementsLength - 1) {
|
if (i < elementsLength - 1) {
|
||||||
scribe.runTailFormatter();
|
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) {
|
private int visit(ICPPASTTryBlockStatement node) {
|
||||||
scribe.printNextToken(Token.t_try, scribe.printComment());
|
scribe.printNextToken(Token.t_try, scribe.printComment());
|
||||||
final IASTStatement tryBody= node.getTryBody();
|
final IASTStatement tryBody= node.getTryBody();
|
||||||
|
@ -3782,18 +3803,23 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
if (locations.length == 0) {
|
if (locations.length == 0) {
|
||||||
} else if (locations[0] instanceof IASTMacroExpansionLocation) {
|
} else if (!fInsideMacroArguments && locations[0] instanceof IASTMacroExpansionLocation) {
|
||||||
IASTMacroExpansionLocation location = (IASTMacroExpansionLocation) locations[0];
|
IASTMacroExpansionLocation location = (IASTMacroExpansionLocation) locations[0];
|
||||||
if (locations.length <= 2 && node instanceof IASTStatement) {
|
if (locations.length <= 2 && node instanceof IASTStatement) {
|
||||||
IASTPreprocessorMacroExpansion macroExpansion = location.getExpansion();
|
IASTPreprocessorMacroExpansion macroExpansion = location.getExpansion();
|
||||||
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
|
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
|
||||||
IASTFileLocation nodeLocation = node.getFileLocation();
|
IASTFileLocation nodeLocation = getFileLocation(node);
|
||||||
if (macroLocation.getNodeOffset() >= getCurrentPosition() &&
|
if (macroLocation.getNodeOffset() >= getCurrentPosition() &&
|
||||||
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
|
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
|
||||||
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
|
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
|
||||||
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
|
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
|
||||||
locations.length == 2 && isSemicolonLocation(locations[1])) &&
|
locations.length == 2 && isSemicolonLocation(locations[1])) &&
|
||||||
isFunctionStyleMacroExpansion(macroExpansion)) {
|
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);
|
formatFunctionStyleMacroExpansion(macroExpansion);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3808,12 +3834,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
scribe.restartAtOffset(fileLocation.getNodeOffset());
|
scribe.restartAtOffset(fileLocation.getNodeOffset());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IASTFileLocation getFileLocation(IASTNode node) {
|
||||||
|
return fInsideMacroArguments ? ((ASTNode) node).getImageLocation() : node.getFileLocation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatting of node is complete. Undo skip region if any.
|
* Formatting of node is complete. Undo skip region if any.
|
||||||
*
|
*
|
||||||
|
@ -3824,7 +3854,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scribe.skipRange()) {
|
if (scribe.skipRange()) {
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
||||||
scribe.restartAtOffset(nodeEndOffset);
|
scribe.restartAtOffset(nodeEndOffset);
|
||||||
|
@ -3845,7 +3875,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
if (node instanceof IASTProblemHolder || node instanceof IASTTranslationUnit) {
|
if (node instanceof IASTProblemHolder || node instanceof IASTTranslationUnit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation == null) {
|
if (fileLocation == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3855,20 +3885,22 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
if (currentOffset > nodeEndOffset) {
|
if (currentOffset > nodeEndOffset) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
if (!fInsideMacroArguments) {
|
||||||
for (int i= 0; i < locations.length; i++) {
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
IASTNodeLocation nodeLocation= locations[i];
|
for (int i= 0; i < locations.length; i++) {
|
||||||
if (nodeLocation instanceof IASTMacroExpansionLocation) {
|
IASTNodeLocation nodeLocation= locations[i];
|
||||||
IASTFileLocation expansionLocation= nodeLocation.asFileLocation();
|
if (nodeLocation instanceof IASTMacroExpansionLocation) {
|
||||||
int startOffset= expansionLocation.getNodeOffset();
|
IASTFileLocation expansionLocation= nodeLocation.asFileLocation();
|
||||||
int endOffset= startOffset + expansionLocation.getNodeLength();
|
int startOffset= expansionLocation.getNodeOffset();
|
||||||
if (currentOffset <= startOffset) {
|
int endOffset= startOffset + expansionLocation.getNodeLength();
|
||||||
break;
|
if (currentOffset <= startOffset) {
|
||||||
}
|
break;
|
||||||
if (currentOffset < endOffset ||
|
}
|
||||||
currentOffset == endOffset && i == locations.length - 1) {
|
if (currentOffset < endOffset ||
|
||||||
scribe.skipRange(startOffset, endOffset);
|
currentOffset == endOffset && i == locations.length - 1) {
|
||||||
break;
|
scribe.skipRange(startOffset, endOffset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3881,7 +3913,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipNode(IASTNode node) {
|
private void skipNode(IASTNode node) {
|
||||||
final IASTNodeLocation fileLocation= node.getFileLocation();
|
final IASTNodeLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null && fileLocation.getNodeLength() > 0) {
|
if (fileLocation != null && fileLocation.getNodeLength() > 0) {
|
||||||
final int endOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
final int endOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
||||||
final int currentOffset= getCurrentPosition();
|
final int currentOffset= getCurrentPosition();
|
||||||
|
@ -3893,7 +3925,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipToNode(IASTNode node) {
|
private void skipToNode(IASTNode node) {
|
||||||
final IASTNodeLocation fileLocation= node.getFileLocation();
|
final IASTNodeLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
final int startOffset= fileLocation.getNodeOffset();
|
final int startOffset= fileLocation.getNodeOffset();
|
||||||
final int currentOffset= getCurrentPosition();
|
final int currentOffset= getCurrentPosition();
|
||||||
|
@ -3905,7 +3937,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipNonWhitespaceToNode(IASTNode node) {
|
private void skipNonWhitespaceToNode(IASTNode node) {
|
||||||
final IASTNodeLocation fileLocation= node.getFileLocation();
|
final IASTNodeLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
final int startOffset= fileLocation.getNodeOffset();
|
final int startOffset= fileLocation.getNodeOffset();
|
||||||
final int nextTokenOffset= getNextTokenOffset();
|
final int nextTokenOffset= getNextTokenOffset();
|
||||||
|
@ -3985,18 +4017,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();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
||||||
locations[0] instanceof IASTMacroExpansionLocation) {
|
locations[0] instanceof IASTMacroExpansionLocation) {
|
||||||
IASTFileLocation expansionLocation= locations[0].asFileLocation();
|
IASTFileLocation expansionLocation= locations[0].asFileLocation();
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
return expansionLocation.getNodeOffset() == fileLocation.getNodeOffset();
|
return expansionLocation.getNodeOffset() == fileLocation.getNodeOffset();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean endsWithMacroExpansion(IASTNode node) {
|
private boolean endsWithMacroExpansion(IASTNode node) {
|
||||||
|
if (fInsideMacroArguments)
|
||||||
|
return false;
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
||||||
locations[locations.length - 1] instanceof IASTMacroExpansionLocation) {
|
locations[locations.length - 1] instanceof IASTMacroExpansionLocation) {
|
||||||
|
@ -4005,13 +4041,17 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean enclosedInMacroExpansion(IASTNode node) {
|
private boolean enclosedInMacroExpansion(IASTNode node) {
|
||||||
|
if (fInsideMacroArguments)
|
||||||
|
return false;
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
return locations.length == 1 && locations[0] instanceof IASTMacroExpansionLocation;
|
return locations.length == 1 && locations[0] instanceof IASTMacroExpansionLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean withinMacroExpansion(IASTNode node, int offset) {
|
private boolean withinMacroExpansion(IASTNode node, int offset) {
|
||||||
IASTFileLocation loc = node.getFileLocation();
|
if (fInsideMacroArguments)
|
||||||
|
return false;
|
||||||
|
IASTFileLocation loc = getFileLocation(node);
|
||||||
if (loc == null || offset < loc.getNodeOffset() || offset >= loc.getNodeOffset() + loc.getNodeLength()) {
|
if (loc == null || offset < loc.getNodeOffset() || offset >= loc.getNodeOffset() + loc.getNodeLength()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4061,9 +4101,9 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
* normally separated by other tokens this is an indication that they were produced by the same
|
* normally separated by other tokens this is an indication that they were produced by the same
|
||||||
* macro expansion.
|
* macro expansion.
|
||||||
*/
|
*/
|
||||||
private static boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
|
private boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
|
||||||
IASTFileLocation loc1 = node1.getFileLocation();
|
IASTFileLocation loc1 = getFileLocation(node1);
|
||||||
IASTFileLocation loc2 = node2.getFileLocation();
|
IASTFileLocation loc2 = getFileLocation(node2);
|
||||||
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
|
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
|
||||||
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
|
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
|
||||||
}
|
}
|
||||||
|
@ -4073,16 +4113,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
* separated by other tokens this is an indication that they were produced by the same macro
|
* separated by other tokens this is an indication that they were produced by the same macro
|
||||||
* expansion.
|
* expansion.
|
||||||
*/
|
*/
|
||||||
private static boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
|
private boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
|
||||||
return nodeOffset(node1) == nodeOffset(node2);
|
return nodeOffset(node1) == nodeOffset(node2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int nodeOffset(IASTNode node) {
|
private int nodeOffset(IASTNode node) {
|
||||||
return node.getFileLocation().getNodeOffset();
|
return getFileLocation(node).getNodeOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int nodeEndOffset(IASTNode node) {
|
private int nodeEndOffset(IASTNode node) {
|
||||||
IASTFileLocation loc = node.getFileLocation();
|
IASTFileLocation loc = getFileLocation(node);
|
||||||
return loc.getNodeOffset() + loc.getNodeLength();
|
return loc.getNodeOffset() + loc.getNodeLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4407,14 +4447,19 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findTokenWithinNode(int tokenType, IASTNode node) {
|
private int findTokenWithinNode(int tokenType, IASTNode node) {
|
||||||
IASTFileLocation location = node.getFileLocation();
|
IASTFileLocation location = getFileLocation(node);
|
||||||
int endOffset = location.getNodeOffset() + location.getNodeLength();
|
int endOffset = location.getNodeOffset() + location.getNodeLength();
|
||||||
return scribe.findToken(tokenType, endOffset);
|
return scribe.findToken(tokenType, endOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findTokenAfterNode(int tokenType, IASTNode node) {
|
private int findTokenAfterNodeOrTokenRange(int tokenType, Object nodeOrTokenRange) {
|
||||||
IASTFileLocation location = node.getFileLocation();
|
int startOffset;
|
||||||
int startOffset = location.getNodeOffset() + location.getNodeLength();
|
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);
|
return scribe.findToken(tokenType, startOffset, scribe.scannerEndPosition - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1765,7 +1765,6 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
// }
|
// }
|
||||||
//#endif
|
//#endif
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public void testMacroAsFunctionArguments_Bug253039() throws Exception {
|
public void testMacroAsFunctionArguments_Bug253039() throws Exception {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
}
|
}
|
||||||
|
@ -1901,6 +1900,33 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
assertFormatterResult();
|
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;
|
||||||
|
|
||||||
//bool member __attribute__ ((__unused__)) = false;
|
//bool member __attribute__ ((__unused__)) = false;
|
||||||
|
@ -2892,7 +2918,7 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
//void f() {
|
//void f() {
|
||||||
// if (1) {
|
// if (1) {
|
||||||
// }
|
// }
|
||||||
// IF(1>0);
|
// IF(1 > 0);
|
||||||
//}
|
//}
|
||||||
public void testMacroAfterCompoundStatement_Bug356690() throws Exception {
|
public void testMacroAfterCompoundStatement_Bug356690() throws Exception {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -96,8 +96,8 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
|
||||||
fCFile= null;
|
fCFile= null;
|
||||||
super.tearDown();
|
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()) {
|
if (CTestPlugin.getDefault().isDebugging()) {
|
||||||
System.out.println("\n\n\n\n\nTesting "+this.getClass().getName());
|
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();
|
long endTime= System.currentTimeMillis();
|
||||||
assertTrue(results != null);
|
assertTrue(results != null);
|
||||||
|
|
||||||
if(isTemplate) {
|
if (filterResults) {
|
||||||
results= filterResultsKeepTemplates(results);
|
if (isTemplate) {
|
||||||
} else {
|
results= filterResultsKeepTemplates(results);
|
||||||
results= filterResults(results, isCode);
|
} else {
|
||||||
|
results= filterResults(results, isCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
String[] resultStrings= toStringArray(results, compareType);
|
String[] resultStrings= toStringArray(results, compareType);
|
||||||
Arrays.sort(expected);
|
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 {
|
protected void assertContentAssistResults(int offset, String[] expected, boolean isCompletion, int compareType) throws Exception {
|
||||||
assertContentAssistResults(offset, 0, expected, isCompletion, false, compareType);
|
assertContentAssistResults(offset, 0, expected, isCompletion, false, compareType);
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -1374,4 +1374,10 @@ public class CompletionTests extends AbstractContentAssistTest {
|
||||||
final String[] expected= { "foo;" };
|
final String[] expected= { "foo;" };
|
||||||
assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1081,11 +1081,13 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ICConfigurationDescription cfgDescription = getConfigurationDescription();
|
ICConfigurationDescription cfgDescription = getConfigurationDescription();
|
||||||
String cfgId = cfgDescription.getId();
|
if (cfgDescription != null) {
|
||||||
if (!initialProvidersByCfg.containsKey(cfgId)) {
|
String cfgId = cfgDescription.getId();
|
||||||
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
|
if (!initialProvidersByCfg.containsKey(cfgId)) {
|
||||||
List<ILanguageSettingsProvider> initialProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
|
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
|
||||||
initialProvidersByCfg.put(cfgId, initialProviders);
|
List<ILanguageSettingsProvider> initialProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
|
||||||
|
initialProvidersByCfg.put(cfgId, initialProviders);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.dsf.gdb.service;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
|
@ -169,72 +170,117 @@ public class GDBBreakpoints_7_4 extends GDBBreakpoints_7_2 implements IEventList
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> finalRm) {
|
protected void addBreakpoint(
|
||||||
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
|
final IBreakpointsTargetDMContext context,
|
||||||
|
final Map<String, Object> attributes,
|
||||||
|
final DataRequestMonitor<IBreakpointDMContext> finalRm) {
|
||||||
|
final MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
|
||||||
if (bs != null) {
|
if (bs != null) {
|
||||||
// Skip the breakpoints set from the console or from outside of Eclipse
|
// Skip the breakpoints set from the console or from outside of Eclipse
|
||||||
// because they are already installed on the target.
|
// because they are already installed on the target.
|
||||||
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
|
bs.getTargetBreakpoint(
|
||||||
if (miBpt != null) {
|
context,
|
||||||
bs.removeCreatedTargetBreakpoint(context, miBpt);
|
attributes,
|
||||||
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
|
new DataRequestMonitor<MIBreakpoint>(getExecutor(), finalRm) {
|
||||||
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
|
@Override
|
||||||
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
|
@ConfinedToDsfExecutor( "fExecutor" )
|
||||||
finalRm.setData(dmc);
|
protected void handleSuccess() {
|
||||||
|
MIBreakpoint miBpt = getData();
|
||||||
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
|
if (miBpt != null) {
|
||||||
|
bs.removeCreatedTargetBreakpoint(context, miBpt);
|
||||||
finalRm.done();
|
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
|
||||||
return;
|
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
|
||||||
}
|
IBreakpointDMContext dmc =
|
||||||
|
new MIBreakpointDMContext(GDBBreakpoints_7_4.this, new IDMContext[] { context }, newBreakpoint.getNumber());
|
||||||
|
finalRm.setData(dmc);
|
||||||
|
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
|
||||||
|
finalRm.done();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GDBBreakpoints_7_4.super.addBreakpoint(context, attributes, finalRm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.addBreakpoint(context, attributes, finalRm);
|
||||||
}
|
}
|
||||||
super.addBreakpoint(context, attributes, finalRm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addTracepoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm) {
|
protected void addTracepoint(
|
||||||
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
|
final IBreakpointsTargetDMContext context,
|
||||||
|
final Map<String, Object> attributes,
|
||||||
|
final DataRequestMonitor<IBreakpointDMContext> drm) {
|
||||||
|
final MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
|
||||||
if (bs != null) {
|
if (bs != null) {
|
||||||
// Skip the breakpoints set from the console or from outside of Eclipse
|
// Skip the breakpoints set from the console or from outside of Eclipse
|
||||||
// because they are already installed on the target.
|
// because they are already installed on the target.
|
||||||
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
|
bs.getTargetBreakpoint(
|
||||||
if (miBpt != null) {
|
context,
|
||||||
bs.removeCreatedTargetBreakpoint(context, miBpt);
|
attributes,
|
||||||
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
|
new DataRequestMonitor<MIBreakpoint>(getExecutor(), drm) {
|
||||||
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
|
@Override
|
||||||
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
|
@ConfinedToDsfExecutor( "fExecutor" )
|
||||||
drm.setData(dmc);
|
protected void handleSuccess() {
|
||||||
|
MIBreakpoint miBpt = getData();
|
||||||
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
|
if (miBpt != null) {
|
||||||
|
bs.removeCreatedTargetBreakpoint(context, miBpt);
|
||||||
drm.done();
|
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
|
||||||
return;
|
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
|
||||||
}
|
IBreakpointDMContext dmc =
|
||||||
|
new MIBreakpointDMContext(GDBBreakpoints_7_4.this, new IDMContext[] { context }, newBreakpoint.getNumber());
|
||||||
|
drm.setData(dmc);
|
||||||
|
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GDBBreakpoints_7_4.super.addTracepoint(context, attributes, drm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.addTracepoint(context, attributes, drm);
|
||||||
}
|
}
|
||||||
super.addTracepoint(context, attributes, drm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addWatchpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm) {
|
protected void addWatchpoint(
|
||||||
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
|
final IBreakpointsTargetDMContext context,
|
||||||
|
final Map<String, Object> attributes,
|
||||||
|
final DataRequestMonitor<IBreakpointDMContext> drm) {
|
||||||
|
final MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
|
||||||
if (bs != null) {
|
if (bs != null) {
|
||||||
// Skip the breakpoints set from the console or from outside of Eclipse
|
// Skip the breakpoints set from the console or from outside of Eclipse
|
||||||
// because they are already installed on the target.
|
// because they are already installed on the target.
|
||||||
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
|
bs.getTargetBreakpoint(
|
||||||
if (miBpt != null) {
|
context,
|
||||||
bs.removeCreatedTargetBreakpoint(context, miBpt);
|
attributes,
|
||||||
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
|
new DataRequestMonitor<MIBreakpoint>(getExecutor(), drm) {
|
||||||
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
|
@Override
|
||||||
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
|
@ConfinedToDsfExecutor( "fExecutor" )
|
||||||
drm.setData(dmc);
|
protected void handleSuccess() {
|
||||||
|
MIBreakpoint miBpt = getData();
|
||||||
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
|
if (miBpt != null) {
|
||||||
|
bs.removeCreatedTargetBreakpoint(context, miBpt);
|
||||||
drm.done();
|
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
|
||||||
return;
|
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
|
||||||
}
|
IBreakpointDMContext dmc =
|
||||||
|
new MIBreakpointDMContext(GDBBreakpoints_7_4.this, new IDMContext[] { context }, newBreakpoint.getNumber());
|
||||||
|
drm.setData(dmc);
|
||||||
|
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GDBBreakpoints_7_4.super.addWatchpoint(context, attributes, drm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super.addWatchpoint(context, attributes, drm);
|
||||||
}
|
}
|
||||||
super.addWatchpoint(context, attributes, drm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -51,6 +51,8 @@ import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl2;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl2;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||||
|
@ -1727,13 +1729,15 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void runToLine(IExecutionDMContext context, String sourceFile,
|
public void runToLine(final IExecutionDMContext context, String sourceFile,
|
||||||
int lineNumber, boolean skipBreakpoints, RequestMonitor rm) {
|
final int lineNumber, final boolean skipBreakpoints, final RequestMonitor rm) {
|
||||||
|
|
||||||
// Hack around a MinGW bug; see 196154
|
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
|
||||||
sourceFile = adjustDebuggerPath(sourceFile);
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
runToLocation(context, sourceFile + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
|
runToLocation(context, getData() + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -1778,33 +1782,37 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void moveToLine(IExecutionDMContext context, String sourceFile,
|
public void moveToLine(final IExecutionDMContext context, String sourceFile,
|
||||||
int lineNumber, boolean resume, RequestMonitor rm) {
|
final int lineNumber, final boolean resume, final RequestMonitor rm) {
|
||||||
IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
|
final IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
|
||||||
if (threadExecDmc == null) {
|
if (threadExecDmc == null) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
|
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
|
||||||
sourceFile = adjustDebuggerPath(sourceFile);
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
String location = sourceFile + ":" + lineNumber; //$NON-NLS-1$
|
String debuggerPath = getData();
|
||||||
if (resume)
|
|
||||||
resumeAtLocation(context, location, rm);
|
String location = debuggerPath + ":" + lineNumber; //$NON-NLS-1$
|
||||||
else
|
if (resume) {
|
||||||
{
|
resumeAtLocation(context, location, rm);
|
||||||
// Create the breakpoint attributes
|
} else {
|
||||||
Map<String,Object> attr = new HashMap<String,Object>();
|
// Create the breakpoint attributes
|
||||||
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
|
Map<String,Object> attr = new HashMap<String,Object>();
|
||||||
attr.put(MIBreakpoints.FILE_NAME, sourceFile);
|
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
|
||||||
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
|
attr.put(MIBreakpoints.FILE_NAME, debuggerPath);
|
||||||
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
|
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
|
||||||
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
|
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
|
||||||
// Now do the operation
|
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
|
||||||
moveToLocation(context, location, attr, rm);
|
|
||||||
}
|
// Now do the operation
|
||||||
|
moveToLocation(context, location, attr, rm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1866,6 +1874,34 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Determine the path that should be sent to the debugger as per the source lookup service.
|
||||||
|
*
|
||||||
|
* @param dmc A context that can be used to obtain the sourcelookup context.
|
||||||
|
* @param hostPath The path of the file on the host, which must be converted.
|
||||||
|
* @param rm The result of the conversion.
|
||||||
|
*/
|
||||||
|
private void determineDebuggerPath(IDMContext dmc, String hostPath, final DataRequestMonitor<String> rm)
|
||||||
|
{
|
||||||
|
ISourceLookup sourceLookup = getServicesTracker().getService(ISourceLookup.class);
|
||||||
|
ISourceLookupDMContext srcDmc = DMContexts.getAncestorOfType(dmc, ISourceLookupDMContext.class);
|
||||||
|
if (sourceLookup == null || srcDmc == null) {
|
||||||
|
// Source lookup not available for given context, use the host
|
||||||
|
// path for the debugger path.
|
||||||
|
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
|
||||||
|
rm.done(adjustDebuggerPath(hostPath));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceLookup.getDebuggerPath(srcDmc, hostPath, new DataRequestMonitor<String>(getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
|
||||||
|
rm.done(adjustDebuggerPath(getData()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* See bug 196154
|
* See bug 196154
|
||||||
*
|
*
|
||||||
* @param path
|
* @param path
|
||||||
|
|
|
@ -549,7 +549,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
/**
|
/**
|
||||||
* Install a platform breakpoint on the back-end. For a given context, a
|
* Install a platform breakpoint on the back-end. For a given context, a
|
||||||
* platform breakpoint can resolve into multiple back-end breakpoints when
|
* platform breakpoint can resolve into multiple back-end breakpoints when
|
||||||
* threads are taken into account.
|
* threads are taken into account or if multiple breakpoints are created
|
||||||
|
* on the target using the console.
|
||||||
*
|
*
|
||||||
* @param dmc
|
* @param dmc
|
||||||
* @param breakpoint
|
* @param breakpoint
|
||||||
|
@ -572,13 +573,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
|
||||||
final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
|
final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
|
||||||
assert threadsIDs != null;
|
assert threadsIDs != null;
|
||||||
|
|
||||||
// Minimal validation
|
|
||||||
if (breakpointIDs.containsKey(breakpoint) || targetBPs.containsValue(breakpoint)) {
|
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, BREAKPOINT_ALREADY_INSTALLED, null));
|
|
||||||
rm.done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the breakpoint has a valid debugger source path
|
// Ensure the breakpoint has a valid debugger source path
|
||||||
if (breakpoint instanceof ICLineBreakpoint
|
if (breakpoint instanceof ICLineBreakpoint
|
||||||
&& !(breakpoint instanceof ICAddressBreakpoint)
|
&& !(breakpoint instanceof ICAddressBreakpoint)
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.eclipse.cdt.debug.core.model.ICTracepoint;
|
||||||
import org.eclipse.cdt.debug.core.model.ICWatchpoint;
|
import org.eclipse.cdt.debug.core.model.ICWatchpoint;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
|
@ -731,86 +732,126 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI
|
||||||
return DMContexts.getAncestorOfType(contContext, IBreakpointsTargetDMContext.class);
|
return DMContexts.getAncestorOfType(contContext, IBreakpointsTargetDMContext.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MIBreakpoint getTargetBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes) {
|
public void getTargetBreakpoint(
|
||||||
|
IBreakpointsTargetDMContext context,
|
||||||
|
Map<String, Object> attributes,
|
||||||
|
DataRequestMonitor<MIBreakpoint> rm) {
|
||||||
Map<Integer, MIBreakpoint> map = fCreatedTargetBreakpoints.get(context);
|
Map<Integer, MIBreakpoint> map = fCreatedTargetBreakpoints.get(context);
|
||||||
if (map == null)
|
if (map == null) {
|
||||||
return null;
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
String type = (String)attributes.get(MIBreakpoints.BREAKPOINT_TYPE);
|
String type = (String)attributes.get(MIBreakpoints.BREAKPOINT_TYPE);
|
||||||
if (MIBreakpoints.BREAKPOINT.equals(type)) {
|
if (MIBreakpoints.BREAKPOINT.equals(type)) {
|
||||||
return getTargetLineBreakpoint(
|
getTargetLineBreakpoint(
|
||||||
|
context,
|
||||||
map.values(),
|
map.values(),
|
||||||
(String)attributes.get(MIBreakpoints.FILE_NAME),
|
(String)attributes.get(MIBreakpoints.FILE_NAME),
|
||||||
(Integer)attributes.get(MIBreakpoints.LINE_NUMBER),
|
(Integer)attributes.get(MIBreakpoints.LINE_NUMBER),
|
||||||
(String)attributes.get(MIBreakpoints.FUNCTION),
|
(String)attributes.get(MIBreakpoints.FUNCTION),
|
||||||
(String)attributes.get(MIBreakpoints.ADDRESS),
|
(String)attributes.get(MIBreakpoints.ADDRESS),
|
||||||
(Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE),
|
(Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE),
|
||||||
(Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY));
|
(Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY),
|
||||||
|
rm);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (MIBreakpoints.TRACEPOINT.equals(type)) {
|
else if (MIBreakpoints.TRACEPOINT.equals(type)) {
|
||||||
return getTargetTracepoint(
|
getTargetTracepoint(
|
||||||
|
context,
|
||||||
map.values(),
|
map.values(),
|
||||||
(String)attributes.get(MIBreakpoints.FILE_NAME),
|
(String)attributes.get(MIBreakpoints.FILE_NAME),
|
||||||
(Integer)attributes.get(MIBreakpoints.LINE_NUMBER),
|
(Integer)attributes.get(MIBreakpoints.LINE_NUMBER),
|
||||||
(String)attributes.get(MIBreakpoints.FUNCTION),
|
(String)attributes.get(MIBreakpoints.FUNCTION),
|
||||||
(String)attributes.get(MIBreakpoints.ADDRESS),
|
(String)attributes.get(MIBreakpoints.ADDRESS),
|
||||||
(Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE),
|
(Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE),
|
||||||
(Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY));
|
(Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY),
|
||||||
|
rm);
|
||||||
}
|
}
|
||||||
else if (MIBreakpoints.WATCHPOINT.equals(type)) {
|
else if (MIBreakpoints.WATCHPOINT.equals(type)) {
|
||||||
return getTargetWatchpoint(
|
getTargetWatchpoint(
|
||||||
|
context,
|
||||||
map.values(),
|
map.values(),
|
||||||
(String)attributes.get(MIBreakpoints.EXPRESSION),
|
(String)attributes.get(MIBreakpoints.EXPRESSION),
|
||||||
(Boolean)attributes.get(MIBreakpoints.READ),
|
(Boolean)attributes.get(MIBreakpoints.READ),
|
||||||
(Boolean)attributes.get(MIBreakpoints.WRITE),
|
(Boolean)attributes.get(MIBreakpoints.WRITE),
|
||||||
(Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE),
|
(Boolean)attributes.get(MIBreakpointDMData.IS_HARDWARE),
|
||||||
(Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY));
|
(Boolean)attributes.get(MIBreakpointDMData.IS_TEMPORARY),
|
||||||
|
rm);
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
else {
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private MIBreakpoint getTargetLineBreakpoint(
|
private void getTargetLineBreakpoint(
|
||||||
|
IBreakpointsTargetDMContext bpTargetDMC,
|
||||||
Collection<MIBreakpoint> targetBreakpoints,
|
Collection<MIBreakpoint> targetBreakpoints,
|
||||||
String fileName,
|
String fileName,
|
||||||
Integer lineNumber,
|
Integer lineNumber,
|
||||||
String function,
|
String function,
|
||||||
String address,
|
String address,
|
||||||
Boolean isHardware,
|
Boolean isHardware,
|
||||||
Boolean isTemporary) {
|
Boolean isTemporary,
|
||||||
|
DataRequestMonitor<MIBreakpoint> drm) {
|
||||||
|
List<MIBreakpoint> candidates = new ArrayList<MIBreakpoint>(targetBreakpoints.size());
|
||||||
for (MIBreakpoint miBpt : targetBreakpoints) {
|
for (MIBreakpoint miBpt : targetBreakpoints) {
|
||||||
if (!miBpt.isWatchpoint() && !isCatchpoint(miBpt) && !miBpt.isTracepoint()
|
if (!miBpt.isWatchpoint() && !isCatchpoint(miBpt) && !miBpt.isTracepoint()) {
|
||||||
&& compareBreakpointAttributes(
|
// Filter out target breakpoints with different file names and line numbers
|
||||||
miBpt, fileName, lineNumber, function, address, isHardware, isTemporary))
|
if (fileName == null
|
||||||
return miBpt;
|
|| (new File(fileName).getName().equals(new File(getFileName(miBpt)).getName())
|
||||||
|
&& getLineNumber(miBpt) == lineNumber)) {
|
||||||
|
candidates.add(miBpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
if (candidates.size() == 0) {
|
||||||
|
drm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
findTargetLineBreakpoint(bpTargetDMC, candidates,
|
||||||
|
fileName, lineNumber, function, address, isHardware, isTemporary, drm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MIBreakpoint getTargetTracepoint(
|
private void getTargetTracepoint(
|
||||||
|
IBreakpointsTargetDMContext bpTargetDMC,
|
||||||
Collection<MIBreakpoint> targetBreakpoints,
|
Collection<MIBreakpoint> targetBreakpoints,
|
||||||
String fileName,
|
String fileName,
|
||||||
Integer lineNumber,
|
Integer lineNumber,
|
||||||
String function,
|
String function,
|
||||||
String address,
|
String address,
|
||||||
Boolean isHardware,
|
Boolean isHardware,
|
||||||
Boolean isTemporary) {
|
Boolean isTemporary,
|
||||||
|
DataRequestMonitor<MIBreakpoint> rm) {
|
||||||
|
List<MIBreakpoint> candidates = new ArrayList<MIBreakpoint>(targetBreakpoints.size());
|
||||||
for (MIBreakpoint miBpt : targetBreakpoints) {
|
for (MIBreakpoint miBpt : targetBreakpoints) {
|
||||||
if (miBpt.isTracepoint()
|
if (miBpt.isTracepoint()) {
|
||||||
&& compareBreakpointAttributes(
|
// Filter out target breakpoints with different file names and line numbers
|
||||||
miBpt, fileName, lineNumber, function, address, isHardware, isTemporary))
|
if (new File(fileName).getName().equals(new File(getFileName(miBpt)).getName())
|
||||||
return miBpt;
|
&& miBpt.getLine() == lineNumber) {
|
||||||
|
candidates.add(miBpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
if (candidates.size() == 0) {
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
findTargetLineBreakpoint(bpTargetDMC, candidates,
|
||||||
|
fileName, lineNumber, function, address, isHardware, isTemporary, rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MIBreakpoint getTargetWatchpoint(
|
private void getTargetWatchpoint(
|
||||||
|
IBreakpointsTargetDMContext bpTargetDMC,
|
||||||
Collection<MIBreakpoint> targetBreakpoints,
|
Collection<MIBreakpoint> targetBreakpoints,
|
||||||
String expression,
|
String expression,
|
||||||
boolean readAccess,
|
boolean readAccess,
|
||||||
boolean writeAccess,
|
boolean writeAccess,
|
||||||
Boolean isHardware,
|
Boolean isHardware,
|
||||||
Boolean isTemporary) {
|
Boolean isTemporary,
|
||||||
|
DataRequestMonitor<MIBreakpoint> rm) {
|
||||||
for (MIBreakpoint miBpt : targetBreakpoints) {
|
for (MIBreakpoint miBpt : targetBreakpoints) {
|
||||||
if (!miBpt.isWatchpoint())
|
if (!miBpt.isWatchpoint())
|
||||||
continue;
|
continue;
|
||||||
|
@ -824,25 +865,92 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI
|
||||||
continue;
|
continue;
|
||||||
if (!compareBreakpointTypeAttributes(miBpt, isHardware, isTemporary))
|
if (!compareBreakpointTypeAttributes(miBpt, isHardware, isTemporary))
|
||||||
continue;
|
continue;
|
||||||
return miBpt;
|
rm.setData(miBpt);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return null;
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findTargetLineBreakpoint(
|
||||||
|
final IBreakpointsTargetDMContext bpTargetDMC,
|
||||||
|
final List<MIBreakpoint> candidates,
|
||||||
|
final String fileName,
|
||||||
|
final Integer lineNumber,
|
||||||
|
final String function,
|
||||||
|
final String address,
|
||||||
|
final Boolean isHardware,
|
||||||
|
final Boolean isTemporary,
|
||||||
|
final DataRequestMonitor<MIBreakpoint> drm) {
|
||||||
|
// We need to convert the debugger paths of the candidate target breakpoints
|
||||||
|
// before comparing them with the platform breakpoint's file name.
|
||||||
|
final List<MIBreakpoint> bpts = new ArrayList<MIBreakpoint>(candidates);
|
||||||
|
|
||||||
|
class FindBreakpointRM extends ImmediateDataRequestMonitor<MIBreakpoint> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@ConfinedToDsfExecutor("fExecutor")
|
||||||
|
protected void handleCompleted() {
|
||||||
|
if (bpts.isEmpty()) {
|
||||||
|
drm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final MIBreakpoint bpt = bpts.remove(0);
|
||||||
|
final String debuggerPath = getFileName(bpt);
|
||||||
|
getSource(
|
||||||
|
bpTargetDMC,
|
||||||
|
debuggerPath,
|
||||||
|
new DataRequestMonitor<String>(getExecutor(), drm) {
|
||||||
|
@Override
|
||||||
|
@ConfinedToDsfExecutor( "fExecutor" )
|
||||||
|
protected void handleCompleted() {
|
||||||
|
// If an error occur performing source lookup
|
||||||
|
// log it and use the debugger path.
|
||||||
|
if (!isSuccess()) {
|
||||||
|
GdbPlugin.log(getStatus());
|
||||||
|
}
|
||||||
|
if (compareBreakpointAttributes(
|
||||||
|
bpt,
|
||||||
|
isSuccess() ? getData() : debuggerPath,
|
||||||
|
fileName,
|
||||||
|
lineNumber,
|
||||||
|
function,
|
||||||
|
address,
|
||||||
|
isHardware,
|
||||||
|
isTemporary)) {
|
||||||
|
// The target breakpoint is found, we're done.
|
||||||
|
drm.setData(bpt);
|
||||||
|
drm.done();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Try the next candidate
|
||||||
|
new FindBreakpointRM().done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start the search.
|
||||||
|
new FindBreakpointRM().done();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean compareBreakpointAttributes(
|
private boolean compareBreakpointAttributes(
|
||||||
MIBreakpoint miBpt,
|
MIBreakpoint miBpt,
|
||||||
|
String miBptFileName,
|
||||||
String fileName,
|
String fileName,
|
||||||
Integer lineNumber,
|
Integer lineNumber,
|
||||||
String function,
|
String function,
|
||||||
String address,
|
String address,
|
||||||
Boolean isHardware,
|
Boolean isHardware,
|
||||||
Boolean isTemporary) {
|
Boolean isTemporary) {
|
||||||
return compareBreakpointLocationAttributes(miBpt, fileName, lineNumber, function, address)
|
return compareBreakpointLocationAttributes(miBpt, miBptFileName, fileName, lineNumber, function, address)
|
||||||
&& compareBreakpointTypeAttributes(miBpt, isHardware, isTemporary);
|
&& compareBreakpointTypeAttributes(miBpt, isHardware, isTemporary);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean compareBreakpointLocationAttributes(
|
private boolean compareBreakpointLocationAttributes(
|
||||||
MIBreakpoint miBpt,
|
MIBreakpoint miBpt,
|
||||||
|
String miBptFileName,
|
||||||
String fileName,
|
String fileName,
|
||||||
Integer lineNumber,
|
Integer lineNumber,
|
||||||
String function,
|
String function,
|
||||||
|
@ -853,7 +961,7 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI
|
||||||
&& (address == null || !address.equals(getPlatformAddress(miBpt.getAddress()).toHexAddressString())))
|
&& (address == null || !address.equals(getPlatformAddress(miBpt.getAddress()).toHexAddressString())))
|
||||||
return false;
|
return false;
|
||||||
if (isLineBreakpoint(miBpt)) {
|
if (isLineBreakpoint(miBpt)) {
|
||||||
if (fileName == null || !fileName.equals(getFileName(miBpt)))
|
if (fileName == null || !fileName.equals(miBptFileName))
|
||||||
return false;
|
return false;
|
||||||
if (lineNumber == null || lineNumber.intValue() != getLineNumber(miBpt))
|
if (lineNumber == null || lineNumber.intValue() != getLineNumber(miBpt))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
||||||
import org.eclipse.cdt.core.IAddress;
|
import org.eclipse.cdt.core.IAddress;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.Immutable;
|
import org.eclipse.cdt.dsf.concurrent.Immutable;
|
||||||
|
@ -40,6 +41,8 @@ import org.eclipse.cdt.dsf.debug.service.IBreakpointsExtension.IBreakpointHitDME
|
||||||
import org.eclipse.cdt.dsf.debug.service.ICachingService;
|
import org.eclipse.cdt.dsf.debug.service.ICachingService;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.BufferedCommandControl;
|
import org.eclipse.cdt.dsf.debug.service.command.BufferedCommandControl;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
|
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
|
||||||
|
@ -1435,13 +1438,15 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void runToLine(IExecutionDMContext context, String sourceFile,
|
public void runToLine(final IExecutionDMContext context, String sourceFile,
|
||||||
int lineNumber, boolean skipBreakpoints, RequestMonitor rm) {
|
final int lineNumber, final boolean skipBreakpoints, final RequestMonitor rm) {
|
||||||
|
|
||||||
// Hack around a MinGW bug; see 196154
|
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
|
||||||
sourceFile = MIBreakpointsManager.adjustDebuggerPath(sourceFile);
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
runToLocation(context, sourceFile + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
|
runToLocation(context, getData() + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -1487,33 +1492,37 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void moveToLine(IExecutionDMContext context, String sourceFile,
|
public void moveToLine(final IExecutionDMContext context, String sourceFile,
|
||||||
int lineNumber, boolean resume, RequestMonitor rm) {
|
final int lineNumber, final boolean resume, final RequestMonitor rm) {
|
||||||
IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
|
final IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
|
||||||
if (threadExecDmc == null) {
|
if (threadExecDmc == null) {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
|
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
|
||||||
sourceFile = MIBreakpointsManager.adjustDebuggerPath(sourceFile);
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
String location = sourceFile + ":" + lineNumber; //$NON-NLS-1$
|
String debuggerPath = getData();
|
||||||
if (resume)
|
|
||||||
resumeAtLocation(context, location, rm);
|
String location = debuggerPath + ":" + lineNumber; //$NON-NLS-1$
|
||||||
else {
|
if (resume) {
|
||||||
// Create the breakpoint attributes
|
resumeAtLocation(context, location, rm);
|
||||||
Map<String,Object> attr = new HashMap<String,Object>();
|
} else {
|
||||||
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
|
// Create the breakpoint attributes
|
||||||
attr.put(MIBreakpoints.FILE_NAME, sourceFile);
|
Map<String,Object> attr = new HashMap<String,Object>();
|
||||||
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
|
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
|
||||||
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
|
attr.put(MIBreakpoints.FILE_NAME, debuggerPath);
|
||||||
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
|
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
|
||||||
|
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
|
||||||
// Now do the operation
|
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
|
||||||
moveToLocation(context, location, attr, rm);
|
|
||||||
}
|
// Now do the operation
|
||||||
|
moveToLocation(context, location, attr, rm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1578,4 +1587,32 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
|
||||||
// we know GDB is accepting commands
|
// we know GDB is accepting commands
|
||||||
return !fTerminated && fSuspended && !fResumePending;
|
return !fTerminated && fSuspended && !fResumePending;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the path that should be sent to the debugger as per the source lookup service.
|
||||||
|
*
|
||||||
|
* @param dmc A context that can be used to obtain the sourcelookup context.
|
||||||
|
* @param hostPath The path of the file on the host, which must be converted.
|
||||||
|
* @param rm The result of the conversion.
|
||||||
|
*/
|
||||||
|
private void determineDebuggerPath(IDMContext dmc, String hostPath, final DataRequestMonitor<String> rm)
|
||||||
|
{
|
||||||
|
ISourceLookup sourceLookup = getServicesTracker().getService(ISourceLookup.class);
|
||||||
|
ISourceLookupDMContext srcDmc = DMContexts.getAncestorOfType(dmc, ISourceLookupDMContext.class);
|
||||||
|
if (sourceLookup == null || srcDmc == null) {
|
||||||
|
// Source lookup not available for given context, use the host
|
||||||
|
// path for the debugger path.
|
||||||
|
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
|
||||||
|
rm.done(MIBreakpointsManager.adjustDebuggerPath(hostPath));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceLookup.getDebuggerPath(srcDmc, hostPath, new DataRequestMonitor<String>(getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
|
||||||
|
rm.done(MIBreakpointsManager.adjustDebuggerPath(getData()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,7 @@ abstract public class Sequence extends DsfRunnable implements Future<Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If sequence was cencelled during last step (or before the sequence
|
* If sequence was cancelled during last step (or before the sequence
|
||||||
* was ever executed), start rolling back the execution.
|
* was ever executed), start rolling back the execution.
|
||||||
*/
|
*/
|
||||||
if (isCancelled()) {
|
if (isCancelled()) {
|
||||||
|
|
|
@ -268,8 +268,10 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
|
||||||
* the model provider.
|
* the model provider.
|
||||||
*/
|
*/
|
||||||
fModel = factory.createModelProxy(block, context);
|
fModel = factory.createModelProxy(block, context);
|
||||||
fModel.installed(null);
|
if ( fModel != null ) {
|
||||||
fModel.addModelChangedListener(TraditionalRendering.this);
|
fModel.installed(null);
|
||||||
|
fModel.addModelChangedListener(TraditionalRendering.this);
|
||||||
|
}
|
||||||
|
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,9 +72,13 @@ public class SRecordExporter implements IMemoryExporter
|
||||||
fProperties.put(TRANSFER_START, fStartText.getText());
|
fProperties.put(TRANSFER_START, fStartText.getText());
|
||||||
fProperties.put(TRANSFER_END, fEndText.getText());
|
fProperties.put(TRANSFER_END, fEndText.getText());
|
||||||
|
|
||||||
fStartAddress = getStartAddress();
|
try
|
||||||
fEndAddress = getEndAddress();
|
{
|
||||||
fOutputFile = getFile();
|
fStartAddress = getStartAddress();
|
||||||
|
fEndAddress = getEndAddress();
|
||||||
|
fOutputFile = getFile();
|
||||||
|
}
|
||||||
|
catch(Exception e) {}
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
@ -157,11 +161,38 @@ public class SRecordExporter implements IMemoryExporter
|
||||||
|
|
||||||
textValue = fProperties.get(TRANSFER_START);
|
textValue = fProperties.get(TRANSFER_START);
|
||||||
fStartText.setText(textValue != null ? textValue : "0x0"); //$NON-NLS-1$
|
fStartText.setText(textValue != null ? textValue : "0x0"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
getStartAddress();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
fStartText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
textValue = fProperties.get(TRANSFER_END);
|
textValue = fProperties.get(TRANSFER_END);
|
||||||
fEndText.setText(textValue != null ? textValue : "0x0"); //$NON-NLS-1$
|
fEndText.setText(textValue != null ? textValue : "0x0"); //$NON-NLS-1$
|
||||||
|
|
||||||
fLengthText.setText(getEndAddress().subtract(getStartAddress()).toString());
|
try
|
||||||
|
{
|
||||||
|
getEndAddress();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fLengthText.setText(getEndAddress().subtract(getStartAddress()).toString());
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
fLengthText.setText("0");
|
||||||
|
fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
||||||
|
}
|
||||||
|
|
||||||
fileButton.addSelectionListener(new SelectionListener() {
|
fileButton.addSelectionListener(new SelectionListener() {
|
||||||
|
|
||||||
|
@ -208,7 +239,6 @@ public class SRecordExporter implements IMemoryExporter
|
||||||
{
|
{
|
||||||
fStartText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
fStartText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
||||||
validate();
|
validate();
|
||||||
//fParentDialog.setValid(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,9 +264,8 @@ public class SRecordExporter implements IMemoryExporter
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
||||||
validate();
|
validate();
|
||||||
//fParentDialog.setValid(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,9 +282,8 @@ public class SRecordExporter implements IMemoryExporter
|
||||||
String endString = "0x" + getStartAddress().add(length).toString(16); //$NON-NLS-1$
|
String endString = "0x" + getStartAddress().add(length).toString(16); //$NON-NLS-1$
|
||||||
if(!fEndText.getText().equals(endString)) {
|
if(!fEndText.getText().equals(endString)) {
|
||||||
if ( ! length.equals( BigInteger.ZERO ) ) {
|
if ( ! length.equals( BigInteger.ZERO ) ) {
|
||||||
fLengthText.setText(endString);
|
fEndText.setText(endString);
|
||||||
}
|
}
|
||||||
fEndText.setText(endString);
|
|
||||||
}
|
}
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
@ -263,7 +291,6 @@ public class SRecordExporter implements IMemoryExporter
|
||||||
{
|
{
|
||||||
fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
|
||||||
validate();
|
validate();
|
||||||
//fParentDialog.setValid(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,11 +90,15 @@ public class WinEnvironmentVariableSupplier
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current support is for Windows SDK 7.1 with Visual C++ 10.0
|
// Current support is for Windows SDK 8.0 with Visual C++ 11.0
|
||||||
// Secondary support for Windows SDK 7.0 with Visual C++ 9.0
|
// or Windows SDK 7.1 with Visual C++ 10.0
|
||||||
|
// or Windows SDK 7.0 with Visual C++ 9.0
|
||||||
private static String getSDKDir() {
|
private static String getSDKDir() {
|
||||||
WindowsRegistry reg = WindowsRegistry.getRegistry();
|
WindowsRegistry reg = WindowsRegistry.getRegistry();
|
||||||
String sdkDir = getSoftwareKey(reg, "Microsoft\\Microsoft SDKs\\Windows\\v7.1", "InstallationFolder");
|
String sdkDir = getSoftwareKey(reg, "Microsoft\\Microsoft SDKs\\Windows\\v8.0", "InstallationFolder");
|
||||||
|
if (sdkDir != null)
|
||||||
|
return sdkDir;
|
||||||
|
sdkDir = getSoftwareKey(reg, "Microsoft\\Microsoft SDKs\\Windows\\v7.1", "InstallationFolder");
|
||||||
if (sdkDir != null)
|
if (sdkDir != null)
|
||||||
return sdkDir;
|
return sdkDir;
|
||||||
return getSoftwareKey(reg, "Microsoft SDKs\\Windows\\v7.0", "InstallationFolder");
|
return getSoftwareKey(reg, "Microsoft SDKs\\Windows\\v7.0", "InstallationFolder");
|
||||||
|
@ -102,7 +106,10 @@ public class WinEnvironmentVariableSupplier
|
||||||
|
|
||||||
private static String getVCDir() {
|
private static String getVCDir() {
|
||||||
WindowsRegistry reg = WindowsRegistry.getRegistry();
|
WindowsRegistry reg = WindowsRegistry.getRegistry();
|
||||||
String vcDir = getSoftwareKey(reg, "Microsoft\\VisualStudio\\SxS\\VC7", "10.0");
|
String vcDir = getSoftwareKey(reg, "Microsoft\\VisualStudio\\SxS\\VC7", "11.0");
|
||||||
|
if (vcDir != null)
|
||||||
|
return vcDir;
|
||||||
|
vcDir = getSoftwareKey(reg, "Microsoft\\VisualStudio\\SxS\\VC7", "10.0");
|
||||||
if (vcDir != null)
|
if (vcDir != null)
|
||||||
return vcDir;
|
return vcDir;
|
||||||
return getSoftwareKey(reg, "Microsoft\\VisualStudio\\SxS\\VC7", "9.0");
|
return getSoftwareKey(reg, "Microsoft\\VisualStudio\\SxS\\VC7", "9.0");
|
||||||
|
@ -151,8 +158,10 @@ public class WinEnvironmentVariableSupplier
|
||||||
buff = new StringBuffer();
|
buff = new StringBuffer();
|
||||||
if (vcDir != null)
|
if (vcDir != null)
|
||||||
buff.append(vcDir).append("Lib;");
|
buff.append(vcDir).append("Lib;");
|
||||||
if (sdkDir != null)
|
if (sdkDir != null) {
|
||||||
buff.append(sdkDir).append("Lib;");
|
buff.append(sdkDir).append("Lib;");
|
||||||
|
buff.append(sdkDir).append("Lib\\win8\\um\\x86;");
|
||||||
|
}
|
||||||
|
|
||||||
addvar(new WindowsBuildEnvironmentVariable("LIB", buff.toString(), IBuildEnvironmentVariable.ENVVAR_PREPEND));
|
addvar(new WindowsBuildEnvironmentVariable("LIB", buff.toString(), IBuildEnvironmentVariable.ENVVAR_PREPEND));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue