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.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.Kind;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -1544,19 +1545,19 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
// CT<int> v1;
public void testUniqueInstance_Bug241641() throws Exception {
IASTName name= findName("v1", 2);
ICPPVariable v1= getBindingFromASTName("v1", 2, ICPPVariable.class);
ICPPVariable v2= getBindingFromASTName("v1", 2, ICPPVariable.class);
IType t1= v1.getType();
assertInstance(t1, ICPPTemplateInstance.class);
ICPPTemplateInstance inst= (ICPPTemplateInstance) t1;
final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition();
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments());
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments(), name);
assertSame(inst, inst2);
IBinding charInst1= 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))});
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))}, name);
assertSame(charInst1, charInst2);
}

View file

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

View file

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

View file

@ -13,6 +13,7 @@
package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet;
/**
@ -87,34 +88,106 @@ public interface IScope {
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
* 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 Use {@link #getBindings(ScopeLookupData)} instead
*/
@Deprecated
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
* 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
* @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
* @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
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
*/
public IType getFieldOwnerType();
/**
* @since 5.4
*/
@Override
public ICPPASTExpression getFieldOwner();
}

View file

@ -12,7 +12,7 @@
package org.eclipse.cdt.core.dom.ast.cpp;
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
@ -26,5 +26,5 @@ public interface ICPPASTInitializerClause extends IASTInitializerClause {
* Returns the evaluation object for this expression.
* @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;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
/**
@ -24,9 +25,16 @@ public interface ICPPClassSpecialization extends ICPPSpecialization, ICPPClassTy
@Override
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
* 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.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
/**
* Base implementation for all ambiguous nodes.
@ -163,4 +164,7 @@ public abstract class ASTAmbiguousNode extends ASTNode {
public final boolean isLValue() {
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.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer;
@ -35,8 +33,6 @@ import org.eclipse.cdt.internal.core.parser.scanner.Token;
* Base class for all non-preprocessor nodes in the AST.
*/
public abstract class ASTNode implements IASTNode {
protected static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null);
private IASTNode parent;
private ASTNodeProperty property;

View file

@ -100,7 +100,7 @@ public abstract class ASTTypeIdInitializerExpression extends ASTNode implements
}
@Override
public final ValueCategory getValueCategory() {
public ValueCategory getValueCategory() {
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,15 +8,14 @@
* Contributors:
* 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 {
CPPUnknownFunctionType() {
super(CPPUnknownClass.createUnnamedInstance(), IType.EMPTY_TYPE_ARRAY);
}
public interface ISerializableEvaluation {
void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException;
}

View file

@ -20,16 +20,35 @@ import org.eclipse.core.runtime.CoreException;
*/
public interface ITypeMarshalBuffer {
final static byte BASIC_TYPE= 1;
final static byte POINTER= 2;
final static byte ARRAY= 3;
final static byte CVQUALIFIER= 4;
final static byte POINTER_TYPE= 2;
final static byte ARRAY_TYPE= 3;
final static byte CVQUALIFIER_TYPE= 4;
final static byte FUNCTION_TYPE= 5;
final static byte REFERENCE= 6;
final static byte POINTER_TO_MEMBER= 7;
final static byte PACK_EXPANSION= 8;
final static byte REFERENCE_TYPE= 6;
final static byte POINTER_TO_MEMBER_TYPE= 7;
final static byte PACK_EXPANSION_TYPE= 8;
final static byte PROBLEM_TYPE= 9;
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 FLAG2 = 0x20;
@ -41,6 +60,7 @@ public interface ITypeMarshalBuffer {
IType unmarshalType() throws CoreException;
IValue unmarshalValue() throws CoreException;
IBinding unmarshalBinding() throws CoreException;
ISerializableEvaluation unmarshalEvaluation() throws CoreException;
int getByte() throws CoreException;
int getShort() throws CoreException;
long getLong() throws CoreException;
@ -49,6 +69,7 @@ public interface ITypeMarshalBuffer {
void marshalType(IType type) throws CoreException;
void marshalValue(IValue value) throws CoreException;
void marshalBinding(IBinding binding) throws CoreException;
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void putByte(byte data);
void putShort(short data);
void putLong(long data);

View file

@ -211,8 +211,20 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
/* (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)
*/
@Override
public IBinding[] getBindings(ScopeLookupData lookup) {
return IBinding.EMPTY_BINDING_ARRAY;
}

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.dom.parser;
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.internal.core.parser.ParserMessages;
import org.eclipse.core.runtime.CoreException;
@ -20,6 +21,7 @@ import org.eclipse.core.runtime.CoreException;
*/
public class ProblemType implements IProblemType, ISerializableType {
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;

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.IASTIdExpression;
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.IASTUnaryExpression;
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.parser.util.CharArrayUtils;
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.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
@ -75,7 +77,7 @@ public class Value implements IValue {
private static class Reevaluation {
public final char[] fExpression;
private int fPackOffset;
private final int fPackOffset;
public int pos=0;
public final Map<String, Integer> fUnknownSigs;
public final List<ICPPUnknownBinding> fUnknowns;
@ -989,4 +991,9 @@ public class Value implements IValue {
buf.getChars(0, len, result, 0);
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;
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.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -105,7 +104,6 @@ public class CASTIdExpression extends ASTNode implements IASTIdExpression, IASTC
@Override
public IType getExpressionType() {
IBinding binding = getName().resolveBinding();
try {
if (binding instanceof IVariable) {
return ((IVariable)binding).getType();
}
@ -118,9 +116,6 @@ public class CASTIdExpression extends ASTNode implements IASTIdExpression, IASTC
if (binding instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME);
}
} catch (DOMException e) {
return e.getProblem();
}
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}

View file

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

View file

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

View file

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

View file

@ -247,7 +247,7 @@ public class CScope implements ICScope, IASTInternalScope {
@Override
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
@ -332,14 +332,26 @@ public class CScope implements ICScope, IASTInternalScope {
/* (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) {
char[] c = name.toCharArray();
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)
*/
@Override
public final IBinding[] getBindings(ScopeLookupData lookup) {
char[] c = lookup.getLookupKey();
Object[] obj = null;
populateCache();
for (CharArrayObjectMap<?> map : mapsToNameOrBinding) {
if (prefixLookup) {
if (lookup.isPrefixLookup()) {
IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c);
Object[] keys = map.keyArray();
for (Object key2 : keys) {
@ -358,11 +370,12 @@ public class CScope implements ICScope, IASTInternalScope {
IIndex index = tu.getIndex();
if (index != null) {
try {
IBinding[] bindings = prefixLookup ?
index.findBindingsForContentAssist(name.toCharArray(), true, INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null) :
index.findBindings(name.toCharArray(), INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null);
if (fileSet != null) {
bindings = fileSet.filterFileLocalBindings(bindings);
IBinding[] bindings = lookup.isPrefixLookup() ?
index.findBindingsForContentAssist(lookup.getLookupKey(), true, INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null) :
index.findBindings(lookup.getLookupKey(), INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null);
IIndexFileSet filter = lookup.getIncludedFiles();
if (filter != null) {
bindings = filter.filterFileLocalBindings(bindings);
}
obj = ArrayUtil.addAll(Object.class, obj, bindings);
@ -387,7 +400,7 @@ public class CScope implements ICScope, IASTInternalScope {
if (n != null) {
IBinding b = n.getBinding();
if (b == null) {
if (resolve && n != name) {
if (lookup.isResolve() && n != lookup.getLookupPoint()) {
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.IProblemBinding;
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.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
@ -356,7 +357,7 @@ public class CVisitor extends ASTQueries {
public static class CollectReferencesAction extends ASTVisitor {
private static final int DEFAULT_LIST_SIZE = 8;
private IASTName[] refs;
private IBinding binding;
private final IBinding binding;
private int idx = 0;
private int kind;
@ -1065,23 +1066,11 @@ public class CVisitor extends ASTQueries {
if (scope == 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;
CharArraySet handled= new CharArraySet(1);
while (scope != null) {
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) {
final char[] n= b.getNameCharArray();
// 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.EScopeKind;
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.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -63,11 +64,11 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
@Override
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
public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) {
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) {
char[] c = name.getLookupKey();
if (CharArrayUtils.equals(c, specialClass.getNameCharArray())
@ -77,44 +78,39 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
ICPPClassType specialized = specialClass.getSpecializedBinding();
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)
return null;
IBinding[] specs = new IBinding[0];
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);
return CPPSemantics.resolveAmbiguities(name, specs);
}
@Override
final public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup,
@Deprecated @Override
final public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
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,
IIndexFileSet fileSet, boolean checkPointOfDecl) {
@Override
final public IBinding[] getBindings(ScopeLookupData lookup) {
ICPPClassType specialized = specialClass.getSpecializedBinding();
IScope classScope = specialized.getCompositeScope();
if (classScope == null)
return IBinding.EMPTY_BINDING_ARRAY;
IBinding[] bindings;
if (classScope instanceof ICPPASTInternalScope) {
bindings= ((ICPPASTInternalScope) classScope).getBindings(name, forceResolve, prefixLookup, fileSet, checkPointOfDecl);
} else {
bindings= classScope.getBindings(name, forceResolve, prefixLookup, fileSet);
}
IBinding[] bindings= classScope.getBindings(lookup);
IBinding[] result= null;
for (IBinding binding : bindings) {
if (binding == specialized) {
binding= specialClass;
} else {
binding= specialClass.specializeMember(binding);
binding= specialClass.specializeMember(binding, lookup.getLookupPoint());
}
result = ArrayUtil.append(IBinding.class, result, binding);
}
@ -134,11 +130,12 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
if (bases.length == 0) {
fBases= bases;
} else {
IASTNode point= null; // Instantiation of dependent expression may not work.
final ICPPTemplateParameterMap tpmap = specialClass.getTemplateParameterMap();
for (ICPPBase base : bases) {
IBinding origClass = base.getBaseClass();
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) {
result= ArrayUtil.append(ICPPBase.class, result, base);
} else {
@ -155,7 +152,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
}
if (origClass instanceof IType) {
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);
if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) {
specBase.setBaseClass((IBinding) specClass);
@ -172,31 +169,33 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
}
@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)
return array;
T[] newArray= array.clone();
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;
}
@Override
public ICPPField[] getDeclaredFields() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields();
return specializeMembers(fields);
return specializeMembers(fields, point);
}
@Override
public ICPPMethod[] getImplicitMethods() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPClassScope origClassScope= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope();
if (origClassScope == null) {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
ICPPMethod[] methods= origClassScope.getImplicitMethods();
return specializeMembers(methods);
return specializeMembers(methods, point);
}
@Override
@ -208,26 +207,31 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
@Override
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();
return specializeMembers(ctors);
return specializeMembers(ctors, point);
}
@Override
public ICPPMethod[] getDeclaredMethods() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods();
return specializeMembers(bindings);
return specializeMembers(bindings, point);
}
@Override
public ICPPClassType[] getNestedClasses() {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses();
return specializeMembers(bindings);
return specializeMembers(bindings, point);
}
@Override
public IBinding[] getFriends() {
IASTNode point= null; // Instantiation of dependent expression may not work.
IBinding[] friends = specialClass.getSpecializedBinding().getFriends();
return specializeMembers(friends);
return specializeMembers(friends, point);
}
@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.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
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) {
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.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
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) {
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.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
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.IASTAmbiguousExpression;
public class CPPASTAmbiguousExpression extends ASTAmbiguousNode implements
IASTAmbiguousExpression {
IASTAmbiguousExpression, ICPPASTExpression {
private IASTExpression [] exp = new IASTExpression[2];
private int expPos=-1;

View file

@ -13,42 +13,28 @@
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.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.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
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.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.internal.core.dom.parser.ASTNode;
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.Conversions;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTArraySubscriptExpression extends ASTNode
implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent {
private IASTExpression arrayExpression;
private IASTInitializerClause subscriptExp;
private ICPPFunction overload= UNINITIALIZED_FUNCTION;
private ICPPASTExpression arrayExpression;
private ICPPASTInitializerClause subscriptExp;
private ICPPEvaluation evaluation;
private IASTImplicitName[] implicitNames;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTArraySubscriptExpression() {
}
@ -76,33 +62,37 @@ public class CPPASTArraySubscriptExpression extends ASTNode
}
@Override
public IASTExpression getArrayExpression() {
public ICPPASTExpression getArrayExpression() {
return arrayExpression;
}
@Override
public void setArrayExpression(IASTExpression expression) {
assertNotFrozen();
arrayExpression = expression;
if (expression != null) {
if (!(expression instanceof ICPPASTExpression))
throw new IllegalArgumentException(expression.getClass().getName());
expression.setParent(this);
expression.setPropertyInParent(ARRAY);
}
arrayExpression = (ICPPASTExpression) expression;
}
@Override
public IASTInitializerClause getArgument() {
public ICPPASTInitializerClause getArgument() {
return subscriptExp;
}
@Override
public void setArgument(IASTInitializerClause arg) {
assertNotFrozen();
subscriptExp = arg;
if (arg != null) {
if (!(arg instanceof ICPPASTInitializerClause))
throw new IllegalArgumentException(arg.getClass().getName());
arg.setParent(this);
arg.setPropertyInParent(SUBSCRIPT);
}
subscriptExp = (ICPPASTInitializerClause) arg;
}
@Override
@ -142,16 +132,11 @@ public class CPPASTArraySubscriptExpression extends ASTNode
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;
private ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalBinary)
return ((EvalBinary) eval).getOverload(this);
return null;
}
@Override
@ -192,56 +177,41 @@ public class CPPASTArraySubscriptExpression extends ASTNode
if (child == subscriptExp) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
subscriptExp = (IASTExpression) other;
subscriptExp = (ICPPASTExpression) other;
}
if (child == arrayExpression) {
other.setPropertyInParent(child.getPropertyInParent());
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
public IType getExpressionType() {
ICPPFunction op = getOverload();
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);
return getEvaluation().getTypeOrFunctionSet(this);
}
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
public boolean isLValue() {
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;
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.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.IASTInitializerClause;
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.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.ICPPFunctionType;
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.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.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
private int op;
private IASTExpression operand1;
private IASTInitializerClause operand2;
private IType type;
private ICPPFunction overload= UNINITIALIZED_FUNCTION;
private ICPPASTExpression operand1;
private ICPPASTInitializerClause operand2;
private ICPPEvaluation evaluation;
private IASTImplicitName[] implicitNames = null;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTBinaryExpression() {
}
@ -107,20 +96,25 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
@Override
public void setOperand1(IASTExpression expression) {
assertNotFrozen();
operand1 = expression;
if (expression != null) {
if (!(expression instanceof ICPPASTExpression))
throw new IllegalArgumentException(expression.getClass().getName());
expression.setParent(this);
expression.setPropertyInParent(OPERAND_ONE);
}
operand1 = (ICPPASTExpression) expression;
}
public void setInitOperand2(IASTInitializerClause operand) {
assertNotFrozen();
operand2 = operand;
if (operand != null) {
if (!(operand instanceof ICPPASTInitializerClause))
throw new IllegalArgumentException(operand.getClass().getName());
operand.setParent(this);
operand.setPropertyInParent(OPERAND_TWO);
}
operand2 = (ICPPASTInitializerClause) operand;
}
@Override
@ -251,144 +245,51 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
if (child == operand1) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
operand1 = (IASTExpression) other;
operand1 = (ICPPASTExpression) other;
}
if (child == operand2) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
operand2 = (IASTInitializerClause) other;
operand2 = (ICPPASTInitializerClause) other;
}
}
@Override
public ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalBinary)
return ((EvalBinary) eval).getOverload(this);
return null;
}
@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() {
if (type == null) {
type= createExpressionType();
}
return type;
}
@Override
public ICPPFunction getOverload() {
if (overload != UNINITIALIZED_FUNCTION)
return overload;
return overload = CPPSemantics.findOverloadedOperator(this);
return getEvaluation().getTypeOrFunctionSet(this);
}
@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;
return getEvaluation().getValueCategory(this);
}
@Override
public boolean isLValue() {
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,27 +11,23 @@
*******************************************************************************/
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.IASTBinaryTypeIdExpression;
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.cpp.ICPPASTExpression;
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 {
private Operator fOperator;
private IASTTypeId fOperand1;
private IASTTypeId fOperand2;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
private ICPPEvaluation fEvaluation;
public CPPASTBinaryTypeIdExpression() {
}
@ -122,12 +118,26 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr
}
@Override
public IType getExpressionType() {
switch (getOperator()) {
case __is_base_of:
return CPPBasicType.BOOLEAN;
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
if (fOperand1 == null || fOperand2 == null) {
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
@ -137,6 +147,6 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr
@Override
public ValueCategory getValueCategory() {
return isLValue() ? LVALUE : PRVALUE;
return PRVALUE;
}
}

View file

@ -12,33 +12,29 @@
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.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.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
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.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.IASTAmbiguityParent;
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++
*/
public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpression, IASTAmbiguityParent {
private int op;
private IASTExpression operand;
private ICPPASTExpression operand;
private IASTTypeId typeId;
private IType fType;
private ValueCategory fValueCategory;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
private ICPPEvaluation fEvaluation;
public CPPASTCastExpression() {
}
@ -102,7 +98,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
@Override
public void setOperand(IASTExpression expression) {
assertNotFrozen();
operand = expression;
operand = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(OPERAND);
@ -138,26 +134,38 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
if (child == operand) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
operand = (IASTExpression) other;
operand = (ICPPASTExpression) other;
}
}
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null)
fEvaluation= computeEvaluation();
return fEvaluation;
}
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() {
if (fType == null) {
IType t= CPPVisitor.createType(typeId.getAbstractDeclarator());
fValueCategory= valueCategoryFromReturnType(t);
fType= typeFromReturnType(t);
}
return fType;
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
if (fValueCategory == null) {
getExpressionType(); // as a side effect fValueCategory is computed
}
return fValueCategory;
return getEvaluation().getValueCategory(this);
}
@Override

View file

@ -12,18 +12,17 @@
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.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
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.cpp.ICPPASTExpression;
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.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: ({ ... })
@ -31,14 +30,25 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUASTCompoundStatementExpression, ICPPASTExpression {
private IASTCompoundStatement statement;
private ICPPEvaluation fEval;
public CPPASTCompoundStatementExpression() {
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
public ICPPEvaluation getEvaluation() {
if (fEval == 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) {
@ -100,14 +110,7 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS
@Override
public IType getExpressionType() {
IASTCompoundStatement compound = getCompoundStatement();
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);
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override

View file

@ -12,53 +12,28 @@
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.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.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
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.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.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.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;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTConditionalExpression extends ASTNode implements IASTConditionalExpression,
ICPPASTExpression, IASTAmbiguityParent {
private IASTExpression fCondition;
private IASTExpression fPositive;
private IASTExpression fNegative;
private IType fType;
private ValueCategory fValueCategory;
private ICPPASTExpression fCondition;
private ICPPASTExpression fPositive;
private ICPPASTExpression fNegative;
private ICPPEvaluation fEval;
public CPPASTConditionalExpression() {
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTConditionalExpression(IASTExpression condition, IASTExpression postive, IASTExpression negative) {
setLogicalConditionExpression(condition);
@ -92,7 +67,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
@Override
public void setLogicalConditionExpression(IASTExpression expression) {
assertNotFrozen();
fCondition = expression;
fCondition = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(LOGICAL_CONDITION);
@ -107,7 +82,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
@Override
public void setPositiveResultExpression(IASTExpression expression) {
assertNotFrozen();
this.fPositive = expression;
this.fPositive = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(POSITIVE_RESULT);
@ -122,7 +97,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
@Override
public void setNegativeResultExpression(IASTExpression expression) {
assertNotFrozen();
this.fNegative = expression;
this.fNegative = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(NEGATIVE_RESULT);
@ -157,157 +132,17 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
if (child == fCondition) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
fCondition = (IASTExpression) other;
fCondition = (ICPPASTExpression) other;
}
if (child == fPositive) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
fPositive = (IASTExpression) other;
fPositive = (ICPPASTExpression) other;
}
if (child == fNegative) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
fNegative = (IASTExpression) 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);
}
}
fNegative = (ICPPASTExpression) other;
}
}
@ -326,50 +161,33 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio
return false;
}
private Cost convertToMatch(IType t1, ValueCategory vcat1, IType uqt1, IType t2, ValueCategory vcat2, IType uqt2) {
// 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);
if (c.converts()) {
fType= t2;
fValueCategory= vcat2;
return c;
@Override
public ICPPEvaluation getEvaluation() {
if (fEval == null) {
if (fCondition == null || fNegative == null) {
fEval= EvalFixed.INCOMPLETE;
} else {
final ICPPEvaluation condEval = fCondition.getEvaluation();
final ICPPEvaluation posEval = fPositive == null ? null : fPositive.getEvaluation();
fEval= new EvalConditional(condEval, posEval, fNegative.getEvaluation(),
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;
}
private boolean isVoidType(IType t) {
return t instanceof ICPPBasicType && ((ICPPBasicType) t).getKind() == Kind.eVoid;
@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

@ -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.ICPPFunction;
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.EvalFixed;
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
private static final ICPPEvaluation EVALUATION = new EvalFixed(CPPSemantics.VOID_TYPE, PRVALUE, Value.UNKNOWN);
private IASTExpression operand;
private boolean isGlobal;
private boolean isVectored;
private IASTImplicitName[] implicitNames = null;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTDeleteExpression() {
}
@ -172,6 +171,11 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
return true;
}
@Override
public ICPPEvaluation getEvaluation() {
return EVALUATION;
}
@Override
public IType getExpressionType() {
return CPPSemantics.VOID_TYPE;

View file

@ -13,30 +13,22 @@
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.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.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
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.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
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.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
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.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.EvalComma;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
private static final ICPPFunction[] NO_FUNCTIONS = {};
private IASTExpression[] expressions = new IASTExpression[2];
@ -45,13 +37,8 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
* @see CPPASTExpressionList#computeImplicitNames
*/
private IASTImplicitName[] implicitNames;
private ICPPFunction[] overloads;
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
private ICPPEvaluation fEvaluation;
@Override
public CPPASTExpressionList copy() {
@ -155,42 +142,11 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
}
private ICPPFunction[] getOverloads() {
if (overloads == null) {
IASTExpression[] exprs = getExpressions();
if (exprs.length < 2)
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);
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalComma) {
return ((EvalComma) eval).getOverloads(this);
}
}
}
}
return overloads;
return null;
}
@Override
@ -205,41 +161,34 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
}
}
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null)
fEvaluation= computeEvaluation();
return fEvaluation;
}
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() {
ICPPFunction[] overloads = getOverloads();
if (overloads.length > 0) {
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 getEvaluation().getTypeOrFunctionSet(this);
}
@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;
return getEvaluation().getValueCategory(this);
}
@Override

View file

@ -14,57 +14,45 @@
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.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.Collection;
import java.util.List;
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.IASTImplicitName;
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.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.ISemanticProblem;
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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
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.ICPPConstructor;
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.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
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.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.CVQualifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
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.EvalID;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
public class CPPASTFieldReference extends ASTNode
implements ICPPASTFieldReference, IASTAmbiguityParent, ICPPASTCompletionContext {
private boolean isTemplate;
private IASTExpression owner;
private ICPPASTExpression owner;
private IASTName name;
private boolean isDeref;
private IASTImplicitName[] implicitNames;
private ICPPEvaluation fEvaluation;
public CPPASTFieldReference() {
}
@ -73,11 +61,6 @@ public class CPPASTFieldReference extends ASTNode
setFieldName(name);
setFieldOwner(owner);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public CPPASTFieldReference copy() {
@ -110,14 +93,14 @@ public class CPPASTFieldReference extends ASTNode
}
@Override
public IASTExpression getFieldOwner() {
public ICPPASTExpression getFieldOwner() {
return owner;
}
@Override
public void setFieldOwner(IASTExpression expression) {
assertNotFrozen();
owner = expression;
owner = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(FIELD_OWNER);
@ -158,7 +141,7 @@ public class CPPASTFieldReference extends ASTNode
// Collect the function bindings
List<ICPPFunction> functionBindings = new ArrayList<ICPPFunction>();
getFieldOwnerType(functionBindings);
EvalMemberAccess.getFieldOwnerType(owner.getExpressionType(), isDeref, this, functionBindings, false);
if (functionBindings.isEmpty())
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
@ -224,100 +207,10 @@ public class CPPASTFieldReference extends ASTNode
if (child == owner) {
other.setPropertyInParent(child.getPropertyInParent());
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
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces);
@ -347,56 +240,63 @@ public class CPPASTFieldReference extends ASTNode
*/
@Override
public IType getFieldOwnerType() {
return getFieldOwnerType(null);
return EvalMemberAccess.getFieldOwnerType(owner.getExpressionType(), isDeref, this, null, true);
}
/*
* Also collects the function bindings if requested.
*/
private IType getFieldOwnerType(Collection<ICPPFunction> functionBindings) {
final IASTExpression owner = getFieldOwner();
if (owner == null)
return null;
IType type= owner.getExpressionType();
if (!isPointerDereference())
return type;
// bug 205964: as long as the type is a class type, recurse.
// Be defensive and allow a max of 20 levels.
for (int j = 0; j < 20; j++) {
// for unknown types we cannot determine the overloaded -> operator
IType classType= getUltimateTypeUptoPointers(type);
if (classType instanceof ICPPUnknownType)
return CPPUnknownClass.createUnnamedInstance();
if (!(classType instanceof ICPPClassType))
break;
/*
* 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);
if (op == null)
break;
if (functionBindings != null)
functionBindings.add(op);
type= typeFromFunctionCall(op);
type= SemanticUtil.mapToAST(type, owner);
@Override
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= createEvaluation();
}
return fEvaluation;
}
IType prValue= prvalueTypeWithResolvedTypedefs(type);
if (prValue instanceof IPointerType) {
return glvalueType(((IPointerType) prValue).getType());
private ICPPEvaluation createEvaluation() {
ICPPEvaluation ownerEval = owner.getEvaluation();
if (!ownerEval.isTypeDependent()) {
IType ownerType= EvalMemberAccess.getFieldOwnerType(ownerEval.getTypeOrFunctionSet(this), isDeref, this, null, false);
if (ownerType != null) {
IBinding binding = name.resolvePreBinding();
if (binding instanceof CPPFunctionSet)
binding= name.resolveBinding();
if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor)
return EvalFixed.INCOMPLETE;
return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, isDeref);
}
}
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;
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.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 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.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.IASTNode;
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.cpp.ICPPASTExpression;
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.ICPPClassType;
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.internal.core.dom.parser.ASTNode;
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.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.SemanticUtil;
public class CPPASTFunctionCallExpression extends ASTNode
implements ICPPASTFunctionCallExpression, IASTAmbiguityParent {
private IASTExpression functionName;
private ICPPASTExpression functionName;
private IASTInitializerClause[] fArguments;
private IASTImplicitName[] implicitNames;
private ICPPFunction overload= UNINITIALIZED_FUNCTION;
private ICPPEvaluation evaluation;
public CPPASTFunctionCallExpression() {
setArguments(null);
@ -71,11 +57,6 @@ public class CPPASTFunctionCallExpression extends ASTNode
setFunctionNameExpression(functionName);
setArguments(args);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public CPPASTFunctionCallExpression copy() {
@ -105,7 +86,7 @@ public class CPPASTFunctionCallExpression extends ASTNode
@Override
public void setFunctionNameExpression(IASTExpression expression) {
assertNotFrozen();
this.functionName = expression;
this.functionName = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(FUNCTION_NAME);
@ -134,11 +115,11 @@ public class CPPASTFunctionCallExpression extends ASTNode
@Override
public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) {
ICPPFunction overload = getOperator();
ICPPFunction overload = getOverload();
if (overload == null)
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
if (isExplicitTypeConversion() != null) {
if (getEvaluation() instanceof EvalTypeId) {
CPPASTImplicitName n1 = new CPPASTImplicitName(overload.getNameCharArray(), this);
n1.setOffsetAndLength((ASTNode) functionName);
n1.setBinding(overload);
@ -227,7 +208,7 @@ public class CPPASTFunctionCallExpression extends ASTNode
if (child == functionName) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
functionName = (IASTExpression) other;
functionName = (ICPPASTExpression) other;
}
for (int i = 0; i < fArguments.length; ++i) {
if (child == fArguments[i]) {
@ -238,112 +219,7 @@ 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
@Deprecated
@ -380,4 +256,82 @@ public class CPPASTFunctionCallExpression extends ASTNode
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;
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.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding;
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.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.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.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.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;
public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext {
private static final ICPPASTFieldReference NOT_INITIALIZED = new CPPASTFieldReference();
private IASTName name;
private ICPPASTFieldReference fTransformedExpression= NOT_INITIALIZED;
private ICPPEvaluation fEvaluation;
public CPPASTIdExpression() {
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTIdExpression(IASTName name) {
setName(name);
@ -126,120 +98,6 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP
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
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] 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) {
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.IASTInitializerClause;
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.parser.util.ArrayUtil;
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.cpp.semantics.EvalInitList;
/**
* e.g.: int a[]= {1,2,3};
*/
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 actualSize;
private boolean fIsPackExpansion;
private ICPPEvaluation fEvaluation;
@Override
public CPPASTInitializerList copy() {
return copy(CopyStyle.withoutLocations);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public CPPASTInitializerList copy(CopyStyle style) {
@ -62,10 +61,10 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer
}
@Override
public IASTInitializerClause[] getClauses() {
public ICPPASTInitializerClause[] getClauses() {
if (initializers == null)
return IASTExpression.EMPTY_EXPRESSION_ARRAY;
initializers = ArrayUtil.trimAt(IASTInitializerClause.class, initializers, initializersPos);
return NO_CLAUSES;
initializers = ArrayUtil.trimAt(ICPPASTInitializerClause.class, initializers, initializersPos);
return initializers;
}
@ -95,7 +94,7 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer
public void addClause(IASTInitializerClause d) {
assertNotFrozen();
if (d != null) {
initializers = ArrayUtil.appendAt( IASTInitializerClause.class, initializers, ++initializersPos, d );
initializers = ArrayUtil.appendAt(ICPPASTInitializerClause.class, initializers, ++initializersPos, (ICPPASTInitializerClause) d);
d.setParent(this);
d.setPropertyInParent(NESTED_INITIALIZER);
}
@ -154,9 +153,25 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer
if (child == initializers[i]) {
other.setPropertyInParent(child.getPropertyInParent());
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;
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.IASTCompoundStatement;
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.parser.util.ArrayUtil;
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.
@ -32,18 +36,14 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
private IASTCompoundStatement fBody;
private CPPClosureType fClosureType;
private IASTImplicitName fClosureTypeName;
private IASTImplicitName fImplicitFunctionCallName;
private ICPPEvaluation fEvaluation;
public CPPASTLambdaExpression() {
fCaptureDefault= CaptureDefault.UNSPECIFIED;
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTExpression#copy()
@ -206,11 +206,16 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
}
@Override
public CPPClosureType getExpressionType() {
if (fClosureType == null)
fClosureType= new CPPClosureType(this);
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
fEvaluation= new EvalFixed(new CPPClosureType(this), PRVALUE, Value.UNKNOWN);
}
return fEvaluation;
}
return fClosureType;
@Override
public CPPClosureType getExpressionType() {
return (CPPClosureType) getEvaluation().getTypeOrFunctionSet(this);
}
@Override

View file

@ -11,38 +11,41 @@
*******************************************************************************/
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.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
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.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
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.ProblemType;
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.EvalFixed;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
/**
* Represents a C++ literal.
*/
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 =
new CPPASTLiteralExpression(lk_integer_constant, new char[] {'0'});
private int kind;
private char[] value = CharArrayUtils.EMPTY;
private ICPPEvaluation fEvaluation;
public CPPASTLiteralExpression() {
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTLiteralExpression(int kind, char[] value) {
this.kind = kind;
@ -111,46 +114,6 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
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() {
char[] value= getValue();
int length= value.length-1;
@ -261,4 +224,74 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
public CPPASTLiteralExpression(int kind, String value) {
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.ASTQueries;
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.cpp.semantics.CPPSemantics;
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;
@ -49,6 +51,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
private boolean isNewTypeId;
private IASTExpression[] cachedArraySizes;
private ICPPEvaluation fEvaluation;
public CPPASTNewExpression() {
}
@ -58,11 +61,6 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
setTypeId(typeId);
setInitializer(initializer);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public CPPASTNewExpression copy() {
@ -249,12 +247,20 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
}
@Override
public IType getExpressionType() {
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
IType t= CPPVisitor.createType(getTypeId());
if (t instanceof IArrayType) {
t= ((IArrayType) t).getType();
}
return new CPPPointerType(t);
fEvaluation= new EvalFixed(new CPPPointerType(t), PRVALUE, Value.UNKNOWN);
}
return fEvaluation;
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override

View file

@ -10,22 +10,25 @@
*******************************************************************************/
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.IASTExpression;
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.cpp.ICPPASTPackExpansionExpression;
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.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.
*/
public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPackExpansionExpression, IASTAmbiguityParent {
private IASTExpression fPattern;
private ICPPEvaluation fEvaluation;
public CPPASTPackExpansionExpression(IASTExpression pattern) {
setPattern(pattern);
@ -41,11 +44,6 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
pattern.setPropertyInParent(ICPPASTPackExpansionExpression.PATTERN);
}
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public IASTExpression getPattern() {
@ -68,12 +66,22 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
}
@Override
public IType getExpressionType() {
final IType type = fPattern.getExpressionType();
if (type == null)
return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, getRawSignatureChars());
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;
}
return new CPPParameterPackType(type);
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override

View file

@ -11,13 +11,14 @@
*******************************************************************************/
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.IASTProblem;
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.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 {
@ -33,12 +34,6 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
public CPPASTProblemExpression copy() {
return copy(CopyStyle.withoutLocations);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public CPPASTProblemExpression copy(CopyStyle style) {
CPPASTProblemExpression copy = new CPPASTProblemExpression();
@ -65,18 +60,23 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
return true;
}
@Override
public ICPPEvaluation getEvaluation() {
return EvalFixed.INCOMPLETE;
}
@Override
public IType getExpressionType() {
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public boolean isLValue() {
return false;
return getValueCategory() == LVALUE;
}
@Override
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;
} else if (type instanceof ICPPClassType) {
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);
name.setOffset(position.getOffset());
CPPASTFieldReference fieldRef = new CPPASTFieldReference(name, forInitExpr.copy());

View file

@ -11,26 +11,28 @@
*******************************************************************************/
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.IASTExpression;
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.IType;
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.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.ICPPBasicType;
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.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
ICPPASTSimpleTypeConstructorExpression {
private ICPPASTDeclSpecifier fDeclSpec;
private IASTInitializer fInitializer;
private IType fType;
private ICPPEvaluation fEvaluation;
public CPPASTSimpleTypeConstructorExpression() {
}
@ -39,11 +41,6 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
setDeclSpecifier(declSpec);
setInitializer(init);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public CPPASTSimpleTypeConstructorExpression copy() {
@ -93,11 +90,34 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
}
@Override
public IType getExpressionType() {
if (fType == null) {
fType= prvalueType(CPPVisitor.createType(fDeclSpec));
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();
}
return fType;
fEvaluation= new EvalTypeId(type, args);
} else if (fInitializer instanceof ICPPASTInitializerList) {
fEvaluation= new EvalTypeId(type, ((ICPPASTInitializerList) fInitializer).getEvaluation());
} else {
fEvaluation= EvalFixed.INCOMPLETE;
}
}
return fEvaluation;
}
@Override
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this);
}
@Override
@ -105,11 +125,6 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements
return false;
}
@Override
public ValueCategory getValueCategory() {
return PRVALUE;
}
@Override
public boolean accept(ASTVisitor action) {
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.IFunction;
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.ICPPFunction;
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.
*/
public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTAmbiguousExpression {
public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTAmbiguousExpression,
ICPPASTExpression {
private BinaryOperator fLastOperator;
private IASTInitializerClause fLastExpression;
private final BranchPoint fVariants;
private IASTNode[] fNodes;
private AbstractGNUSourceCodeParser fParser;
private final AbstractGNUSourceCodeParser fParser;
public CPPASTTemplateIDAmbiguity(AbstractGNUSourceCodeParser parser, BinaryOperator lastOperator, IASTInitializerClause expr,
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.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.IBasicType;
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.
public ICPPClassType mapToAST(ICPPClassType binding) {
return fScopeMapper.mapToAST(binding);
public ICPPClassType mapToAST(ICPPClassType binding, IASTNode point) {
return fScopeMapper.mapToAST(binding, point);
}
/**

View file

@ -12,18 +12,21 @@
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.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.IType;
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.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 {
private int op;
private IASTTypeId typeId;
private ICPPEvaluation fEvaluation;
public CPPASTTypeIdExpression() {
}
@ -32,11 +35,6 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
this.op = op;
setTypeId(typeId);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public CPPASTTypeIdExpression copy() {
@ -103,43 +101,30 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
}
@Override
public IType getExpressionType() {
switch (getOperator()) {
case op_sizeof:
case op_alignof:
return CPPVisitor.get_SIZE_T(this);
case op_typeid:
return CPPVisitor.get_type_info(this);
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;
public ICPPEvaluation getEvaluation() {
if (fEvaluation == null) {
IType type= CPPVisitor.createType(typeId);
if (type == null || type instanceof IProblemType) {
fEvaluation= EvalFixed.INCOMPLETE;
} else {
fEvaluation= new EvalUnaryTypeID(op, type);
}
return CPPVisitor.createType(getTypeId());
}
return fEvaluation;
}
@Override
public boolean isLValue() {
switch (getOperator()) {
case op_typeid:
return true;
}
return false;
public IType getExpressionType() {
return getEvaluation().getTypeOrFunctionSet(this);
}
@Override
public ValueCategory getValueCategory() {
return isLValue() ? LVALUE : PRVALUE;
return getEvaluation().getValueCategory(this);
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
}

View file

@ -10,32 +10,31 @@
*******************************************************************************/
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.IASTTypeId;
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.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.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 }
*/
public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpression implements ICPPASTExpression {
private ICPPEvaluation fEvaluation;
private CPPASTTypeIdInitializerExpression() {
}
public CPPASTTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) {
super(typeId, initializer);
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
@Override
public IASTTypeIdInitializerExpression copy() {
@ -49,9 +48,33 @@ public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpre
return expr;
}
@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() {
final IASTTypeId typeId = getTypeId();
return prvalueType(CPPVisitor.createType(typeId.getAbstractDeclarator()));
return getEvaluation().getTypeOrFunctionSet(this);
}
@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.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.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.IBinding;
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.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IProblemType;
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.ICPPASTUnaryExpression;
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.ICPPMethod;
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.ITypeContainer;
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.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
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++
*/
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
private int op;
private IASTExpression operand;
private ICPPFunction overload = UNINITIALIZED_FUNCTION;
private IASTImplicitName[] implicitNames = null;
private int fOperator;
private ICPPASTExpression fOperand;
private IASTImplicitName[] fImplicitNames = null;
private ICPPEvaluation fEvaluation;
public CPPASTUnaryExpression() {
}
@Override
public ICPPInitClauseEvaluation getEvaluation() {
// mstodo Auto-generated method stub
return null;
}
public CPPASTUnaryExpression(int operator, IASTExpression operand) {
op = operator;
fOperator = operator;
setOperand(operand);
}
@ -78,31 +67,35 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
@Override
public CPPASTUnaryExpression copy(CopyStyle style) {
CPPASTUnaryExpression copy =
new CPPASTUnaryExpression(op, operand == null ? null : operand.copy(style));
return copy(copy, style);
CPPASTUnaryExpression copy = new CPPASTUnaryExpression(fOperator, fOperand == null ? null
: fOperand.copy(style));
copy.setOffsetAndLength(this);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
}
@Override
public int getOperator() {
return op;
return fOperator;
}
@Override
public void setOperator(int operator) {
assertNotFrozen();
op = operator;
fOperator = operator;
}
@Override
public IASTExpression getOperand() {
return operand;
return fOperand;
}
@Override
public void setOperand(IASTExpression expression) {
assertNotFrozen();
operand = expression;
fOperand = (ICPPASTExpression) expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(OPERAND);
@ -110,7 +103,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
}
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
public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) {
if (fImplicitNames == null) {
ICPPFunction overload = getOverload();
if (overload == null || overload instanceof CPPImplicitFunction) {
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
} else {
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);
operatorName.setOperator(true);
operatorName.setBinding(overload);
operatorName.computeOperatorOffsets(operand, isPostfixOperator());
implicitNames = new IASTImplicitName[] { operatorName };
operatorName.computeOperatorOffsets(fOperand, isPostfixOperator());
fImplicitNames = new IASTImplicitName[] { operatorName };
}
}
return implicitNames;
return fImplicitNames;
}
@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;
if (isPostfix && action.shouldVisitImplicitNames) {
@ -175,27 +168,18 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
@Override
public void replace(IASTNode child, IASTNode other) {
if (child == operand) {
if (child == fOperand) {
other.setPropertyInParent(child.getPropertyInParent());
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() {
IASTNode child= operand;
if (fOperator != op_amper)
return null;
IASTNode child= fOperand;
boolean inParenthesis= false;
while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
child= ((IASTUnaryExpression) child).getOperand();
@ -203,136 +187,93 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
}
if (child instanceof IASTIdExpression) {
IASTName name= ((IASTIdExpression) child).getName();
if (name instanceof ICPPASTQualifiedName) {
IBinding b= name.resolveBinding();
if (b instanceof ICPPMember) {
ICPPMember member= (ICPPMember) b;
if (!member.isStatic()) {
try {
if (name instanceof ICPPASTQualifiedName) {
if (!member.isStatic()) { // so if the member is static it will fall through
overload= null;
if (!inParenthesis) {
return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false, false);
} 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();
}
}
}
}
}
return null;
}
@Override
public ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalUnary)
return ((EvalUnary) eval).getOverload(this);
return null;
}
@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() {
final int op= getOperator();
switch (op) {
case op_sizeof:
case op_sizeofParameterPack:
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;
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);
}
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 new CPPPointerType(type);
}
}
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;
return getEvaluation().getValueCategory(this);
}
@Override
public boolean isLValue() {
return getValueCategory() == LVALUE;
}
}

View file

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

View file

@ -226,9 +226,9 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
}
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
IIndexFileSet fileSet, boolean checkPointOfDecl) {
char[] c = name.getLookupKey();
public IBinding[] getBindings(ScopeLookupData lookup) {
char[] c = lookup.getLookupKey();
final boolean prefixLookup= lookup.isPrefixLookup();
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
IASTName compName = compType.getName().getLastName();
@ -238,16 +238,16 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
IBinding[] result = null;
if ((!prefixLookup && CharArrayUtils.equals(c, compName.getLookupKey()))
|| (prefixLookup && ContentAssistMatcherFactory.getInstance().match(c, compName.getLookupKey()))) {
if (shallReturnConstructors(name, prefixLookup)) {
result = ArrayUtil.addAll(IBinding.class, result, getConstructors(name, resolve));
final IASTName lookupName = lookup.getLookupName();
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
result = ArrayUtil.append(IBinding.class, result, compName.resolveBinding());
if (!prefixLookup)
return ArrayUtil.trim(IBinding.class, result);
}
result = ArrayUtil.addAll(IBinding.class, result,
super.getBindings(name, resolve, prefixLookup, fileSet, checkPointOfDecl));
result = ArrayUtil.addAll(IBinding.class, result, super.getBindings(lookup));
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) {
if (name == null)
return false;
if (!isPrefixLookup)
return CPPVisitor.isConstructorDeclaration(name);
if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY)
return false;
IASTNode node = name.getParent();
if (node instanceof ICPPASTTemplateId)
return false;

View file

@ -12,6 +12,9 @@
*******************************************************************************/
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.IASTNode;
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.parser.util.CharArrayUtils;
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.core.runtime.Assert;
/**
* Specialization of a class.
@ -41,8 +46,16 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
public class CPPClassSpecialization extends CPPSpecialization
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 ObjectMap specializationMap= ObjectMap.EMPTY_MAP;
private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>();
public CPPClassSpecialization(ICPPClassType specialized, IBinding owner, ICPPTemplateParameterMap argumentMap) {
super(specialized, owner, argumentMap);
@ -56,13 +69,28 @@ public class CPPClassSpecialization extends CPPSpecialization
@Override
public IBinding specializeMember(IBinding original) {
return specializeMember(original, null);
}
@Override
public IBinding specializeMember(IBinding original, IASTNode point) {
Set<IBinding> set;
synchronized(this) {
IBinding result= (IBinding) specializationMap.get(original);
if (result != null)
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) {
IBinding concurrent= (IBinding) specializationMap.get(original);
if (concurrent != null)

View file

@ -1,4 +1,4 @@
/*******************************************************************************
/*******************************************************************************
* Copyright (c) 2009, 2011 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
@ -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.IType;
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.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization;
@ -34,11 +33,14 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
private ObjectMap instances = null;
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);
fClassTemplate= template;
fArguments= args;
}
@Override
@ -96,17 +98,7 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
@Override
public ICPPTemplateArgument[] getTemplateArguments() {
ICPPTemplateArgument[] args = ((ICPPClassTemplatePartialSpecialization) getSpecializedBinding()).getTemplateArguments();
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;
}
return fArguments;
}
@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.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTNode;
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.ICPPClassTemplatePartialSpecialization;
@ -42,11 +43,12 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
@Override
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() {
if (fPartialSpecs == null) {
IASTNode point= null; // Instantiation of dependent expression may not work.
ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding();
ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations();
ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length];
for (int i = 0; i < orig.length; i++) {
spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i]);
spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i], point);
}
fPartialSpecs = spec;
}

View file

@ -404,18 +404,27 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) {
if (name instanceof ICPPASTTemplateId)
return IBinding.EMPTY_BINDING_ARRAY;
if (prefixLookup)
return getPrefixBindings(name.getSimpleID());
return getBindings(name.getSimpleID());
return getBindings(new ScopeLookupData(name, resolve, prefixLookup));
}
/**
* @deprecated Use {@link #getBindings(ScopeLookupData)} instead
*/
@Deprecated
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup,
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

View file

@ -11,8 +11,10 @@
*******************************************************************************/
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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
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 CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner,
CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) {
super(orig, owner, tpmap, args);
CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpec) {
super(orig, owner, tpmap, args, type, exceptionSpec);
}
}

View file

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

View file

@ -11,8 +11,10 @@
*******************************************************************************/
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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
/**
@ -22,7 +24,7 @@ public class CPPConstructorTemplateSpecialization extends CPPMethodTemplateSpeci
implements ICPPConstructor {
public CPPConstructorTemplateSpecialization(ICPPConstructor original,
ICPPClassType owner, ICPPTemplateParameterMap tpmap) {
super(original, owner, tpmap);
ICPPClassType owner, ICPPTemplateParameterMap tpmap, ICPPFunctionType type, IType[] exceptionSpecs) {
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.ICPPField;
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.
*/
public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField, IInternalVariable {
public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField {
private IType type = 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);
this.type= type;
this.value= value;
}
private ICPPField getField() {
@ -48,9 +49,6 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
@Override
public IType getType() {
if (type == null) {
type= specializeType(getField().getType());
}
return type;
}
@ -91,21 +89,6 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
@Override
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;
}
}

View file

@ -59,6 +59,8 @@ import org.eclipse.core.runtime.PlatformObject;
* Binding for c++ function
*/
public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInternalFunction {
public static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null);
protected IASTDeclarator[] declarations;
protected ICPPASTFunctionDeclarator definition;
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.
*/
public class CPPFunctionInstance extends CPPFunctionSpecialization implements ICPPTemplateInstance {
private ICPPTemplateArgument[] fArguments;
private final ICPPTemplateArgument[] fArguments;
public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) {
super(orig, owner, argMap);
public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, argMap, type, exceptionSpecs);
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.IType;
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.ICPPFunctionType;
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.index.IIndexBinding;
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.
*/
public class CPPFunctionSpecialization extends CPPSpecialization implements ICPPFunction, ICPPInternalFunction {
private ICPPFunctionType type;
private final ICPPFunctionType fType;
private ICPPParameter[] fParams;
private IType[] specializedExceptionSpec;
private final ICPPClassSpecialization fContext;
private final IType[] fExceptionSpecs;
public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap) {
this(orig, owner, argMap, null);
}
public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap,
ICPPClassSpecialization context) {
public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, argMap);
fContext= context;
}
@Override
protected ICPPClassSpecialization getSpecializationContext() {
if (fContext != null)
return fContext;
return super.getSpecializationContext();
fType= type;
fExceptionSpecs= exceptionSpecs;
}
private ICPPFunction getFunction() {
@ -109,12 +95,7 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
@Override
public ICPPFunctionType getType() {
if (type == null) {
ICPPFunction function = (ICPPFunction) getSpecializedBinding();
type = (ICPPFunctionType) specializeType(function.getType());
}
return type;
return fType;
}
@Override
@ -331,31 +312,6 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
@Override
public IType[] getExceptionSpecification() {
if (specializedExceptionSpec == null) {
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;
return fExceptionSpecs;
}
}

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.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.ICPPFunction;
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.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
@ -30,8 +32,8 @@ public class CPPFunctionTemplateSpecialization extends CPPFunctionSpecialization
private ObjectMap instances = null;
public CPPFunctionTemplateSpecialization(ICPPFunction original, ICPPClassType owner, ICPPTemplateParameterMap argumentMap) {
super(original, owner, argumentMap);
public CPPFunctionTemplateSpecialization(ICPPFunction original, ICPPClassType owner, ICPPTemplateParameterMap argumentMap, ICPPFunctionType type, IType[] exceptionSpecs) {
super(original, owner, argumentMap, type, exceptionSpecs);
}
@Override

View file

@ -11,7 +11,9 @@
*******************************************************************************/
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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
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 CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) {
super(orig, owner, tpmap, args);
public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, tpmap, args, type, exceptionSpecs);
}
/* (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.cpp.ICPPASTDeclSpecifier;
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.ICPPTemplateParameterMap;
@ -26,8 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
*/
public class CPPMethodSpecialization extends CPPFunctionSpecialization implements ICPPMethod {
public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap) {
super(orig, owner, argMap);
public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpec ) {
super(orig, owner, argMap, type, exceptionSpec );
}
@Override

View file

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

View file

@ -72,7 +72,7 @@ public class CPPParameterPackType implements ICPPParameterPackType, ITypeContain
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.PACK_EXPANSION;
int firstByte= ITypeMarshalBuffer.PACK_EXPANSION_TYPE;
buffer.putByte((byte) firstByte);
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.
*/
public class CPPParameterSpecialization extends CPPSpecialization implements ICPPParameter {
private IType fType;
private final IType fType;
public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, IType type, ICPPTemplateParameterMap tpmap) {
super(orig, owner, tpmap);
@ -46,12 +46,6 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP
return fType instanceof ICPPParameterPackType;
}
@Override
public IType specializeType(IType type) {
assert false;
return type;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
*/

View file

@ -97,7 +97,7 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe
@Override
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 (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2;
if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3;

View file

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

View file

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

View file

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

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.IASTFunctionDefinition;
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.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -104,13 +105,18 @@ public class CPPScopeMapper {
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings) {
return fScope.getBinding(name, resolve, acceptLocalBindings);
}
@Override
@Override @Deprecated
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) {
return fScope.getBindings(name, resolve, prefixLookup);
}
@Override
@Override @Deprecated
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
public IScope getParent() throws DOMException {
@ -363,14 +369,14 @@ public class CPPScopeMapper {
return scope;
}
public ICPPClassType mapToAST(ICPPClassType type) {
public ICPPClassType mapToAST(ICPPClassType type, IASTNode point) {
if (type instanceof ICPPTemplateInstance) {
ICPPTemplateInstance inst= (ICPPTemplateInstance) type;
ICPPTemplateDefinition template= inst.getTemplateDefinition();
if (template instanceof IIndexBinding && template instanceof ICPPClassType) {
IBinding mapped= mapToAST((ICPPClassType) template);
IBinding mapped= mapToAST((ICPPClassType) template, point);
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)
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.IBinding;
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.ICPPClassSpecialization;
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.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.ICPPTemplateParameterMap;
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.
*/
public abstract class CPPSpecialization extends PlatformObject implements ICPPSpecialization, ICPPInternalBinding {
private IBinding owner;
private IBinding specialized;
private ICPPTemplateParameterMap argumentMap;
private final IBinding owner;
private final IBinding specialized;
private final ICPPTemplateParameterMap argumentMap;
protected IASTNode definition;
private IASTNode[] declarations;
@ -52,45 +48,6 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
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
public IBinding getSpecializedBinding() {
return specialized;

View file

@ -12,90 +12,30 @@
*******************************************************************************/
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.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
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.ICPPTemplateParameterMap;
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.
*/
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_TYPE_NESTING = 60;
private IType type;
private int fResolutionDepth;
private IType fType;
public CPPTypedefSpecialization(IBinding specialized, ICPPClassType owner,
ICPPTemplateParameterMap tpmap) {
public CPPTypedefSpecialization(IBinding specialized, ICPPClassType owner, ICPPTemplateParameterMap tpmap, IType type) {
super(specialized, owner, tpmap);
fType= type;
}
private ITypedef getTypedef() {
return (ITypedef) getSpecializedBinding();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.ITypedef#getType()
*/
@Override
public IType getType() {
return getType(MAX_TYPE_NESTING);
}
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;
return fType;
}
/* (non-Javadoc)
@ -134,6 +74,6 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType
@Override
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.ICPPScope;
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.core.runtime.PlatformObject;
@ -39,7 +38,6 @@ public class CPPUnknownBinding extends PlatformObject
public CPPUnknownBinding(IBinding owner, char[] name) {
super();
this.name = new CPPASTName(name);
this.name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY);
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.ICPPFunctionType;
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
@ -26,6 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
*/
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 {
if (sample instanceof ICPPConstructor)
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
@ -33,7 +36,6 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio
return new CPPUnknownFunction(sample.getOwner(), sample.getNameCharArray());
}
private ICPPFunctionType fType;
public CPPUnknownFunction(IBinding owner, char[] name) {
super(owner, name);
@ -76,10 +78,7 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio
@Override
public ICPPFunctionType getType() {
if (fType == null) {
fType= new CPPUnknownFunctionType();
}
return fType;
return FUNCTION_TYPE;
}
@Override

View file

@ -13,33 +13,17 @@
*******************************************************************************/
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.index.IIndexFileSet;
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
* 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 CPPUnknownScope implements ICPPInternalUnknownScope {
private final ICPPUnknownBinding binding;
private final IASTName scopeName;
public class CPPUnknownScope extends CPPUnknownTypeScope implements ICPPInternalUnknownScope {
/**
* This field needs to be protected when used in PDOMCPPUnknownScope,
* don't use it outside of {@link #getOrCreateBinding(IASTName, int)}
@ -47,164 +31,38 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope {
private CharArrayObjectMap<IBinding[]> map;
public CPPUnknownScope(ICPPUnknownBinding binding, IASTName name) {
super();
this.scopeName = name;
this.binding = binding;
super(name, 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
public void addName(IASTName name) {
}
@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() == 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) {
protected IBinding getOrCreateBinding(final char[] name, int idx) {
if (map == null)
map = new CharArrayObjectMap<IBinding[]>(2);
final char[] c = name.getLookupKey();
IBinding[] o = map.get(c);
IBinding[] o = map.get(name);
if (o == null) {
o = new IBinding[3];
map.put(c, o);
map.put(name, o);
}
IBinding result= o[idx];
if (result == null) {
switch (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;
}
result= super.getOrCreateBinding(name, idx);
o[idx]= 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
public void addBinding(IBinding binding) {
// 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
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;
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.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
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.
*/
public class CPPUsingDeclarationSpecialization extends CPPSpecialization implements ICPPUsingDeclaration {
private IBinding[] fDelegates;
private final IBinding[] fDelegates;
public CPPUsingDeclarationSpecialization(ICPPUsingDeclaration specialized, ICPPClassSpecialization owner,
ICPPTemplateParameterMap tpmap) {
ICPPTemplateParameterMap tpmap, IBinding[] delegates) {
super(specialized, owner, tpmap);
fDelegates= delegates;
}
@Override
public IBinding[] getDelegates() {
if (fDelegates == null) {
fDelegates= specializeDelegates();
}
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;
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.index.IIndexFileSet;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
/**
* Interface for internal c++ scopes
*/
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;
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;
/**
* Assists in evaluating expressions.
*/
public interface ICPPInitClauseEvaluation {
public interface ICPPEvaluation extends ISerializableEvaluation {
boolean isInitializerList();
boolean isFunctionSet();
boolean isTypeDependent();
boolean isValueDependent();
IType getTypeOrFunctionSet();
IValue getValue();
ValueCategory getCategory();
IType getTypeOrFunctionSet(IASTNode point);
IValue getValue(IASTNode point);
ValueCategory getValueCategory(IASTNode point);
}

View file

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

View file

@ -224,11 +224,11 @@ public class AccessContext {
private ICPPClassType getFirstCandidateForNamingClass(IASTName name) throws DOMException {
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)) {
scope = CPPSemantics.getParentScope(scope, data.tu);
scope = CPPSemantics.getParentScope(scope, data.getTranslationUnit());
}
if (scope instanceof ICPPClassScope) {
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.ICPPClassType;
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.CharArrayObjectMap;
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.
*/
class BaseClassLookup {
public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope, IIndexFileSet fileSet) {
public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope) {
if (classScope == null)
return;
@ -50,7 +49,7 @@ class BaseClassLookup {
return;
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) {
rootInfo.collectResultForContentAssist(data);
} else {
@ -137,7 +136,7 @@ class BaseClassLookup {
}
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)
return null;
@ -164,9 +163,9 @@ class BaseClassLookup {
result= new BaseClassLookup(baseClassScope.getClassType());
infoMap.put(baseClassScope, result);
try {
IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, fileSet, data);
IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, data);
if (members != null && members.length > 0 && members[0] != null) {
if (data.prefixLookup) {
if (data.isPrefixLookup()) {
matches= members;
} else {
result.setResult(members);
@ -227,7 +226,7 @@ class BaseClassLookup {
continue;
BaseClassLookup baseInfo= lookupInBaseClass(data, (ICPPClassScope) grandBaseScope,
grandBase.isVirtual(), root, fileSet, infoMap, depth);
grandBase.isVirtual(), root, infoMap, depth);
if (baseInfo != null)
result.addBase(grandBase.isVirtual(), baseInfo);
}
@ -335,7 +334,7 @@ class BaseClassLookup {
return result;
} else {
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;
}
@ -356,7 +355,7 @@ class BaseClassLookup {
fBindings[numBindingsToAdd] = 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.
data.problem= new ProblemBinding(data.astName,
data.problem= new ProblemBinding(data.getLookupName(),
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, result);
}
result= ArrayUtil.addAll(result, fBindings);

View file

@ -10,7 +10,6 @@
*******************************************************************************/
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 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.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
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.CPPImplicitFunction;
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;
/**
@ -59,12 +57,12 @@ class BuiltinOperators {
private static final int SECOND = 1;
private static final IType PTR_DIFF = new CPPBasicType(Kind.eInt, 0);
public static ICPPFunction[] create(OverloadableOperator operator, IASTInitializerClause[] args,
IASTTranslationUnit tu, Object[] globCandidates) {
public static ICPPFunction[] create(OverloadableOperator operator, ICPPEvaluation[] args,
IASTNode point, Object[] globCandidates) {
if (operator == null || args == null || args.length == 0)
return EMPTY;
return new BuiltinOperators(operator, args, tu.getScope(), globCandidates).create();
return new BuiltinOperators(operator, args, point, globCandidates).create();
}
private final OverloadableOperator fOperator;
@ -78,20 +76,20 @@ class BuiltinOperators {
private Set<String> fSignatures;
private Object[] fGlobalCandidates;
BuiltinOperators(OverloadableOperator operator, IASTInitializerClause[] args, IScope fileScope,
BuiltinOperators(OverloadableOperator operator, ICPPEvaluation[] args, IASTNode point,
Object[] globCandidates) {
fFileScope= fileScope;
fFileScope= point.getTranslationUnit().getScope();
fOperator= operator;
fUnary= args.length<2;
fGlobalCandidates= globCandidates;
if (args.length > 0 && args[0] instanceof IASTExpression) {
IType type= typeOrFunctionSet((IASTExpression) args[0]);
if (args.length > 0) {
IType type= args[0].getTypeOrFunctionSet(point);
if (!(type instanceof ISemanticProblem))
fType1= type;
}
if (args.length > 1 && args[1] instanceof IASTExpression) {
IType type= typeOrFunctionSet((IASTExpression) args[1]);
if (args.length > 1) {
IType type= args[1].getTypeOrFunctionSet(point);
if (!(type instanceof ISemanticProblem))
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.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.IScope;
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.internal.core.dom.Linkage;
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;
/**
@ -23,10 +26,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.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);
fTemplateArguments= args;
fName= name;
}
@Override
@ -60,10 +67,9 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding {
@Override
public IBinding resolveFinalBinding(CPPASTNameBase astName) {
return CPPSemantics.resolveTargetedFunction(astName, fBindings);
return CPPSemantics.resolveTargetedFunction(astName, this);
}
@Override
@SuppressWarnings("unchecked")
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
@ -71,4 +77,20 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding {
return this;
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.IASTFunctionDefinition;
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.IASTNode;
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.ICPPASTElaboratedTypeSpecifier;
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.ICPPASTParameterDeclaration;
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>.
*/
public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args) {
return instantiate(template, args, false, false);
public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args, IASTNode point) {
return instantiate(template, args, false, false, point);
}
/**
* Instantiates a class template with the given arguments. May return <code>null</code>.
*/
private static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args,
boolean isDefinition, boolean isExplicitSpecialization) {
boolean isDefinition, boolean isExplicitSpecialization, IASTNode point) {
try {
// Add default arguments, if necessary.
ICPPTemplateArgument[] arguments= SemanticUtil.getSimplifiedArguments(args);
arguments= addDefaultArguments(template, arguments);
arguments= addDefaultArguments(template, arguments, point);
if (arguments == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
@ -185,7 +183,7 @@ public class CPPTemplates {
}
if (template instanceof ICPPClassTemplatePartialSpecialization) {
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null);
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null, point);
}
final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
@ -208,7 +206,7 @@ public class CPPTemplates {
}
if (i < numArgs) {
ICPPTemplateArgument arg= arguments[i];
ICPPTemplateArgument newArg = CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
ICPPTemplateArgument newArg = CPPTemplates.matchTemplateParameterAndArgument(param, arg, map, point);
if (newArg == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
if (newArg != arg) {
@ -239,12 +237,12 @@ public class CPPTemplates {
return prim;
if (!isExplicitSpecialization) {
IBinding result= CPPTemplates.selectSpecialization(template, arguments, isDefinition);
IBinding result= CPPTemplates.selectSpecialization(template, arguments, isDefinition, point);
if (result != null)
return result;
}
return instantiatePrimaryTemplate(template, arguments, map, isDefinition);
return instantiatePrimaryTemplate(template, arguments, map, isDefinition, point);
} catch (DOMException e) {
return e.getProblem();
}
@ -308,24 +306,25 @@ public class CPPTemplates {
}
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);
if (instance != null) {
return instance;
}
IBinding owner= template.getOwner();
instance = CPPTemplates.createInstance(owner, template, map, arguments);
instance = CPPTemplates.createInstance(owner, template, map, arguments, point);
addInstance(template, arguments, instance);
return instance;
}
/**
* Instantiates a partial class template specialization.
* @param point
*/
private static IBinding instantiatePartialSpecialization(
ICPPClassTemplatePartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef,
CPPTemplateParameterMap tpMap) throws DOMException {
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef);
if (instance != null)
return instance;
@ -333,11 +332,11 @@ public class CPPTemplates {
if (tpMap == null) {
tpMap = new CPPTemplateParameterMap(args.length);
if (!TemplateArgumentDeduction.fromTemplateArguments(partialSpec.getTemplateParameters(),
partialSpec.getTemplateArguments(), args, tpMap))
partialSpec.getTemplateArguments(), args, tpMap, point))
return null;
}
instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args);
instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args, point);
addInstance(partialSpec, args, instance);
return instance;
}
@ -347,7 +346,7 @@ public class CPPTemplates {
* @param map
*/
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);
ICPPTemplateInstance instance= getInstance(template, arguments, isDef);
@ -356,7 +355,7 @@ public class CPPTemplates {
}
IBinding owner= template.getOwner();
instance = CPPTemplates.createInstance(owner, template, map, arguments);
instance = CPPTemplates.createInstance(owner, template, map, arguments, point);
addInstance(template, arguments, instance);
return instance;
}
@ -395,7 +394,7 @@ public class CPPTemplates {
}
private static ICPPTemplateArgument[] addDefaultArguments(ICPPClassTemplate template,
ICPPTemplateArgument[] arguments) throws DOMException {
ICPPTemplateArgument[] arguments, IASTNode point) throws DOMException {
if (template instanceof ICPPClassTemplatePartialSpecialization)
return arguments;
@ -461,7 +460,7 @@ public class CPPTemplates {
}
if (defaultArg == null)
return null;
arg= instantiateArgument(defaultArg, map, -1, null);
arg= instantiateArgument(defaultArg, map, -1, null, point);
arg= SemanticUtil.getSimplifiedArgument(arg);
if (!isValidArgument(arg)) {
return null;
@ -672,7 +671,7 @@ public class CPPTemplates {
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
result= classTemplate;
} else {
args= addDefaultArguments(classTemplate, args);
args= addDefaultArguments(classTemplate, args, id);
if (args == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
@ -692,7 +691,7 @@ public class CPPTemplates {
}
}
if (result == null) {
result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization);
result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization, id);
if (result instanceof ICPPInternalBinding) {
if (isDeclaration) {
ASTInternal.addDeclaration(result, id);
@ -731,7 +730,7 @@ public class CPPTemplates {
public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template,
CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args) {
CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args, IASTNode point) {
if (owner instanceof ICPPSpecialization) {
ICPPTemplateParameterMap map= ((ICPPSpecialization) owner).getTemplateParameterMap();
if (map != null) {
@ -742,26 +741,36 @@ public class CPPTemplates {
ICPPTemplateInstance instance = null;
if (template instanceof ICPPClassType) {
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) {
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;
}
public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl) {
public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl, IASTNode point) {
IBinding spec = null;
final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap();
if (decl instanceof ICPPClassTemplatePartialSpecialization) {
try {
final ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl;
ICPPClassTemplate template= (ICPPClassTemplate) owner.specializeMember(pspec.getPrimaryClassTemplate());
spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, template, tpMap);
ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
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) {
}
} else if (decl instanceof ICPPClassTemplate) {
@ -774,33 +783,82 @@ public class CPPTemplates {
spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap);
}
} else if (decl instanceof ICPPField) {
spec = new CPPFieldSpecialization(decl, owner, tpMap);
} else if (decl instanceof ICPPFunctionTemplate) {
final ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPField field= (ICPPField) decl;
IType type= CPPTemplates.instantiateType(field.getType(), tpMap, -1, within, point);
IValue value= CPPTemplates.instantiateValue(field.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point);
spec = new CPPFieldSpecialization(decl, owner, tpMap, type, value);
} else if (decl instanceof ICPPFunction) {
ICPPFunction func= (ICPPFunction) decl;
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);
spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
else if (decl instanceof ICPPMethod)
spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap);
spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs);
else
spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap);
spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap, type, exceptionSpecs);
} else if (decl instanceof ICPPConstructor) {
spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap);
spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
} else if (decl instanceof ICPPMethod) {
spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap);
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, owner);
spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs);
}
} 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) {
// TODO(sprigogin): Deal with a case when an enumerator value depends on a template parameter.
spec = decl;
} 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;
}
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)
return null;
IBinding[] unknowns= value.getUnknownBindings();
@ -811,7 +869,7 @@ public class CPPTemplates {
IBinding resolved= unknown;
if (unknown instanceof ICPPUnknownBinding) {
try {
resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within);
resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within, point);
} catch (DOMException e) {
return Value.UNKNOWN;
}
@ -945,9 +1003,13 @@ public class CPPTemplates {
* Instantiates types contained in an array.
* @param types an array of types
* @param tpMap template argument map
* @param point
* @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.
IType[] result = types;
int j= 0;
@ -966,12 +1028,12 @@ public class CPPTemplates {
System.arraycopy(result, 0, newResult, 0, j);
result= newResult;
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;
}
} else {
newType = CPPTemplates.instantiateType(origType, tpMap, packOffset, within);
newType = CPPTemplates.instantiateType(origType, tpMap, packOffset, within, point);
}
if (result != types) {
result[j++]= newType;
@ -989,9 +1051,10 @@ public class CPPTemplates {
/**
* Instantiates arguments contained in an array.
* @param point
*/
public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within)
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point)
throws DOMException {
// Don't create a new array until it's really needed.
ICPPTemplateArgument[] result = args;
@ -1011,14 +1074,14 @@ public class CPPTemplates {
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i+resultShift);
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;
resultShift+= shift;
continue;
}
} else {
newArg = CPPTemplates.instantiateArgument(origArg, tpMap, packOffset, within);
newArg = CPPTemplates.instantiateArgument(origArg, tpMap, packOffset, within, point);
}
if (result != args) {
result[i+resultShift]= newArg;
@ -1036,41 +1099,42 @@ public class CPPTemplates {
/**
* Instantiates an argument
* @param point
*/
static ICPPTemplateArgument instantiateArgument(ICPPTemplateArgument arg,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) {
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
if (arg == null)
return null;
if (arg.isNonTypeValue()) {
final IValue origValue= arg.getNonTypeValue();
final IType origType= arg.getTypeOfNonTypeValue();
final IValue instValue= instantiateValue(origValue, tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH);
final IType instType= instantiateType(origType, tpMap, packOffset, within);
final IValue instValue= instantiateValue(origValue, tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
final IType instType= instantiateType(origType, tpMap, packOffset, within, point);
if (origType == instType && origValue == instValue)
return arg;
return new CPPTemplateArgument(instValue, instType);
}
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)
return arg;
return new CPPTemplateArgument(inst);
}
private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPClassSpecialization within) {
int packOffset, ICPPClassSpecialization within, IASTNode point) {
final Integer[] positions = orig.getAllParameterPositions();
CPPTemplateParameterMap newMap= new CPPTemplateParameterMap(positions.length);
for (Integer key : positions) {
ICPPTemplateArgument arg = orig.getArgument(key);
if (arg != null) {
newMap.put(key, instantiateArgument(arg, tpMap, packOffset, within));
newMap.put(key, instantiateArgument(arg, tpMap, packOffset, within, point));
} else {
ICPPTemplateArgument[] args = orig.getPackExpansion(key);
if (args != null) {
try {
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within));
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point));
} catch (DOMException e) {
newMap.put(key, args);
}
@ -1083,9 +1147,10 @@ public class CPPTemplates {
/**
* Instantiates the given type with the provided map and packoffset.
* The context is used to replace templates with their specialization, where appropriate.
* @param point
*/
public static IType instantiateType(IType type, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within) {
ICPPClassSpecialization within, IASTNode point) {
try {
if (tpMap == null)
return type;
@ -1095,9 +1160,9 @@ public class CPPTemplates {
IType ret = null;
IType[] params = null;
final IType r = ft.getReturnType();
ret = instantiateType(r, tpMap, packOffset, within);
ret = instantiateType(r, tpMap, packOffset, within, point);
IType[] ps = ft.getParameterTypes();
params = instantiateTypes(ps, tpMap, packOffset, within);
params = instantiateTypes(ps, tpMap, packOffset, within, point);
if (ret == r && params == ps) {
return type;
}
@ -1137,7 +1202,7 @@ public class CPPTemplates {
}
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)
return (IType) binding;
@ -1161,11 +1226,11 @@ public class CPPTemplates {
// another binding, to the more specialized version.
newOwner= within;
} else {
newOwner= instantiateType(ownerAsType, tpMap, packOffset, within);
newOwner= instantiateType(ownerAsType, tpMap, packOffset, within, point);
}
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();
if (origClass instanceof ICPPClassType) {
ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within);
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset, within, point);
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);
}
}
@ -1187,11 +1252,11 @@ public class CPPTemplates {
if (type instanceof ITypeContainer) {
final ITypeContainer typeContainer = (ITypeContainer) type;
IType nestedType = typeContainer.getType();
IType newNestedType = instantiateType(nestedType, tpMap, packOffset, within);
IType newNestedType = instantiateType(nestedType, tpMap, packOffset, within, point);
if (typeContainer instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer;
IType memberOfClass = ptm.getMemberOfClass();
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within);
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within, point);
if (newMemberOfClass instanceof IQualifierType) {
newMemberOfClass = ((IQualifierType) newMemberOfClass).getType();
}
@ -1209,7 +1274,7 @@ public class CPPTemplates {
IArrayType at= (IArrayType) typeContainer;
IValue asize= at.getSize();
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) {
return new CPPArrayType(newNestedType, newSize);
}
@ -1653,15 +1718,10 @@ public class CPPTemplates {
return result;
}
static ICPPFunction[] instantiateForFunctionCall(IASTName name, ICPPFunction[] fns,
List<IType> fnArgs, List<ValueCategory> argCats, boolean withImpliedObjectArg) {
if (name != null && name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
name= (IASTName) name.getParent();
}
static ICPPFunction[] instantiateForFunctionCall(ICPPFunction[] fns, ICPPTemplateArgument[] tmplArgs,
List<IType> fnArgs, List<ValueCategory> argCats, boolean withImpliedObjectArg, IASTNode point) {
// Extract template arguments.
ICPPTemplateArgument[] tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS;
boolean requireTemplate= name instanceof ICPPASTTemplateId;
boolean requireTemplate= tmplArgs != null;
boolean haveTemplate= false;
for (final ICPPFunction func : fns) {
@ -1675,7 +1735,6 @@ public class CPPTemplates {
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
if (requireTemplate) {
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
if (hasDependentArgument(tmplArgs))
return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)};
}
@ -1695,7 +1754,7 @@ public class CPPTemplates {
if (fn != null) {
if (fn instanceof ICPPFunctionTemplate) {
ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn;
ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, withImpliedObjectArg);
ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, withImpliedObjectArg, point);
if (inst != null)
result.add(inst);
} else if (!requireTemplate || fn instanceof ICPPUnknownBinding) {
@ -1708,7 +1767,7 @@ public class CPPTemplates {
private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argCats,
boolean withImpliedObjectArg) {
boolean withImpliedObjectArg, IASTNode point) {
if (withImpliedObjectArg && template instanceof ICPPMethod) {
fnArgs= fnArgs.subList(1, fnArgs.size());
argCats= argCats.subList(1, argCats.size());
@ -1716,9 +1775,9 @@ public class CPPTemplates {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.size());
try {
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map);
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map, point);
if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map);
IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) {
final ICPPFunction f = (ICPPFunction) instance;
if (isValidType(f.getType()))
@ -1732,8 +1791,9 @@ public class CPPTemplates {
/**
* 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;
ICPPFunction[] result= functions;
int i=0;
@ -1758,9 +1818,9 @@ public class CPPTemplates {
}
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
try {
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map);
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map, point);
if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map);
IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) {
inst= (ICPPFunction) instance;
}
@ -1784,15 +1844,16 @@ public class CPPTemplates {
/**
* 14.8.2.6 Deducing template arguments from a function declaration
* @param point
* @return
*/
static ICPPFunction instantiateForFunctionDeclaration(ICPPFunctionTemplate template,
ICPPTemplateArgument[] args, ICPPFunctionType functionType) {
ICPPTemplateArgument[] args, ICPPFunctionType functionType, IASTNode point) {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
try {
args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map);
args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map, point);
if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map);
IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) {
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]
*/
static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target, IASTName name) {
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
name= (IASTName) name.getParent();
}
static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target,
ICPPTemplateArgument[] args, IASTNode point) {
try {
if (target != null && isDependentType(target)) {
return CPPUnknownFunction.createForSample(template);
}
ICPPTemplateArgument[] tmplArgs;
if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) {
tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name);
if (hasDependentArgument(tmplArgs)) {
return CPPUnknownFunction.createForSample(template);
}
} else {
tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS;
}
if (template instanceof ICPPConstructor || args == null)
args= ICPPTemplateArgument.EMPTY_ARGUMENTS;
CPPTemplateParameterMap map= new CPPTemplateParameterMap(4);
ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForAddressOf(template, tmplArgs, target, map);
args= TemplateArgumentDeduction.deduceForAddressOf(template, args, target, map, point);
if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map);
IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) {
return (ICPPFunction) instance;
}
@ -1840,7 +1892,7 @@ public class CPPTemplates {
}
// 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 {
if (f1 == f2)
return 0;
@ -1849,8 +1901,8 @@ public class CPPTemplates {
if (f2 == null)
return 1;
int s1 = compareSpecialization(f1, f2, mode);
int s2 = compareSpecialization(f2, f1, mode);
int s1 = compareSpecialization(f1, f2, mode, point);
int s2 = compareSpecialization(f2, f1, mode, point);
if (s1 == s2)
return 0;
@ -1860,7 +1912,7 @@ public class CPPTemplates {
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 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)
return (ICPPFunction) result;
@ -1895,8 +1947,8 @@ public class CPPTemplates {
return arg;
}
private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode) throws DOMException {
ICPPFunction transF1 = transferFunctionTemplate(f1);
private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point) throws DOMException {
ICPPFunction transF1 = transferFunctionTemplate(f1, point);
if (transF1 == null)
return -1;
@ -1928,7 +1980,7 @@ public class CPPTemplates {
}
break;
}
return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args);
return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args, point);
}
private static boolean isNonStaticMember(ICPPFunctionTemplate f) {
@ -1965,7 +2017,7 @@ public class CPPTemplates {
}
private static IBinding selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args,
boolean isDef) throws DOMException {
boolean isDef, IASTNode point) throws DOMException {
if (template == null) {
return null;
}
@ -1980,8 +2032,8 @@ public class CPPTemplates {
for (ICPPClassTemplatePartialSpecialization specialization : specializations) {
spec = specialization;
final CPPTemplateParameterMap map = new CPPTemplateParameterMap(args.length);
if (TemplateArgumentDeduction.fromTemplateArguments(spec.getTemplateParameters(), spec.getTemplateArguments(), args, map)) {
int compare = orderSpecializations(bestMatch, spec);
if (TemplateArgumentDeduction.fromTemplateArguments(spec.getTemplateParameters(), spec.getTemplateArguments(), args, map, point)) {
int compare = orderSpecializations(bestMatch, spec, point);
if (compare == 0) {
bestMatchIsBest = false;
} else if (compare < 0) {
@ -2001,7 +2053,7 @@ public class CPPTemplates {
if (bestMatch == 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.
* @param spec1
* @param spec2
* @param point
* @return
* @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) {
return -1;
}
@ -2023,8 +2076,8 @@ public class CPPTemplates {
// 14.5.5.2
// 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.
boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2);
boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1);
boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2, point);
boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1, point);
if (f1IsAtLeastAsSpecializedAsF2 == f2IsAtLeastAsSpecializedAsF1)
return 0;
@ -2035,7 +2088,7 @@ public class CPPTemplates {
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
// Using the transformed parameter list, perform argument deduction against the other
// function template
@ -2058,16 +2111,16 @@ public class CPPTemplates {
args[i]= 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
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap))
if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point))
return false;
// Compare
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]))
return false;
}
@ -2103,7 +2156,7 @@ public class CPPTemplates {
}
static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param,
ICPPTemplateArgument arg, CPPTemplateParameterMap map) {
ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) {
if (arg == null || !isValidType(arg.getTypeValue())) {
return null;
}
@ -2150,9 +2203,9 @@ public class CPPTemplates {
pType= ((ICPPParameterPackType) pType).getType();
}
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 null;
@ -2226,14 +2279,14 @@ public class CPPTemplates {
* @return
* @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
if (paramType instanceof IFunctionType) {
paramType = new CPPPointerType(paramType);
} else if (paramType instanceof IArrayType) {
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();
}
@ -2326,7 +2379,7 @@ public class CPPTemplates {
}
t= ((ITypeContainer) t).getType();
} else if (t instanceof InitializerListType) {
return isDependentInitializerList(((InitializerListType) t).getInitializerList());
return ((InitializerListType) t).getEvaluation().isTypeDependent();
} else if (t instanceof IBinding) {
IBinding owner = ((IBinding) t).getOwner();
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) {
for (Object arg : tpMap.valueArray()) {
if (isDependentType((IType)arg))
@ -2365,9 +2403,9 @@ public class CPPTemplates {
* Attempts to (partially) resolve an unknown binding with the given arguments.
*/
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) {
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset, within);
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset, within, point);
}
final IBinding owner= unknown.getOwner();
@ -2375,14 +2413,14 @@ public class CPPTemplates {
return 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) {
t = SemanticUtil.getUltimateType(t, false);
if (t instanceof ICPPUnknownBinding) {
if (unknown instanceof ICPPUnknownClassInstance) {
ICPPUnknownClassInstance ucli= (ICPPUnknownClassInstance) unknown;
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) {
newArgs= SemanticUtil.getSimplifiedArguments(newArgs);
result= new CPPUnknownClassInstance((ICPPUnknownBinding) t, ucli.getNameCharArray(), newArgs);
@ -2402,9 +2440,9 @@ public class CPPTemplates {
result= CPPSemantics.resolveUnknownName(s, unknown);
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(
((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within);
((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within, point);
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,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) {
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
ICPPTemplateArgument[] newArgs;
try {
newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within);
newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within, point);
} catch (DOMException e) {
return e.getProblem();
}
boolean changed= arguments != newArgs;
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) {
classTemplate= (ICPPClassTemplate) classTemplateSpecialization;
changed= true;
@ -2438,11 +2476,11 @@ public class CPPTemplates {
IBinding inst= null;
if (classTemplate instanceof ICPPClassTemplatePartialSpecialization) {
try {
inst= instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) classTemplate, newArgs, false, null);
inst= instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) classTemplate, newArgs, false, null, point);
} catch (DOMException e) {
}
} else {
inst= instantiate(classTemplate, newArgs);
inst= instantiate(classTemplate, newArgs, point);
}
if (inst != null)
return inst;

View file

@ -13,11 +13,7 @@
*******************************************************************************/
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.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 static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import java.util.ArrayList;
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.ICPPASTFunctionDefinition;
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.ICPPASTLambdaExpression;
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.CPPTemplateParameterMap;
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.ICPPEvaluation;
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.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexScope;
/**
@ -230,6 +230,7 @@ public class CPPVisitor extends ASTQueries {
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) {
IASTNode parent = name.getParent();
@ -307,6 +308,32 @@ public class CPPVisitor extends ASTQueries {
if (names.length < 2)
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();
if (pb instanceof IProblemBinding)
return false;
@ -320,32 +347,8 @@ public class CPPVisitor extends ASTQueries {
} else if (pb instanceof ICPPNamespace) {
scope= ((ICPPNamespace)pb).getNamespaceScope();
}
if (scope == null)
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();
}
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;
return scope == inScope;
}
private static IBinding createBinding(IASTGotoStatement gotoStatement) {
@ -452,7 +455,7 @@ public class CPPVisitor extends ASTQueries {
binding = CPPSemantics.resolveBinding(elabType.getName());
}
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);
}
@ -874,7 +877,7 @@ public class CPPVisitor extends ASTQueries {
if (name == null)
return false;
final ASTNodeProperty propertyInParent = name.getPropertyInParent();
if (propertyInParent == CPPSemantics.STRING_LOOKUP_PROPERTY || propertyInParent == null)
if (propertyInParent == null)
return false;
IASTNode parent = name.getParent();
if (parent instanceof ICPPASTTemplateId) {
@ -1130,11 +1133,7 @@ public class CPPVisitor extends ASTQueries {
}
public static IScope getContainingScope(IASTName name) {
return getContainingScope(name, null);
}
public static IScope getContainingScope(IASTName name, LookupData data) {
IScope scope= getContainingScopeOrNull(name, data);
IScope scope= getContainingScopeOrNull(name);
if (scope == null) {
return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE);
}
@ -1142,7 +1141,7 @@ public class CPPVisitor extends ASTQueries {
return scope;
}
private static IScope getContainingScopeOrNull(IASTName name, LookupData data) {
private static IScope getContainingScopeOrNull(IASTName name) {
if (name == null) {
return null;
}
@ -1172,9 +1171,6 @@ public class CPPVisitor extends ASTQueries {
parent= name.getParent();
}
} else if (i > 0) {
if (data != null) {
data.usesEnclosingScope= false;
}
// For template functions we may need to resolve a template parameter
// as a parent of an unknown type used as parameter type.
IBinding binding = names[i - 1].resolvePreBinding();
@ -1190,7 +1186,7 @@ public class CPPVisitor extends ASTQueries {
IScope scope= null;
if (binding instanceof ICPPClassType) {
if (binding instanceof IIndexBinding && tu != null) {
binding= (((CPPASTTranslationUnit) tu)).mapToAST((ICPPClassType) binding);
binding= (((CPPASTTranslationUnit) tu)).mapToAST((ICPPClassType) binding, name);
}
scope= ((ICPPClassType) binding).getCompositeScope();
} else if (binding instanceof ICPPNamespace) {
@ -1215,9 +1211,6 @@ public class CPPVisitor extends ASTQueries {
}
if (parent instanceof ICPPASTFieldReference) {
if (data != null) {
data.usesEnclosingScope= false;
}
final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference) parent;
IType type = fieldReference.getFieldOwnerType();
type= getUltimateTypeUptoPointers(type);
@ -1226,8 +1219,9 @@ public class CPPVisitor extends ASTQueries {
return ((ICPPClassType) type).getCompositeScope();
} else if (type instanceof ICPPUnknownBinding) {
return ((ICPPUnknownBinding) type).asScope();
} else if (type instanceof ICPPUnknownType) {
return UNKNOWN_TYPE_SCOPE;
} else {
// mstodo introduce problem category
return new CPPScope.CPPScopeProblem(name, ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
} else if (parent instanceof IASTGotoStatement || parent instanceof IASTLabelStatement) {
@ -1285,7 +1279,7 @@ public class CPPVisitor extends ASTQueries {
public static IASTNode getContainingBlockItem(IASTNode node) {
if (node == null) return null;
if (node.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return null;
if (node.getPropertyInParent() == null) return null;
IASTNode parent = node.getParent();
if (parent == null)
return null;
@ -1960,14 +1954,14 @@ public class CPPVisitor extends ASTQueries {
if (declarator instanceof ICPPASTFunctionDeclarator) {
return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator);
}
IASTInitializerClause autoInitClause= null;
ICPPASTInitializerClause autoInitClause= null;
IASTNode parent = declarator.getParent().getParent();
if (parent instanceof ICPPASTNewExpression) {
IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer();
if (initializer != null) {
IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments();
if (arguments.length == 1) {
autoInitClause = arguments[0];
autoInitClause = (ICPPASTInitializerClause) arguments[0];
}
}
} else if (parent instanceof ICPPASTRangeBasedForStatement) {
@ -1988,9 +1982,9 @@ public class CPPVisitor extends ASTQueries {
IBinding b= implicits[0].getBinding();
CPPASTName name= new CPPASTName();
name.setBinding(b);
if (b instanceof ICPPMethod) {
if (b instanceof ICPPMethod && forInit instanceof IASTExpression) {
beginExpr= new CPPASTFunctionCallExpression(
new CPPASTFieldReference(name, null), NO_ARGS);
new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS);
} else {
beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS);
}
@ -2008,15 +2002,15 @@ public class CPPVisitor extends ASTQueries {
} else {
IASTInitializer initClause= declarator.getInitializer();
if (initClause instanceof IASTEqualsInitializer) {
autoInitClause= ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof IASTInitializerClause) {
autoInitClause= (IASTInitializerClause) initClause;
autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause();
} else if (initClause instanceof ICPPASTInitializerClause) {
autoInitClause= (ICPPASTInitializerClause) initClause;
}
}
return createAutoType(autoInitClause, declSpec, declarator);
}
private static IType createAutoType(IASTInitializerClause initClause, IASTDeclSpecifier declSpec,
private static IType createAutoType(ICPPASTInitializerClause initClause, IASTDeclSpecifier declSpec,
IASTDeclarator declarator) {
// C++0x: 7.1.6.4
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);
}
type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) });
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause);
if (type instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
}
}
type = decorateType(type, declSpec, declarator);
if (initClause instanceof IASTExpression) {
final IASTExpression expression = (IASTExpression) initClause;
initType = expression.getExpressionType();
valueCat= expression.getValueCategory();
} else if (initClause instanceof ICPPASTInitializerList) {
initType = new InitializerListType((ICPPASTInitializerList) initClause);
}
final ICPPEvaluation evaluation = initClause.getEvaluation();
initType= evaluation.getTypeOrFunctionSet(declarator);
valueCat= evaluation.getValueCategory(declarator);
if (initType == null) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
}
@ -2058,7 +2047,7 @@ public class CPPVisitor extends ASTQueries {
ICPPFunctionTemplate template = new AutoTypeResolver(type);
CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1);
TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType),
Collections.singletonList(valueCat), paramMap);
Collections.singletonList(valueCat), paramMap, initClause);
ICPPTemplateArgument argument = paramMap.getArgument(0, 0);
if (argument == null) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
@ -2069,7 +2058,7 @@ public class CPPVisitor extends ASTQueries {
type = t;
if (initClause instanceof ICPPASTInitializerList) {
type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) });
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause);
}
return decorateType(type, declSpec, declarator);
}
@ -2241,8 +2230,8 @@ public class CPPVisitor extends ASTQueries {
return null;
}
public static IType getPointerDiffType(final IASTBinaryExpression binary) {
IType t= getStdType(binary, PTRDIFF_T);
public static IType getPointerDiffType(final IASTNode point) {
IType t= getStdType(point, PTRDIFF_T);
return t != null ? t : INT_TYPE;
}
@ -2264,8 +2253,8 @@ public class CPPVisitor extends ASTQueries {
return null;
}
public static IType get_type_info(IASTExpression expression) {
IType t= getStdType(expression, TYPE_INFO);
public static IType get_type_info(IASTNode point) {
IType t= getStdType(point, TYPE_INFO);
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.IASTExpression;
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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
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.IType;
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.ICPPClassType;
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.ITypeContainer;
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.CPPPointerToMemberType;
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.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.Rank;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBinding;
@ -93,7 +91,7 @@ public class Conversions {
* @throws DOMException
*/
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;
if (isImpliedObject)
udc= UDCMode.FORBIDDEN;
@ -124,7 +122,7 @@ public class Conversions {
if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.CONST)
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()) {
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)
// and choosing the best one through overload resolution (13.3)),
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) {
cost.setReferenceBinding(refBindingType);
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
// function lvalue that is the result of the conversion;
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) {
cost.setReferenceBinding(refBindingType);
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,
// in either case, to the appropriate base class sub-object of the object).
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) {
cost.setReferenceBinding(refBindingType);
return cost;
@ -242,7 +240,7 @@ public class Conversions {
// 13.3.3.1.7 no temporary object when converting the implicit object parameter
if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) {
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()) {
cost.setReferenceBinding(refBindingType);
}
@ -253,13 +251,14 @@ public class Conversions {
}
// 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
* @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 {
ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2);
Cost operatorCost= null;
@ -282,7 +281,7 @@ public class Conversions {
// Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost udcFuncCost= new FunctionCost(op, udcCost);
int cmp= udcFuncCost.compareTo(null, bestUdcCost);
int cmp= udcFuncCost.compareTo(null, bestUdcCost, point);
if (cmp <= 0) {
Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false); // converted to target
if (cost != null) {
@ -306,9 +305,9 @@ public class Conversions {
/**
* 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) {
return listInitializationSequence(((InitializerListType) source), target, udc, false);
return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false, point);
}
IType uqTarget= SemanticUtil.getNestedType(target, TDEF | REF | CVTYPE);
@ -329,14 +328,14 @@ public class Conversions {
if (udc == UDCMode.FORBIDDEN)
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 (udc == UDCMode.FORBIDDEN)
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);
@ -345,15 +344,14 @@ public class Conversions {
/**
* 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);
if (listType != null) {
IType[] exprTypes= arg.getExpressionTypes();
ValueCategory[] valueCats= arg.getValueCategories();
Cost worstCost= new Cost(arg, target, Rank.IDENTITY);
for (int i = 0; i < exprTypes.length; i++) {
IType exprType = exprTypes[i];
Cost cost= checkImplicitConversionSequence(listType, exprType, valueCats[i], UDCMode.ALLOWED, Context.ORDINARY);
ICPPEvaluation[] clauses = arg.getClauses();
Cost worstCost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY);
for (ICPPEvaluation clause : clauses) {
Cost cost= checkImplicitConversionSequence(listType, clause.getTypeOrFunctionSet(point),
clause.getValueCategory(point), UDCMode.ALLOWED, Context.ORDINARY, point);
if (!cost.converts())
return cost;
if (cost.isNarrowingConversion()) {
@ -374,26 +372,25 @@ public class Conversions {
ICPPClassType classTarget= (ICPPClassType) noCVTarget;
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);
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) {
final IASTInitializerClause firstArg = args[0];
if (firstArg instanceof IASTExpression) {
IASTExpression expr= (IASTExpression) firstArg;
Cost cost= checkImplicitConversionSequence(target, expr.getExpressionType(), expr.getValueCategory(), udc, Context.ORDINARY);
final ICPPEvaluation firstArg = args[0];
if (!firstArg.isInitializerList()) {
Cost cost= checkImplicitConversionSequence(target, firstArg.getTypeOrFunctionSet(point), firstArg.getValueCategory(point), udc, Context.ORDINARY, point);
if (cost.isNarrowingConversion()) {
return Cost.NO_CONVERSION;
}
return cost;
}
} 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;
@ -538,9 +535,9 @@ public class Conversions {
}
// 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) {
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);
return c;
}
@ -554,8 +551,8 @@ public class Conversions {
for (ICPPConstructor ctor : ctors) {
final int minArgCount = ctor.getRequiredArgumentCount();
if (minArgCount == 0) {
if (arg.getExpressionTypes().length == 0) {
Cost c= new Cost(arg, t, Rank.IDENTITY);
if (arg.getClauses().length == 0) {
Cost c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.IDENTITY);
c.setUserDefinedConversion(ctor);
return c;
}
@ -565,7 +562,7 @@ public class Conversions {
final IType target = parTypes[0];
if (getInitListType(target) != null) {
hasInitListConstructor= true;
Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect);
Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect, point);
if (cost.converts()) {
int cmp= cost.compareTo(bestCost);
if (bestCost == null || cmp < 0) {
@ -593,13 +590,8 @@ public class Conversions {
}
// No initializer-list constructor
final ICPPASTInitializerList initializerList = arg.getInitializerList();
LookupData data= new LookupData();
IASTName name = new CPPASTName(t.getNameCharArray());
name.setParent(initializerList);
name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY);
final IASTInitializerClause[] expandedArgs = initializerList.getClauses();
LookupData data= new LookupData(t.getNameCharArray(), null, point);
final ICPPEvaluation[] expandedArgs = arg.getClauses();
data.setFunctionArguments(false, expandedArgs);
data.fNoNarrowing= true;
@ -623,11 +615,11 @@ public class Conversions {
final IBinding result= CPPSemantics.resolveFunction(data, filteredConstructors, true);
final Cost c;
if (result instanceof ICPPMethod) {
c= new Cost(arg, t, Rank.IDENTITY);
c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.IDENTITY);
c.setUserDefinedConversion((ICPPMethod) result);
} else if (result instanceof IProblemBinding
&& ((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);
} else {
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]
*/
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) {
Cost c= new Cost(source, t, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS);
@ -648,8 +640,8 @@ public class Conversions {
FunctionCost cost1= null;
Cost cost2= null;
ICPPFunction[] ctors= t.getConstructors();
ctors = CPPTemplates.instantiateForFunctionCall(null, ctors,
Collections.singletonList(source), Collections.singletonList(valueCat), false);
ctors = CPPTemplates.instantiateForFunctionCall(ctors, null,
Collections.singletonList(source), Collections.singletonList(valueCat), false, point);
for (ICPPFunction f : ctors) {
if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding)
@ -677,9 +669,9 @@ public class Conversions {
if (ctor.getRequiredArgumentCount() > 1)
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) {
cost1= c1;
cost2= new Cost(t, t, Rank.IDENTITY);
@ -694,7 +686,7 @@ public class Conversions {
final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE);
if (uqSource instanceof ICPPClassType) {
ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource);
ops= CPPTemplates.instantiateConversionTemplates(ops, t);
ops= CPPTemplates.instantiateConversionTemplates(ops, t, point);
for (final ICPPFunction f : ops) {
if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) {
ICPPMethod op= (ICPPMethod) f;
@ -710,7 +702,7 @@ public class Conversions {
// Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost c1= new FunctionCost(op, udcCost);
int cmp= c1.compareTo(null, cost1);
int cmp= c1.compareTo(null, cost1, point);
if (cmp <= 0) {
cost1= c1;
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]
*/
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) {
Cost c= new Cost(source, target, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
return c;
}
ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource);
ops= CPPTemplates.instantiateConversionTemplates(ops, target);
ops= CPPTemplates.instantiateConversionTemplates(ops, target, point);
FunctionCost cost1= null;
Cost cost2= null;
for (final ICPPFunction f : ops) {
@ -756,7 +748,7 @@ public class Conversions {
final IType returnType = op.getType().getReturnType();
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 (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
continue;
@ -766,7 +758,7 @@ public class Conversions {
// Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost c1= new FunctionCost(op, udcCost);
int cmp= c1.compareTo(null, cost1);
int cmp= c1.compareTo(null, cost1, point);
if (cmp <= 0) {
cost1= c1;
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