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:
parent
1bb6d2eecc
commit
fad6fcfe01
147 changed files with 5751 additions and 3282 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -52,4 +52,10 @@ public interface ICPPASTFieldReference extends IASTFieldReference, ICPPASTExpres
|
|||
* @since 5.4
|
||||
*/
|
||||
public IType getFieldOwnerType();
|
||||
|
||||
/**
|
||||
* @since 5.4
|
||||
*/
|
||||
@Override
|
||||
public ICPPASTExpression getFieldOwner();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ public abstract class ASTTypeIdInitializerExpression extends ASTNode implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public final ValueCategory getValueCategory() {
|
||||
public ValueCategory getValueCategory() {
|
||||
return ValueCategory.PRVALUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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()]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
Loading…
Add table
Reference in a new issue