From 3eb91c4fa0b2186d0457b8208ef99a8a669bd92a Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 21 May 2008 12:03:44 +0000 Subject: [PATCH] Name resolution for user-defined function operator, bug 231277. --- .../parser/cpp/semantics/CPPSemantics.java | 13 ++ .../dom/parser/cpp/semantics/CPPVisitor.java | 7 ++ .../dom/parser/cpp/semantics/LookupData.java | 119 ++++++++++-------- .../text/contentassist2/CompletionTests.java | 9 ++ 4 files changed, 95 insertions(+), 53 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 451c8015d5c..d38cadbf3cd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -2386,6 +2386,19 @@ public class CPPSemantics { data = new LookupData(astName); data.forceQualified = true; data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY; + } else if (exp instanceof IASTFunctionCallExpression) { + astName.setName(OverloadableOperator.PAREN.toCharArray()); + data = new LookupData(astName); + data.forceQualified = true; + final IASTExpression paramExpression = ((IASTFunctionCallExpression)exp).getParameterExpression(); + if (paramExpression == null) { + data.functionParameters= IASTExpression.EMPTY_EXPRESSION_ARRAY; + } + else if (paramExpression instanceof IASTExpressionList) { + data.functionParameters= ((IASTExpressionList) paramExpression).getExpressions(); + } else { + data.functionParameters = new IASTExpression[] {paramExpression}; + } } else { return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index d10d7e16262..40a4d20d93e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -1864,6 +1864,13 @@ public class CPPVisitor { if (ftype != null) return ftype.getReturnType(); } + t= getUltimateTypeUptoPointers(t); + if (t instanceof ICPPClassType) { + ICPPFunction op = CPPSemantics.findOperator(expression, (ICPPClassType) t); + if (op != null) { + return op.getType().getReturnType(); + } + } } catch(DOMException e) { return e.getProblem(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index 5e105268d61..32a9786828e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -297,60 +297,73 @@ class LookupData { * an IType[] of function arguments, including the implied object argument */ public IType getImpliedObjectArgument() { - IType implied = null; - - if (astName != null) { - IASTName tempName = astName; - while (tempName.getParent() instanceof IASTName) - tempName = (IASTName) tempName.getParent(); - - ASTNodeProperty prop = tempName.getPropertyInParent(); - if ((prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof ICPPASTUnaryExpression)) { - ICPPASTUnaryExpression unaryExp = (ICPPASTUnaryExpression) tempName.getParent(); - IASTExpression oprd= unaryExp.getOperand(); - return CPPVisitor.getExpressionType(oprd); - } else if (prop == IASTFieldReference.FIELD_NAME || - (prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof ICPPASTFieldReference)) { - ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempName.getParent(); - implied = CPPVisitor.getExpressionType(fieldRef.getFieldOwner()); - IType ultimateImplied= SemanticUtil.getUltimateTypeUptoPointers(implied); - if (prop != CPPSemantics.STRING_LOOKUP_PROPERTY && fieldRef.isPointerDereference() && - ultimateImplied instanceof ICPPClassType) { - ICPPFunction operator= CPPSemantics.findOperator(fieldRef, (ICPPClassType) ultimateImplied); - try { - if (operator!=null) { - implied= operator.getType().getReturnType(); - } - } catch(DOMException de) { - return de.getProblem(); - } - } else if (fieldRef.isPointerDereference() && implied instanceof IPointerType) { - try { - implied = ((IPointerType)implied).getType(); - } catch (DOMException e) { - implied = e.getProblem(); - } - } - } else if (prop == IASTIdExpression.ID_NAME) { - IScope scope = CPPVisitor.getContainingScope(tempName); - if (scope instanceof ICPPClassScope) { - implied = ((ICPPClassScope)scope).getClassType(); - } else { - implied = CPPVisitor.getThisType(scope); - if (implied instanceof IPointerType) { - try { - implied = ((IPointerType)implied).getType(); - } catch (DOMException e) { - implied = e.getProblem(); - } - } - } - } else if (prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof IASTArraySubscriptExpression) { - IASTExpression exp = ((IASTArraySubscriptExpression)tempName.getParent()).getArrayExpression(); - implied = CPPVisitor.getExpressionType(exp); - } + if (astName == null) + return null; + + IASTName tempName= astName; + IASTNode tempNameParent= tempName.getParent(); + while (tempNameParent instanceof IASTName) { + tempName= (IASTName) tempNameParent; + tempNameParent= tempName.getParent(); + } + + try { + final ASTNodeProperty prop = tempName.getPropertyInParent(); + if (prop == CPPSemantics.STRING_LOOKUP_PROPERTY) { + if (tempNameParent instanceof ICPPASTUnaryExpression) { + ICPPASTUnaryExpression unaryExp = (ICPPASTUnaryExpression) tempNameParent; + IASTExpression oprd= unaryExp.getOperand(); + return CPPVisitor.getExpressionType(oprd); + } + if (tempNameParent instanceof ICPPASTFieldReference) { + ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempNameParent; + IType implied = CPPVisitor.getExpressionType(fieldRef.getFieldOwner()); + if (fieldRef.isPointerDereference() && implied instanceof IPointerType) { + return ((IPointerType)implied).getType(); + } + return implied; + } + if (tempNameParent instanceof IASTArraySubscriptExpression) { + IASTExpression exp = ((IASTArraySubscriptExpression)tempNameParent).getArrayExpression(); + return CPPVisitor.getExpressionType(exp); + } + if (tempNameParent instanceof IASTFunctionCallExpression) { + return CPPVisitor.getExpressionType(((IASTFunctionCallExpression) tempNameParent).getFunctionNameExpression()); + } + return null; + } + if (prop == IASTFieldReference.FIELD_NAME) { + ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempNameParent; + IType implied = CPPVisitor.getExpressionType(fieldRef.getFieldOwner()); + IType ultimateImplied= SemanticUtil.getUltimateTypeUptoPointers(implied); + if (fieldRef.isPointerDereference()) { + if (ultimateImplied instanceof ICPPClassType) { + ICPPFunction operator= CPPSemantics.findOperator(fieldRef, (ICPPClassType) ultimateImplied); + if (operator!=null) { + return operator.getType().getReturnType(); + } + } else if (implied instanceof IPointerType) { + return ((IPointerType)implied).getType(); + } + } + return implied; + } + if (prop == IASTIdExpression.ID_NAME) { + IScope scope = CPPVisitor.getContainingScope(tempName); + if (scope instanceof ICPPClassScope) { + return ((ICPPClassScope)scope).getClassType(); + } + + IType implied = CPPVisitor.getThisType(scope); + if (implied instanceof IPointerType) { + return ((IPointerType)implied).getType(); + } + return implied; + } + return null; + } catch (DOMException e) { + return e.getProblem(); } - return implied; } public boolean forFriendship() { diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 6995fe158b5..a465a3ffa62 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -103,6 +103,7 @@ public class CompletionTests extends AbstractContentAssistTest { // C2* m123(); // C2* m12(); // C2* m23(); +// C1* operator()(int x); // //private: // void m2private(); @@ -1147,4 +1148,12 @@ public class CompletionTests extends AbstractContentAssistTest { final String[] expected= {"enum0", "enum1", "enum2"}; assertCompletionResults(expected); } + + // void test() { + // C2 c2; + // c2(1)->iam/*cursor*/ + public void testUserdefinedCallOperator_Bug231277() throws Exception { + final String[] expected= {"iam1()"}; + assertCompletionResults(expected); + } }