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 c8082663ae6..2799764cc95 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 @@ -16,8 +16,6 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; -import junit.framework.TestSuite; - import org.eclipse.jface.preference.IPreferenceStore; import com.ibm.icu.text.MessageFormat; @@ -40,6 +38,8 @@ import org.eclipse.cdt.ui.testplugin.CTestPlugin; import org.eclipse.cdt.internal.ui.refactoring.includes.BindingClassifier; import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeCreationContext; +import junit.framework.TestSuite; + /** * Tests for {@link BindingClassifier}. */ @@ -420,6 +420,24 @@ public class BindingClassifierTest extends OneSourceMultipleHeadersTestCase { assertDeclared("B"); } + // namespace std { + // template class shared_ptr {}; + // } + // + // struct A { + // int x; + // }; + // struct B { + // const std::shared_ptr y; + // }; + + // int test(B* b) { + // return b->y->x; + // }; + public void testFieldReference_487971() throws Exception { + assertDefined("A", "B"); + } + // typedef unsigned int size_t; // size_t a; 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 411e9faa3b3..2888a80c54c 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 @@ -77,6 +77,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -1377,12 +1378,12 @@ public class BindingClassifier { * allowing incomplete argument types, defines the argument type. */ private void defineIndirectTypes(IType type) { - IType resolvedType = resolveTypedef(type); + IType resolvedType = removeQualifiers(resolveTypedef(type)); if (resolvedType instanceof IPointerType || resolvedType instanceof ICPPReferenceType) { defineTypeExceptTypedefOrNonFixedEnum(resolvedType); } else { - if (type instanceof ICPPTemplateInstance) { - ICPPTemplateInstance instance = (ICPPTemplateInstance) type; + if (resolvedType instanceof ICPPTemplateInstance) { + ICPPTemplateInstance instance = (ICPPTemplateInstance) resolvedType; IBinding template = instance.getSpecializedBinding(); if (isTemplateAllowingIncompleteArgumentType(template)) { ICPPTemplateArgument[] arguments = instance.getTemplateArguments(); @@ -1456,6 +1457,17 @@ public class BindingClassifier { return type; } + /** + * If the given type is a qualified type, returns the corresponding unqualified type. + * Otherwise returns the given type. + */ + private IType removeQualifiers(IType type) { + while (type instanceof IQualifierType) { + type = ((IQualifierType) type).getType(); + } + return type; + } + /** * Checks if the given name is part of a template argument. */