1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

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 <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2013-01-27 22:35:21 -05:00 committed by Sergey Prigogin
parent b8fa0f2269
commit e3150dce7f
6 changed files with 78 additions and 20 deletions

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,6 +9,7 @@
* Devin Steffler (IBM Corporation) - initial API and implementation * Devin Steffler (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2; package org.eclipse.cdt.core.parser.tests.ast2;
@ -6060,14 +6061,14 @@ public class AST2CPPSpecTest extends AST2SpecTestBase {
BindingAssertionHelper bh= new BindingAssertionHelper(code, true); BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPTemplateInstance inst; ICPPTemplateInstance inst;
inst= bh.assertNonProblem("f1(v)", 2); inst= bh.assertNonProblem("f1(v)", 2);
assertEquals("<20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<int20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
inst= bh.assertNonProblem("f1<20>(v)", -3); inst= bh.assertNonProblem("f1<20>(v)", -3);
assertEquals("<20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<int20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
bh.assertProblem("f2(v)", 2); bh.assertProblem("f2(v)", 2);
inst= bh.assertNonProblem("f2<10>(v)", -3); inst= bh.assertNonProblem("f2<10>(v)", -3);
assertEquals("<10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<int10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
inst= bh.assertNonProblem("f3(v)", 2); inst= bh.assertNonProblem("f3(v)", 2);
assertEquals("<10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<int10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
} }
// template <int i> class A { }; // template <int i> class A { };
@ -6086,9 +6087,9 @@ public class AST2CPPSpecTest extends AST2SpecTestBase {
ICPPTemplateInstance inst; ICPPTemplateInstance inst;
bh.assertProblem("g(a1)", 1); bh.assertProblem("g(a1)", 1);
inst= bh.assertNonProblem("g<0>(a1)", -4); inst= bh.assertNonProblem("g<0>(a1)", -4);
assertEquals("<0>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<int0>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
inst= bh.assertNonProblem("f(a1, a2)", 1); inst= bh.assertNonProblem("f(a1, a2)", 1);
assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<int1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
} }
// template<typename T> class A { // template<typename T> class A {
@ -6134,9 +6135,9 @@ public class AST2CPPSpecTest extends AST2SpecTestBase {
ICPPTemplateInstance inst; ICPPTemplateInstance inst;
bh.assertProblem("f(a)", 1); bh.assertProblem("f(a)", 1);
inst= bh.assertNonProblem("f<1>(a)", -3); inst= bh.assertNonProblem("f<1>(a)", -3);
assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<short int1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
inst= bh.assertNonProblem("g(b)", 1); inst= bh.assertNonProblem("g(b)", 1);
assertEquals("<1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true)); assertEquals("<short int1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
} }
// template<class T> void f(void(*)(T,int)); // template<class T> void f(void(*)(T,int));

View file

@ -7125,4 +7125,28 @@ public class AST2TemplateTests extends AST2TestBase {
public void testClassTemplateSpecializationPartialOrdering_398044b() throws Exception { public void testClassTemplateSpecializationPartialOrdering_398044b() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename>
// struct meta {
// static const bool value = 1;
// };
// template <bool>
// struct enable_if {};
// template <>
// struct enable_if<true> {
// typedef void type;
// };
// template <class T>
// struct pair {
// template <typename = typename enable_if<meta<T>::value>::type>
// pair(int);
// };
// void push_back(pair<long>&&);
// void push_back(const pair<long>&);
// void test() {
// push_back(0);
// }
public void testRegression_399142() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -9,6 +9,7 @@
* Rational Software - initial implementation * Rational Software - initial implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
@ -183,6 +184,7 @@ public class ASTTypeUtil {
private static void appendArgument(ICPPTemplateArgument arg, boolean normalize, StringBuilder buf) { private static void appendArgument(ICPPTemplateArgument arg, boolean normalize, StringBuilder buf) {
IValue val= arg.getNonTypeValue(); IValue val= arg.getNonTypeValue();
if (val != null) { if (val != null) {
appendType(arg.getTypeOfNonTypeValue(), normalize, buf);
buf.append(val.getSignature()); buf.append(val.getSignature());
} else { } else {
IType type = normalize ? arg.getTypeValue() : arg.getOriginalTypeValue(); IType type = normalize ? arg.getTypeValue() : arg.getOriginalTypeValue();

View file

@ -1344,13 +1344,29 @@ public class CPPTemplates {
} else if (binding instanceof ICPPMethod || binding instanceof ICPPField || binding instanceof ICPPEnumeration) { } else if (binding instanceof ICPPMethod || binding instanceof ICPPField || binding instanceof ICPPEnumeration) {
IBinding owner = binding.getOwner(); IBinding owner = binding.getOwner();
if (owner instanceof ICPPClassTemplate) { if (owner instanceof ICPPClassTemplate) {
owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), owner = resolveUnknown(createDeferredInstance((ICPPClassTemplate) owner),
tpMap, packOffset, within, point); tpMap, packOffset, within, point);
} }
if (owner instanceof ICPPClassSpecialization) { if (owner instanceof ICPPClassSpecialization) {
// TODO(nathanridge): use specializeMember instead, then combine with ICPPEnumeration branch
return ((ICPPClassSpecialization) owner).specializeMember(binding, point); 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; return binding;
} }
@ -2460,7 +2476,8 @@ public class CPPTemplates {
if (arg.isTypeValue()) if (arg.isTypeValue())
return isDependentType(arg.getTypeValue()); return isDependentType(arg.getTypeValue());
return arg.getNonTypeEvaluation().isValueDependent(); ICPPEvaluation evaluation = arg.getNonTypeEvaluation();
return evaluation.isTypeDependent() || evaluation.isValueDependent();
} }
public static boolean containsDependentType(List<IType> ts) { public static boolean containsDependentType(List<IType> ts) {

View file

@ -238,20 +238,14 @@ public class EvalBinding extends CPPEvaluation {
} }
if (binding instanceof ICPPTemplateNonTypeParameter) { if (binding instanceof ICPPTemplateNonTypeParameter) {
IType type= ((ICPPTemplateNonTypeParameter) binding).getType(); IType type= ((ICPPTemplateNonTypeParameter) binding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return prvalueType(type); return prvalueType(type);
} }
if (binding instanceof IVariable) { if (binding instanceof IVariable) {
final IType type = ((IVariable) binding).getType(); final IType type = ((IVariable) binding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return SemanticUtil.mapToAST(glvalueType(type), point); return SemanticUtil.mapToAST(glvalueType(type), point);
} }
if (binding instanceof IFunction) { if (binding instanceof IFunction) {
final IFunctionType type = ((IFunction) binding).getType(); final IFunctionType type = ((IFunction) binding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return SemanticUtil.mapToAST(type, point); return SemanticUtil.mapToAST(type, point);
} }
return ProblemType.UNKNOWN_FOR_EXPRESSION; return ProblemType.UNKNOWN_FOR_EXPRESSION;
@ -339,7 +333,7 @@ public class EvalBinding extends CPPEvaluation {
} else { } else {
IBinding instantiatedBinding = instantiateBinding(origBinding, tpMap, packOffset, within, maxdepth, point); IBinding instantiatedBinding = instantiateBinding(origBinding, tpMap, packOffset, within, maxdepth, point);
if (instantiatedBinding != origBinding) if (instantiatedBinding != origBinding)
return new EvalBinding(instantiatedBinding, getFixedType()); return new EvalBinding(instantiatedBinding, null);
} }
return this; return this;
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.ui.tests.text.selection; package org.eclipse.cdt.ui.tests.text.selection;
@ -1204,4 +1205,23 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
assertEquals(offsetV, ((ASTNode) decl).getOffset()); assertEquals(offsetV, ((ASTNode) decl).getOffset());
} }
// template <typename>
// 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);
}
} }