mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
Bug 528072 - Implement evaluation of __is_trivially_constructible
Change-Id: I331ea5c2f5203a87290d4ef537a8a75dab384c34
This commit is contained in:
parent
f8cd850957
commit
2ac7089288
9 changed files with 266 additions and 7 deletions
|
@ -12500,4 +12500,19 @@ public class AST2CPPTests extends AST2CPPTestBase {
|
||||||
public void test_ElabTypeSpecInNewExprInConditional_526134() throws Exception {
|
public void test_ElabTypeSpecInNewExprInConditional_526134() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constexpr bool waldo1 = __is_trivially_constructible(int, short);
|
||||||
|
// struct S { int fMem; S(int mem) : fMem(mem) {} };
|
||||||
|
// constexpr bool waldo2 = __is_trivially_constructible(S);
|
||||||
|
// constexpr bool waldo3 = __is_trivially_constructible(S, const S&);
|
||||||
|
// constexpr bool waldo4 = __is_trivially_constructible(S, int);
|
||||||
|
// constexpr bool waldo5 = __is_trivially_constructible(S, const S&, float);
|
||||||
|
public void testIsTriviallyConstructible_528072() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo1", 1);
|
||||||
|
helper.assertVariableValue("waldo2", 0);
|
||||||
|
helper.assertVariableValue("waldo3", 1);
|
||||||
|
helper.assertVariableValue("waldo4", 0);
|
||||||
|
helper.assertVariableValue("waldo5", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,8 @@ public interface ITypeMarshalBuffer {
|
||||||
EVAL_CONSTRUCTOR = 0x11,
|
EVAL_CONSTRUCTOR = 0x11,
|
||||||
EVAL_REFERENCE = 0x12,
|
EVAL_REFERENCE = 0x12,
|
||||||
EVAL_POINTER = 0x13,
|
EVAL_POINTER = 0x13,
|
||||||
EVAL_COMPOSITE_ACCESS = 0x14;
|
EVAL_COMPOSITE_ACCESS = 0x14,
|
||||||
|
EVAL_NARY_TYPE_ID = 0x15;
|
||||||
// Can add more evaluations up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
|
// Can add more evaluations up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
|
||||||
|
|
||||||
final static byte
|
final static byte
|
||||||
|
|
|
@ -37,6 +37,8 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof;
|
||||||
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.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.TDEF;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression;
|
||||||
|
@ -57,6 +59,8 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression.Operator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
@ -268,6 +272,14 @@ public class ValueFactory {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IValue evaluateNaryTypeIdExpression(Operator operator, IType[] operands,
|
||||||
|
IBinding pointOfDefinition) {
|
||||||
|
IValue val = applyNaryTypeIdOperator(operator, operands, pointOfDefinition);
|
||||||
|
if (isInvalidValue(val))
|
||||||
|
return IntegralValue.UNKNOWN;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the canonical representation of the value of the expression.
|
* Computes the canonical representation of the value of the expression.
|
||||||
*/
|
*/
|
||||||
|
@ -596,6 +608,21 @@ public class ValueFactory {
|
||||||
return IntegralValue.UNKNOWN;
|
return IntegralValue.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IValue applyNaryTypeIdOperator(ICPPASTNaryTypeIdExpression.Operator operator,
|
||||||
|
IType[] operands, IBinding pointOfDefinition) {
|
||||||
|
switch (operator) {
|
||||||
|
case __is_trivially_constructible:
|
||||||
|
if (operands.length == 0) {
|
||||||
|
return IntegralValue.UNKNOWN;
|
||||||
|
}
|
||||||
|
IType typeToConstruct = operands[0];
|
||||||
|
IType[] argumentTypes = Arrays.copyOfRange(operands, 1, operands.length);
|
||||||
|
return IntegralValue.create(TypeTraits.isTriviallyConstructible(typeToConstruct, argumentTypes,
|
||||||
|
pointOfDefinition) ? 1 : 0);
|
||||||
|
}
|
||||||
|
return IntegralValue.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isInvalidValue(IValue value) {
|
private static boolean isInvalidValue(IValue value) {
|
||||||
return value == null || value == IntegralValue.UNKNOWN || value == IntegralValue.ERROR;
|
return value == null || value == IntegralValue.UNKNOWN || value == IntegralValue.ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,15 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
|
||||||
|
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.EvalFixed;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalNaryTypeId;
|
||||||
|
|
||||||
public class CPPASTNaryTypeIdExpression extends ASTNode implements ICPPASTNaryTypeIdExpression {
|
public class CPPASTNaryTypeIdExpression extends ASTNode implements ICPPASTNaryTypeIdExpression {
|
||||||
private Operator fOperator;
|
private Operator fOperator;
|
||||||
private ICPPASTTypeId[] fOperands;
|
private ICPPASTTypeId[] fOperands;
|
||||||
|
private ICPPEvaluation fEvaluation;
|
||||||
|
|
||||||
public CPPASTNaryTypeIdExpression(Operator operator, ICPPASTTypeId[] operands) {
|
public CPPASTNaryTypeIdExpression(Operator operator, ICPPASTTypeId[] operands) {
|
||||||
fOperator = operator;
|
fOperator = operator;
|
||||||
|
@ -81,14 +85,23 @@ public class CPPASTNaryTypeIdExpression extends ASTNode implements ICPPASTNaryTy
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation getEvaluation() {
|
public ICPPEvaluation getEvaluation() {
|
||||||
// TODO: Implement. This will need a new evaluation type, EvalNaryTypeId.
|
if (fEvaluation == null) {
|
||||||
return EvalFixed.INCOMPLETE;
|
IType[] types = new IType[fOperands.length];
|
||||||
|
for (int i = 0; i < fOperands.length; i++) {
|
||||||
|
types[i] = CPPVisitor.createType(fOperands[i]);
|
||||||
|
if (types[i] == null) {
|
||||||
|
fEvaluation = EvalFixed.INCOMPLETE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fEvaluation = new EvalNaryTypeId(fOperator, types, this);
|
||||||
|
}
|
||||||
|
return fEvaluation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IType getExpressionType() {
|
public IType getExpressionType() {
|
||||||
// TODO: When getEvaluation() is implemented, delegate to getEvaluation().getType().
|
return CPPEvaluation.getType(this);
|
||||||
return CPPBasicType.BOOLEAN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs evaluation of an expression.
|
* Evaluation for a binary type-id expression.
|
||||||
*/
|
*/
|
||||||
public class EvalBinaryTypeId extends CPPDependentEvaluation {
|
public class EvalBinaryTypeId extends CPPDependentEvaluation {
|
||||||
private final Operator fOperator;
|
private final Operator fOperator;
|
||||||
|
@ -153,6 +153,6 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean referencesTemplateParameter() {
|
public boolean referencesTemplateParameter() {
|
||||||
return CPPTemplates.isDependentType(fType1) || CPPTemplates.isDependentType(fType2);
|
return isValueDependent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017 Nathan Ridge.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNaryTypeIdExpression.Operator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
|
||||||
|
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.ValueFactory;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluation for a n-ary type-id expression.
|
||||||
|
*/
|
||||||
|
public class EvalNaryTypeId extends CPPDependentEvaluation {
|
||||||
|
private final Operator fOperator;
|
||||||
|
private final IType[] fOperands;
|
||||||
|
|
||||||
|
private boolean fCheckedValueDependent;
|
||||||
|
private boolean fIsValueDependent;
|
||||||
|
|
||||||
|
public EvalNaryTypeId(Operator operator, IType[] operands, IASTNode pointOfDefinition) {
|
||||||
|
this(operator, operands, findEnclosingTemplate(pointOfDefinition));
|
||||||
|
}
|
||||||
|
|
||||||
|
public EvalNaryTypeId(Operator operator, IType[] operands, IBinding templateDefinition) {
|
||||||
|
super(templateDefinition);
|
||||||
|
fOperator = operator;
|
||||||
|
fOperands = operands;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Operator getOperator() {
|
||||||
|
return fOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IType[] getOperands() {
|
||||||
|
return fOperands;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInitializerList() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFunctionSet() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTypeDependent() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValueDependent() {
|
||||||
|
if (!fCheckedValueDependent) {
|
||||||
|
for (IType operand : fOperands) {
|
||||||
|
if (CPPTemplates.isDependentType(operand)) {
|
||||||
|
fIsValueDependent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fCheckedValueDependent = true;
|
||||||
|
}
|
||||||
|
return fIsValueDependent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConstantExpression() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IType getType() {
|
||||||
|
switch (fOperator) {
|
||||||
|
case __is_trivially_constructible:
|
||||||
|
return CPPBasicType.BOOLEAN;
|
||||||
|
}
|
||||||
|
return ProblemType.UNKNOWN_FOR_EXPRESSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IValue getValue() {
|
||||||
|
if (isValueDependent()) {
|
||||||
|
return DependentValue.create(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValueFactory.evaluateNaryTypeIdExpression(fOperator, fOperands, getTemplateDefinition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ValueCategory getValueCategory() {
|
||||||
|
return ValueCategory.PRVALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
|
||||||
|
IType[] operands = CPPTemplates.instantiateTypes(fOperands, context);
|
||||||
|
if (operands == fOperands) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return new EvalNaryTypeId(fOperator, operands, getTemplateDefinition());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPEvaluation computeForFunctionCall(ActivationRecord record,
|
||||||
|
ConstexprEvaluationContext context) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
||||||
|
int result = 0;
|
||||||
|
for (int i = 0; i < fOperands.length; i++) {
|
||||||
|
result = CPPTemplates.combinePackSize(result,
|
||||||
|
CPPTemplates.determinePackSize(fOperands[i], tpMap));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return isValueDependent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
|
||||||
|
buffer.putShort(ITypeMarshalBuffer.EVAL_NARY_TYPE_ID);
|
||||||
|
buffer.putByte((byte) fOperator.ordinal());
|
||||||
|
buffer.putInt(fOperands.length);
|
||||||
|
for (IType operand : fOperands) {
|
||||||
|
buffer.marshalType(operand);
|
||||||
|
}
|
||||||
|
marshalTemplateDefinition(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ICPPEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
|
||||||
|
int op = buffer.getByte();
|
||||||
|
int len = buffer.getInt();
|
||||||
|
IType[] operands = new IType[len];
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
operands[i] = buffer.unmarshalType();
|
||||||
|
}
|
||||||
|
IBinding templateDefinition = buffer.unmarshalBinding();
|
||||||
|
return new EvalNaryTypeId(Operator.values()[op], operands, templateDefinition);
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,9 +20,11 @@ import java.util.Set;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||||
|
@ -30,12 +32,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries;
|
import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
|
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
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.CPPFunction;
|
||||||
|
@ -43,6 +47,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitConstructor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -559,4 +564,29 @@ public class TypeTraits {
|
||||||
return isScalar(type);
|
return isScalar(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if 'typeToConstruct' is trivially constructible from arguments
|
||||||
|
* of type 'argumentTypes', as defined in [meta.unary.prop].
|
||||||
|
*/
|
||||||
|
public static boolean isTriviallyConstructible(IType typeToConstruct, IType[] argumentTypes,
|
||||||
|
IBinding pointOfDefinition) {
|
||||||
|
IType type = SemanticUtil.getSimplifiedType(typeToConstruct);
|
||||||
|
if (!(type instanceof ICPPClassType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Invent (the evaluation of) a type constructor expression of the form "T(declval<Args>()...)".
|
||||||
|
// (The standard says a variable declaration of the form "T t(declval<Args>()...)",
|
||||||
|
// but we don't currently type-check variable initialization, and a type constructor expression
|
||||||
|
// should have the same semantics.)
|
||||||
|
ICPPEvaluation[] arguments = new ICPPEvaluation[argumentTypes.length];
|
||||||
|
for (int i = 0; i < argumentTypes.length; i++) {
|
||||||
|
// Value category is xvalue because declval() returns an rvalue reference.
|
||||||
|
arguments[i] = new EvalFixed(argumentTypes[i], ValueCategory.XVALUE, IntegralValue.UNKNOWN);
|
||||||
|
}
|
||||||
|
EvalTypeId eval = new EvalTypeId(type, pointOfDefinition, false, false, arguments);
|
||||||
|
ICPPFunction constructor = eval.getConstructor();
|
||||||
|
// TODO check that conversions are trivial as well
|
||||||
|
return constructor instanceof ICPPMethod && ((ICPPMethod) constructor).isImplicit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalNaryTypeId;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackExpansion;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackExpansion;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
|
||||||
|
@ -441,6 +442,14 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
|
||||||
compositeTemplateDefinition);
|
compositeTemplateDefinition);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
if (eval instanceof EvalNaryTypeId) {
|
||||||
|
EvalNaryTypeId e = (EvalNaryTypeId) eval;
|
||||||
|
IType[] operands = e.getOperands();
|
||||||
|
IType[] operands2 = getCompositeTypes(operands);
|
||||||
|
if (operands != operands2 || templateDefinition != compositeTemplateDefinition)
|
||||||
|
e = new EvalNaryTypeId(e.getOperator(), operands2, compositeTemplateDefinition);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
if (eval instanceof EvalPackExpansion) {
|
if (eval instanceof EvalPackExpansion) {
|
||||||
EvalPackExpansion e = (EvalPackExpansion) eval;
|
EvalPackExpansion e = (EvalPackExpansion) eval;
|
||||||
ICPPEvaluation a = e.getExpansionPattern();
|
ICPPEvaluation a = e.getExpansionPattern();
|
||||||
|
|
|
@ -131,6 +131,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalNaryTypeId;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackExpansion;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPackExpansion;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPointer;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalPointer;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalReference;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalReference;
|
||||||
|
@ -1698,6 +1699,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
return EvalPointer.unmarshal(firstBytes, buffer);
|
return EvalPointer.unmarshal(firstBytes, buffer);
|
||||||
case ITypeMarshalBuffer.EVAL_COMPOSITE_ACCESS:
|
case ITypeMarshalBuffer.EVAL_COMPOSITE_ACCESS:
|
||||||
return EvalCompositeAccess.unmarshal(firstBytes, buffer);
|
return EvalCompositeAccess.unmarshal(firstBytes, buffer);
|
||||||
|
case ITypeMarshalBuffer.EVAL_NARY_TYPE_ID:
|
||||||
|
return EvalNaryTypeId.unmarshal(firstBytes, buffer);
|
||||||
}
|
}
|
||||||
throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first bytes=" + firstBytes)); //$NON-NLS-1$
|
throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first bytes=" + firstBytes)); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue