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 a4f8afe32e1..8e6c0127fca 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 @@ -600,6 +600,23 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase { assertDeclared(); } + // struct A { + // void operator()(); + // }; + // struct B : public A { + // }; + // struct C { + // B b; + // }; + + // void test(C* c) { + // c->b(); + // } + public void testFieldAccess_442841() throws Exception { + assertDefined("C", "operator ()"); + assertDeclared(); + } + // struct A {}; // struct B {}; // struct C {}; 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 2c7d06db48e..d1840e7e676 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 @@ -553,6 +553,34 @@ public class IncludeOrganizerTest extends IncludesTestBase { assertExpectedResults(); } + //h1.h + //struct A { + // void operator()(); + //}; + //struct B : public A { + //}; + + //h2.h + //#include "h1.h" + // + //struct C { + // B b; + //}; + + //source.cpp + //void test(C* c) { + // c->b(); + //} + //==================== + //#include "h2.h" + // + //void test(C* c) { + // c->b(); + //} + public void testFieldAccess_442841() throws Exception { + assertExpectedResults(); + } + //h1.h //namespace ns3 { //class C {}; 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 199c09434af..05045831072 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 @@ -142,7 +142,6 @@ public class BindingClassifier { "unique_ptr", // 20.7.1 //$NON-NLS-1$ "weak_ptr" // 20.7.2.3 //$NON-NLS-1$ }; - public enum InclusionType { DECLARATION, DEFINITION } private class BindingCollector extends ASTVisitor { BindingCollector() { @@ -399,7 +398,7 @@ public class BindingClassifier { } } } else if (memberBinding instanceof ICPPConstructor) { - // Class construction + // Class construction. ICPPConstructor constructor = (ICPPConstructor) memberBinding; // We need to define the owning type of the constructor. @@ -808,9 +807,24 @@ public class BindingClassifier { } else { IBinding owner = binding.getOwner(); if (owner instanceof IType) { - defineBinding(owner); // Member access requires definition of the containing type. + defineBinding(owner); // Member access requires definition of the containing type. if (binding instanceof IProblemBinding) declareBinding(binding); + if (!isDefinedLocally(owner) && + (!(binding instanceof ICPPMember) || !((ICPPMember) binding).isStatic())) { + // Record the fact that the header file defining the owner must also + // provide a definition of the type of this member (bug 442841). + IType type = null; + if (binding instanceof IVariable) { + type = ((IVariable) binding).getType(); + } else if (binding instanceof IFunction) { + type = ((IFunction) binding).getType().getReturnType(); + } + type = getNestedType(type, ALLCVQ); + if (type instanceof IBinding) { + markAsDefined((IBinding) type); + } + } } else { declareBinding(binding); // Declare the binding of this name. } @@ -1051,8 +1065,8 @@ public class BindingClassifier { } } } - // Get the specialized binding - e.g. get the binding for X if the current binding is - // for the template specialization X. + // Get the specialized binding - e.g. get the binding for X if the current binding + // is for the template specialization X. addRequiredBindings(((ICPPSpecialization) binding).getSpecializedBinding(), queue); } else { bindings.add(binding); @@ -1217,7 +1231,7 @@ public class BindingClassifier { private void defineBinding(IBinding binding) { if (!markAsDefined(binding)) return; - if (binding instanceof CPPClosureType || fAst.getDefinitionsInAST(binding).length != 0) + if (isDefinedLocally(binding)) return; // Defined locally. Collection requiredBindings = getRequiredBindings(binding); @@ -1226,13 +1240,17 @@ public class BindingClassifier { if (requiredBinding != binding) { if (!markAsDefined(requiredBinding)) continue; - if (fAst.getDefinitionsInAST(requiredBinding).length != 0) + if (isDefinedLocally(requiredBinding)) continue; // Defined locally. } fBindingsToDefine.add(requiredBinding); } } + private boolean isDefinedLocally(IBinding binding) { + return binding instanceof CPPClosureType || fAst.getDefinitionsInAST(binding).length != 0; + } + private void defineBindingForName(IASTName name) { IBinding binding = name.resolveBinding(); if (!isPartOfExternalMacroDefinition(name))