Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add c++17 fold expression #234

Merged
merged 1 commit into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*******************************************************************************
* Copyright (c) 2023 Igor V. Kovalenko.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Igor V. Kovalenko - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2.cxx17;

import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;

import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;

/**
* AST tests for C++17 fold expressions.
*/
public class FoldExpressionTests extends AST2CPPTestBase {
// using size_t = decltype(sizeof(int));
//
// template<typename T> struct X {
// static constexpr size_t g(const T& arg) noexcept { return sizeof(arg); }
// };
//
// template<typename... Pack>
// constexpr size_t f1(const Pack&... pack) { return (... + X<Pack>::g(pack)); }
// template<typename... Pack>
// constexpr size_t f2(const Pack&... pack) { return (0 + ... + X<Pack>::g(pack)); }
// template<typename... Pack>
// constexpr size_t f3(const Pack&... pack) { return (X<Pack>::g(pack) + ...); }
// template<typename... Pack>
// constexpr size_t f4(const Pack&... pack) { return (X<Pack>::g(pack) + ... + 0); }
//
// static constexpr auto val1 = f1(1, 2., "1");
// static constexpr auto val2 = f2(1, 2., "12");
// static constexpr auto val3 = f3(1, 2., "123");
// static constexpr auto val4 = f4(1, 2., "1234");
public void testFoldExpression1() throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableValue("val1", 14);
helper.assertVariableValue("val2", 15);
helper.assertVariableValue("val3", 16);
helper.assertVariableValue("val4", 17);
}

// template<typename... Pack>
// constexpr bool f1(const Pack&... pack) { return (... && pack); }
// template<typename... Pack>
// constexpr bool f2(const Pack&... pack) { return (pack && ...); }
// template<typename... Pack>
// constexpr bool f3(const Pack&... pack) { return (... || pack); }
// template<typename... Pack>
// constexpr bool f4(const Pack&... pack) { return (pack || ...); }
//
// static constexpr auto val1 = f1();
// static constexpr auto val21 = f2(false);
// static constexpr auto val22 = f2(true);
// static constexpr auto val3 = f3();
// static constexpr auto val41 = f4(false);
// static constexpr auto val42 = f4(true);
public void testFoldExpression2() throws Exception {
parseAndCheckBindings();
BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableValue("val1", 1);
helper.assertVariableValue("val21", 0);
helper.assertVariableValue("val22", 1);
helper.assertVariableValue("val3", 0);
helper.assertVariableValue("val41", 0);
helper.assertVariableValue("val42", 1);
}

// template <typename CharT>
// struct ostream {
// template <typename T>
// ostream& operator<<(T);
//
// ostream& operator<<(ostream&(*)(ostream&));
// };
//
// template <typename CharT>
// ostream<CharT>& endl(ostream<CharT>&);
//
// template <typename... T>
// void sum(T... vals) {
// ostream<char> out;
// out << (... + vals) << endl;
// }
public void testFoldExpressionInBinaryExpression() throws Exception {
parseAndCheckBindings();
}

// template<typename... T>
// void sum(T... vals) {
// bar(... + vals);
// }
public void testFoldExpressionRecognition1() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu = parse(code, CPP, false, false);
ICPPASTTemplateDeclaration tdef = getDeclaration(tu, 0);
IASTFunctionDefinition fdef = (IASTFunctionDefinition) tdef.getDeclaration();
IASTProblemStatement p1 = getStatement(fdef, 0);
}

// template<typename... T>
// void sum(T... vals) {
// ... + vals;
// }
public void testFoldExpressionRecognition2() throws Exception {
final String code = getAboveComment();
IASTTranslationUnit tu = parse(code, CPP, false, false);
ICPPASTTemplateDeclaration tdef = getDeclaration(tu, 0);
IASTFunctionDefinition fdef = (IASTFunctionDefinition) tdef.getDeclaration();
IASTProblemStatement p1 = getStatement(fdef, 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2022 Igor V. Kovalenko.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Igor V. Kovalenko - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;

/**
* Fold expression, introduced in C++17.
*
* @since 8.0
jonahgraham marked this conversation as resolved.
Show resolved Hide resolved
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/

public interface ICPPASTFoldExpression extends ICPPASTExpression {
i-garrison marked this conversation as resolved.
Show resolved Hide resolved

}
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,17 @@ public ICPPASTFunctionWithTryBlock newFunctionTryBlock(IASTDeclSpecifier declSpe
*/
public ICPPASTLambdaExpression newLambdaExpression();

/**
* @since 8.0
*/
public IASTExpression newFoldExpressionToken();

/**
* @since 8.0
*/
public ICPPASTFoldExpression newFoldExpression(int opToken, boolean isComma, IASTExpression lhs,
IASTExpression rhs);

public ICPPASTLinkageSpecification newLinkageSpecification(String literal);

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1010,9 +1010,13 @@ public BinaryOperator getNext() {
public void setNext(BinaryOperator next) {
fNext = next;
}

public int getOperatorToken() {
return fOperatorToken;
}
}

public final IASTExpression buildExpression(BinaryOperator leftChain, IASTInitializerClause expr) {
public IASTExpression buildExpression(BinaryOperator leftChain, IASTInitializerClause expr) {
BinaryOperator rightChain = null;
for (;;) {
if (leftChain == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public interface ITypeMarshalBuffer {
EVAL_FUNCTION_SET = 0x09, EVAL_ID = 0x0A, EVAL_INIT_LIST = 0x0B, EVAL_MEMBER_ACCESS = 0x0C,
EVAL_PACK_EXPANSION = 0x0D, EVAL_TYPE_ID = 0x0E, EVAL_UNARY = 0x0F, EVAL_UNARY_TYPE_ID = 0x10,
EVAL_CONSTRUCTOR = 0x11, EVAL_REFERENCE = 0x12, EVAL_POINTER = 0x13, EVAL_COMPOSITE_ACCESS = 0x14,
EVAL_NARY_TYPE_ID = 0x15, EVAL_PACK_ACCESS = 0x16;
EVAL_NARY_TYPE_ID = 0x15, EVAL_PACK_ACCESS = 0x16, EVAL_FOLD_EXPRESSION = 0x17;
// Can add more evaluations up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.

final static byte EXEC_COMPOUND_STATEMENT = 0x01, EXEC_BREAK = 0x02, EXEC_CASE = 0x03, EXEC_CONTINUE = 0x04,
Expand Down