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

Merge remote-tracking branch 'origin/master' into bug_45203

This commit is contained in:
Sergey Prigogin 2013-01-09 15:42:08 -08:00
commit a205a71148
50 changed files with 1127 additions and 622 deletions

View file

@ -221,7 +221,8 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser
// appending fileName to cwd should yield file path
filePath = cwd.append(fileName);
}
if (!filePath.toString().equalsIgnoreCase(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()))) {
IPath fileLocation = new Path(EFSExtensionManager.getDefault().getPathFromURI(file.getLocationURI()));
if (!filePath.toString().equalsIgnoreCase(fileLocation.toString())) {
// must be the cwd is wrong
// check if file name starts with ".."
if (fileName.startsWith("..")) { //$NON-NLS-1$
@ -238,7 +239,7 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser
tPath = tPath.removeFirstSegments(1);
}
// 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());
if (lastFileSegment.matchingFirstSegments(tPath) == tPath.segmentCount()) {
cwd = filePath.removeLastSegments(tPath.segmentCount());

View file

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

View file

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

View file

@ -15,6 +15,9 @@ import java.util.ArrayList;
import java.util.List;
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.LanguageSettingsStorage;
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.ICSettingBase;
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.IResource;
import org.eclipse.core.runtime.IPath;
@ -73,12 +77,24 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase
if (!new Path(pathStr).isAbsolute()) {
// 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
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);
ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager();
try {
// Substitute build/environment variables
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)) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Gil Barash
* Copyright (c) 2010, 2013 Gil Barash
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -116,7 +116,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
if (str.toLowerCase().contains(fNoBreakComment.toLowerCase()))
continue;
}
reportProblem(curr, prevCase);
reportProblem(curr);
}
}
}
@ -159,7 +159,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
}
}
private void reportProblem(IASTStatement curr, IASTStatement prevCase) {
private void reportProblem(IASTStatement curr) {
reportProblem(ER_ID, getProblemLocationAtEndOfNode(curr));
}
@ -218,7 +218,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
super.initPreferences(problem);
addPreference(problem, PARAM_NO_BREAK_COMMENT, CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
DEFAULT_NO_BREAK_COMMENT);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.TRUE);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.FALSE);
addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, Boolean.FALSE);
}

View file

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

View file

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

View file

@ -6938,7 +6938,70 @@ public class AST2TemplateTests extends AST2BaseTest {
// static const int value = sizeof(waldo(f));
// };
// 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();
}
}

View file

@ -7420,4 +7420,9 @@ public class AST2Tests extends AST2BaseTest {
public void testGCCDecltype_397227() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
// #define macro(R) #R""
public void testNoRawStringInPlainC_397127() throws Exception {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C, true);
}
}

View file

@ -27,10 +27,12 @@ public class LexerTests extends BaseTestCase {
private static final LexerOptions NO_DOLLAR = new LexerOptions();
private static final LexerOptions NO_MINMAX = new LexerOptions();
private static final LexerOptions SLASH_PERCENT = new LexerOptions();
private static final LexerOptions CPP_OPTIONS = new LexerOptions();
static {
NO_DOLLAR.fSupportDollarInIdentifiers= false;
NO_MINMAX.fSupportMinAndMax= false;
SLASH_PERCENT.fSupportSlashPercentComments= true;
CPP_OPTIONS.fSupportRawStringLiterals= true;
}
static String TRIGRAPH_REPLACES_CHARS= "#^[]|{}~\\";
@ -41,7 +43,7 @@ public class LexerTests extends BaseTestCase {
}
private Lexer fLexer;
private TestLexerLog fLog= new TestLexerLog();
private final TestLexerLog fLog= new TestLexerLog();
private int fLastEndOffset;
public LexerTests() {
@ -576,51 +578,51 @@ public class LexerTests extends BaseTestCase {
public void testRawStringLiteral() throws Exception {
String lit= "abc0123\\\"'.:; \\\\ \n\"(";
init("R\"(" + lit + ")\"");
init("R\"(" + lit + ")\"", CPP_OPTIONS);
rstr("", lit);
eof();
init("LR\"(" + lit + ")\"");
init("LR\"(" + lit + ")\"", CPP_OPTIONS);
wrstr("", lit);
eof();
init("u8R\"(" + lit + ")\"");
init("u8R\"(" + lit + ")\"", CPP_OPTIONS);
utf8rstr("", lit);
eof();
init("uR\"(" + lit + ")\"");
init("uR\"(" + lit + ")\"", CPP_OPTIONS);
utf16rstr("", lit);
eof();
init("UR\"(" + lit + ")\"");
init("UR\"(" + lit + ")\"", CPP_OPTIONS);
utf32rstr("", lit);
eof();
init("R\"ut");
init("R\"ut", CPP_OPTIONS);
problem(IProblem.SCANNER_UNBOUNDED_STRING, "R\"ut");
token(IToken.tSTRING, "R\"ut");
eof();
init("LR\"(ut");
init("LR\"(ut", CPP_OPTIONS);
problem(IProblem.SCANNER_UNBOUNDED_STRING, "LR\"(ut");
token(IToken.tLSTRING, "LR\"(ut");
eof();
init("uR\"p()");
init("uR\"p()", CPP_OPTIONS);
problem(IProblem.SCANNER_UNBOUNDED_STRING, "uR\"p()");
token(IToken.tUTF16STRING, "uR\"p()");
eof();
init("UR\"(ut");
init("UR\"(ut", CPP_OPTIONS);
problem(IProblem.SCANNER_UNBOUNDED_STRING, "UR\"(ut");
token(IToken.tUTF32STRING, "UR\"(ut");
eof();
init("R\"+=(Text)=+\"Text)+=\"");
init("R\"+=(Text)=+\"Text)+=\"", CPP_OPTIONS);
rstr("+=", "Text)=+\"Text");
eof();
init("UR uR LR u8R U8R\"\"");
init("UR uR LR u8R U8R\"\"", CPP_OPTIONS);
id("UR"); ws();
id("uR"); ws();
id("LR"); ws();
@ -630,7 +632,7 @@ public class LexerTests extends BaseTestCase {
}
public void testRawStringLiteralInInactiveCode() throws Exception {
init("start\n" + "inactive: Rbla\n" + "#end");
init("start\n" + "inactive: Rbla\n" + "#end", CPP_OPTIONS);
id("start");
nextDirective();
token(IToken.tPOUND);
@ -638,7 +640,7 @@ public class LexerTests extends BaseTestCase {
eof();
// 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");
nextDirective();
token(IToken.tPOUND);

View file

@ -29,8 +29,8 @@ public abstract class AbstractScannerExtensionConfiguration implements IScannerE
private CharArrayIntMap fAddPreprocessorKeywords;
protected static class MacroDefinition implements IMacro {
private char[] fSignature;
private char[] fExpansion;
private final char[] fSignature;
private final char[] fExpansion;
MacroDefinition(char[] signature, char[] expansion) {
fSignature= signature;
@ -103,6 +103,14 @@ public abstract class AbstractScannerExtensionConfiguration implements IScannerE
return false;
}
/**
* @since 5.5
*/
@Override
public boolean supportRawStringLiterals() {
return false;
}
@Override
public CharArrayIntMap getAdditionalPreprocessorKeywords() {
return fAddPreprocessorKeywords;

View file

@ -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"
*/
public boolean supportUTFLiterals();
/**
* Support for C++ raw string literals.
* @since 5.5
*/
public boolean supportRawStringLiterals();
}

View file

@ -113,4 +113,12 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
public boolean supportMinAndMaxOperators() {
return true;
}
/**
* @since 5.5
*/
@Override
public boolean supportRawStringLiterals() {
return true;
}
}

View file

@ -8,12 +8,11 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/
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.IFunction;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
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=
new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY);
public static ICPPFunction createForSample(IFunction sample) throws DOMException {
if (sample instanceof ICPPConstructor)
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
/**
* Creates a CPPDeferredFunction given a set of overloaded functions
* (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();
return new CPPDeferredFunction(owner, sample.getNameCharArray());
final IBinding owner = candidates[0].getOwner();
return new CPPDeferredFunction(owner, candidates[0].getNameCharArray(), candidates);
}
private final IBinding fOwner;
private final ICPPFunction[] fCandidates;
public CPPDeferredFunction(IBinding owner, char[] name) {
public CPPDeferredFunction(IBinding owner, char[] name, ICPPFunction[] candidates) {
super(name);
fOwner= owner;
fCandidates = candidates;
}
public ICPPFunction[] getCandidates() {
return fCandidates;
}
@Override

View file

@ -8,11 +8,13 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Thomas Corbat (IFS)
* Nathan Ridge
*******************************************************************************/
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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
/**
* 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 CPPUnknownConstructor(ICPPClassType owner) {
super(owner, owner.getNameCharArray());
super(owner, owner.getNameCharArray(), null);
}
public CPPUnknownConstructor(ICPPClassType owner, ICPPFunction[] candidates) {
super(owner, owner.getNameCharArray(), candidates);
}
@Override

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2012 IBM Corporation and others.
* Copyright (c) 2002, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -2057,7 +2057,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
List<ICPPASTTemplateParameter> parms= outerTemplateParameterList();
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
if (LT(1) != IToken.tEOC) {
consume(IToken.tGT, IToken.tGT_in_SHIFTR);
}
IASTDeclaration d = declaration(option);
ICPPASTTemplateDeclaration templateDecl = nodeFactory.newTemplateDeclaration(d);
setRange(templateDecl, offset, calculateEndOffset(d));

View file

@ -240,7 +240,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
try {
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point);
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point, false);
} catch (DOMException e) {
CCorePlugin.log(e);
}

View file

@ -92,7 +92,7 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding {
public void setToUnknown() {
if (fName != null) {
fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray()));
fName.setBinding(new CPPDeferredFunction(null, fName.toCharArray(), fBindings));
}
}
}

View file

@ -13,6 +13,7 @@
* Sergey Prigogin (Google)
* Mike Kucera (IBM)
* Thomas Corbat (IFS)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -451,7 +452,7 @@ public class CPPSemantics {
final ASTNodeProperty namePropertyInParent = name.getPropertyInParent();
if (binding == null && data.skippedScope != null) {
if (data.hasFunctionArguments()) {
binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID());
binding= new CPPDeferredFunction(data.skippedScope, name.getSimpleID(), null);
} else {
if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) {
binding= new CPPUnknownMemberClass(data.skippedScope, name.getSimpleID());
@ -2395,7 +2396,7 @@ public class CPPSemantics {
if (viableCount == 1)
return fns[0];
setTargetedFunctionsToUnknown(argTypes);
return CPPDeferredFunction.createForSample(fns[0]);
return CPPDeferredFunction.createForCandidates(fns);
}
IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good
@ -2403,7 +2404,7 @@ public class CPPSemantics {
// Loop over all functions
List<FunctionCost> potentialCosts= null;
IFunction unknownFunction= null;
ICPPFunction unknownFunction= null;
final CPPASTTranslationUnit tu = data.getTranslationUnit();
for (ICPPFunction fn : fns) {
if (fn == null)
@ -2455,7 +2456,7 @@ public class CPPSemantics {
return null;
setTargetedFunctionsToUnknown(argTypes);
return CPPDeferredFunction.createForSample(unknownFunction);
return CPPDeferredFunction.createForCandidates(fns);
}
if (ambiguousFunctions != null) {

View file

@ -11,6 +11,7 @@
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
* Nathan Ridge
*******************************************************************************/
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_FAIL = -2;
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 }
/**
@ -789,7 +789,7 @@ public class CPPTemplates {
ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
ICPPTemplateArgument[] args = pspec.getTemplateArguments();
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);
} 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,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point)
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within,
IASTNode point, boolean strict)
throws DOMException {
// Don't create a new array until it's really needed.
ICPPTemplateArgument[] result = args;
@ -1066,11 +1071,19 @@ public class CPPTemplates {
} else if (packSize == PACK_SIZE_DEFER) {
newArg= origArg;
} else {
final int shift = packSize - 1;
int shift = packSize - 1;
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i + resultShift);
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;
resultShift += shift;
@ -1078,7 +1091,13 @@ public class CPPTemplates {
}
} else {
newArg = instantiateArgument(origArg, tpMap, packOffset, within, point);
if (!isValidArgument(newArg)) {
if (strict)
return null;
newArg = origArg;
}
}
if (result != args) {
result[i + resultShift]= newArg;
} else if (newArg != origArg) {
@ -1122,12 +1141,15 @@ public class CPPTemplates {
for (Integer key : positions) {
ICPPTemplateArgument arg = orig.getArgument(key);
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 {
ICPPTemplateArgument[] args = orig.getPackExpansion(key);
if (args != null) {
try {
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point));
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point, false));
} catch (DOMException e) {
newMap.put(key, args);
}
@ -1211,7 +1233,7 @@ public class CPPTemplates {
final IBinding origClass = classInstance.getSpecializedBinding();
if (origClass instanceof ICPPClassType) {
ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point);
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point, false);
if (newArgs != args) {
CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within, point);
return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args);
@ -1728,18 +1750,12 @@ public class CPPTemplates {
requireTemplate= false;
if (func instanceof ICPPFunctionTemplate) {
ICPPFunctionTemplate template= (ICPPFunctionTemplate) func;
try {
if (containsDependentType(fnArgs))
return new ICPPFunction[] {CPPDeferredFunction.createForSample(template)};
if (containsDependentType(fnArgs))
return new ICPPFunction[] {CPPDeferredFunction.createForCandidates(fns)};
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;
break;
}
@ -1805,15 +1821,11 @@ public class CPPTemplates {
// Extract template arguments and parameter types.
if (!checkedForDependentType) {
try {
if (isDependentType(conversionType)) {
inst= CPPDeferredFunction.createForSample(template);
done= true;
}
checkedForDependentType= true;
} catch (DOMException e) {
return functions;
if (isDependentType(conversionType)) {
inst= CPPDeferredFunction.createForCandidates(functions);
done= true;
}
checkedForDependentType= true;
}
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
try {
@ -1871,7 +1883,7 @@ public class CPPTemplates {
ICPPTemplateArgument[] args, IASTNode point) {
try {
if (target != null && isDependentType(target)) {
return CPPDeferredFunction.createForSample(template);
return CPPDeferredFunction.createForCandidates(template);
}
if (template instanceof ICPPConstructor || args == null)
@ -2061,12 +2073,7 @@ public class CPPTemplates {
private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args,
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
args = instantiateArguments(args, tpMap, -1, null, point);
for (ICPPTemplateArgument arg : args) {
if (!isValidArgument(arg))
return false;
}
return true;
return instantiateArguments(args, tpMap, -1, null, point, true) != null;
}
/**
@ -2124,7 +2131,7 @@ public class CPPTemplates {
args[i]= 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
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
@ -2468,7 +2475,7 @@ public class CPPTemplates {
if (unknown instanceof ICPPUnknownMemberClassInstance) {
ICPPUnknownMemberClassInstance ucli= (ICPPUnknownMemberClassInstance) unknown;
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)) {
args1= SemanticUtil.getSimplifiedArguments(args1);
result= new CPPUnknownClassInstance(ot1, ucli.getNameCharArray(), args1);
@ -2486,7 +2493,7 @@ public class CPPTemplates {
result= CPPSemantics.resolveUnknownName(s, unknown, point);
if (unknown instanceof ICPPUnknownMemberClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] args1 = instantiateArguments(
((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point);
((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point, false);
if (result instanceof ICPPClassTemplate) {
result = instantiate((ICPPClassTemplate) result, args1, point);
}
@ -2505,7 +2512,7 @@ public class CPPTemplates {
ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
ICPPTemplateArgument[] newArgs;
try {
newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point);
newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point, false);
} catch (DOMException e) {
return e.getProblem();
}

View file

@ -11,6 +11,7 @@
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -2017,11 +2018,13 @@ public class CPPVisitor extends ASTQueries {
IBinding b= implicits[0].getBinding();
CPPASTName name= new CPPASTName();
name.setBinding(b);
IASTInitializerClause[] beginCallArguments = new IASTInitializerClause[] { forInit.copy() };
if (b instanceof ICPPMethod && forInit instanceof IASTExpression) {
beginExpr= new CPPASTFunctionCallExpression(
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS);
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()),
beginCallArguments);
} else {
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), beginCallArguments);
}
} else {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);

View file

@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -362,6 +363,13 @@ public class EvalBinding extends CPPEvaluation {
binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
binding, point);
}
} else if (binding instanceof ICPPParameter) {
ICPPParameter parameter = (ICPPParameter) binding;
IType originalType = parameter.getType();
IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point);
if (originalType != type) {
return new EvalFixed(type, ValueCategory.LVALUE, Value.create(this));
}
}
if (binding == fBinding)
return this;

View file

@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -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.IValue;
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.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
@ -145,12 +147,16 @@ public class EvalFunctionSet extends CPPEvaluation {
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments();
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 owner = originalOwner;
if (originalOwner instanceof ICPPUnknownBinding) {
if (owner instanceof ICPPUnknownBinding) {
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) {
IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
if (type instanceof IBinding)

View file

@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -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.ITypeMarshalBuffer;
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.ICPPUnknownBinding;
import org.eclipse.core.runtime.CoreException;
@ -184,15 +186,6 @@ public class EvalID extends CPPEvaluation {
return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr));
}
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;
final IASTName lastName = name.getLastName();
if (lastName instanceof ICPPASTTemplateId) {
@ -202,6 +195,25 @@ public class EvalID extends CPPEvaluation {
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),
name instanceof ICPPASTQualifiedName, templateArgs);
}

View file

@ -290,6 +290,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fLexOptions.fSupportMinAndMax = configuration.supportMinAndMaxOperators();
fLexOptions.fSupportSlashPercentComments= configuration.supportSlashPercentComments();
fLexOptions.fSupportUTFLiterals = configuration.supportUTFLiterals();
fLexOptions.fSupportRawStringLiterals = configuration.supportRawStringLiterals();
fLocationMap= new LocationMap(fLexOptions);
fKeywords= new CharArrayIntMap(40, -1);
fPPKeywords= new CharArrayIntMap(40, -1);

View file

@ -54,6 +54,7 @@ final public class Lexer implements ITokenSequence {
public boolean fCreateImageLocations= true;
public boolean fSupportSlashPercentComments= false;
public boolean fSupportUTFLiterals= true;
public boolean fSupportRawStringLiterals= false;
@Override
public Object clone() {
@ -73,7 +74,7 @@ final public class Lexer implements ITokenSequence {
// the input to the lexer
private final AbstractCharArray fInput;
private int fStart;
private final int fStart;
private int fLimit;
// after phase 3 (newline, trigraph, line-splice)
@ -267,12 +268,14 @@ final public class Lexer implements ITokenSequence {
case 'L':
switch(d) {
case 'R':
markPhase3();
if (nextCharPhase3() == '"') {
nextCharPhase3();
return rawStringLiteral(start, 3, IToken.tLSTRING);
if (fOptions.fSupportRawStringLiterals) {
markPhase3();
if (nextCharPhase3() == '"') {
nextCharPhase3();
return rawStringLiteral(start, 3, IToken.tLSTRING);
}
restorePhase3();
}
restorePhase3();
break;
case '"':
nextCharPhase3();
@ -288,12 +291,14 @@ final public class Lexer implements ITokenSequence {
if (fOptions.fSupportUTFLiterals) {
switch(d) {
case 'R':
markPhase3();
if (nextCharPhase3() == '"') {
nextCharPhase3();
return rawStringLiteral(start, 3, c == 'u' ? IToken.tUTF16STRING : IToken.tUTF32STRING);
if (fOptions.fSupportRawStringLiterals) {
markPhase3();
if (nextCharPhase3() == '"') {
nextCharPhase3();
return rawStringLiteral(start, 3, c == 'u' ? IToken.tUTF16STRING : IToken.tUTF32STRING);
}
restorePhase3();
}
restorePhase3();
break;
case '"':
nextCharPhase3();
@ -306,7 +311,7 @@ final public class Lexer implements ITokenSequence {
markPhase3();
switch (nextCharPhase3()) {
case 'R':
if (nextCharPhase3() == '"') {
if (fOptions.fSupportRawStringLiterals && nextCharPhase3() == '"') {
nextCharPhase3();
return rawStringLiteral(start, 4, IToken.tSTRING);
}
@ -323,7 +328,7 @@ final public class Lexer implements ITokenSequence {
return identifier(start, 1);
case 'R':
if (d == '"') {
if (fOptions.fSupportRawStringLiterals && d == '"') {
nextCharPhase3();
return rawStringLiteral(start, 2, IToken.tSTRING);
}

View file

@ -266,18 +266,16 @@ public class MacroDefinitionParser {
break loop;
case IToken.tIDENTIFIER:
if (paramList != null) {
// convert the parameters to special tokens
// Convert the parameters to special tokens.
final char[] image = candidate.getCharImage();
int idx= CharArrayUtils.indexOf(image, paramList);
if (idx >= 0) {
candidate= new TokenParameterReference(CPreprocessor.tMACRO_PARAMETER, idx, lexer.getSource(), candidate.getOffset(), candidate.getEndOffset(), paramList[idx]);
needParam= false;
}
else {
} else {
if (needParam) {
log.handleProblem(IProblem.PREPROCESSOR_MACRO_PASTING_ERROR, name, fExpansionOffset, candidate.getEndOffset());
}
else if (CharArrayUtils.equals(Keywords.cVA_ARGS, image)) {
} else if (CharArrayUtils.equals(Keywords.cVA_ARGS, image)) {
log.handleProblem(IProblem.PREPROCESSOR_INVALID_VA_ARGS, null, fExpansionOffset, candidate.getEndOffset());
}
needParam= false;

View file

@ -112,7 +112,7 @@ public class MacroExpander {
if (fLexer != null) {
t= fLexer.currentToken();
while(t.getType() == Lexer.tNEWLINE) {
while (t.getType() == Lexer.tNEWLINE) {
t= fLexer.nextToken();
}
return t.getType() == IToken.tLPAREN;
@ -271,7 +271,7 @@ public class MacroExpander {
try {
lastConsumed= parseArguments(input, (FunctionStyleMacro) macro, forbidden, argInputs, tracker);
} catch (AbortMacroExpansionException e) {
// ignore this macro expansion
// Ignore this macro expansion.
for (TokenSource argInput : argInputs) {
executeScopeMarkers(argInput, forbidden);
if (tracker != null) {
@ -342,7 +342,7 @@ public class MacroExpander {
private void executeScopeMarkers(TokenSource input, IdentityHashMap<PreprocessorMacro, PreprocessorMacro> forbidden) {
Token t= input.removeFirst();
while(t != null) {
while (t != null) {
if (t.getType() == CPreprocessor.tSCOPE_MARKER) {
((ExpansionBoundary) t).execute(forbidden);
}
@ -356,7 +356,7 @@ public class MacroExpander {
boolean protect= false;
Token l= null;
Token t= input.removeFirst();
while(t != null) {
while (t != null) {
switch (t.getType()) {
case CPreprocessor.tSCOPE_MARKER:
((ExpansionBoundary) t).execute(forbidden);
@ -418,6 +418,14 @@ public class MacroExpander {
return result;
}
private void addImageLocationInfo(int offset, Token t) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
}
private ImageLocationInfo createImageLocationInfo(Token t) {
if (fLocationMap != null) {
final Object s= t.fSource;
@ -460,7 +468,7 @@ public class MacroExpander {
throws OffsetLimitReachedException, AbortMacroExpansionException {
final int argCount= macro.getParameterPlaceholderList().length;
final boolean hasVarargs= macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS;
final int requiredArgs= hasVarargs ? argCount-1 : argCount;
final int requiredArgs= hasVarargs ? argCount - 1 : argCount;
int idx= 0;
int nesting= -1;
for (int i = 0; i < result.length; i++) {
@ -514,7 +522,7 @@ public class MacroExpander {
continue loop;
case IToken.tLPAREN:
// the first one sets nesting to zero.
// The first one sets nesting to zero.
if (++nesting == 0) {
continue;
}
@ -530,7 +538,7 @@ public class MacroExpander {
case IToken.tCOMMA:
assert nesting >= 0;
if (nesting == 0) {
if (idx < argCount-1) { // next argument
if (idx < argCount - 1) { // Next argument.
isFirstOfArg= true;
spaceMarkers.clear();
idx++;
@ -592,7 +600,7 @@ public class MacroExpander {
Token l= null;
Token n;
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();
switch (t.getType()) {
@ -715,7 +723,7 @@ public class MacroExpander {
idx= ((TokenParameterReference) nn).getIndex();
// check for gcc-extension preventing the paste operation
if (idx == args.length-1 && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
if (idx == args.length - 1 && macro.hasVarArgs() != FunctionStyleMacro.NO_VAARGS &&
!isKind(nn.getNext(), IToken.tPOUNDPOUND)) {
final Token nnn= (Token) nn.getNext();
TokenList arg= clone(expandedArgs[idx]);
@ -950,20 +958,12 @@ public class MacroExpander {
case CPreprocessor.tEXPANDED_IDENTIFIER:
t.setType(IToken.tIDENTIFIER);
if (createImageLocations) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
addImageLocationInfo(offset, t);
}
break;
case IToken.tIDENTIFIER:
if (createImageLocations) {
ImageLocationInfo info= createImageLocationInfo(t);
if (info != null) {
info.fTokenOffsetInExpansion= offset;
fImageLocationInfos.add(info);
}
addImageLocationInfo(offset, t);
}
break;
@ -978,6 +978,12 @@ public class MacroExpander {
t.setOffset(offset, offset + t.getLength());
t.setNext(null);
return;
default:
if (createImageLocations && t.fSource instanceof CPreprocessor) {
addImageLocationInfo(offset, t);
}
break;
}
t.setOffset(offset, ++offset);
l= t;

View file

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

View file

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

View file

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

View file

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

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
@ -147,7 +147,6 @@ public class TokenUtil {
}
}
/**
* Returns the last token in the given token list.
* @throws NullPointerException if the argument is null
@ -156,8 +155,7 @@ public class TokenUtil {
IToken last;
do {
last = tokenList;
} while((tokenList = tokenList.getNext()) != null);
} while ((tokenList = tokenList.getNext()) != null);
return last;
}
}

View file

@ -214,7 +214,7 @@ public final class TypeMarshalBuffer implements ITypeMarshalBuffer {
fPos--;
IType type = unmarshalType();
IType originalType = unmarshalType();
if (originalType == null)
if (originalType == null || originalType == UNSTORABLE_TYPE_PROBLEM)
originalType= type;
return new CPPTemplateTypeArgument(type, originalType);
}

View file

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

View file

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

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2012 IBM Corporation and others.
* Copyright (c) 2004, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -97,7 +97,7 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
super.tearDown();
}
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, int compareType) throws Exception {
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, boolean filterResults, int compareType) throws Exception {
if (CTestPlugin.getDefault().isDebugging()) {
System.out.println("\n\n\n\n\nTesting "+this.getClass().getName());
}
@ -116,10 +116,12 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
long endTime= System.currentTimeMillis();
assertTrue(results != null);
if(isTemplate) {
results= filterResultsKeepTemplates(results);
} else {
results= filterResults(results, isCode);
if (filterResults) {
if (isTemplate) {
results= filterResultsKeepTemplates(results);
} else {
results= filterResults(results, isCode);
}
}
String[] resultStrings= toStringArray(results, compareType);
Arrays.sort(expected);
@ -161,6 +163,10 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
}
protected void assertContentAssistResults(int offset, int length, String[] expected, boolean isCompletion, boolean isTemplate, int compareType) throws Exception {
assertContentAssistResults(offset, length, expected, isCompletion, isTemplate, true, compareType);
}
protected void assertContentAssistResults(int offset, String[] expected, boolean isCompletion, int compareType) throws Exception {
assertContentAssistResults(offset, 0, expected, isCompletion, false, compareType);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2012 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2013 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -1374,4 +1374,10 @@ public class CompletionTests extends AbstractContentAssistTest {
final String[] expected= { "foo;" };
assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS);
}
// template <typen/*cursor*/
public void testTemplateDeclaration_Bug397288() throws Exception {
final String[] expected= { "typename" };
assertContentAssistResults(fCursorOffset, 0, expected, true, false, false, COMPARE_REP_STRINGS);
}
}

View file

@ -1081,11 +1081,13 @@ public class LanguageSettingsProviderTab extends AbstractCPropertyTab {
return;
ICConfigurationDescription cfgDescription = getConfigurationDescription();
String cfgId = cfgDescription.getId();
if (!initialProvidersByCfg.containsKey(cfgId)) {
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
List<ILanguageSettingsProvider> initialProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
initialProvidersByCfg.put(cfgId, initialProviders);
if (cfgDescription != null) {
String cfgId = cfgDescription.getId();
if (!initialProvidersByCfg.containsKey(cfgId)) {
if (cfgDescription instanceof ILanguageSettingsProvidersKeeper) {
List<ILanguageSettingsProvider> initialProviders = ((ILanguageSettingsProvidersKeeper) cfgDescription).getLanguageSettingProviders();
initialProvidersByCfg.put(cfgId, initialProviders);
}
}
}

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.dsf.gdb.service;
import java.util.Hashtable;
import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
@ -169,72 +170,117 @@ public class GDBBreakpoints_7_4 extends GDBBreakpoints_7_2 implements IEventList
}
@Override
protected void addBreakpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> finalRm) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
protected void addBreakpoint(
final IBreakpointsTargetDMContext context,
final Map<String, Object> attributes,
final DataRequestMonitor<IBreakpointDMContext> finalRm) {
final MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
// Skip the breakpoints set from the console or from outside of Eclipse
// because they are already installed on the target.
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
finalRm.setData(dmc);
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
finalRm.done();
return;
}
bs.getTargetBreakpoint(
context,
attributes,
new DataRequestMonitor<MIBreakpoint>(getExecutor(), finalRm) {
@Override
@ConfinedToDsfExecutor( "fExecutor" )
protected void handleSuccess() {
MIBreakpoint miBpt = getData();
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
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
protected void addTracepoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
protected void addTracepoint(
final IBreakpointsTargetDMContext context,
final Map<String, Object> attributes,
final DataRequestMonitor<IBreakpointDMContext> drm) {
final MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
// Skip the breakpoints set from the console or from outside of Eclipse
// because they are already installed on the target.
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
drm.setData(dmc);
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
drm.done();
return;
}
bs.getTargetBreakpoint(
context,
attributes,
new DataRequestMonitor<MIBreakpoint>(getExecutor(), drm) {
@Override
@ConfinedToDsfExecutor( "fExecutor" )
protected void handleSuccess() {
MIBreakpoint miBpt = getData();
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
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
protected void addWatchpoint(IBreakpointsTargetDMContext context, Map<String, Object> attributes, DataRequestMonitor<IBreakpointDMContext> drm) {
MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
protected void addWatchpoint(
final IBreakpointsTargetDMContext context,
final Map<String, Object> attributes,
final DataRequestMonitor<IBreakpointDMContext> drm) {
final MIBreakpointsSynchronizer bs = getServicesTracker().getService(MIBreakpointsSynchronizer.class);
if (bs != null) {
// Skip the breakpoints set from the console or from outside of Eclipse
// because they are already installed on the target.
MIBreakpoint miBpt = bs.getTargetBreakpoint(context, attributes);
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
getBreakpointMap(context).put(newBreakpoint.getNumber(), newBreakpoint);
IBreakpointDMContext dmc = new MIBreakpointDMContext(this, new IDMContext[] { context }, newBreakpoint.getNumber());
drm.setData(dmc);
getSession().dispatchEvent(new BreakpointAddedEvent(dmc), getProperties());
drm.done();
return;
}
bs.getTargetBreakpoint(
context,
attributes,
new DataRequestMonitor<MIBreakpoint>(getExecutor(), drm) {
@Override
@ConfinedToDsfExecutor( "fExecutor" )
protected void handleSuccess() {
MIBreakpoint miBpt = getData();
if (miBpt != null) {
bs.removeCreatedTargetBreakpoint(context, miBpt);
MIBreakpointDMData newBreakpoint = new MIBreakpointDMData(miBpt);
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

View file

@ -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.IRunControl;
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.command.ICommand;
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
*/
@Override
public void runToLine(IExecutionDMContext context, String sourceFile,
int lineNumber, boolean skipBreakpoints, RequestMonitor rm) {
public void runToLine(final IExecutionDMContext context, String sourceFile,
final int lineNumber, final boolean skipBreakpoints, final RequestMonitor rm) {
// Hack around a MinGW bug; see 196154
sourceFile = adjustDebuggerPath(sourceFile);
runToLocation(context, sourceFile + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
@Override
protected void handleSuccess() {
runToLocation(context, getData() + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
}
});
}
/* (non-Javadoc)
@ -1778,33 +1782,37 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
* @since 3.0
*/
@Override
public void moveToLine(IExecutionDMContext context, String sourceFile,
int lineNumber, boolean resume, RequestMonitor rm) {
IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
public void moveToLine(final IExecutionDMContext context, String sourceFile,
final int lineNumber, final boolean resume, final RequestMonitor rm) {
final IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
if (threadExecDmc == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
rm.done();
}
else
{
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
sourceFile = adjustDebuggerPath(sourceFile);
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
@Override
protected void handleSuccess() {
String debuggerPath = getData();
String location = sourceFile + ":" + lineNumber; //$NON-NLS-1$
if (resume)
resumeAtLocation(context, location, rm);
else
{
// Create the breakpoint attributes
Map<String,Object> attr = new HashMap<String,Object>();
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
attr.put(MIBreakpoints.FILE_NAME, sourceFile);
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
// Now do the operation
moveToLocation(context, location, attr, rm);
}
String location = debuggerPath + ":" + lineNumber; //$NON-NLS-1$
if (resume) {
resumeAtLocation(context, location, rm);
} else {
// Create the breakpoint attributes
Map<String,Object> attr = new HashMap<String,Object>();
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
attr.put(MIBreakpoints.FILE_NAME, debuggerPath);
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
// 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
*
* @param path

View file

@ -549,7 +549,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
/**
* Install a platform breakpoint on the back-end. For a given context, a
* 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 breakpoint
@ -572,13 +573,6 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
final Map<ICBreakpoint, Set<String>> threadsIDs = fBreakpointThreads.get(dmc);
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
if (breakpoint instanceof ICLineBreakpoint
&& !(breakpoint instanceof ICAddressBreakpoint)

View file

@ -37,6 +37,7 @@ import org.eclipse.cdt.debug.core.model.ICTracepoint;
import org.eclipse.cdt.debug.core.model.ICWatchpoint;
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
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.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
@ -731,86 +732,126 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI
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);
if (map == null)
return null;
if (map == null) {
rm.done();
return;
}
String type = (String)attributes.get(MIBreakpoints.BREAKPOINT_TYPE);
if (MIBreakpoints.BREAKPOINT.equals(type)) {
return getTargetLineBreakpoint(
getTargetLineBreakpoint(
context,
map.values(),
(String)attributes.get(MIBreakpoints.FILE_NAME),
(Integer)attributes.get(MIBreakpoints.LINE_NUMBER),
(String)attributes.get(MIBreakpoints.FUNCTION),
(String)attributes.get(MIBreakpoints.ADDRESS),
(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)) {
return getTargetTracepoint(
getTargetTracepoint(
context,
map.values(),
(String)attributes.get(MIBreakpoints.FILE_NAME),
(Integer)attributes.get(MIBreakpoints.LINE_NUMBER),
(String)attributes.get(MIBreakpoints.FUNCTION),
(String)attributes.get(MIBreakpoints.ADDRESS),
(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)) {
return getTargetWatchpoint(
getTargetWatchpoint(
context,
map.values(),
(String)attributes.get(MIBreakpoints.EXPRESSION),
(Boolean)attributes.get(MIBreakpoints.READ),
(Boolean)attributes.get(MIBreakpoints.WRITE),
(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,
String fileName,
Integer lineNumber,
String function,
String address,
Boolean isHardware,
Boolean isTemporary) {
Boolean isTemporary,
DataRequestMonitor<MIBreakpoint> drm) {
List<MIBreakpoint> candidates = new ArrayList<MIBreakpoint>(targetBreakpoints.size());
for (MIBreakpoint miBpt : targetBreakpoints) {
if (!miBpt.isWatchpoint() && !isCatchpoint(miBpt) && !miBpt.isTracepoint()
&& compareBreakpointAttributes(
miBpt, fileName, lineNumber, function, address, isHardware, isTemporary))
return miBpt;
if (!miBpt.isWatchpoint() && !isCatchpoint(miBpt) && !miBpt.isTracepoint()) {
// Filter out target breakpoints with different file names and line numbers
if (fileName == null
|| (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,
String fileName,
Integer lineNumber,
String function,
String address,
Boolean isHardware,
Boolean isTemporary) {
Boolean isTemporary,
DataRequestMonitor<MIBreakpoint> rm) {
List<MIBreakpoint> candidates = new ArrayList<MIBreakpoint>(targetBreakpoints.size());
for (MIBreakpoint miBpt : targetBreakpoints) {
if (miBpt.isTracepoint()
&& compareBreakpointAttributes(
miBpt, fileName, lineNumber, function, address, isHardware, isTemporary))
return miBpt;
if (miBpt.isTracepoint()) {
// Filter out target breakpoints with different file names and line numbers
if (new File(fileName).getName().equals(new File(getFileName(miBpt)).getName())
&& 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,
String expression,
boolean readAccess,
boolean writeAccess,
Boolean isHardware,
Boolean isTemporary) {
Boolean isTemporary,
DataRequestMonitor<MIBreakpoint> rm) {
for (MIBreakpoint miBpt : targetBreakpoints) {
if (!miBpt.isWatchpoint())
continue;
@ -824,25 +865,92 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI
continue;
if (!compareBreakpointTypeAttributes(miBpt, isHardware, isTemporary))
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(
MIBreakpoint miBpt,
String miBptFileName,
String fileName,
Integer lineNumber,
String function,
String address,
Boolean isHardware,
Boolean isTemporary) {
return compareBreakpointLocationAttributes(miBpt, fileName, lineNumber, function, address)
return compareBreakpointLocationAttributes(miBpt, miBptFileName, fileName, lineNumber, function, address)
&& compareBreakpointTypeAttributes(miBpt, isHardware, isTemporary);
}
private boolean compareBreakpointLocationAttributes(
MIBreakpoint miBpt,
String miBptFileName,
String fileName,
Integer lineNumber,
String function,
@ -853,7 +961,7 @@ public class MIBreakpointsSynchronizer extends AbstractDsfService implements IMI
&& (address == null || !address.equals(getPlatformAddress(miBpt.getAddress()).toHexAddressString())))
return false;
if (isLineBreakpoint(miBpt)) {
if (fileName == null || !fileName.equals(getFileName(miBpt)))
if (fileName == null || !fileName.equals(miBptFileName))
return false;
if (lineNumber == null || lineNumber.intValue() != getLineNumber(miBpt))
return false;

View file

@ -21,6 +21,7 @@ import java.util.Map;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
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.ImmediateRequestMonitor;
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.IDisassembly.IDisassemblyDMContext;
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.command.BufferedCommandControl;
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
@ -1435,13 +1438,15 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
* @since 3.0
*/
@Override
public void runToLine(IExecutionDMContext context, String sourceFile,
int lineNumber, boolean skipBreakpoints, RequestMonitor rm) {
public void runToLine(final IExecutionDMContext context, String sourceFile,
final int lineNumber, final boolean skipBreakpoints, final RequestMonitor rm) {
// Hack around a MinGW bug; see 196154
sourceFile = MIBreakpointsManager.adjustDebuggerPath(sourceFile);
runToLocation(context, sourceFile + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
@Override
protected void handleSuccess() {
runToLocation(context, getData() + ":" + Integer.toString(lineNumber), skipBreakpoints, rm); //$NON-NLS-1$
}
});
}
/* (non-Javadoc)
@ -1487,33 +1492,37 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
* @since 3.0
*/
@Override
public void moveToLine(IExecutionDMContext context, String sourceFile,
int lineNumber, boolean resume, RequestMonitor rm) {
IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
public void moveToLine(final IExecutionDMContext context, String sourceFile,
final int lineNumber, final boolean resume, final RequestMonitor rm) {
final IMIExecutionDMContext threadExecDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
if (threadExecDmc == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Invalid thread context", null)); //$NON-NLS-1$
rm.done();
}
else
{
// Hack around a MinGW bug; see 369622 (and also 196154 and 232415)
sourceFile = MIBreakpointsManager.adjustDebuggerPath(sourceFile);
determineDebuggerPath(context, sourceFile, new ImmediateDataRequestMonitor<String>(rm) {
@Override
protected void handleSuccess() {
String debuggerPath = getData();
String location = sourceFile + ":" + lineNumber; //$NON-NLS-1$
if (resume)
resumeAtLocation(context, location, rm);
else {
// Create the breakpoint attributes
Map<String,Object> attr = new HashMap<String,Object>();
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
attr.put(MIBreakpoints.FILE_NAME, sourceFile);
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
String location = debuggerPath + ":" + lineNumber; //$NON-NLS-1$
if (resume) {
resumeAtLocation(context, location, rm);
} else {
// Create the breakpoint attributes
Map<String,Object> attr = new HashMap<String,Object>();
attr.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);
attr.put(MIBreakpoints.FILE_NAME, debuggerPath);
attr.put(MIBreakpoints.LINE_NUMBER, lineNumber);
attr.put(MIBreakpointDMData.IS_TEMPORARY, true);
attr.put(MIBreakpointDMData.THREAD_ID, Integer.toString(threadExecDmc.getThreadId()));
// Now do the operation
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
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()));
}
});
}
}

View file

@ -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.
*/
if (isCancelled()) {

View file

@ -268,8 +268,10 @@ public class TraditionalRendering extends AbstractMemoryRendering implements IRe
* the model provider.
*/
fModel = factory.createModelProxy(block, context);
fModel.installed(null);
fModel.addModelChangedListener(TraditionalRendering.this);
if ( fModel != null ) {
fModel.installed(null);
fModel.addModelChangedListener(TraditionalRendering.this);
}
}});
}

View file

@ -72,9 +72,13 @@ public class SRecordExporter implements IMemoryExporter
fProperties.put(TRANSFER_START, fStartText.getText());
fProperties.put(TRANSFER_END, fEndText.getText());
fStartAddress = getStartAddress();
fEndAddress = getEndAddress();
fOutputFile = getFile();
try
{
fStartAddress = getStartAddress();
fEndAddress = getEndAddress();
fOutputFile = getFile();
}
catch(Exception e) {}
super.dispose();
}
@ -158,10 +162,37 @@ public class SRecordExporter implements IMemoryExporter
textValue = fProperties.get(TRANSFER_START);
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);
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() {
@ -208,7 +239,6 @@ public class SRecordExporter implements IMemoryExporter
{
fStartText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
validate();
//fParentDialog.setValid(false);
}
}
@ -234,9 +264,8 @@ public class SRecordExporter implements IMemoryExporter
}
catch(Exception ex)
{
fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
fEndText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
validate();
//fParentDialog.setValid(false);
}
}
@ -253,9 +282,8 @@ public class SRecordExporter implements IMemoryExporter
String endString = "0x" + getStartAddress().add(length).toString(16); //$NON-NLS-1$
if(!fEndText.getText().equals(endString)) {
if ( ! length.equals( BigInteger.ZERO ) ) {
fLengthText.setText(endString);
fEndText.setText(endString);
}
fEndText.setText(endString);
}
validate();
}
@ -263,7 +291,6 @@ public class SRecordExporter implements IMemoryExporter
{
fLengthText.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
validate();
//fParentDialog.setValid(false);
}
}

View file

@ -90,11 +90,15 @@ public class WinEnvironmentVariableSupplier
return value;
}
// Current support is for Windows SDK 7.1 with Visual C++ 10.0
// Secondary support for Windows SDK 7.0 with Visual C++ 9.0
// Current support is for Windows SDK 8.0 with Visual C++ 11.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() {
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)
return sdkDir;
return getSoftwareKey(reg, "Microsoft SDKs\\Windows\\v7.0", "InstallationFolder");
@ -102,7 +106,10 @@ public class WinEnvironmentVariableSupplier
private static String getVCDir() {
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)
return vcDir;
return getSoftwareKey(reg, "Microsoft\\VisualStudio\\SxS\\VC7", "9.0");
@ -151,8 +158,10 @@ public class WinEnvironmentVariableSupplier
buff = new StringBuffer();
if (vcDir != null)
buff.append(vcDir).append("Lib;");
if (sdkDir != null)
if (sdkDir != null) {
buff.append(sdkDir).append("Lib;");
buff.append(sdkDir).append("Lib\\win8\\um\\x86;");
}
addvar(new WindowsBuildEnvironmentVariable("LIB", buff.toString(), IBuildEnvironmentVariable.ENVVAR_PREPEND));