From 56e5da5aa573119e765da47e1b1d7d7b98710647 Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Sun, 5 Mar 2023 15:12:42 +0300 Subject: [PATCH] Allow expansion with typeids in fold expression --- .../tests/ast2/cxx17/FoldExpressionTests.java | 36 +++++++++++++++++++ .../dom/parser/cpp/CPPASTFoldExpression.java | 19 ++++++++++ 2 files changed, 55 insertions(+) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/FoldExpressionTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/FoldExpressionTests.java index 35b2c6d6ff0..cdefebc3811 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/FoldExpressionTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/FoldExpressionTests.java @@ -186,4 +186,40 @@ public class FoldExpressionTests extends AST2CPPTestBase { IASTFunctionDefinition fdef = (IASTFunctionDefinition) tdef.getDeclaration(); IASTProblemExpression e1 = getExpressionOfStatement(fdef, 0); } + + // template struct predicate { + // static constexpr bool evaluated = true; + // }; + // + // template struct condition { + // static constexpr bool value = arg; + // }; + // + // template + // struct fold_condition { + // static constexpr bool value = condition<(predicate::evaluated && ...)>::value; + // }; + // + // constexpr bool result = fold_condition::value; + public void testFoldExpressionInClassTemplateArguments() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableValue("result", 1); + } + + // template constexpr bool predicate = true; + // + // template struct condition { + // static constexpr bool value = arg; + // }; + // + // template + // struct fold_condition { + // static constexpr bool value = condition<(predicate && ...)>::value; + // }; + // + // constexpr bool result = fold_condition::value; + public void testFoldExpressionInVariableTemplateArguments() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableValue("result", 1); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFoldExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFoldExpression.java index 4a88b91491f..851db7e366b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFoldExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFoldExpression.java @@ -19,14 +19,17 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitDestructorName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; 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.ICPPASTFoldExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; 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.CPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFoldExpression; @@ -103,6 +106,7 @@ public class CPPASTFoldExpression extends ASTNode implements ICPPASTFoldExpressi public UnexpandedParameterPackCounter() { super(false); shouldVisitExpressions = true; + shouldVisitTypeIds = true; count = 0; } @@ -122,6 +126,21 @@ public class CPPASTFoldExpression extends ASTNode implements ICPPASTFoldExpressi } return PROCESS_CONTINUE; } + + @Override + public int visit(IASTTypeId typeId) { + IType type = CPPVisitor.createType(typeId); + if (type instanceof ICPPTemplateParameter templateParameter) { + if (templateParameter.isParameterPack()) { + ++count; + } else { + boolean notParameterPack = true; + } + } else { + boolean notTemplateParameter = true; + } + return PROCESS_CONTINUE; + } } private int countUnexpandedParameterPacks(IASTExpression e) {