1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 06:45:43 +02:00

Bug 401973 - sizeof... operator on a template parameter pack

Change-Id: Ia502928ddf8fc2003f3a034ef13d38622ad9f0b9
Reviewed-on: https://git.eclipse.org/r/10803
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2013-02-28 04:08:40 -05:00 committed by Sergey Prigogin
parent 8364d2fbce
commit 664da44695
4 changed files with 35 additions and 14 deletions

View file

@ -7351,4 +7351,17 @@ public class AST2TemplateTests extends AST2TestBase {
public void testVariadicNonTypeTemplateParameter_401400() throws Exception {
parseAndCheckBindings();
}
// template <typename... Args>
// struct foo {
// static constexpr int i = sizeof...(Args);
// };
// constexpr int bar = foo<int, double>::i;
public void testSizeofParameterPackOnTypeid_401973() throws Exception {
BindingAssertionHelper helper = new BindingAssertionHelper(getAboveComment(), true);
ICPPVariable bar = helper.assertNonProblem("bar", ICPPVariable.class);
Long barValue = bar.getInitialValue().numericalValue();
assertNotNull(barValue);
assertEquals(2, barValue.longValue());
}
}

View file

@ -146,6 +146,12 @@ public interface IASTTypeIdExpression extends IASTExpression {
*/
public static final int op_is_trivial= 21;
/**
* <code>op_sizeofParameterPack</code> is used for sizeof... ( typeid ) expressions.
* @since 5.5
*/
public static final int op_sizeofParameterPack = 22;
/**
* @deprecated constants should be declared here, to avoid using the same constant in different
* interfaces.

View file

@ -1279,19 +1279,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LTcatchEOF(2) == IToken.tELLIPSIS) {
int offset= consume().getOffset(); // sizeof
consume(); // ...
consume(IToken.tLPAREN); // (
IASTName id= identifier();
IASTIdExpression idexpr= nodeFactory.newIdExpression(id);
setRange(idexpr, id);
IASTUnaryExpression expr= nodeFactory.newUnaryExpression(IASTUnaryExpression.op_sizeofParameterPack, idexpr);
final int lt1= LT(1);
if (lt1 == IToken.tEOC) {
setRange(expr, offset, calculateEndOffset(id));
} else {
final int endOffset = consume(IToken.tRPAREN).getEndOffset(); // )
setRange(expr, offset, endOffset);
}
return expr;
return parseTypeidInParenthesisOrUnaryExpression(true, offset,
IASTTypeIdExpression.op_sizeofParameterPack,
IASTUnaryExpression.op_sizeofParameterPack, ctx, strat);
}
return parseTypeidInParenthesisOrUnaryExpression(false, consume().getOffset(),
IASTTypeIdExpression.op_sizeof, IASTUnaryExpression.op_sizeof, ctx, strat);

View file

@ -32,6 +32,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_standard_l
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_trivial;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_union;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeof;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeofParameterPack;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeid;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof;
@ -92,6 +93,8 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
@Override
public boolean isValueDependent() {
switch (fOperator) {
case op_sizeofParameterPack:
return true;
case op_sizeof:
case op_alignof:
case op_has_nothrow_copy:
@ -130,6 +133,7 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
private IType computeType(IASTNode point) {
switch (fOperator) {
case op_sizeof:
case op_sizeofParameterPack:
case op_alignof:
return CPPVisitor.get_SIZE_T(point);
case op_typeid:
@ -191,6 +195,14 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
if (fOperator == op_sizeofParameterPack) {
int packSize = determinePackSize(tpMap);
if (packSize == CPPTemplates.PACK_SIZE_FAIL || packSize == CPPTemplates.PACK_SIZE_NOT_FOUND) {
return EvalFixed.INCOMPLETE;
} else if (packSize != CPPTemplates.PACK_SIZE_DEFER) {
return new EvalFixed(getTypeOrFunctionSet(point), getValueCategory(point), Value.create(packSize));
}
}
IType type = CPPTemplates.instantiateType(fOrigType, tpMap, packOffset, within, point);
if (type == fOrigType)
return this;