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

Bug 299911: Introduce ICPPEvaluation

This commit is contained in:
Markus Schorn 2012-05-31 16:07:46 +02:00 committed by Sergey Prigogin
parent 1bb6d2eecc
commit fad6fcfe01
147 changed files with 5751 additions and 3282 deletions

View file

@ -17,6 +17,7 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -1544,19 +1545,19 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
// CT<int> v1; // CT<int> v1;
public void testUniqueInstance_Bug241641() throws Exception { public void testUniqueInstance_Bug241641() throws Exception {
IASTName name= findName("v1", 2);
ICPPVariable v1= getBindingFromASTName("v1", 2, ICPPVariable.class); ICPPVariable v1= getBindingFromASTName("v1", 2, ICPPVariable.class);
ICPPVariable v2= getBindingFromASTName("v1", 2, ICPPVariable.class);
IType t1= v1.getType(); IType t1= v1.getType();
assertInstance(t1, ICPPTemplateInstance.class); assertInstance(t1, ICPPTemplateInstance.class);
ICPPTemplateInstance inst= (ICPPTemplateInstance) t1; ICPPTemplateInstance inst= (ICPPTemplateInstance) t1;
final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition(); final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition();
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments()); IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments(), name);
assertSame(inst, inst2); assertSame(inst, inst2);
IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}); IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, name);
IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}); IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, name);
assertSame(charInst1, charInst2); assertSame(charInst1, charInst2);
} }

View file

@ -610,18 +610,14 @@ public class ASTTypeUtil {
IBinding binding = declarator.getName().resolveBinding(); IBinding binding = declarator.getName().resolveBinding();
IType type = null; IType type = null;
try { if (binding instanceof IEnumerator) {
if (binding instanceof IEnumerator) { type = ((IEnumerator)binding).getType();
type = ((IEnumerator) binding).getType(); } else if (binding instanceof IFunction) {
} else if (binding instanceof IFunction) { type = ((IFunction)binding).getType();
type = ((IFunction) binding).getType(); } else if (binding instanceof ITypedef) {
} else if (binding instanceof ITypedef) { type = ((ITypedef)binding).getType();
type = ((ITypedef) binding).getType(); } else if (binding instanceof IVariable) {
} else if (binding instanceof IVariable) { type = ((IVariable)binding).getType();
type = ((IVariable) binding).getType();
}
} catch (DOMException e) {
return EMPTY_STRING;
} }
if (type != null) { if (type != null) {

View file

@ -23,7 +23,7 @@ public interface IEnumerator extends IBinding {
* *
* @return the type of the enumeration * @return the type of the enumeration
*/ */
public IType getType() throws DOMException; public IType getType();
/** /**
* Returns the value assigned to this enumerator. * Returns the value assigned to this enumerator.

View file

@ -13,6 +13,7 @@
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
/** /**
@ -87,34 +88,106 @@ public interface IScope {
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings); public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings);
/** /**
* Get the bindings in this scope that the given name or prefix could resolve to. Could * @deprecated Use {@link #getBindings(ScopeLookupData)} instead
* return null if there is no matching bindings in this scope, if the bindings have not
* yet been cached in this scope, or if resolve == false and the appropriate bindings
* have not yet been resolved.
*
* @param name
* @param resolve :
* whether or not to resolve the matching bindings if they have not
* been so already.
* @param prefixLookup whether the lookup is for a full name or a prefix
* @return : the bindings in this scope that match the name or prefix, or null
*/ */
@Deprecated
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup); public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup);
/**
* @deprecated Use {@link #getBindings(ScopeLookupData)} instead
*/
@Deprecated
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings);
/**
* @since 5.4
* @noextend This class is not intended to be subclassed by clients.
*/
public static class ScopeLookupData {
private char[] fLookupKey;
private final IASTNode fLookupPoint;
private final IASTTranslationUnit fTu;
private final boolean fLookupPointIsName;
private boolean fResolve= true;
private boolean fPrefixLookup= false;
private boolean fIgnorePointOfDeclaration= false;
public ScopeLookupData(IASTName name, boolean resolve, boolean prefixLookup) {
if (name == null)
throw new IllegalArgumentException();
fLookupPoint = name;
fLookupPointIsName= true;
fLookupKey= name.getLookupKey();
fResolve = resolve;
fPrefixLookup = prefixLookup;
fTu= name.getTranslationUnit();
}
public ScopeLookupData(char[] name, IASTNode point) {
// To support IScope.find(...) the lookup point may be null.
fLookupPoint= point;
fLookupPointIsName= false;
fLookupKey= name;
fIgnorePointOfDeclaration= true;
if (fLookupPoint == null) {
fTu= null;
fIgnorePointOfDeclaration= true;
} else {
fTu= fLookupPoint.getTranslationUnit();
}
}
public void setPrefixLookup(boolean prefixLookup) {
fPrefixLookup = prefixLookup;
}
public void setResolve(boolean resolve) {
fResolve = resolve;
}
public void setIgnorePointOfDeclaration(boolean ignorePointOfDeclaration) {
fIgnorePointOfDeclaration = ignorePointOfDeclaration;
}
public void setLookupKey(char[] key) {
fLookupKey= key;
}
public char[] getLookupKey() {
return fLookupKey;
}
public IASTNode getLookupPoint() {
return fLookupPoint;
}
public boolean isResolve() {
return fResolve;
}
public boolean isPrefixLookup() {
return fPrefixLookup;
}
public boolean isIgnorePointOfDeclaration() {
return fIgnorePointOfDeclaration;
}
public IIndexFileSet getIncludedFiles() {
return fTu == null ? IIndexFileSet.EMPTY : fTu.getIndexFileSet();
}
public IIndex getIndex() {
return fTu == null ? null : fTu.getIndex();
}
public IASTName getLookupName() {
return fLookupPointIsName ? (IASTName) fLookupPoint : null;
}
public IASTTranslationUnit getTranslationUnit() {
return fTu;
}
}
/** /**
* Get the bindings in this scope that the given name or prefix could resolve to. Could * Get the bindings in this scope that the given name or prefix could resolve to. Could
* return null if there is no matching bindings in this scope, if the bindings have not * return null if there is no matching bindings in this scope, if the bindings have not
* yet been cached in this scope, or if resolve == false and the appropriate bindings * yet been cached in this scope, or if resolve == false and the appropriate bindings
* have not yet been resolved. * have not yet been resolved.
* *
* @param name
* @param resolve :
* whether or not to resolve the matching bindings if they have not
* been so already.
* @param prefixLookup whether the lookup is for a full name or a prefix
* @param acceptLocalBindings a set of files for which to accept local bindings.
* @return : the bindings in this scope that match the name or prefix, or null * @return : the bindings in this scope that match the name or prefix, or null
* @since 5.4
*/ */
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings); public IBinding[] getBindings(ScopeLookupData lookup);
} }

View file

@ -29,4 +29,16 @@ public interface ICPPASTArraySubscriptExpression extends IASTArraySubscriptExpre
*/ */
@Override @Override
public ICPPASTArraySubscriptExpression copy(CopyStyle style); public ICPPASTArraySubscriptExpression copy(CopyStyle style);
/**
* @since 5.4
*/
@Override
public ICPPASTExpression getArrayExpression();
/**
* @since 5.4
*/
@Override
public ICPPASTInitializerClause getArgument();
} }

View file

@ -52,4 +52,10 @@ public interface ICPPASTFieldReference extends IASTFieldReference, ICPPASTExpres
* @since 5.4 * @since 5.4
*/ */
public IType getFieldOwnerType(); public IType getFieldOwnerType();
/**
* @since 5.4
*/
@Override
public ICPPASTExpression getFieldOwner();
} }

View file

@ -12,7 +12,7 @@
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInitClauseEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
/** /**
* C++ specific initializer clause * C++ specific initializer clause
@ -26,5 +26,5 @@ public interface ICPPASTInitializerClause extends IASTInitializerClause {
* Returns the evaluation object for this expression. * Returns the evaluation object for this expression.
* @noreference This method is not intended to be referenced by clients. * @noreference This method is not intended to be referenced by clients.
*/ */
ICPPInitClauseEvaluation getEvaluation(); ICPPEvaluation getEvaluation();
} }

View file

@ -10,6 +10,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
/** /**
@ -24,9 +25,16 @@ public interface ICPPClassSpecialization extends ICPPSpecialization, ICPPClassTy
@Override @Override
ICPPClassType getSpecializedBinding(); ICPPClassType getSpecializedBinding();
/**
* @deprecated Specializing a member may require a point of instantiation.
*/
@Deprecated
IBinding specializeMember(IBinding binding);
/** /**
* Creates a specialized binding for a member of the original class. The result is * Creates a specialized binding for a member of the original class. The result is
* a member of this class specialization. * a member of this class specialization.
* @since 5.4
*/ */
IBinding specializeMember(IBinding binding); IBinding specializeMember(IBinding binding, IASTNode point);
} }

View file

@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
/** /**
* Base implementation for all ambiguous nodes. * Base implementation for all ambiguous nodes.
@ -163,4 +164,7 @@ public abstract class ASTAmbiguousNode extends ASTNode {
public final boolean isLValue() { public final boolean isLValue() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public final ICPPEvaluation getEvaluation() {
throw new UnsupportedOperationException();
}
} }

View file

@ -20,11 +20,9 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.OffsetLimitReachedException; import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog; import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver; import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer; import org.eclipse.cdt.internal.core.parser.scanner.Lexer;
@ -35,8 +33,6 @@ import org.eclipse.cdt.internal.core.parser.scanner.Token;
* Base class for all non-preprocessor nodes in the AST. * Base class for all non-preprocessor nodes in the AST.
*/ */
public abstract class ASTNode implements IASTNode { public abstract class ASTNode implements IASTNode {
protected static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null);
private IASTNode parent; private IASTNode parent;
private ASTNodeProperty property; private ASTNodeProperty property;

View file

@ -100,7 +100,7 @@ public abstract class ASTTypeIdInitializerExpression extends ASTNode implements
} }
@Override @Override
public final ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE; return ValueCategory.PRVALUE;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others. * Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,15 +8,14 @@
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.cdt.core.dom.ast.IType;
/** /**
* Models the type of an unknown function. * Interface for marshalling types for storage in the index.
*/ */
public class CPPUnknownFunctionType extends CPPFunctionType implements ICPPUnknownType { public interface ISerializableEvaluation {
CPPUnknownFunctionType() { void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException;
super(CPPUnknownClass.createUnnamedInstance(), IType.EMPTY_TYPE_ARRAY);
}
} }

View file

@ -19,17 +19,36 @@ import org.eclipse.core.runtime.CoreException;
* Buffer for marshalling and unmarshalling types. * Buffer for marshalling and unmarshalling types.
*/ */
public interface ITypeMarshalBuffer { public interface ITypeMarshalBuffer {
final static byte BASIC_TYPE= 1; final static byte BASIC_TYPE= 1;
final static byte POINTER= 2; final static byte POINTER_TYPE= 2;
final static byte ARRAY= 3; final static byte ARRAY_TYPE= 3;
final static byte CVQUALIFIER= 4; final static byte CVQUALIFIER_TYPE= 4;
final static byte FUNCTION_TYPE= 5; final static byte FUNCTION_TYPE= 5;
final static byte REFERENCE= 6; final static byte REFERENCE_TYPE= 6;
final static byte POINTER_TO_MEMBER= 7; final static byte POINTER_TO_MEMBER_TYPE= 7;
final static byte PACK_EXPANSION= 8; final static byte PACK_EXPANSION_TYPE= 8;
final static byte PROBLEM_TYPE= 9; final static byte PROBLEM_TYPE= 9;
final static byte VALUE= 10; final static byte VALUE= 10;
static final byte KIND_MASK = 0xf; final static byte DEPENDENT_EXPRESSION_TYPE= 11;
final static byte
EVAL_BINARY= 1,
EVAL_BINARY_TYPE_ID = 2,
EVAL_BINDING = 3,
EVAL_COMMA = 4,
EVAL_COMPOUND = 5,
EVAL_CONDITIONAL = 6,
EVAL_FIXED= 7,
EVAL_FUNCTION_CALL= 8,
EVAL_FUNCTION_SET= 9,
EVAL_ID= 10,
EVAL_INIT_LIST= 11,
EVAL_MEMBER_ACCESS= 12,
EVAL_TYPE_ID= 13,
EVAL_UNARY= 14,
EVAL_UNARY_TYPE_ID = 15;
static final byte KIND_MASK= 15;
final static int FLAG1 = 0x10; final static int FLAG1 = 0x10;
final static int FLAG2 = 0x20; final static int FLAG2 = 0x20;
@ -41,6 +60,7 @@ public interface ITypeMarshalBuffer {
IType unmarshalType() throws CoreException; IType unmarshalType() throws CoreException;
IValue unmarshalValue() throws CoreException; IValue unmarshalValue() throws CoreException;
IBinding unmarshalBinding() throws CoreException; IBinding unmarshalBinding() throws CoreException;
ISerializableEvaluation unmarshalEvaluation() throws CoreException;
int getByte() throws CoreException; int getByte() throws CoreException;
int getShort() throws CoreException; int getShort() throws CoreException;
long getLong() throws CoreException; long getLong() throws CoreException;
@ -49,6 +69,7 @@ public interface ITypeMarshalBuffer {
void marshalType(IType type) throws CoreException; void marshalType(IType type) throws CoreException;
void marshalValue(IValue value) throws CoreException; void marshalValue(IValue value) throws CoreException;
void marshalBinding(IBinding binding) throws CoreException; void marshalBinding(IBinding binding) throws CoreException;
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void putByte(byte data); void putByte(byte data);
void putShort(short data); void putShort(short data);
void putLong(long data); void putLong(long data);

View file

@ -209,10 +209,22 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/
/**
* @deprecated Use {@link #getBindings(ScopeLookupData)} instead
*/
@Deprecated
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) * @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/ */
@Override @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { public IBinding[] getBindings(ScopeLookupData lookup) {
return IBinding.EMPTY_BINDING_ARRAY; return IBinding.EMPTY_BINDING_ARRAY;
} }

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IProblemType; import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.parser.ParserMessages; import org.eclipse.cdt.internal.core.parser.ParserMessages;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -20,6 +21,7 @@ import org.eclipse.core.runtime.CoreException;
*/ */
public class ProblemType implements IProblemType, ISerializableType { public class ProblemType implements IProblemType, ISerializableType {
public static final IType UNRESOLVED_NAME = new ProblemType(TYPE_UNRESOLVED_NAME); public static final IType UNRESOLVED_NAME = new ProblemType(TYPE_UNRESOLVED_NAME);
public static final IType UNKNOWN_FOR_EXPRESSION = new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
private final int fID; private final int fID;

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -36,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
@ -75,7 +77,7 @@ public class Value implements IValue {
private static class Reevaluation { private static class Reevaluation {
public final char[] fExpression; public final char[] fExpression;
private int fPackOffset; private final int fPackOffset;
public int pos=0; public int pos=0;
public final Map<String, Integer> fUnknownSigs; public final Map<String, Integer> fUnknownSigs;
public final List<ICPPUnknownBinding> fUnknowns; public final List<ICPPUnknownBinding> fUnknowns;
@ -989,4 +991,9 @@ public class Value implements IValue {
buf.getChars(0, len, result, 0); buf.getChars(0, len, result, 0);
return result; return result;
} }
public static IValue create(ICPPEvaluation eval, IASTNode point) {
// compute value of evaluation
return Value.UNKNOWN;
}
} }

View file

@ -14,7 +14,6 @@
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
@ -105,21 +104,17 @@ public class CASTIdExpression extends ASTNode implements IASTIdExpression, IASTC
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
IBinding binding = getName().resolveBinding(); IBinding binding = getName().resolveBinding();
try { if (binding instanceof IVariable) {
if (binding instanceof IVariable) { return ((IVariable)binding).getType();
return ((IVariable)binding).getType(); }
} if (binding instanceof IFunction) {
if (binding instanceof IFunction) { return ((IFunction)binding).getType();
return ((IFunction)binding).getType(); }
} if (binding instanceof IEnumerator) {
if (binding instanceof IEnumerator) { return ((IEnumerator)binding).getType();
return ((IEnumerator)binding).getType(); }
} if (binding instanceof IProblemBinding) {
if (binding instanceof IProblemBinding) { return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
}
} catch (DOMException e) {
return e.getProblem();
} }
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
} }

View file

@ -160,7 +160,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.ARRAY; int firstByte= ITypeMarshalBuffer.ARRAY_TYPE;
int flags= 0; int flags= 0;
short nval= -1; short nval= -1;
IValue val= null; IValue val= null;

View file

@ -94,7 +94,7 @@ public class CPointerType implements ICPointerType, ITypeContainer, ISerializabl
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.POINTER; int firstByte= ITypeMarshalBuffer.POINTER_TYPE;
if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1;
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3;

View file

@ -144,7 +144,7 @@ public class CQualifierType implements ICQualifierType, ITypeContainer, ISeriali
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.CVQUALIFIER; int firstByte= ITypeMarshalBuffer.CVQUALIFIER_TYPE;
if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1;
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3;

View file

@ -247,7 +247,7 @@ public class CScope implements ICScope, IASTInternalScope {
@Override @Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); return getBindings(new ScopeLookupData(name, resolve, prefix));
} }
@Override @Override
@ -330,16 +330,28 @@ public class CScope implements ICScope, IASTInternalScope {
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.c.ICScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/
/**
* @deprecated Use {@link #getBindings(ScopeLookupData)} instead
*/
@Deprecated
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.c.ICScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) * @see org.eclipse.cdt.core.dom.ast.c.ICScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean)
*/ */
@Override @Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { public final IBinding[] getBindings(ScopeLookupData lookup) {
char[] c = name.toCharArray(); char[] c = lookup.getLookupKey();
Object[] obj = null; Object[] obj = null;
populateCache(); populateCache();
for (CharArrayObjectMap<?> map : mapsToNameOrBinding) { for (CharArrayObjectMap<?> map : mapsToNameOrBinding) {
if (prefixLookup) { if (lookup.isPrefixLookup()) {
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c); IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c);
Object[] keys = map.keyArray(); Object[] keys = map.keyArray();
for (Object key2 : keys) { for (Object key2 : keys) {
@ -358,11 +370,12 @@ public class CScope implements ICScope, IASTInternalScope {
IIndex index = tu.getIndex(); IIndex index = tu.getIndex();
if (index != null) { if (index != null) {
try { try {
IBinding[] bindings = prefixLookup ? IBinding[] bindings = lookup.isPrefixLookup() ?
index.findBindingsForContentAssist(name.toCharArray(), true, INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null) : index.findBindingsForContentAssist(lookup.getLookupKey(), true, INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null) :
index.findBindings(name.toCharArray(), INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null); index.findBindings(lookup.getLookupKey(), INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null);
if (fileSet != null) { IIndexFileSet filter = lookup.getIncludedFiles();
bindings = fileSet.filterFileLocalBindings(bindings); if (filter != null) {
bindings = filter.filterFileLocalBindings(bindings);
} }
obj = ArrayUtil.addAll(Object.class, obj, bindings); obj = ArrayUtil.addAll(Object.class, obj, bindings);
@ -387,7 +400,7 @@ public class CScope implements ICScope, IASTInternalScope {
if (n != null) { if (n != null) {
IBinding b = n.getBinding(); IBinding b = n.getBinding();
if (b == null) { if (b == null) {
if (resolve && n != name) { if (lookup.isResolve() && n != lookup.getLookupPoint()) {
b = n.resolveBinding(); b = n.resolveBinding();
} }
} }

View file

@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.ILabel;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IScope.ScopeLookupData;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
@ -356,7 +357,7 @@ public class CVisitor extends ASTQueries {
public static class CollectReferencesAction extends ASTVisitor { public static class CollectReferencesAction extends ASTVisitor {
private static final int DEFAULT_LIST_SIZE = 8; private static final int DEFAULT_LIST_SIZE = 8;
private IASTName[] refs; private IASTName[] refs;
private IBinding binding; private final IBinding binding;
private int idx = 0; private int idx = 0;
private int kind; private int kind;
@ -1065,23 +1066,11 @@ public class CVisitor extends ASTQueries {
if (scope == null) if (scope == null)
return null; return null;
IIndexFileSet fileSet= IIndexFileSet.EMPTY;
IASTTranslationUnit tu= name.getTranslationUnit();
if (tu == null && scope instanceof IASTInternalScope) {
tu= ((IASTInternalScope) scope).getPhysicalNode().getTranslationUnit();
}
if (tu != null) {
final IIndexFileSet fs= (IIndexFileSet) tu.getAdapter(IIndexFileSet.class);
if (fs != null) {
fileSet= fs;
}
}
IBinding[] result = null; IBinding[] result = null;
CharArraySet handled= new CharArraySet(1); CharArraySet handled= new CharArraySet(1);
while (scope != null) { while (scope != null) {
if (!(scope instanceof ICCompositeTypeScope)) { if (!(scope instanceof ICCompositeTypeScope)) {
IBinding[] bindings= scope.getBindings(name, true, true, fileSet); IBinding[] bindings= scope.getBindings(new ScopeLookupData(name, true, true));
for (IBinding b : bindings) { for (IBinding b : bindings) {
final char[] n= b.getNameCharArray(); final char[] n= b.getNameCharArray();
// consider binding only if no binding with the same name was found in another scope. // consider binding only if no binding with the same name was found in another scope.

View file

@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTName; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
@ -63,11 +64,11 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
@Override @Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); return getBindings(new ScopeLookupData(name, resolve, prefix));
} }
@Override @Override
public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) { public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) {
char[] c = name.getLookupKey(); char[] c = name.getLookupKey();
if (CharArrayUtils.equals(c, specialClass.getNameCharArray()) if (CharArrayUtils.equals(c, specialClass.getNameCharArray())
@ -77,44 +78,39 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
ICPPClassType specialized = specialClass.getSpecializedBinding(); ICPPClassType specialized = specialClass.getSpecializedBinding();
IScope classScope = specialized.getCompositeScope(); IScope classScope = specialized.getCompositeScope();
IBinding[] bindings = classScope != null ? classScope.getBindings(name, forceResolve, false) : null; IBinding[] bindings = classScope != null ? classScope.getBindings(new ScopeLookupData(name, resolve, false)) : null;
if (bindings == null) if (bindings == null)
return null; return null;
IBinding[] specs = new IBinding[0]; IBinding[] specs = new IBinding[0];
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
specs = ArrayUtil.append(IBinding.class, specs, specialClass.specializeMember(binding)); specs = ArrayUtil.append(IBinding.class, specs, specialClass.specializeMember(binding, name));
} }
specs = ArrayUtil.trim(IBinding.class, specs); specs = ArrayUtil.trim(IBinding.class, specs);
return CPPSemantics.resolveAmbiguities(name, specs); return CPPSemantics.resolveAmbiguities(name, specs);
} }
@Override @Deprecated @Override
final public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup, final public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
IIndexFileSet fileSet) { IIndexFileSet fileSet) {
return getBindings(name, forceResolve, prefixLookup, fileSet, true); return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
} }
public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup, @Override
IIndexFileSet fileSet, boolean checkPointOfDecl) { final public IBinding[] getBindings(ScopeLookupData lookup) {
ICPPClassType specialized = specialClass.getSpecializedBinding(); ICPPClassType specialized = specialClass.getSpecializedBinding();
IScope classScope = specialized.getCompositeScope(); IScope classScope = specialized.getCompositeScope();
if (classScope == null) if (classScope == null)
return IBinding.EMPTY_BINDING_ARRAY; return IBinding.EMPTY_BINDING_ARRAY;
IBinding[] bindings; IBinding[] bindings= classScope.getBindings(lookup);
if (classScope instanceof ICPPASTInternalScope) {
bindings= ((ICPPASTInternalScope) classScope).getBindings(name, forceResolve, prefixLookup, fileSet, checkPointOfDecl);
} else {
bindings= classScope.getBindings(name, forceResolve, prefixLookup, fileSet);
}
IBinding[] result= null; IBinding[] result= null;
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
if (binding == specialized) { if (binding == specialized) {
binding= specialClass; binding= specialClass;
} else { } else {
binding= specialClass.specializeMember(binding); binding= specialClass.specializeMember(binding, lookup.getLookupPoint());
} }
result = ArrayUtil.append(IBinding.class, result, binding); result = ArrayUtil.append(IBinding.class, result, binding);
} }
@ -134,11 +130,12 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
if (bases.length == 0) { if (bases.length == 0) {
fBases= bases; fBases= bases;
} else { } else {
IASTNode point= null; // Instantiation of dependent expression may not work.
final ICPPTemplateParameterMap tpmap = specialClass.getTemplateParameterMap(); final ICPPTemplateParameterMap tpmap = specialClass.getTemplateParameterMap();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding origClass = base.getBaseClass(); IBinding origClass = base.getBaseClass();
if (origClass instanceof ICPPTemplateParameter && ((ICPPTemplateParameter) origClass).isParameterPack()) { if (origClass instanceof ICPPTemplateParameter && ((ICPPTemplateParameter) origClass).isParameterPack()) {
IType[] specClasses= CPPTemplates.instantiateTypes(new IType[]{new CPPParameterPackType((IType) origClass)}, tpmap, -1, specialClass); IType[] specClasses= CPPTemplates.instantiateTypes(new IType[]{new CPPParameterPackType((IType) origClass)}, tpmap, -1, specialClass, point);
if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) { if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) {
result= ArrayUtil.append(ICPPBase.class, result, base); result= ArrayUtil.append(ICPPBase.class, result, base);
} else { } else {
@ -155,7 +152,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
if (origClass instanceof IType) { if (origClass instanceof IType) {
ICPPBase specBase = base.clone(); ICPPBase specBase = base.clone();
IType specClass= CPPTemplates.instantiateType((IType) origClass, tpmap, -1, specialClass); IType specClass= CPPTemplates.instantiateType((IType) origClass, tpmap, -1, specialClass, point);
specClass = SemanticUtil.getUltimateType(specClass, false); specClass = SemanticUtil.getUltimateType(specClass, false);
if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) { if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) {
specBase.setBaseClass((IBinding) specClass); specBase.setBaseClass((IBinding) specClass);
@ -172,31 +169,33 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T extends IBinding> T[] specializeMembers(T[] array) { private <T extends IBinding> T[] specializeMembers(T[] array, IASTNode point) {
if (array == null || array.length == 0) if (array == null || array.length == 0)
return array; return array;
T[] newArray= array.clone(); T[] newArray= array.clone();
for (int i = 0; i < newArray.length; i++) { for (int i = 0; i < newArray.length; i++) {
newArray[i]= (T) specialClass.specializeMember(array[i]); newArray[i]= (T) specialClass.specializeMember(array[i], point);
} }
return newArray; return newArray;
} }
@Override @Override
public ICPPField[] getDeclaredFields() { public ICPPField[] getDeclaredFields() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields(); ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields();
return specializeMembers(fields); return specializeMembers(fields, point);
} }
@Override @Override
public ICPPMethod[] getImplicitMethods() { public ICPPMethod[] getImplicitMethods() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPClassScope origClassScope= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope(); ICPPClassScope origClassScope= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope();
if (origClassScope == null) { if (origClassScope == null) {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
} }
ICPPMethod[] methods= origClassScope.getImplicitMethods(); ICPPMethod[] methods= origClassScope.getImplicitMethods();
return specializeMembers(methods); return specializeMembers(methods, point);
} }
@Override @Override
@ -208,26 +207,31 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
@Override @Override
public ICPPConstructor[] getConstructors() { public ICPPConstructor[] getConstructors() {
// mstodo need to pass the point of instantiation
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors(); ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors();
return specializeMembers(ctors); return specializeMembers(ctors, point);
} }
@Override @Override
public ICPPMethod[] getDeclaredMethods() { public ICPPMethod[] getDeclaredMethods() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods(); ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods();
return specializeMembers(bindings); return specializeMembers(bindings, point);
} }
@Override @Override
public ICPPClassType[] getNestedClasses() { public ICPPClassType[] getNestedClasses() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses(); ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses();
return specializeMembers(bindings); return specializeMembers(bindings, point);
} }
@Override @Override
public IBinding[] getFriends() { public IBinding[] getFriends() {
IASTNode point= null; // Instantiation of dependent expression may not work.
IBinding[] friends = specialClass.getSpecializedBinding().getFriends(); IBinding[] friends = specialClass.getSpecializedBinding().getFriends();
return specializeMembers(friends); return specializeMembers(friends, point);
} }
@Override @Override

View file

@ -12,9 +12,10 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousBinaryVsCastExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousBinaryVsCastExpression;
public class CPPASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsCastExpression { public class CPPASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsCastExpression implements ICPPASTExpression {
public CPPASTAmbiguousBinaryVsCastExpression(IASTBinaryExpression bexp, IASTCastExpression castExpr) { public CPPASTAmbiguousBinaryVsCastExpression(IASTBinaryExpression bexp, IASTCastExpression castExpr) {
super(bexp, castExpr); super(bexp, castExpr);

View file

@ -12,9 +12,11 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousCastVsFunctionCallExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousCastVsFunctionCallExpression;
public class CPPASTAmbiguousCastVsFunctionCallExpression extends ASTAmbiguousCastVsFunctionCallExpression { public class CPPASTAmbiguousCastVsFunctionCallExpression extends
ASTAmbiguousCastVsFunctionCallExpression implements ICPPASTExpression {
public CPPASTAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall) { public CPPASTAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall) {
super(castExpr, funcCall); super(castExpr, funcCall);

View file

@ -13,12 +13,13 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
public class CPPASTAmbiguousExpression extends ASTAmbiguousNode implements public class CPPASTAmbiguousExpression extends ASTAmbiguousNode implements
IASTAmbiguousExpression { IASTAmbiguousExpression, ICPPASTExpression {
private IASTExpression [] exp = new IASTExpression[2]; private IASTExpression [] exp = new IASTExpression[2];
private int expPos=-1; private int expPos=-1;

View file

@ -13,42 +13,28 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTArraySubscriptExpression extends ASTNode public class CPPASTArraySubscriptExpression extends ASTNode
implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent { implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent {
private IASTExpression arrayExpression; private ICPPASTExpression arrayExpression;
private IASTInitializerClause subscriptExp; private ICPPASTInitializerClause subscriptExp;
private ICPPFunction overload= UNINITIALIZED_FUNCTION; private ICPPEvaluation evaluation;
private IASTImplicitName[] implicitNames; private IASTImplicitName[] implicitNames;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTArraySubscriptExpression() { public CPPASTArraySubscriptExpression() {
} }
@ -76,33 +62,37 @@ public class CPPASTArraySubscriptExpression extends ASTNode
} }
@Override @Override
public IASTExpression getArrayExpression() { public ICPPASTExpression getArrayExpression() {
return arrayExpression; return arrayExpression;
} }
@Override @Override
public void setArrayExpression(IASTExpression expression) { public void setArrayExpression(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
arrayExpression = expression;
if (expression != null) { if (expression != null) {
if (!(expression instanceof ICPPASTExpression))
throw new IllegalArgumentException(expression.getClass().getName());
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(ARRAY); expression.setPropertyInParent(ARRAY);
} }
arrayExpression = (ICPPASTExpression) expression;
} }
@Override @Override
public IASTInitializerClause getArgument() { public ICPPASTInitializerClause getArgument() {
return subscriptExp; return subscriptExp;
} }
@Override @Override
public void setArgument(IASTInitializerClause arg) { public void setArgument(IASTInitializerClause arg) {
assertNotFrozen(); assertNotFrozen();
subscriptExp = arg;
if (arg != null) { if (arg != null) {
if (!(arg instanceof ICPPASTInitializerClause))
throw new IllegalArgumentException(arg.getClass().getName());
arg.setParent(this); arg.setParent(this);
arg.setPropertyInParent(SUBSCRIPT); arg.setPropertyInParent(SUBSCRIPT);
} }
subscriptExp = (ICPPASTInitializerClause) arg;
} }
@Override @Override
@ -118,7 +108,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode
public void setSubscriptExpression(IASTExpression expression) { public void setSubscriptExpression(IASTExpression expression) {
setArgument(expression); setArgument(expression);
} }
@Override @Override
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (implicitNames == null) {
@ -141,20 +131,15 @@ public class CPPASTArraySubscriptExpression extends ASTNode
return implicitNames; return implicitNames;
} }
public ICPPFunction getOverload() {
if (overload == UNINITIALIZED_FUNCTION) {
overload= null;
IType t = getArrayExpression().getExpressionType();
t= SemanticUtil.getNestedType(t, TDEF | REF | CVTYPE);
if (t instanceof ICPPClassType) {
overload= CPPSemantics.findOverloadedOperator(this);
}
}
return overload;
}
@Override private ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalBinary)
return ((EvalBinary) eval).getOverload(this);
return null;
}
@Override
public boolean accept(ASTVisitor action) { public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) { if (action.shouldVisitExpressions) {
switch (action.visit(this)) { switch (action.visit(this)) {
@ -192,56 +177,41 @@ public class CPPASTArraySubscriptExpression extends ASTNode
if (child == subscriptExp) { if (child == subscriptExp) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
subscriptExp = (IASTExpression) other; subscriptExp = (ICPPASTExpression) other;
} }
if (child == arrayExpression) { if (child == arrayExpression) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
arrayExpression = (IASTExpression) other; arrayExpression = (ICPPASTExpression) other;
} }
} }
@Override
public ICPPEvaluation getEvaluation() {
if (evaluation == null)
evaluation= computeEvaluation();
return evaluation;
}
private ICPPEvaluation computeEvaluation() {
if (arrayExpression == null || subscriptExp == null)
return EvalFixed.INCOMPLETE;
return new EvalBinary(EvalBinary.op_arrayAccess, arrayExpression.getEvaluation(), subscriptExp.getEvaluation());
}
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
ICPPFunction op = getOverload(); return getEvaluation().getTypeOrFunctionSet(this);
if (op != null) {
return ExpressionTypes.typeFromFunctionCall(op);
}
IType t1 = getArrayExpression().getExpressionType();
t1= Conversions.lvalue_to_rvalue(t1, true);
if (t1 instanceof IPointerType) {
t1= ((IPointerType) t1).getType();
return glvalueType(t1);
}
IType t2= null;
IASTInitializerClause arg = getArgument();
if (arg instanceof IASTExpression) {
t2= Conversions.lvalue_to_rvalue(t2, true);
if (t2 instanceof IPointerType) {
t2= ((IPointerType) t2).getType();
return glvalueType(t2);
}
}
if (t1 instanceof ICPPUnknownType || t2 instanceof ICPPUnknownType) {
// mstodo type of unknown
return CPPUnknownClass.createUnnamedInstance();
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
} }
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
@Override @Override
public boolean isLValue() { public boolean isLValue() {
return getValueCategory() == LVALUE; return getValueCategory() == LVALUE;
} }
@Override
public ValueCategory getValueCategory() {
ICPPFunction op = getOverload();
if (op != null) {
return ExpressionTypes.valueCategoryFromFunctionCall(op);
}
return ValueCategory.LVALUE;
}
} }

View file

@ -14,9 +14,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
@ -25,33 +22,25 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent { public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
private int op; private int op;
private IASTExpression operand1; private ICPPASTExpression operand1;
private IASTInitializerClause operand2; private ICPPASTInitializerClause operand2;
private IType type;
private ICPPFunction overload= UNINITIALIZED_FUNCTION; private ICPPEvaluation evaluation;
private IASTImplicitName[] implicitNames = null; private IASTImplicitName[] implicitNames = null;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTBinaryExpression() { public CPPASTBinaryExpression() {
} }
@ -107,20 +96,25 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
@Override @Override
public void setOperand1(IASTExpression expression) { public void setOperand1(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
operand1 = expression;
if (expression != null) { if (expression != null) {
if (!(expression instanceof ICPPASTExpression))
throw new IllegalArgumentException(expression.getClass().getName());
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(OPERAND_ONE); expression.setPropertyInParent(OPERAND_ONE);
} }
operand1 = (ICPPASTExpression) expression;
} }
public void setInitOperand2(IASTInitializerClause operand) { public void setInitOperand2(IASTInitializerClause operand) {
assertNotFrozen(); assertNotFrozen();
operand2 = operand;
if (operand != null) { if (operand != null) {
if (!(operand instanceof ICPPASTInitializerClause))
throw new IllegalArgumentException(operand.getClass().getName());
operand.setParent(this); operand.setParent(this);
operand.setPropertyInParent(OPERAND_TWO); operand.setPropertyInParent(OPERAND_TWO);
} }
operand2 = (ICPPASTInitializerClause) operand;
} }
@Override @Override
@ -251,144 +245,51 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
if (child == operand1) { if (child == operand1) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
operand1 = (IASTExpression) other; operand1 = (ICPPASTExpression) other;
} }
if (child == operand2) { if (child == operand2) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
operand2 = (IASTInitializerClause) other; operand2 = (ICPPASTInitializerClause) other;
} }
} }
@Override
public IType getExpressionType() {
if (type == null) {
type= createExpressionType();
}
return type;
}
@Override @Override
public ICPPFunction getOverload() { public ICPPFunction getOverload() {
if (overload != UNINITIALIZED_FUNCTION) ICPPEvaluation eval = getEvaluation();
return overload; if (eval instanceof EvalBinary)
return ((EvalBinary) eval).getOverload(this);
return overload = CPPSemantics.findOverloadedOperator(this); return null;
}
@Override
public ValueCategory getValueCategory() {
ICPPFunction op = getOverload();
if (op != null) {
return valueCategoryFromFunctionCall(op);
}
switch (getOperator()) {
case op_assign:
case op_binaryAndAssign:
case op_binaryOrAssign:
case op_binaryXorAssign:
case op_divideAssign:
case op_minusAssign:
case op_moduloAssign:
case op_multiplyAssign:
case op_plusAssign:
case op_shiftLeftAssign:
case op_shiftRightAssign:
return LVALUE;
case op_pmdot:
if (!(getExpressionType() instanceof ICPPFunctionType)) {
return operand1.getValueCategory();
}
return PRVALUE;
case op_pmarrow:
if (!(getExpressionType() instanceof ICPPFunctionType))
return LVALUE;
return PRVALUE;
}
return PRVALUE;
} }
@Override
public ICPPEvaluation getEvaluation() {
if (evaluation == null)
evaluation= computeEvaluation();
return evaluation;
}
private ICPPEvaluation computeEvaluation() {
if (operand1 == null || operand2 == null)
return EvalFixed.INCOMPLETE;
return new EvalBinary(op, operand1.getEvaluation(), operand2.getEvaluation());
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
@Override @Override
public boolean isLValue() { public boolean isLValue() {
return getValueCategory() == LVALUE; return getValueCategory() == LVALUE;
} }
private IType createExpressionType() {
IType originalType1 = operand1.getExpressionType();
IType originalType2 = operand2 instanceof IASTExpression ?
((IASTExpression) operand2).getExpressionType() : null;
// Check for overloaded operator.
ICPPFunction o= getOverload();
if (o != null) {
IType type = typeFromFunctionCall(o);
return restoreTypedefs(type, originalType1, originalType2);
}
final int op = getOperator();
IType type1 = prvalueType(originalType1);
if (type1 instanceof ISemanticProblem) {
return type1;
}
IType type2 = null;
if (originalType2 != null) {
type2= prvalueType(originalType2);
if (type2 instanceof ISemanticProblem) {
return type2;
}
}
IType type= CPPArithmeticConversion.convertCppOperandTypes(op, type1, type2);
if (type != null) {
return restoreTypedefs(type, originalType1, originalType2);
}
switch (op) {
case IASTBinaryExpression.op_lessEqual:
case IASTBinaryExpression.op_lessThan:
case IASTBinaryExpression.op_greaterEqual:
case IASTBinaryExpression.op_greaterThan:
case IASTBinaryExpression.op_logicalAnd:
case IASTBinaryExpression.op_logicalOr:
case IASTBinaryExpression.op_equals:
case IASTBinaryExpression.op_notequals:
return CPPBasicType.BOOLEAN;
case IASTBinaryExpression.op_plus:
if (SemanticUtil.getNestedType(type1, TDEF) instanceof IPointerType) {
return type1;
}
if (SemanticUtil.getNestedType(type2, TDEF) instanceof IPointerType) {
return type2;
}
break;
case IASTBinaryExpression.op_minus:
if (SemanticUtil.getNestedType(type1, TDEF) instanceof IPointerType) {
if (SemanticUtil.getNestedType(type2, TDEF) instanceof IPointerType) {
return CPPVisitor.getPointerDiffType(this);
}
return type1;
}
break;
case ICPPASTBinaryExpression.op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot:
if (type2 instanceof ICPPPointerToMemberType) {
IType t= ((ICPPPointerToMemberType) type2).getType();
if (t instanceof ICPPFunctionType)
return t;
if (op == ICPPASTBinaryExpression.op_pmdot && operand1.getValueCategory() == PRVALUE) {
return prvalueType(t);
}
return glvalueType(t);
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return restoreTypedefs(type1, originalType1);
}
} }

View file

@ -11,28 +11,24 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpression, IASTBinaryTypeIdExpression { public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpression, IASTBinaryTypeIdExpression {
private Operator fOperator; private Operator fOperator;
private IASTTypeId fOperand1; private IASTTypeId fOperand1;
private IASTTypeId fOperand2; private IASTTypeId fOperand2;
@Override private ICPPEvaluation fEvaluation;
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTBinaryTypeIdExpression() { public CPPASTBinaryTypeIdExpression() {
} }
@ -122,12 +118,26 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr
} }
@Override @Override
public IType getExpressionType() { public ICPPEvaluation getEvaluation() {
switch (getOperator()) { if (fEvaluation == null) {
case __is_base_of: if (fOperand1 == null || fOperand2 == null) {
return CPPBasicType.BOOLEAN; fEvaluation= EvalFixed.INCOMPLETE;
} else {
IType t1= CPPVisitor.createType(fOperand1);
IType t2= CPPVisitor.createType(fOperand1);
if (t1 == null || t2 == null) {
fEvaluation= EvalFixed.INCOMPLETE;
} else {
fEvaluation= new EvalBinaryTypeId(fOperator, t1, t2);
}
}
} }
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); return fEvaluation;
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
} }
@Override @Override
@ -137,6 +147,6 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return isLValue() ? LVALUE : PRVALUE; return PRVALUE;
} }
} }

View file

@ -12,34 +12,30 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
/** /**
* Cast expression for C++ * Cast expression for C++
*/ */
public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpression, IASTAmbiguityParent { public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpression, IASTAmbiguityParent {
private int op; private int op;
private IASTExpression operand; private ICPPASTExpression operand;
private IASTTypeId typeId; private IASTTypeId typeId;
private IType fType; private ICPPEvaluation fEvaluation;
private ValueCategory fValueCategory;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTCastExpression() { public CPPASTCastExpression() {
} }
@ -102,7 +98,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
@Override @Override
public void setOperand(IASTExpression expression) { public void setOperand(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
operand = expression; operand = (ICPPASTExpression) expression;
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(OPERAND); expression.setPropertyInParent(OPERAND);
@ -138,26 +134,38 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
if (child == operand) { if (child == operand) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
operand = (IASTExpression) other; operand = (ICPPASTExpression) other;
} }
} }
@Override @Override
public IType getExpressionType() { public ICPPEvaluation getEvaluation() {
if (fType == null) { if (fEvaluation == null)
IType t= CPPVisitor.createType(typeId.getAbstractDeclarator()); fEvaluation= computeEvaluation();
fValueCategory= valueCategoryFromReturnType(t);
fType= typeFromReturnType(t); return fEvaluation;
}
return fType;
} }
private ICPPEvaluation computeEvaluation() {
if (operand == null)
return EvalFixed.INCOMPLETE;
IType type= CPPVisitor.createType(getTypeId());
if (type == null || type instanceof IProblemType)
return EvalFixed.INCOMPLETE;
return new EvalTypeId(type, operand.getEvaluation());
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
if (fValueCategory == null) { return getEvaluation().getValueCategory(this);
getExpressionType(); // as a side effect fValueCategory is computed
}
return fValueCategory;
} }
@Override @Override

View file

@ -12,18 +12,17 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompound;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
/** /**
* Gnu-extension: ({ ... }) * Gnu-extension: ({ ... })
@ -31,14 +30,25 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUASTCompoundStatementExpression, ICPPASTExpression { public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUASTCompoundStatementExpression, ICPPASTExpression {
private IASTCompoundStatement statement; private IASTCompoundStatement statement;
private ICPPEvaluation fEval;
public CPPASTCompoundStatementExpression() { public CPPASTCompoundStatementExpression() {
} }
@Override @Override
public ICPPInitClauseEvaluation getEvaluation() { public ICPPEvaluation getEvaluation() {
// mstodo Auto-generated method stub if (fEval == null) {
return null; IASTCompoundStatement compound = getCompoundStatement();
IASTStatement[] statements = compound.getStatements();
if (statements.length > 0) {
IASTStatement st = statements[statements.length - 1];
if (st instanceof IASTExpressionStatement) {
fEval= new EvalCompound(((ICPPASTExpression) ((IASTExpressionStatement) st).getExpression()).getEvaluation());
}
}
if (fEval == null)
fEval= EvalFixed.INCOMPLETE;
}
return fEval;
} }
public CPPASTCompoundStatementExpression(IASTCompoundStatement statement) { public CPPASTCompoundStatementExpression(IASTCompoundStatement statement) {
@ -100,14 +110,7 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
IASTCompoundStatement compound = getCompoundStatement(); return getEvaluation().getTypeOrFunctionSet(this);
IASTStatement[] statements = compound.getStatements();
if (statements.length > 0) {
IASTStatement st = statements[statements.length - 1];
if (st instanceof IASTExpressionStatement)
return prvalueType(((IASTExpressionStatement) st).getExpression().getExpressionType());
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
} }
@Override @Override

View file

@ -12,54 +12,29 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
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.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTConditionalExpression extends ASTNode implements IASTConditionalExpression, public class CPPASTConditionalExpression extends ASTNode implements IASTConditionalExpression,
ICPPASTExpression, IASTAmbiguityParent { ICPPASTExpression, IASTAmbiguityParent {
private IASTExpression fCondition; private ICPPASTExpression fCondition;
private IASTExpression fPositive; private ICPPASTExpression fPositive;
private IASTExpression fNegative; private ICPPASTExpression fNegative;
private IType fType; private ICPPEvaluation fEval;
private ValueCategory fValueCategory;
public CPPASTConditionalExpression() { public CPPASTConditionalExpression() {
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTConditionalExpression(IASTExpression condition, IASTExpression postive, IASTExpression negative) { public CPPASTConditionalExpression(IASTExpression condition, IASTExpression postive, IASTExpression negative) {
setLogicalConditionExpression(condition); setLogicalConditionExpression(condition);
setPositiveResultExpression(postive); setPositiveResultExpression(postive);
@ -92,7 +67,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
@Override @Override
public void setLogicalConditionExpression(IASTExpression expression) { public void setLogicalConditionExpression(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
fCondition = expression; fCondition = (ICPPASTExpression) expression;
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(LOGICAL_CONDITION); expression.setPropertyInParent(LOGICAL_CONDITION);
@ -107,7 +82,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
@Override @Override
public void setPositiveResultExpression(IASTExpression expression) { public void setPositiveResultExpression(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
this.fPositive = expression; this.fPositive = (ICPPASTExpression) expression;
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(POSITIVE_RESULT); expression.setPropertyInParent(POSITIVE_RESULT);
@ -122,7 +97,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
@Override @Override
public void setNegativeResultExpression(IASTExpression expression) { public void setNegativeResultExpression(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
this.fNegative = expression; this.fNegative = (ICPPASTExpression) expression;
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(NEGATIVE_RESULT); expression.setPropertyInParent(NEGATIVE_RESULT);
@ -157,159 +132,19 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
if (child == fCondition) { if (child == fCondition) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
fCondition = (IASTExpression) other; fCondition = (ICPPASTExpression) other;
} }
if (child == fPositive) { if (child == fPositive) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
fPositive = (IASTExpression) other; fPositive = (ICPPASTExpression) other;
} }
if (child == fNegative) { if (child == fNegative) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
fNegative = (IASTExpression) other; fNegative = (ICPPASTExpression) other;
} }
} }
@Override
public IType getExpressionType() {
evaluate();
return fType;
}
@Override
public ValueCategory getValueCategory() {
evaluate();
return fValueCategory;
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
private void evaluate() {
if (fValueCategory != null)
return;
fValueCategory= PRVALUE;
// Gnu-extension: Empty positive expression is replaced by condition.
IASTExpression expr2 = getPositiveResultExpression();
final IASTExpression expr3 = getNegativeResultExpression();
if (expr2 == null) {
expr2= getLogicalConditionExpression();
}
IType t2 = expr2.getExpressionType();
IType t3 = expr3.getExpressionType();
if (t2 == null || t3 == null) {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
return;
}
final IType uqt2= getNestedType(t2, TDEF | REF | CVTYPE);
final IType uqt3= getNestedType(t3, TDEF | REF | CVTYPE);
if (uqt2 instanceof ISemanticProblem || uqt2 instanceof ICPPUnknownType) {
fType= uqt2;
return;
}
if (uqt3 instanceof ISemanticProblem || uqt3 instanceof ICPPUnknownType) {
fType= uqt3;
return;
}
final boolean void2= isVoidType(uqt2);
final boolean void3= isVoidType(uqt3);
// Void types: Either both are void or one is a throw expression.
if (void2 || void3) {
if (isThrowExpression(expr2)) {
fType= Conversions.lvalue_to_rvalue(t3, false);
} else if (isThrowExpression(expr3)) {
fType= Conversions.lvalue_to_rvalue(t2, false);
} else if (void2 && void3) {
fType= uqt2;
} else {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
final ValueCategory vcat2= expr2.getValueCategory();
final ValueCategory vcat3= expr3.getValueCategory();
// Same type
if (t2.isSameType(t3)) {
if (vcat2 == vcat3) {
fType= t2;
fValueCategory= vcat2;
} else {
fType= prvalueType(t2);
fValueCategory= PRVALUE;
}
return;
}
final boolean isClassType2 = uqt2 instanceof ICPPClassType;
final boolean isClassType3 = uqt3 instanceof ICPPClassType;
// Different types with at least one class type
if (isClassType2 || isClassType3) {
final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3); // sets fType and fValueCategory
final Cost cost3= convertToMatch(t3, vcat3, uqt3, t2, vcat2, uqt2); // sets fType and fValueCategory
if (cost2.converts() || cost3.converts()) {
if (cost2.converts()) {
if (cost3.converts() || cost2.isAmbiguousUDC()) {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
} else if (cost3.isAmbiguousUDC()) {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
} else if (vcat2 == vcat3 && vcat2.isGLValue() && uqt2.isSameType(uqt3)) {
// Two lvalues or two xvalues with same type up to qualification.
final CVQualifier cv2 = SemanticUtil.getCVQualifier(t2);
final CVQualifier cv3 = SemanticUtil.getCVQualifier(t3);
if (cv2.isAtLeastAsQualifiedAs(cv3)) {
fType= t2;
fValueCategory= vcat2;
} else if (cv3.isAtLeastAsQualifiedAs(cv2)) {
fType= t3;
fValueCategory= vcat3;
} else {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
// 5.16-5: At least one class type but no conversion
if (isClassType2 || isClassType3) {
ICPPFunction builtin = CPPSemantics.findOverloadedConditionalOperator(expr2, expr3);
if (builtin != null) {
fType= ExpressionTypes.typeFromFunctionCall(builtin);
} else {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
// 5.16-6
t2= Conversions.lvalue_to_rvalue(t2, false);
t3= Conversions.lvalue_to_rvalue(t3, false);
if (t2.isSameType(t3)) {
fType= t2;
} else {
fType= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t2, t3);
if (fType == null) {
fType= Conversions.compositePointerType(t2, t3);
if (fType == null) {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
}
}
}
private boolean isThrowExpression(IASTExpression expr) { private boolean isThrowExpression(IASTExpression expr) {
while (expr instanceof IASTUnaryExpression) { while (expr instanceof IASTUnaryExpression) {
@ -326,50 +161,33 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
return false; return false;
} }
private Cost convertToMatch(IType t1, ValueCategory vcat1, IType uqt1, IType t2, ValueCategory vcat2, IType uqt2) { @Override
// E2 is an lvalue or E2 is an xvalue public ICPPEvaluation getEvaluation() {
try { if (fEval == null) {
if (vcat2.isGLValue()) { if (fCondition == null || fNegative == null) {
IType target= new CPPReferenceType(t2, vcat2 == XVALUE); fEval= EvalFixed.INCOMPLETE;
Cost c= Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED, Context.REQUIRE_DIRECT_BINDING); } else {
if (c.converts()) { final ICPPEvaluation condEval = fCondition.getEvaluation();
fType= t2; final ICPPEvaluation posEval = fPositive == null ? null : fPositive.getEvaluation();
fValueCategory= vcat2; fEval= new EvalConditional(condEval, posEval, fNegative.getEvaluation(),
return c; isThrowExpression(fPositive), isThrowExpression(fNegative));
}
} }
// Both are class types and one derives from the other
if (uqt1 instanceof ICPPClassType && uqt2 instanceof ICPPClassType) {
int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2);
if (dist >= 0) {
CVQualifier cv1 = SemanticUtil.getCVQualifier(t1);
CVQualifier cv2 = SemanticUtil.getCVQualifier(t2);
if (cv2.isAtLeastAsQualifiedAs(cv1)) {
fType= t2;
fValueCategory= PRVALUE;
return new Cost(t1, t2, Rank.IDENTITY);
}
return Cost.NO_CONVERSION;
}
if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1) >= 0)
return Cost.NO_CONVERSION;
}
// Unrelated class types or just one class:
if (vcat2 != PRVALUE) {
t2= Conversions.lvalue_to_rvalue(t2, false);
}
Cost c= Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY);
if (c.converts()) {
fType= t2;
fValueCategory= PRVALUE;
return c;
}
} catch (DOMException e) {
} }
return Cost.NO_CONVERSION; return fEval;
} }
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
private boolean isVoidType(IType t) { @Override
return t instanceof ICPPBasicType && ((ICPPBasicType) t).getKind() == Kind.eVoid; public boolean isLValue() {
return getValueCategory() == LVALUE;
} }
} }

View file

@ -23,20 +23,19 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression { public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
private static final ICPPEvaluation EVALUATION = new EvalFixed(CPPSemantics.VOID_TYPE, PRVALUE, Value.UNKNOWN);
private IASTExpression operand; private IASTExpression operand;
private boolean isGlobal; private boolean isGlobal;
private boolean isVectored; private boolean isVectored;
private IASTImplicitName[] implicitNames = null; private IASTImplicitName[] implicitNames = null;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTDeleteExpression() { public CPPASTDeleteExpression() {
} }
@ -172,6 +171,11 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
return true; return true;
} }
@Override
public ICPPEvaluation getEvaluation() {
return EVALUATION;
}
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return CPPSemantics.VOID_TYPE; return CPPSemantics.VOID_TYPE;

View file

@ -13,30 +13,22 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent { public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
private static final ICPPFunction[] NO_FUNCTIONS = {};
private IASTExpression[] expressions = new IASTExpression[2]; private IASTExpression[] expressions = new IASTExpression[2];
@ -45,13 +37,8 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
* @see CPPASTExpressionList#computeImplicitNames * @see CPPASTExpressionList#computeImplicitNames
*/ */
private IASTImplicitName[] implicitNames; private IASTImplicitName[] implicitNames;
private ICPPFunction[] overloads;
private ICPPEvaluation fEvaluation;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTExpressionList copy() { public CPPASTExpressionList copy() {
@ -155,42 +142,11 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
} }
private ICPPFunction[] getOverloads() { private ICPPFunction[] getOverloads() {
if (overloads == null) { ICPPEvaluation eval = getEvaluation();
IASTExpression[] exprs = getExpressions(); if (eval instanceof EvalComma) {
if (exprs.length < 2) return ((EvalComma) eval).getOverloads(this);
return overloads = NO_FUNCTIONS;
ASTNodeProperty prop = getPropertyInParent();
if (prop == IASTFunctionCallExpression.ARGUMENT ||
prop == ICPPASTConstructorChainInitializer.INITIALIZER ||
prop == ICPPASTConstructorInitializer.ARGUMENT ||
prop == ICPPASTNewExpression.NEW_INITIALIZER)
return overloads = NO_FUNCTIONS;
overloads = new ICPPFunction[exprs.length - 1];
IType lookupType = typeOrFunctionSet(exprs[0]);
ValueCategory vcat= valueCat(exprs[0]);
for (int i = 1; i < exprs.length; i++) {
IASTExpression e1 = exprs[i - 1], e2 = exprs[i];
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(e1, lookupType, vcat, e2);
if (overload == null) {
lookupType = typeOrFunctionSet(e2);
vcat= valueCat(e2);
} else {
overloads[i - 1] = overload;
lookupType = overload.getType().getReturnType();
vcat= valueCategoryFromReturnType(lookupType);
lookupType= typeFromReturnType(lookupType);
if (lookupType instanceof ISemanticProblem) {
lookupType = typeOrFunctionSet(e2);
vcat= valueCat(e2);
}
}
}
} }
return null;
return overloads;
} }
@Override @Override
@ -206,42 +162,35 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
} }
@Override @Override
public IType getExpressionType() { public ICPPEvaluation getEvaluation() {
ICPPFunction[] overloads = getOverloads(); if (fEvaluation == null)
if (overloads.length > 0) { fEvaluation= computeEvaluation();
ICPPFunction last = overloads[overloads.length - 1];
if (last != null) {
return typeFromFunctionCall(last);
}
}
for (int i = expressions.length - 1; i >= 0; i--) {
IASTExpression expr = expressions[i];
if (expr != null)
return expr.getExpressionType();
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); return fEvaluation;
}
@Override
public ValueCategory getValueCategory() {
ICPPFunction[] overloads = getOverloads();
if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1];
if (last != null) {
return valueCategoryFromFunctionCall(last);
}
}
for (int i = expressions.length-1; i >= 0; i--) {
IASTExpression expr= expressions[i];
if (expr != null)
return expr.getValueCategory();
}
return PRVALUE;
} }
private ICPPEvaluation computeEvaluation() {
final IASTExpression[] exprs = getExpressions();
if (exprs.length < 2)
return EvalFixed.INCOMPLETE;
ICPPEvaluation[] evals= new ICPPEvaluation[exprs.length];
for (int i = 0; i < evals.length; i++) {
evals[i]= ((ICPPASTExpression) exprs[i]).getEvaluation();
}
return new EvalComma(evals);
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
@Override @Override
public boolean isLValue() { public boolean isLValue() {
return getValueCategory() == LVALUE; return getValueCategory() == LVALUE;

View file

@ -14,57 +14,45 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueTypeWithResolvedTypedefs;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
public class CPPASTFieldReference extends ASTNode public class CPPASTFieldReference extends ASTNode
implements ICPPASTFieldReference, IASTAmbiguityParent, ICPPASTCompletionContext { implements ICPPASTFieldReference, IASTAmbiguityParent, ICPPASTCompletionContext {
private boolean isTemplate; private boolean isTemplate;
private IASTExpression owner; private ICPPASTExpression owner;
private IASTName name; private IASTName name;
private boolean isDeref; private boolean isDeref;
private IASTImplicitName[] implicitNames; private IASTImplicitName[] implicitNames;
private ICPPEvaluation fEvaluation;
public CPPASTFieldReference() { public CPPASTFieldReference() {
} }
@ -73,11 +61,6 @@ public class CPPASTFieldReference extends ASTNode
setFieldName(name); setFieldName(name);
setFieldOwner(owner); setFieldOwner(owner);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTFieldReference copy() { public CPPASTFieldReference copy() {
@ -110,14 +93,14 @@ public class CPPASTFieldReference extends ASTNode
} }
@Override @Override
public IASTExpression getFieldOwner() { public ICPPASTExpression getFieldOwner() {
return owner; return owner;
} }
@Override @Override
public void setFieldOwner(IASTExpression expression) { public void setFieldOwner(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
owner = expression; owner = (ICPPASTExpression) expression;
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(FIELD_OWNER); expression.setPropertyInParent(FIELD_OWNER);
@ -158,7 +141,7 @@ public class CPPASTFieldReference extends ASTNode
// Collect the function bindings // Collect the function bindings
List<ICPPFunction> functionBindings = new ArrayList<ICPPFunction>(); List<ICPPFunction> functionBindings = new ArrayList<ICPPFunction>();
getFieldOwnerType(functionBindings); EvalMemberAccess.getFieldOwnerType(owner.getExpressionType(), isDeref, this, functionBindings, false);
if (functionBindings.isEmpty()) if (functionBindings.isEmpty())
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
@ -224,100 +207,10 @@ public class CPPASTFieldReference extends ASTNode
if (child == owner) { if (child == owner) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
owner = (IASTExpression) other; owner = (ICPPASTExpression) other;
} }
} }
@Override
public IType getExpressionType() {
IASTName name= getFieldName();
IBinding binding = name.resolvePreBinding();
try {
if (binding instanceof IVariable) {
IType e2= ((IVariable) binding).getType();
e2= SemanticUtil.getNestedType(e2, TDEF);
if (e2 instanceof ICPPReferenceType) {
e2= glvalueType(e2);
} else if (binding instanceof ICPPField && !((ICPPField) binding).isStatic()) {
IType e1= getFieldOwner().getExpressionType();
if (isPointerDereference()) {
e1= SemanticUtil.getNestedType(e1, TDEF | REF | CVTYPE);
if (e1 instanceof IPointerType) {
e1= ((IPointerType) e1).getType();
}
}
e2 = addQualifiersForAccess((ICPPField) binding, e2, e1);
if (!isPointerDereference() && owner.getValueCategory() == PRVALUE) {
e2= prvalueType(e2);
} else {
e2= glvalueType(e2);
}
}
return SemanticUtil.mapToAST(e2, this);
}
if (binding instanceof IEnumerator) {
return ((IEnumerator) binding).getType();
}
if (binding instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
}
if (binding instanceof ICPPUnknownBinding) {
// mstodo type of unknown.
return CPPUnknownClass.createUnnamedInstance();
}
if (binding instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
} catch (DOMException e) {
return e.getProblem();
}
}
public static IType addQualifiersForAccess(ICPPField field, IType fieldType, IType ownerType) {
CVQualifier cvq1 = SemanticUtil.getCVQualifier(ownerType);
CVQualifier cvq2 = SemanticUtil.getCVQualifier(fieldType);
if (field.isMutable()) {
// Remove const, add union of volatile.
if (cvq2.isConst()) {
fieldType= SemanticUtil.getNestedType(fieldType, ALLCVQ | TDEF | REF);
}
fieldType= SemanticUtil.addQualifiers(fieldType, false, cvq1.isVolatile() || cvq2.isVolatile(), cvq2.isRestrict());
} else {
fieldType= SemanticUtil.addQualifiers(fieldType, cvq1.isConst(), cvq1.isVolatile(), cvq2.isRestrict());
}
return fieldType;
}
@Override
public ValueCategory getValueCategory() {
IASTName name= getFieldName();
IBinding binding = name.resolvePreBinding();
if (binding instanceof IVariable) {
IType e2= ((IVariable) binding).getType();
e2= SemanticUtil.getNestedType(e2, TDEF);
if (e2 instanceof ICPPReferenceType) {
return LVALUE;
}
if (binding instanceof ICPPField && !((ICPPField) binding).isStatic()) {
if (isPointerDereference())
return LVALUE;
return owner.getValueCategory();
}
return LVALUE;
}
if (binding instanceof IFunction) {
return LVALUE;
}
return PRVALUE;
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override @Override
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces);
@ -347,56 +240,63 @@ public class CPPASTFieldReference extends ASTNode
*/ */
@Override @Override
public IType getFieldOwnerType() { public IType getFieldOwnerType() {
return getFieldOwnerType(null); return EvalMemberAccess.getFieldOwnerType(owner.getExpressionType(), isDeref, this, null, true);
} }
/* @Override
* Also collects the function bindings if requested. public ICPPEvaluation getEvaluation() {
*/ if (fEvaluation == null) {
private IType getFieldOwnerType(Collection<ICPPFunction> functionBindings) { fEvaluation= createEvaluation();
final IASTExpression owner = getFieldOwner(); }
if (owner == null) return fEvaluation;
return null; }
IType type= owner.getExpressionType(); private ICPPEvaluation createEvaluation() {
if (!isPointerDereference()) ICPPEvaluation ownerEval = owner.getEvaluation();
return type; if (!ownerEval.isTypeDependent()) {
IType ownerType= EvalMemberAccess.getFieldOwnerType(ownerEval.getTypeOrFunctionSet(this), isDeref, this, null, false);
// bug 205964: as long as the type is a class type, recurse. if (ownerType != null) {
// Be defensive and allow a max of 20 levels. IBinding binding = name.resolvePreBinding();
for (int j = 0; j < 20; j++) { if (binding instanceof CPPFunctionSet)
// for unknown types we cannot determine the overloaded -> operator binding= name.resolveBinding();
IType classType= getUltimateTypeUptoPointers(type);
if (classType instanceof ICPPUnknownType)
return CPPUnknownClass.createUnnamedInstance();
if (!(classType instanceof ICPPClassType)) if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor)
break; return EvalFixed.INCOMPLETE;
/*
* 13.5.6-1: An expression x->m is interpreted as (x.operator->())->m for a
* class object x of type T
*
* Construct an AST fragment for x.operator-> which the lookup routines can
* examine for type information.
*/
ICPPFunction op = CPPSemantics.findOverloadedOperator(this, type, (ICPPClassType) classType); return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, isDeref);
if (op == null) }
break;
if (functionBindings != null)
functionBindings.add(op);
type= typeFromFunctionCall(op);
type= SemanticUtil.mapToAST(type, owner);
}
IType prValue= prvalueTypeWithResolvedTypedefs(type);
if (prValue instanceof IPointerType) {
return glvalueType(((IPointerType) prValue).getType());
} }
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); IBinding qualifier= null;
} ICPPTemplateArgument[] args= null;
IASTName n= name;
if (n instanceof ICPPASTQualifiedName) {
IASTName[] ns= ((ICPPASTQualifiedName) n).getNames();
if (ns.length < 2)
return EvalFixed.INCOMPLETE;
qualifier= ns[ns.length-2].resolveBinding();
if (qualifier instanceof IProblemBinding)
return EvalFixed.INCOMPLETE;
n= ns[ns.length-1];
}
if (n instanceof ICPPASTTemplateId) {
args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n);
}
return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, qualifier != null, args);
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
} }

View file

@ -13,17 +13,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.COND_TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
@ -35,13 +25,9 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
@ -49,19 +35,19 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTFunctionCallExpression extends ASTNode public class CPPASTFunctionCallExpression extends ASTNode
implements ICPPASTFunctionCallExpression, IASTAmbiguityParent { implements ICPPASTFunctionCallExpression, IASTAmbiguityParent {
private IASTExpression functionName; private ICPPASTExpression functionName;
private IASTInitializerClause[] fArguments; private IASTInitializerClause[] fArguments;
private IASTImplicitName[] implicitNames; private IASTImplicitName[] implicitNames;
private ICPPFunction overload= UNINITIALIZED_FUNCTION; private ICPPEvaluation evaluation;
public CPPASTFunctionCallExpression() { public CPPASTFunctionCallExpression() {
setArguments(null); setArguments(null);
@ -71,11 +57,6 @@ public class CPPASTFunctionCallExpression extends ASTNode
setFunctionNameExpression(functionName); setFunctionNameExpression(functionName);
setArguments(args); setArguments(args);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTFunctionCallExpression copy() { public CPPASTFunctionCallExpression copy() {
@ -105,7 +86,7 @@ public class CPPASTFunctionCallExpression extends ASTNode
@Override @Override
public void setFunctionNameExpression(IASTExpression expression) { public void setFunctionNameExpression(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
this.functionName = expression; this.functionName = (ICPPASTExpression) expression;
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(FUNCTION_NAME); expression.setPropertyInParent(FUNCTION_NAME);
@ -134,11 +115,11 @@ public class CPPASTFunctionCallExpression extends ASTNode
@Override @Override
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (implicitNames == null) {
ICPPFunction overload = getOperator(); ICPPFunction overload = getOverload();
if (overload == null) if (overload == null)
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
if (isExplicitTypeConversion() != null) { if (getEvaluation() instanceof EvalTypeId) {
CPPASTImplicitName n1 = new CPPASTImplicitName(overload.getNameCharArray(), this); CPPASTImplicitName n1 = new CPPASTImplicitName(overload.getNameCharArray(), this);
n1.setOffsetAndLength((ASTNode) functionName); n1.setOffsetAndLength((ASTNode) functionName);
n1.setBinding(overload); n1.setBinding(overload);
@ -227,7 +208,7 @@ public class CPPASTFunctionCallExpression extends ASTNode
if (child == functionName) { if (child == functionName) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
functionName = (IASTExpression) other; functionName = (ICPPASTExpression) other;
} }
for (int i = 0; i < fArguments.length; ++i) { for (int i = 0; i < fArguments.length; ++i) {
if (child == fArguments[i]) { if (child == fArguments[i]) {
@ -238,113 +219,8 @@ public class CPPASTFunctionCallExpression extends ASTNode
} }
} }
public ICPPFunction getOperator() {
if (overload == UNINITIALIZED_FUNCTION) {
overload= null;
IType t= isExplicitTypeConversion();
if (t != null) {
t = getNestedType(t, TDEF | CVTYPE | REF);
if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownBinding)) {
ICPPClassType cls= (ICPPClassType) t;
LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) functionName).getName());
try {
IBinding b= CPPSemantics.resolveFunction(data, cls.getConstructors(), true);
if (b instanceof ICPPFunction)
overload= (ICPPFunction) b;
} catch (DOMException e) {
}
}
} else {
t= SemanticUtil.getNestedType(functionName.getExpressionType(), TDEF | REF | CVTYPE);
if (t instanceof ICPPClassType) {
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType) t);
}
}
}
return overload;
}
@Override
public IType getExpressionType() {
// Handle explicit type conversion in functional notation.
IType type= isExplicitTypeConversion();
if (type != null) {
if (type instanceof IProblemBinding) {
return ProblemType.UNRESOLVED_NAME;
}
return prvalueType(type);
}
type= SemanticUtil.getNestedType(functionName.getExpressionType(), COND_TDEF | REF | CVTYPE);
IType t = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
if (t instanceof ICPPClassType) {
if (overload == UNINITIALIZED_FUNCTION) {
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType) t);
}
if (overload != null) {
return typeFromFunctionCall(overload);
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
if (t instanceof IPointerType) {
t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE);
}
if (t instanceof IFunctionType) {
type = typeFromReturnType(((IFunctionType) t).getReturnType());
if (functionName instanceof ICPPASTFieldReference) {
IType ownerType = ((ICPPASTFieldReference) functionName).getFieldOwnerType();
t = SemanticUtil.substituteTypedef(type, ownerType);
if (t != null)
type = t;
}
return type;
}
if (CPPTemplates.isDependentType(type))
return CPPUnknownClass.createUnnamedInstance();
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
private IType isExplicitTypeConversion() {
if (functionName instanceof IASTIdExpression) {
final IASTName name = ((IASTIdExpression) functionName).getName();
IBinding b= name.resolvePreBinding();
if (b instanceof IType)
return (IType) b;
}
return null;
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override
public ValueCategory getValueCategory() {
if (isExplicitTypeConversion() != null)
return PRVALUE;
IType t= functionName.getExpressionType();
if (t instanceof ICPPClassType) {
if (overload == UNINITIALIZED_FUNCTION) {
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType) t);
}
if (overload != null) {
return valueCategoryFromFunctionCall(overload);
}
} else {
if (t instanceof IPointerType) {
t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE);
}
if (t instanceof IFunctionType) {
return valueCategoryFromReturnType(((IFunctionType) t).getReturnType());
}
}
return ValueCategory.PRVALUE;
}
@Override @Override
@Deprecated @Deprecated
public IASTExpression getParameterExpression() { public IASTExpression getParameterExpression() {
@ -380,4 +256,82 @@ public class CPPASTFunctionCallExpression extends ASTNode
setArguments(new IASTExpression[] {expression}); setArguments(new IASTExpression[] {expression});
} }
} }
public ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalFunctionCall)
return ((EvalFunctionCall) eval).getOverload(this);
if (eval instanceof EvalTypeId) {
if (!eval.isTypeDependent()) {
IType t= getNestedType(((EvalTypeId) eval).getInputType(), TDEF|CVTYPE|REF);
if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownBinding)) {
ICPPClassType cls= (ICPPClassType) t;
LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) functionName).getName());
try {
IBinding b= CPPSemantics.resolveFunction(data, cls.getConstructors(), true);
if (b instanceof ICPPFunction)
return (ICPPFunction) b;
} catch (DOMException e) {
}
}
}
}
return null;
}
@Override
public ICPPEvaluation getEvaluation() {
if (evaluation == null)
evaluation= computeEvaluation();
return evaluation;
}
private ICPPEvaluation computeEvaluation() {
if (functionName == null || fArguments == null)
return EvalFixed.INCOMPLETE;
ICPPEvaluation conversion= checkForExplicitTypeConversion();
if (conversion != null)
return conversion;
ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length+1];
args[0]= functionName.getEvaluation();
for (int i = 1; i < args.length; i++) {
args[i]= ((ICPPASTExpression) fArguments[i-1]).getEvaluation();
}
return new EvalFunctionCall(args);
}
private ICPPEvaluation checkForExplicitTypeConversion() {
if (functionName instanceof IASTIdExpression) {
final IASTName name = ((IASTIdExpression) functionName).getName();
IBinding b= name.resolvePreBinding();
if (b instanceof IType) {
ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length];
for (int i = 1; i < args.length; i++) {
args[i]= ((ICPPASTExpression) fArguments[i]).getEvaluation();
}
return new EvalTypeId((IType) b, args);
}
}
return null;
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
} }

View file

@ -13,56 +13,28 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
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.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext { public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext {
private static final ICPPASTFieldReference NOT_INITIALIZED = new CPPASTFieldReference();
private IASTName name; private IASTName name;
private ICPPASTFieldReference fTransformedExpression= NOT_INITIALIZED; private ICPPEvaluation fEvaluation;
public CPPASTIdExpression() { public CPPASTIdExpression() {
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTIdExpression(IASTName name) { public CPPASTIdExpression(IASTName name) {
setName(name); setName(name);
@ -126,120 +98,6 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP
return r_unclear; return r_unclear;
} }
@Override
public IType getExpressionType() {
IBinding binding = name.resolvePreBinding();
if (binding instanceof CPPFunctionSet)
binding= name.resolveBinding();
if (checkForTransformation(binding)) {
return fTransformedExpression.getExpressionType();
}
try {
if (binding instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
}
if (binding instanceof IType || binding instanceof ICPPConstructor) {
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
if (binding instanceof IEnumerator) {
IType type= ((IEnumerator) binding).getType();
if (type instanceof ICPPEnumeration) {
ICPPEnumeration enumType= (ICPPEnumeration) type;
if (enumType.asScope() == CPPVisitor.getContainingScope(this)) {
// C++0x: 7.2-5
IType fixedType= enumType.getFixedType();
if (fixedType != null)
return fixedType;
// This is a simplification, the actual type is determined
// - in an implementation dependent manner - by the value
// of the enumerator.
return CPPSemantics.INT_TYPE;
}
}
return type;
}
if (binding instanceof IVariable) {
final IType t = glvalueType(((IVariable) binding).getType());
return SemanticUtil.mapToAST(t, this);
}
if (binding instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
}
if (binding instanceof ICPPTemplateNonTypeParameter) {
return prvalueType(((ICPPTemplateNonTypeParameter) binding).getType());
}
if (binding instanceof ICPPUnknownBinding) {
// mstodo typeof unknown binding
return CPPUnknownClass.createUnnamedInstance();
}
} catch (DOMException e) {
return e.getProblem();
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
/**
* 9.3.1-3 Transformation to class member access within the definition of a non-static
* member function.
*/
public boolean checkForTransformation(IBinding binding) {
if (fTransformedExpression == NOT_INITIALIZED) {
fTransformedExpression= null;
if (name instanceof ICPPASTQualifiedName) {
IASTNode parent= name.getParent();
if (parent instanceof ICPPASTUnaryExpression) {
if (((ICPPASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_amper) {
return false;
}
}
}
if (binding instanceof ICPPMember && !(binding instanceof IType) && !(binding instanceof ICPPConstructor)
&&!((ICPPMember) binding).isStatic()) {
IASTNode parent= getParent();
while (parent != null && !(parent instanceof ICPPASTFunctionDefinition)) {
parent= parent.getParent();
}
if (parent instanceof ICPPASTFunctionDefinition) {
ICPPASTFunctionDefinition fdef= (ICPPASTFunctionDefinition) parent;
final IBinding methodBinding = fdef.getDeclarator().getName().resolvePreBinding();
if (methodBinding instanceof ICPPMethod && !((ICPPMethod) methodBinding).isStatic()) {
IASTName nameDummy= new CPPASTName();
nameDummy.setBinding(binding);
IASTExpression owner= new CPPASTLiteralExpression(IASTLiteralExpression.lk_this,
CharArrayUtils.EMPTY);
owner= new CPPASTUnaryExpression(IASTUnaryExpression.op_star, owner);
fTransformedExpression= new CPPASTFieldReference(nameDummy, owner);
fTransformedExpression.setParent(getParent());
fTransformedExpression.setPropertyInParent(getPropertyInParent());
}
}
}
}
return fTransformedExpression != null;
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override
public ValueCategory getValueCategory() {
IBinding binding = name.resolvePreBinding();
if (checkForTransformation(binding)) {
return fTransformedExpression.getValueCategory();
}
if (binding instanceof ICPPTemplateNonTypeParameter)
return ValueCategory.PRVALUE;
if (binding instanceof IVariable || binding instanceof IFunction) {
return ValueCategory.LVALUE;
}
return ValueCategory.PRVALUE;
}
@Override @Override
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {
return CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); return CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces);
@ -254,4 +112,35 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP
public IBinding[] findBindings(IASTName n, boolean isPrefix) { public IBinding[] findBindings(IASTName n, boolean isPrefix) {
return findBindings(n, isPrefix, null); return findBindings(n, isPrefix, null);
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= EvalID.create(this);
}
return fEvaluation;
}
@Override
public IType getExpressionType() {
IType type= getEvaluation().getTypeOrFunctionSet(this);
if (type instanceof FunctionSetType) {
IBinding binding= name.resolveBinding();
if (binding instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this);
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
}
return type;
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
} }

View file

@ -17,29 +17,28 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
/** /**
* e.g.: int a[]= {1,2,3}; * e.g.: int a[]= {1,2,3};
*/ */
public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializerList, IASTAmbiguityParent { public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializerList, IASTAmbiguityParent {
private IASTInitializerClause [] initializers; private static final ICPPASTInitializerClause[] NO_CLAUSES = {};
private ICPPASTInitializerClause [] initializers;
private int initializersPos= -1; private int initializersPos= -1;
private int actualSize; private int actualSize;
private boolean fIsPackExpansion; private boolean fIsPackExpansion;
private ICPPEvaluation fEvaluation;
@Override @Override
public CPPASTInitializerList copy() { public CPPASTInitializerList copy() {
return copy(CopyStyle.withoutLocations); return copy(CopyStyle.withoutLocations);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTInitializerList copy(CopyStyle style) { public CPPASTInitializerList copy(CopyStyle style) {
@ -62,10 +61,10 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer
} }
@Override @Override
public IASTInitializerClause[] getClauses() { public ICPPASTInitializerClause[] getClauses() {
if (initializers == null) if (initializers == null)
return IASTExpression.EMPTY_EXPRESSION_ARRAY; return NO_CLAUSES;
initializers = ArrayUtil.trimAt(IASTInitializerClause.class, initializers, initializersPos); initializers = ArrayUtil.trimAt(ICPPASTInitializerClause.class, initializers, initializersPos);
return initializers; return initializers;
} }
@ -95,7 +94,7 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer
public void addClause(IASTInitializerClause d) { public void addClause(IASTInitializerClause d) {
assertNotFrozen(); assertNotFrozen();
if (d != null) { if (d != null) {
initializers = ArrayUtil.appendAt( IASTInitializerClause.class, initializers, ++initializersPos, d ); initializers = ArrayUtil.appendAt(ICPPASTInitializerClause.class, initializers, ++initializersPos, (ICPPASTInitializerClause) d);
d.setParent(this); d.setParent(this);
d.setPropertyInParent(NESTED_INITIALIZER); d.setPropertyInParent(NESTED_INITIALIZER);
} }
@ -154,9 +153,25 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer
if (child == initializers[i]) { if (child == initializers[i]) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
initializers[i] = (IASTInitializerClause) other; initializers[i] = (ICPPASTInitializerClause) other;
} }
} }
} }
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null)
fEvaluation= createEvaluation();
return fEvaluation;
}
private ICPPEvaluation createEvaluation() {
final ICPPASTInitializerClause[] clauses = getClauses();
ICPPEvaluation[] evals= new ICPPEvaluation[clauses.length];
for (int i = 0; i < evals.length; i++) {
evals[i]= clauses[i].getEvaluation();
}
return new EvalInitList(evals);
}
} }

View file

@ -10,6 +10,8 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
@ -19,6 +21,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
/** /**
* Implementation for lambda expressions. * Implementation for lambda expressions.
@ -32,18 +36,14 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
private IASTCompoundStatement fBody; private IASTCompoundStatement fBody;
private CPPClosureType fClosureType;
private IASTImplicitName fClosureTypeName; private IASTImplicitName fClosureTypeName;
private IASTImplicitName fImplicitFunctionCallName; private IASTImplicitName fImplicitFunctionCallName;
private ICPPEvaluation fEvaluation;
public CPPASTLambdaExpression() { public CPPASTLambdaExpression() {
fCaptureDefault= CaptureDefault.UNSPECIFIED; fCaptureDefault= CaptureDefault.UNSPECIFIED;
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTExpression#copy() * @see org.eclipse.cdt.core.dom.ast.IASTExpression#copy()
@ -205,12 +205,17 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
fDeclarator= dtor; fDeclarator= dtor;
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= new EvalFixed(new CPPClosureType(this), PRVALUE, Value.UNKNOWN);
}
return fEvaluation;
}
@Override @Override
public CPPClosureType getExpressionType() { public CPPClosureType getExpressionType() {
if (fClosureType == null) return (CPPClosureType) getEvaluation().getTypeOrFunctionSet(this);
fClosureType= new CPPClosureType(this);
return fClosureType;
} }
@Override @Override

View file

@ -11,38 +11,41 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
/** /**
* Represents a C++ literal. * Represents a C++ literal.
*/ */
public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralExpression { public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralExpression {
private static final EvalFixed EVAL_TRUE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, Value.create(1));
private static final EvalFixed EVAL_FALSE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, Value.create(0));
private static final EvalFixed EVAL_NULL_PTR = new EvalFixed(CPPBasicType.NULL_PTR, PRVALUE, Value.create(0));
public static final CPPASTLiteralExpression INT_ZERO = public static final CPPASTLiteralExpression INT_ZERO =
new CPPASTLiteralExpression(lk_integer_constant, new char[] {'0'}); new CPPASTLiteralExpression(lk_integer_constant, new char[] {'0'});
private int kind; private int kind;
private char[] value = CharArrayUtils.EMPTY; private char[] value = CharArrayUtils.EMPTY;
private ICPPEvaluation fEvaluation;
public CPPASTLiteralExpression() { public CPPASTLiteralExpression() {
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTLiteralExpression(int kind, char[] value) { public CPPASTLiteralExpression(int kind, char[] value) {
this.kind = kind; this.kind = kind;
@ -111,46 +114,6 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
return true; return true;
} }
@Override
public IType getExpressionType() {
switch (getKind()) {
case lk_this: {
IScope scope = CPPVisitor.getContainingScope(this);
IType type= CPPVisitor.getImpliedObjectType(scope);
if (type == null) {
return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
}
return new CPPPointerType(type);
}
case lk_true:
case lk_false:
return CPPBasicType.BOOLEAN;
case lk_char_constant:
return new CPPBasicType(getCharType(), 0, this);
case lk_float_constant:
return classifyTypeOfFloatLiteral();
case lk_integer_constant:
return classifyTypeOfIntLiteral();
case lk_string_literal:
IType type = new CPPBasicType(getCharType(), 0, this);
type = new CPPQualifierType(type, true, false);
return new CPPArrayType(type, getStringLiteralSize());
case lk_nullptr:
return CPPBasicType.NULL_PTR;
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
@Override
public boolean isLValue() {
return getKind() == IASTLiteralExpression.lk_string_literal;
}
@Override
public ValueCategory getValueCategory() {
return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE;
}
private IValue getStringLiteralSize() { private IValue getStringLiteralSize() {
char[] value= getValue(); char[] value= getValue();
int length= value.length-1; int length= value.length-1;
@ -261,4 +224,74 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
public CPPASTLiteralExpression(int kind, String value) { public CPPASTLiteralExpression(int kind, String value) {
this(kind, value.toCharArray()); this(kind, value.toCharArray());
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null)
fEvaluation= createEvaluation();
return fEvaluation;
}
private ICPPEvaluation createEvaluation() {
switch (kind) {
case lk_this: {
IScope scope = CPPVisitor.getContainingScope(this);
IType type= CPPVisitor.getImpliedObjectType(scope);
if (type == null)
return EvalFixed.INCOMPLETE;
return new EvalFixed(new CPPPointerType(type), PRVALUE, Value.UNKNOWN);
}
case lk_true:
return EVAL_TRUE;
case lk_false:
return EVAL_FALSE;
case lk_char_constant:
return new EvalFixed(new CPPBasicType(getCharType(), 0, this), PRVALUE, createCharValue());
case lk_float_constant:
return new EvalFixed(classifyTypeOfFloatLiteral(), PRVALUE, Value.UNKNOWN);
case lk_integer_constant:
return new EvalFixed(classifyTypeOfIntLiteral(),PRVALUE, createIntValue());
case lk_string_literal:
IType type = new CPPBasicType(getCharType(), 0, this);
type = new CPPQualifierType(type, true, false);
return new EvalFixed(new CPPArrayType(type, getStringLiteralSize()), LVALUE, Value.UNKNOWN);
case lk_nullptr:
return EVAL_NULL_PTR;
}
return EvalFixed.INCOMPLETE;
}
private IValue createCharValue() {
try {
final char[] image= getValue();
if (image.length > 1 && image[0] == 'L')
return Value.create(ExpressionEvaluator.getChar(image, 2));
return Value.create(ExpressionEvaluator.getChar(image, 1));
} catch (EvalException e1) {
return Value.UNKNOWN;
}
}
private IValue createIntValue() {
try {
return Value.create(ExpressionEvaluator.getNumber(getValue()));
} catch (EvalException e1) {
return Value.UNKNOWN;
}
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
@Override
public ValueCategory getValueCategory() {
return getKind() == lk_string_literal ? LVALUE : PRVALUE;
}
} }

View file

@ -34,9 +34,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList; import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Assert;
@ -49,6 +51,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
private boolean isNewTypeId; private boolean isNewTypeId;
private IASTExpression[] cachedArraySizes; private IASTExpression[] cachedArraySizes;
private ICPPEvaluation fEvaluation;
public CPPASTNewExpression() { public CPPASTNewExpression() {
} }
@ -58,11 +61,6 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
setTypeId(typeId); setTypeId(typeId);
setInitializer(initializer); setInitializer(initializer);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTNewExpression copy() { public CPPASTNewExpression copy() {
@ -248,13 +246,21 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
} }
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
IType t= CPPVisitor.createType(getTypeId());
if (t instanceof IArrayType) {
t= ((IArrayType) t).getType();
}
fEvaluation= new EvalFixed(new CPPPointerType(t), PRVALUE, Value.UNKNOWN);
}
return fEvaluation;
}
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
IType t= CPPVisitor.createType(getTypeId()); return getEvaluation().getTypeOrFunctionSet(this);
if (t instanceof IArrayType) {
t= ((IArrayType) t).getType();
}
return new CPPPointerType(t);
} }
@Override @Override

View file

@ -10,22 +10,25 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
/** /**
* Implementation of pack expansion expression. * Implementation of pack expansion expression.
*/ */
public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPackExpansionExpression, IASTAmbiguityParent { public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPackExpansionExpression, IASTAmbiguityParent {
private IASTExpression fPattern; private IASTExpression fPattern;
private ICPPEvaluation fEvaluation;
public CPPASTPackExpansionExpression(IASTExpression pattern) { public CPPASTPackExpansionExpression(IASTExpression pattern) {
setPattern(pattern); setPattern(pattern);
@ -41,11 +44,6 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
pattern.setPropertyInParent(ICPPASTPackExpansionExpression.PATTERN); pattern.setPropertyInParent(ICPPASTPackExpansionExpression.PATTERN);
} }
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public IASTExpression getPattern() { public IASTExpression getPattern() {
@ -67,13 +65,23 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
return copy; return copy;
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
IType type = fPattern.getExpressionType();
if (type == null) {
type= ProblemType.UNKNOWN_FOR_EXPRESSION;
} else {
type= new CPPParameterPackType(type);
}
fEvaluation= new EvalFixed(type, PRVALUE, Value.UNKNOWN);
}
return fEvaluation;
}
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
final IType type = fPattern.getExpressionType(); return getEvaluation().getTypeOrFunctionSet(this);
if (type == null)
return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, getRawSignatureChars());
return new CPPParameterPackType(type);
} }
@Override @Override

View file

@ -11,13 +11,14 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression; import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression, ICPPASTExpression { public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression, ICPPASTExpression {
@ -33,12 +34,6 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
public CPPASTProblemExpression copy() { public CPPASTProblemExpression copy() {
return copy(CopyStyle.withoutLocations); return copy(CopyStyle.withoutLocations);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTProblemExpression copy(CopyStyle style) { public CPPASTProblemExpression copy(CopyStyle style) {
CPPASTProblemExpression copy = new CPPASTProblemExpression(); CPPASTProblemExpression copy = new CPPASTProblemExpression();
@ -64,19 +59,24 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
} }
return true; return true;
} }
@Override
public ICPPEvaluation getEvaluation() {
return EvalFixed.INCOMPLETE;
}
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); return getEvaluation().getTypeOrFunctionSet(this);
} }
@Override @Override
public boolean isLValue() { public boolean isLValue() {
return false; return getValueCategory() == LVALUE;
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return ValueCategory.PRVALUE; return getEvaluation().getValueCategory(this);
} }
} }

View file

@ -125,7 +125,7 @@ public class CPPASTRangeBasedForStatement extends ASTAttributeOwner
fImplicitNames= IASTImplicitName.EMPTY_NAME_ARRAY; fImplicitNames= IASTImplicitName.EMPTY_NAME_ARRAY;
} else if (type instanceof ICPPClassType) { } else if (type instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) type; ICPPClassType ct= (ICPPClassType) type;
if (CPPSemantics.findBindings(ct.getCompositeScope(), CPPVisitor.BEGIN_STR, true).length > 0) { if (CPPSemantics.findBindings(ct.getCompositeScope(), CPPVisitor.BEGIN, true, this).length > 0) {
CPPASTName name = new CPPASTName(CPPVisitor.BEGIN); CPPASTName name = new CPPASTName(CPPVisitor.BEGIN);
name.setOffset(position.getOffset()); name.setOffset(position.getOffset());
CPPASTFieldReference fieldRef = new CPPASTFieldReference(name, forInitExpr.copy()); CPPASTFieldReference fieldRef = new CPPASTFieldReference(name, forInitExpr.copy());

View file

@ -11,26 +11,28 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
ICPPASTSimpleTypeConstructorExpression { ICPPASTSimpleTypeConstructorExpression {
private ICPPASTDeclSpecifier fDeclSpec; private ICPPASTDeclSpecifier fDeclSpec;
private IASTInitializer fInitializer; private IASTInitializer fInitializer;
private IType fType; private ICPPEvaluation fEvaluation;
public CPPASTSimpleTypeConstructorExpression() { public CPPASTSimpleTypeConstructorExpression() {
} }
@ -39,11 +41,6 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
setDeclSpecifier(declSpec); setDeclSpecifier(declSpec);
setInitializer(init); setInitializer(init);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTSimpleTypeConstructorExpression copy() { public CPPASTSimpleTypeConstructorExpression copy() {
@ -91,13 +88,36 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
initializer.setPropertyInParent(INITIALIZER); initializer.setPropertyInParent(INITIALIZER);
} }
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
final IType type = CPPVisitor.createType(fDeclSpec);
ICPPEvaluation[] args= null;
if (fInitializer instanceof ICPPASTConstructorInitializer) {
IASTInitializerClause[] a = ((ICPPASTConstructorInitializer) fInitializer).getArguments();
args= new ICPPEvaluation[a.length];
for (int i = 0; i < a.length; i++) {
args[i]= ((ICPPASTInitializerClause) a[i]).getEvaluation();
}
fEvaluation= new EvalTypeId(type, args);
} else if (fInitializer instanceof ICPPASTInitializerList) {
fEvaluation= new EvalTypeId(type, ((ICPPASTInitializerList) fInitializer).getEvaluation());
} else {
fEvaluation= EvalFixed.INCOMPLETE;
}
}
return fEvaluation;
}
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
if (fType == null) { return getEvaluation().getTypeOrFunctionSet(this);
fType= prvalueType(CPPVisitor.createType(fDeclSpec)); }
}
return fType; @Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
} }
@Override @Override
@ -105,11 +125,6 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
return false; return false;
} }
@Override
public ValueCategory getValueCategory() {
return PRVALUE;
}
@Override @Override
public boolean accept(ASTVisitor action) { public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) { if (action.shouldVisitExpressions) {

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
@ -40,13 +41,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.NameOrTemplateIDVariants.Var
/** /**
* Models expression variants for the ambiguity of a template id. * Models expression variants for the ambiguity of a template id.
*/ */
public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTAmbiguousExpression { public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTAmbiguousExpression,
ICPPASTExpression {
private BinaryOperator fLastOperator; private BinaryOperator fLastOperator;
private IASTInitializerClause fLastExpression; private IASTInitializerClause fLastExpression;
private final BranchPoint fVariants; private final BranchPoint fVariants;
private IASTNode[] fNodes; private IASTNode[] fNodes;
private AbstractGNUSourceCodeParser fParser; private final AbstractGNUSourceCodeParser fParser;
public CPPASTTemplateIDAmbiguity(AbstractGNUSourceCodeParser parser, BinaryOperator lastOperator, IASTInitializerClause expr, public CPPASTTemplateIDAmbiguity(AbstractGNUSourceCodeParser parser, BinaryOperator lastOperator, IASTInitializerClause expr,
BranchPoint variants) { BranchPoint variants) {

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
@ -175,8 +176,8 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
} }
// bug 262719: class types from the index have to be mapped back to the AST. // bug 262719: class types from the index have to be mapped back to the AST.
public ICPPClassType mapToAST(ICPPClassType binding) { public ICPPClassType mapToAST(ICPPClassType binding, IASTNode point) {
return fScopeMapper.mapToAST(binding); return fScopeMapper.mapToAST(binding, point);
} }
/** /**

View file

@ -12,18 +12,21 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID;
public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpression { public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpression {
private int op; private int op;
private IASTTypeId typeId; private IASTTypeId typeId;
private ICPPEvaluation fEvaluation;
public CPPASTTypeIdExpression() { public CPPASTTypeIdExpression() {
} }
@ -32,11 +35,6 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
this.op = op; this.op = op;
setTypeId(typeId); setTypeId(typeId);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public CPPASTTypeIdExpression copy() { public CPPASTTypeIdExpression copy() {
@ -103,43 +101,30 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
} }
@Override @Override
public IType getExpressionType() { public ICPPEvaluation getEvaluation() {
switch (getOperator()) { if (fEvaluation == null) {
case op_sizeof: IType type= CPPVisitor.createType(typeId);
case op_alignof: if (type == null || type instanceof IProblemType) {
return CPPVisitor.get_SIZE_T(this); fEvaluation= EvalFixed.INCOMPLETE;
case op_typeid: } else {
return CPPVisitor.get_type_info(this); fEvaluation= new EvalUnaryTypeID(op, type);
case op_has_nothrow_copy: }
case op_has_nothrow_constructor:
case op_has_trivial_assign:
case op_has_trivial_constructor:
case op_has_trivial_copy:
case op_has_trivial_destructor:
case op_has_virtual_destructor:
case op_is_abstract:
case op_is_class:
case op_is_empty:
case op_is_enum:
case op_is_pod:
case op_is_polymorphic:
case op_is_union:
return CPPBasicType.BOOLEAN;
} }
return CPPVisitor.createType(getTypeId()); return fEvaluation;
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
} }
@Override @Override
public boolean isLValue() { public boolean isLValue() {
switch (getOperator()) { return getValueCategory() == LVALUE;
case op_typeid:
return true;
}
return false;
}
@Override
public ValueCategory getValueCategory() {
return isLValue() ? LVALUE : PRVALUE;
} }
} }

View file

@ -10,32 +10,31 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.internal.core.dom.parser.ASTTypeIdInitializerExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTTypeIdInitializerExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
/** /**
* C++ variant of type id initializer expression. type-id { initializer } * C++ variant of type id initializer expression. type-id { initializer }
*/ */
public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpression implements ICPPASTExpression { public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpression implements ICPPASTExpression {
private ICPPEvaluation fEvaluation;
private CPPASTTypeIdInitializerExpression() { private CPPASTTypeIdInitializerExpression() {
} }
public CPPASTTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) { public CPPASTTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) {
super(typeId, initializer); super(typeId, initializer);
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override @Override
public IASTTypeIdInitializerExpression copy() { public IASTTypeIdInitializerExpression copy() {
@ -50,8 +49,32 @@ public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpre
} }
@Override @Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null)
fEvaluation= computeEvaluation();
return fEvaluation;
}
private ICPPEvaluation computeEvaluation() {
final IASTInitializer initializer = getInitializer();
if (!(initializer instanceof ICPPASTInitializerClause))
return EvalFixed.INCOMPLETE;
IType type= CPPVisitor.createType(getTypeId());
if (type == null || type instanceof IProblemType)
return EvalFixed.INCOMPLETE;
return new EvalTypeId(type, ((ICPPASTInitializerClause) initializer).getEvaluation());
}
@Override
public IType getExpressionType() { public IType getExpressionType() {
final IASTTypeId typeId = getTypeId(); return getEvaluation().getTypeOrFunctionSet(this);
return prvalueType(CPPVisitor.createType(typeId.getAbstractDeclarator())); }
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
} }
} }

View file

@ -15,12 +15,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueTypeWithResolvedTypedefs;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
@ -32,42 +26,37 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType;
/** /**
* Unary expression in c++ * Unary expression in c++
*/ */
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent { public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
private int op; private int fOperator;
private IASTExpression operand; private ICPPASTExpression fOperand;
private IASTImplicitName[] fImplicitNames = null;
private ICPPFunction overload = UNINITIALIZED_FUNCTION; private ICPPEvaluation fEvaluation;
private IASTImplicitName[] implicitNames = null;
public CPPASTUnaryExpression() { public CPPASTUnaryExpression() {
} }
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTUnaryExpression(int operator, IASTExpression operand) { public CPPASTUnaryExpression(int operator, IASTExpression operand) {
op = operator; fOperator = operator;
setOperand(operand); setOperand(operand);
} }
@ -78,31 +67,35 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
@Override @Override
public CPPASTUnaryExpression copy(CopyStyle style) { public CPPASTUnaryExpression copy(CopyStyle style) {
CPPASTUnaryExpression copy = CPPASTUnaryExpression copy = new CPPASTUnaryExpression(fOperator, fOperand == null ? null
new CPPASTUnaryExpression(op, operand == null ? null : operand.copy(style)); : fOperand.copy(style));
return copy(copy, style); copy.setOffsetAndLength(this);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
} }
@Override @Override
public int getOperator() { public int getOperator() {
return op; return fOperator;
} }
@Override @Override
public void setOperator(int operator) { public void setOperator(int operator) {
assertNotFrozen(); assertNotFrozen();
op = operator; fOperator = operator;
} }
@Override @Override
public IASTExpression getOperand() { public IASTExpression getOperand() {
return operand; return fOperand;
} }
@Override @Override
public void setOperand(IASTExpression expression) { public void setOperand(IASTExpression expression) {
assertNotFrozen(); assertNotFrozen();
operand = expression; fOperand = (ICPPASTExpression) expression;
if (expression != null) { if (expression != null) {
expression.setParent(this); expression.setParent(this);
expression.setPropertyInParent(OPERAND); expression.setPropertyInParent(OPERAND);
@ -110,7 +103,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
} }
public boolean isPostfixOperator() { public boolean isPostfixOperator() {
return op == op_postFixDecr || op == op_postFixIncr; return fOperator == op_postFixDecr || fOperator == op_postFixIncr;
} }
/** /**
@ -118,20 +111,20 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
*/ */
@Override @Override
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (fImplicitNames == null) {
ICPPFunction overload = getOverload(); ICPPFunction overload = getOverload();
if (overload == null || overload instanceof CPPImplicitFunction) { if (overload == null || overload instanceof CPPImplicitFunction) {
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
} else { } else {
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this); CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);
operatorName.setOperator(true); operatorName.setOperator(true);
operatorName.setBinding(overload); operatorName.setBinding(overload);
operatorName.computeOperatorOffsets(operand, isPostfixOperator()); operatorName.computeOperatorOffsets(fOperand, isPostfixOperator());
implicitNames = new IASTImplicitName[] { operatorName }; fImplicitNames = new IASTImplicitName[] { operatorName };
} }
} }
return implicitNames; return fImplicitNames;
} }
@Override @Override
@ -153,7 +146,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
} }
} }
if (operand != null && !operand.accept(action)) if (fOperand != null && !fOperand.accept(action))
return false; return false;
if (isPostfix && action.shouldVisitImplicitNames) { if (isPostfix && action.shouldVisitImplicitNames) {
@ -175,27 +168,18 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
@Override @Override
public void replace(IASTNode child, IASTNode other) { public void replace(IASTNode child, IASTNode other) {
if (child == operand) { if (child == fOperand) {
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent()); other.setParent(child.getParent());
operand = (IASTExpression) other; fOperand = (ICPPASTExpression) other;
} }
} }
@Override
public ICPPFunction getOverload() {
if (overload != UNINITIALIZED_FUNCTION)
return overload;
overload = CPPSemantics.findOverloadedOperator(this);
if (overload != null && op == op_amper && computePointerToMemberType() instanceof CPPPointerToMemberType)
overload = null;
return overload;
}
private IType computePointerToMemberType() { private IType computePointerToMemberType() {
IASTNode child= operand; if (fOperator != op_amper)
return null;
IASTNode child= fOperand;
boolean inParenthesis= false; boolean inParenthesis= false;
while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) { while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
child= ((IASTUnaryExpression) child).getOperand(); child= ((IASTUnaryExpression) child).getOperand();
@ -203,22 +187,21 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
} }
if (child instanceof IASTIdExpression) { if (child instanceof IASTIdExpression) {
IASTName name= ((IASTIdExpression) child).getName(); IASTName name= ((IASTIdExpression) child).getName();
IBinding b= name.resolveBinding(); if (name instanceof ICPPASTQualifiedName) {
if (b instanceof ICPPMember) { IBinding b= name.resolveBinding();
ICPPMember member= (ICPPMember) b; if (b instanceof ICPPMember) {
try { ICPPMember member= (ICPPMember) b;
if (name instanceof ICPPASTQualifiedName) { if (!member.isStatic()) {
if (!member.isStatic()) { // so if the member is static it will fall through try {
overload= null;
if (!inParenthesis) { if (!inParenthesis) {
return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false, false); return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false, false);
} else if (member instanceof IFunction) { } else if (member instanceof IFunction) {
return new ProblemBinding(operand, IProblemBinding.SEMANTIC_INVALID_TYPE, operand.getRawSignature().toCharArray()); return new ProblemBinding(fOperand, IProblemBinding.SEMANTIC_INVALID_TYPE, fOperand.getRawSignature().toCharArray());
} }
} catch (DOMException e) {
return e.getProblem();
} }
} }
} catch (DOMException e) {
return e.getProblem();
} }
} }
} }
@ -226,113 +209,71 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
} }
@Override @Override
public IType getExpressionType() { public ICPPFunction getOverload() {
final int op= getOperator(); ICPPEvaluation eval = getEvaluation();
switch (op) { if (eval instanceof EvalUnary)
case op_sizeof: return ((EvalUnary) eval).getOverload(this);
case op_sizeofParameterPack: return null;
return CPPVisitor.get_SIZE_T(this);
case op_typeid:
return CPPVisitor.get_type_info(this);
case op_bracketedPrimary:
return getOperand().getExpressionType();
case op_throw:
return CPPSemantics.VOID_TYPE;
}
final IASTExpression operand = getOperand();
if (op == op_amper) { // check for pointer to member
IType ptm = computePointerToMemberType();
if (ptm != null)
return ptm;
ICPPFunction overload = getOverload();
if (overload != null)
return typeFromFunctionCall(overload);
return new CPPPointerType(operand.getExpressionType());
}
ICPPFunction overload = getOverload();
if (overload != null)
return typeFromFunctionCall(overload);
if (op == op_star) {
IType type= operand.getExpressionType();
type = prvalueTypeWithResolvedTypedefs(type);
if (type instanceof IPointerType) {
type= ((ITypeContainer) type).getType();
return glvalueType(type);
}
if (type instanceof ISemanticProblem) {
return type;
}
type= getUltimateTypeUptoPointers(type);
if (type instanceof ICPPUnknownType) {
// mstodo Type of unknown
return CPPUnknownClass.createUnnamedInstance();
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
IType typeOfOperand= operand.getExpressionType();
switch (op) {
case op_not:
return CPPBasicType.BOOLEAN;
case op_postFixDecr:
case op_postFixIncr:
typeOfOperand= prvalueType(typeOfOperand);
break;
case op_minus:
case op_plus:
case op_tilde:
IType t= CPPArithmeticConversion.promoteCppType(prvalueType(typeOfOperand));
if (t != null) {
return t;
}
break;
}
if (typeOfOperand instanceof CPPBasicType) {
((CPPBasicType) typeOfOperand).setFromExpression(this);
}
return typeOfOperand;
}
@Override
public ValueCategory getValueCategory() {
final int op= getOperator();
switch (op) {
case op_typeid:
return LVALUE;
case op_sizeof:
case op_sizeofParameterPack:
return PRVALUE;
case op_bracketedPrimary:
return (operand).getValueCategory();
}
if (op == op_amper && computePointerToMemberType() != null) {
return PRVALUE;
}
ICPPFunction overload = getOverload();
if (overload != null)
return valueCategoryFromFunctionCall(overload);
switch(op) {
case op_star:
case op_prefixDecr:
case op_prefixIncr:
return LVALUE;
}
return PRVALUE;
} }
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
if (fOperand == null)
return EvalFixed.INCOMPLETE;
final ICPPEvaluation arg = fOperand.getEvaluation();
if (fOperator == op_bracketedPrimary) {
fEvaluation= arg;
} else if (arg.isFunctionSet() && fOperator == op_amper) {
return arg;
} else {
IType type= computePointerToMemberType();
if (type != null) {
if (type instanceof IProblemType)
return EvalFixed.INCOMPLETE;
fEvaluation= new EvalFixed(type, PRVALUE, Value.UNKNOWN);
} else {
fEvaluation= new EvalUnary(fOperator, fOperand.getEvaluation());
}
}
}
return fEvaluation;
}
@Override
public IType getExpressionType() {
IType type= getEvaluation().getTypeOrFunctionSet(this);
if (type instanceof FunctionSetType) {
type= fOperand.getExpressionType();
if (fOperator == op_amper) {
if (fOperand instanceof IASTIdExpression) {
IASTIdExpression idExpr = (IASTIdExpression) fOperand;
final IASTName name = idExpr.getName();
if (name instanceof ICPPASTQualifiedName) {
IBinding binding = name.resolveBinding();
if (binding instanceof ICPPMethod) {
ICPPMethod method = (ICPPMethod) binding;
if (!method.isStatic()) {
return new CPPPointerToMemberType(method.getType(), method.getClassOwner(), false, false, false);
}
}
}
}
return new CPPPointerType(type);
}
}
return type;
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
@Override @Override
public boolean isLValue() { public boolean isLValue() {
return getValueCategory() == LVALUE; return getValueCategory() == LVALUE;
} }
} }

View file

@ -110,7 +110,7 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
final byte firstByte = ITypeMarshalBuffer.ARRAY; final byte firstByte = ITypeMarshalBuffer.ARRAY_TYPE;
IValue val= getSize(); IValue val= getSize();
if (val == null) { if (val == null) {

View file

@ -226,10 +226,10 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
} }
@Override @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, public IBinding[] getBindings(ScopeLookupData lookup) {
IIndexFileSet fileSet, boolean checkPointOfDecl) { char[] c = lookup.getLookupKey();
char[] c = name.getLookupKey(); final boolean prefixLookup= lookup.isPrefixLookup();
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode(); ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
IASTName compName = compType.getName().getLastName(); IASTName compName = compType.getName().getLastName();
if (compName instanceof ICPPASTTemplateId) { if (compName instanceof ICPPASTTemplateId) {
@ -238,16 +238,16 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
IBinding[] result = null; IBinding[] result = null;
if ((!prefixLookup && CharArrayUtils.equals(c, compName.getLookupKey())) if ((!prefixLookup && CharArrayUtils.equals(c, compName.getLookupKey()))
|| (prefixLookup && ContentAssistMatcherFactory.getInstance().match(c, compName.getLookupKey()))) { || (prefixLookup && ContentAssistMatcherFactory.getInstance().match(c, compName.getLookupKey()))) {
if (shallReturnConstructors(name, prefixLookup)) { final IASTName lookupName = lookup.getLookupName();
result = ArrayUtil.addAll(IBinding.class, result, getConstructors(name, resolve)); if (shallReturnConstructors(lookupName, prefixLookup)) {
result = ArrayUtil.addAll(IBinding.class, result, getConstructors(lookupName, lookup.isResolve()));
} }
//9.2 ... The class-name is also inserted into the scope of the class itself //9.2 ... The class-name is also inserted into the scope of the class itself
result = ArrayUtil.append(IBinding.class, result, compName.resolveBinding()); result = ArrayUtil.append(IBinding.class, result, compName.resolveBinding());
if (!prefixLookup) if (!prefixLookup)
return ArrayUtil.trim(IBinding.class, result); return ArrayUtil.trim(IBinding.class, result);
} }
result = ArrayUtil.addAll(IBinding.class, result, result = ArrayUtil.addAll(IBinding.class, result, super.getBindings(lookup));
super.getBindings(name, resolve, prefixLookup, fileSet, checkPointOfDecl));
return ArrayUtil.trim(IBinding.class, result); return ArrayUtil.trim(IBinding.class, result);
} }
@ -325,12 +325,12 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
} }
public static boolean shallReturnConstructors(IASTName name, boolean isPrefixLookup) { public static boolean shallReturnConstructors(IASTName name, boolean isPrefixLookup) {
if (name == null)
return false;
if (!isPrefixLookup) if (!isPrefixLookup)
return CPPVisitor.isConstructorDeclaration(name); return CPPVisitor.isConstructorDeclaration(name);
if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY)
return false;
IASTNode node = name.getParent(); IASTNode node = name.getParent();
if (node instanceof ICPPASTTemplateId) if (node instanceof ICPPASTTemplateId)
return false; return false;

View file

@ -12,6 +12,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -33,7 +36,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.core.runtime.Assert;
/** /**
* Specialization of a class. * Specialization of a class.
@ -41,8 +46,16 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
public class CPPClassSpecialization extends CPPSpecialization public class CPPClassSpecialization extends CPPSpecialization
implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost { implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost {
public final static class RecursionResolvingBinding extends ProblemBinding {
public RecursionResolvingBinding(IASTNode node, char[] arg) {
super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, arg);
Assert.isTrue(CPPASTNameBase.sAllowRecursionBindings, getMessage());
}
}
private ICPPClassSpecializationScope specScope; private ICPPClassSpecializationScope specScope;
private ObjectMap specializationMap= ObjectMap.EMPTY_MAP; private ObjectMap specializationMap= ObjectMap.EMPTY_MAP;
private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>();
public CPPClassSpecialization(ICPPClassType specialized, IBinding owner, ICPPTemplateParameterMap argumentMap) { public CPPClassSpecialization(ICPPClassType specialized, IBinding owner, ICPPTemplateParameterMap argumentMap) {
super(specialized, owner, argumentMap); super(specialized, owner, argumentMap);
@ -55,14 +68,29 @@ public class CPPClassSpecialization extends CPPSpecialization
} }
@Override @Override
public IBinding specializeMember(IBinding original) { public IBinding specializeMember(IBinding original) {
return specializeMember(original, null);
}
@Override
public IBinding specializeMember(IBinding original, IASTNode point) {
Set<IBinding> set;
synchronized(this) { synchronized(this) {
IBinding result= (IBinding) specializationMap.get(original); IBinding result= (IBinding) specializationMap.get(original);
if (result != null) if (result != null)
return result; return result;
set= fInProgress.get();
if (set == null) {
set= new HashSet<IBinding>();
fInProgress.set(set);
}
if (!set.add(original))
return new RecursionResolvingBinding(null, null);
} }
IBinding result= CPPTemplates.createSpecialization(this, original); IBinding result= CPPTemplates.createSpecialization(this, original, point);
set.remove(original);
synchronized(this) { synchronized(this) {
IBinding concurrent= (IBinding) specializationMap.get(original); IBinding concurrent= (IBinding) specializationMap.get(original);
if (concurrent != null) if (concurrent != null)

View file

@ -1,4 +1,4 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2011 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2011 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -15,7 +15,6 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization;
@ -34,11 +33,14 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
private ObjectMap instances = null; private ObjectMap instances = null;
private ICPPDeferredClassInstance fDeferredInstance; private ICPPDeferredClassInstance fDeferredInstance;
private ICPPClassTemplate fClassTemplate; private final ICPPClassTemplate fClassTemplate;
private final ICPPTemplateArgument[] fArguments;
public CPPClassTemplatePartialSpecializationSpecialization(ICPPClassTemplatePartialSpecialization orig, ICPPClassTemplate template, ICPPTemplateParameterMap argumentMap) throws DOMException { public CPPClassTemplatePartialSpecializationSpecialization(ICPPClassTemplatePartialSpecialization orig, ICPPTemplateParameterMap argumentMap, ICPPClassTemplate template,
ICPPTemplateArgument[] args) throws DOMException {
super(orig, template.getOwner(), argumentMap); super(orig, template.getOwner(), argumentMap);
fClassTemplate= template; fClassTemplate= template;
fArguments= args;
} }
@Override @Override
@ -96,17 +98,7 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
@Override @Override
public ICPPTemplateArgument[] getTemplateArguments() { public ICPPTemplateArgument[] getTemplateArguments() {
ICPPTemplateArgument[] args = ((ICPPClassTemplatePartialSpecialization) getSpecializedBinding()).getTemplateArguments(); return fArguments;
try {
final IBinding owner = getOwner();
if (owner instanceof ICPPClassSpecialization) {
return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1,
(ICPPClassSpecialization) owner);
}
return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1, null);
} catch (DOMException e) {
return args;
}
} }
@Override @Override

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
@ -42,11 +43,12 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
@Override @Override
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() {
if (fPartialSpecs == null) { if (fPartialSpecs == null) {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding();
ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations();
ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length];
for (int i = 0; i < orig.length; i++) { for (int i = 0; i < orig.length; i++) {
spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i]); spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i], point);
} }
fPartialSpecs = spec; fPartialSpecs = spec;
} }

View file

@ -404,18 +404,27 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
@Override @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) {
if (name instanceof ICPPASTTemplateId) return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
return IBinding.EMPTY_BINDING_ARRAY;
if (prefixLookup)
return getPrefixBindings(name.getSimpleID());
return getBindings(name.getSimpleID());
} }
/**
* @deprecated Use {@link #getBindings(ScopeLookupData)} instead
*/
@Deprecated
@Override @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
IIndexFileSet acceptLocalBindings) { IIndexFileSet acceptLocalBindings) {
return getBindings(name, resolve, prefixLookup); return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
}
@Override
public IBinding[] getBindings(ScopeLookupData lookup) {
if (lookup.getLookupName() instanceof ICPPASTTemplateId)
return IBinding.EMPTY_BINDING_ARRAY;
if (lookup.isPrefixLookup())
return getPrefixBindings(lookup.getLookupKey());
return getBindings(lookup.getLookupKey());
} }
@Override @Override

View file

@ -11,8 +11,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
/** /**
@ -21,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
public class CPPConstructorInstance extends CPPMethodInstance implements ICPPConstructor { public class CPPConstructorInstance extends CPPMethodInstance implements ICPPConstructor {
public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner, public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner,
CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) { CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpec) {
super(orig, owner, tpmap, args); super(orig, owner, tpmap, args, type, exceptionSpec);
} }
} }

View file

@ -11,8 +11,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
/** /**
@ -22,7 +24,7 @@ public class CPPConstructorSpecialization extends CPPMethodSpecialization
implements ICPPConstructor { implements ICPPConstructor {
public CPPConstructorSpecialization(ICPPConstructor orig, ICPPClassType owner, public CPPConstructorSpecialization(ICPPConstructor orig, ICPPClassType owner,
ICPPTemplateParameterMap argMap) { ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, argMap); super(orig, owner, argMap, type, exceptionSpecs);
} }
} }

View file

@ -11,8 +11,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
/** /**
@ -22,7 +24,7 @@ public class CPPConstructorTemplateSpecialization extends CPPMethodTemplateSpeci
implements ICPPConstructor { implements ICPPConstructor {
public CPPConstructorTemplateSpecialization(ICPPConstructor original, public CPPConstructorTemplateSpecialization(ICPPConstructor original,
ICPPClassType owner, ICPPTemplateParameterMap tpmap) { ICPPClassType owner, ICPPTemplateParameterMap tpmap, ICPPFunctionType type, IType[] exceptionSpecs) {
super(original, owner, tpmap); super(original, owner, tpmap, type, exceptionSpecs);
} }
} }

View file

@ -18,18 +18,19 @@ import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable;
import org.eclipse.cdt.internal.core.dom.parser.Value;
/** /**
* Binding for a specialization of a field. * Binding for a specialization of a field.
*/ */
public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField, IInternalVariable { public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField {
private IType type = null; private IType type = null;
private IValue value= null; private IValue value= null;
public CPPFieldSpecialization( IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap) { public CPPFieldSpecialization(IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap,
IType type, IValue value) {
super(orig, owner, tpmap); super(orig, owner, tpmap);
this.type= type;
this.value= value;
} }
private ICPPField getField() { private ICPPField getField() {
@ -48,9 +49,6 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
@Override @Override
public IType getType() { public IType getType() {
if (type == null) {
type= specializeType(getField().getType());
}
return type; return type;
} }
@ -91,21 +89,6 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
@Override @Override
public IValue getInitialValue() { public IValue getInitialValue() {
return getInitialValue(Value.MAX_RECURSION_DEPTH);
}
@Override
public IValue getInitialValue(int maxRecursionDepth) {
if (value == null) {
ICPPField field= getField();
IValue v;
if (field instanceof IInternalVariable) {
v= ((IInternalVariable) field).getInitialValue(maxRecursionDepth);
} else {
v= getField().getInitialValue();
}
value= specializeValue(v, maxRecursionDepth);
}
return value; return value;
} }
} }

View file

@ -59,6 +59,8 @@ import org.eclipse.core.runtime.PlatformObject;
* Binding for c++ function * Binding for c++ function
*/ */
public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInternalFunction { public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInternalFunction {
public static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null);
protected IASTDeclarator[] declarations; protected IASTDeclarator[] declarations;
protected ICPPASTFunctionDeclarator definition; protected ICPPASTFunctionDeclarator definition;
protected ICPPFunctionType type; protected ICPPFunctionType type;

View file

@ -26,10 +26,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
* The instantiation of a function template. * The instantiation of a function template.
*/ */
public class CPPFunctionInstance extends CPPFunctionSpecialization implements ICPPTemplateInstance { public class CPPFunctionInstance extends CPPFunctionSpecialization implements ICPPTemplateInstance {
private ICPPTemplateArgument[] fArguments; private final ICPPTemplateArgument[] fArguments;
public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) { public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, argMap); super(orig, owner, argMap, type, exceptionSpecs);
fArguments = args; fArguments = args;
} }

View file

@ -25,11 +25,9 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
@ -41,26 +39,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
* also used as base class for function instances. * also used as base class for function instances.
*/ */
public class CPPFunctionSpecialization extends CPPSpecialization implements ICPPFunction, ICPPInternalFunction { public class CPPFunctionSpecialization extends CPPSpecialization implements ICPPFunction, ICPPInternalFunction {
private ICPPFunctionType type; private final ICPPFunctionType fType;
private ICPPParameter[] fParams; private ICPPParameter[] fParams;
private IType[] specializedExceptionSpec; private final IType[] fExceptionSpecs;
private final ICPPClassSpecialization fContext;
public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap) { public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpecs) {
this(orig, owner, argMap, null);
}
public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap,
ICPPClassSpecialization context) {
super(orig, owner, argMap); super(orig, owner, argMap);
fContext= context; fType= type;
} fExceptionSpecs= exceptionSpecs;
@Override
protected ICPPClassSpecialization getSpecializationContext() {
if (fContext != null)
return fContext;
return super.getSpecializationContext();
} }
private ICPPFunction getFunction() { private ICPPFunction getFunction() {
@ -109,12 +95,7 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
@Override @Override
public ICPPFunctionType getType() { public ICPPFunctionType getType() {
if (type == null) { return fType;
ICPPFunction function = (ICPPFunction) getSpecializedBinding();
type = (ICPPFunctionType) specializeType(function.getType());
}
return type;
} }
@Override @Override
@ -331,31 +312,6 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
@Override @Override
public IType[] getExceptionSpecification() { public IType[] getExceptionSpecification() {
if (specializedExceptionSpec == null) { return fExceptionSpecs;
ICPPFunction function = (ICPPFunction) getSpecializedBinding();
IType[] types = function.getExceptionSpecification();
if (types != null) {
IType[] specializedTypeList = new IType[types.length];
int j= 0;
for (int i= 0; i < types.length; ++i) {
final IType origType = types[i];
if (origType instanceof ICPPParameterPackType) {
IType[] specialized= specializeTypePack((ICPPParameterPackType) origType);
if (specialized.length != 1) {
IType[] x= new IType[specializedTypeList.length + specialized.length-1];
System.arraycopy(specializedTypeList, 0, x, 0, j);
specializedTypeList= x;
}
for (IType iType : specialized) {
specializedTypeList[j++] = iType;
}
} else {
specializedTypeList[j++] = specializeType(origType);
}
}
specializedExceptionSpec= specializedTypeList;
}
}
return specializedExceptionSpec;
} }
} }

View file

@ -13,9 +13,11 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
@ -30,8 +32,8 @@ public class CPPFunctionTemplateSpecialization extends CPPFunctionSpecialization
private ObjectMap instances = null; private ObjectMap instances = null;
public CPPFunctionTemplateSpecialization(ICPPFunction original, ICPPClassType owner, ICPPTemplateParameterMap argumentMap) { public CPPFunctionTemplateSpecialization(ICPPFunction original, ICPPClassType owner, ICPPTemplateParameterMap argumentMap, ICPPFunctionType type, IType[] exceptionSpecs) {
super(original, owner, argumentMap); super(original, owner, argumentMap, type, exceptionSpecs);
} }
@Override @Override

View file

@ -11,7 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
@ -20,8 +22,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
*/ */
public class CPPMethodInstance extends CPPFunctionInstance implements ICPPMethod { public class CPPMethodInstance extends CPPFunctionInstance implements ICPPMethod {
public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) { public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, tpmap, args); super(orig, owner, tpmap, args, type, exceptionSpecs);
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
@ -26,8 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
*/ */
public class CPPMethodSpecialization extends CPPFunctionSpecialization implements ICPPMethod { public class CPPMethodSpecialization extends CPPFunctionSpecialization implements ICPPMethod {
public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap) { public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpec ) {
super(orig, owner, argMap); super(orig, owner, argMap, type, exceptionSpec );
} }
@Override @Override

View file

@ -12,7 +12,9 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
@ -23,8 +25,8 @@ public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpeciali
implements ICPPMethod { implements ICPPMethod {
public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassType owner, public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassType owner,
ICPPTemplateParameterMap ctmap) { ICPPTemplateParameterMap ctmap, ICPPFunctionType type, IType[] exceptionSpecs) {
super(specialized, owner, ctmap); super(specialized, owner, ctmap, type, exceptionSpecs);
} }
@Override @Override

View file

@ -72,7 +72,7 @@ public class CPPParameterPackType implements ICPPParameterPackType, ITypeContain
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.PACK_EXPANSION; int firstByte= ITypeMarshalBuffer.PACK_EXPANSION_TYPE;
buffer.putByte((byte) firstByte); buffer.putByte((byte) firstByte);
buffer.marshalType(getType()); buffer.marshalType(getType());
} }

View file

@ -22,7 +22,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
* Binding for a specialization of a parameter. * Binding for a specialization of a parameter.
*/ */
public class CPPParameterSpecialization extends CPPSpecialization implements ICPPParameter { public class CPPParameterSpecialization extends CPPSpecialization implements ICPPParameter {
private IType fType; private final IType fType;
public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, IType type, ICPPTemplateParameterMap tpmap) { public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, IType type, ICPPTemplateParameterMap tpmap) {
super(orig, owner, tpmap); super(orig, owner, tpmap);
@ -46,12 +46,6 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP
return fType instanceof ICPPParameterPackType; return fType instanceof ICPPParameterPackType;
} }
@Override
public IType specializeType(IType type) {
assert false;
return type;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic() * @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
*/ */

View file

@ -97,7 +97,7 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.POINTER_TO_MEMBER; int firstByte= ITypeMarshalBuffer.POINTER_TO_MEMBER_TYPE;
if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1;
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3;

View file

@ -108,7 +108,7 @@ public class CPPPointerType implements IPointerType, ITypeContainer, ISerializab
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.POINTER; int firstByte= ITypeMarshalBuffer.POINTER_TYPE;
if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1;
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3;

View file

@ -92,7 +92,7 @@ public class CPPQualifierType implements IQualifierType, ITypeContainer, ISerial
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.CVQUALIFIER; int firstByte= ITypeMarshalBuffer.CVQUALIFIER_TYPE;
if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1;
if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
buffer.putByte((byte) firstByte); buffer.putByte((byte) firstByte);

View file

@ -109,7 +109,7 @@ public class CPPReferenceType implements ICPPReferenceType, ITypeContainer, ISer
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.REFERENCE; int firstByte= ITypeMarshalBuffer.REFERENCE_TYPE;
if (isRValueReference()) { if (isRValueReference()) {
firstByte |= ITypeMarshalBuffer.FLAG1; firstByte |= ITypeMarshalBuffer.FLAG1;
} }

View file

@ -57,7 +57,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
private static final IProgressMonitor NPM = new NullProgressMonitor(); private static final IProgressMonitor NPM = new NullProgressMonitor();
private static final ICPPNamespace UNINITIALIZED = new CPPNamespace.CPPNamespaceProblem(null, 0, null); private static final ICPPNamespace UNINITIALIZED = new CPPNamespace.CPPNamespaceProblem(null, 0, null);
private IASTNode physicalNode; private final IASTNode physicalNode;
private boolean isCached = false; private boolean isCached = false;
protected CharArrayObjectMap<Object> bindings; protected CharArrayObjectMap<Object> bindings;
private ICPPNamespace fIndexNamespace= UNINITIALIZED; private ICPPNamespace fIndexNamespace= UNINITIALIZED;
@ -121,7 +121,10 @@ abstract public class CPPScope implements ICPPASTInternalScope {
@Override @Override
public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) { public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) {
IBinding binding= getBindingInAST(name, forceResolve); final ScopeLookupData lookup = new ScopeLookupData(name, forceResolve, false);
lookup.setIgnorePointOfDeclaration(true);
IBinding[] bs= getBindingsInAST(lookup);
IBinding binding= CPPSemantics.resolveAmbiguities(name, bs);
if (binding == null && forceResolve) { if (binding == null && forceResolve) {
final IASTTranslationUnit tu = name.getTranslationUnit(); final IASTTranslationUnit tu = name.getTranslationUnit();
IIndex index = tu == null ? null : tu.getIndex(); IIndex index = tu == null ? null : tu.getIndex();
@ -169,29 +172,28 @@ abstract public class CPPScope implements ICPPASTInternalScope {
return fIndexNamespace; return fIndexNamespace;
} }
public IBinding getBindingInAST(IASTName name, boolean forceResolve) { /**
IBinding[] bs= getBindingsInAST(name, forceResolve, false, false); * @deprecated Use {@link #getBindings(ScopeLookupData)} instead
return CPPSemantics.resolveAmbiguities(name, bs); */
} @Deprecated
@Override @Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return getBindings(name, resolve, prefixLookup, fileSet, true); return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
} }
@Override @Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet, public IBinding[] getBindings(ScopeLookupData lookup) {
boolean checkPointOfDecl) { IBinding[] result = getBindingsInAST(lookup);
IBinding[] result = getBindingsInAST(name, resolve, prefixLookup, checkPointOfDecl); final IASTTranslationUnit tu = lookup.getLookupPoint().getTranslationUnit();
final IASTTranslationUnit tu = name.getTranslationUnit();
if (tu != null) { if (tu != null) {
IIndex index = tu.getIndex(); IIndex index = tu.getIndex();
if (index != null) { if (index != null) {
IIndexFileSet fileSet= lookup.getIncludedFiles();
if (physicalNode instanceof IASTTranslationUnit) { if (physicalNode instanceof IASTTranslationUnit) {
try { try {
IndexFilter filter = IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE; IndexFilter filter = IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE;
final char[] nchars = name.getLookupKey(); final char[] nchars = lookup.getLookupKey();
IBinding[] bindings = prefixLookup ? IBinding[] bindings = lookup.isPrefixLookup() ?
index.findBindingsForContentAssist(nchars, true, filter, null) : index.findBindingsForContentAssist(nchars, true, filter, null) :
index.findBindings(nchars, filter, null); index.findBindings(nchars, filter, null);
if (fileSet != null) { if (fileSet != null) {
@ -207,10 +209,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
IIndexBinding binding = index.findBinding(ns.getName()); IIndexBinding binding = index.findBinding(ns.getName());
if (binding instanceof ICPPNamespace) { if (binding instanceof ICPPNamespace) {
ICPPNamespaceScope indexNs = ((ICPPNamespace) binding).getNamespaceScope(); ICPPNamespaceScope indexNs = ((ICPPNamespace) binding).getNamespaceScope();
IBinding[] bindings = indexNs.getBindings(name, resolve, prefixLookup); IBinding[] bindings = indexNs.getBindings(lookup);
if (fileSet != null) {
bindings= fileSet.filterFileLocalBindings(bindings);
}
result = ArrayUtil.addAll(IBinding.class, result, bindings); result = ArrayUtil.addAll(IBinding.class, result, bindings);
} }
} catch (CoreException e) { } catch (CoreException e) {
@ -224,14 +223,13 @@ abstract public class CPPScope implements ICPPASTInternalScope {
} }
public IBinding[] getBindingsInAST(IASTName name, boolean forceResolve, boolean prefixLookup, public IBinding[] getBindingsInAST(ScopeLookupData lookup) {
boolean checkPointOfDecl) {
populateCache(); populateCache();
final char[] c = name.getLookupKey(); final char[] c = lookup.getLookupKey();
IBinding[] result = null; IBinding[] result = null;
Object obj = null; Object obj = null;
if (prefixLookup) { if (lookup.isPrefixLookup()) {
Object[] keys = bindings != null ? bindings.keyArray() : new Object[0]; Object[] keys = bindings != null ? bindings.keyArray() : new Object[0];
ObjectSet<Object> all= new ObjectSet<Object>(16); ObjectSet<Object> all= new ObjectSet<Object>(16);
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c); IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c);
@ -255,21 +253,21 @@ abstract public class CPPScope implements ICPPASTInternalScope {
if (obj instanceof ObjectSet<?>) { if (obj instanceof ObjectSet<?>) {
ObjectSet<?> os= (ObjectSet<?>) obj; ObjectSet<?> os= (ObjectSet<?>) obj;
for (int j = 0; j < os.size(); j++) { for (int j = 0; j < os.size(); j++) {
result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, result); result= addCandidate(os.keyAt(j), lookup, result);
} }
} else { } else {
result = addCandidate(obj, name, forceResolve, checkPointOfDecl, result); result = addCandidate(obj, lookup, result);
} }
} }
return ArrayUtil.trim(IBinding.class, result); return ArrayUtil.trim(IBinding.class, result);
} }
private IBinding[] addCandidate(Object candidate, IASTName name, boolean forceResolve, private IBinding[] addCandidate(Object candidate, ScopeLookupData lookup, IBinding[] result) {
boolean checkPointOfDecl, IBinding[] result) { final IASTNode point = lookup.getLookupPoint();
if (checkPointOfDecl) { if (!lookup.isIgnorePointOfDeclaration()) {
IASTTranslationUnit tu= name.getTranslationUnit(); IASTTranslationUnit tu= point.getTranslationUnit();
if (!CPPSemantics.declaredBefore(candidate, name, tu != null && tu.getIndex() != null)) { if (!CPPSemantics.declaredBefore(candidate, point, tu != null && tu.getIndex() != null)) {
if (!(this instanceof ICPPClassScope) || !LookupData.checkWholeClassScope(name)) if (!(this instanceof ICPPClassScope) || !LookupData.checkWholeClassScope(lookup.getLookupName()))
return result; return result;
} }
} }
@ -281,7 +279,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
if (simpleName instanceof ICPPASTTemplateId) { if (simpleName instanceof ICPPASTTemplateId) {
simpleName= ((ICPPASTTemplateId) simpleName).getTemplateName(); simpleName= ((ICPPASTTemplateId) simpleName).getTemplateName();
} }
if (forceResolve && candName != name && simpleName != name) { if (lookup.isResolve() && candName != point && simpleName != point) {
candName.resolvePreBinding(); // Make sure to resolve the template-id candName.resolvePreBinding(); // Make sure to resolve the template-id
binding = simpleName.resolvePreBinding(); binding = simpleName.resolvePreBinding();
} else { } else {
@ -377,7 +375,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
@Override @Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY, true); return getBindings(new ScopeLookupData(name, resolve, prefix));
} }
@Override @Override

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
@ -104,13 +105,18 @@ public class CPPScopeMapper {
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings) { public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings) {
return fScope.getBinding(name, resolve, acceptLocalBindings); return fScope.getBinding(name, resolve, acceptLocalBindings);
} }
@Override @Override @Deprecated
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) {
return fScope.getBindings(name, resolve, prefixLookup); return fScope.getBindings(name, resolve, prefixLookup);
} }
@Override @Override @Deprecated
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings) { public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings) {
return fScope.getBindings(name, resolve, prefixLookup, acceptLocalBindings); return getBindings(name, resolve, prefixLookup, acceptLocalBindings);
}
@Override
public IBinding[] getBindings(ScopeLookupData lookup) {
return fScope.getBindings(lookup);
} }
@Override @Override
public IScope getParent() throws DOMException { public IScope getParent() throws DOMException {
@ -363,14 +369,14 @@ public class CPPScopeMapper {
return scope; return scope;
} }
public ICPPClassType mapToAST(ICPPClassType type) { public ICPPClassType mapToAST(ICPPClassType type, IASTNode point) {
if (type instanceof ICPPTemplateInstance) { if (type instanceof ICPPTemplateInstance) {
ICPPTemplateInstance inst= (ICPPTemplateInstance) type; ICPPTemplateInstance inst= (ICPPTemplateInstance) type;
ICPPTemplateDefinition template= inst.getTemplateDefinition(); ICPPTemplateDefinition template= inst.getTemplateDefinition();
if (template instanceof IIndexBinding && template instanceof ICPPClassType) { if (template instanceof IIndexBinding && template instanceof ICPPClassType) {
IBinding mapped= mapToAST((ICPPClassType) template); IBinding mapped= mapToAST((ICPPClassType) template, point);
if (mapped != template && mapped instanceof ICPPClassType) { if (mapped != template && mapped instanceof ICPPClassType) {
mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments()); mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments(), point);
if (mapped instanceof ICPPClassType) if (mapped instanceof ICPPClassType)
return (ICPPClassType) mapped; return (ICPPClassType) mapped;
} }

View file

@ -16,14 +16,10 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -40,9 +36,9 @@ import org.eclipse.core.runtime.PlatformObject;
* is a need to synchronize non-final members. * is a need to synchronize non-final members.
*/ */
public abstract class CPPSpecialization extends PlatformObject implements ICPPSpecialization, ICPPInternalBinding { public abstract class CPPSpecialization extends PlatformObject implements ICPPSpecialization, ICPPInternalBinding {
private IBinding owner; private final IBinding owner;
private IBinding specialized; private final IBinding specialized;
private ICPPTemplateParameterMap argumentMap; private final ICPPTemplateParameterMap argumentMap;
protected IASTNode definition; protected IASTNode definition;
private IASTNode[] declarations; private IASTNode[] declarations;
@ -52,45 +48,6 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
this.argumentMap = argumentMap; this.argumentMap = argumentMap;
} }
public IType specializeType(IType type) {
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, getSpecializationContext());
}
protected ICPPClassSpecialization getSpecializationContext() {
if (owner instanceof ICPPClassSpecialization) {
ICPPClassSpecialization within = (ICPPClassSpecialization) owner;
ICPPClassType orig = within.getSpecializedBinding();
for(;;) {
IBinding o1 = within.getOwner();
IBinding o2 = orig.getOwner();
if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType))
return within;
ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1;
orig= (ICPPClassType) o2;
if (orig.isSameType(nextWithin))
return within;
within= nextWithin;
}
}
return null;
}
public IType[] specializeTypePack(ICPPParameterPackType type) {
if (owner instanceof ICPPClassSpecialization) {
return CPPTemplates.instantiateTypes(new IType[]{type}, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner);
} else {
return CPPTemplates.instantiateTypes(new IType[]{type}, getTemplateParameterMap(), -1, null);
}
}
public IValue specializeValue(IValue value, int maxdepth) {
if (owner instanceof ICPPClassSpecialization) {
return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner, maxdepth);
} else {
return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), -1, null, maxdepth);
}
}
@Override @Override
public IBinding getSpecializedBinding() { public IBinding getSpecializedBinding() {
return specialized; return specialized;

View file

@ -12,91 +12,31 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.core.runtime.Assert;
/** /**
* Specialization of a typedef in the context of a class-specialization. * Specialization of a typedef in the context of a class-specialization.
*/ */
public class CPPTypedefSpecialization extends CPPSpecialization implements ITypedef, ITypeContainer { public class CPPTypedefSpecialization extends CPPSpecialization implements ITypedef, ITypeContainer {
final static class RecursionResolvingBinding extends ProblemBinding {
public RecursionResolvingBinding(IASTNode node, char[] arg) {
super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, arg);
Assert.isTrue(CPPASTNameBase.sAllowRecursionBindings, getMessage());
}
}
public static final int MAX_RESOLUTION_DEPTH = 5; public static final int MAX_RESOLUTION_DEPTH = 5;
public static final int MAX_TYPE_NESTING = 60; public static final int MAX_TYPE_NESTING = 60;
private IType type; private IType fType;
private int fResolutionDepth;
public CPPTypedefSpecialization(IBinding specialized, ICPPClassType owner, public CPPTypedefSpecialization(IBinding specialized, ICPPClassType owner, ICPPTemplateParameterMap tpmap, IType type) {
ICPPTemplateParameterMap tpmap) {
super(specialized, owner, tpmap); super(specialized, owner, tpmap);
fType= type;
} }
private ITypedef getTypedef() {
return (ITypedef) getSpecializedBinding();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.ITypedef#getType()
*/
@Override @Override
public IType getType() { public IType getType() {
return getType(MAX_TYPE_NESTING); return fType;
} }
private IType getType(int maxDepth) {
if (type == null) {
try {
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
type = new RecursionResolvingBinding(getDefinition(), getNameCharArray());
} else {
type= specializeType(getTypedef().getType());
// A typedef pointing to itself is a sure recipe for an infinite loop -- replace
// with a problem binding.
if (!verifyType(type, maxDepth)) {
type = new RecursionResolvingBinding(getDefinition(), getNameCharArray());
}
}
} finally {
--fResolutionDepth;
}
}
return type;
}
private boolean verifyType(IType type, int maxTypeNesting) {
for (;;) {
if (--maxTypeNesting < 0)
return false;
if (equals(type))
return false;
if (type instanceof CPPTypedefSpecialization) {
type= ((CPPTypedefSpecialization) type).getType(maxTypeNesting);
} else if (type instanceof ITypeContainer) {
type= ((ITypeContainer) type).getType();
} else {
return true;
}
}
}
public int incResolutionDepth(int increment) {
fResolutionDepth += increment;
return fResolutionDepth;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#clone() * @see java.lang.Object#clone()
@ -134,6 +74,6 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType
@Override @Override
public void setType(IType type) { public void setType(IType type) {
this.type = type; fType = type;
} }
} }

View file

@ -23,7 +23,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
@ -39,7 +38,6 @@ public class CPPUnknownBinding extends PlatformObject
public CPPUnknownBinding(IBinding owner, char[] name) { public CPPUnknownBinding(IBinding owner, char[] name) {
super(); super();
this.name = new CPPASTName(name); this.name = new CPPASTName(name);
this.name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY);
fOwner= owner; fOwner= owner;
} }

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
/** /**
* Represents a reference to a (member) function (instance), which cannot be resolved because * Represents a reference to a (member) function (instance), which cannot be resolved because
@ -26,6 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
*/ */
public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction { public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction {
private static final ICPPFunctionType FUNCTION_TYPE= new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY);
public static ICPPFunction createForSample(IFunction sample) throws DOMException { public static ICPPFunction createForSample(IFunction sample) throws DOMException {
if (sample instanceof ICPPConstructor) if (sample instanceof ICPPConstructor)
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner()); return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
@ -33,7 +36,6 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio
return new CPPUnknownFunction(sample.getOwner(), sample.getNameCharArray()); return new CPPUnknownFunction(sample.getOwner(), sample.getNameCharArray());
} }
private ICPPFunctionType fType;
public CPPUnknownFunction(IBinding owner, char[] name) { public CPPUnknownFunction(IBinding owner, char[] name) {
super(owner, name); super(owner, name);
@ -76,10 +78,7 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio
@Override @Override
public ICPPFunctionType getType() { public ICPPFunctionType getType() {
if (fType == null) { return FUNCTION_TYPE;
fType= new CPPUnknownFunctionType();
}
return fType;
} }
@Override @Override

View file

@ -13,33 +13,17 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/** /**
* Models the scope represented by an unknown binding such (e.g.: template type parameter). Used within * Models the scope represented by an unknown binding such (e.g.: template type parameter). Used within
* the context of templates, only. * the context of templates, only.
* For safe usage in index bindings, all fields need to be final or used in a thread-safe manner otherwise. * For safe usage in index bindings, all fields need to be final or used in a thread-safe manner otherwise.
*/ */
public class CPPUnknownScope implements ICPPInternalUnknownScope { public class CPPUnknownScope extends CPPUnknownTypeScope implements ICPPInternalUnknownScope {
private final ICPPUnknownBinding binding;
private final IASTName scopeName;
/** /**
* This field needs to be protected when used in PDOMCPPUnknownScope, * This field needs to be protected when used in PDOMCPPUnknownScope,
* don't use it outside of {@link #getOrCreateBinding(IASTName, int)} * don't use it outside of {@link #getOrCreateBinding(IASTName, int)}
@ -47,164 +31,38 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
private CharArrayObjectMap<IBinding[]> map; private CharArrayObjectMap<IBinding[]> map;
public CPPUnknownScope(ICPPUnknownBinding binding, IASTName name) { public CPPUnknownScope(ICPPUnknownBinding binding, IASTName name) {
super(); super(name, binding);
this.scopeName = name;
this.binding = binding;
} }
@Override
public EScopeKind getKind() {
return EScopeKind.eClassType;
}
@Override
public IName getScopeName() {
return scopeName;
}
@Override
public IScope getParent() throws DOMException {
return binding.getScope();
}
@Override
public IBinding[] find(String name) {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public IASTNode getPhysicalNode() {
return scopeName;
}
@Override @Override
public void addName(IASTName name) { public void addName(IASTName name) {
} }
@Override @Override
public final IBinding getBinding(IASTName name, boolean resolve) { protected IBinding getOrCreateBinding(final char[] name, int idx) {
return getBinding(name, resolve, IIndexFileSet.EMPTY);
}
@Override
public IBinding getBinding(final IASTName name, boolean resolve, IIndexFileSet fileSet) {
boolean type= false;
boolean function= false;
if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) {
type= true;
} else {
IASTName n= name;
IASTNode parent= name.getParent();
if (parent instanceof ICPPASTTemplateId) {
n= (IASTName) parent;
parent= n.getParent();
}
if (parent instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent;
if (qname.getLastName() != n) {
type= true;
} else {
parent= qname.getParent();
}
}
if (!type) {
if (parent instanceof ICPPASTBaseSpecifier ||
parent instanceof ICPPASTConstructorChainInitializer) {
type= true;
} else if (parent instanceof ICPPASTNamedTypeSpecifier) {
ICPPASTNamedTypeSpecifier nts= (ICPPASTNamedTypeSpecifier) parent;
type= nts.isTypename();
} else if (parent instanceof ICPPASTUsingDeclaration) {
ICPPASTUsingDeclaration ud= (ICPPASTUsingDeclaration) parent;
type= ud.isTypename();
}
if (!type && parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) {
function= true;
}
}
}
int idx= type ? 0 : function ? 1 : 2;
IBinding result = getOrCreateBinding(name, idx);
return result;
}
protected IBinding getOrCreateBinding(final IASTName name, int idx) {
if (map == null) if (map == null)
map = new CharArrayObjectMap<IBinding[]>(2); map = new CharArrayObjectMap<IBinding[]>(2);
final char[] c = name.getLookupKey(); IBinding[] o = map.get(name);
IBinding[] o = map.get(c);
if (o == null) { if (o == null) {
o = new IBinding[3]; o = new IBinding[3];
map.put(c, o); map.put(name, o);
} }
IBinding result= o[idx]; IBinding result= o[idx];
if (result == null) { if (result == null) {
switch (idx) { result= super.getOrCreateBinding(name, idx);
case 0:
result= new CPPUnknownClass(binding, name.getSimpleID());
break;
case 1:
result= new CPPUnknownFunction(binding, name.getSimpleID());
break;
case 2:
result= new CPPUnknownBinding(binding, name.getSimpleID());
break;
}
o[idx]= result; o[idx]= result;
} }
return result; return result;
} }
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY);
}
@Override
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return getBindings(name, resolve, prefixLookup, fileSet, true);
}
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl) {
if (prefixLookup) {
if (binding instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) binding;
IScope scope = instance.getClassTemplate().getCompositeScope();
if (scope != null) {
return scope.getBindings(name, resolve, prefixLookup, acceptLocalBindings);
}
}
return IBinding.EMPTY_BINDING_ARRAY;
}
return new IBinding[] {getBinding(name, resolve, acceptLocalBindings)};
}
@Override @Override
public void addBinding(IBinding binding) { public void addBinding(IBinding binding) {
// do nothing, this is part of template magic and not a normal scope // do nothing, this is part of template magic and not a normal scope
} }
@Override
public ICPPBinding getScopeBinding() {
return binding;
}
/* (non-Javadoc)
* For debug purposes only
*/
@Override
public String toString() {
return scopeName.toString();
}
@Override @Override
public void populateCache() {} public void populateCache() {}

View file

@ -0,0 +1,178 @@
/*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others.
* 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:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
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.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.index.IIndexFileSet;
/**
* Models the scope represented by an unknown type (e.g.: typeof(template type parameter)). Used within
* the context of templates, only.
* For safe usage in index bindings, all fields need to be final or used in a thread-safe manner otherwise.
*/
public class CPPUnknownTypeScope implements ICPPScope {
private final IASTName fName;
private final ICPPBinding fScopeBinding;
public CPPUnknownTypeScope(IASTName name, ICPPBinding scopeBinding) {
fName= name;
fScopeBinding= scopeBinding;
}
@Override
public EScopeKind getKind() {
return EScopeKind.eClassType;
}
public IASTNode getPhysicalNode() {
return fName;
}
@Override
public IName getScopeName() {
return fName;
}
@Override
public IScope getParent() throws DOMException {
return fScopeBinding == null ? null : fScopeBinding.getScope();
}
@Override
public IBinding[] find(String name) {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public final IBinding getBinding(IASTName name, boolean resolve) {
return getBinding(name, resolve, IIndexFileSet.EMPTY);
}
@Override
public IBinding getBinding(final IASTName name, boolean resolve, IIndexFileSet fileSet) {
boolean type= false;
boolean function= false;
if (name.getPropertyInParent() == null) {
type= true;
} else {
IASTName n= name;
IASTNode parent= name.getParent();
if (parent instanceof ICPPASTTemplateId) {
n= (IASTName) parent;
parent= n.getParent();
}
if (parent instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent;
if (qname.getLastName() != n) {
type= true;
} else {
parent= qname.getParent();
}
}
if (!type) {
if (parent instanceof ICPPASTBaseSpecifier ||
parent instanceof ICPPASTConstructorChainInitializer) {
type= true;
} else if (parent instanceof ICPPASTNamedTypeSpecifier) {
ICPPASTNamedTypeSpecifier nts= (ICPPASTNamedTypeSpecifier) parent;
type= nts.isTypename();
} else if (parent instanceof ICPPASTUsingDeclaration) {
ICPPASTUsingDeclaration ud= (ICPPASTUsingDeclaration) parent;
type= ud.isTypename();
}
if (!type && parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) {
function= true;
}
}
}
int idx= type ? 0 : function ? 1 : 2;
IBinding result = getOrCreateBinding(name.getSimpleID(), idx);
return result;
}
protected IBinding getOrCreateBinding(final char[] name, int idx) {
IBinding result= null;
switch (idx) {
case 0:
result= new CPPUnknownClass(fScopeBinding, name);
break;
case 1:
result= new CPPUnknownFunction(fScopeBinding, name);
break;
case 2:
result= new CPPUnknownBinding(fScopeBinding, name);
break;
}
return result;
}
@Override @Deprecated
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) {
return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY);
}
@Override @Deprecated
public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) {
return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
}
@Override
public final IBinding[] getBindings(ScopeLookupData lookup) {
if (lookup.isPrefixLookup()) {
if (fScopeBinding instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) fScopeBinding;
IScope scope = instance.getClassTemplate().getCompositeScope();
if (scope != null) {
return scope.getBindings(lookup);
}
}
return IBinding.EMPTY_BINDING_ARRAY;
}
IASTName lookupName= lookup.getLookupName();
if (lookupName != null)
return new IBinding[] {getBinding(lookupName, lookup.isResolve(), lookup.getIncludedFiles())};
// When dealing with dependent expressions we always create an unknown class. That is because
// unknown objects are not used within the expressions, they are attached to names only.
return new IBinding[] {getOrCreateBinding(lookup.getLookupKey(), 0)};
}
public ICPPBinding getScopeBinding() {
return fScopeBinding;
}
@Override
public String toString() {
return fName.toString();
}
}

View file

@ -10,58 +10,25 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
/** /**
* Specialization of a typedef in the context of a class-specialization. * Specialization of a typedef in the context of a class-specialization.
*/ */
public class CPPUsingDeclarationSpecialization extends CPPSpecialization implements ICPPUsingDeclaration { public class CPPUsingDeclarationSpecialization extends CPPSpecialization implements ICPPUsingDeclaration {
private IBinding[] fDelegates; private final IBinding[] fDelegates;
public CPPUsingDeclarationSpecialization(ICPPUsingDeclaration specialized, ICPPClassSpecialization owner, public CPPUsingDeclarationSpecialization(ICPPUsingDeclaration specialized, ICPPClassSpecialization owner,
ICPPTemplateParameterMap tpmap) { ICPPTemplateParameterMap tpmap, IBinding[] delegates) {
super(specialized, owner, tpmap); super(specialized, owner, tpmap);
fDelegates= delegates;
} }
@Override @Override
public IBinding[] getDelegates() { public IBinding[] getDelegates() {
if (fDelegates == null) {
fDelegates= specializeDelegates();
}
return fDelegates; return fDelegates;
} }
private IBinding[] specializeDelegates() {
IBinding[] origDelegates= ((ICPPUsingDeclaration) getSpecializedBinding()).getDelegates();
List<IBinding> result= new ArrayList<IBinding>();
ICPPClassSpecialization owner= (ICPPClassSpecialization) getOwner();
for (IBinding delegate : origDelegates) {
if (delegate instanceof ICPPUnknownBinding) {
try {
delegate= CPPTemplates.resolveUnknown((ICPPUnknownBinding) delegate,
owner.getTemplateParameterMap(), -1, null);
if (delegate instanceof CPPFunctionSet) {
for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) {
result.add(b);
}
} else if (delegate != null) {
result.add(delegate);
}
} catch (DOMException e) {
}
} else {
result.add(delegate);
}
}
return result.toArray(new IBinding[result.size()]);
}
} }

View file

@ -10,22 +10,11 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
/** /**
* Interface for internal c++ scopes * Interface for internal c++ scopes
*/ */
public interface ICPPASTInternalScope extends IASTInternalScope, ICPPScope { public interface ICPPASTInternalScope extends IASTInternalScope, ICPPScope {
/**
* Same as {@link IScope#getBindings(IASTName, boolean, boolean, IIndexFileSet)} with the
* possibility to disable checking the point of declaration. The method is used to resolve
* dependent bindings, where the points of declaration may be reversed.
*/
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl);
} }

View file

@ -12,19 +12,22 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
/** /**
* Assists in evaluating expressions. * Assists in evaluating expressions.
*/ */
public interface ICPPInitClauseEvaluation { public interface ICPPEvaluation extends ISerializableEvaluation {
boolean isInitializerList(); boolean isInitializerList();
boolean isFunctionSet();
boolean isTypeDependent(); boolean isTypeDependent();
boolean isValueDependent(); boolean isValueDependent();
IType getTypeOrFunctionSet(); IType getTypeOrFunctionSet(IASTNode point);
IValue getValue(); IValue getValue(IASTNode point);
ValueCategory getCategory(); ValueCategory getValueCategory(IASTNode point);
} }

View file

@ -174,8 +174,8 @@ public enum OverloadableOperator {
* *
* @throws NullPointerException if {@code expression} is {@code null}. * @throws NullPointerException if {@code expression} is {@code null}.
*/ */
public static OverloadableOperator fromBinaryExpression(IASTBinaryExpression expression) { public static OverloadableOperator fromBinaryExpression(int binaryOp) {
switch (expression.getOperator()) { switch (binaryOp) {
case IASTBinaryExpression.op_binaryAnd: return AMPER; case IASTBinaryExpression.op_binaryAnd: return AMPER;
case IASTBinaryExpression.op_binaryAndAssign: return AMPERASSIGN; case IASTBinaryExpression.op_binaryAndAssign: return AMPERASSIGN;
case IASTBinaryExpression.op_pmarrow: return ARROW; case IASTBinaryExpression.op_pmarrow: return ARROW;
@ -219,8 +219,8 @@ public enum OverloadableOperator {
return null; return null;
} }
public static OverloadableOperator fromUnaryExpression(IASTUnaryExpression expression) { public static OverloadableOperator fromUnaryExpression(int unaryOp) {
switch(expression.getOperator()) { switch(unaryOp) {
case IASTUnaryExpression.op_prefixIncr: return INCR; case IASTUnaryExpression.op_prefixIncr: return INCR;
case IASTUnaryExpression.op_prefixDecr: return DECR; case IASTUnaryExpression.op_prefixDecr: return DECR;
case IASTUnaryExpression.op_plus: return PLUS; case IASTUnaryExpression.op_plus: return PLUS;

View file

@ -224,11 +224,11 @@ public class AccessContext {
private ICPPClassType getFirstCandidateForNamingClass(IASTName name) throws DOMException { private ICPPClassType getFirstCandidateForNamingClass(IASTName name) throws DOMException {
LookupData data = new LookupData(name); LookupData data = new LookupData(name);
isUnqualifiedLookup= !data.qualified(); isUnqualifiedLookup= !data.qualified;
ICPPScope scope= CPPSemantics.getLookupScope(name, data); ICPPScope scope= CPPSemantics.getLookupScope(name);
while (scope != null && !(scope instanceof ICPPClassScope)) { while (scope != null && !(scope instanceof ICPPClassScope)) {
scope = CPPSemantics.getParentScope(scope, data.tu); scope = CPPSemantics.getParentScope(scope, data.getTranslationUnit());
} }
if (scope instanceof ICPPClassScope) { if (scope instanceof ICPPClassScope) {
return ((ICPPClassScope) scope).getClassType(); return ((ICPPClassScope) scope).getClassType();

View file

@ -26,7 +26,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
@ -41,7 +40,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
* from the graph. * from the graph.
*/ */
class BaseClassLookup { class BaseClassLookup {
public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope, IIndexFileSet fileSet) { public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope) {
if (classScope == null) if (classScope == null)
return; return;
@ -50,7 +49,7 @@ class BaseClassLookup {
return; return;
final HashMap<IScope, BaseClassLookup> infoMap = new HashMap<IScope, BaseClassLookup>(); final HashMap<IScope, BaseClassLookup> infoMap = new HashMap<IScope, BaseClassLookup>();
BaseClassLookup rootInfo= lookupInBaseClass(data, null, false, classType, fileSet, infoMap, 0); BaseClassLookup rootInfo= lookupInBaseClass(data, null, false, classType, infoMap, 0);
if (data.contentAssist) { if (data.contentAssist) {
rootInfo.collectResultForContentAssist(data); rootInfo.collectResultForContentAssist(data);
} else { } else {
@ -137,7 +136,7 @@ class BaseClassLookup {
} }
static BaseClassLookup lookupInBaseClass(LookupData data, ICPPClassScope baseClassScope, boolean isVirtual, static BaseClassLookup lookupInBaseClass(LookupData data, ICPPClassScope baseClassScope, boolean isVirtual,
ICPPClassType root, IIndexFileSet fileSet, HashMap<IScope, BaseClassLookup> infoMap, int depth) { ICPPClassType root, HashMap<IScope, BaseClassLookup> infoMap, int depth) {
if (depth++ > CPPSemantics.MAX_INHERITANCE_DEPTH) if (depth++ > CPPSemantics.MAX_INHERITANCE_DEPTH)
return null; return null;
@ -164,9 +163,9 @@ class BaseClassLookup {
result= new BaseClassLookup(baseClassScope.getClassType()); result= new BaseClassLookup(baseClassScope.getClassType());
infoMap.put(baseClassScope, result); infoMap.put(baseClassScope, result);
try { try {
IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, fileSet, data); IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, data);
if (members != null && members.length > 0 && members[0] != null) { if (members != null && members.length > 0 && members[0] != null) {
if (data.prefixLookup) { if (data.isPrefixLookup()) {
matches= members; matches= members;
} else { } else {
result.setResult(members); result.setResult(members);
@ -227,7 +226,7 @@ class BaseClassLookup {
continue; continue;
BaseClassLookup baseInfo= lookupInBaseClass(data, (ICPPClassScope) grandBaseScope, BaseClassLookup baseInfo= lookupInBaseClass(data, (ICPPClassScope) grandBaseScope,
grandBase.isVirtual(), root, fileSet, infoMap, depth); grandBase.isVirtual(), root, infoMap, depth);
if (baseInfo != null) if (baseInfo != null)
result.addBase(grandBase.isVirtual(), baseInfo); result.addBase(grandBase.isVirtual(), baseInfo);
} }
@ -335,7 +334,7 @@ class BaseClassLookup {
return result; return result;
} else { } else {
if (fCollectedAsRegularBase && data.problem == null && containsNonStaticMember()) { if (fCollectedAsRegularBase && data.problem == null && containsNonStaticMember()) {
data.problem= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP); data.problem= new ProblemBinding(data.getLookupName(), IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
} }
fCollectedAsRegularBase= true; fCollectedAsRegularBase= true;
} }
@ -356,7 +355,7 @@ class BaseClassLookup {
fBindings[numBindingsToAdd] = null; fBindings[numBindingsToAdd] = null;
if (result.length > 0 && numBindingsToAdd > 0 && data.problem == null) { if (result.length > 0 && numBindingsToAdd > 0 && data.problem == null) {
// Matches are found in more than one base class - this is an indication of ambiguity. // Matches are found in more than one base class - this is an indication of ambiguity.
data.problem= new ProblemBinding(data.astName, data.problem= new ProblemBinding(data.getLookupName(),
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, result); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, result);
} }
result= ArrayUtil.addAll(result, fBindings); result= ArrayUtil.addAll(result, fBindings);

View file

@ -10,7 +10,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeOrFunctionSet;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.ArrayList; import java.util.ArrayList;
@ -21,9 +20,7 @@ import java.util.Set;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
@ -48,6 +45,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
/** /**
@ -59,12 +57,12 @@ class BuiltinOperators {
private static final int SECOND = 1; private static final int SECOND = 1;
private static final IType PTR_DIFF = new CPPBasicType(Kind.eInt, 0); private static final IType PTR_DIFF = new CPPBasicType(Kind.eInt, 0);
public static ICPPFunction[] create(OverloadableOperator operator, IASTInitializerClause[] args, public static ICPPFunction[] create(OverloadableOperator operator, ICPPEvaluation[] args,
IASTTranslationUnit tu, Object[] globCandidates) { IASTNode point, Object[] globCandidates) {
if (operator == null || args == null || args.length == 0) if (operator == null || args == null || args.length == 0)
return EMPTY; return EMPTY;
return new BuiltinOperators(operator, args, tu.getScope(), globCandidates).create(); return new BuiltinOperators(operator, args, point, globCandidates).create();
} }
private final OverloadableOperator fOperator; private final OverloadableOperator fOperator;
@ -78,20 +76,20 @@ class BuiltinOperators {
private Set<String> fSignatures; private Set<String> fSignatures;
private Object[] fGlobalCandidates; private Object[] fGlobalCandidates;
BuiltinOperators(OverloadableOperator operator, IASTInitializerClause[] args, IScope fileScope, BuiltinOperators(OverloadableOperator operator, ICPPEvaluation[] args, IASTNode point,
Object[] globCandidates) { Object[] globCandidates) {
fFileScope= fileScope; fFileScope= point.getTranslationUnit().getScope();
fOperator= operator; fOperator= operator;
fUnary= args.length<2; fUnary= args.length<2;
fGlobalCandidates= globCandidates; fGlobalCandidates= globCandidates;
if (args.length > 0 && args[0] instanceof IASTExpression) { if (args.length > 0) {
IType type= typeOrFunctionSet((IASTExpression) args[0]); IType type= args[0].getTypeOrFunctionSet(point);
if (!(type instanceof ISemanticProblem)) if (!(type instanceof ISemanticProblem))
fType1= type; fType1= type;
} }
if (args.length > 1 && args[1] instanceof IASTExpression) { if (args.length > 1) {
IType type= typeOrFunctionSet((IASTExpression) args[1]); IType type= args[1].getTypeOrFunctionSet(point);
if (!(type instanceof ISemanticProblem)) if (!(type instanceof ISemanticProblem))
fType2= type; fType2= type;
} }

View file

@ -9,12 +9,15 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPTwoPhaseBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPTwoPhaseBinding;
/** /**
@ -23,10 +26,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPTwoPhaseBinding;
*/ */
public class CPPFunctionSet implements ICPPTwoPhaseBinding { public class CPPFunctionSet implements ICPPTwoPhaseBinding {
final ICPPFunction[] fBindings; private final ICPPFunction[] fBindings;
private final IASTName fName;
private final ICPPTemplateArgument[] fTemplateArguments;
public CPPFunctionSet(ICPPFunction[] bindingList) { public CPPFunctionSet(ICPPFunction[] bindingList, ICPPTemplateArgument[] args, IASTName name) {
fBindings = ArrayUtil.removeNulls(bindingList); fBindings = ArrayUtil.removeNulls(bindingList);
fTemplateArguments= args;
fName= name;
} }
@Override @Override
@ -60,10 +67,9 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding {
@Override @Override
public IBinding resolveFinalBinding(CPPASTNameBase astName) { public IBinding resolveFinalBinding(CPPASTNameBase astName) {
return CPPSemantics.resolveTargetedFunction(astName, fBindings); return CPPSemantics.resolveTargetedFunction(astName, this);
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
@ -71,4 +77,20 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding {
return this; return this;
return null; return null;
} }
public ICPPTemplateArgument[] getTemplateArguments() {
return fTemplateArguments;
}
public void applySelectedFunction(ICPPFunction selectedFunction) {
if (selectedFunction != null && fName != null) {
fName.setBinding(selectedFunction);
}
}
public void setToUnknown() {
if (fName != null) {
fName.setBinding(new CPPUnknownFunction(null, fName.toCharArray()));
}
}
} }

View file

@ -34,7 +34,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -58,7 +57,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -164,19 +162,19 @@ public class CPPTemplates {
/** /**
* Instantiates a class template with the given arguments. May return <code>null</code>. * Instantiates a class template with the given arguments. May return <code>null</code>.
*/ */
public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args) { public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args, IASTNode point) {
return instantiate(template, args, false, false); return instantiate(template, args, false, false, point);
} }
/** /**
* Instantiates a class template with the given arguments. May return <code>null</code>. * Instantiates a class template with the given arguments. May return <code>null</code>.
*/ */
private static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args, private static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args,
boolean isDefinition, boolean isExplicitSpecialization) { boolean isDefinition, boolean isExplicitSpecialization, IASTNode point) {
try { try {
// Add default arguments, if necessary. // Add default arguments, if necessary.
ICPPTemplateArgument[] arguments= SemanticUtil.getSimplifiedArguments(args); ICPPTemplateArgument[] arguments= SemanticUtil.getSimplifiedArguments(args);
arguments= addDefaultArguments(template, arguments); arguments= addDefaultArguments(template, arguments, point);
if (arguments == null) if (arguments == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
@ -185,7 +183,7 @@ public class CPPTemplates {
} }
if (template instanceof ICPPClassTemplatePartialSpecialization) { if (template instanceof ICPPClassTemplatePartialSpecialization) {
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null); return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null, point);
} }
final ICPPTemplateParameter[] parameters= template.getTemplateParameters(); final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
@ -208,7 +206,7 @@ public class CPPTemplates {
} }
if (i < numArgs) { if (i < numArgs) {
ICPPTemplateArgument arg= arguments[i]; ICPPTemplateArgument arg= arguments[i];
ICPPTemplateArgument newArg = CPPTemplates.matchTemplateParameterAndArgument(param, arg, map); ICPPTemplateArgument newArg = CPPTemplates.matchTemplateParameterAndArgument(param, arg, map, point);
if (newArg == null) if (newArg == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
if (newArg != arg) { if (newArg != arg) {
@ -239,12 +237,12 @@ public class CPPTemplates {
return prim; return prim;
if (!isExplicitSpecialization) { if (!isExplicitSpecialization) {
IBinding result= CPPTemplates.selectSpecialization(template, arguments, isDefinition); IBinding result= CPPTemplates.selectSpecialization(template, arguments, isDefinition, point);
if (result != null) if (result != null)
return result; return result;
} }
return instantiatePrimaryTemplate(template, arguments, map, isDefinition); return instantiatePrimaryTemplate(template, arguments, map, isDefinition, point);
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }
@ -308,24 +306,25 @@ public class CPPTemplates {
} }
private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template,
ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map) throws DOMException { ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map, IASTNode point) throws DOMException {
ICPPTemplateInstance instance= getInstance(template, arguments, false); ICPPTemplateInstance instance= getInstance(template, arguments, false);
if (instance != null) { if (instance != null) {
return instance; return instance;
} }
IBinding owner= template.getOwner(); IBinding owner= template.getOwner();
instance = CPPTemplates.createInstance(owner, template, map, arguments); instance = CPPTemplates.createInstance(owner, template, map, arguments, point);
addInstance(template, arguments, instance); addInstance(template, arguments, instance);
return instance; return instance;
} }
/** /**
* Instantiates a partial class template specialization. * Instantiates a partial class template specialization.
* @param point
*/ */
private static IBinding instantiatePartialSpecialization( private static IBinding instantiatePartialSpecialization(
ICPPClassTemplatePartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef, ICPPClassTemplatePartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef,
CPPTemplateParameterMap tpMap) throws DOMException { CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef); ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef);
if (instance != null) if (instance != null)
return instance; return instance;
@ -333,11 +332,11 @@ public class CPPTemplates {
if (tpMap == null) { if (tpMap == null) {
tpMap = new CPPTemplateParameterMap(args.length); tpMap = new CPPTemplateParameterMap(args.length);
if (!TemplateArgumentDeduction.fromTemplateArguments(partialSpec.getTemplateParameters(), if (!TemplateArgumentDeduction.fromTemplateArguments(partialSpec.getTemplateParameters(),
partialSpec.getTemplateArguments(), args, tpMap)) partialSpec.getTemplateArguments(), args, tpMap, point))
return null; return null;
} }
instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args); instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args, point);
addInstance(partialSpec, args, instance); addInstance(partialSpec, args, instance);
return instance; return instance;
} }
@ -347,7 +346,7 @@ public class CPPTemplates {
* @param map * @param map
*/ */
private static IBinding instantiatePrimaryTemplate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, private static IBinding instantiatePrimaryTemplate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments,
CPPTemplateParameterMap map, boolean isDef) throws DOMException { CPPTemplateParameterMap map, boolean isDef, IASTNode point) throws DOMException {
assert !(template instanceof ICPPClassTemplatePartialSpecialization); assert !(template instanceof ICPPClassTemplatePartialSpecialization);
ICPPTemplateInstance instance= getInstance(template, arguments, isDef); ICPPTemplateInstance instance= getInstance(template, arguments, isDef);
@ -356,7 +355,7 @@ public class CPPTemplates {
} }
IBinding owner= template.getOwner(); IBinding owner= template.getOwner();
instance = CPPTemplates.createInstance(owner, template, map, arguments); instance = CPPTemplates.createInstance(owner, template, map, arguments, point);
addInstance(template, arguments, instance); addInstance(template, arguments, instance);
return instance; return instance;
} }
@ -395,7 +394,7 @@ public class CPPTemplates {
} }
private static ICPPTemplateArgument[] addDefaultArguments(ICPPClassTemplate template, private static ICPPTemplateArgument[] addDefaultArguments(ICPPClassTemplate template,
ICPPTemplateArgument[] arguments) throws DOMException { ICPPTemplateArgument[] arguments, IASTNode point) throws DOMException {
if (template instanceof ICPPClassTemplatePartialSpecialization) if (template instanceof ICPPClassTemplatePartialSpecialization)
return arguments; return arguments;
@ -461,7 +460,7 @@ public class CPPTemplates {
} }
if (defaultArg == null) if (defaultArg == null)
return null; return null;
arg= instantiateArgument(defaultArg, map, -1, null); arg= instantiateArgument(defaultArg, map, -1, null, point);
arg= SemanticUtil.getSimplifiedArgument(arg); arg= SemanticUtil.getSimplifiedArgument(arg);
if (!isValidArgument(arg)) { if (!isValidArgument(arg)) {
return null; return null;
@ -672,7 +671,7 @@ public class CPPTemplates {
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) { if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
result= classTemplate; result= classTemplate;
} else { } else {
args= addDefaultArguments(classTemplate, args); args= addDefaultArguments(classTemplate, args, id);
if (args == null) { if (args == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray()); return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
} }
@ -692,7 +691,7 @@ public class CPPTemplates {
} }
} }
if (result == null) { if (result == null) {
result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization); result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization, id);
if (result instanceof ICPPInternalBinding) { if (result instanceof ICPPInternalBinding) {
if (isDeclaration) { if (isDeclaration) {
ASTInternal.addDeclaration(result, id); ASTInternal.addDeclaration(result, id);
@ -731,7 +730,7 @@ public class CPPTemplates {
public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template, public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template,
CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args) { CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args, IASTNode point) {
if (owner instanceof ICPPSpecialization) { if (owner instanceof ICPPSpecialization) {
ICPPTemplateParameterMap map= ((ICPPSpecialization) owner).getTemplateParameterMap(); ICPPTemplateParameterMap map= ((ICPPSpecialization) owner).getTemplateParameterMap();
if (map != null) { if (map != null) {
@ -742,26 +741,36 @@ public class CPPTemplates {
ICPPTemplateInstance instance = null; ICPPTemplateInstance instance = null;
if (template instanceof ICPPClassType) { if (template instanceof ICPPClassType) {
instance = new CPPClassInstance((ICPPClassType) template, owner, tpMap, args); instance = new CPPClassInstance((ICPPClassType) template, owner, tpMap, args);
} else if (owner instanceof ICPPClassType && template instanceof ICPPMethod) {
if (template instanceof ICPPConstructor) {
instance = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args);
} else {
instance = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args);
}
} else if (template instanceof ICPPFunction) { } else if (template instanceof ICPPFunction) {
instance = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args); ICPPFunction func= (ICPPFunction) template;
ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPFunctionType type= (ICPPFunctionType) CPPTemplates.instantiateType(func.getType(), tpMap, -1, within, point);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point);
if (owner instanceof ICPPClassType && template instanceof ICPPMethod) {
if (template instanceof ICPPConstructor) {
instance = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs);
} else {
instance = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs);
}
} else {
instance = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args, type, exceptionSpecs);
}
} }
return instance; return instance;
} }
public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl) { public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl, IASTNode point) {
IBinding spec = null; IBinding spec = null;
final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap(); final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap();
if (decl instanceof ICPPClassTemplatePartialSpecialization) { if (decl instanceof ICPPClassTemplatePartialSpecialization) {
try { try {
final ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl; ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl;
ICPPClassTemplate template= (ICPPClassTemplate) owner.specializeMember(pspec.getPrimaryClassTemplate()); ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, template, tpMap); ICPPTemplateArgument[] args = pspec.getTemplateArguments();
template= (ICPPClassTemplate) owner.specializeMember(template, point);
args= CPPTemplates.instantiateArguments(args, tpMap, -1, within, point);
spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args);
} catch (DOMException e) { } catch (DOMException e) {
} }
} else if (decl instanceof ICPPClassTemplate) { } else if (decl instanceof ICPPClassTemplate) {
@ -774,33 +783,82 @@ public class CPPTemplates {
spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap); spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap);
} }
} else if (decl instanceof ICPPField) { } else if (decl instanceof ICPPField) {
spec = new CPPFieldSpecialization(decl, owner, tpMap); final ICPPClassSpecialization within = getSpecializationContext(owner);
} else if (decl instanceof ICPPFunctionTemplate) { ICPPField field= (ICPPField) decl;
if (decl instanceof ICPPConstructor) IType type= CPPTemplates.instantiateType(field.getType(), tpMap, -1, within, point);
spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap); IValue value= CPPTemplates.instantiateValue(field.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point);
else if (decl instanceof ICPPMethod) spec = new CPPFieldSpecialization(decl, owner, tpMap, type, value);
spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap);
else
spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap);
} else if (decl instanceof ICPPConstructor) {
spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap);
} else if (decl instanceof ICPPMethod) {
spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap);
} else if (decl instanceof ICPPFunction) { } else if (decl instanceof ICPPFunction) {
IBinding oldOwner = decl.getOwner(); ICPPFunction func= (ICPPFunction) decl;
spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, owner); ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPFunctionType type= (ICPPFunctionType) CPPTemplates.instantiateType(func.getType(), tpMap, -1, within, point);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point);
if (decl instanceof ICPPFunctionTemplate) {
if (decl instanceof ICPPConstructor)
spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
else if (decl instanceof ICPPMethod)
spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs);
else
spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap, type, exceptionSpecs);
} else if (decl instanceof ICPPConstructor) {
spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
} else if (decl instanceof ICPPMethod) {
spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs);
} else if (decl instanceof ICPPFunction) {
IBinding oldOwner = decl.getOwner();
spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs);
}
} else if (decl instanceof ITypedef) { } else if (decl instanceof ITypedef) {
spec = new CPPTypedefSpecialization(decl, owner, tpMap); IType type= CPPTemplates.instantiateType(((ITypedef) decl).getType(), tpMap, -1, getSpecializationContext(owner), point);
spec = new CPPTypedefSpecialization(decl, owner, tpMap, type);
} else if (decl instanceof IEnumeration || decl instanceof IEnumerator) { } else if (decl instanceof IEnumeration || decl instanceof IEnumerator) {
// TODO(sprigogin): Deal with a case when an enumerator value depends on a template parameter. // TODO(sprigogin): Deal with a case when an enumerator value depends on a template parameter.
spec = decl; spec = decl;
} else if (decl instanceof ICPPUsingDeclaration) { } else if (decl instanceof ICPPUsingDeclaration) {
spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap); IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates();
List<IBinding> result= new ArrayList<IBinding>();
ICPPClassSpecialization within = getSpecializationContext(owner);
for (IBinding delegate : delegates) {
try {
if (delegate instanceof ICPPUnknownBinding) {
delegate= CPPTemplates.resolveUnknown((ICPPUnknownBinding) delegate, tpMap, -1, within, point);
}
if (delegate instanceof CPPFunctionSet) {
for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) {
result.add(b);
}
} else if (delegate != null) {
result.add(delegate);
}
} catch (DOMException e) {
}
}
delegates= result.toArray(new IBinding[result.size()]);
spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap, delegates);
} }
return spec; return spec;
} }
public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth) { private static ICPPClassSpecialization getSpecializationContext(IBinding owner) {
if (!(owner instanceof ICPPClassSpecialization))
return null;
ICPPClassSpecialization within= (ICPPClassSpecialization) owner;
ICPPClassType orig = within.getSpecializedBinding();
for(;;) {
IBinding o1 = within.getOwner();
IBinding o2 = orig.getOwner();
if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType))
return within;
ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1;
orig= (ICPPClassType) o2;
if (orig.isSameType(nextWithin))
return within;
within= nextWithin;
}
}
public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) {
if (value == null) if (value == null)
return null; return null;
IBinding[] unknowns= value.getUnknownBindings(); IBinding[] unknowns= value.getUnknownBindings();
@ -811,7 +869,7 @@ public class CPPTemplates {
IBinding resolved= unknown; IBinding resolved= unknown;
if (unknown instanceof ICPPUnknownBinding) { if (unknown instanceof ICPPUnknownBinding) {
try { try {
resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within); resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within, point);
} catch (DOMException e) { } catch (DOMException e) {
return Value.UNKNOWN; return Value.UNKNOWN;
} }
@ -945,9 +1003,13 @@ public class CPPTemplates {
* Instantiates types contained in an array. * Instantiates types contained in an array.
* @param types an array of types * @param types an array of types
* @param tpMap template argument map * @param tpMap template argument map
* @param point
* @return an array containing instantiated types. * @return an array containing instantiated types.
*/ */
public static IType[] instantiateTypes(IType[] types, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) { public static IType[] instantiateTypes(IType[] types, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
if (types == null)
return null;
// Don't create a new array until it's really needed. // Don't create a new array until it's really needed.
IType[] result = types; IType[] result = types;
int j= 0; int j= 0;
@ -966,12 +1028,12 @@ public class CPPTemplates {
System.arraycopy(result, 0, newResult, 0, j); System.arraycopy(result, 0, newResult, 0, j);
result= newResult; result= newResult;
for(int k=0; k<packSize; k++) { for(int k=0; k<packSize; k++) {
result[j++]= CPPTemplates.instantiateType(origType, tpMap, k, within); result[j++]= CPPTemplates.instantiateType(origType, tpMap, k, within, point);
} }
continue; continue;
} }
} else { } else {
newType = CPPTemplates.instantiateType(origType, tpMap, packOffset, within); newType = CPPTemplates.instantiateType(origType, tpMap, packOffset, within, point);
} }
if (result != types) { if (result != types) {
result[j++]= newType; result[j++]= newType;
@ -989,9 +1051,10 @@ public class CPPTemplates {
/** /**
* Instantiates arguments contained in an array. * Instantiates arguments contained in an array.
* @param point
*/ */
public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args, public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point)
throws DOMException { throws DOMException {
// Don't create a new array until it's really needed. // Don't create a new array until it's really needed.
ICPPTemplateArgument[] result = args; ICPPTemplateArgument[] result = args;
@ -1011,14 +1074,14 @@ public class CPPTemplates {
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift]; ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i+resultShift); System.arraycopy(result, 0, newResult, 0, i+resultShift);
for(int j=0; j<packSize; j++) { for(int j=0; j<packSize; j++) {
newResult[i+resultShift+j]= CPPTemplates.instantiateArgument(origArg, tpMap, j, within); newResult[i+resultShift+j]= CPPTemplates.instantiateArgument(origArg, tpMap, j, within, point);
} }
result= newResult; result= newResult;
resultShift+= shift; resultShift+= shift;
continue; continue;
} }
} else { } else {
newArg = CPPTemplates.instantiateArgument(origArg, tpMap, packOffset, within); newArg = CPPTemplates.instantiateArgument(origArg, tpMap, packOffset, within, point);
} }
if (result != args) { if (result != args) {
result[i+resultShift]= newArg; result[i+resultShift]= newArg;
@ -1036,41 +1099,42 @@ public class CPPTemplates {
/** /**
* Instantiates an argument * Instantiates an argument
* @param point
*/ */
static ICPPTemplateArgument instantiateArgument(ICPPTemplateArgument arg, static ICPPTemplateArgument instantiateArgument(ICPPTemplateArgument arg,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) { ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
if (arg == null) if (arg == null)
return null; return null;
if (arg.isNonTypeValue()) { if (arg.isNonTypeValue()) {
final IValue origValue= arg.getNonTypeValue(); final IValue origValue= arg.getNonTypeValue();
final IType origType= arg.getTypeOfNonTypeValue(); final IType origType= arg.getTypeOfNonTypeValue();
final IValue instValue= instantiateValue(origValue, tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH); final IValue instValue= instantiateValue(origValue, tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
final IType instType= instantiateType(origType, tpMap, packOffset, within); final IType instType= instantiateType(origType, tpMap, packOffset, within, point);
if (origType == instType && origValue == instValue) if (origType == instType && origValue == instValue)
return arg; return arg;
return new CPPTemplateArgument(instValue, instType); return new CPPTemplateArgument(instValue, instType);
} }
final IType orig= arg.getTypeValue(); final IType orig= arg.getTypeValue();
final IType inst= instantiateType(orig, tpMap, packOffset, within); final IType inst= instantiateType(orig, tpMap, packOffset, within, point);
if (orig == inst) if (orig == inst)
return arg; return arg;
return new CPPTemplateArgument(inst); return new CPPTemplateArgument(inst);
} }
private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig, ICPPTemplateParameterMap tpMap, private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPClassSpecialization within) { int packOffset, ICPPClassSpecialization within, IASTNode point) {
final Integer[] positions = orig.getAllParameterPositions(); final Integer[] positions = orig.getAllParameterPositions();
CPPTemplateParameterMap newMap= new CPPTemplateParameterMap(positions.length); CPPTemplateParameterMap newMap= new CPPTemplateParameterMap(positions.length);
for (Integer key : positions) { for (Integer key : positions) {
ICPPTemplateArgument arg = orig.getArgument(key); ICPPTemplateArgument arg = orig.getArgument(key);
if (arg != null) { if (arg != null) {
newMap.put(key, instantiateArgument(arg, tpMap, packOffset, within)); newMap.put(key, instantiateArgument(arg, tpMap, packOffset, within, point));
} else { } else {
ICPPTemplateArgument[] args = orig.getPackExpansion(key); ICPPTemplateArgument[] args = orig.getPackExpansion(key);
if (args != null) { if (args != null) {
try { try {
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within)); newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point));
} catch (DOMException e) { } catch (DOMException e) {
newMap.put(key, args); newMap.put(key, args);
} }
@ -1083,9 +1147,10 @@ public class CPPTemplates {
/** /**
* Instantiates the given type with the provided map and packoffset. * Instantiates the given type with the provided map and packoffset.
* The context is used to replace templates with their specialization, where appropriate. * The context is used to replace templates with their specialization, where appropriate.
* @param point
*/ */
public static IType instantiateType(IType type, ICPPTemplateParameterMap tpMap, int packOffset, public static IType instantiateType(IType type, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within) { ICPPClassSpecialization within, IASTNode point) {
try { try {
if (tpMap == null) if (tpMap == null)
return type; return type;
@ -1095,9 +1160,9 @@ public class CPPTemplates {
IType ret = null; IType ret = null;
IType[] params = null; IType[] params = null;
final IType r = ft.getReturnType(); final IType r = ft.getReturnType();
ret = instantiateType(r, tpMap, packOffset, within); ret = instantiateType(r, tpMap, packOffset, within, point);
IType[] ps = ft.getParameterTypes(); IType[] ps = ft.getParameterTypes();
params = instantiateTypes(ps, tpMap, packOffset, within); params = instantiateTypes(ps, tpMap, packOffset, within, point);
if (ret == r && params == ps) { if (ret == r && params == ps) {
return type; return type;
} }
@ -1137,7 +1202,7 @@ public class CPPTemplates {
} }
if (type instanceof ICPPUnknownBinding) { if (type instanceof ICPPUnknownBinding) {
IBinding binding= resolveUnknown((ICPPUnknownBinding) type, tpMap, packOffset, within); IBinding binding= resolveUnknown((ICPPUnknownBinding) type, tpMap, packOffset, within, point);
if (binding instanceof IType) if (binding instanceof IType)
return (IType) binding; return (IType) binding;
@ -1161,11 +1226,11 @@ public class CPPTemplates {
// another binding, to the more specialized version. // another binding, to the more specialized version.
newOwner= within; newOwner= within;
} else { } else {
newOwner= instantiateType(ownerAsType, tpMap, packOffset, within); newOwner= instantiateType(ownerAsType, tpMap, packOffset, within, point);
} }
if (newOwner != owner && newOwner instanceof ICPPClassSpecialization) { if (newOwner != owner && newOwner instanceof ICPPClassSpecialization) {
return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding); return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding, point);
} }
} }
@ -1175,9 +1240,9 @@ public class CPPTemplates {
final IBinding origClass = classInstance.getSpecializedBinding(); final IBinding origClass = classInstance.getSpecializedBinding();
if (origClass instanceof ICPPClassType) { if (origClass instanceof ICPPClassType) {
ICPPTemplateArgument[] args = classInstance.getTemplateArguments(); ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within); ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point);
if (newArgs != args) { if (newArgs != args) {
CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within); CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(), tpMap, packOffset, within, point);
return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args); return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args);
} }
} }
@ -1187,11 +1252,11 @@ public class CPPTemplates {
if (type instanceof ITypeContainer) { if (type instanceof ITypeContainer) {
final ITypeContainer typeContainer = (ITypeContainer) type; final ITypeContainer typeContainer = (ITypeContainer) type;
IType nestedType = typeContainer.getType(); IType nestedType = typeContainer.getType();
IType newNestedType = instantiateType(nestedType, tpMap, packOffset, within); IType newNestedType = instantiateType(nestedType, tpMap, packOffset, within, point);
if (typeContainer instanceof ICPPPointerToMemberType) { if (typeContainer instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer; ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer;
IType memberOfClass = ptm.getMemberOfClass(); IType memberOfClass = ptm.getMemberOfClass();
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within); IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within, point);
if (newMemberOfClass instanceof IQualifierType) { if (newMemberOfClass instanceof IQualifierType) {
newMemberOfClass = ((IQualifierType) newMemberOfClass).getType(); newMemberOfClass = ((IQualifierType) newMemberOfClass).getType();
} }
@ -1209,7 +1274,7 @@ public class CPPTemplates {
IArrayType at= (IArrayType) typeContainer; IArrayType at= (IArrayType) typeContainer;
IValue asize= at.getSize(); IValue asize= at.getSize();
if (asize != null) { if (asize != null) {
IValue newSize= instantiateValue(asize, tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH); IValue newSize= instantiateValue(asize, tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
if (newSize != asize) { if (newSize != asize) {
return new CPPArrayType(newNestedType, newSize); return new CPPArrayType(newNestedType, newSize);
} }
@ -1653,15 +1718,10 @@ public class CPPTemplates {
return result; return result;
} }
static ICPPFunction[] instantiateForFunctionCall(IASTName name, ICPPFunction[] fns, static ICPPFunction[] instantiateForFunctionCall(ICPPFunction[] fns, ICPPTemplateArgument[] tmplArgs,
List<IType> fnArgs, List<ValueCategory> argCats, boolean withImpliedObjectArg) { List<IType> fnArgs, List<ValueCategory> argCats, boolean withImpliedObjectArg, IASTNode point) {
if (name != null && name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
name= (IASTName) name.getParent();
}
// Extract template arguments. // Extract template arguments.
ICPPTemplateArgument[] tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS; boolean requireTemplate= tmplArgs != null;
boolean requireTemplate= name instanceof ICPPASTTemplateId;
boolean haveTemplate= false; boolean haveTemplate= false;
for (final ICPPFunction func : fns) { for (final ICPPFunction func : fns) {
@ -1675,7 +1735,6 @@ public class CPPTemplates {
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)}; return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
if (requireTemplate) { if (requireTemplate) {
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
if (hasDependentArgument(tmplArgs)) if (hasDependentArgument(tmplArgs))
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)}; return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
} }
@ -1695,7 +1754,7 @@ public class CPPTemplates {
if (fn != null) { if (fn != null) {
if (fn instanceof ICPPFunctionTemplate) { if (fn instanceof ICPPFunctionTemplate) {
ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn; ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn;
ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, withImpliedObjectArg); ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, withImpliedObjectArg, point);
if (inst != null) if (inst != null)
result.add(inst); result.add(inst);
} else if (!requireTemplate || fn instanceof ICPPUnknownBinding) { } else if (!requireTemplate || fn instanceof ICPPUnknownBinding) {
@ -1708,7 +1767,7 @@ public class CPPTemplates {
private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template, private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argCats, ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argCats,
boolean withImpliedObjectArg) { boolean withImpliedObjectArg, IASTNode point) {
if (withImpliedObjectArg && template instanceof ICPPMethod) { if (withImpliedObjectArg && template instanceof ICPPMethod) {
fnArgs= fnArgs.subList(1, fnArgs.size()); fnArgs= fnArgs.subList(1, fnArgs.size());
argCats= argCats.subList(1, argCats.size()); argCats= argCats.subList(1, argCats.size());
@ -1716,9 +1775,9 @@ public class CPPTemplates {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.size()); CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.size());
try { try {
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map); ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map, point);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map); IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
final ICPPFunction f = (ICPPFunction) instance; final ICPPFunction f = (ICPPFunction) instance;
if (isValidType(f.getType())) if (isValidType(f.getType()))
@ -1732,8 +1791,9 @@ public class CPPTemplates {
/** /**
* 14.8.2.3 Deducing conversion function template arguments * 14.8.2.3 Deducing conversion function template arguments
* @param point
*/ */
static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType) { static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType, IASTNode point) {
boolean checkedForDependentType= false; boolean checkedForDependentType= false;
ICPPFunction[] result= functions; ICPPFunction[] result= functions;
int i=0; int i=0;
@ -1758,9 +1818,9 @@ public class CPPTemplates {
} }
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
try { try {
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map); ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map, point);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map); IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
inst= (ICPPFunction) instance; inst= (ICPPFunction) instance;
} }
@ -1784,15 +1844,16 @@ public class CPPTemplates {
/** /**
* 14.8.2.6 Deducing template arguments from a function declaration * 14.8.2.6 Deducing template arguments from a function declaration
* @param point
* @return * @return
*/ */
static ICPPFunction instantiateForFunctionDeclaration(ICPPFunctionTemplate template, static ICPPFunction instantiateForFunctionDeclaration(ICPPFunctionTemplate template,
ICPPTemplateArgument[] args, ICPPFunctionType functionType) { ICPPTemplateArgument[] args, ICPPFunctionType functionType, IASTNode point) {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
try { try {
args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map); args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map, point);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map); IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
return (ICPPFunction) instance; return (ICPPFunction) instance;
} }
@ -1807,29 +1868,20 @@ public class CPPTemplates {
/** /**
* 14.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr] * 14.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr]
*/ */
static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target, IASTName name) { static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target,
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { ICPPTemplateArgument[] args, IASTNode point) {
name= (IASTName) name.getParent();
}
try { try {
if (target != null && isDependentType(target)) { if (target != null && isDependentType(target)) {
return CPPUnknownFunction.createForSample(template); return CPPUnknownFunction.createForSample(template);
} }
ICPPTemplateArgument[] tmplArgs; if (template instanceof ICPPConstructor || args == null)
if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) { args= ICPPTemplateArgument.EMPTY_ARGUMENTS;
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
if (hasDependentArgument(tmplArgs)) {
return CPPUnknownFunction.createForSample(template);
}
} else {
tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS;
}
CPPTemplateParameterMap map= new CPPTemplateParameterMap(4); CPPTemplateParameterMap map= new CPPTemplateParameterMap(4);
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForAddressOf(template, tmplArgs, target, map); args= TemplateArgumentDeduction.deduceForAddressOf(template, args, target, map, point);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map); IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
return (ICPPFunction) instance; return (ICPPFunction) instance;
} }
@ -1840,7 +1892,7 @@ public class CPPTemplates {
} }
// 14.5.6.2 Partial ordering of function templates // 14.5.6.2 Partial ordering of function templates
static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode) static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point)
throws DOMException { throws DOMException {
if (f1 == f2) if (f1 == f2)
return 0; return 0;
@ -1849,8 +1901,8 @@ public class CPPTemplates {
if (f2 == null) if (f2 == null)
return 1; return 1;
int s1 = compareSpecialization(f1, f2, mode); int s1 = compareSpecialization(f1, f2, mode, point);
int s2 = compareSpecialization(f2, f1, mode); int s2 = compareSpecialization(f2, f1, mode, point);
if (s1 == s2) if (s1 == s2)
return 0; return 0;
@ -1860,7 +1912,7 @@ public class CPPTemplates {
return 1; return 1;
} }
private static ICPPFunction transferFunctionTemplate(ICPPFunctionTemplate f) throws DOMException { private static ICPPFunction transferFunctionTemplate(ICPPFunctionTemplate f, IASTNode point) throws DOMException {
final ICPPTemplateParameter[] tpars = f.getTemplateParameters(); final ICPPTemplateParameter[] tpars = f.getTemplateParameters();
final int argLen = tpars.length; final int argLen = tpars.length;
@ -1878,7 +1930,7 @@ public class CPPTemplates {
} }
} }
IBinding result = instantiateFunctionTemplate(f, args, map); IBinding result = instantiateFunctionTemplate(f, args, map, point);
if (result instanceof ICPPFunction) if (result instanceof ICPPFunction)
return (ICPPFunction) result; return (ICPPFunction) result;
@ -1895,8 +1947,8 @@ public class CPPTemplates {
return arg; return arg;
} }
private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode) throws DOMException { private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point) throws DOMException {
ICPPFunction transF1 = transferFunctionTemplate(f1); ICPPFunction transF1 = transferFunctionTemplate(f1, point);
if (transF1 == null) if (transF1 == null)
return -1; return -1;
@ -1928,7 +1980,7 @@ public class CPPTemplates {
} }
break; break;
} }
return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args); return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args, point);
} }
private static boolean isNonStaticMember(ICPPFunctionTemplate f) { private static boolean isNonStaticMember(ICPPFunctionTemplate f) {
@ -1965,7 +2017,7 @@ public class CPPTemplates {
} }
private static IBinding selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args, private static IBinding selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args,
boolean isDef) throws DOMException { boolean isDef, IASTNode point) throws DOMException {
if (template == null) { if (template == null) {
return null; return null;
} }
@ -1980,8 +2032,8 @@ public class CPPTemplates {
for (ICPPClassTemplatePartialSpecialization specialization : specializations) { for (ICPPClassTemplatePartialSpecialization specialization : specializations) {
spec = specialization; spec = specialization;
final CPPTemplateParameterMap map = new CPPTemplateParameterMap(args.length); final CPPTemplateParameterMap map = new CPPTemplateParameterMap(args.length);
if (TemplateArgumentDeduction.fromTemplateArguments(spec.getTemplateParameters(), spec.getTemplateArguments(), args, map)) { if (TemplateArgumentDeduction.fromTemplateArguments(spec.getTemplateParameters(), spec.getTemplateArguments(), args, map, point)) {
int compare = orderSpecializations(bestMatch, spec); int compare = orderSpecializations(bestMatch, spec, point);
if (compare == 0) { if (compare == 0) {
bestMatchIsBest = false; bestMatchIsBest = false;
} else if (compare < 0) { } else if (compare < 0) {
@ -2001,7 +2053,7 @@ public class CPPTemplates {
if (bestMatch == null) if (bestMatch == null)
return null; return null;
return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap); return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap, point);
} }
/** /**
@ -2009,10 +2061,11 @@ public class CPPTemplates {
* is more specialized, = 0 otherwise. * is more specialized, = 0 otherwise.
* @param spec1 * @param spec1
* @param spec2 * @param spec2
* @param point
* @return * @return
* @throws DOMException * @throws DOMException
*/ */
static private int orderSpecializations(ICPPClassTemplatePartialSpecialization spec1, ICPPClassTemplatePartialSpecialization spec2) throws DOMException { static private int orderSpecializations(ICPPClassTemplatePartialSpecialization spec1, ICPPClassTemplatePartialSpecialization spec2, IASTNode point) throws DOMException {
if (spec1 == null) { if (spec1 == null) {
return -1; return -1;
} }
@ -2023,8 +2076,8 @@ public class CPPTemplates {
// 14.5.5.2 // 14.5.5.2
// A template is more specialized than another if and only if it is at least as specialized as the // A template is more specialized than another if and only if it is at least as specialized as the
// other template and that template is not at least as specialized as the first. // other template and that template is not at least as specialized as the first.
boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2); boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2, point);
boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1); boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1, point);
if (f1IsAtLeastAsSpecializedAsF2 == f2IsAtLeastAsSpecializedAsF1) if (f1IsAtLeastAsSpecializedAsF2 == f2IsAtLeastAsSpecializedAsF1)
return 0; return 0;
@ -2035,7 +2088,7 @@ public class CPPTemplates {
return -1; return -1;
} }
private static boolean isAtLeastAsSpecializedAs(ICPPClassTemplatePartialSpecialization f1, ICPPClassTemplatePartialSpecialization f2) throws DOMException { private static boolean isAtLeastAsSpecializedAs(ICPPClassTemplatePartialSpecialization f1, ICPPClassTemplatePartialSpecialization f2, IASTNode point) throws DOMException {
// 14.5.5.2 // 14.5.5.2
// Using the transformed parameter list, perform argument deduction against the other // Using the transformed parameter list, perform argument deduction against the other
// function template // function template
@ -2058,16 +2111,16 @@ public class CPPTemplates {
args[i]= arg; args[i]= arg;
transferMap.put(param, arg); transferMap.put(param, arg);
} }
final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null); final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point);
// Deduce arguments for specialization 2 // Deduce arguments for specialization 2
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2); final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap)) if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point))
return false; return false;
// Compare // Compare
for (int i = 0; i < targs2.length; i++) { for (int i = 0; i < targs2.length; i++) {
ICPPTemplateArgument transferredArg2= instantiateArgument(targs2[i], deductionMap, -1, null); ICPPTemplateArgument transferredArg2= instantiateArgument(targs2[i], deductionMap, -1, null, point);
if (!transferredArg2.isSameValue(transferredArgs1[i])) if (!transferredArg2.isSameValue(transferredArgs1[i]))
return false; return false;
} }
@ -2103,7 +2156,7 @@ public class CPPTemplates {
} }
static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param, static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param,
ICPPTemplateArgument arg, CPPTemplateParameterMap map) { ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) {
if (arg == null || !isValidType(arg.getTypeValue())) { if (arg == null || !isValidType(arg.getTypeValue())) {
return null; return null;
} }
@ -2150,9 +2203,9 @@ public class CPPTemplates {
pType= ((ICPPParameterPackType) pType).getType(); pType= ((ICPPParameterPackType) pType).getType();
} }
if (map != null && pType != null) { if (map != null && pType != null) {
pType= instantiateType(pType, map, -1, null); pType= instantiateType(pType, map, -1, null, point);
} }
if (argType instanceof ICPPUnknownType || argType instanceof ISemanticProblem || isNonTypeArgumentConvertible(pType, argType)) { if (argType instanceof ICPPUnknownType || argType instanceof ISemanticProblem || isNonTypeArgumentConvertible(pType, argType, point)) {
return new CPPTemplateArgument(arg.getNonTypeValue(), pType); return new CPPTemplateArgument(arg.getNonTypeValue(), pType);
} }
return null; return null;
@ -2226,14 +2279,14 @@ public class CPPTemplates {
* @return * @return
* @throws DOMException * @throws DOMException
*/ */
private static boolean isNonTypeArgumentConvertible(IType paramType, IType arg) throws DOMException { private static boolean isNonTypeArgumentConvertible(IType paramType, IType arg, IASTNode point) throws DOMException {
//14.1s8 function to pointer and array to pointer conversions //14.1s8 function to pointer and array to pointer conversions
if (paramType instanceof IFunctionType) { if (paramType instanceof IFunctionType) {
paramType = new CPPPointerType(paramType); paramType = new CPPPointerType(paramType);
} else if (paramType instanceof IArrayType) { } else if (paramType instanceof IArrayType) {
paramType = new CPPPointerType(((IArrayType) paramType).getType()); paramType = new CPPPointerType(((IArrayType) paramType).getType());
} }
Cost cost = Conversions.checkImplicitConversionSequence(paramType, arg, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY); Cost cost = Conversions.checkImplicitConversionSequence(paramType, arg, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY, point);
return cost != null && cost.converts(); return cost != null && cost.converts();
} }
@ -2326,7 +2379,7 @@ public class CPPTemplates {
} }
t= ((ITypeContainer) t).getType(); t= ((ITypeContainer) t).getType();
} else if (t instanceof InitializerListType) { } else if (t instanceof InitializerListType) {
return isDependentInitializerList(((InitializerListType) t).getInitializerList()); return ((InitializerListType) t).getEvaluation().isTypeDependent();
} else if (t instanceof IBinding) { } else if (t instanceof IBinding) {
IBinding owner = ((IBinding) t).getOwner(); IBinding owner = ((IBinding) t).getOwner();
if (owner instanceof ICPPClassTemplate) if (owner instanceof ICPPClassTemplate)
@ -2338,21 +2391,6 @@ public class CPPTemplates {
} }
} }
private static boolean isDependentInitializerList(ICPPASTInitializerList initializerList) {
IASTInitializerClause[] clauses= initializerList.getClauses();
for (IASTInitializerClause clause : clauses) {
if (clause instanceof IASTExpression) {
IType t= ((IASTExpression) clause).getExpressionType();
if (isDependentType(t))
return true;
} else if (clause instanceof ICPPASTInitializerList) {
if (isDependentInitializerList((ICPPASTInitializerList) clause))
return true;
}
}
return false;
}
public static boolean containsDependentArg(ObjectMap tpMap) { public static boolean containsDependentArg(ObjectMap tpMap) {
for (Object arg : tpMap.valueArray()) { for (Object arg : tpMap.valueArray()) {
if (isDependentType((IType)arg)) if (isDependentType((IType)arg))
@ -2365,9 +2403,9 @@ public class CPPTemplates {
* Attempts to (partially) resolve an unknown binding with the given arguments. * Attempts to (partially) resolve an unknown binding with the given arguments.
*/ */
public static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap, public static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPClassSpecialization within) throws DOMException { int packOffset, ICPPClassSpecialization within, IASTNode point) throws DOMException {
if (unknown instanceof ICPPDeferredClassInstance) { if (unknown instanceof ICPPDeferredClassInstance) {
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset, within); return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset, within, point);
} }
final IBinding owner= unknown.getOwner(); final IBinding owner= unknown.getOwner();
@ -2375,14 +2413,14 @@ public class CPPTemplates {
return unknown; return unknown;
IBinding result = unknown; IBinding result = unknown;
IType t = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within); IType t = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
if (t != null) { if (t != null) {
t = SemanticUtil.getUltimateType(t, false); t = SemanticUtil.getUltimateType(t, false);
if (t instanceof ICPPUnknownBinding) { if (t instanceof ICPPUnknownBinding) {
if (unknown instanceof ICPPUnknownClassInstance) { if (unknown instanceof ICPPUnknownClassInstance) {
ICPPUnknownClassInstance ucli= (ICPPUnknownClassInstance) unknown; ICPPUnknownClassInstance ucli= (ICPPUnknownClassInstance) unknown;
final ICPPTemplateArgument[] arguments = ucli.getArguments(); final ICPPTemplateArgument[] arguments = ucli.getArguments();
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within); ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within, point);
if (!t.equals(owner) && newArgs != arguments) { if (!t.equals(owner) && newArgs != arguments) {
newArgs= SemanticUtil.getSimplifiedArguments(newArgs); newArgs= SemanticUtil.getSimplifiedArguments(newArgs);
result= new CPPUnknownClassInstance((ICPPUnknownBinding) t, ucli.getNameCharArray(), newArgs); result= new CPPUnknownClassInstance((ICPPUnknownBinding) t, ucli.getNameCharArray(), newArgs);
@ -2402,9 +2440,9 @@ public class CPPTemplates {
result= CPPSemantics.resolveUnknownName(s, unknown); result= CPPSemantics.resolveUnknownName(s, unknown);
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) { if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments( ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(
((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within); ((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within, point);
if (result instanceof ICPPClassTemplate) { if (result instanceof ICPPClassTemplate) {
result = instantiate((ICPPClassTemplate) result, newArgs); result = instantiate((ICPPClassTemplate) result, newArgs, point);
} }
} }
} }
@ -2417,18 +2455,18 @@ public class CPPTemplates {
} }
private static IBinding resolveDeferredClassInstance(ICPPDeferredClassInstance dci, private static IBinding resolveDeferredClassInstance(ICPPDeferredClassInstance dci,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) { ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
ICPPTemplateArgument[] arguments = dci.getTemplateArguments(); ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
ICPPTemplateArgument[] newArgs; ICPPTemplateArgument[] newArgs;
try { try {
newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within); newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within, point);
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }
boolean changed= arguments != newArgs; boolean changed= arguments != newArgs;
ICPPClassTemplate classTemplate = dci.getClassTemplate(); ICPPClassTemplate classTemplate = dci.getClassTemplate();
IType classTemplateSpecialization= instantiateType(classTemplate, tpMap, packOffset, within); IType classTemplateSpecialization= instantiateType(classTemplate, tpMap, packOffset, within, point);
if (classTemplateSpecialization != classTemplate && classTemplateSpecialization instanceof ICPPClassTemplate) { if (classTemplateSpecialization != classTemplate && classTemplateSpecialization instanceof ICPPClassTemplate) {
classTemplate= (ICPPClassTemplate) classTemplateSpecialization; classTemplate= (ICPPClassTemplate) classTemplateSpecialization;
changed= true; changed= true;
@ -2438,11 +2476,11 @@ public class CPPTemplates {
IBinding inst= null; IBinding inst= null;
if (classTemplate instanceof ICPPClassTemplatePartialSpecialization) { if (classTemplate instanceof ICPPClassTemplatePartialSpecialization) {
try { try {
inst= instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) classTemplate, newArgs, false, null); inst= instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) classTemplate, newArgs, false, null, point);
} catch (DOMException e) { } catch (DOMException e) {
} }
} else { } else {
inst= instantiate(classTemplate, newArgs); inst= instantiate(classTemplate, newArgs, point);
} }
if (inst != null) if (inst != null)
return inst; return inst;

View file

@ -13,11 +13,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -108,6 +104,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
@ -197,9 +194,12 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
/** /**
@ -230,6 +230,7 @@ public class CPPVisitor extends ASTQueries {
return new HashSet<IASTDeclSpecifier>(); return new HashSet<IASTDeclSpecifier>();
} }
}; };
private static final ICPPScope UNKNOWN_TYPE_SCOPE = new CPPUnknownTypeScope(new CPPASTName("<unknown type>".toCharArray()), null); //$NON-NLS-1$
public static IBinding createBinding(IASTName name) { public static IBinding createBinding(IASTName name) {
IASTNode parent = name.getParent(); IASTNode parent = name.getParent();
@ -307,6 +308,32 @@ public class CPPVisitor extends ASTQueries {
if (names.length < 2) if (names.length < 2)
return false; return false;
IASTNode parent= qname.getParent();
IASTNode decl= null;
if (parent instanceof IASTCompositeTypeSpecifier) {
decl= parent.getParent();
} else if (parent instanceof IASTDeclarator) {
decl= ASTQueries.findOutermostDeclarator((IASTDeclarator) parent).getParent();
}
IScope inScope= null;
while (decl != null) {
ASTNodeProperty prop = decl.getPropertyInParent();
if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) {
inScope = ((ICPPASTCompositeTypeSpecifier) decl.getParent()).getScope();
break;
} else if (prop == ICPPASTNamespaceDefinition.OWNED_DECLARATION) {
inScope = ((ICPPASTNamespaceDefinition) decl.getParent()).getScope();
break;
} else if (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) {
decl= decl.getParent();
} else {
return false;
}
}
if (inScope == null)
return false;
IBinding pb= names[names.length-2].resolvePreBinding(); IBinding pb= names[names.length-2].resolvePreBinding();
if (pb instanceof IProblemBinding) if (pb instanceof IProblemBinding)
return false; return false;
@ -320,32 +347,8 @@ public class CPPVisitor extends ASTQueries {
} else if (pb instanceof ICPPNamespace) { } else if (pb instanceof ICPPNamespace) {
scope= ((ICPPNamespace)pb).getNamespaceScope(); scope= ((ICPPNamespace)pb).getNamespaceScope();
} }
if (scope == null)
return false; return scope == inScope;
IASTNode parent= qname.getParent();
IASTNode decl= null;
if (parent instanceof IASTCompositeTypeSpecifier) {
decl= parent.getParent();
} else if (parent instanceof IASTDeclarator) {
decl= ASTQueries.findOutermostDeclarator((IASTDeclarator) parent).getParent();
}
while (decl != null) {
ASTNodeProperty prop = decl.getPropertyInParent();
if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) {
return scope == ((ICPPASTCompositeTypeSpecifier) decl.getParent()).getScope();
}
if (prop == ICPPASTNamespaceDefinition.OWNED_DECLARATION) {
return scope == ((ICPPASTNamespaceDefinition) decl.getParent()).getScope();
}
if (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) {
decl= decl.getParent();
} else {
return false;
}
}
return false;
} }
private static IBinding createBinding(IASTGotoStatement gotoStatement) { private static IBinding createBinding(IASTGotoStatement gotoStatement) {
@ -452,7 +455,7 @@ public class CPPVisitor extends ASTQueries {
binding = CPPSemantics.resolveBinding(elabType.getName()); binding = CPPSemantics.resolveBinding(elabType.getName());
} }
if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) { if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) {
binding= ((CPPASTTranslationUnit) elabType.getTranslationUnit()).mapToAST((ICPPClassType) binding); binding= ((CPPASTTranslationUnit) elabType.getTranslationUnit()).mapToAST((ICPPClassType) binding, elabType);
ASTInternal.addDeclaration(binding, elabType); ASTInternal.addDeclaration(binding, elabType);
} }
@ -874,7 +877,7 @@ public class CPPVisitor extends ASTQueries {
if (name == null) if (name == null)
return false; return false;
final ASTNodeProperty propertyInParent = name.getPropertyInParent(); final ASTNodeProperty propertyInParent = name.getPropertyInParent();
if (propertyInParent == CPPSemantics.STRING_LOOKUP_PROPERTY || propertyInParent == null) if (propertyInParent == null)
return false; return false;
IASTNode parent = name.getParent(); IASTNode parent = name.getParent();
if (parent instanceof ICPPASTTemplateId) { if (parent instanceof ICPPASTTemplateId) {
@ -1130,11 +1133,7 @@ public class CPPVisitor extends ASTQueries {
} }
public static IScope getContainingScope(IASTName name) { public static IScope getContainingScope(IASTName name) {
return getContainingScope(name, null); IScope scope= getContainingScopeOrNull(name);
}
public static IScope getContainingScope(IASTName name, LookupData data) {
IScope scope= getContainingScopeOrNull(name, data);
if (scope == null) { if (scope == null) {
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE); return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE);
} }
@ -1142,7 +1141,7 @@ public class CPPVisitor extends ASTQueries {
return scope; return scope;
} }
private static IScope getContainingScopeOrNull(IASTName name, LookupData data) { private static IScope getContainingScopeOrNull(IASTName name) {
if (name == null) { if (name == null) {
return null; return null;
} }
@ -1172,9 +1171,6 @@ public class CPPVisitor extends ASTQueries {
parent= name.getParent(); parent= name.getParent();
} }
} else if (i > 0) { } else if (i > 0) {
if (data != null) {
data.usesEnclosingScope= false;
}
// For template functions we may need to resolve a template parameter // For template functions we may need to resolve a template parameter
// as a parent of an unknown type used as parameter type. // as a parent of an unknown type used as parameter type.
IBinding binding = names[i - 1].resolvePreBinding(); IBinding binding = names[i - 1].resolvePreBinding();
@ -1190,7 +1186,7 @@ public class CPPVisitor extends ASTQueries {
IScope scope= null; IScope scope= null;
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
if (binding instanceof IIndexBinding && tu != null) { if (binding instanceof IIndexBinding && tu != null) {
binding= (((CPPASTTranslationUnit) tu)).mapToAST((ICPPClassType) binding); binding= (((CPPASTTranslationUnit) tu)).mapToAST((ICPPClassType) binding, name);
} }
scope= ((ICPPClassType) binding).getCompositeScope(); scope= ((ICPPClassType) binding).getCompositeScope();
} else if (binding instanceof ICPPNamespace) { } else if (binding instanceof ICPPNamespace) {
@ -1215,9 +1211,6 @@ public class CPPVisitor extends ASTQueries {
} }
if (parent instanceof ICPPASTFieldReference) { if (parent instanceof ICPPASTFieldReference) {
if (data != null) {
data.usesEnclosingScope= false;
}
final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference) parent; final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference) parent;
IType type = fieldReference.getFieldOwnerType(); IType type = fieldReference.getFieldOwnerType();
type= getUltimateTypeUptoPointers(type); type= getUltimateTypeUptoPointers(type);
@ -1226,8 +1219,9 @@ public class CPPVisitor extends ASTQueries {
return ((ICPPClassType) type).getCompositeScope(); return ((ICPPClassType) type).getCompositeScope();
} else if (type instanceof ICPPUnknownBinding) { } else if (type instanceof ICPPUnknownBinding) {
return ((ICPPUnknownBinding) type).asScope(); return ((ICPPUnknownBinding) type).asScope();
} else if (type instanceof ICPPUnknownType) {
return UNKNOWN_TYPE_SCOPE;
} else { } else {
// mstodo introduce problem category
return new CPPScope.CPPScopeProblem(name, ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); return new CPPScope.CPPScopeProblem(name, ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
} }
} else if (parent instanceof IASTGotoStatement || parent instanceof IASTLabelStatement) { } else if (parent instanceof IASTGotoStatement || parent instanceof IASTLabelStatement) {
@ -1285,7 +1279,7 @@ public class CPPVisitor extends ASTQueries {
public static IASTNode getContainingBlockItem(IASTNode node) { public static IASTNode getContainingBlockItem(IASTNode node) {
if (node == null) return null; if (node == null) return null;
if (node.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return null; if (node.getPropertyInParent() == null) return null;
IASTNode parent = node.getParent(); IASTNode parent = node.getParent();
if (parent == null) if (parent == null)
return null; return null;
@ -1960,14 +1954,14 @@ public class CPPVisitor extends ASTQueries {
if (declarator instanceof ICPPASTFunctionDeclarator) { if (declarator instanceof ICPPASTFunctionDeclarator) {
return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator); return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator);
} }
IASTInitializerClause autoInitClause= null; ICPPASTInitializerClause autoInitClause= null;
IASTNode parent = declarator.getParent().getParent(); IASTNode parent = declarator.getParent().getParent();
if (parent instanceof ICPPASTNewExpression) { if (parent instanceof ICPPASTNewExpression) {
IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer(); IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer();
if (initializer != null) { if (initializer != null) {
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments(); IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments();
if (arguments.length == 1) { if (arguments.length == 1) {
autoInitClause = arguments[0]; autoInitClause = (ICPPASTInitializerClause) arguments[0];
} }
} }
} else if (parent instanceof ICPPASTRangeBasedForStatement) { } else if (parent instanceof ICPPASTRangeBasedForStatement) {
@ -1988,9 +1982,9 @@ public class CPPVisitor extends ASTQueries {
IBinding b= implicits[0].getBinding(); IBinding b= implicits[0].getBinding();
CPPASTName name= new CPPASTName(); CPPASTName name= new CPPASTName();
name.setBinding(b); name.setBinding(b);
if (b instanceof ICPPMethod) { if (b instanceof ICPPMethod && forInit instanceof IASTExpression) {
beginExpr= new CPPASTFunctionCallExpression( beginExpr= new CPPASTFunctionCallExpression(
new CPPASTFieldReference(name, null), NO_ARGS); new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS);
} else { } else {
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS); beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
} }
@ -2008,15 +2002,15 @@ public class CPPVisitor extends ASTQueries {
} else { } else {
IASTInitializer initClause= declarator.getInitializer(); IASTInitializer initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) { if (initClause instanceof IASTEqualsInitializer) {
autoInitClause= ((IASTEqualsInitializer) initClause).getInitializerClause(); autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof IASTInitializerClause) { } else if (initClause instanceof ICPPASTInitializerClause) {
autoInitClause= (IASTInitializerClause) initClause; autoInitClause= (ICPPASTInitializerClause) initClause;
} }
} }
return createAutoType(autoInitClause, declSpec, declarator); return createAutoType(autoInitClause, declSpec, declarator);
} }
private static IType createAutoType(IASTInitializerClause initClause, IASTDeclSpecifier declSpec, private static IType createAutoType(ICPPASTInitializerClause initClause, IASTDeclSpecifier declSpec,
IASTDeclarator declarator) { IASTDeclarator declarator) {
// C++0x: 7.1.6.4 // C++0x: 7.1.6.4
if (initClause == null || !autoTypeDeclSpecs.get().add(declSpec)) { if (initClause == null || !autoTypeDeclSpecs.get().add(declSpec)) {
@ -2035,20 +2029,15 @@ public class CPPVisitor extends ASTQueries {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
type = (IType) CPPTemplates.instantiate(initializer_list_template, type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }); new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause);
if (type instanceof IProblemBinding) { if (type instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
} }
type = decorateType(type, declSpec, declarator); type = decorateType(type, declSpec, declarator);
final ICPPEvaluation evaluation = initClause.getEvaluation();
if (initClause instanceof IASTExpression) { initType= evaluation.getTypeOrFunctionSet(declarator);
final IASTExpression expression = (IASTExpression) initClause; valueCat= evaluation.getValueCategory(declarator);
initType = expression.getExpressionType();
valueCat= expression.getValueCategory();
} else if (initClause instanceof ICPPASTInitializerList) {
initType = new InitializerListType((ICPPASTInitializerList) initClause);
}
if (initType == null) { if (initType == null) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
@ -2058,7 +2047,7 @@ public class CPPVisitor extends ASTQueries {
ICPPFunctionTemplate template = new AutoTypeResolver(type); ICPPFunctionTemplate template = new AutoTypeResolver(type);
CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1); CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1);
TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType), TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType),
Collections.singletonList(valueCat), paramMap); Collections.singletonList(valueCat), paramMap, initClause);
ICPPTemplateArgument argument = paramMap.getArgument(0, 0); ICPPTemplateArgument argument = paramMap.getArgument(0, 0);
if (argument == null) { if (argument == null) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
@ -2069,7 +2058,7 @@ public class CPPVisitor extends ASTQueries {
type = t; type = t;
if (initClause instanceof ICPPASTInitializerList) { if (initClause instanceof ICPPASTInitializerList) {
type = (IType) CPPTemplates.instantiate(initializer_list_template, type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }); new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause);
} }
return decorateType(type, declSpec, declarator); return decorateType(type, declSpec, declarator);
} }
@ -2241,8 +2230,8 @@ public class CPPVisitor extends ASTQueries {
return null; return null;
} }
public static IType getPointerDiffType(final IASTBinaryExpression binary) { public static IType getPointerDiffType(final IASTNode point) {
IType t= getStdType(binary, PTRDIFF_T); IType t= getStdType(point, PTRDIFF_T);
return t != null ? t : INT_TYPE; return t != null ? t : INT_TYPE;
} }
@ -2264,8 +2253,8 @@ public class CPPVisitor extends ASTQueries {
return null; return null;
} }
public static IType get_type_info(IASTExpression expression) { public static IType get_type_info(IASTNode point) {
IType t= getStdType(expression, TYPE_INFO); IType t= getStdType(point, TYPE_INFO);
return t != null ? t : INT_TYPE; return t != null ? t : INT_TYPE;
} }

View file

@ -32,9 +32,8 @@ import java.util.Collections;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
@ -46,7 +45,6 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; 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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
@ -63,12 +61,12 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.DeferredUDC; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.DeferredUDC;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBinding;
@ -93,7 +91,7 @@ public class Conversions {
* @throws DOMException * @throws DOMException
*/ */
public static Cost checkImplicitConversionSequence(IType target, IType exprType, public static Cost checkImplicitConversionSequence(IType target, IType exprType,
ValueCategory valueCat, UDCMode udc, Context ctx) throws DOMException { ValueCategory valueCat, UDCMode udc, Context ctx, IASTNode point) throws DOMException {
final boolean isImpliedObject= ctx == Context.IMPLICIT_OBJECT; final boolean isImpliedObject= ctx == Context.IMPLICIT_OBJECT;
if (isImpliedObject) if (isImpliedObject)
udc= UDCMode.FORBIDDEN; udc= UDCMode.FORBIDDEN;
@ -124,7 +122,7 @@ public class Conversions {
if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.CONST) if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.CONST)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
Cost cost= listInitializationSequence(((InitializerListType) exprType), T1, udc, false); Cost cost= listInitializationSequence(((InitializerListType) exprType).getEvaluation(), T1, udc, false, point);
if (cost.converts()) { if (cost.converts()) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
} }
@ -148,7 +146,7 @@ public class Conversions {
// 'cv3 T3' (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) // 'cv3 T3' (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6)
// and choosing the best one through overload resolution (13.3)), // and choosing the best one through overload resolution (13.3)),
if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) { if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) {
Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx); Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx, point);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -182,7 +180,7 @@ public class Conversions {
// and choosing the best one through overload resolution (13.3)), the reference is bound to the // and choosing the best one through overload resolution (13.3)), the reference is bound to the
// function lvalue that is the result of the conversion; // function lvalue that is the result of the conversion;
if (T2 instanceof ICPPClassType) { if (T2 instanceof ICPPClassType) {
Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx); Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx, point);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -215,7 +213,7 @@ public class Conversions {
// first case and to the object that is the result of the conversion in the second case (or, // first case and to the object that is the result of the conversion in the second case (or,
// in either case, to the appropriate base class sub-object of the object). // in either case, to the appropriate base class sub-object of the object).
if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) { if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) {
Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, ctx); Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, ctx, point);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -242,7 +240,7 @@ public class Conversions {
// 13.3.3.1.7 no temporary object when converting the implicit object parameter // 13.3.3.1.7 no temporary object when converting the implicit object parameter
if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) { if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) {
if (isReferenceRelated(T1, T2) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) { if (isReferenceRelated(T1, T2) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) {
Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc); Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc, point);
if (cost.converts()) { if (cost.converts()) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
} }
@ -253,13 +251,14 @@ public class Conversions {
} }
// Non-reference binding // Non-reference binding
return nonReferenceConversion(valueCat, exprType, T1, udc); return nonReferenceConversion(valueCat, exprType, T1, udc, point);
} }
/** /**
* C++0x: 13.3.1.6 Initialization by conversion function for direct reference binding * C++0x: 13.3.1.6 Initialization by conversion function for direct reference binding
* @param point
*/ */
private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, boolean needLValue, Context ctx) private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, boolean needLValue, Context ctx, IASTNode point)
throws DOMException { throws DOMException {
ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2); ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2);
Cost operatorCost= null; Cost operatorCost= null;
@ -282,7 +281,7 @@ public class Conversions {
// Make sure top-level cv-qualifiers are compared // Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost udcFuncCost= new FunctionCost(op, udcCost); FunctionCost udcFuncCost= new FunctionCost(op, udcCost);
int cmp= udcFuncCost.compareTo(null, bestUdcCost); int cmp= udcFuncCost.compareTo(null, bestUdcCost, point);
if (cmp <= 0) { if (cmp <= 0) {
Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false); // converted to target Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false); // converted to target
if (cost != null) { if (cost != null) {
@ -306,9 +305,9 @@ public class Conversions {
/** /**
* 8.5-16 * 8.5-16
*/ */
private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc) throws DOMException { private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc, IASTNode point) throws DOMException {
if (source instanceof InitializerListType) { if (source instanceof InitializerListType) {
return listInitializationSequence(((InitializerListType) source), target, udc, false); return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false, point);
} }
IType uqTarget= SemanticUtil.getNestedType(target, TDEF | REF | CVTYPE); IType uqTarget= SemanticUtil.getNestedType(target, TDEF | REF | CVTYPE);
@ -329,14 +328,14 @@ public class Conversions {
if (udc == UDCMode.FORBIDDEN) if (udc == UDCMode.FORBIDDEN)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER); return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER, point);
} }
if (uqSource instanceof ICPPClassType) { if (uqSource instanceof ICPPClassType) {
if (udc == UDCMode.FORBIDDEN) if (udc == UDCMode.FORBIDDEN)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER); return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER, point);
} }
return checkStandardConversionSequence(uqSource, target); return checkStandardConversionSequence(uqSource, target);
@ -345,15 +344,14 @@ public class Conversions {
/** /**
* 13.3.3.1.5 List-initialization sequence [over.ics.list] * 13.3.3.1.5 List-initialization sequence [over.ics.list]
*/ */
static Cost listInitializationSequence(InitializerListType arg, IType target, UDCMode udc, boolean isDirect) throws DOMException { static Cost listInitializationSequence(EvalInitList arg, IType target, UDCMode udc, boolean isDirect, IASTNode point) throws DOMException {
IType listType= getInitListType(target); IType listType= getInitListType(target);
if (listType != null) { if (listType != null) {
IType[] exprTypes= arg.getExpressionTypes(); ICPPEvaluation[] clauses = arg.getClauses();
ValueCategory[] valueCats= arg.getValueCategories(); Cost worstCost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY);
Cost worstCost= new Cost(arg, target, Rank.IDENTITY); for (ICPPEvaluation clause : clauses) {
for (int i = 0; i < exprTypes.length; i++) { Cost cost= checkImplicitConversionSequence(listType, clause.getTypeOrFunctionSet(point),
IType exprType = exprTypes[i]; clause.getValueCategory(point), UDCMode.ALLOWED, Context.ORDINARY, point);
Cost cost= checkImplicitConversionSequence(listType, exprType, valueCats[i], UDCMode.ALLOWED, Context.ORDINARY);
if (!cost.converts()) if (!cost.converts())
return cost; return cost;
if (cost.isNarrowingConversion()) { if (cost.isNarrowingConversion()) {
@ -374,26 +372,25 @@ public class Conversions {
ICPPClassType classTarget= (ICPPClassType) noCVTarget; ICPPClassType classTarget= (ICPPClassType) noCVTarget;
if (ClassTypeHelper.isAggregateClass(classTarget)) { if (ClassTypeHelper.isAggregateClass(classTarget)) {
Cost cost= new Cost(arg, target, Rank.IDENTITY); Cost cost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY);
cost.setUserDefinedConversion(null); cost.setUserDefinedConversion(null);
return cost; return cost;
} }
return listInitializationOfClass(arg, classTarget, isDirect, udc == UDCMode.DEFER); return listInitializationOfClass(arg, classTarget, isDirect, udc == UDCMode.DEFER, point);
} }
IASTInitializerClause[] args = arg.getInitializerList().getClauses(); ICPPEvaluation[] args = arg.getClauses();
if (args.length == 1) { if (args.length == 1) {
final IASTInitializerClause firstArg = args[0]; final ICPPEvaluation firstArg = args[0];
if (firstArg instanceof IASTExpression) { if (!firstArg.isInitializerList()) {
IASTExpression expr= (IASTExpression) firstArg; Cost cost= checkImplicitConversionSequence(target, firstArg.getTypeOrFunctionSet(point), firstArg.getValueCategory(point), udc, Context.ORDINARY, point);
Cost cost= checkImplicitConversionSequence(target, expr.getExpressionType(), expr.getValueCategory(), udc, Context.ORDINARY);
if (cost.isNarrowingConversion()) { if (cost.isNarrowingConversion()) {
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
} }
return cost; return cost;
} }
} else if (args.length == 0) { } else if (args.length == 0) {
return new Cost(arg, target, Rank.IDENTITY); return new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY);
} }
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
@ -538,9 +535,9 @@ public class Conversions {
} }
// 13.3.1.7 Initialization by list-initialization // 13.3.1.7 Initialization by list-initialization
static Cost listInitializationOfClass(InitializerListType arg, ICPPClassType t, boolean isDirect, boolean deferUDC) throws DOMException { static Cost listInitializationOfClass(EvalInitList arg, ICPPClassType t, boolean isDirect, boolean deferUDC, IASTNode point) throws DOMException {
if (deferUDC) { if (deferUDC) {
Cost c= new Cost(arg, t, Rank.USER_DEFINED_CONVERSION); Cost c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(isDirect ? DeferredUDC.DIRECT_LIST_INIT_OF_CLASS : DeferredUDC.LIST_INIT_OF_CLASS); c.setDeferredUDC(isDirect ? DeferredUDC.DIRECT_LIST_INIT_OF_CLASS : DeferredUDC.LIST_INIT_OF_CLASS);
return c; return c;
} }
@ -554,8 +551,8 @@ public class Conversions {
for (ICPPConstructor ctor : ctors) { for (ICPPConstructor ctor : ctors) {
final int minArgCount = ctor.getRequiredArgumentCount(); final int minArgCount = ctor.getRequiredArgumentCount();
if (minArgCount == 0) { if (minArgCount == 0) {
if (arg.getExpressionTypes().length == 0) { if (arg.getClauses().length == 0) {
Cost c= new Cost(arg, t, Rank.IDENTITY); Cost c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.IDENTITY);
c.setUserDefinedConversion(ctor); c.setUserDefinedConversion(ctor);
return c; return c;
} }
@ -565,7 +562,7 @@ public class Conversions {
final IType target = parTypes[0]; final IType target = parTypes[0];
if (getInitListType(target) != null) { if (getInitListType(target) != null) {
hasInitListConstructor= true; hasInitListConstructor= true;
Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect); Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect, point);
if (cost.converts()) { if (cost.converts()) {
int cmp= cost.compareTo(bestCost); int cmp= cost.compareTo(bestCost);
if (bestCost == null || cmp < 0) { if (bestCost == null || cmp < 0) {
@ -593,13 +590,8 @@ public class Conversions {
} }
// No initializer-list constructor // No initializer-list constructor
final ICPPASTInitializerList initializerList = arg.getInitializerList(); LookupData data= new LookupData(t.getNameCharArray(), null, point);
final ICPPEvaluation[] expandedArgs = arg.getClauses();
LookupData data= new LookupData();
IASTName name = new CPPASTName(t.getNameCharArray());
name.setParent(initializerList);
name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY);
final IASTInitializerClause[] expandedArgs = initializerList.getClauses();
data.setFunctionArguments(false, expandedArgs); data.setFunctionArguments(false, expandedArgs);
data.fNoNarrowing= true; data.fNoNarrowing= true;
@ -623,11 +615,11 @@ public class Conversions {
final IBinding result= CPPSemantics.resolveFunction(data, filteredConstructors, true); final IBinding result= CPPSemantics.resolveFunction(data, filteredConstructors, true);
final Cost c; final Cost c;
if (result instanceof ICPPMethod) { if (result instanceof ICPPMethod) {
c= new Cost(arg, t, Rank.IDENTITY); c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.IDENTITY);
c.setUserDefinedConversion((ICPPMethod) result); c.setUserDefinedConversion((ICPPMethod) result);
} else if (result instanceof IProblemBinding } else if (result instanceof IProblemBinding
&& ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) { && ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) {
c = new Cost(arg, t, Rank.USER_DEFINED_CONVERSION); c = new Cost(arg.getTypeOrFunctionSet(point), t, Rank.USER_DEFINED_CONVERSION);
c.setAmbiguousUDC(true); c.setAmbiguousUDC(true);
} else { } else {
c= Cost.NO_CONVERSION; c= Cost.NO_CONVERSION;
@ -638,7 +630,7 @@ public class Conversions {
/** /**
* 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy] * 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
*/ */
static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC) throws DOMException { static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC, IASTNode point) throws DOMException {
if (deferUDC) { if (deferUDC) {
Cost c= new Cost(source, t, Rank.USER_DEFINED_CONVERSION); Cost c= new Cost(source, t, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS); c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS);
@ -648,8 +640,8 @@ public class Conversions {
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
ICPPFunction[] ctors= t.getConstructors(); ICPPFunction[] ctors= t.getConstructors();
ctors = CPPTemplates.instantiateForFunctionCall(null, ctors, ctors = CPPTemplates.instantiateForFunctionCall(ctors, null,
Collections.singletonList(source), Collections.singletonList(valueCat), false); Collections.singletonList(source), Collections.singletonList(valueCat), false, point);
for (ICPPFunction f : ctors) { for (ICPPFunction f : ctors) {
if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding) if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding)
@ -677,9 +669,9 @@ public class Conversions {
if (ctor.getRequiredArgumentCount() > 1) if (ctor.getRequiredArgumentCount() > 1)
continue; continue;
c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY)); c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY, point));
} }
int cmp= c1.compareTo(null, cost1); int cmp= c1.compareTo(null, cost1, point);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
cost2= new Cost(t, t, Rank.IDENTITY); cost2= new Cost(t, t, Rank.IDENTITY);
@ -694,7 +686,7 @@ public class Conversions {
final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE); final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE);
if (uqSource instanceof ICPPClassType) { if (uqSource instanceof ICPPClassType) {
ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource); ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource);
ops= CPPTemplates.instantiateConversionTemplates(ops, t); ops= CPPTemplates.instantiateConversionTemplates(ops, t, point);
for (final ICPPFunction f : ops) { for (final ICPPFunction f : ops) {
if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) { if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) {
ICPPMethod op= (ICPPMethod) f; ICPPMethod op= (ICPPMethod) f;
@ -710,7 +702,7 @@ public class Conversions {
// Make sure top-level cv-qualifiers are compared // Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost c1= new FunctionCost(op, udcCost); FunctionCost c1= new FunctionCost(op, udcCost);
int cmp= c1.compareTo(null, cost1); int cmp= c1.compareTo(null, cost1, point);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
cost2= new Cost(t, t, Rank.IDENTITY); cost2= new Cost(t, t, Rank.IDENTITY);
@ -737,14 +729,14 @@ public class Conversions {
/** /**
* 13.3.1.5 Initialization by conversion function [over.match.conv] * 13.3.1.5 Initialization by conversion function [over.match.conv]
*/ */
static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target, boolean deferUDC) throws DOMException { static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target, boolean deferUDC, IASTNode point) throws DOMException {
if (deferUDC) { if (deferUDC) {
Cost c= new Cost(source, target, Rank.USER_DEFINED_CONVERSION); Cost c= new Cost(source, target, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION); c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
return c; return c;
} }
ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource); ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource);
ops= CPPTemplates.instantiateConversionTemplates(ops, target); ops= CPPTemplates.instantiateConversionTemplates(ops, target, point);
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
for (final ICPPFunction f : ops) { for (final ICPPFunction f : ops) {
@ -756,7 +748,7 @@ public class Conversions {
final IType returnType = op.getType().getReturnType(); final IType returnType = op.getType().getReturnType();
IType uqReturnType= getNestedType(returnType, TDEF | ALLCVQ); IType uqReturnType= getNestedType(returnType, TDEF | ALLCVQ);
Cost c2= checkImplicitConversionSequence(target, uqReturnType, valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY); Cost c2= checkImplicitConversionSequence(target, uqReturnType, valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY, point);
if (c2.converts()) { if (c2.converts()) {
if (isExplicitConversion && c2.getRank() != Rank.IDENTITY) if (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
continue; continue;
@ -766,7 +758,7 @@ public class Conversions {
// Make sure top-level cv-qualifiers are compared // Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost c1= new FunctionCost(op, udcCost); FunctionCost c1= new FunctionCost(op, udcCost);
int cmp= c1.compareTo(null, cost1); int cmp= c1.compareTo(null, cost1, point);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
cost2= c2; cost2= c2;

View file

@ -0,0 +1,276 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
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.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalBinary implements ICPPEvaluation {
public final static int op_arrayAccess= Byte.MAX_VALUE;
private final int fOperator;
private final ICPPEvaluation fArg1;
private final ICPPEvaluation fArg2;
private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
private IType fType;
public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2) {
fOperator= operator;
fArg1= arg1;
fArg2= arg2;
}
public int getOperator() {
return fOperator;
}
public ICPPEvaluation getArg1() {
return fArg1;
}
public ICPPEvaluation getArg2() {
return fArg2;
}
@Override
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null) {
if (isTypeDependent()) {
fType= new TypeOfDependentExpression(this);
} else {
ICPPFunction overload = getOverload(point);
if (overload != null) {
fType= ExpressionTypes.typeFromFunctionCall(overload);
} else {
fType= computeType(point);
}
}
}
return fType;
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public boolean isTypeDependent() {
if (fType != null) {
return fType instanceof TypeOfDependentExpression;
}
return fArg1.isTypeDependent() || fArg2.isTypeDependent();
}
@Override
public boolean isValueDependent() {
return fArg1.isValueDependent() || fArg2.isValueDependent();
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
if (isTypeDependent())
return ValueCategory.PRVALUE;
ICPPFunction overload = getOverload(point);
if (overload != null)
return ExpressionTypes.valueCategoryFromFunctionCall(overload);
switch (fOperator) {
case op_arrayAccess:
case IASTBinaryExpression.op_assign:
case IASTBinaryExpression.op_binaryAndAssign:
case IASTBinaryExpression.op_binaryOrAssign:
case IASTBinaryExpression.op_binaryXorAssign:
case IASTBinaryExpression.op_divideAssign:
case IASTBinaryExpression.op_minusAssign:
case IASTBinaryExpression.op_moduloAssign:
case IASTBinaryExpression.op_multiplyAssign:
case IASTBinaryExpression.op_plusAssign:
case IASTBinaryExpression.op_shiftLeftAssign:
case IASTBinaryExpression.op_shiftRightAssign:
return LVALUE;
case IASTBinaryExpression.op_pmdot:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return fArg1.getValueCategory(point);
break;
case IASTBinaryExpression.op_pmarrow:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return LVALUE;
break;
}
return ValueCategory.PRVALUE;
}
public ICPPFunction getOverload(IASTNode point) {
if (fOverload == CPPFunction.UNINITIALIZED_FUNCTION) {
fOverload= computeOverload(point);
}
return fOverload;
}
private ICPPFunction computeOverload(IASTNode point) {
if (isTypeDependent())
return null;
if (fOperator == op_arrayAccess) {
IType type = fArg1.getTypeOrFunctionSet(point);
type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
if (type instanceof ICPPClassType) {
return CPPSemantics.findOverloadedBinaryOperator(point, OverloadableOperator.BRACKET, fArg1, fArg2);
}
} else {
final OverloadableOperator op = OverloadableOperator.fromBinaryExpression(fOperator);
if (op != null) {
return CPPSemantics.findOverloadedBinaryOperator(point, op, fArg1, fArg2);
}
}
return null;
}
public IType computeType(IASTNode point) {
// Check for overloaded operator.
ICPPFunction o= getOverload(point);
if (o != null)
return typeFromFunctionCall(o);
IType type1 = prvalueType(fArg1.getTypeOrFunctionSet(point));
if (type1 instanceof ISemanticProblem) {
return type1;
}
IType type2 = prvalueType(fArg2.getTypeOrFunctionSet(point));
if (type2 instanceof ISemanticProblem) {
return type2;
}
IType type= CPPArithmeticConversion.convertCppOperandTypes(fOperator, type1, type2);
if (type != null) {
return type;
}
switch (fOperator) {
case op_arrayAccess:
if (type1 instanceof IPointerType) {
return glvalueType(((IPointerType) type1).getType());
}
if (type2 instanceof IPointerType) {
return glvalueType(((IPointerType) type2).getType());
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
case IASTBinaryExpression.op_lessEqual:
case IASTBinaryExpression.op_lessThan:
case IASTBinaryExpression.op_greaterEqual:
case IASTBinaryExpression.op_greaterThan:
case IASTBinaryExpression.op_logicalAnd:
case IASTBinaryExpression.op_logicalOr:
case IASTBinaryExpression.op_equals:
case IASTBinaryExpression.op_notequals:
return CPPBasicType.BOOLEAN;
case IASTBinaryExpression.op_plus:
if (type1 instanceof IPointerType) {
return type1;
}
if (type2 instanceof IPointerType) {
return type2;
}
break;
case IASTBinaryExpression.op_minus:
if (type1 instanceof IPointerType) {
if (type2 instanceof IPointerType) {
return CPPVisitor.getPointerDiffType(point);
}
return type1;
}
break;
case ICPPASTBinaryExpression.op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot:
if (type2 instanceof ICPPPointerToMemberType) {
IType t= ((ICPPPointerToMemberType) type2).getType();
if (t instanceof ICPPFunctionType)
return t;
if (fOperator == ICPPASTBinaryExpression.op_pmdot && fArg1.getValueCategory(point) == PRVALUE) {
return prvalueType(t);
}
return glvalueType(t);
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
}
return type1;
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_BINARY);
buffer.putByte((byte) fOperator);
buffer.marshalEvaluation(fArg1, includeValue);
buffer.marshalEvaluation(fArg2, includeValue);
}
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);
}
}

View file

@ -0,0 +1,115 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
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.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
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;
/**
* Performs evaluation of an expression.
*/
public class EvalBinaryTypeId implements ICPPEvaluation {
private final Operator fOperator;
private final IType fType1, fType2;
private boolean fCheckedValueDependent;
private boolean fIsValueDependent;
public EvalBinaryTypeId(Operator kind, IType type1, IType type2) {
fOperator= kind;
fType1= type1;
fType2= type2;
}
public Operator getOperator() {
return fOperator;
}
public IType getType1() {
return fType1;
}
public IType getType2() {
return fType2;
}
@Override
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
switch (fOperator) {
case __is_base_of:
return CPPBasicType.BOOLEAN;
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public boolean isTypeDependent() {
return false;
}
@Override
public boolean isValueDependent() {
if (!fCheckedValueDependent) {
fIsValueDependent= CPPTemplates.isDependentType(fType1) || CPPTemplates.isDependentType(fType2);
fCheckedValueDependent= true;
}
return fIsValueDependent;
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
return PRVALUE;
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_BINARY_TYPE_ID);
buffer.putByte((byte) fOperator.ordinal());
buffer.marshalType(fType1);
buffer.marshalType(fType2);
}
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);
}
}

View file

@ -0,0 +1,189 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
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.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
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 implements ICPPEvaluation {
private final IBinding fBinding;
private final boolean fFixedType;
private IType fType;
private boolean fCheckedIsValueDependent;
private boolean fIsValueDependent;
private boolean fIsTypeDependent;
private boolean fCheckedIsTypeDependent;
public EvalBinding(IBinding binding, IType type) {
fBinding= binding;
fType= type;
fFixedType= type != null;
}
public IBinding getBinding() {
return fBinding;
}
public IType getFixedType() {
return fFixedType ? fType : null;
}
@Override
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
}
@Override
public boolean isTypeDependent() {
if (!fCheckedIsTypeDependent) {
fCheckedIsTypeDependent= true;
fIsTypeDependent= computeIsTypeDependent();
}
return fIsTypeDependent;
}
private boolean computeIsTypeDependent() {
if (fBinding instanceof ICPPUnknownBinding)
return true;
IType t= null;
if (fBinding instanceof IEnumerator) {
t= ((IEnumerator) fBinding).getType();
} else if (fBinding instanceof ICPPTemplateNonTypeParameter) {
t= ((ICPPTemplateNonTypeParameter) fBinding).getType();
} else if (fBinding instanceof IVariable) {
t = ((IVariable) fBinding).getType();
} else if (fBinding instanceof IFunction) {
t= ((IFunction) fBinding).getType();
} else if (fBinding instanceof ICPPUnknownBinding) {
return true;
} else {
return false;
}
return CPPTemplates.isDependentType(t);
}
@Override
public boolean isValueDependent() {
if (!fCheckedIsValueDependent) {
fCheckedIsValueDependent= true;
fIsValueDependent= computeIsValueDependent();
}
return fIsValueDependent;
}
private boolean computeIsValueDependent() {
if (fBinding instanceof IEnumerator) {
return Value.isDependentValue(((IEnumerator) fBinding).getValue());
}
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
return true;
}
if (fBinding instanceof IVariable) {
return Value.isDependentValue(((IVariable) fBinding).getInitialValue());
}
if (fBinding instanceof IFunction) {
return false;
}
if (fBinding instanceof ICPPUnknownBinding) {
return true;
}
return false;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null) {
fType= computeType(point);
}
return fType;
}
private IType computeType(IASTNode point) {
if (fBinding instanceof IEnumerator) {
return ((IEnumerator) fBinding).getType();
}
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
IType type= ((ICPPTemplateNonTypeParameter) fBinding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return prvalueType(type);
}
if (fBinding instanceof IVariable) {
final IType type = ((IVariable) fBinding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return SemanticUtil.mapToAST(glvalueType(type), point);
}
if (fBinding instanceof IFunction) {
final IFunctionType type = ((IFunction) fBinding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return SemanticUtil.mapToAST(type, point);
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
if (fBinding instanceof ICPPTemplateNonTypeParameter)
return ValueCategory.PRVALUE;
if (fBinding instanceof IVariable || fBinding instanceof IFunction) {
return ValueCategory.LVALUE;
}
return ValueCategory.PRVALUE;
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_BINDING);
buffer.marshalBinding(fBinding);
buffer.marshalType(fFixedType ? fType : null);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IBinding binding= buffer.unmarshalBinding();
IType type= buffer.unmarshalType();
return new EvalBinding(binding, type);
}
}

View file

@ -0,0 +1,164 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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 implements ICPPEvaluation {
private static final ICPPFunction[] NO_FUNCTIONS = {};
private final ICPPEvaluation[] fArguments;
private ICPPFunction[] fOverloads;
private IType fType;
public EvalComma(ICPPEvaluation[] evals) {
fArguments= evals;
}
public ICPPEvaluation[] getArguments() {
return fArguments;
}
@Override
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
}
@Override
public boolean isTypeDependent() {
if (fType != null)
return fType instanceof TypeOfDependentExpression;
for (ICPPEvaluation arg : fArguments) {
if (arg.isTypeDependent())
return true;
}
return false;
}
@Override
public boolean isValueDependent() {
for (ICPPEvaluation arg : fArguments) {
if (arg.isValueDependent())
return true;
}
return false;
}
public ICPPFunction[] getOverloads(IASTNode point) {
if (fOverloads == null) {
fOverloads= computeOverloads(point);
}
return fOverloads;
}
private ICPPFunction[] computeOverloads(IASTNode point) {
if (fArguments.length < 2)
return NO_FUNCTIONS;
if (isTypeDependent())
return NO_FUNCTIONS;
ICPPFunction[] overloads = new ICPPFunction[fArguments.length - 1];
ICPPEvaluation e1= fArguments[0];
for (int i = 1; i < fArguments.length; i++) {
ICPPEvaluation e2 = fArguments[i];
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(point, e1, e2);
if (overload == null) {
e1= e2;
} else {
overloads[i - 1] = overload;
e1= new EvalFixed(typeFromFunctionCall(overload), valueCategoryFromFunctionCall(overload), Value.UNKNOWN);
if (e1.getTypeOrFunctionSet(point) instanceof ISemanticProblem) {
e1= e2;
}
}
}
return overloads;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null) {
fType= computeType(point);
}
return fType;
}
private IType computeType(IASTNode point) {
if (isTypeDependent()) {
return new TypeOfDependentExpression(this);
}
ICPPFunction[] overloads = getOverloads(point);
if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1];
if (last != null) {
return typeFromFunctionCall(last);
}
}
return fArguments[fArguments.length-1].getTypeOrFunctionSet(point);
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
ICPPFunction[] overloads = getOverloads(point);
if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1];
if (last != null) {
return valueCategoryFromFunctionCall(last);
}
}
return fArguments[fArguments.length-1].getValueCategory(point);
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_COMMA);
buffer.putShort((short) fArguments.length);
for (ICPPEvaluation arg : fArguments) {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
ICPPEvaluation[] args = new ICPPEvaluation[len];
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
}
return new EvalComma(args);
}
}

View file

@ -0,0 +1,85 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
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.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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;
/**
* Performs evaluation of an expression.
*/
public class EvalCompound implements ICPPEvaluation {
private final ICPPEvaluation fDelegate;
public EvalCompound(ICPPEvaluation delegate) {
fDelegate= delegate;
}
public ICPPEvaluation getLastEvaluation() {
return fDelegate;
}
@Override
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
}
@Override
public boolean isTypeDependent() {
return fDelegate.isTypeDependent();
}
@Override
public boolean isValueDependent() {
return fDelegate.isValueDependent();
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
return fDelegate.getTypeOrFunctionSet(point);
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
return PRVALUE;
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_COMPOUND);
buffer.marshalEvaluation(fDelegate, includeValue);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation();
return new EvalCompound(arg);
}
}

View file

@ -0,0 +1,311 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
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.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
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.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalConditional implements ICPPEvaluation {
private final ICPPEvaluation fCondition, fPositive, fNegative;
private final boolean fPositiveThrows, fNegativeThrows;
private ValueCategory fValueCategory;
private IType fType;
private ICPPFunction fOverload;
public EvalConditional(ICPPEvaluation arg1, ICPPEvaluation arg2, ICPPEvaluation arg3,
boolean positiveThrows, boolean negativeThrows) {
// Gnu-extension: Empty positive expression is replaced by condition.
fCondition= arg1;
fPositive= arg2;
fNegative= arg3;
fPositiveThrows= positiveThrows;
fNegativeThrows= negativeThrows;
}
public ICPPEvaluation getCondition() {
return fCondition;
}
public ICPPEvaluation getPositive() {
return fPositive;
}
public ICPPEvaluation getNegative() {
return fNegative;
}
public boolean isPositiveThrows() {
return fPositiveThrows;
}
public boolean isNegativeThrows() {
return fNegativeThrows;
}
@Override
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
}
public ICPPFunction getOverload(IASTNode point) {
evaluate(point);
return fOverload;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
evaluate(point);
return fType;
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
evaluate(point);
return fValueCategory;
}
@Override
public boolean isTypeDependent() {
final ICPPEvaluation positive = fPositive == null ? fCondition : fPositive;
return positive.isTypeDependent() || fNegative.isTypeDependent();
}
@Override
public boolean isValueDependent() {
return fCondition.isValueDependent() || (fPositive != null && fPositive.isValueDependent())
|| fNegative.isValueDependent();
}
private void evaluate(IASTNode point) {
if (fValueCategory != null)
return;
fValueCategory= PRVALUE;
final ICPPEvaluation positive = fPositive == null ? fCondition : fPositive;
IType t2 = positive.getTypeOrFunctionSet(point);
IType t3 = fNegative.getTypeOrFunctionSet(point);
final IType uqt2= getNestedType(t2, TDEF | REF | CVTYPE);
final IType uqt3= getNestedType(t3, TDEF | REF | CVTYPE);
if (uqt2 instanceof ISemanticProblem || uqt2 instanceof ICPPUnknownType) {
fType= uqt2;
return;
}
if (uqt3 instanceof ISemanticProblem || uqt3 instanceof ICPPUnknownType) {
fType= uqt3;
return;
}
final boolean void2= isVoidType(uqt2);
final boolean void3= isVoidType(uqt3);
// Void types: Either both are void or one is a throw expression.
if (void2 || void3) {
if (fPositiveThrows) {
fType= Conversions.lvalue_to_rvalue(t3, false);
} else if (fNegativeThrows) {
fType= Conversions.lvalue_to_rvalue(t2, false);
} else if (void2 && void3) {
fType= uqt2;
} else {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
final ValueCategory vcat2= positive.getValueCategory(point);
final ValueCategory vcat3= fNegative.getValueCategory(point);
// Same type
if (t2.isSameType(t3)) {
if (vcat2 == vcat3) {
fType= t2;
fValueCategory= vcat2;
} else {
fType= prvalueType(t2);
fValueCategory= PRVALUE;
}
return;
}
final boolean isClassType2 = uqt2 instanceof ICPPClassType;
final boolean isClassType3 = uqt3 instanceof ICPPClassType;
// Different types with at least one class type
if (isClassType2 || isClassType3) {
final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3, point); // sets fType and fValueCategory
final Cost cost3= convertToMatch(t3, vcat3, uqt3, t2, vcat2, uqt2, point); // sets fType and fValueCategory
if (cost2.converts() || cost3.converts()) {
if (cost2.converts()) {
if (cost3.converts() || cost2.isAmbiguousUDC()) {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
} else if (cost3.isAmbiguousUDC()) {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
} else if (vcat2 == vcat3 && vcat2.isGLValue() && uqt2.isSameType(uqt3)) {
// Two lvalues or two xvalues with same type up to qualification.
final CVQualifier cv2 = SemanticUtil.getCVQualifier(t2);
final CVQualifier cv3 = SemanticUtil.getCVQualifier(t3);
if (cv2.isAtLeastAsQualifiedAs(cv3)) {
fType= t2;
fValueCategory= vcat2;
} else if (cv3.isAtLeastAsQualifiedAs(cv2)) {
fType= t3;
fValueCategory= vcat3;
} else {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
// 5.16-5: At least one class type but no conversion
if (isClassType2 || isClassType3) {
fOverload = CPPSemantics.findOverloadedConditionalOperator(point, positive, fNegative);
if (fOverload != null) {
fType= ExpressionTypes.typeFromFunctionCall(fOverload);
} else {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
return;
}
// 5.16-6
t2= Conversions.lvalue_to_rvalue(t2, false);
t3= Conversions.lvalue_to_rvalue(t3, false);
if (t2.isSameType(t3)) {
fType= t2;
} else {
fType= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t2, t3);
if (fType == null) {
fType= Conversions.compositePointerType(t2, t3);
if (fType == null) {
fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
}
}
}
private Cost convertToMatch(IType t1, ValueCategory vcat1, IType uqt1, IType t2, ValueCategory vcat2, IType uqt2, IASTNode point) {
// E2 is an lvalue or E2 is an xvalue
try {
if (vcat2.isGLValue()) {
IType target= new CPPReferenceType(t2, vcat2 == XVALUE);
Cost c= Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED, Context.REQUIRE_DIRECT_BINDING, point);
if (c.converts()) {
fType= t2;
fValueCategory= vcat2;
return c;
}
}
// Both are class types and one derives from the other
if (uqt1 instanceof ICPPClassType && uqt2 instanceof ICPPClassType) {
int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2);
if (dist >= 0) {
CVQualifier cv1 = SemanticUtil.getCVQualifier(t1);
CVQualifier cv2 = SemanticUtil.getCVQualifier(t2);
if (cv2.isAtLeastAsQualifiedAs(cv1)) {
fType= t2;
fValueCategory= PRVALUE;
return new Cost(t1, t2, Rank.IDENTITY);
}
return Cost.NO_CONVERSION;
}
if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1) >= 0)
return Cost.NO_CONVERSION;
}
// Unrelated class types or just one class:
if (vcat2 != PRVALUE) {
t2= Conversions.lvalue_to_rvalue(t2, false);
}
Cost c= Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY, point);
if (c.converts()) {
fType= t2;
fValueCategory= PRVALUE;
return c;
}
} catch (DOMException e) {
}
return Cost.NO_CONVERSION;
}
private boolean isVoidType(IType t) {
return t instanceof ICPPBasicType && ((ICPPBasicType) t).getKind() == ICPPBasicType.Kind.eVoid;
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
int firstByte = ITypeMarshalBuffer.EVAL_CONDITIONAL;
if (fPositiveThrows)
firstByte |= ITypeMarshalBuffer.FLAG1;
if (fNegativeThrows)
firstByte |= ITypeMarshalBuffer.FLAG2;
buffer.putByte((byte) firstByte);
buffer.marshalEvaluation(fCondition, includeValue);
buffer.marshalEvaluation(fPositive, includeValue);
buffer.marshalEvaluation(fNegative, includeValue);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
boolean pth= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
boolean nth= (firstByte & ITypeMarshalBuffer.FLAG2) != 0;
ICPPEvaluation cond= (ICPPEvaluation) buffer.unmarshalEvaluation();
ICPPEvaluation pos= (ICPPEvaluation) buffer.unmarshalEvaluation();
ICPPEvaluation neg= (ICPPEvaluation) buffer.unmarshalEvaluation();
return new EvalConditional(cond, pos, neg, pth, nth);
}
}

View file

@ -0,0 +1,149 @@
/*******************************************************************************
* Copyright (c) 2012 Wind River Systems, Inc. and others.
* 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
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;
/**
* Performs evaluation of an expression.
*/
public class EvalFixed implements ICPPEvaluation {
public static final ICPPEvaluation INCOMPLETE = new EvalFixed(
ProblemType.UNKNOWN_FOR_EXPRESSION, PRVALUE, Value.UNKNOWN);
private final IType fType;
private final IValue fValue;
private final ValueCategory fValueCategory;
private boolean fIsTypeDependent;
private boolean fCheckedIsTypeDependent;
private boolean fIsValueDependent;
private boolean fCheckedIsValueDependent;
public EvalFixed(IType type, ValueCategory cat, IValue value) {
fType= type;
fValueCategory= cat;
fValue= value;
}
public IType getType() {
return fType;
}
public IValue getValue() {
return fValue;
}
public ValueCategory getValueCategory() {
return fValueCategory;
}
@Override
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
}
@Override
public boolean isTypeDependent() {
if (!fCheckedIsTypeDependent) {
fCheckedIsTypeDependent= true;
fIsTypeDependent= CPPTemplates.isDependentType(fType);
}
return fIsTypeDependent;
}
@Override
public boolean isValueDependent() {
if (!fCheckedIsValueDependent) {
fCheckedIsValueDependent= true;
fIsValueDependent= Value.isDependentValue(fValue);
}
return fIsValueDependent;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
return fType;
}
@Override
public IValue getValue(IASTNode point) {
return fValue;
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
return fValueCategory;
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
includeValue= includeValue && fValue != Value.UNKNOWN;
int firstByte = ITypeMarshalBuffer.EVAL_FIXED;
if (includeValue)
firstByte |= ITypeMarshalBuffer.FLAG1;
switch(fValueCategory) {
case LVALUE:
firstByte |= ITypeMarshalBuffer.FLAG2;
break;
case PRVALUE:
firstByte |= ITypeMarshalBuffer.FLAG3;
break;
default:
break;
}
buffer.putByte((byte) firstByte);
buffer.marshalType(fType);
if (includeValue) {
buffer.marshalValue(fValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean readValue= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
IValue value;
ValueCategory cat;
switch (firstByte & (ITypeMarshalBuffer.FLAG2 | ITypeMarshalBuffer.FLAG3)) {
case ITypeMarshalBuffer.FLAG2:
cat= LVALUE;
break;
case ITypeMarshalBuffer.FLAG3:
cat= PRVALUE;
break;
default:
cat= XVALUE;
break;
}
IType type= buffer.unmarshalType();
value= readValue ? buffer.unmarshalValue() : Value.UNKNOWN;
return new EvalFixed(type, cat, value);
}
}

Some files were not shown because too many files have changed in this diff Show more