diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java index 857168d1778..ea46ee12f56 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/selection/CPPSelectionTestsNoIndexer.java @@ -1297,4 +1297,18 @@ public class CPPSelectionTestsNoIndexer extends BaseSelectionTests { // not the definition. assertInstance(target.getParent(), IASTElaboratedTypeSpecifier.class); } + + // struct Waldo {}; + // Waldo find(); + // int main() { + // auto waldo = find(); + // } + public void testAutoType_511522() throws Exception { + String code = getAboveComment(); + IFile file = importFile("testBug511522.cpp", code); + + int offset = code.indexOf("auto"); + IASTNode target = testF3(file, offset); + assertInstance(target, IASTName.class); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java index 19d4b2c2799..bc43c5cc8c3 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java @@ -14,6 +14,9 @@ package org.eclipse.cdt.internal.ui.search.actions; import static java.lang.Math.max; import static java.lang.Math.min; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.PTR; import java.util.ArrayList; import java.util.Arrays; @@ -60,6 +63,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; @@ -458,6 +462,9 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { /** * Returns definitions of bindings referenced by implicit name at the given location. + * + * Also, if the given location is over the 'auto' in a variable declaration, the + * variable's type is opened. */ private IName[] findImplicitTargets(IASTTranslationUnit ast, IASTNodeSelector nodeSelector, int offset, int length) throws CoreException { @@ -472,6 +479,29 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { definitions = ArrayUtil.addAll(definitions, declNames); } } + } else { + IASTNode enclosingNode = nodeSelector.findEnclosingNode(offset, length); + if (enclosingNode instanceof ICPPASTSimpleDeclSpecifier) { + if (((ICPPASTSimpleDeclSpecifier) enclosingNode).getType() == ICPPASTSimpleDeclSpecifier.t_auto) { + if (enclosingNode.getParent() instanceof IASTSimpleDeclaration) { + IASTDeclarator[] declarators = ((IASTSimpleDeclaration) enclosingNode.getParent()).getDeclarators(); + if (declarators.length > 0) { + // It's invalid for different declarators to deduce different + // types with 'auto', so just get the type based on the first + // declarator. + IType type = CPPVisitor.createType(declarators[0]); + // Strip qualifiers, references, and pointers, but NOT + // typedefs, since for typedefs we want to navigate to the + // typedef declaration. + type = SemanticUtil.getNestedType(type, CVTYPE | REF | PTR); + if (type instanceof IBinding) { + IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, (IBinding) type); + definitions = ArrayUtil.addAll(definitions, declNames); + } + } + } + } + } } return ArrayUtil.trim(definitions); }