mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-03 22:35: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:
parent
8364d2fbce
commit
664da44695
4 changed files with 35 additions and 14 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,13 @@ public interface IASTTypeIdExpression extends IASTExpression {
|
|||
* @since 5.5
|
||||
*/
|
||||
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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue