diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml index d6ddcd803f3..9c859267933 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml @@ -15,6 +15,14 @@ org.eclipse.cdt.managedbuilder.core.tests eclipse-test-plugin + + + cdt.repo + file:/${basedir}/../../releng/org.eclipse.cdt.repo/target/repository + p2 + + + @@ -29,6 +37,18 @@ **/AllManagedBuildTests.* true + + + org.eclipse.platform.feature.group + 3.7.0 + p2-installable-unit + + + org.eclipse.cdt.feature.group + 8.0.0.${buildQualifier} + p2-installable-unit + + diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 804b3f7fc24..67758d824e9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -9513,4 +9513,13 @@ public class AST2CPPTests extends AST2BaseTest { assertNotSame(g1, g2); assertSame(g2, g3); } + + + // class A : A { + // }; + public void testRecursiveClassInheritance_Bug357256() throws Exception { + BindingAssertionHelper bh= getAssertionHelper(); + ICPPClassType c= bh.assertNonProblem("A", 1); + assertEquals(0, ClassTypeHelper.getPureVirtualMethods(c).length); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 478da74c6c7..e26814e4cb9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -5481,4 +5481,36 @@ public class AST2TemplateTests extends AST2BaseTest { public void testExplicitSpecializationOfForbiddenAsImplicit_356818() throws Exception { parseAndCheckBindings(); } + + // struct A { + // void f() { } + // }; + // template struct B : A { + // using A::f; + // void f(int) { } + // }; + // template struct C : B { + // using B::f; + // void f(int, int); + // }; + // + // void test() { + // B b; + // C c; + // b.f(); + // b.f(1); + // c.f(); + // c.f(1); + // c.f(1,1); + // } + public void testSpecializationOfUsingDeclaration_357293() throws Exception { + parseAndCheckBindings(); + } + + // template struct SS {}; + // template > class Cont> + // Cont f() {} + public void testReferenceToParameterOfTemplateTemplateParameter_357308() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 73aedf05974..727c98a3edc 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -1866,4 +1866,35 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa IBinding[] friends = ct.getFriends(); assertEquals(0, friends.length); // not yet supported } + + // struct A { + // void f() { } + // }; + // template struct B : A { + // using A::f; + // void f(int) { } + // }; + // template struct C : B { + // using B::f; + // void f(int, int); + // }; + // B b; + // C c; + + // #include "header.h" + // void test() { + // b.f(); + // b.f(1); + // c.f( ); + // c.f(2); + // c.f(2,1); + // } + public void testSpecializationOfUsingDeclaration_357293() throws Exception { + getBindingFromASTName("f()", 1, ICPPMethod.class); + getBindingFromASTName("f(1)", 1, ICPPMethod.class); + getBindingFromASTName("f( )", 1, ICPPMethod.class); + getBindingFromASTName("f(2)", 1, ICPPMethod.class); + getBindingFromASTName("f(2,1)", 1, ICPPMethod.class); + } + } diff --git a/core/org.eclipse.cdt.core.tests/pom.xml b/core/org.eclipse.cdt.core.tests/pom.xml index c4bd1c14f79..6bd853b6b0d 100644 --- a/core/org.eclipse.cdt.core.tests/pom.xml +++ b/core/org.eclipse.cdt.core.tests/pom.xml @@ -37,6 +37,11 @@ true + + org.eclipse.platform.feature.group + 3.7.0 + p2-installable-unit + org.eclipse.cdt.feature.group 8.0.0.${buildQualifier} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java index 86f8412761a..d807643ba55 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2011 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -159,7 +159,7 @@ public class BaseTestCase extends TestCase { if (statusLog.size() != fExpectedLoggedNonOK) { StringBuffer msg= new StringBuffer("Expected number (" + fExpectedLoggedNonOK + ") of "); - msg.append("non-OK status objects differs from actual (" + statusLog.size() + ").\n"); + msg.append("non-OK status objects in log differs from actual (" + statusLog.size() + ").\n"); Throwable cause= null; if (!statusLog.isEmpty()) { for (IStatus status : statusLog) { diff --git a/core/org.eclipse.cdt.core.tests/templateengine/org/eclipse/cdt/core/tests/templateengine/TestTemplateEngine.java b/core/org.eclipse.cdt.core.tests/templateengine/org/eclipse/cdt/core/tests/templateengine/TestTemplateEngine.java index 2753c8e53cc..9c313c66565 100644 --- a/core/org.eclipse.cdt.core.tests/templateengine/org/eclipse/cdt/core/tests/templateengine/TestTemplateEngine.java +++ b/core/org.eclipse.cdt.core.tests/templateengine/org/eclipse/cdt/core/tests/templateengine/TestTemplateEngine.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Symbian Software Limited and others. + * Copyright (c) 2007, 2011 Symbian Software Limited and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,7 +12,6 @@ package org.eclipse.cdt.core.tests.templateengine; import org.eclipse.cdt.core.templateengine.TemplateEngine; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; -import org.eclipse.ui.PlatformUI; /** * Test the functionality of TemplateEngine. @@ -50,20 +49,15 @@ public class TestTemplateEngine extends BaseTestCase { * check for non null SharedDefaults * */ - public void testSharedDefaults(){ - // when running the testcase in head-less mode, the TestExtraPagesProvider class cannot be loaded, - // which is logged. - if (!PlatformUI.isWorkbenchRunning()) { - setExpectedNumberOfLoggedNonOKStatusObjects(1); - } - assertNotNull(TemplateEngine.getSharedDefaults()); + public void testSharedDefaults() { + assertNotNull(TemplateEngine.getSharedDefaults()); } /** - * check that the instace is created once(Singleton). + * check that the instance is created once(Singleton). */ - public void testSingleton(){ - assertSame(templateEngine, TemplateEngine.getDefault()); + public void testSingleton() { + assertSame(templateEngine, TemplateEngine.getDefault()); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java index 67906826647..11faa3f8b08 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java @@ -6,18 +6,17 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Doug Schaefer (IBM) - Initial API and implementation + * Doug Schaefer (IBM) - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; /** - * The if statement including the optional else clause. + * The 'if' statement including the optional else clause. * * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ public interface IASTIfStatement extends IASTStatement { - /** * CONDITION represents the relationship between an * IASTIfStatement and its nested IASTExpression. @@ -40,14 +39,16 @@ public interface IASTIfStatement extends IASTStatement { public static final ASTNodeProperty ELSE = new ASTNodeProperty("IASTIfStatement.ELSE - IASTStatement (else) for IASTIfStatement"); //$NON-NLS-1$ /** - * Get the condition in the if statement. + * Returns the condition in the if statement. * - * @return the condition IASTExpression + * @return the condition IASTExpression. May return null if the 'if' + * statement has condition declaration instead of condition expression + * (see {@link org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement}). */ public IASTExpression getConditionExpression(); /** - * Set the condition in the if statement. + * Sets the condition in the if statement. * * @param condition * IASTExpression @@ -55,14 +56,14 @@ public interface IASTIfStatement extends IASTStatement { public void setConditionExpression(IASTExpression condition); /** - * Get the statement that is executed if the condition is true. + * Returns the statement that is executed if the condition is true. * * @return the then clause IASTStatement */ public IASTStatement getThenClause(); /** - * Set the statement that is executed if the condition is true. + * Sets the statement that is executed if the condition is true. * * @param thenClause * IASTStatement @@ -70,7 +71,7 @@ public interface IASTIfStatement extends IASTStatement { public void setThenClause(IASTStatement thenClause); /** - * Get the statement that is executed if the condition is false. This clause + * Returns the statement that is executed if the condition is false. This clause * is optional and returns null if there is none. * * @return the else clause or null IASTStatement @@ -78,7 +79,7 @@ public interface IASTIfStatement extends IASTStatement { public IASTStatement getElseClause(); /** - * Set the else clause. + * Sets the else clause. * * @param elseClause * IASTStatement diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTIfStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTIfStatement.java index 7beba63747a..b92519009d3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTIfStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTIfStatement.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * IBM - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; @@ -15,17 +15,28 @@ import org.eclipse.cdt.core.dom.ast.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IScope; /** + * The 'if' statement including the optional else clause. * * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ public interface ICPPASTIfStatement extends IASTIfStatement { - + /** + * Returns the condition declaration. The condition declaration and the condition expression are + * mutually exclusive. + * + * @return the condition declaration, or null if the 'if' statement doesn't + * have a condition declaration. + */ public IASTDeclaration getConditionDeclaration(); - public void setConditionDeclaration( IASTDeclaration d ); + + /** + * Sets the condition declaration. + */ + public void setConditionDeclaration(IASTDeclaration d); /** - * Get the implicit IScope represented by this if statement + * Returns the implicit IScope represented by this if statement * * @return IScope */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java index 099562a03d6..dc285516c86 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplatedTypeTemplateParameter.java @@ -92,6 +92,12 @@ public interface ICPPASTTemplatedTypeTemplateParameter extends ICPPASTTemplatePa */ public void setDefaultValue(IASTExpression expression); + /** + * Returns the scope that contains the template parameters of this template-template parameter. + * @since 5.4 + */ + public ICPPScope asScope(); + /** * @deprecated Use {@link #addTemplateParameter(ICPPASTTemplateParameter)}; */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java index d68d7a8cfe5..dab0e9d2ee1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplatedTypeTemplateParameter.java @@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; @@ -31,6 +32,7 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements private boolean fIsParameterPack; private IASTName fName; private IASTExpression fDefaultValue; + private CPPTemplateTemplateParameterScope fScope; public CPPASTTemplatedTypeTemplateParameter() { } @@ -156,4 +158,11 @@ public class CPPASTTemplatedTypeTemplateParameter extends ASTNode implements fDefaultValue = (IASTExpression) other; } } + + public ICPPScope asScope() { + if (fScope == null) { + fScope= new CPPTemplateTemplateParameterScope(this); + } + return fScope; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterScope.java new file mode 100644 index 00000000000..cf1e2ad30c4 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterScope.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.IName; +import org.eclipse.cdt.core.dom.ast.EScopeKind; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; + +/** + * Represents the scope of a template-template parameter. + */ +public class CPPTemplateTemplateParameterScope extends CPPScope { + + public CPPTemplateTemplateParameterScope(ICPPASTTemplatedTypeTemplateParameter parameter) { + super(parameter); + } + + public EScopeKind getKind() { + return EScopeKind.eLocal; + } + + @Override + public IName getScopeName() { + return ((ICPPASTTemplatedTypeTemplateParameter) getPhysicalNode()).getName(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java new file mode 100644 index 00000000000..3e8ebd91cea --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; + +/** + * Specialization of a typedef in the context of a class-specialization. + */ +public class CPPUsingDeclarationSpecialization extends CPPSpecialization implements ICPPUsingDeclaration { + private IBinding[] fDelegates; + + public CPPUsingDeclarationSpecialization(ICPPUsingDeclaration specialized, ICPPClassSpecialization owner, + ICPPTemplateParameterMap tpmap) { + super(specialized, owner, tpmap); + } + + public IBinding[] getDelegates() { + if (fDelegates == null) { + fDelegates= specializeDelegates(); + } + return fDelegates; + } + + private IBinding[] specializeDelegates() { + IBinding[] origDelegates= ((ICPPUsingDeclaration) getSpecializedBinding()).getDelegates(); + List result= new ArrayList(); + ICPPClassSpecialization owner= (ICPPClassSpecialization) getOwner(); + for (IBinding delegate : origDelegates) { + if (delegate instanceof ICPPUnknownBinding) { + try { + delegate= CPPTemplates.resolveUnknown((ICPPUnknownBinding) delegate, + owner.getTemplateParameterMap(), -1, null); + if (delegate instanceof CPPFunctionSet) { + for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) { + result.add(b); + } + } else if (delegate != null) { + result.add(delegate); + } + } catch (DOMException e) { + } + } else { + result.add(delegate); + } + } + return result.toArray(new IBinding[result.size()]); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index e62bdc67091..d27172e0038 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -16,7 +16,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -819,22 +818,78 @@ public class ClassTypeHelper { * template parameters. */ public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType) { - Collection> result = collectPureVirtualMethods(classType).values(); + Map> result= collectPureVirtualMethods(classType, + new HashMap>>()); + int resultArraySize = 0; - for (Set set : result) { - resultArraySize += set.size(); + for (List methods : result.values()) { + resultArraySize += methods.size(); } ICPPMethod[] resultArray = new ICPPMethod[resultArraySize]; int resultArrayIdx = 0; - for (Set methodsSet : result) { - for (ICPPMethod method : methodsSet) { - resultArray[resultArrayIdx] = method; - ++resultArrayIdx; + for (List methods : result.values()) { + for (ICPPMethod method : methods) { + resultArray[resultArrayIdx++] = method; } } return resultArray; } + private static Map> collectPureVirtualMethods(ICPPClassType classType, + Map>> cache) { + + Map> result = cache.get(classType); + if (result != null) + return result; + + result= new HashMap>(); + cache.put(classType, result); + + // Look at the pure virtual methods of the base classes + Set handledBaseClasses= new HashSet(); + for (ICPPBase base : classType.getBases()) { + final IBinding baseClass = base.getBaseClass(); + if (baseClass instanceof ICPPClassType && handledBaseClasses.add(baseClass)) { + Map> pureVirtuals = collectPureVirtualMethods((ICPPClassType) baseClass, cache); + // Merge derived pure virtual methods + for (String key : pureVirtuals.keySet()) { + List list = result.get(key); + if (list == null) { + list= new ArrayList(); + result.put(key, list); + } + list.addAll(pureVirtuals.get(key)); + } + } + } + + // Remove overridden pure-virtual methods and add in new pure virutals. + final ObjectSet methods = getOwnMethods(classType); + for (ICPPMethod method : methods) { + String key= getMethodNameForOverrideKey(method); + List list = result.get(key); + if (list != null) { + final ICPPFunctionType methodType = method.getType(); + for (Iterator it= list.iterator(); it.hasNext(); ) { + ICPPMethod pureVirtual = it.next(); + if (functionTypesAllowOverride(methodType, pureVirtual.getType())) { + it.remove(); + } + } + } + if (method.isPureVirtual()) { + if (list == null) { + list= new ArrayList(); + result.put(key, list); + } + list.add(method); + } else if (list != null && list.isEmpty()) { + result.remove(key); + } + } + return result; + } + private static String getMethodNameForOverrideKey(ICPPMethod method) { if (method.isDestructor()) { // Destructor's names may differ but they will override each other. @@ -843,59 +898,4 @@ public class ClassTypeHelper { return method.getName(); } } - - /** - * Returns pure virtual methods of the given class grouped by their names. - * - * @param classType The class to obtain the pure virtual method for. - * @return pure virtual methods grouped by their names. - */ - private static Map > collectPureVirtualMethods(ICPPClassType classType) { - // Collect pure virtual functions from base classes - Map> pureVirtualMethods = new HashMap>(); - for (ICPPBase base : classType.getBases()) { - if (base.getBaseClass() instanceof ICPPClassType) { - ICPPClassType baseClass = (ICPPClassType) base.getBaseClass(); - Map > derivedPureVirtualMethods = collectPureVirtualMethods(baseClass); - // Merge derived pure virtual methods - for (Map.Entry > currMethodEntry : derivedPureVirtualMethods.entrySet()) { - Set methodsSet = pureVirtualMethods.get(currMethodEntry.getKey()); - if (methodsSet == null) { - pureVirtualMethods.put(currMethodEntry.getKey(), currMethodEntry.getValue()); - } else { - methodsSet.addAll(currMethodEntry.getValue()); - } - } - } - } - - // Remove overridden methods (even if they are pure virtual) - for (ICPPMethod declaredMethod : getOwnMethods(classType)) { - Set methodsSet = pureVirtualMethods.get(getMethodNameForOverrideKey(declaredMethod)); - if (methodsSet != null) { - for (Iterator methodIt = methodsSet.iterator(); methodIt.hasNext();) { - ICPPMethod method = methodIt.next(); - if (functionTypesAllowOverride(declaredMethod.getType(), method.getType())) { - methodIt.remove(); - } - } - if (methodsSet.isEmpty()) { - pureVirtualMethods.remove(getMethodNameForOverrideKey(declaredMethod)); - } - } - } - - // Add pure virtual methods of current class - for (ICPPMethod method : classType.getDeclaredMethods()) { - if (method.isPureVirtual()) { - Set methodsSet = pureVirtualMethods.get(getMethodNameForOverrideKey(method)); - if (methodsSet == null) { - methodsSet = new HashSet(); - pureVirtualMethods.put(getMethodNameForOverrideKey(method), methodsSet); - } - methodsSet.add(method); - } - } - return pureVirtualMethods; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 6af7c70a0a8..c413f46c01d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -1426,6 +1426,15 @@ public class CPPSemantics { ASTInternal.addName(scope, enumerator.getName()); } return; + } else if (parent instanceof ICPPASTTemplatedTypeTemplateParameter) { + // The template-template parameter scope contains the parameters + for (ICPPASTTemplateParameter par : ((ICPPASTTemplatedTypeTemplateParameter) parent).getTemplateParameters()) { + IASTName name= CPPTemplates.getTemplateParameterName(par); + if (name != null) { + ASTInternal.addName(scope, name); + } + } + return; } int idx = -1; @@ -2465,7 +2474,7 @@ public class CPPSemantics { boolean haveASTResult= false; for (ICPPFunction f : fns) { // Use the ast binding - final boolean fromIndex = f instanceof IIndexBinding; + final boolean fromIndex = isFromIndex(f); if (haveASTResult && fromIndex) break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 034b816e34b..fe1e8b40d4c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -79,7 +79,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; @@ -89,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArraySet; @@ -134,6 +134,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclarationSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; @@ -597,20 +598,6 @@ public class CPPTemplates { return new CPPTemplateNonTypeParameter(ASTQueries.findInnermostDeclarator(dtor).getName()); } - static public ICPPScope getContainingScope(IASTNode node) { - while (node != null) { - if (node instanceof ICPPASTTemplateParameter) { - IASTNode parent = node.getParent(); - if (parent instanceof ICPPASTTemplateDeclaration) { - return ((ICPPASTTemplateDeclaration) parent).getScope(); - } - } - node = node.getParent(); - } - - return null; - } - public static IBinding createBinding(ICPPASTTemplateId id) { if (!isClassTemplate(id)) { //functions are instantiated as part of the resolution process @@ -794,6 +781,8 @@ public class CPPTemplates { } else if (decl instanceof IEnumeration || decl instanceof IEnumerator) { // TODO(sprigogin): Deal with a case when an enumerator value depends on a template parameter. spec = decl; + } else if (decl instanceof ICPPUsingDeclaration) { + spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap); } return spec; } @@ -2294,7 +2283,7 @@ public class CPPTemplates { /** * Attempts to (partially) resolve an unknown binding with the given arguments. */ - private static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap, + public static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) throws DOMException { if (unknown instanceof ICPPDeferredClassInstance) { return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset, within); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 323d31e342a..c074fcfc1b0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -908,7 +908,7 @@ public class CPPVisitor extends ASTQueries { if (result != null) return result; } else if (parent instanceof ICPPASTTemplateDeclaration) { - return CPPTemplates.getContainingScope(node); + return ((ICPPASTTemplateDeclaration) parent).getScope(); } } else if (node instanceof IASTInitializer) { if (node instanceof ICPPASTConstructorChainInitializer) { @@ -979,7 +979,13 @@ public class CPPVisitor extends ASTQueries { continue; } } else if (node instanceof ICPPASTTemplateParameter) { - return CPPTemplates.getContainingScope(node); + if (node instanceof ICPPASTTemplatedTypeTemplateParameter && node != inputNode) { + return ((ICPPASTTemplatedTypeTemplateParameter) node).asScope(); + } + IASTNode parent = node.getParent(); + if (parent instanceof ICPPASTTemplateDeclaration) { + return ((ICPPASTTemplateDeclaration) parent).getScope(); + } } else if (node instanceof ICPPASTBaseSpecifier) { ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) node.getParent(); IASTName n = compSpec.getName(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java index 6185ba51929..adc31d84c7b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java @@ -58,4 +58,5 @@ public interface IIndexCPPBindingConstants { int CPP_TEMPLATE_TEMPLATE_PARAMETER= IIndexBindingConstants.LAST_CONSTANT + 46; int CPP_CLASS_TEMPLATE_PARTIAL_SPEC_SPEC = IIndexBindingConstants.LAST_CONSTANT + 47; int CPP_UNKNOWN_BINDING = IIndexBindingConstants.LAST_CONSTANT + 48; + int CPP_USING_DECLARATION_SPECIALIZATION= IIndexBindingConstants.LAST_CONSTANT + 49; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index 545020408d7..86ff782071a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -293,6 +293,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { return new CompositeCPPParameterSpecialization(this, (ICPPParameter) binding); } else if (binding instanceof ITypedef) { return new CompositeCPPTypedefSpecialization(this, (ICPPBinding) binding); + } else if (binding instanceof ICPPUsingDeclaration) { + return new CompositeCPPUsingDeclarationSpecialization(this, (ICPPUsingDeclaration) binding); } else { throw new CompositingNotImplementedError("composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPUsingDeclarationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPUsingDeclarationSpecialization.java new file mode 100644 index 00000000000..401e2d9a3bb --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPUsingDeclarationSpecialization.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; +import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; + +class CompositeCPPUsingDeclarationSpecialization extends CompositeCPPUsingDeclaration implements ICPPSpecialization { + public CompositeCPPUsingDeclarationSpecialization(ICompositesFactory cf, ICPPUsingDeclaration delegate) { + super(cf, delegate); + } + + public IBinding getSpecializedBinding() { + return TemplateInstanceUtil.getSpecializedBinding(cf, rbinding); + } + + public ICPPTemplateParameterMap getTemplateParameterMap() { + IBinding owner= getOwner(); + if (owner instanceof ICPPSpecialization) { + return ((ICPPSpecialization) owner).getTemplateParameterMap(); + } + return CPPTemplateParameterMap.EMPTY; + } + + @Deprecated + public ObjectMap getArgumentMap() { + return TemplateInstanceUtil.getArgumentMap(cf, rbinding); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 79f9fecac9d..0c1d82decf1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -209,10 +209,11 @@ public class PDOM extends PlatformObject implements IPDOM { * * CDT 8.1 development (versions not supported on teh 8.0.x branch) * 120.0 - Enumerators in global index, bug 356235 + * 120.1 - Specializations of using declarations, bug 357293. */ private static final int MIN_SUPPORTED_VERSION= version(120, 0); private static final int MAX_SUPPORTED_VERSION= version(120, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(120, 0); + private static final int DEFAULT_VERSION = version(120, 1); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index 16e67f87efc..35cc42ef67b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -379,11 +379,11 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage } /** - * Usually bindings are added on behalf of a name, only. For unknown values we need to - * add further bindings. + * Usually bindings are added on behalf of a name, only. For unknown values or using declarations + * we need to add further bindings. * @throws CoreException */ - public PDOMBinding addUnknownValue(IBinding binding) throws CoreException { + public PDOMBinding addPotentiallyUnknownBinding(IBinding binding) throws CoreException { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index cad18e550a2..8b7dab40caf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -239,7 +239,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { } @Override - public PDOMBinding addUnknownValue(IBinding binding) throws CoreException { + public PDOMBinding addPotentiallyUnknownBinding(IBinding binding) throws CoreException { return addBinding(binding, null); } @@ -461,6 +461,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { result= new PDOMCPPClassSpecialization(this, parent, (ICPPClassType) special, orig); } else if (special instanceof ITypedef) { result= new PDOMCPPTypedefSpecialization(this, parent, (ITypedef) special, orig); + } else if (special instanceof ICPPUsingDeclaration) { + result= new PDOMCPPUsingDeclarationSpecialization(this, parent, (ICPPUsingDeclaration) special, orig); } return result; @@ -805,6 +807,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return new PDOMCPPClassTemplateSpecialization(this, record); case CPP_TYPEDEF_SPECIALIZATION: return new PDOMCPPTypedefSpecialization(this, record); + case CPP_USING_DECLARATION_SPECIALIZATION: + return new PDOMCPPUsingDeclarationSpecialization(this, record); } assert false : "nodeid= " + nodeType; //$NON-NLS-1$ return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUsingDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUsingDeclaration.java index 8f3aa29586d..07ceaa1c657 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUsingDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUsingDeclaration.java @@ -54,7 +54,7 @@ class PDOMCPPUsingDeclaration extends PDOMCPPBinding implements ICPPUsingDeclara Set targets= new LinkedHashSet(); PDOMCPPUsingDeclaration last= null; for (IBinding delegate : using.getDelegates()) { - PDOMBinding target = getLinkage().adaptBinding(delegate); + PDOMBinding target = getLinkage().addPotentiallyUnknownBinding(delegate); if (target != null && targets.add(target)) { if (last == null) { setTargetBinding(linkage, target); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUsingDeclarationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUsingDeclarationSpecialization.java new file mode 100644 index 00000000000..5e84e80e8a6 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUsingDeclarationSpecialization.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2011 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +class PDOMCPPUsingDeclarationSpecialization extends PDOMCPPSpecialization implements ICPPUsingDeclaration { + private static final int TARGET_BINDINGS = PDOMCPPSpecialization.RECORD_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = TARGET_BINDINGS + Database.PTR_SIZE; + + private volatile IBinding[] delegates; + + public PDOMCPPUsingDeclarationSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPUsingDeclaration using, PDOMBinding specialized) + throws CoreException { + super(linkage, parent, (ICPPSpecialization) using, specialized); + + Set targets= new LinkedHashSet(); + PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + TARGET_BINDINGS); + for (IBinding delegate : using.getDelegates()) { + PDOMBinding target = getLinkage().adaptBinding(delegate); + if (target != null && targets.add(target)) { + list.addMember(target); + } + } + } + + public PDOMCPPUsingDeclarationSpecialization(PDOMLinkage linkage, long record) { + super(linkage, record); + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_USING_DECLARATION; + } + + public IBinding[] getDelegates() { + if (delegates == null) { + PDOMNodeLinkedList list= new PDOMNodeLinkedList(getLinkage(), record+TARGET_BINDINGS); + final List result= new ArrayList(); + try { + list.accept(new IPDOMVisitor() { + public boolean visit(IPDOMNode node) { + if (node instanceof IBinding) { + result.add((IBinding) node); + } + return true; + } + public void leave(IPDOMNode node) { + } + }); + } catch (CoreException e) { + } + delegates = result.toArray(new IBinding[result.size()]); + } + return delegates; + } +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java index a5299967ae1..ff05296897e 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java @@ -114,6 +114,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; @@ -157,7 +158,7 @@ import org.eclipse.text.edits.TextEdit; * Some heuristic is applied in case of syntax errors or other problems * to skip those areas, but because of incomplete location information * the formatting may fail. The reason of the failure is logged. - * + * * @since 4.0 */ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, ICASTVisitor { @@ -827,7 +828,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, /** * Determine whether the given declarator is the first in a list of declarators (if any). - * + * * @param node the declarator node * @return true if this node is the first in a list */ @@ -1527,7 +1528,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, /** * Returns the position of the last character of a node, or -1 if that character is part of * a macro expansion. - * + * * @param node an AST node * @return the position of the last character of a node, or -1 if that character is part of * a macro expansion. @@ -1658,12 +1659,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, Runnable tailFormatter = fExpectSemicolonAfterDeclaration ? new TrailingSemicolonFormatter(node) : null; if (declarators.size() == 1) { - scribe.setTailFormatter(tailFormatter); - try { + if (tailFormatter != null) { + scribe.setTailFormatter(tailFormatter); + try { + visit(declarators.get(0)); + scribe.runTailFormatter(); + } finally { + scribe.setTailFormatter(null); + } + } else { visit(declarators.get(0)); - scribe.runTailFormatter(); - } finally { - scribe.setTailFormatter(null); } } else { final ListOptions options= new ListOptions(preferences.alignment_for_declarator_list); @@ -2047,7 +2052,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, * @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. + * the last element of the list. */ private void formatList(List elements, ListOptions options, boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) { @@ -2153,12 +2158,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } final IASTDeclaration decl= node.getDeclaration(); if (decl != null) { - fExpectSemicolonAfterDeclaration= false; - try { - decl.accept(this); - } finally { - fExpectSemicolonAfterDeclaration= true; - } + formatInlineDeclaration(decl); } else if (node.isCatchAll()) { scribe.printNextToken(Token.tELIPSE, false /* preferences.insert_space_before_ellipsis */); // if (false /* preferences.insert_space_after_ellipsis */) { @@ -2173,6 +2173,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, return PROCESS_SKIP; } + private void formatInlineDeclaration(final IASTDeclaration decl) { + fExpectSemicolonAfterDeclaration= false; + try { + decl.accept(this); + } finally { + fExpectSemicolonAfterDeclaration= true; + } + } + private int visit(IASTCompoundStatement node) { formatBlock(node, preferences.brace_position_for_block, preferences.insert_space_before_opening_brace_in_block, preferences.indent_statements_compare_to_block); return PROCESS_SKIP; @@ -2288,7 +2297,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, /** * Formats given expressions as a function call, ie. enclosed in parenthesis. - * + * * @param args the argument expressions, may be null */ private void formatFunctionCallArguments(IASTInitializerClause[] args) { @@ -2785,7 +2794,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } private boolean isOverloadedLeftShift(IASTBinaryExpression node) { - return node.getOperator() == IASTBinaryExpression.op_shiftLeft && + return node.getOperator() == IASTBinaryExpression.op_shiftLeft && node instanceof ICPPASTBinaryExpression && ((ICPPASTBinaryExpression) node).getOverload() != null; } @@ -3079,14 +3088,29 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } private int visit(IASTForStatement node) { - scribe.printNextToken(Token.t_for); - final int line = scribe.line; - scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for); - fInsideFor= true; - if (preferences.insert_space_after_opening_paren_in_for) { - scribe.space(); + if (!startsWithMacroExpansion(node)) { + scribe.printNextToken(Token.t_for); } + final int line = scribe.line; IASTStatement initializerStmt= node.getInitializerStatement(); + IASTStatement body = node.getBody(); + Runnable tailFormatter = null; + if (!doNodesHaveSameOffset(node, initializerStmt)) { + scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for); + fInsideFor= true; + if (preferences.insert_space_after_opening_paren_in_for) { + scribe.space(); + } + if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) && + body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) { + tailFormatter = new TrailingTokenFormatter(Token.tLBRACE, + body.getFileLocation().getNodeOffset(), + preferences.insert_space_before_opening_brace_in_block, false); + } + tailFormatter = new ClosingParensesisTailFormatter( + preferences.insert_space_before_closing_paren_in_for, tailFormatter); + } + initializerStmt.accept(this); if (peekNextToken() == Token.tSEMI) { scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon_in_for); @@ -3124,6 +3148,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon_in_for); } + scribe.setTailFormatter(tailFormatter); scribe.alignFragment(alignment, 1); IASTExpression iterationExpr= node.getIterationExpression(); if (iterationExpr != null) { @@ -3132,52 +3157,62 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } iterationExpr.accept(this); } + if (tailFormatter != null) { + scribe.runTailFormatter(); + scribe.setTailFormatter(null); + } } finally { fInsideFor= false; } - if (peekNextToken() == Token.tRPAREN) { - scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for); - } - IASTStatement body = node.getBody(); - if (body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) { - formatLeftCurlyBrace(line, preferences.brace_position_for_block); - if (startNode(body)) { - try { - final boolean braceOnSameLine = DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block); - if (!braceOnSameLine) { - ok = true; - scribe.exitAlignment(alignment, true); - } - formatBlockOpening((IASTCompoundStatement) body, - preferences.brace_position_for_block, - preferences.insert_space_before_opening_brace_in_block); - if (braceOnSameLine) { - ok = true; - scribe.exitAlignment(alignment, true); - } - formatOpenedBlock((IASTCompoundStatement) body, - preferences.brace_position_for_block, - preferences.indent_statements_compare_to_block); - } finally { - endOfNode(body); - } - } else { - ok = true; - scribe.exitAlignment(alignment, true); - } - } else { - ok = true; - scribe.exitAlignment(alignment, true); - formatAction(line, body, preferences.brace_position_for_block); - } + ok = true; } catch (AlignmentException e) { - if (ok) { - throw e; - } scribe.redoAlignment(e); } } while (!ok); + scribe.exitAlignment(alignment, true); + if (body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) { +// if (body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) { +// formatLeftCurlyBrace(line, preferences.brace_position_for_block); +// if (startNode(body)) { +// try { +// final boolean braceOnSameLine = DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block); +// if (!braceOnSameLine) { +// ok = true; +// scribe.exitAlignment(alignment, true); +// } +// formatBlockOpening((IASTCompoundStatement) body, +// preferences.brace_position_for_block, +// preferences.insert_space_before_opening_brace_in_block); +// if (braceOnSameLine) { +// ok = true; +// scribe.exitAlignment(alignment, true); +// } +// formatOpenedBlock((IASTCompoundStatement) body, +// preferences.brace_position_for_block, +// preferences.indent_statements_compare_to_block); +// } finally { +// endOfNode(body); +// } +// } +// } + if (startNode(body)) { + try { + if (scribe.scanner.getCurrentPosition() <= body.getFileLocation().getNodeOffset()) { + formatLeftCurlyBrace(line, preferences.brace_position_for_block); + } + formatBlock((IASTCompoundStatement) body, + preferences.brace_position_for_block, + preferences.insert_space_before_opening_brace_in_block, + preferences.indent_statements_compare_to_block); + } finally { + endOfNode(body); + } + } + } else { + formatAction(line, body, preferences.brace_position_for_block); + } + scribe.printTrailingComment(); return PROCESS_SKIP; } @@ -3210,36 +3245,53 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } private int visit(IASTIfStatement node) { - scribe.printNextToken(Token.t_if); - final int line = scribe.line; - scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_if); - if (preferences.insert_space_after_opening_paren_in_if) { - scribe.space(); + if (!startsWithMacroExpansion(node)) { + scribe.printNextToken(Token.t_if); + } + final int line = scribe.line; + IASTNode condition = node.getConditionExpression(); + if (condition == null && node instanceof ICPPASTIfStatement) { + condition = ((ICPPASTIfStatement) node).getConditionDeclaration(); } - IASTExpression condExpr= node.getConditionExpression(); final IASTStatement thenStatement = node.getThenClause(); final IASTStatement elseStatement = node.getElseClause(); - Runnable tailFormatter = null; - if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) && - thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) { - tailFormatter = new TrailingTokenFormatter(Token.tLBRACE, - thenStatement.getFileLocation().getNodeOffset(), - preferences.insert_space_before_opening_brace_in_block, false); + + fExpectSemicolonAfterDeclaration= false; + try { + if (condition == null || !doNodesHaveSameOffset(node, condition)) { + scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_if); + if (preferences.insert_space_after_opening_paren_in_if) { + scribe.space(); + } + Runnable tailFormatter = null; + if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) && + thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) { + tailFormatter = new TrailingTokenFormatter(Token.tLBRACE, + thenStatement.getFileLocation().getNodeOffset(), + preferences.insert_space_before_opening_brace_in_block, false); + } + tailFormatter = new ClosingParensesisTailFormatter( + preferences.insert_space_before_closing_paren_in_if, tailFormatter); + scribe.setTailFormatter(tailFormatter); + if (condition == null || condition instanceof IASTProblemHolder) { + scribe.skipToToken(Token.tRPAREN); + } else { + condition.accept(this); + } + scribe.runTailFormatter(); + scribe.setTailFormatter(null); + } else if (!(condition instanceof IASTProblemHolder)) { + condition.accept(this); + } + } finally { + fExpectSemicolonAfterDeclaration= true; } - tailFormatter = new ClosingParensesisTailFormatter( - preferences.insert_space_before_closing_paren_in_if, tailFormatter); - scribe.setTailFormatter(tailFormatter); - if (condExpr == null || condExpr instanceof IASTProblemExpression) { - scribe.skipToToken(Token.tRPAREN); - } else { - condExpr.accept(this); - } - scribe.runTailFormatter(); - scribe.setTailFormatter(null); boolean thenStatementIsBlock = false; if (thenStatement != null) { - if (thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) { + if (condition != null && doNodeLocationsOverlap(condition, thenStatement)) { + thenStatement.accept(this); + } else if (thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) { final IASTCompoundStatement block = (IASTCompoundStatement) thenStatement; thenStatementIsBlock = true; final List statements = Arrays.asList(block.getStatements()); @@ -3263,7 +3315,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } } } else { - if (node.getFileLocation().getNodeOffset() == thenStatement.getFileLocation().getNodeOffset()) { + if (doNodesHaveSameOffset(node, thenStatement)) { startNode(thenStatement); } if (elseStatement == null && preferences.keep_simple_if_on_one_line) { @@ -3310,34 +3362,38 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } if (elseStatement != null) { - if (peekNextToken() == Token.t_else) { - if (thenStatementIsBlock) { - scribe.printNextToken(Token.t_else, preferences.insert_space_after_closing_brace_in_block); - } else { - scribe.printNextToken(Token.t_else, true); - } - } - - if (elseStatement instanceof IASTCompoundStatement && !enclosedInMacroExpansion(elseStatement)) { - elseStatement.accept(this); - } else if (elseStatement instanceof IASTIfStatement) { - if (!preferences.compact_else_if) { - scribe.startNewLine(); - scribe.indent(); - } - scribe.space(); - elseStatement.accept(this); - if (!preferences.compact_else_if) { - scribe.unIndent(); - } - } else if (preferences.keep_else_statement_on_same_line) { - scribe.space(); + if (condition != null && doNodeLocationsOverlap(condition, elseStatement)) { elseStatement.accept(this); } else { - scribe.startNewLine(); - scribe.indent(); - elseStatement.accept(this); - scribe.unIndent(); + if (peekNextToken() == Token.t_else) { + if (thenStatementIsBlock) { + scribe.printNextToken(Token.t_else, preferences.insert_space_after_closing_brace_in_block); + } else { + scribe.printNextToken(Token.t_else, true); + } + } + + if (elseStatement instanceof IASTCompoundStatement && !enclosedInMacroExpansion(elseStatement)) { + elseStatement.accept(this); + } else if (elseStatement instanceof IASTIfStatement) { + if (!preferences.compact_else_if) { + scribe.startNewLine(); + scribe.indent(); + } + scribe.space(); + elseStatement.accept(this); + if (!preferences.compact_else_if) { + scribe.unIndent(); + } + } else if (preferences.keep_else_statement_on_same_line) { + scribe.space(); + elseStatement.accept(this); + } else { + scribe.startNewLine(); + scribe.indent(); + elseStatement.accept(this); + scribe.unIndent(); + } } } return PROCESS_SKIP; @@ -3624,7 +3680,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, scribe.indent(); } scribe.startNewLine(); - + formatClosingBrace(brace_position); } } finally { @@ -3684,9 +3740,9 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, * Test whether the next node location is inside a macro expansion. If it is * a macro expansion, formatting will be skipped until the next node outside * the expansion is reached. - * + * * @param node the AST node to be tested - * @return false if the node should be skipped + * @return false if the node should be skipped */ private boolean startNode(IASTNode node) { scribe.startNode(); @@ -3702,7 +3758,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, IASTFileLocation macroLocation = macroExpansion.getFileLocation(); IASTFileLocation nodeLocation = node.getFileLocation(); if (macroLocation.getNodeOffset() >= scribe.scanner.getCurrentPosition() && - !scribe.shouldSkip(macroLocation.getNodeOffset()) && + !scribe.shouldSkip(macroLocation.getNodeOffset()) && (nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() == macroLocation.getNodeOffset() + macroLocation.getNodeLength() || locations.length == 2 && isSemicolonLocation(locations[1])) && @@ -3729,7 +3785,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, /** * Formatting of node is complete. Undo skip region if any. - * + * * @param node */ private void endOfNode(IASTNode node) { @@ -3751,7 +3807,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, /** * Formatting of node continues after completion of a child node. Establish next skip region. - * + * * @param node */ private void continueNode(IASTNode node) { @@ -3835,7 +3891,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, /** * Format an expression nested in parenthesis. If the operand is * null, empty parenthesis are expected. - * + * * @param operand */ private void formatParenthesizedExpression(final IASTExpression operand) { @@ -3944,11 +4000,25 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, return true; } + /** + * Returns true if the two given nodes have overlapping file locations. For nodes that are + * 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(); return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() && - loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength(); + loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength(); + } + + /** + * Returns true if the two given nodes have the same offset. For nodes that are normally + * 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) { + return node1.getFileLocation().getNodeOffset() == node2.getFileLocation().getNodeOffset(); } private void formatBlock(IASTCompoundStatement block, String block_brace_position, diff --git a/core/org.eclipse.cdt.ui.tests/pom.xml b/core/org.eclipse.cdt.ui.tests/pom.xml index ad42712da88..bd0a7e91f40 100644 --- a/core/org.eclipse.cdt.ui.tests/pom.xml +++ b/core/org.eclipse.cdt.ui.tests/pom.xml @@ -15,6 +15,14 @@ org.eclipse.cdt.ui.tests eclipse-test-plugin + + + cdt.repo + file:/${basedir}/../../releng/org.eclipse.cdt.repo/target/repository + p2 + + + @@ -28,6 +36,18 @@ **/AutomatedSuite.* true + + + org.eclipse.platform.feature.group + 3.7.0 + p2-installable-unit + + + org.eclipse.cdt.feature.group + 8.0.0.${buildQualifier} + p2-installable-unit + + diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java index 98bae6602eb..ef207f78c7f 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java @@ -963,7 +963,7 @@ public class CodeFormatterTest extends BaseUITestCase { //M* A::c(M* tm) { N::iterator it = myN.find(tm); if (!it) return NULL; else return *it; } //void A::a(C e) { - // if (D::iterator it = m.find (e)) + // if (D::iterator it = m.find(e)) // m.erase(it); //} //T* A::b(T* t) { @@ -1505,6 +1505,24 @@ public class CodeFormatterTest extends BaseUITestCase { assertFormatterResult(); } + //#define BLOCK { } + //#define ALWAYS if(true) + // + //void foo() { + //ALWAYS BLOCK + //} + + //#define BLOCK { } + //#define ALWAYS if(true) + // + //void foo() { + // ALWAYS + // BLOCK + //} + public void testCompoundStatementAsMacro_Temp() throws Exception { + assertFormatterResult(); + } + //#define BLOCK { } //#define DOIT1() { } //#define DOIT2() do { } while(false) @@ -2400,6 +2418,37 @@ public class CodeFormatterTest extends BaseUITestCase { assertFormatterResult(); } + //struct Stream { + //Stream& operator <<(const char*); + //}; + //Stream GetStream(); + // + //#define MY_MACRO switch (0) case 0: default: if (bool x = false) ; else GetStream() + // + //void test() { + //MY_MACRO << "Loooooooooooooooooooong string literal" << " another literal."; + //MY_MACRO << "Looooooooooooooooooooong string literal" << " another literal."; + //} + + //struct Stream { + // Stream& operator <<(const char*); + //}; + //Stream GetStream(); + // + //#define MY_MACRO switch (0) case 0: default: if (bool x = false) ; else GetStream() + // + //void test() { + // MY_MACRO << "Loooooooooooooooooooong string literal" << " another literal."; + // MY_MACRO << "Looooooooooooooooooooong string literal" + // << " another literal."; + //} + public void testOverloadedLeftShiftChain_6() throws Exception { + fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE); + fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_OVERLOADED_LEFT_SHIFT_CHAIN, + Integer.toString(Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_ON_COLUMN)); + assertFormatterResult(); + } + //int main() { // std::vector> test; // // some comment diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java index 40010e2f2ab..029478e7efd 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java @@ -17,6 +17,7 @@ package org.eclipse.cdt.dsf.mi.service; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; @@ -845,9 +846,9 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo final Map> threadsIDs = fBreakpointThreads.get(dmc); assert threadsIDs != null; - // Minimal validation - if (!platformBPs.containsKey(breakpoint)) { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, UNKNOWN_BREAKPOINT, null)); + boolean filtered = isBreakpointEntirelyFiltered(dmc, breakpoint); + + if (filtered && !platformBPs.containsKey(breakpoint)) { rm.done(); return; } @@ -860,7 +861,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo // Note that Tracepoints are not affected by "skip-all" boolean bpEnabled = attributes.get(ICBreakpoint.ENABLED).equals(true) && (breakpoint instanceof ICTracepoint || fBreakpointManager.isEnabled()); - if (bpEnabled) { + if (!filtered && bpEnabled) { attributes.put(ATTR_DEBUGGER_PATH, NULL_STRING); attributes.put(ATTR_THREAD_FILTER, extractThreads(dmc, breakpoint)); attributes.put(ATTR_THREAD_ID, NULL_STRING); @@ -876,6 +877,11 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo } return; } + + if (filtered) { + uninstallBreakpoint(dmc, breakpoint, rm ); + return; + } // Get the original breakpoint attributes final Map original_attributes = platformBPs.get(breakpoint); @@ -975,8 +981,11 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo protected void handleSuccess() { // Get the list of new back-end breakpoints contexts newTargetBPs.addAll(getData()); + for (IBreakpointDMContext newRef : newTargetBPs) + targetBPs.put(newRef, breakpoint); threadsIDs.put(breakpoint, newThreads); for (final IBreakpointDMContext ref : oldTargetBPs) { + targetBPs.remove(ref); decrementInstallCount(ref, breakpoint, // A tad early but it should work... new RequestMonitor(getExecutor(), removeRM) { @Override @@ -1883,4 +1892,18 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo return !(breakpoint instanceof ICWatchpoint); } + /** + * Returns whether the breakpoint is filtered for given target. + */ + private boolean isBreakpointEntirelyFiltered(IBreakpointsTargetDMContext dmc, ICBreakpoint breakpoint) { + IContainerDMContext currentDmc = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class); + try { + IContainerDMContext[] targetDmcs = getFilterExtension(breakpoint).getTargetFilters(); + if (Arrays.asList(targetDmcs).contains(currentDmc)) + return false; + } + catch(CoreException e) { + } + return true; + } } diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCPPTests.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCPPTests.java index 025fe3b7043..7ed30dbf11c 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCPPTests.java +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCPPTests.java @@ -146,6 +146,9 @@ public class LRCPPTests extends AST2CPPTests { @Override public void testStaticAssertions_294730() throws Exception {} + //outer::foo x + @Override + public void testAttributeInUsingDirective_351228() throws Exception {} @Override diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java index e8499024b80..a209083c336 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRCompletionBasicTest.java @@ -48,7 +48,8 @@ public class LRCompletionBasicTest extends BasicCompletionTest { public void testCastExpression_Bug301933() throws Exception {} @Override public void testConditionalOperator_Bug308611() throws Exception {} - + @Override + public void testCompletionInDesignatedInitializor_353281() throws Exception {} @Override @SuppressWarnings("unused") diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRTemplateTests.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRTemplateTests.java index 6175c96f960..82dc3aae40d 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRTemplateTests.java +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/LRTemplateTests.java @@ -107,6 +107,12 @@ public class LRTemplateTests extends AST2TemplateTests { //variadic template @Override public void testVariadicFunctionTemplate_Bug333389() throws Exception {} + //auto + @Override + public void testRRefVsRef_351927() throws Exception {} + //Variadic template arguments + @Override + public void testTemplateTemplateParameterMatching_352859() throws Exception {} @Override @SuppressWarnings("unused") diff --git a/releng/org.eclipse.cdt-feature/feature.xml b/releng/org.eclipse.cdt-feature/feature.xml index 311021f9ce8..63dbe36ae82 100644 --- a/releng/org.eclipse.cdt-feature/feature.xml +++ b/releng/org.eclipse.cdt-feature/feature.xml @@ -42,8 +42,4 @@ id="org.eclipse.cdt.gnu.dsf" version="0.0.0"/> - - diff --git a/releng/org.eclipse.cdt.repo/category.xml b/releng/org.eclipse.cdt.repo/category.xml index bd60fda1282..31618a27716 100644 --- a/releng/org.eclipse.cdt.repo/category.xml +++ b/releng/org.eclipse.cdt.repo/category.xml @@ -2,11 +2,13 @@ + - + + diff --git a/releng/org.eclipse.cdt.repo/pom.xml b/releng/org.eclipse.cdt.repo/pom.xml index e21aa8d8182..80042b99d9f 100644 --- a/releng/org.eclipse.cdt.repo/pom.xml +++ b/releng/org.eclipse.cdt.repo/pom.xml @@ -14,4 +14,45 @@ 8.0.0-SNAPSHOT org.eclipse.cdt.repo eclipse-repository + + + + production + + /home/data/httpd/download.eclipse.org/tools/cdt/builds/hudson/cdt-nightly + + + + + maven-antrun-plugin + + + deploy + install + + run + + + + + + + + + + + + + + + + + + + + diff --git a/windows/org.eclipse.cdt.msw.build/plugin.xml b/windows/org.eclipse.cdt.msw.build/plugin.xml index 1bdff01da76..922acd93c40 100644 --- a/windows/org.eclipse.cdt.msw.build/plugin.xml +++ b/windows/org.eclipse.cdt.msw.build/plugin.xml @@ -477,6 +477,7 @@ valueType="boolean"/>