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
* 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("<int20>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
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);
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);
assertEquals("<10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
assertEquals("<int10>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
}
// template <int i> 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("<int0>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
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 {
@ -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("<short int1>", ASTTypeUtil.getArgumentListString(inst.getTemplateArguments(), true));
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));

View file

@ -7125,4 +7125,28 @@ public class AST2TemplateTests extends AST2TestBase {
public void testClassTemplateSpecializationPartialOrdering_398044b() throws Exception {
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
* 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();

View file

@ -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<IType> ts) {

View file

@ -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;
}

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
* 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 <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);
}
}