Skip to content

Commit

Permalink
Add c++17 fold expression
Browse files Browse the repository at this point in the history
  • Loading branch information
i-garrison authored and jonahgraham committed Feb 8, 2023
1 parent eb083f8 commit f2f8623
Show file tree
Hide file tree
Showing 11 changed files with 1,096 additions and 7 deletions.
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
* @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 {

}
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

0 comments on commit f2f8623

Please sign in to comment.