From e3150dce7f21d0a41b0751bb6291034f5d0f5dde Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Sun, 27 Jan 2013 22:35:21 -0500 Subject: [PATCH] Bug 399142 - [regression] 'Open Declaration' does not work inside template Change-Id: Ie61924e7bba3aea1fff1df6d996d5af317e8c435 Reviewed-on: https://git.eclipse.org/r/9984 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../parser/tests/ast2/AST2CPPSpecTest.java | 19 ++++++++------- .../parser/tests/ast2/AST2TemplateTests.java | 24 +++++++++++++++++++ .../eclipse/cdt/core/dom/ast/ASTTypeUtil.java | 2 ++ .../parser/cpp/semantics/CPPTemplates.java | 23 +++++++++++++++--- .../dom/parser/cpp/semantics/EvalBinding.java | 8 +------ .../selection/CPPSelectionTestsNoIndexer.java | 22 ++++++++++++++++- 6 files changed, 78 insertions(+), 20 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index 5f28ad59cf6..eb2d81fa18e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,6 +9,7 @@ * Devin Steffler (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; @@ -6060,14 +6061,14 @@ public class AST2CPPSpecTest extends AST2SpecTestBase { BindingAssertionHelper bh= new BindingAssertionHelper(code, true); ICPPTemplateInstance inst; inst= bh.assertNonProblem("f1(v)", 2); - assertEquals("<20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("f1<20>(v)", -3); - assertEquals("<20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); bh.assertProblem("f2(v)", 2); inst= bh.assertNonProblem("f2<10>(v)", -3); - assertEquals("<10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("f3(v)", 2); - assertEquals("<10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); } // template class A { }; @@ -6086,9 +6087,9 @@ public class AST2CPPSpecTest extends AST2SpecTestBase { ICPPTemplateInstance inst; bh.assertProblem("g(a1)", 1); inst= bh.assertNonProblem("g<0>(a1)", -4); - assertEquals("<0>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("f(a1, a2)", 1); - assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); } // template class A { @@ -6134,9 +6135,9 @@ public class AST2CPPSpecTest extends AST2SpecTestBase { ICPPTemplateInstance inst; bh.assertProblem("f(a)", 1); inst= bh.assertNonProblem("f<1>(a)", -3); - assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); inst= bh.assertNonProblem("g(b)", 1); - assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); + assertEquals("", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); } // template void f(void(*)(T,int)); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 9190046da02..dea19e865e7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -7125,4 +7125,28 @@ public class AST2TemplateTests extends AST2TestBase { public void testClassTemplateSpecializationPartialOrdering_398044b() throws Exception { parseAndCheckBindings(); } + + // template + // struct meta { + // static const bool value = 1; + // }; + // template + // struct enable_if {}; + // template <> + // struct enable_if { + // typedef void type; + // }; + // template + // struct pair { + // template ::value>::type> + // pair(int); + // }; + // void push_back(pair&&); + // void push_back(const pair&); + // void test() { + // push_back(0); + // } + public void testRegression_399142() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java index f2097edf8d8..5a254287247 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java @@ -9,6 +9,7 @@ * Rational Software - initial implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -183,6 +184,7 @@ public class ASTTypeUtil { private static void appendArgument(ICPPTemplateArgument arg, boolean normalize, StringBuilder buf) { IValue val= arg.getNonTypeValue(); if (val != null) { + appendType(arg.getTypeOfNonTypeValue(), normalize, buf); buf.append(val.getSignature()); } else { IType type = normalize ? arg.getTypeValue() : arg.getOriginalTypeValue(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 0e5e3383e75..392b133cac0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -1344,13 +1344,29 @@ public class CPPTemplates { } else if (binding instanceof ICPPMethod || binding instanceof ICPPField || binding instanceof ICPPEnumeration) { IBinding owner = binding.getOwner(); if (owner instanceof ICPPClassTemplate) { - owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), + owner = resolveUnknown(createDeferredInstance((ICPPClassTemplate) owner), tpMap, packOffset, within, point); } if (owner instanceof ICPPClassSpecialization) { - // TODO(nathanridge): use specializeMember instead, then combine with ICPPEnumeration branch return ((ICPPClassSpecialization) owner).specializeMember(binding, point); } + } else if (binding instanceof CPPFunctionInstance) { + // TODO(nathanridge): + // Maybe we should introduce a CPPDeferredFunctionInstance and have things that can return + // a dependent CPPFunctionInstance (like instantiateForAddressOfFunction) return that when + // appropriate? + CPPFunctionInstance origInstance = (CPPFunctionInstance) binding; + ICPPTemplateArgument[] origArgs = origInstance.getTemplateArguments(); + ICPPTemplateArgument[] newArgs = instantiateArguments(origArgs, tpMap, packOffset, within, point, false); + if (origArgs != newArgs) { + CPPTemplateParameterMap newMap = instantiateArgumentMap(origInstance.getTemplateParameterMap(), + tpMap, packOffset, within, point); + IType newType = instantiateType(origInstance.getType(), tpMap, packOffset, within, point); + IType[] newExceptionSpecs = instantiateTypes(origInstance.getExceptionSpecification(), + tpMap, packOffset, within, point); + return new CPPFunctionInstance((ICPPFunction) origInstance.getTemplateDefinition(), origInstance.getOwner(), + newMap, newArgs, (ICPPFunctionType) newType, newExceptionSpecs); + } } return binding; } @@ -2460,7 +2476,8 @@ public class CPPTemplates { if (arg.isTypeValue()) return isDependentType(arg.getTypeValue()); - return arg.getNonTypeEvaluation().isValueDependent(); + ICPPEvaluation evaluation = arg.getNonTypeEvaluation(); + return evaluation.isTypeDependent() || evaluation.isValueDependent(); } public static boolean containsDependentType(List ts) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index d2eaaabe21c..d8567779e1e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -238,20 +238,14 @@ public class EvalBinding extends CPPEvaluation { } if (binding instanceof ICPPTemplateNonTypeParameter) { IType type= ((ICPPTemplateNonTypeParameter) binding).getType(); - if (CPPTemplates.isDependentType(type)) - return new TypeOfDependentExpression(this); return prvalueType(type); } if (binding instanceof IVariable) { final IType type = ((IVariable) binding).getType(); - if (CPPTemplates.isDependentType(type)) - return new TypeOfDependentExpression(this); return SemanticUtil.mapToAST(glvalueType(type), point); } if (binding instanceof IFunction) { final IFunctionType type = ((IFunction) binding).getType(); - if (CPPTemplates.isDependentType(type)) - return new TypeOfDependentExpression(this); return SemanticUtil.mapToAST(type, point); } return ProblemType.UNKNOWN_FOR_EXPRESSION; @@ -339,7 +333,7 @@ public class EvalBinding extends CPPEvaluation { } else { IBinding instantiatedBinding = instantiateBinding(origBinding, tpMap, packOffset, within, maxdepth, point); if (instantiatedBinding != origBinding) - return new EvalBinding(instantiatedBinding, getFixedType()); + return new EvalBinding(instantiatedBinding, null); } return this; } 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 9fdaeddc016..29c78c5e609 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.selection; @@ -1204,4 +1205,23 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase { assertEquals(offsetV, ((ASTNode) decl).getOffset()); } + // template + // struct A { + // struct S { + // void foo(); + // }; + // void test() { + // S s; + // s.foo(); + // } + // }; + public void testBug399142() throws Exception { + String code = getAboveComment(); + IFile file = importFile("testBug399142.cpp", code); //$NON-NLS-1$ + + int offset = code.indexOf("s.foo()") + 2; + IASTNode decl = testF3(file, offset); + assertTrue(decl instanceof IASTName); + } + }