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

Bug 259927. Fix and test case.

This commit is contained in:
Sergey Prigogin 2009-01-11 00:22:23 +00:00
parent 89b260739c
commit 00d8f03ce2
5 changed files with 172 additions and 71 deletions

View file

@ -6331,7 +6331,7 @@ public class AST2CPPTests extends AST2BaseTest {
ICPPFunction f2= ba.assertNonProblem("func(*b)", 4, ICPPFunction.class);
assertNotSame(f1, f2);
}
// struct C {int a;};
// void myfunc(C c) {
// return c < c.a ||
@ -6346,4 +6346,32 @@ public class AST2CPPTests extends AST2BaseTest {
final String code= getAboveComment();
parseAndCheckBindings(code);
}
// struct A {
// int a;
// };
//
// struct B {
// A operator-(B b2);
// A operator+(B& b2);
// A operator*(const B& b2);
// A operator/(B b2) const;
// A operator%(const B& b2) const;
// };
//
// void test(B p1, B p2) {
// (p1 - p2).a; //1
// (p1 + p2).a; //2
// (p1 * p2).a; //3
// (p1 / p2).a; //4
// (p1 % p2).a; //5
// }
public void testOverloadedBinaryOperator_259927() throws Exception {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
ba.assertNonProblem("a; //1", 1, ICPPField.class);
ba.assertNonProblem("a; //2", 1, ICPPField.class);
ba.assertNonProblem("a; //3", 1, ICPPField.class);
ba.assertNonProblem("a; //4", 1, ICPPField.class);
ba.assertNonProblem("a; //5", 1, ICPPField.class);
}
}

View file

@ -7,9 +7,11 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.parser.IToken;
/**
@ -66,7 +68,6 @@ public enum OverloadableOperator {
DELETE("delete"),
NEW_ARRAY("new[]");
private final char[] rep;
private OverloadableOperator(String rep) {
@ -78,59 +79,110 @@ public enum OverloadableOperator {
}
/**
* Returns the OverloadableOperator constant that corresponds to the
* given token. Only works for operators that consist of one token.
* Returns the OverloadableOperator constant that corresponds to
* the given token. Only works for operators that consist of one token.
*
* @throws NullPointerException if token is null
* @throws NullPointerException if {@code token} is {@code null}.
*/
public static OverloadableOperator valueOf(IToken token) {
switch(token.getType()) {
case IToken.t_delete: return DELETE;
case IToken.t_new: return NEW;
case IToken.tAMPER: return AMPER;
case IToken.tAMPERASSIGN: return AMPERASSIGN;
case IToken.tARROW: return ARROW;
case IToken.tARROWSTAR: return ARROWSTAR;
case IToken.tBITOR: return BITOR;
case IToken.tBITORASSIGN: return BITORASSIGN;
case IToken.tBITCOMPLEMENT: return BITCOMPLEMENT;
case IToken.tSHIFTL: return SHIFTL;
case IToken.tSHIFTLASSIGN: return SHIFTLASSIGN;
case IToken.tSHIFTR: return SHIFTR;
case IToken.tSHIFTRASSIGN: return SHIFTRASSIGN;
case IToken.tXOR: return XOR;
case IToken.tXORASSIGN: return XORASSIGN;
// logical operations
case IToken.tNOT: return NOT;
case IToken.tAND: return AND;
case IToken.tOR: return OR;
switch (token.getType()) {
case IToken.t_delete: return DELETE;
case IToken.t_new: return NEW;
case IToken.tAMPER: return AMPER;
case IToken.tAMPERASSIGN: return AMPERASSIGN;
case IToken.tARROW: return ARROW;
case IToken.tARROWSTAR: return ARROWSTAR;
case IToken.tBITOR: return BITOR;
case IToken.tBITORASSIGN: return BITORASSIGN;
case IToken.tBITCOMPLEMENT: return BITCOMPLEMENT;
case IToken.tSHIFTL: return SHIFTL;
case IToken.tSHIFTLASSIGN: return SHIFTLASSIGN;
case IToken.tSHIFTR: return SHIFTR;
case IToken.tSHIFTRASSIGN: return SHIFTRASSIGN;
case IToken.tXOR: return XOR;
case IToken.tXORASSIGN: return XORASSIGN;
// logical operations
case IToken.tNOT: return NOT;
case IToken.tAND: return AND;
case IToken.tOR: return OR;
// arithmetic
case IToken.tDECR: return DECR;
case IToken.tINCR: return INCR;
case IToken.tDIV: return DIV;
case IToken.tDIVASSIGN: return DIVASSIGN;
case IToken.tMINUS: return MINUS;
case IToken.tMINUSASSIGN: return MINUSASSIGN;
case IToken.tMOD: return MOD;
case IToken.tMODASSIGN: return MODASSIGN;
case IToken.tPLUS: return PLUS;
case IToken.tPLUSASSIGN: return PLUSASSIGN;
case IToken.tSTAR: return STAR;
case IToken.tSTARASSIGN: return STARASSIGN;
// comparison
case IToken.tEQUAL: return EQUAL;
case IToken.tNOTEQUAL: return NOTEQUAL;
case IToken.tGT: return GT;
case IToken.tGTEQUAL: return GTEQUAL;
case IToken.tLT: return LT;
case IToken.tLTEQUAL: return LTEQUAL;
// other
case IToken.tASSIGN: return ASSIGN;
case IToken.tCOMMA: return COMMA;
// arithmetic
case IToken.tDECR: return DECR;
case IToken.tINCR: return INCR;
case IToken.tDIV: return DIV;
case IToken.tDIVASSIGN: return DIVASSIGN;
case IToken.tMINUS: return MINUS;
case IToken.tMINUSASSIGN: return MINUSASSIGN;
case IToken.tMOD: return MOD;
case IToken.tMODASSIGN: return MODASSIGN;
case IToken.tPLUS: return PLUS;
case IToken.tPLUSASSIGN: return PLUSASSIGN;
case IToken.tSTAR: return STAR;
case IToken.tSTARASSIGN: return STARASSIGN;
// comparison
case IToken.tEQUAL: return EQUAL;
case IToken.tNOTEQUAL: return NOTEQUAL;
case IToken.tGT: return GT;
case IToken.tGTEQUAL: return GTEQUAL;
case IToken.tLT: return LT;
case IToken.tLTEQUAL: return LTEQUAL;
// other
case IToken.tASSIGN: return ASSIGN;
case IToken.tCOMMA: return COMMA;
}
return null;
}
/**
* Returns the OverloadableOperator constant that corresponds to
* the given binary expression.
*
* @throws NullPointerException if {@code expression} is {@code null}.
*/
public static OverloadableOperator fromBinaryExpression(IASTBinaryExpression expression) {
switch (expression.getOperator()) {
case IASTBinaryExpression.op_binaryAnd: return AMPER;
case IASTBinaryExpression.op_binaryAndAssign: return AMPERASSIGN;
case IASTBinaryExpression.op_pmarrow: return ARROW;
case IASTBinaryExpression.op_binaryOr: return BITOR;
case IASTBinaryExpression.op_binaryOrAssign: return BITORASSIGN;
case IASTBinaryExpression.op_shiftLeft: return SHIFTL;
case IASTBinaryExpression.op_shiftLeftAssign: return SHIFTLASSIGN;
case IASTBinaryExpression.op_shiftRight: return SHIFTR;
case IASTBinaryExpression.op_shiftRightAssign: return SHIFTRASSIGN;
case IASTBinaryExpression.op_binaryXor: return XOR;
case IASTBinaryExpression.op_binaryXorAssign: return XORASSIGN;
// logical operations
case IASTBinaryExpression.op_logicalAnd: return AND;
case IASTBinaryExpression.op_logicalOr: return OR;
// arithmetic
case IASTBinaryExpression.op_divide: return DIV;
case IASTBinaryExpression.op_divideAssign: return DIVASSIGN;
case IASTBinaryExpression.op_minus: return MINUS;
case IASTBinaryExpression.op_minusAssign: return MINUSASSIGN;
case IASTBinaryExpression.op_modulo: return MOD;
case IASTBinaryExpression.op_moduloAssign: return MODASSIGN;
case IASTBinaryExpression.op_plus: return PLUS;
case IASTBinaryExpression.op_plusAssign: return PLUSASSIGN;
case IASTBinaryExpression.op_multiply: return STAR;
case IASTBinaryExpression.op_multiplyAssign: return STARASSIGN;
// comparison
case IASTBinaryExpression.op_equals: return EQUAL;
case IASTBinaryExpression.op_notequals: return NOTEQUAL;
case IASTBinaryExpression.op_greaterThan: return GT;
case IASTBinaryExpression.op_greaterEqual: return GTEQUAL;
case IASTBinaryExpression.op_lessThan: return LT;
case IASTBinaryExpression.op_lessEqual: return LTEQUAL;
// other
case IASTBinaryExpression.op_assign: return ASSIGN;
}
return null;

View file

@ -2574,6 +2574,16 @@ public class CPPSemantics {
} else {
data.functionParameters = new IASTExpression[] {paramExpression};
}
} else if (exp instanceof IASTBinaryExpression) {
final IASTBinaryExpression binary = (IASTBinaryExpression) exp;
OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(binary);
if (operator == null) {
return null;
}
astName.setName(operator.toCharArray());
data = new LookupData(astName);
data.forceQualified = true;
data.functionParameters = new IASTExpression[] { binary.getOperand2() };
} else {
return null;
}

View file

@ -1876,6 +1876,33 @@ public class CPPVisitor extends ASTQueries {
}
} else if (expression instanceof IASTBinaryExpression) {
final IASTBinaryExpression binary = (IASTBinaryExpression) expression;
// Check for overloaded operator.
IType type1 = getExpressionType(binary.getOperand1());
while (type1 instanceof ITypedef) {
try {
type1 = ((ITypedef) type1).getType();
} catch (DOMException e) {
break;
}
}
try {
if (type1 instanceof ICPPReferenceType) {
type1 = ((ICPPReferenceType) type1).getType();
}
if (type1 instanceof IQualifierType) {
type1 = ((IQualifierType) type1).getType();
}
if (type1 instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type1);
if (operator != null) {
return operator.getType().getReturnType();
}
}
} catch (DOMException e) {
return e.getProblem();
}
final int op = binary.getOperator();
switch (op) {
case IASTBinaryExpression.op_lessEqual:

View file

@ -18,26 +18,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.*;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
@ -372,6 +353,9 @@ class LookupData {
if (tempNameParent instanceof IASTFunctionCallExpression) {
return CPPVisitor.getExpressionType(((IASTFunctionCallExpression) tempNameParent).getFunctionNameExpression());
}
if (tempNameParent instanceof IASTBinaryExpression) {
return CPPVisitor.getExpressionType(((IASTBinaryExpression) tempNameParent).getOperand1());
}
return null;
}
if (prop == IASTFieldReference.FIELD_NAME) {