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

Bug 567217 - template functions with lvalue and rvalue parameters of

template tests added.

Change-Id: I1fbbb45c6d895505a66ad917b1342365118e28d0
This commit is contained in:
Michael Uhl 2020-11-05 13:47:17 +01:00 committed by Nathan Ridge
parent 742fbd74d8
commit 6a9a8d409d
3 changed files with 922 additions and 13 deletions

View file

@ -0,0 +1,878 @@
package org.eclipse.cdt.core.parser.tests.ast2;
import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
import java.io.IOException;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionTemplate;
import org.eclipse.cdt.internal.core.parser.ParserException;
public class AST2TemplateLValueRValueTests extends AST2CPPTestBase {
public AST2TemplateLValueRValueTests() {
}
public AST2TemplateLValueRValueTests(String name) {
super(name);
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// template<class C> void demo(C &cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_lvalue_rvalue_caller_templateLvalue_templateRvalue_function() throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
CPPFunctionTemplate targetLvalue = helper.assertNonProblem("demo(C &cont)", "demo");
CPPFunctionTemplate targetRvalue = helper.assertNonProblem("demo(C &&cont)", "demo");
CPPFunctionInstance actualTargetLvalue = helper.assertNonProblem("demo(c)", "demo");
CPPFunctionInstance actualTargetRvalue = helper.assertNonProblem("demo(getClazz())", "demo");
assertEquals(targetLvalue, actualTargetLvalue.getTemplateDefinition());
assertEquals(targetRvalue, actualTargetRvalue.getTemplateDefinition());
}
// class clazz {
// };
//
// typedef clazz clazzz;
//
// template<class C> void demo(C &&cont)
// {
// }
//
// template<class C> void demo(C &cont)
// {
// }
//
// clazz getClazz()
// {
// clazzz c;
// return c;
// }
//
// void testLValue()
// {
// clazzz c;
// demo(c);
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_lvalueTypedef_rvalueTypedef_caller_templateLvalue_templateRvalue_function() throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
CPPFunctionTemplate targetLvalue = helper.assertNonProblem("demo(C &cont)", "demo");
CPPFunctionTemplate targetRvalue = helper.assertNonProblem("demo(C &&cont)", "demo");
CPPFunctionInstance actualTargetLvalue = helper.assertNonProblem("demo(c)", "demo");
CPPFunctionInstance actualTargetRvalue = helper.assertNonProblem("demo(getClazz())", "demo");
assertEquals(targetLvalue, actualTargetLvalue.getTemplateDefinition());
assertEquals(targetRvalue, actualTargetRvalue.getTemplateDefinition());
}
// class clazz {
// };
//
// template <class C>
// using Ref = C&;
//
// template<class C> void demo(C &&cont)
// {
// }
//
// template<class C> void demo(Ref<C> cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_lvalueTypedefRef_rvalueTypedefRef_caller_templateLvalue_templateRvalue_function()
throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
CPPFunctionTemplate targetLvalue = helper.assertNonProblem("demo(Ref<C> cont)", "demo");
CPPFunctionTemplate targetRvalue = helper.assertNonProblem("demo(C &&cont)", "demo");
CPPFunctionInstance actualTargetLvalue = helper.assertNonProblem("demo(c)", "demo");
CPPFunctionInstance actualTargetRvalue = helper.assertNonProblem("demo(getClazz())", "demo");
assertEquals(targetLvalue, actualTargetLvalue.getTemplateDefinition());
assertEquals(targetRvalue, actualTargetRvalue.getTemplateDefinition());
}
// class clazz {
// };
//
// typedef clazz & clazzRef;
//
// template<class C> void demo(C &&cont)
// {
// }
//
// template<class C> void demo(clazzRef cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testLValue()
// {
// clazz c;
// demo<clazz>(c);
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_lvalueTypedefRef_rvalueTypedefRef_caller_templateTpedefLvalue_templateRvalue_function()
throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
CPPFunctionTemplate targetLvalue = helper.assertNonProblem("demo(clazzRef cont)", "demo");
CPPFunctionTemplate targetRvalue = helper.assertNonProblem("demo(C &&cont)", "demo");
CPPFunctionTemplate actualTargetLvalue = helper.assertNonProblem("demo<clazz>(c)", "demo");
CPPFunctionInstance actualTargetRvalue = helper.assertNonProblem("demo(getClazz())", "demo");
assertEquals(targetLvalue, actualTargetLvalue);
assertEquals(targetRvalue, actualTargetRvalue.getTemplateDefinition());
}
// template<class C> void demo(C &&cont)
// {
// }
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(int &&cont)
// {
// }
//
// void demo(int &cont)
// {
// }
//
// int main()
// {
// int c;
// demo(c);
// }
public void test_lvalue_rvalue_caller_templateLvalue_templateRvalue_lvalue_function() throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
CPPFunction intendedTarget = helper.assertNonProblem("demo(int &cont)", "demo");
CPPFunction actualTarget = helper.assertNonProblem("demo(c)", "demo");
assertEquals(intendedTarget, actualTarget);
}
// class clazz {
// };
//
// void demo(clazz &&cont)
// {
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
public void test_lvalue_caller_rvalue_function() throws Exception {
parseAndCheckBindingsForOneProblem();
}
// class clazz {
// };
//
// void demo(clazz &cont)
// {
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
public void test_lvalue_caller_lvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// void demo(clazz &&cont)
// {
// }
//
// void demo(clazz &cont)
// {
// }
//
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_lvalue_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void demo(clazz &cont)
// {
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
public void test_lvalue_caller_templateRvalue_lvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void demo(clazz &cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_templateRvalue_lvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// void demo(clazz &cont)
// {
// }
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_lvalue_function() throws Exception {
parseAndCheckBindingsForOneProblem();
}
// class clazz {
// };
//
// void demo(clazz &&cont)
// {
// }
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_templateLvalue_function() throws Exception {
parseAndCheckBindingsForOneProblem();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_templateRvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo<clazz>(getClazz());
// }
public void test_templatedRvalue_caller__templateRvalue_lvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void demo(clazz &cont) {
// }
//
// void testLValue()
// {
// clazz c;
// demo<clazz>(c);
// }
public void test_templatedLvalue_caller__templateRvalue_lvalue_function() throws Exception {
parseAndCheckBindingsForProblem();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &cont) {
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
public void test_lvalue_caller_templateLvalue_lvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &cont) {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_templateLvalue_lvalue_function() throws Exception {
parseAndCheckBindingsForOneProblem();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &cont) {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo<clazz>(getClazz());
// }
public void test_templatedRvalue_caller_templatedLValue_lvalAST2TemplateRValueRValueTestsue_function()
throws Exception {
parseAndCheckBindingsForProblem();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &cont) {
// }
//
// void testRValue()
// {
// clazz c;
// demo<clazz>(c);
// }
public void test_templatedLvalue_caller_templatedLValue_lvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
public void test_lvalue_caller_templatedRvalue_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_templatedRvalue_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo<clazz>(getClazz());
// }
public void test_templatedRvalue_caller_templatedRvalue_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// void testLValue()
// {
// clazz c;
// demo<clazz>(c);
// }
public void test_templatedLvalue_caller_templatedRvalue_rvalue_function() throws Exception {
parseAndCheckBindingsForProblem();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
public void test_lvalue_caller_templatedLvalue_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_templatedLvalue_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo<clazz>(getClazz());
// }
public void test_templatedRvalue_caller_templatedLvalue_rvalue_function() throws Exception {
parseAndCheckBindingsForProblem();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void demo(clazz &&cont) {
// }
//
// void testRValue()
// {
// clazz c;
// demo<clazz>(c);
// }
public void test_templatedLvalue_caller_templatedLvalue_rvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void testLValue()
// {
// clazz c;
// demo(c);
// }
public void test_lvalue_caller_templatedLvalue_templatedRvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// template<class C> void demo(C &&cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo(getClazz());
// }
public void test_rvalue_caller_templatedLvalue_templatedRvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// template<class C> void demo(C &&cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo<clazz>(getClazz());
// }
public void test_templatedRvalue_caller_templatedLvalue_templatedRvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void testLValue()
// {
// clazz c;
// demo<clazz>(c);
// }
public void test_templatedLvalue_caller_templatedLvalue_templatedRvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo<clazz>(getClazz());
// }
public void test_templatedRvalue_caller_templatedLvalue_function() throws Exception {
parseAndCheckBindingsForProblem();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// clazz getClazz()
// {
// clazz c;
// return c;
// }
//
// void testRValue()
// {
// demo<clazz>(getClazz());
// }
public void test_templatedRvalue_caller_templatedRvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &cont)
// {
// }
//
// void testLValue()
// {
// clazz c;
// demo<clazz>(c);
// }
public void test_templatedLvalue_caller_templatedLvalue_function() throws Exception {
parseAndCheckBindings();
}
// class clazz {
// };
//
// template<class C> void demo(C &&cont)
// {
// }
//
// void testLValue()
// {
// clazz c;
// demo<clazz>(c);
// }
public void test_templatedLvalue_caller_templatedRvalue_function() throws Exception {
parseAndCheckBindingsForProblem();
}
private void parseAndCheckBindingsForOneProblem() throws IOException, ParserException {
final String code = getAboveComment();
IASTTranslationUnit tu = parse(code, CPP, true, false);
NameCollector nc = new NameCollector();
tu.accept(nc);
assertProblemBindings(nc, 1);
}
private void parseAndCheckBindingsForProblem() throws IOException, ParserException {
final String code = getAboveComment();
IASTTranslationUnit tu = parse(code, CPP, true, false);
NameCollector nc = new NameCollector();
tu.accept(nc);
assertProblemBindings(nc);
}
}

View file

@ -532,12 +532,23 @@ public class AST2TestBase extends SemanticTestBase {
final protected void assertProblemBindings(NameCollector col, int count) {
int sum = 0;
for (IASTName n : col.nameList) {
if (n.resolveBinding() instanceof IProblemBinding)
if (n.resolveBinding() instanceof IProblemBinding) {
++sum;
}
}
assertEquals(count, sum);
}
final protected void assertProblemBindings(NameCollector col) {
int sum = 0;
for (IASTName n : col.nameList) {
if (n.resolveBinding() instanceof IProblemBinding) {
++sum;
}
}
assertTrue(sum > 0);
}
final protected <T extends IASTDeclaration> T getDeclaration(IASTTranslationUnit tu, int i_decl) {
Class<T> tclass;
IASTDeclaration[] decls = tu.getDeclarations();

View file

@ -572,25 +572,45 @@ public class TemplateArgumentDeduction {
return true;
}
private static int deduceForPartialOrdering(IType par, IType arg, TemplateArgumentDeduction deduct)
private static int deduceForPartialOrdering(IType parOrig, IType argOrig, TemplateArgumentDeduction deduct)
throws DOMException {
par = getNestedType(par, TDEF);
arg = getNestedType(arg, TDEF);
IType parNested = getNestedType(parOrig, TDEF);
IType argNested = getNestedType(argOrig, TDEF);
boolean isMoreCVQualified = false;
if (par instanceof ICPPReferenceType && arg instanceof ICPPReferenceType) {
par = getNestedType(par, REF | TDEF);
arg = getNestedType(arg, REF | TDEF);
CVQualifier cvp = getCVQualifier(par);
CVQualifier cva = getCVQualifier(arg);
boolean preferForLValueRef = false;
if (parNested instanceof ICPPReferenceType && argNested instanceof ICPPReferenceType) {
preferForLValueRef = compareRValueRValueTemplateFunctions(parNested, argNested);
parNested = getNestedType(parNested, REF | TDEF);
argNested = getNestedType(argNested, REF | TDEF);
CVQualifier cvp = getCVQualifier(parNested);
CVQualifier cva = getCVQualifier(argNested);
isMoreCVQualified = cva.isMoreQualifiedThan(cvp);
}
par = getNestedType(par, TDEF | REF | ALLCVQ);
arg = getNestedType(arg, TDEF | REF | ALLCVQ);
parNested = getNestedType(parNested, TDEF | REF | ALLCVQ);
argNested = getNestedType(argNested, TDEF | REF | ALLCVQ);
if (!deduct.fromType(par, arg, false, false))
if (!deduct.fromType(parNested, argNested, false, false))
return -1;
return isMoreCVQualified ? 1 : 0;
return (isMoreCVQualified || preferForLValueRef) ? 1 : 0;
}
private static boolean compareRValueRValueTemplateFunctions(final IType f1, final IType f2) {
ICPPReferenceType fstTp = (ICPPReferenceType) f1;
ICPPReferenceType sndTp = (ICPPReferenceType) f2;
boolean fstRv = fstTp.isRValueReference();
boolean sndRv = sndTp.isRValueReference();
if (fstRv != sndRv) {
return fstRv;
}
return false;
}
private static boolean isReferenceType(IType fstSpecP) {
return ICPPReferenceType.class.isAssignableFrom(fstSpecP.getClass());
}
/**