diff options
author | Markus Schorn | 2009-07-22 16:05:02 +0000 |
---|---|---|
committer | Markus Schorn | 2009-07-22 16:05:02 +0000 |
commit | f79ded2f1d40ce403f2533148c7528e15acd4313 (patch) | |
tree | acb38a128b501dc10c915cacf646e03f83e8a373 | |
parent | bc2c9b5431233442fa9b89d78abecdd1efa60631 (diff) | |
download | org.eclipse.cdt-f79ded2f1d40ce403f2533148c7528e15acd4313.tar.gz org.eclipse.cdt-f79ded2f1d40ce403f2533148c7528e15acd4313.tar.xz org.eclipse.cdt-f79ded2f1d40ce403f2533148c7528e15acd4313.zip |
Exponential complexity resolving overloaded function calls, bug 283324.
5 files changed, 41 insertions, 14 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index db6d9421b46..593a7e7d426 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -7055,6 +7055,25 @@ public class AST2CPPTests extends AST2BaseTest { parseAndCheckBindings(code, ParserLanguage.CPP); } + // class C { + // C& operator()() {return *this;} + // }; + // void test() { + // C c; + // c()()()()()()()()()()()()()(); + // } + public void testNestedOverloadedFunctionCalls_Bug283324() throws Exception { + final String code = getAboveComment(); + IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP); + IASTFunctionDefinition test= getDeclaration(tu, 1); + IASTExpressionStatement stmt= getStatement(test, 1); + long now= System.currentTimeMillis(); + IType t= stmt.getExpression().getExpressionType(); + assertInstance(t, ICPPReferenceType.class); + final long time = System.currentTimeMillis() - now; + assertTrue("Lasted " + time + "ms", time < 5000); + } + // struct A { int a; }; // struct B { int b; }; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java index e3e32bb477e..4ae8d8d3e12 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java @@ -19,9 +19,11 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.OffsetLimitReachedException; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog; import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver; import org.eclipse.cdt.internal.core.parser.scanner.Lexer; @@ -32,7 +34,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions; * Base class for all non-preprocessor nodes in the AST. */ public abstract class ASTNode implements IASTNode { - + protected static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null); private static final IASTNodeLocation[] EMPTY_LOCATION_ARRAY = new IASTNodeLocation[0]; private IASTNode parent; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java index c20b1eeb3a1..6dcbca4e9a3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java @@ -33,12 +33,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent { - private static final ICPPFunction UNINITIALIZED = new CPPFunction(null); private int op; private IASTExpression operand1; private IASTExpression operand2; private IType type; - private ICPPFunction overload= UNINITIALIZED; + private ICPPFunction overload= UNINITIALIZED_FUNCTION; private IASTImplicitName[] implicitNames = null; @@ -166,7 +165,7 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr } public ICPPFunction getOverload() { - if (overload != UNINITIALIZED) + if (overload != UNINITIALIZED_FUNCTION) return overload; return overload = CPPSemantics.findOverloadedOperator(this); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java index 8748e404250..0834b96c547 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java @@ -44,6 +44,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements private IASTExpression parameter; private IASTImplicitName[] implicitNames = null; + private IType type; // cached type of expression + private ICPPFunction overload= UNINITIALIZED_FUNCTION; public CPPASTFunctionCallExpression() { @@ -182,16 +184,23 @@ public class CPPASTFunctionCallExpression extends ASTNode implements } public ICPPFunction getOperator() { - ICPPFunction[] overload = new ICPPFunction[] {null}; - getExpressionType(overload); - return overload[0]; + if (overload == UNINITIALIZED_FUNCTION) { + overload= null; + // as a side effect this computes the overload + getExpressionType(); + } + return overload; } public IType getExpressionType() { - return getExpressionType(null); + if (type == null) { + type= computeExpressionType(); + } + return type; } - private IType getExpressionType(ICPPFunction[] overload) { + private IType computeExpressionType() { + overload= null; try { IType t= null; if (functionName instanceof IASTIdExpression) { @@ -222,8 +231,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements } else if (t instanceof ICPPClassType) { ICPPFunction op = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t); if (op != null) { - if(overload != null) - overload[0] = op; + overload = op; return op.getType().getReturnType(); } } else if (t instanceof IPointerType) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index 6c9bd21059a..aa3a6db0859 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -45,11 +45,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; * Unary expression in c++ */ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent { - private static final ICPPFunction UNINITIALIZED = new CPPFunction(null); private int op; private IASTExpression operand; - private ICPPFunction overload = UNINITIALIZED; + private ICPPFunction overload = UNINITIALIZED_FUNCTION; private IASTImplicitName[] implicitNames = null; public CPPASTUnaryExpression() { @@ -156,7 +155,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres public ICPPFunction getOverload() { - if (overload != UNINITIALIZED) + if (overload != UNINITIALIZED_FUNCTION) return overload; overload = CPPSemantics.findOverloadedOperator(this); |