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 d18dc267961..ac9a7bb7b6d 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 @@ -201,6 +201,23 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase { assertDeclared(); } + // struct A { + // void a() const; + // }; + // struct B : public A { + // } + // struct C { + // const B& c() const; + // }; + + // void test(const C& x) { + // x.c().a(); + // } + public void testMethodCall_488349() throws Exception { + assertDefined("A::a", "B", "C", "C::c"); + assertDeclared(); + } + // class Base { // public: // void m(); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/IncludeOrganizerTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/IncludeOrganizerTest.java index d8d58893b2f..4f4242a6cf4 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/IncludeOrganizerTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/includes/IncludeOrganizerTest.java @@ -12,8 +12,6 @@ package org.eclipse.cdt.ui.tests.refactoring.includes; import java.util.Collections; -import junit.framework.Test; - import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; @@ -29,6 +27,8 @@ import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeOrganizer; import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences.UnusedStatementDisposition; import org.eclipse.cdt.internal.ui.refactoring.includes.SymbolExportMap; +import junit.framework.Test; + /** * Tests for {@link IncludeOrganizer}. */ @@ -571,6 +571,38 @@ public class IncludeOrganizerTest extends IncludesTestBase { assertExpectedResults(); } + //a.h + //struct A { + // void a() const; + //}; + + //b.h + //#include "a.h" + //struct B : public A { + //} + + //c.h + //class B; + // + //struct C { + // const B& c() const; + //}; + + //source.cpp + //void test(const C& x) { + // x.c().a(); + //} + //==================== + //#include "b.h" + //#include "c.h" + // + //void test(const C& x) { + // x.c().a(); + //} + public void testMethodCall_488349() throws Exception { + assertExpectedResults(); + } + //h1.h //struct A { // void operator()(); 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 f4ec8dde397..09dbaa048dd 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 @@ -701,8 +701,9 @@ public class BindingClassifier { return PROCESS_CONTINUE; IASTInitializerClause[] arguments = functionCallExpression.getArguments(); - IBinding binding = getBindingOfExpression(functionNameExpression); - if (binding != null) { + IASTName functionName = getNameOfIdOrFieldReferenceExpression(functionNameExpression); + if (functionName != null) { + IBinding binding = functionName.resolveBinding(); if (binding instanceof IProblemBinding) { IBinding[] candidates = ((IProblemBinding) binding).getCandidateBindings(); if (candidates.length != 0) { @@ -713,13 +714,18 @@ public class BindingClassifier { defineBinding(binding); } } else { + LookupData data = new LookupData(functionName); + IType impliedObjectType = data.getImpliedObjectType(); + if (impliedObjectType != null) + defineTypeExceptTypedefOrNonFixedEnum(impliedObjectType); defineBindingForFunctionCall(binding, arguments); } } + if (functionCallExpression instanceof IASTImplicitNameOwner) { IASTImplicitName[] implicitNames = ((IASTImplicitNameOwner) functionCallExpression).getImplicitNames(); for (IASTName name : implicitNames) { - binding = name.resolveBinding(); + IBinding binding = name.resolveBinding(); if (binding instanceof IFunction) { defineForFunctionCall((IFunction) binding, arguments); } @@ -739,8 +745,9 @@ public class BindingClassifier { IASTExpression fieldOwner = ((IASTFieldReference) expression).getFieldOwner(); IType expressionType = fieldOwner.getExpressionType(); defineIndirectTypes(expressionType); - IBinding binding = getBindingOfExpression(fieldOwner); - if (binding != null) { + IASTName name = getNameOfIdOrFieldReferenceExpression(fieldOwner); + if (name != null) { + IBinding binding = name.resolveBinding(); defineTypeForBinding(binding, expressionType); } } else if (expression instanceof ICPPASTNewExpression) { @@ -1422,13 +1429,13 @@ public class BindingClassifier { } /** - * @return the binding corresponding to the ID or the field reference expression. + * Returns the name corresponding to the ID or the field reference expression. */ - private static IBinding getBindingOfExpression(IASTExpression expression) { + private static IASTName getNameOfIdOrFieldReferenceExpression(IASTExpression expression) { if (expression instanceof IASTIdExpression) { - return ((IASTIdExpression) expression).getName().resolveBinding(); + return ((IASTIdExpression) expression).getName(); } else if (expression instanceof IASTFieldReference) { - return ((IASTFieldReference) expression).getFieldName().resolveBinding(); + return ((IASTFieldReference) expression).getFieldName(); } return null; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java index 76234107de4..f35f48c8859 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/IncludeOrganizer.java @@ -836,8 +836,9 @@ public class IncludeOrganizer { indexNames = index.findDeclarations(binding); } else if (binding instanceof ICPPMethod) { // Include the headers containing method definitions except the ones also containing - // the definition of the owner class. The headers defining the owner class are taken - // care of separately. + // the definition of the owner class. The definition of owner class will be included because + // BindingClassifier must add a binding that is either the owner itself, or its subclass, or + // a typedef pointing to it. Set declarationFiles = new HashSet<>(); IIndexName[] declarations = index.findNames(binding, IIndex.FIND_DECLARATIONS); for (IIndexName declaration : declarations) {