diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index bada355b7d4..ab237d266b2 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -11385,4 +11385,19 @@ public class AST2TemplateTests extends AST2CPPTestBase { public void testStringLiteralOperatorTemplate_536986() throws Exception { parseAndCheckImplicitNameBindings(); } + + // template + // struct integer_sequence {}; + // + // template + // using make_integer_sequence = integer_sequence<__integer_pack(N)...>; + // + // using type1 = integer_sequence<0, 1, 2>; + // using type2 = make_integer_sequence<3>; + public void testIntegerPack_553794() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + ITypedef type1 = helper.assertNonProblem("type1"); + ITypedef type2 = helper.assertNonProblem("type2"); + assertSameType(type1, type2); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java index 36113a7ae06..41fb096edf5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java @@ -134,6 +134,12 @@ public interface IASTUnaryExpression extends IASTExpression { */ public static final int op_labelReference = 18; + /** + * For GCC parsers in C++ mode, only: '__integer_pack ( expression )' + * @since 6.10 + */ + public static final int op_integerPack = 19; + /** * {@code OPERAND} represents the relationship between an {@code IASTUnaryExpression} and * it's nested {@code IASTExpression}. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java index c3dc69c9c3d..b113e67ba71 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java @@ -175,6 +175,7 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu } if (version >= VERSION_8_0) { addKeyword(GCCKeywords.cp__is_constructible, IGCCToken.tTT_is_constructible); + addKeyword(GCCKeywords.cp__integer_pack, IGCCToken.tTT_integer_pack); } } else if (compiler == CompilerType.Clang) { // As documented at @@ -201,6 +202,7 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu addKeyword(GCCKeywords.cp__is_trivially_constructible, IGCCToken.tTT_is_trivially_constructible); addKeyword(GCCKeywords.cp__is_trivially_assignable, IGCCToken.tTT_is_trivially_assignable); addKeyword(GCCKeywords.cp__is_constructible, IGCCToken.tTT_is_constructible); + addKeyword(GCCKeywords.cp__integer_pack, IGCCToken.tTT_integer_pack); } else if (compiler == CompilerType.MSVC) { // As documented at // https://docs.microsoft.com/en-us/cpp/extensions/compiler-support-for-type-traits-cpp-component-extensions?view=vs-2017 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java index a14247f402a..b4422a6961b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java @@ -90,4 +90,7 @@ public class GCCKeywords { /** @since 6.6 */ public static final char[] cp__is_constructible = "__is_constructible".toCharArray(); + + /** @since 6.10 */ + public static final char[] cp__integer_pack = "__integer_pack".toCharArray(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java index d374401695f..7ab81f8b556 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java @@ -93,4 +93,7 @@ public interface IGCCToken extends IToken { /** @since 6.6 */ int tTT_is_constructible = FIRST_RESERVED_IGCCToken + 35; + + /** @since 6.10 */ + int tTT_integer_pack = FIRST_RESERVED_IGCCToken + 36; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 860cd7d20d0..58686ecc0b4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -1540,7 +1540,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IGCCToken.t___alignof__: return parseTypeidInParenthesisOrUnaryExpression(false, consume().getOffset(), IASTTypeIdExpression.op_alignof, IASTUnaryExpression.op_alignOf, ctx, strat); - + case IGCCToken.tTT_integer_pack: + return unaryExpression(IASTUnaryExpression.op_integerPack, ctx, strat); case IGCCToken.tTT_has_nothrow_assign: case IGCCToken.tTT_has_nothrow_constructor: case IGCCToken.tTT_has_nothrow_copy: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index 1dde894ea42..79eb2395633 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -19,6 +19,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_alignOf; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_amper; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_bracketedPrimary; +import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_integerPack; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_minus; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_noexcept; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_not; @@ -156,6 +157,8 @@ public class EvalUnary extends CPPDependentEvaluation { return fArgument.referencesTemplateParameter(); case op_throw: return false; + case op_integerPack: + return true; default: return fArgument.isValueDependent(); } @@ -242,6 +245,8 @@ public class EvalUnary extends CPPDependentEvaluation { return CPPVisitor.get_type_info(); case op_throw: return CPPSemantics.VOID_TYPE; + case op_integerPack: + return fArgument.getType(); case op_amper: if (fAddressOfQualifiedNameBinding instanceof ICPPMember) { ICPPMember member = (ICPPMember) fAddressOfQualifiedNameBinding; @@ -394,6 +399,10 @@ public class EvalUnary extends CPPDependentEvaluation { @Override public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) { + if (fOperator == op_integerPack && context.getPackOffset() != -1) { + return new EvalFixed(getType(), ValueCategory.PRVALUE, IntegralValue.create(context.getPackOffset())); + } + ICPPEvaluation argument = fArgument.instantiate(context, maxDepth); IBinding binding = fAddressOfQualifiedNameBinding; if (binding instanceof ICPPUnknownBinding) { @@ -520,6 +529,15 @@ public class EvalUnary extends CPPDependentEvaluation { @Override public int determinePackSize(ICPPTemplateParameterMap tpMap) { + if (fOperator == op_integerPack) { + ICPPEvaluation instantiatedArg = fArgument.instantiate(new InstantiationContext(tpMap), + IntegralValue.MAX_RECURSION_DEPTH); + IValue value = instantiatedArg.getValue(); + if (value.numberValue() != null) { + return (int) value.numberValue().longValue(); + } + return CPPTemplates.PACK_SIZE_DEFER; + } return fArgument.determinePackSize(tpMap); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java index 2f06777d22c..c6f17142c50 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java @@ -2322,6 +2322,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable { addTypeTraitPrimitive("is_trivially_copyable", GCCKeywords.cp__is_trivially_copyable); addTypeTraitPrimitive("is_union", GCCKeywords.cp__is_union); addTypeTraitPrimitive("underlying_type", GCCKeywords.cp__underlying_type); + + // TODO: If at some point we add support for __has_builtin, "__integer_pack" + // should be added to the list of supported builtins. } return sSupportedFeatures; }