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

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 <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2013-02-13 00:57:09 -05:00 committed by Sergey Prigogin
parent 2279927623
commit f1542b27c6
39 changed files with 536 additions and 189 deletions

View file

@ -7202,6 +7202,73 @@ public class AST2TemplateTests extends AST2TestBase {
// S<contains_waldo<int>::value>::type t;
// }
public void testVariadicTemplates_401024() throws Exception {
parseAndCheckBindings();
}
// struct S {
// void kind();
// };
// struct T {};
// namespace N {
// S operator++(T);
// template <class T>
// struct impl {
// static T x;
// typedef decltype(++x) type;
// };
// }
// void test() {
// N::impl<T>::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 <class T> any(T); };
// tag operator++(any);
// tag operator,(tag,int);
// S check(tag);
// int check(int);
// template <class T>
// struct impl {
// static T& x;
// typedef decltype(N::check((++x,0))) type;
// };
// }
// void test() {
// N::impl<S>::type operand;
// operand.kind(); // ERROR HERE: Method 'kind' could not be resolved
// }
public void testNameLookupInDependentExpression_399829b() throws Exception {
parseAndCheckBindings();
}
// template <bool> int assertion_failed(void*);
// struct assert_ {};
// assert_ arg;
// char operator==(assert_, assert_);
// template <unsigned> struct assert_relation {};
// template<class>
// struct concept {
// typedef decltype(assertion_failed<true>((assert_relation<sizeof(arg == arg) >*)0)) type;
// };
// template <bool> struct S {};
// template <typename>
// struct is_int
// {
// static const bool value = false;
// };
// template<typename T>
// S<true> operator==(T, T*);
// template<typename T>
// S<(is_int<T>::value)> operator==(T, T);
public void testRegression_399829() throws Exception {
parseAndCheckBindings();
}
}

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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();
}
}
}

View file

@ -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();

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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;