diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java index 644733078cb..dce5a94df9d 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/BindingClassifierTest.java @@ -18,6 +18,8 @@ import java.util.TreeSet; import junit.framework.TestSuite; +import org.eclipse.jface.preference.IPreferenceStore; + import com.ibm.icu.text.MessageFormat; import org.eclipse.cdt.core.CCorePlugin; @@ -29,6 +31,8 @@ import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.parser.util.StringUtil; import org.eclipse.cdt.core.testplugin.util.OneSourceMultipleHeadersTestCase; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.ui.testplugin.CTestPlugin; import org.eclipse.cdt.internal.ui.refactoring.includes.BindingClassifier; @@ -39,7 +43,6 @@ import org.eclipse.cdt.internal.ui.refactoring.includes.InclusionContext; */ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase { private IIndex fIndex; - private InclusionContext fContext; private BindingClassifier fBindingClassifier; public BindingClassifierTest() { @@ -57,23 +60,38 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase { fIndex = CCorePlugin.getIndexManager().getIndex(getCProject(), IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT); fIndex.acquireReadLock(); - ITranslationUnit tu = ast.getOriginatingTranslationUnit(); - fContext = new InclusionContext(tu, fIndex); - fBindingClassifier = new BindingClassifier(fContext); - fBindingClassifier.classifyNodeContents(ast); + IPreferenceStore preferenceStore = getPreferenceStore(); + preferenceStore.setToDefault(PreferenceConstants.FORWARD_DECLARE_FUNCTIONS); + } + + private void classifyBindings() { + if (fBindingClassifier == null) { + IASTTranslationUnit ast = getAst(); + ITranslationUnit tu = ast.getOriginatingTranslationUnit(); + InclusionContext context = new InclusionContext(tu, fIndex); + fBindingClassifier = new BindingClassifier(context); + fBindingClassifier.classifyNodeContents(ast); + } } @Override protected void tearDown() throws Exception { fIndex.releaseReadLock(); + fBindingClassifier = null; super.tearDown(); } + private IPreferenceStore getPreferenceStore() { + return CUIPlugin.getDefault().getPreferenceStore(); + } + private void assertDefined(String... names) { + classifyBindings(); assertExpectedBindings(names, fBindingClassifier.getBindingsToDefine(), "defined"); } private void assertDeclared(String... names) { + classifyBindings(); assertExpectedBindings(names, fBindingClassifier.getBindingsToDeclare(), "declared"); } @@ -169,6 +187,19 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase { assertDeclared(); } + // class A {}; + // void f(const A* p); + + // void test(A* a) { + // f(a); + // } + public void testFunctionCall() throws Exception { + IPreferenceStore preferenceStore = getPreferenceStore(); + preferenceStore.setValue(PreferenceConstants.FORWARD_DECLARE_FUNCTIONS, true); + assertDefined(); + assertDeclared("f", "A"); + } + // struct A {}; // struct B {}; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java index b189fe31b61..2bd8e84a5b4 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java @@ -155,21 +155,25 @@ public class BindingClassifier { private void processParameters(IParameter[] declaredParameters, IASTInitializerClause[] arguments) { for (int i = 0; i < declaredParameters.length; i++) { IType declaredParameterType = declaredParameters[i].getType(); - IType actualParameterType = null; + IType argumentType = null; boolean canBeDeclared = false; if (declaredParameterType instanceof IPointerType || declaredParameterType instanceof ICPPReferenceType) { // The declared parameter type is a pointer or reference type. A declaration is // sufficient if it matches the actual parameter type. - declaredParameterType = getNestedType(declaredParameterType, REF); + declaredParameterType = getNestedType(declaredParameterType, REF | ALLCVQ); if (i < arguments.length) { // This parameter is present within the function call expression. // It's therefore not a default parameter. - IASTInitializerClause actualParameter = arguments[i]; - if (actualParameter instanceof IASTExpression) { - actualParameterType = ((IASTExpression) actualParameter).getExpressionType(); - actualParameterType = getNestedType(actualParameterType, REF); + IASTInitializerClause argument = arguments[i]; + if (argument instanceof IASTExpression) { + argumentType = ((IASTExpression) argument).getExpressionType(); + argumentType = getNestedType(argumentType, REF | ALLCVQ); - if (isSameType(declaredParameterType, actualParameterType)) { + if (declaredParameterType instanceof IPointerType && argumentType instanceof IPointerType) { + declaredParameterType = getNestedType(((IPointerType) declaredParameterType).getType(), ALLCVQ); + argumentType = getNestedType(((IPointerType) argumentType).getType(), ALLCVQ); + } + if (isSameType(declaredParameterType, argumentType)) { canBeDeclared = true; } } @@ -188,7 +192,7 @@ public class BindingClassifier { // Both the type of the declared parameter as well as the type of the actual // parameter require a full definition. defineTypeExceptTypedefOrNonFixedEnum(declaredParameterType); - defineTypeExceptTypedefOrNonFixedEnum(actualParameterType); + defineTypeExceptTypedefOrNonFixedEnum(argumentType); } } }