From f1542b27c6218771330775dd0820e737fcd0514e Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 13 Feb 2013 00:57:09 -0500 Subject: [PATCH] Bug 399829 - Wrong context for name lookup in dependent expression Change-Id: Iab800a2264c56bdf01498c238b08a2948ca3cfc8 Reviewed-on: https://git.eclipse.org/r/10333 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../parser/tests/ast2/AST2TemplateTests.java | 67 +++++++++ .../cdt/internal/core/dom/parser/Value.java | 10 +- .../cpp/CPPASTArraySubscriptExpression.java | 2 +- .../parser/cpp/CPPASTBinaryExpression.java | 4 +- .../cpp/CPPASTBinaryTypeIdExpression.java | 2 +- .../dom/parser/cpp/CPPASTCastExpression.java | 2 +- .../CPPASTCompoundStatementExpression.java | 2 +- .../cpp/CPPASTConditionalExpression.java | 2 +- .../dom/parser/cpp/CPPASTExpressionList.java | 2 +- .../dom/parser/cpp/CPPASTFieldReference.java | 4 +- .../cpp/CPPASTFunctionCallExpression.java | 4 +- .../dom/parser/cpp/CPPASTInitializerList.java | 2 +- ...CPPASTSimpleTypeConstructorExpression.java | 5 +- .../parser/cpp/CPPASTTypeIdExpression.java | 2 +- .../CPPASTTypeIdInitializerExpression.java | 2 +- .../dom/parser/cpp/CPPASTUnaryExpression.java | 2 +- .../cpp/CPPTemplateNonTypeArgument.java | 2 +- .../core/dom/parser/cpp/ICPPEvaluation.java | 8 + .../cpp/semantics/CPPDependentEvaluation.java | 137 ++++++++++++++++++ .../parser/cpp/semantics/CPPEvaluation.java | 5 + .../parser/cpp/semantics/CPPSemantics.java | 76 ++++++---- .../parser/cpp/semantics/CPPTemplates.java | 20 +-- .../dom/parser/cpp/semantics/EvalBinary.java | 23 ++- .../cpp/semantics/EvalBinaryTypeId.java | 15 +- .../dom/parser/cpp/semantics/EvalBinding.java | 23 ++- .../dom/parser/cpp/semantics/EvalComma.java | 19 ++- .../parser/cpp/semantics/EvalCompound.java | 17 ++- .../parser/cpp/semantics/EvalConditional.java | 20 ++- .../cpp/semantics/EvalFunctionCall.java | 19 ++- .../parser/cpp/semantics/EvalFunctionSet.java | 16 +- .../core/dom/parser/cpp/semantics/EvalID.java | 39 +++-- .../parser/cpp/semantics/EvalInitList.java | 17 ++- .../cpp/semantics/EvalMemberAccess.java | 17 ++- .../dom/parser/cpp/semantics/EvalTypeId.java | 19 ++- .../dom/parser/cpp/semantics/EvalUnary.java | 20 ++- .../parser/cpp/semantics/EvalUnaryTypeID.java | 15 +- .../semantics/TemplateArgumentDeduction.java | 10 +- .../composite/cpp/CPPCompositesFactory.java | 66 +++++---- .../eclipse/cdt/internal/core/pdom/PDOM.java | 8 +- 39 files changed, 536 insertions(+), 189 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 30a2844295d..5b5b5fefb4e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -7202,6 +7202,73 @@ public class AST2TemplateTests extends AST2TestBase { // S::value>::type t; // } public void testVariadicTemplates_401024() throws Exception { + parseAndCheckBindings(); + } + + // struct S { + // void kind(); + // }; + // struct T {}; + // namespace N { + // S operator++(T); + // template + // struct impl { + // static T x; + // typedef decltype(++x) type; + // }; + // } + // void test() { + // N::impl::type operand; + // operand.kind(); // ERROR HERE: Method 'kind' could not be resolved + // } + public void testNameLookupInDependentExpression_399829a() throws Exception { + parseAndCheckBindings(); + } + + // struct S { + // void kind(); + // }; + // namespace N { + // struct tag {}; + // struct any { template any(T); }; + // tag operator++(any); + // tag operator,(tag,int); + // S check(tag); + // int check(int); + // template + // struct impl { + // static T& x; + // typedef decltype(N::check((++x,0))) type; + // }; + // } + // void test() { + // N::impl::type operand; + // operand.kind(); // ERROR HERE: Method 'kind' could not be resolved + // } + public void testNameLookupInDependentExpression_399829b() throws Exception { + parseAndCheckBindings(); + } + + // template int assertion_failed(void*); + // struct assert_ {}; + // assert_ arg; + // char operator==(assert_, assert_); + // template struct assert_relation {}; + // template + // struct concept { + // typedef decltype(assertion_failed((assert_relation*)0)) type; + // }; + // template struct S {}; + // template + // struct is_int + // { + // static const bool value = false; + // }; + // template + // S operator==(T, T*); + // template + // S<(is_int::value)> operator==(T, T); + public void testRegression_399829() throws Exception { parseAndCheckBindings(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java index 8c074ef9932..5a5673d05f8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java @@ -56,6 +56,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; @@ -234,10 +235,11 @@ public class Value implements IValue { } /** - * Creates a value representing the given template parameter. + * Creates a value representing the given template parameter + * in the given template. */ - public static IValue create(ICPPTemplateNonTypeParameter tntp) { - EvalBinding eval = new EvalBinding(tntp, null); + public static IValue create(ICPPTemplateDefinition template, ICPPTemplateNonTypeParameter tntp) { + EvalBinding eval = new EvalBinding(tntp, null, template); return new Value(null, eval); } @@ -284,7 +286,7 @@ public class Value implements IValue { } ICPPEvaluation arg1 = value.getEvaluation(); EvalFixed arg2 = new EvalFixed(INT_TYPE, ValueCategory.PRVALUE, create(increment)); - return create(new EvalBinary(IASTBinaryExpression.op_plus, arg1, arg2)); + return create(new EvalBinary(IASTBinaryExpression.op_plus, arg1, arg2, arg1.getTemplateDefinition())); } private static Number applyUnaryTypeIdOperator(int operator, IType type, IASTNode point) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java index 111aee3c912..2068c5b6ef5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java @@ -197,7 +197,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode private ICPPEvaluation computeEvaluation() { if (arrayExpression == null || subscriptExp == null) return EvalFixed.INCOMPLETE; - return new EvalBinary(EvalBinary.op_arrayAccess, arrayExpression.getEvaluation(), subscriptExp.getEvaluation()); + return new EvalBinary(EvalBinary.op_arrayAccess, arrayExpression.getEvaluation(), subscriptExp.getEvaluation(), this); } @Override 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 f8d836931c9..d53a27e9918 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 @@ -274,8 +274,8 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr private ICPPEvaluation computeEvaluation() { if (operand1 == null || operand2 == null) return EvalFixed.INCOMPLETE; - - return new EvalBinary(op, operand1.getEvaluation(), operand2.getEvaluation()); + + return new EvalBinary(op, operand1.getEvaluation(), operand2.getEvaluation(), this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java index 916731241c1..8f66d94a242 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java @@ -128,7 +128,7 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr if (t1 == null || t2 == null) { fEvaluation= EvalFixed.INCOMPLETE; } else { - fEvaluation= new EvalBinaryTypeId(fOperator, t1, t2); + fEvaluation= new EvalBinaryTypeId(fOperator, t1, t2, this); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java index f1cf7b966f8..456e6263699 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java @@ -155,7 +155,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi if (type == null || type instanceof IProblemType) return EvalFixed.INCOMPLETE; - return new EvalTypeId(type, operand.getEvaluation()); + return new EvalTypeId(type, this, operand.getEvaluation()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java index 8d363e18898..623b8436c5c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java @@ -42,7 +42,7 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS if (statements.length > 0) { IASTStatement st = statements[statements.length - 1]; if (st instanceof IASTExpressionStatement) { - fEval= new EvalCompound(((ICPPASTExpression) ((IASTExpressionStatement) st).getExpression()).getEvaluation()); + fEval= new EvalCompound(((ICPPASTExpression) ((IASTExpressionStatement) st).getExpression()).getEvaluation(), this); } } if (fEval == null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java index cbc866f92a6..4b2f09961b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java @@ -170,7 +170,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio final ICPPEvaluation condEval = fCondition.getEvaluation(); final ICPPEvaluation posEval = fPositive == null ? null : fPositive.getEvaluation(); fEval= new EvalConditional(condEval, posEval, fNegative.getEvaluation(), - isThrowExpression(fPositive), isThrowExpression(fNegative)); + isThrowExpression(fPositive), isThrowExpression(fNegative), this); } } return fEval; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java index 17a3cde3860..9f14ca221b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java @@ -178,7 +178,7 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi for (int i = 0; i < evals.length; i++) { evals[i]= ((ICPPASTExpression) exprs[i]).getEvaluation(); } - return new EvalComma(evals); + return new EvalComma(evals, this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index 827e8d992c7..d90230333e2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -260,7 +260,7 @@ public class CPPASTFieldReference extends ASTNode if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor) return EvalFixed.INCOMPLETE; - return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, isDeref); + return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, isDeref, this); } } @@ -283,7 +283,7 @@ public class CPPASTFieldReference extends ASTNode return EvalFixed.INCOMPLETE; } } - return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, true, args); + return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, true, args, this); } @Override 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 555bba47128..269d24c139a 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 @@ -303,7 +303,7 @@ public class CPPASTFunctionCallExpression extends ASTNode for (int i = 1; i < args.length; i++) { args[i]= ((ICPPASTInitializerClause) fArguments[i - 1]).getEvaluation(); } - return new EvalFunctionCall(args); + return new EvalFunctionCall(args, this); } private ICPPEvaluation checkForExplicitTypeConversion() { @@ -315,7 +315,7 @@ public class CPPASTFunctionCallExpression extends ASTNode for (int i = 0; i < args.length; i++) { args[i]= ((ICPPASTInitializerClause) fArguments[i]).getEvaluation(); } - return new EvalTypeId((IType) b, args); + return new EvalTypeId((IType) b, this, args); } } return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java index 1556865508f..08858266359 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java @@ -172,6 +172,6 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer for (int i = 0; i < evals.length; i++) { evals[i]= clauses[i].getEvaluation(); } - return new EvalInitList(evals); + return new EvalInitList(evals, this); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java index adb1ad1db1b..375b6a8a4a3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java @@ -100,9 +100,10 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements for (int i = 0; i < a.length; i++) { args[i]= ((ICPPASTInitializerClause) a[i]).getEvaluation(); } - fEvaluation= new EvalTypeId(type, args); + fEvaluation= new EvalTypeId(type, this, args); } else if (fInitializer instanceof ICPPASTInitializerList) { - fEvaluation= new EvalTypeId(type, ((ICPPASTInitializerList) fInitializer).getEvaluation()); + fEvaluation= new EvalTypeId(type, this, + ((ICPPASTInitializerList) fInitializer).getEvaluation()); } else { fEvaluation= EvalFixed.INCOMPLETE; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java index 5de9d648038..fee516ec4fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java @@ -103,7 +103,7 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr if (type == null || type instanceof IProblemType) { fEvaluation= EvalFixed.INCOMPLETE; } else { - fEvaluation= new EvalUnaryTypeID(op, type); + fEvaluation= new EvalUnaryTypeID(op, type, this); } } return fEvaluation; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java index b4c7e7e523d..7330c3f81ec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java @@ -65,7 +65,7 @@ public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpre if (type == null || type instanceof IProblemType) return EvalFixed.INCOMPLETE; - return new EvalTypeId(type, ((ICPPASTInitializerClause) initializer).getEvaluation()); + return new EvalTypeId(type, this, ((ICPPASTInitializerClause) initializer).getEvaluation()); } @Override 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 5176d296cf5..9a68aad31bd 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 @@ -204,7 +204,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres return EvalFixed.INCOMPLETE; } } - return new EvalUnary(fOperator, nestedEval, addressOfQualifiedNameBinding); + return new EvalUnary(fOperator, nestedEval, addressOfQualifiedNameBinding, this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java index 73129221962..d18ff891a0e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java @@ -94,7 +94,7 @@ public class CPPTemplateNonTypeArgument implements ICPPTemplateArgument { EvalFixed fixed = (EvalFixed) fEvaluation; evaluation = new EvalFixed(t, fixed.getValueCategory(), fixed.getValue()); } else { - evaluation = new EvalTypeId(t, fEvaluation); + evaluation = new EvalTypeId(t, fEvaluation.getTemplateDefinition(), fEvaluation); } return new CPPTemplateNonTypeArgument(evaluation, null); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java index 043325baa46..0a4fc340f15 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; @@ -104,4 +105,11 @@ public interface ICPPEvaluation extends ISerializableEvaluation { * evaluations. */ boolean referencesTemplateParameter(); + + /** + * If the evaluation is dependent (or instantiated from a dependent + * evaluation), returns the template definition in which the + * evaluation occurs. Otherwise returns null. + */ + IBinding getTemplateDefinition(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java new file mode 100644 index 00000000000..650a36cc4bb --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nathan Ridge + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.PlatformObject; + +/** + * Base class for evaluations that are dependent, or that have been instantiated + * from a dependent evaluation. These evaluations keep track of the template + * in which they are defined, so that certain name lookups can be performed + * starting from their point of definition. + */ +public abstract class CPPDependentEvaluation extends CPPEvaluation { + + private IBinding fTemplateDefinition; + private IScope fTemplateDefinitionScope; + + CPPDependentEvaluation(IBinding templateDefinition) { + fTemplateDefinition = templateDefinition; + } + + @Override + public IBinding getTemplateDefinition() { + if (fTemplateDefinition instanceof DeferredResolutionBinding) { + IBinding toResolve = fTemplateDefinition; + // While resolve() is called, set fTemplateDefinition to null to avoid + // infinite recursion in some cases where the resolution process ends + // up (indirectly) calling getTemplateDefinition() on this evaluation. + fTemplateDefinition = null; + fTemplateDefinition = ((DeferredResolutionBinding) toResolve).resolve(); + } + return fTemplateDefinition; + } + + protected IScope getTemplateDefinitionScope() { + if (fTemplateDefinitionScope == null) { + IBinding templateDefinition = getTemplateDefinition(); + if (templateDefinition != null) { + if (templateDefinition instanceof ICPPClassType) { + fTemplateDefinitionScope = ((ICPPClassType) templateDefinition).getCompositeScope(); + } + try { + fTemplateDefinitionScope = templateDefinition.getScope(); + } catch (DOMException e) { + } + } + } + return fTemplateDefinitionScope; + } + + /** + * If the given node is contained in some template declaration, + * return the binding for that template. Otherwise return null. + */ + protected static IBinding findEnclosingTemplate(IASTNode node) { + while (node != null) { + if (node instanceof ICPPASTTemplateDeclaration) { + ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) node; + IASTName templateName = CPPTemplates.getTemplateName(templateDecl); + if (templateName == null) + return null; + return new DeferredResolutionBinding(templateName); + } + node = node.getParent(); + } + return null; + } + + protected void marshalTemplateDefinition(ITypeMarshalBuffer buffer) throws CoreException { + // Don't marshal the template definition when building a signature. + // While the template definition needs to be stored in the index, it does not + // need to be part of the signature, and trying to resolve it at the time a + // signature is built sometimes causes recursion (as the call to resolve() + // may end up needing the signature). + if (!(buffer instanceof SignatureBuilder)) + buffer.marshalBinding(getTemplateDefinition()); + } + + /** + * Used to defer the resolution of a template definition until it is needed, + * to avoid recursion. The only valid operation on this binding is resolve(). + */ + private static class DeferredResolutionBinding extends PlatformObject implements IBinding { + private final IASTName fName; + + public DeferredResolutionBinding(IASTName name) { + fName = name; + } + + public IBinding resolve() { + return fName.resolveBinding(); + } + + @Override + public String getName() { + throw new UnsupportedOperationException(); + } + + @Override + public char[] getNameCharArray() { + throw new UnsupportedOperationException(); + } + + @Override + public ILinkage getLinkage() { + throw new UnsupportedOperationException(); + } + + @Override + public IBinding getOwner() { + throw new UnsupportedOperationException(); + } + + @Override + public IScope getScope() throws DOMException { + throw new UnsupportedOperationException(); + } + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index c68c28a7f23..99d2bf6d6c2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -27,6 +27,11 @@ public abstract class CPPEvaluation implements ICPPEvaluation { CPPEvaluation() { } + @Override + public IBinding getTemplateDefinition() { + return null; + } + @Override public char[] getSignature() { SignatureBuilder buf = new SignatureBuilder(); 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 70ca109fd0e..126a1dd02a6 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 @@ -391,7 +391,7 @@ public class CPPSemantics { if (CPPTemplates.areSameArguments(((ICPPClassTemplatePartialSpecialization) usedHere).getTemplateArguments(), dcl.getTemplateArguments())) binding= ((ICPPClassTemplatePartialSpecialization) usedHere).asDeferredInstance(); } else if (usedHere instanceof ICPPClassTemplate) { - if (CPPTemplates.areSameArguments(CPPTemplates.templateParametersAsArguments(((ICPPClassTemplate) usedHere).getTemplateParameters()), dcl.getTemplateArguments())) { + if (CPPTemplates.areSameArguments(CPPTemplates.templateParametersAsArguments((ICPPClassTemplate) usedHere), dcl.getTemplateArguments())) { binding= ((ICPPClassTemplate) usedHere).asDeferredInstance(); } } @@ -2503,9 +2503,10 @@ public class CPPSemantics { isCandidate= true; } else { // See 14.3-7 - final ICPPTemplateParameter[] tpars = ((ICPPFunctionTemplate) f).getTemplateParameters(); + ICPPFunctionTemplate funcTemp = (ICPPFunctionTemplate) f; + final ICPPTemplateParameter[] tpars = funcTemp.getTemplateParameters(); final CPPTemplateParameterMap map = new CPPTemplateParameterMap(tpars.length); - isCandidate= TemplateArgumentDeduction.addExplicitArguments(tpars, args, map, point); + isCandidate= TemplateArgumentDeduction.addExplicitArguments(funcTemp, tpars, args, map, point); } } else { isCandidate= args == null; @@ -2981,14 +2982,14 @@ public class CPPSemantics { return result; } - public static ICPPFunction findOverloadedBinaryOperator(IASTNode point, OverloadableOperator op, - ICPPEvaluation arg1, ICPPEvaluation arg2) { + public static ICPPFunction findOverloadedBinaryOperator(IASTNode pointOfInstantiation, IScope pointOfDefinition, + OverloadableOperator op, ICPPEvaluation arg1, ICPPEvaluation arg2) { if (op == null || arg1 == null || arg2 == null) return null; - IType op1type = getNestedType(arg1.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE); + IType op1type = getNestedType(arg1.getTypeOrFunctionSet(pointOfInstantiation), TDEF | REF | CVTYPE); if (!isUserDefined(op1type) && !isUserDefined( - getNestedType(arg2.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE))) + getNestedType(arg2.getTypeOrFunctionSet(pointOfInstantiation), TDEF | REF | CVTYPE))) return null; final LookupMode lookupNonMember; @@ -2997,7 +2998,7 @@ public class CPPSemantics { } else { lookupNonMember= LookupMode.LIMITED_GLOBALS; } - return findOverloadedOperator(point, new ICPPEvaluation[] {arg1, arg2}, + return findOverloadedOperator(pointOfInstantiation, pointOfDefinition, new ICPPEvaluation[] {arg1, arg2}, op1type, op, lookupNonMember); } @@ -3008,8 +3009,8 @@ public class CPPSemantics { return null; final IASTInitializerClause[] placement = expr.getPlacementArguments(); - final ICPPEvaluation arg1= new EvalUnary(IASTUnaryExpression.op_star, evaluation, null); - final ICPPEvaluation arg2= new EvalUnary(IASTUnaryExpression.op_sizeof, evaluation, null); + final ICPPEvaluation arg1= new EvalUnary(IASTUnaryExpression.op_star, evaluation, null, expr); + final ICPPEvaluation arg2= new EvalUnary(IASTUnaryExpression.op_sizeof, evaluation, null, expr); ICPPEvaluation[] args; if (placement == null) { @@ -3028,7 +3029,7 @@ public class CPPSemantics { } } IType type= getNestedType(arg1.getTypeOrFunctionSet(expr), TDEF | REF | CVTYPE); - return findOverloadedOperator(expr, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS); + return findOverloadedOperator(expr, null, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS); } public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression expr) { @@ -3041,7 +3042,7 @@ public class CPPSemantics { new EvalFixed(type, LVALUE, Value.UNKNOWN), ((ICPPASTExpression) expr.getOperand()).getEvaluation() }; - return findOverloadedOperator(expr, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS); + return findOverloadedOperator(expr, null, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS); } private static IType getTypeOfPointer(IType type) { @@ -3235,9 +3236,10 @@ public class CPPSemantics { /** * For simplicity returns an operator of form RT (T, T) rather than RT (boolean, T, T) */ - public static ICPPFunction findOverloadedConditionalOperator(IASTNode point, ICPPEvaluation positive, ICPPEvaluation negative) { + public static ICPPFunction findOverloadedConditionalOperator(IASTNode pointOfInstantiation, IScope pointOfDefinition, + ICPPEvaluation positive, ICPPEvaluation negative) { final ICPPEvaluation[] args = new ICPPEvaluation[] {positive, negative}; - return findOverloadedOperator(point, args, null, + return findOverloadedOperator(pointOfInstantiation, pointOfDefinition, args, null, OverloadableOperator.CONDITIONAL_OPERATOR, LookupMode.NO_GLOBALS); } @@ -3245,27 +3247,29 @@ public class CPPSemantics { * Returns the operator,() function that would apply to the two given arguments. * The lookup type of the class where the operator,() might be found must also be provided. */ - public static ICPPFunction findOverloadedOperatorComma(IASTNode point, ICPPEvaluation arg1, ICPPEvaluation arg2) { - IType op1type = getNestedType(arg1.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE); - IType op2type = getNestedType(arg2.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE); + public static ICPPFunction findOverloadedOperatorComma(IASTNode pointOfInstantiation, IScope pointOfDefinition, + ICPPEvaluation arg1, ICPPEvaluation arg2) { + IType op1type = getNestedType(arg1.getTypeOrFunctionSet(pointOfInstantiation), TDEF | REF | CVTYPE); + IType op2type = getNestedType(arg2.getTypeOrFunctionSet(pointOfInstantiation), TDEF | REF | CVTYPE); if (!isUserDefined(op1type) && !isUserDefined(op2type)) return null; ICPPEvaluation[] args = { arg1 , arg2 }; - return findOverloadedOperator(point, args, op1type, OverloadableOperator.COMMA, LookupMode.LIMITED_GLOBALS); + return findOverloadedOperator(pointOfInstantiation, pointOfDefinition, args, op1type, + OverloadableOperator.COMMA, LookupMode.LIMITED_GLOBALS); } static enum LookupMode {NO_GLOBALS, GLOBALS_IF_NO_MEMBERS, LIMITED_GLOBALS, ALL_GLOBALS} - static ICPPFunction findOverloadedOperator(IASTNode point, ICPPEvaluation[] args, IType methodLookupType, - OverloadableOperator operator, LookupMode mode) { - while (point instanceof IASTName) - point= point.getParent(); + static ICPPFunction findOverloadedOperator(IASTNode pointOfInstantiation, IScope pointOfDefinition, + ICPPEvaluation[] args, IType methodLookupType, OverloadableOperator operator, LookupMode mode) { + while (pointOfInstantiation instanceof IASTName) + pointOfInstantiation= pointOfInstantiation.getParent(); ICPPClassType callToObjectOfClassType= null; IType type2= null; if (args.length >= 2) { - type2 = args[1].getTypeOrFunctionSet(point); + type2 = args[1].getTypeOrFunctionSet(pointOfInstantiation); type2= getNestedType(type2, TDEF | REF | CVTYPE); } @@ -3275,7 +3279,7 @@ public class CPPSemantics { return null; if (methodLookupType instanceof ICPPClassType) { ICPPClassType classType = (ICPPClassType) methodLookupType; - methodData = new LookupData(operator.toCharArray(), null, point); + methodData = new LookupData(operator.toCharArray(), null, pointOfInstantiation); methodData.setFunctionArguments(true, args); methodData.qualified = true; // (13.3.1.2.3) @@ -3294,7 +3298,7 @@ public class CPPSemantics { } // Find a function - LookupData funcData = new LookupData(operator.toCharArray(), null, point); + LookupData funcData = new LookupData(operator.toCharArray(), null, pointOfInstantiation); // Global new and delete operators do not take an argument for the this pointer. switch (operator) { @@ -3311,7 +3315,7 @@ public class CPPSemantics { if (mode == LookupMode.ALL_GLOBALS || mode == LookupMode.LIMITED_GLOBALS || (mode == LookupMode.GLOBALS_IF_NO_MEMBERS && !haveMembers)) { try { - IScope scope = CPPVisitor.getContainingScope(point); + IScope scope = CPPVisitor.getContainingScope(pointOfInstantiation); if (scope == null) return null; lookup(funcData, scope); @@ -3319,8 +3323,20 @@ public class CPPSemantics { doKoenigLookup(funcData); } catch (DOMException e) { } + + // Also do a lookup at the point of definition. + if (pointOfDefinition != null) { + LookupData funcData2 = new LookupData(operator.toCharArray(), null, pointOfInstantiation); + funcData2.setFunctionArguments(true, args); + funcData2.ignoreMembers = true; + lookup(funcData2, pointOfDefinition); + if (funcData2.hasResults()) { + mergeResults(funcData, funcData2.foundItems, false); + } + } + // Filter with file-set - IASTTranslationUnit tu= point.getTranslationUnit(); + IASTTranslationUnit tu= pointOfInstantiation.getTranslationUnit(); if (tu != null && funcData.foundItems instanceof Object[]) { final IIndexFileSet fileSet = tu.getIndexFileSet(); if (fileSet != null) { @@ -3395,7 +3411,7 @@ public class CPPSemantics { if (callToObjectOfClassType != null) { try { // 13.3.1.1.2 call to object of class type - ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType, point); + ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType, pointOfInstantiation); for (ICPPMethod op : ops) { if (op.isExplicit()) continue; @@ -3406,7 +3422,7 @@ public class CPPSemantics { IType ptt= SemanticUtil.getNestedType(((IPointerType) rt).getType(), SemanticUtil.TDEF); if (ptt instanceof IFunctionType) { IFunctionType ft2= (IFunctionType) ptt; - IBinding sf= createSurrogateCallFunction(point.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes()); + IBinding sf= createSurrogateCallFunction(pointOfInstantiation.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes()); mergeResults(funcData, sf, false); } } @@ -3418,7 +3434,7 @@ public class CPPSemantics { } if (methodLookupType instanceof ICPPClassType || type2 instanceof ICPPClassType) { - ICPPFunction[] builtins= BuiltinOperators.create(operator, args, point, (Object[]) funcData.foundItems); + ICPPFunction[] builtins= BuiltinOperators.create(operator, args, pointOfInstantiation, (Object[]) funcData.foundItems); mergeResults(funcData, builtins, false); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index a1421067623..0069e6758bf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -231,7 +231,7 @@ public class CPPTemplates { } if (i < numArgs) { ICPPTemplateArgument arg= arguments[i]; - ICPPTemplateArgument newArg = matchTemplateParameterAndArgument(param, arg, map, point); + ICPPTemplateArgument newArg = matchTemplateParameterAndArgument(template, param, arg, map, point); if (newArg == null) return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point); if (newArg != arg) { @@ -499,12 +499,13 @@ public class CPPTemplates { if (ct instanceof ICPPClassTemplatePartialSpecialization) { args= ((ICPPClassTemplatePartialSpecialization) ct).getTemplateArguments(); } else { - args = templateParametersAsArguments(ct.getTemplateParameters()); + args = templateParametersAsArguments(ct); } return new CPPDeferredClassInstance(ct, args, (ICPPScope) ct.getCompositeScope()); } - public static ICPPTemplateArgument[] templateParametersAsArguments(ICPPTemplateParameter[] tpars) { + public static ICPPTemplateArgument[] templateParametersAsArguments(ICPPClassTemplate template) { + ICPPTemplateParameter[] tpars = template.getTemplateParameters(); ICPPTemplateArgument[] args; args = new ICPPTemplateArgument[tpars.length]; for (int i = 0; i < tpars.length; i++) { @@ -518,7 +519,7 @@ public class CPPTemplates { } else if (tp instanceof ICPPTemplateNonTypeParameter) { // Non-type template parameter pack already has type 'ICPPParameterPackType' final ICPPTemplateNonTypeParameter nttp = (ICPPTemplateNonTypeParameter) tp; - args[i] = new CPPTemplateNonTypeArgument(Value.create(nttp), nttp.getType()); + args[i] = new CPPTemplateNonTypeArgument(Value.create(template, nttp), nttp.getType()); } else { assert false; } @@ -2274,8 +2275,8 @@ public class CPPTemplates { return arg != null && isValidType(arg.isTypeValue() ? arg.getTypeValue() : arg.getTypeOfNonTypeValue()); } - static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param, - ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) { + static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateDefinition template, + ICPPTemplateParameter param, ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) { if (arg == null || !isValidType(arg.getTypeValue())) { return null; } @@ -2331,7 +2332,7 @@ public class CPPTemplates { if (argType instanceof ICPPUnknownType) { return new CPPTemplateNonTypeArgument(arg.getNonTypeValue(), pType); } - return convertNonTypeTemplateArgument(pType, arg, point); + return convertNonTypeTemplateArgument(template, pType, arg, point); } catch (DOMException e) { return null; } @@ -2399,7 +2400,8 @@ public class CPPTemplates { * specified in 14.3.2 - 5. * @throws DOMException */ - private static ICPPTemplateArgument convertNonTypeTemplateArgument(final IType paramType, ICPPTemplateArgument arg, IASTNode point) throws DOMException { + private static ICPPTemplateArgument convertNonTypeTemplateArgument(ICPPTemplateDefinition template, + final IType paramType, ICPPTemplateArgument arg, IASTNode point) throws DOMException { //14.1s8 function to pointer and array to pointer conversions IType a= arg.getTypeOfNonTypeValue(); IType p; @@ -2422,7 +2424,7 @@ public class CPPTemplates { for (ICPPFunction f : functionSet.getBindings()) { if (p.isSameType(f.getType())) { functionSet.applySelectedFunction(f); - return new CPPTemplateNonTypeArgument(new EvalBinding(f, null), point); + return new CPPTemplateNonTypeArgument(new EvalBinding(f, null, template), point); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java index b80e21c6f32..bb919a9960d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -46,6 +46,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; @@ -70,7 +71,7 @@ import org.eclipse.core.runtime.CoreException; /** * Performs evaluation of an expression. */ -public class EvalBinary extends CPPEvaluation { +public class EvalBinary extends CPPDependentEvaluation { public final static int op_arrayAccess= Byte.MAX_VALUE; private final int fOperator; @@ -80,7 +81,11 @@ public class EvalBinary extends CPPEvaluation { private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION; private IType fType; - public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2) { + public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2, IASTNode pointOfDefinition) { + this(operator, arg1, arg2, findEnclosingTemplate(pointOfDefinition)); + } + public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2, IBinding templateDefinition) { + super(templateDefinition); fOperator= operator; fArg1= arg1; fArg2= arg2; @@ -234,12 +239,14 @@ public class EvalBinary extends CPPEvaluation { IType type = fArg1.getTypeOrFunctionSet(point); type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); if (type instanceof ICPPClassType) { - return CPPSemantics.findOverloadedBinaryOperator(point, OverloadableOperator.BRACKET, fArg1, fArg2); + return CPPSemantics.findOverloadedBinaryOperator(point, getTemplateDefinitionScope(), + OverloadableOperator.BRACKET, fArg1, fArg2); } } else { final OverloadableOperator op = OverloadableOperator.fromBinaryExpression(fOperator); if (op != null) { - return CPPSemantics.findOverloadedBinaryOperator(point, op, fArg1, fArg2); + return CPPSemantics.findOverloadedBinaryOperator(point, getTemplateDefinitionScope(), + op, fArg1, fArg2); } } return null; @@ -328,13 +335,15 @@ public class EvalBinary extends CPPEvaluation { buffer.putByte((byte) fOperator); buffer.marshalEvaluation(fArg1, includeValue); buffer.marshalEvaluation(fArg2, includeValue); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { int op= buffer.getByte(); ICPPEvaluation arg1= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation arg2= (ICPPEvaluation) buffer.unmarshalEvaluation(); - return new EvalBinary(op, arg1, arg2); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalBinary(op, arg1, arg2, templateDefinition); } @Override @@ -344,7 +353,7 @@ public class EvalBinary extends CPPEvaluation { ICPPEvaluation arg2 = fArg2.instantiate(tpMap, packOffset, within, maxdepth, point); if (arg1 == fArg1 && arg2 == fArg2) return this; - return new EvalBinary(fOperator, arg1, arg2); + return new EvalBinary(fOperator, arg1, arg2, getTemplateDefinition()); } @Override @@ -354,7 +363,7 @@ public class EvalBinary extends CPPEvaluation { ICPPEvaluation arg2 = fArg2.computeForFunctionCall(parameterMap, maxdepth, point); if (arg1 == fArg1 && arg2 == fArg2) return this; - return new EvalBinary(fOperator, arg1, arg2); + return new EvalBinary(fOperator, arg1, arg2, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java index 98dac57bcd6..8521bfa51c1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java @@ -16,6 +16,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression.Operator; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; @@ -31,14 +32,18 @@ import org.eclipse.core.runtime.CoreException; /** * Performs evaluation of an expression. */ -public class EvalBinaryTypeId extends CPPEvaluation { +public class EvalBinaryTypeId extends CPPDependentEvaluation { private final Operator fOperator; private final IType fType1, fType2; private boolean fCheckedValueDependent; private boolean fIsValueDependent; - public EvalBinaryTypeId(Operator kind, IType type1, IType type2) { + public EvalBinaryTypeId(Operator kind, IType type1, IType type2, IASTNode pointOfDefinition) { + this(kind, type1, type2, findEnclosingTemplate(pointOfDefinition)); + } + public EvalBinaryTypeId(Operator kind, IType type1, IType type2, IBinding templateDefinition) { + super(templateDefinition); fOperator= kind; fType1= type1; fType2= type2; @@ -108,13 +113,15 @@ public class EvalBinaryTypeId extends CPPEvaluation { buffer.putByte((byte) fOperator.ordinal()); buffer.marshalType(fType1); buffer.marshalType(fType2); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { int op= buffer.getByte(); IType arg1= buffer.unmarshalType(); IType arg2= buffer.unmarshalType(); - return new EvalBinaryTypeId(Operator.values()[op], arg1, arg2); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalBinaryTypeId(Operator.values()[op], arg1, arg2, templateDefinition); } @Override @@ -124,7 +131,7 @@ public class EvalBinaryTypeId extends CPPEvaluation { IType type2 = CPPTemplates.instantiateType(fType2, tpMap, packOffset, within, point); if (type1 == fType1 && type2 == fType2) return this; - return new EvalBinaryTypeId(fOperator, type1, type2); + return new EvalBinaryTypeId(fOperator, type1, type2, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index d8567779e1e..17a09e84790 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -43,7 +43,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.core.runtime.CoreException; -public class EvalBinding extends CPPEvaluation { +public class EvalBinding extends CPPDependentEvaluation { /** * The function owning the parameter if the binding is a function parameter, otherwise * {@code null}. May be computed lazily and remains {@code null} until computed. @@ -68,14 +68,22 @@ public class EvalBinding extends CPPEvaluation { private boolean fIsTypeDependent; private boolean fCheckedIsTypeDependent; - public EvalBinding(IBinding binding, IType type) { + public EvalBinding(IBinding binding, IType type, IASTNode pointOfDefinition) { + this(binding, type, findEnclosingTemplate(pointOfDefinition)); + } + public EvalBinding(IBinding binding, IType type, IBinding templateDefinition) { + super(templateDefinition); fParameterPosition = -1; fBinding= binding; fType= type; fFixedType= type != null; } - public EvalBinding(ICPPFunction parameterOwner, int parameterPosition, IType type) { + public EvalBinding(ICPPFunction parameterOwner, int parameterPosition, IType type, IASTNode pointOfDefinition) { + this(parameterOwner, parameterPosition, type, findEnclosingTemplate(pointOfDefinition)); + } + public EvalBinding(ICPPFunction parameterOwner, int parameterPosition, IType type, IBinding templateDefinition) { + super(templateDefinition); fParameterOwner = parameterOwner; fParameterPosition = parameterPosition; fType= type; @@ -298,6 +306,7 @@ public class EvalBinding extends CPPEvaluation { buffer.marshalBinding(fBinding); } buffer.marshalType(fFixedType ? fType : null); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -305,11 +314,13 @@ public class EvalBinding extends CPPEvaluation { ICPPFunction parameterOwner= (ICPPFunction) buffer.unmarshalBinding(); int parameterPosition= buffer.getInt(); IType type= buffer.unmarshalType(); - return new EvalBinding(parameterOwner, parameterPosition, type); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalBinding(parameterOwner, parameterPosition, type, templateDefinition); } else { IBinding binding= buffer.unmarshalBinding(); IType type= buffer.unmarshalType(); - return new EvalBinding(binding, type); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalBinding(binding, type, templateDefinition); } } @@ -333,7 +344,7 @@ public class EvalBinding extends CPPEvaluation { } else { IBinding instantiatedBinding = instantiateBinding(origBinding, tpMap, packOffset, within, maxdepth, point); if (instantiatedBinding != origBinding) - return new EvalBinding(instantiatedBinding, null); + return new EvalBinding(instantiatedBinding, null, getTemplateDefinition()); } return this; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java index b1821c5926a..889a2f0ce07 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java @@ -16,6 +16,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionT import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; @@ -28,7 +29,7 @@ import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.core.runtime.CoreException; -public class EvalComma extends CPPEvaluation { +public class EvalComma extends CPPDependentEvaluation { private static final ICPPFunction[] NO_FUNCTIONS = {}; private final ICPPEvaluation[] fArguments; @@ -36,7 +37,11 @@ public class EvalComma extends CPPEvaluation { private IType fType; - public EvalComma(ICPPEvaluation[] evals) { + public EvalComma(ICPPEvaluation[] evals, IASTNode pointOfDefinition) { + this(evals, findEnclosingTemplate(pointOfDefinition)); + } + public EvalComma(ICPPEvaluation[] evals, IBinding templateDefinition) { + super(templateDefinition); fArguments= evals; } @@ -93,7 +98,7 @@ public class EvalComma extends CPPEvaluation { ICPPEvaluation e1= fArguments[0]; for (int i = 1; i < fArguments.length; i++) { ICPPEvaluation e2 = fArguments[i]; - ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(point, e1, e2); + ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(point, getTemplateDefinitionScope(), e1, e2); if (overload == null) { e1= e2; } else { @@ -159,6 +164,7 @@ public class EvalComma extends CPPEvaluation { for (ICPPEvaluation arg : fArguments) { buffer.marshalEvaluation(arg, includeValue); } + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -167,7 +173,8 @@ public class EvalComma extends CPPEvaluation { for (int i = 0; i < args.length; i++) { args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); } - return new EvalComma(args); + IBinding templateDefinition = buffer.unmarshalBinding(); + return new EvalComma(args, templateDefinition); } @Override @@ -186,7 +193,7 @@ public class EvalComma extends CPPEvaluation { } if (args == fArguments) return this; - return new EvalComma(args); + return new EvalComma(args, getTemplateDefinition()); } @Override @@ -205,7 +212,7 @@ public class EvalComma extends CPPEvaluation { } if (args == fArguments) return this; - return new EvalComma(args); + return new EvalComma(args, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java index 280e0f05d4b..6e8f0486710 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java @@ -15,6 +15,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; @@ -28,10 +29,14 @@ import org.eclipse.core.runtime.CoreException; * Performs evaluation of a compound statement expression. Most but not all methods * delegate to the evaluation of the last expression in the compound one. */ -public class EvalCompound extends CPPEvaluation { +public class EvalCompound extends CPPDependentEvaluation { private final ICPPEvaluation fDelegate; - public EvalCompound(ICPPEvaluation delegate) { + public EvalCompound(ICPPEvaluation delegate, IASTNode pointOfDefinition) { + this(delegate, findEnclosingTemplate(pointOfDefinition)); + } + public EvalCompound(ICPPEvaluation delegate, IBinding templateDefinition) { + super(templateDefinition); fDelegate= delegate; } @@ -78,11 +83,13 @@ public class EvalCompound extends CPPEvaluation { public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { buffer.putByte(ITypeMarshalBuffer.EVAL_COMPOUND); buffer.marshalEvaluation(fDelegate, includeValue); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation(); - return new EvalCompound(arg); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalCompound(arg, templateDefinition); } @Override @@ -91,7 +98,7 @@ public class EvalCompound extends CPPEvaluation { ICPPEvaluation delegate = fDelegate.instantiate(tpMap, packOffset, within, maxdepth, point); if (delegate == fDelegate) return this; - return new EvalCompound(delegate); + return new EvalCompound(delegate, getTemplateDefinition()); } @Override @@ -100,7 +107,7 @@ public class EvalCompound extends CPPEvaluation { ICPPEvaluation delegate = fDelegate.computeForFunctionCall(parameterMap, maxdepth, point); if (delegate == fDelegate) return this; - return new EvalCompound(delegate); + return new EvalCompound(delegate, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java index 393c1f7c372..c130d0f763b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; @@ -47,7 +48,7 @@ import org.eclipse.core.runtime.CoreException; /** * Performs evaluation of an expression. */ -public class EvalConditional extends CPPEvaluation { +public class EvalConditional extends CPPDependentEvaluation { private final ICPPEvaluation fCondition, fPositive, fNegative; private final boolean fPositiveThrows, fNegativeThrows; @@ -56,7 +57,12 @@ public class EvalConditional extends CPPEvaluation { private ICPPFunction fOverload; public EvalConditional(ICPPEvaluation condition, ICPPEvaluation positive, ICPPEvaluation negative, - boolean positiveThrows, boolean negativeThrows) { + boolean positiveThrows, boolean negativeThrows, IASTNode pointOfDefinition) { + this(condition, positive, negative, positiveThrows, negativeThrows, findEnclosingTemplate(pointOfDefinition)); + } + public EvalConditional(ICPPEvaluation condition, ICPPEvaluation positive, ICPPEvaluation negative, + boolean positiveThrows, boolean negativeThrows, IBinding templateDefinition) { + super(templateDefinition); // Gnu-extension: Empty positive expression is replaced by condition. fCondition= condition; fPositive= positive; @@ -229,7 +235,7 @@ public class EvalConditional extends CPPEvaluation { // 5.16-5: At least one class type but no conversion if (isClassType2 || isClassType3) { - fOverload = CPPSemantics.findOverloadedConditionalOperator(point, positive, fNegative); + fOverload = CPPSemantics.findOverloadedConditionalOperator(point, getTemplateDefinitionScope(), positive, fNegative); if (fOverload != null) { fType= ExpressionTypes.typeFromFunctionCall(fOverload); } else { @@ -313,6 +319,7 @@ public class EvalConditional extends CPPEvaluation { buffer.marshalEvaluation(fCondition, includeValue); buffer.marshalEvaluation(fPositive, includeValue); buffer.marshalEvaluation(fNegative, includeValue); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -321,7 +328,8 @@ public class EvalConditional extends CPPEvaluation { ICPPEvaluation cond= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation pos= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation neg= (ICPPEvaluation) buffer.unmarshalEvaluation(); - return new EvalConditional(cond, pos, neg, pth, nth); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalConditional(cond, pos, neg, pth, nth, templateDefinition); } @Override @@ -333,7 +341,7 @@ public class EvalConditional extends CPPEvaluation { ICPPEvaluation negative = fNegative.instantiate(tpMap, packOffset, within, maxdepth, point); if (condition == fCondition && positive == fPositive && negative == fNegative) return this; - return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows); + return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows, getTemplateDefinition()); } @Override @@ -345,7 +353,7 @@ public class EvalConditional extends CPPEvaluation { ICPPEvaluation negative = fNegative.computeForFunctionCall(parameterMap, maxdepth, point); if (condition == fCondition && positive == fPositive && negative == fNegative) return this; - return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows); + return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index 5636cf9bf2f..7df4e724073 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -43,12 +43,16 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode; import org.eclipse.core.runtime.CoreException; -public class EvalFunctionCall extends CPPEvaluation { +public class EvalFunctionCall extends CPPDependentEvaluation { private final ICPPEvaluation[] fArguments; private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION; private IType fType; - public EvalFunctionCall(ICPPEvaluation[] args) { + public EvalFunctionCall(ICPPEvaluation[] args, IASTNode pointOfDefinition) { + this(args, findEnclosingTemplate(pointOfDefinition)); + } + public EvalFunctionCall(ICPPEvaluation[] args, IBinding templateDefinition) { + super(templateDefinition); fArguments= args; } @@ -101,7 +105,8 @@ public class EvalFunctionCall extends CPPEvaluation { IType t= SemanticUtil.getNestedType(fArguments[0].getTypeOrFunctionSet(point), TDEF | REF | CVTYPE); if (t instanceof ICPPClassType) { - return CPPSemantics.findOverloadedOperator(point, fArguments, t, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS); + return CPPSemantics.findOverloadedOperator(point, getTemplateDefinitionScope(), fArguments, t, + OverloadableOperator.PAREN, LookupMode.NO_GLOBALS); } return null; } @@ -174,6 +179,7 @@ public class EvalFunctionCall extends CPPEvaluation { for (ICPPEvaluation arg : fArguments) { buffer.marshalEvaluation(arg, includeValue); } + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -182,7 +188,8 @@ public class EvalFunctionCall extends CPPEvaluation { for (int i = 0; i < args.length; i++) { args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); } - return new EvalFunctionCall(args); + IBinding templateDefinition = buffer.unmarshalBinding(); + return new EvalFunctionCall(args, templateDefinition); } @Override @@ -206,7 +213,7 @@ public class EvalFunctionCall extends CPPEvaluation { // Resolve the function using the parameters of the function call. args[0] = ((EvalFunctionSet) args[0]).resolveFunction(Arrays.copyOfRange(args, 1, args.length), point); } - return new EvalFunctionCall(args); + return new EvalFunctionCall(args, getTemplateDefinition()); } @Override @@ -228,7 +235,7 @@ public class EvalFunctionCall extends CPPEvaluation { } EvalFunctionCall eval = this; if (args != fArguments) - eval = new EvalFunctionCall(args); + eval = new EvalFunctionCall(args, getTemplateDefinition()); return eval.computeForFunctionCall(maxdepth - 1, point); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index 60771fd3cfe..a267dd3f409 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -38,11 +38,15 @@ import org.eclipse.core.runtime.CoreException; /** * Performs evaluation of an expression. */ -public class EvalFunctionSet extends CPPEvaluation { +public class EvalFunctionSet extends CPPDependentEvaluation { private final CPPFunctionSet fFunctionSet; private final boolean fAddressOf; - public EvalFunctionSet(CPPFunctionSet set, boolean addressOf) { + public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IASTNode pointOfDefinition) { + this(set, addressOf, findEnclosingTemplate(pointOfDefinition)); + } + public EvalFunctionSet(CPPFunctionSet set, boolean addressOf, IBinding templateDefinition) { + super(templateDefinition); fFunctionSet= set; fAddressOf= addressOf; } @@ -122,6 +126,7 @@ public class EvalFunctionSet extends CPPEvaluation { buffer.marshalTemplateArgument(arg); } } + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -139,7 +144,8 @@ public class EvalFunctionSet extends CPPEvaluation { args[i]= buffer.unmarshalTemplateArgument(); } } - return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf, templateDefinition); } @Override @@ -173,7 +179,7 @@ public class EvalFunctionSet extends CPPEvaluation { } if (Arrays.equals(arguments, originalArguments) && functions == originalFunctions) return this; - return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf); + return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf, getTemplateDefinition()); } @Override @@ -198,7 +204,7 @@ public class EvalFunctionSet extends CPPEvaluation { try { IBinding binding = CPPSemantics.resolveFunction(data, functions, true); if (binding instanceof ICPPFunction && !(binding instanceof ICPPUnknownBinding)) - return new EvalBinding(binding, null); + return new EvalBinding(binding, null, getTemplateDefinition()); } catch (DOMException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 61c5c7883af..49960745ddc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -54,7 +54,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.core.runtime.CoreException; -public class EvalID extends CPPEvaluation { +public class EvalID extends CPPDependentEvaluation { private final ICPPEvaluation fFieldOwner; private final char[] fName; private final IBinding fNameOwner; @@ -63,7 +63,12 @@ public class EvalID extends CPPEvaluation { private final ICPPTemplateArgument[] fTemplateArgs; public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, - boolean qualified, ICPPTemplateArgument[] templateArgs) { + boolean qualified, ICPPTemplateArgument[] templateArgs, IASTNode pointOfDefinition) { + this(fieldOwner, nameOwner, simpleID, addressOf, qualified, templateArgs, findEnclosingTemplate(pointOfDefinition)); + } + public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, + boolean qualified, ICPPTemplateArgument[] templateArgs, IBinding templateDefinition) { + super(templateDefinition); fFieldOwner= fieldOwner; fName= simpleID; fNameOwner= nameOwner; @@ -158,6 +163,7 @@ public class EvalID extends CPPEvaluation { buffer.marshalTemplateArgument(arg); } } + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -174,7 +180,8 @@ public class EvalID extends CPPEvaluation { args[i]= buffer.unmarshalTemplateArgument(); } } - return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, args); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, args, templateDefinition); } public static ICPPEvaluation create(IASTIdExpression expr) { @@ -183,7 +190,7 @@ public class EvalID extends CPPEvaluation { if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor) return EvalFixed.INCOMPLETE; if (binding instanceof CPPFunctionSet) { - return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr)); + return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr), expr); } if (binding instanceof ICPPUnknownBinding) { ICPPTemplateArgument[] templateArgs = null; @@ -200,7 +207,7 @@ public class EvalID extends CPPEvaluation { CPPDeferredFunction deferredFunction = (CPPDeferredFunction) binding; if (deferredFunction.getCandidates() != null) { CPPFunctionSet functionSet = new CPPFunctionSet(deferredFunction.getCandidates(), templateArgs, null); - return new EvalFunctionSet(functionSet, isAddressOf(expr)); + return new EvalFunctionSet(functionSet, isAddressOf(expr), expr); } } @@ -215,7 +222,7 @@ public class EvalID extends CPPEvaluation { } return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr), - name instanceof ICPPASTQualifiedName, templateArgs); + name instanceof ICPPASTQualifiedName, templateArgs, expr); } /** * 9.3.1-3 Transformation to class member access within a non-static member function. @@ -224,7 +231,7 @@ public class EvalID extends CPPEvaluation { && !(binding instanceof ICPPConstructor) &&!((ICPPMember) binding).isStatic()) { IType fieldOwnerType= withinNonStaticMethod(expr); if (fieldOwnerType != null) { - return new EvalMemberAccess(fieldOwnerType, LVALUE, binding, true); + return new EvalMemberAccess(fieldOwnerType, LVALUE, binding, true, expr); } } @@ -241,14 +248,14 @@ public class EvalID extends CPPEvaluation { // of the enumerator. type= CPPSemantics.INT_TYPE; } - return new EvalBinding(binding, type); + return new EvalBinding(binding, type, expr); } } - return new EvalBinding(binding, null); + return new EvalBinding(binding, null, expr); } if (binding instanceof ICPPTemplateNonTypeParameter || binding instanceof IVariable || binding instanceof IFunction) { - return new EvalBinding(binding, null); + return new EvalBinding(binding, null, expr); } return EvalFixed.INCOMPLETE; } @@ -318,7 +325,7 @@ public class EvalID extends CPPEvaluation { return eval; } - return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs); + return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs, getTemplateDefinition()); } @Override @@ -329,7 +336,7 @@ public class EvalID extends CPPEvaluation { ICPPEvaluation fieldOwner = fFieldOwner.computeForFunctionCall(parameterMap, maxdepth, point); if (fieldOwner == fFieldOwner) return this; - return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fTemplateArgs); + return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fTemplateArgs, getTemplateDefinition()); } private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs, @@ -344,15 +351,15 @@ public class EvalID extends CPPEvaluation { if (bindings.length > 1 && bindings[0] instanceof ICPPFunction) { ICPPFunction[] functions = new ICPPFunction[bindings.length]; System.arraycopy(bindings, 0, functions, 0, bindings.length); - return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fAddressOf); + return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fAddressOf, getTemplateDefinition()); } IBinding binding = bindings.length == 1 ? bindings[0] : null; if (binding instanceof IEnumerator) { - return new EvalBinding(binding, null); + return new EvalBinding(binding, null, getTemplateDefinition()); } else if (binding instanceof ICPPMember) { - return new EvalMemberAccess(nameOwner, ValueCategory.PRVALUE, binding, false); + return new EvalMemberAccess(nameOwner, ValueCategory.PRVALUE, binding, false, getTemplateDefinition()); } else if (binding instanceof CPPFunctionSet) { - return new EvalFunctionSet((CPPFunctionSet) binding, fAddressOf); + return new EvalFunctionSet((CPPFunctionSet) binding, fAddressOf, getTemplateDefinition()); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java index 09355929a34..8364ff49b94 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java @@ -15,6 +15,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; @@ -28,10 +29,14 @@ import org.eclipse.core.runtime.CoreException; /** * Performs evaluation of an expression. */ -public class EvalInitList extends CPPEvaluation { +public class EvalInitList extends CPPDependentEvaluation { private final ICPPEvaluation[] fClauses; - public EvalInitList(ICPPEvaluation[] clauses) { + public EvalInitList(ICPPEvaluation[] clauses, IASTNode pointOfDefinition) { + this(clauses, findEnclosingTemplate(pointOfDefinition)); + } + public EvalInitList(ICPPEvaluation[] clauses, IBinding templateDefinition) { + super(templateDefinition); fClauses= clauses; } @@ -91,6 +96,7 @@ public class EvalInitList extends CPPEvaluation { for (ICPPEvaluation arg : fClauses) { buffer.marshalEvaluation(arg, includeValue); } + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -99,7 +105,8 @@ public class EvalInitList extends CPPEvaluation { for (int i = 0; i < args.length; i++) { args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); } - return new EvalInitList(args); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalInitList(args, templateDefinition); } @Override @@ -118,7 +125,7 @@ public class EvalInitList extends CPPEvaluation { } if (clauses == fClauses) return this; - return new EvalInitList(clauses); + return new EvalInitList(clauses, getTemplateDefinition()); } @Override @@ -137,7 +144,7 @@ public class EvalInitList extends CPPEvaluation { } if (clauses == fClauses) return this; - return new EvalInitList(clauses); + return new EvalInitList(clauses, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java index 88d935356fb..240ab162e65 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java @@ -54,7 +54,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode; import org.eclipse.core.runtime.CoreException; -public class EvalMemberAccess extends CPPEvaluation { +public class EvalMemberAccess extends CPPDependentEvaluation { private final IType fOwnerType; private final IBinding fMember; private final ValueCategory fOwnerValueCategory; @@ -67,7 +67,12 @@ public class EvalMemberAccess extends CPPEvaluation { private boolean fCheckedIsValueDependent; public EvalMemberAccess(IType ownerType, ValueCategory ownerValueCat, IBinding member, - boolean isPointerDeref) { + boolean isPointerDeref, IASTNode pointOfDefinition) { + this(ownerType, ownerValueCat, member, isPointerDeref, findEnclosingTemplate(pointOfDefinition)); + } + public EvalMemberAccess(IType ownerType, ValueCategory ownerValueCat, IBinding member, + boolean isPointerDeref, IBinding templateDefinition) { + super(templateDefinition); fOwnerType= ownerType; fOwnerValueCategory= ownerValueCat; fMember= member; @@ -176,7 +181,7 @@ public class EvalMemberAccess extends CPPEvaluation { */ ICPPEvaluation[] args= { new EvalFixed(type, LVALUE, Value.UNKNOWN) }; - ICPPFunction op= CPPSemantics.findOverloadedOperator(point, args, classType, + ICPPFunction op= CPPSemantics.findOverloadedOperator(point, null, args, classType, OverloadableOperator.ARROW, LookupMode.NO_GLOBALS); if (op == null) break; @@ -302,6 +307,7 @@ public class EvalMemberAccess extends CPPEvaluation { buffer.putByte((byte) firstByte); buffer.marshalType(fOwnerType); buffer.marshalBinding(fMember); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -317,7 +323,8 @@ public class EvalMemberAccess extends CPPEvaluation { IType ownerType= buffer.unmarshalType(); IBinding member= buffer.unmarshalBinding(); - return new EvalMemberAccess(ownerType, ownerValueCat, member, isDeref); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalMemberAccess(ownerType, ownerValueCat, member, isDeref, templateDefinition); } @Override @@ -331,7 +338,7 @@ public class EvalMemberAccess extends CPPEvaluation { if (ownerType instanceof ICPPClassSpecialization) { member = CPPTemplates.createSpecialization((ICPPClassSpecialization) ownerType, fMember, point); } - return new EvalMemberAccess(ownerType, fOwnerValueCategory, member, fIsPointerDeref); + return new EvalMemberAccess(ownerType, fOwnerValueCategory, member, fIsPointerDeref, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index b00f13229f3..60b06027cd3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -16,6 +16,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionT import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; @@ -30,14 +31,18 @@ import org.eclipse.core.runtime.CoreException; /** * Performs evaluation of an expression. */ -public class EvalTypeId extends CPPEvaluation { +public class EvalTypeId extends CPPDependentEvaluation { private final IType fInputType; private final ICPPEvaluation[] fArguments; private IType fOutputType; - public EvalTypeId(IType type, ICPPEvaluation... argument) { + public EvalTypeId(IType type, IASTNode pointOfDefinition, ICPPEvaluation... arguments) { + this(type, findEnclosingTemplate(pointOfDefinition), arguments); + } + public EvalTypeId(IType type, IBinding templateDefinition, ICPPEvaluation... arguments) { + super(templateDefinition); fInputType= type; - fArguments= argument; + fArguments= arguments; } public IType getInputType() { @@ -128,6 +133,7 @@ public class EvalTypeId extends CPPEvaluation { buffer.marshalEvaluation(arg, includeValue); } } + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { @@ -140,7 +146,8 @@ public class EvalTypeId extends CPPEvaluation { args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); } } - return new EvalTypeId(type, args); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalTypeId(type, templateDefinition, args); } @Override @@ -162,7 +169,7 @@ public class EvalTypeId extends CPPEvaluation { IType type = CPPTemplates.instantiateType(fInputType, tpMap, packOffset, within, point); if (args == fArguments && type == fInputType) return this; - return new EvalTypeId(type, args); + return new EvalTypeId(type, getTemplateDefinition(), args); } @Override @@ -183,7 +190,7 @@ public class EvalTypeId extends CPPEvaluation { } if (args == fArguments) return this; - return new EvalTypeId(fInputType, args); + return new EvalTypeId(fInputType, getTemplateDefinition(), args); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index a2d61ae8497..f3dc221be57 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -66,7 +66,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode; import org.eclipse.core.runtime.CoreException; -public class EvalUnary extends CPPEvaluation { +public class EvalUnary extends CPPDependentEvaluation { private static final ICPPEvaluation ZERO_EVAL = new EvalFixed(CPPSemantics.INT_TYPE, PRVALUE, Value.create(0)); private final int fOperator; @@ -75,7 +75,13 @@ public class EvalUnary extends CPPEvaluation { private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION; private IType fType; - public EvalUnary(int operator, ICPPEvaluation operand, IBinding addressOfQualifiedNameBinding) { + public EvalUnary(int operator, ICPPEvaluation operand, IBinding addressOfQualifiedNameBinding, + IASTNode pointOfDefinition) { + this(operator, operand, addressOfQualifiedNameBinding, findEnclosingTemplate(pointOfDefinition)); + } + public EvalUnary(int operator, ICPPEvaluation operand, IBinding addressOfQualifiedNameBinding, + IBinding templateDefinition) { + super(templateDefinition); fOperator= operator; fArgument= operand; fAddressOfQualifiedNameBinding= addressOfQualifiedNameBinding; @@ -170,7 +176,7 @@ public class EvalUnary extends CPPEvaluation { } else { args = new ICPPEvaluation[] { fArgument }; } - return CPPSemantics.findOverloadedOperator(point, args, type, op, LookupMode.LIMITED_GLOBALS); + return CPPSemantics.findOverloadedOperator(point, getTemplateDefinitionScope(), args, type, op, LookupMode.LIMITED_GLOBALS); } @Override @@ -298,13 +304,15 @@ public class EvalUnary extends CPPEvaluation { buffer.putByte((byte) fOperator); buffer.marshalEvaluation(fArgument, includeValue); buffer.marshalBinding(fAddressOfQualifiedNameBinding); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { int op= buffer.getByte(); ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation(); IBinding binding= buffer.unmarshalBinding(); - return new EvalUnary(op, arg, binding); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalUnary(op, arg, binding, templateDefinition); } @Override @@ -321,7 +329,7 @@ public class EvalUnary extends CPPEvaluation { if (argument == fArgument && aoqn == fAddressOfQualifiedNameBinding) return this; - return new EvalUnary(fOperator, argument, aoqn); + return new EvalUnary(fOperator, argument, aoqn, getTemplateDefinition()); } @Override @@ -331,7 +339,7 @@ public class EvalUnary extends CPPEvaluation { if (argument == fArgument) return this; - return new EvalUnary(fOperator, argument, fAddressOfQualifiedNameBinding); + return new EvalUnary(fOperator, argument, fAddressOfQualifiedNameBinding, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java index 9d2e39b7e52..c7ade038d89 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java @@ -37,6 +37,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; @@ -49,12 +50,16 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.core.runtime.CoreException; -public class EvalUnaryTypeID extends CPPEvaluation { +public class EvalUnaryTypeID extends CPPDependentEvaluation { private final int fOperator; private final IType fOrigType; private IType fType; - public EvalUnaryTypeID(int operator, IType type) { + public EvalUnaryTypeID(int operator, IType type, IASTNode pointOfDefinition) { + this(operator, type, findEnclosingTemplate(pointOfDefinition)); + } + public EvalUnaryTypeID(int operator, IType type, IBinding templateDefinition) { + super(templateDefinition); fOperator= operator; fOrigType= type; } @@ -173,12 +178,14 @@ public class EvalUnaryTypeID extends CPPEvaluation { buffer.putByte(ITypeMarshalBuffer.EVAL_UNARY_TYPE_ID); buffer.putByte((byte) fOperator); buffer.marshalType(fOrigType); + marshalTemplateDefinition(buffer); } public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { int op= buffer.getByte(); IType arg= buffer.unmarshalType(); - return new EvalUnaryTypeID(op, arg); + IBinding templateDefinition= buffer.unmarshalBinding(); + return new EvalUnaryTypeID(op, arg, templateDefinition); } @Override @@ -187,7 +194,7 @@ public class EvalUnaryTypeID extends CPPEvaluation { IType type = CPPTemplates.instantiateType(fOrigType, tpMap, packOffset, within, point); if (type == fOrigType) return this; - return new EvalUnaryTypeID(fOperator, type); + return new EvalUnaryTypeID(fOperator, type, getTemplateDefinition()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 8d33b882c8d..f03403601e6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -90,7 +90,7 @@ public class TemplateArgumentDeduction { CPPTemplateParameterMap map, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); - if (tmplArgs != null && !addExplicitArguments(tmplParams, tmplArgs, map, point)) + if (tmplArgs != null && !addExplicitArguments(template, tmplParams, tmplArgs, map, point)) return null; if (!deduceFromFunctionArgs(template, fnArgs, argIsLValue, map, point)) @@ -315,7 +315,7 @@ public class TemplateArgumentDeduction { static ICPPTemplateArgument[] deduceForAddressOf(ICPPFunctionTemplate template, ICPPTemplateArgument[] tmplArgs, IFunctionType arg, CPPTemplateParameterMap map, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); - if (!addExplicitArguments(tmplParams, tmplArgs, map, point)) + if (!addExplicitArguments(template, tmplParams, tmplArgs, map, point)) return null; IType par= template.getType(); @@ -387,7 +387,7 @@ public class TemplateArgumentDeduction { ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); - if (!addExplicitArguments(tmplParams, args, map, point)) + if (!addExplicitArguments(template, tmplParams, args, map, point)) return null; IType a= SemanticUtil.getSimplifiedType(ftype); @@ -479,7 +479,7 @@ public class TemplateArgumentDeduction { /** * Adds the explicit arguments to the map. */ - public static boolean addExplicitArguments(final ICPPTemplateParameter[] tmplParams, + public static boolean addExplicitArguments(ICPPFunctionTemplate template, final ICPPTemplateParameter[] tmplParams, ICPPTemplateArgument[] tmplArgs, CPPTemplateParameterMap map, IASTNode point) { tmplArgs= SemanticUtil.getSimplifiedArguments(tmplArgs); ICPPTemplateParameter tmplParam= null; @@ -495,7 +495,7 @@ public class TemplateArgumentDeduction { } } ICPPTemplateArgument tmplArg= tmplArgs[i]; - tmplArg= CPPTemplates.matchTemplateParameterAndArgument(tmplParam, tmplArg, map, point); + tmplArg= CPPTemplates.matchTemplateParameterAndArgument(template, tmplParam, tmplArg, map, point); if (tmplArg == null) return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index 32d8fe65cdc..3589b59cfa7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -232,6 +232,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { public ICPPEvaluation getCompositeEvaluation(ICPPEvaluation eval) { if (eval == null) return null; + IBinding templateDefinition = eval.getTemplateDefinition(); + IBinding templateDefinition2 = getCompositeBinding((IIndexFragmentBinding) templateDefinition); if (eval instanceof EvalBinary) { EvalBinary e= (EvalBinary) eval; ICPPEvaluation a = e.getArg1(); @@ -239,8 +241,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { ICPPEvaluation a2 = getCompositeEvaluation(a); ICPPEvaluation b2 = getCompositeEvaluation(b); - if (a != a2 || b != b2) - e= new EvalBinary(e.getOperator(), a2, b2); + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) + e= new EvalBinary(e.getOperator(), a2, b2, templateDefinition2); return e; } if (eval instanceof EvalBinaryTypeId) { @@ -250,8 +252,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { IType a2 = getCompositeType(a); IType b2 = getCompositeType(b); - if (a != a2 || b != b2) - e= new EvalBinaryTypeId(e.getOperator(), a2, b2); + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) + e= new EvalBinaryTypeId(e.getOperator(), a2, b2, templateDefinition2); return e; } if (eval instanceof EvalBinding) { @@ -261,9 +263,9 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { IType b = e.getFixedType(); IBinding a2 = getCompositeBinding((IIndexFragmentBinding) parameterOwner); IType b2 = getCompositeType(b); - if (parameterOwner != a2 || b != b2) { + if (parameterOwner != a2 || b != b2 || templateDefinition != templateDefinition2) { int parameterPosition = e.getFunctionParameterPosition(); - e= new EvalBinding((ICPPFunction) a2, parameterPosition, b2); + e= new EvalBinding((ICPPFunction) a2, parameterPosition, b2, templateDefinition2); } } else { IBinding a = e.getBinding(); @@ -271,25 +273,27 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { IBinding a2 = getCompositeBinding((IIndexFragmentBinding) a); IType b2 = getCompositeType(b); - if (a != a2 || b != b2) - e= new EvalBinding(a2, b2); + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) + e= new EvalBinding(a2, b2, templateDefinition2); } return e; } if (eval instanceof EvalComma) { EvalComma e= (EvalComma) eval; ICPPEvaluation[] a = e.getArguments(); + ICPPEvaluation[] a2 = getCompositeEvaluationArray(a); - if (a != a2) - e= new EvalComma(a2); + + if (a != a2 || templateDefinition != templateDefinition2) + e= new EvalComma(a2, templateDefinition2); return e; } if (eval instanceof EvalCompound) { EvalCompound e= (EvalCompound) eval; ICPPEvaluation a = e.getLastEvaluation(); ICPPEvaluation a2 = getCompositeEvaluation(a); - if (a != a2) - e= new EvalCompound(a2); + if (a != a2 || templateDefinition != templateDefinition2) + e= new EvalCompound(a2, templateDefinition2); return e; } if (eval instanceof EvalConditional) { @@ -300,8 +304,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { ICPPEvaluation a2 = getCompositeEvaluation(a); ICPPEvaluation b2 = getCompositeEvaluation(b); ICPPEvaluation c2 = getCompositeEvaluation(c); - if (a != a2 || b != b2 || c != c2) - e= new EvalConditional(a2, b2, c2, e.isPositiveThrows(), e.isNegativeThrows()); + if (a != a2 || b != b2 || c != c2 || templateDefinition != templateDefinition2) + e= new EvalConditional(a2, b2, c2, e.isPositiveThrows(), e.isNegativeThrows(), templateDefinition2); return e; } if (eval instanceof EvalFixed) { @@ -310,7 +314,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { IValue b = e.getValue(); IType a2 = getCompositeType(a); IValue b2= getCompositeValue(b); - if (a != a2 || b != b2) + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) e= new EvalFixed(a2, e.getValueCategory(), b2); return e; } @@ -318,8 +322,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { EvalFunctionCall e= (EvalFunctionCall) eval; ICPPEvaluation[] a = e.getArguments(); ICPPEvaluation[] a2 = getCompositeEvaluationArray(a); - if (a != a2) - e= new EvalFunctionCall(a2); + if (a != a2 || templateDefinition != templateDefinition2) + e= new EvalFunctionCall(a2, templateDefinition2); return e; } if (eval instanceof EvalFunctionSet) { @@ -330,8 +334,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { ICPPFunction[] a2 = getCompositeFunctionArray(a); ICPPTemplateArgument[] b2 = TemplateInstanceUtil.convert(this, b); - if (a != a2 || b != b2) - e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isAddressOf()); + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) + e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isAddressOf(), templateDefinition2); return e; } if (eval instanceof EvalID) { @@ -349,16 +353,16 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { } ICPPTemplateArgument[] c2 = TemplateInstanceUtil.convert(this, c); - if (a != a2 || b != b2 || c != c2) - e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), c2); + if (a != a2 || b != b2 || c != c2 || templateDefinition != templateDefinition2) + e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), c2, templateDefinition2); return e; } if (eval instanceof EvalInitList) { EvalInitList e= (EvalInitList) eval; ICPPEvaluation[] a = e.getClauses(); ICPPEvaluation[] a2 = getCompositeEvaluationArray(a); - if (a != a2) - e= new EvalInitList(a2); + if (a != a2 || templateDefinition != templateDefinition2) + e= new EvalInitList(a2, templateDefinition2); return e; } if (eval instanceof EvalMemberAccess) { @@ -367,8 +371,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { IBinding b = e.getMember(); IType a2= getCompositeType(a); IBinding b2= getCompositeBinding((IIndexFragmentBinding) b); - if (a != a2 || b != b2) - e= new EvalMemberAccess(a2, e.getOwnerValueCategory(), b2, e.isPointerDeref()); + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) + e= new EvalMemberAccess(a2, e.getOwnerValueCategory(), b2, e.isPointerDeref(), templateDefinition2); return e; } if (eval instanceof EvalTypeId) { @@ -377,8 +381,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { ICPPEvaluation[] b = e.getArguments(); IType a2= getCompositeType(a); ICPPEvaluation[] b2 = getCompositeEvaluationArray(b); - if (a != a2 || b != b2) - e= new EvalTypeId(a2, b2); + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) + e= new EvalTypeId(a2, templateDefinition2, b2); return e; } if (eval instanceof EvalUnary) { @@ -387,16 +391,16 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { ICPPEvaluation a2 = getCompositeEvaluation(a); IBinding b= e.getAddressOfQualifiedNameBinding(); IBinding b2= getCompositeBinding((IIndexFragmentBinding) b); - if (a != a2 || b != b2) - e= new EvalUnary(e.getOperator(), a2, b2); + if (a != a2 || b != b2 || templateDefinition != templateDefinition2) + e= new EvalUnary(e.getOperator(), a2, b2, templateDefinition2); return e; } if (eval instanceof EvalUnaryTypeID) { EvalUnaryTypeID e= (EvalUnaryTypeID) eval; IType a = e.getArgument(); IType a2 = getCompositeType(a); - if (a != a2) - e= new EvalUnaryTypeID(e.getOperator(), a2); + if (a != a2 || templateDefinition != templateDefinition2) + e= new EvalUnaryTypeID(e.getOperator(), a2, templateDefinition2); return e; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index c24e8d698af..387ee12009b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -232,11 +232,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 139.0 - More efficient and robust storage of types and template arguments, bug 395243. * 140.0 - Enumerators with dependent values, bug 389009. * 140.1 - Mechanism for tagging nodes with extended data, bug TODO + * 141.0 - Storing enclosing template bindings for evaluations, bug 399829 */ - - private static final int MIN_SUPPORTED_VERSION= version(140, 0); - private static final int MAX_SUPPORTED_VERSION= version(140, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(140, 1); + private static final int MIN_SUPPORTED_VERSION= version(141, 0); + private static final int MAX_SUPPORTED_VERSION= version(141, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(141, 0); private static int version(int major, int minor) { return (major << 16) + minor;