mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
operator-> for template parameters, bug 257194.
This commit is contained in:
parent
b63ecc5470
commit
fbe8ca1282
2 changed files with 53 additions and 50 deletions
|
@ -3426,7 +3426,7 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
// f(b); g(b); h(b); m(b);
|
// f(b); g(b); h(b); m(b);
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
public void testUnknownReferences_Bug257186() throws Exception {
|
public void testUnknownReferences_Bug257194() throws Exception {
|
||||||
final String code = getAboveComment();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
@ -3446,9 +3446,10 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
// T::b.f();
|
// T::b.f();
|
||||||
// T::b.f().d;
|
// T::b.f().d;
|
||||||
// T::f1();
|
// T::f1();
|
||||||
|
// T.x; T.y();
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
public void testTypeOfUnknownReferences_Bug257186a() throws Exception {
|
public void testTypeOfUnknownReferences_Bug257194a() throws Exception {
|
||||||
final String code = getAboveComment();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
@ -3459,6 +3460,8 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
bh.assertNonProblem("f().", 1, ICPPUnknownBinding.class, IFunction.class);
|
bh.assertNonProblem("f().", 1, ICPPUnknownBinding.class, IFunction.class);
|
||||||
bh.assertNonProblem("d;", 1, ICPPUnknownBinding.class);
|
bh.assertNonProblem("d;", 1, ICPPUnknownBinding.class);
|
||||||
bh.assertNonProblem("f1();", 2, ICPPUnknownBinding.class, IFunction.class);
|
bh.assertNonProblem("f1();", 2, ICPPUnknownBinding.class, IFunction.class);
|
||||||
|
bh.assertNonProblem("x;", 1, ICPPUnknownBinding.class);
|
||||||
|
bh.assertNonProblem("y();", 1, ICPPUnknownBinding.class, IFunction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<typename T> struct A {
|
// template<typename T> struct A {
|
||||||
|
@ -3467,9 +3470,10 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
// T::b->f();
|
// T::b->f();
|
||||||
// T::b->f()->d;
|
// T::b->f()->d;
|
||||||
// T::f1();
|
// T::f1();
|
||||||
|
// T->x; T->y();
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
public void testTypeOfUnknownReferences_Bug257186b() throws Exception {
|
public void testTypeOfUnknownReferences_Bug257194b() throws Exception {
|
||||||
final String code = getAboveComment();
|
final String code = getAboveComment();
|
||||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
@ -3480,6 +3484,8 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
bh.assertNonProblem("f()->", 1, ICPPUnknownBinding.class, IFunction.class);
|
bh.assertNonProblem("f()->", 1, ICPPUnknownBinding.class, IFunction.class);
|
||||||
bh.assertNonProblem("d;", 1, ICPPUnknownBinding.class);
|
bh.assertNonProblem("d;", 1, ICPPUnknownBinding.class);
|
||||||
bh.assertNonProblem("f1();", 2, ICPPUnknownBinding.class, IFunction.class);
|
bh.assertNonProblem("f1();", 2, ICPPUnknownBinding.class, IFunction.class);
|
||||||
|
bh.assertNonProblem("x;", 1, ICPPUnknownBinding.class);
|
||||||
|
bh.assertNonProblem("y();", 1, ICPPUnknownBinding.class, IFunction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
// template<typename T> class XT {
|
// template<typename T> class XT {
|
||||||
|
|
|
@ -144,6 +144,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective;
|
||||||
|
@ -2434,27 +2435,26 @@ public class CPPSemantics {
|
||||||
*/
|
*/
|
||||||
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference) throws DOMException {
|
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference) throws DOMException {
|
||||||
IASTExpression owner = fieldReference.getFieldOwner();
|
IASTExpression owner = fieldReference.getFieldOwner();
|
||||||
IType result= CPPVisitor.getExpressionType(owner);
|
IType type= CPPVisitor.getExpressionType(owner);
|
||||||
|
|
||||||
if (fieldReference.isPointerDereference() && !(result instanceof ICPPUnknownType)) {
|
if (!fieldReference.isPointerDereference())
|
||||||
IType type= getUltimateTypeUptoPointers(result);
|
return type;
|
||||||
boolean needCheckClassMemberAccessOperator= true;
|
|
||||||
if (type instanceof IPointerType) {
|
|
||||||
type= getUltimateTypeUptoPointers(((IPointerType) type).getType());
|
|
||||||
if (type instanceof ICPPClassType) {
|
|
||||||
needCheckClassMemberAccessOperator= false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needCheckClassMemberAccessOperator) {
|
|
||||||
IType temp= result;
|
|
||||||
result= null;
|
|
||||||
|
|
||||||
// bug 205964: as long as the type is a class type, recurse.
|
// bug 205964: as long as the type is a class type, recurse.
|
||||||
// Be defensive and allow a max of 10 levels.
|
// Be defensive and allow a max of 10 levels.
|
||||||
|
boolean foundOperator= false;
|
||||||
for (int j = 0; j < 10; j++) {
|
for (int j = 0; j < 10; j++) {
|
||||||
IType uTemp= getUltimateTypeUptoPointers(temp);
|
IType uTemp= getUltimateTypeUptoPointers(type);
|
||||||
if (uTemp instanceof ICPPClassType) {
|
if (uTemp instanceof IPointerType)
|
||||||
|
return type;
|
||||||
|
|
||||||
|
// for unknown types we cannot determine the overloaded -> operator
|
||||||
|
if (uTemp instanceof ICPPUnknownType)
|
||||||
|
return CPPUnknownClass.createUnnamedInstance();
|
||||||
|
|
||||||
|
if (!(uTemp instanceof ICPPClassType))
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 13.5.6-1: An expression x->m is interpreted as (x.operator->())->m for a
|
* 13.5.6-1: An expression x->m is interpreted as (x.operator->())->m for a
|
||||||
* class object x of type T
|
* class object x of type T
|
||||||
|
@ -2465,9 +2465,9 @@ public class CPPSemantics {
|
||||||
|
|
||||||
CPPASTName x= new CPPASTName();
|
CPPASTName x= new CPPASTName();
|
||||||
boolean isConst= false, isVolatile= false;
|
boolean isConst= false, isVolatile= false;
|
||||||
if (temp instanceof IQualifierType) {
|
if (type instanceof IQualifierType) {
|
||||||
isConst= ((IQualifierType)temp).isConst();
|
isConst= ((IQualifierType)type).isConst();
|
||||||
isVolatile= ((IQualifierType)temp).isVolatile();
|
isVolatile= ((IQualifierType)type).isVolatile();
|
||||||
}
|
}
|
||||||
x.setBinding(createVariable(x, uTemp, isConst, isVolatile));
|
x.setBinding(createVariable(x, uTemp, isConst, isVolatile));
|
||||||
|
|
||||||
|
@ -2476,17 +2476,14 @@ public class CPPSemantics {
|
||||||
innerFR.setParent(fieldReference); // connect to the AST
|
innerFR.setParent(fieldReference); // connect to the AST
|
||||||
|
|
||||||
ICPPFunction op = CPPSemantics.findOperator(innerFR, (ICPPClassType) uTemp);
|
ICPPFunction op = CPPSemantics.findOperator(innerFR, (ICPPClassType) uTemp);
|
||||||
if (op != null) {
|
if (op == null)
|
||||||
result= temp= op.getType().getReturnType();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
type= op.getType().getReturnType();
|
||||||
|
foundOperator= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return foundOperator ? type : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPVariable createVariable(IASTName name, final IType type, final boolean isConst, final boolean isVolatile) {
|
private static ICPPVariable createVariable(IASTName name, final IType type, final boolean isConst, final boolean isVolatile) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue