mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-01 04:33:36 +02:00
Bug 522216, 527427: [C++17] Support for constexpr if and init-statements
Change-Id: Ia8195c66334edb107848901619e85fbfb5c78b18 Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch>
This commit is contained in:
parent
cb5c699871
commit
a51f7c0659
17 changed files with 688 additions and 63 deletions
|
@ -10651,4 +10651,148 @@ public class AST2TemplateTests extends AST2CPPTestBase {
|
||||||
public void testLongDependentFunctionCallChain_530692() throws Exception {
|
public void testLongDependentFunctionCallChain_530692() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // A metafunction that loops infinitely on odd inputs.
|
||||||
|
// template <int N>
|
||||||
|
// struct meta {
|
||||||
|
// static constexpr int value = 1 + meta<N - 2>::value;
|
||||||
|
// };
|
||||||
|
// template <>
|
||||||
|
// struct meta<0> {
|
||||||
|
// static constexpr int value = 0;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// // A constexpr function that calls 'meta' on an odd input
|
||||||
|
// // but only in the uninstantiated branch of a constexpr if.
|
||||||
|
// template <int N>
|
||||||
|
// constexpr int foo() {
|
||||||
|
// if constexpr (N % 2 != 0) {
|
||||||
|
// return meta<N - 1>::value;
|
||||||
|
// } else {
|
||||||
|
// return meta<N>::value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Call the function
|
||||||
|
// constexpr int waldo = foo<7>();
|
||||||
|
public void testConditionalInstantiationOfConstexprIfTrueBranch_527427() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo", 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// // A metafunction that loops infinitely on odd inputs.
|
||||||
|
// template <int N>
|
||||||
|
// struct meta {
|
||||||
|
// static constexpr int value = 1 + meta<N - 2>::value;
|
||||||
|
// };
|
||||||
|
// template <>
|
||||||
|
// struct meta<0> {
|
||||||
|
// static constexpr int value = 0;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// // A constexpr function that calls 'meta' on an odd input
|
||||||
|
// // but only in the uninstantiated branch of a constexpr if.
|
||||||
|
// template <int N>
|
||||||
|
// constexpr int foo() {
|
||||||
|
// if constexpr (N % 2 == 0) {
|
||||||
|
// return meta<N>::value;
|
||||||
|
// } else {
|
||||||
|
// return meta<N - 1>::value;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Call the function
|
||||||
|
// constexpr int waldo = foo<7>();
|
||||||
|
public void testConditionalInstantiationOfConstexprIfFalseBranch_527427() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo", 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// template <int N>
|
||||||
|
// constexpr int fib() {
|
||||||
|
// if constexpr (N == 0) {
|
||||||
|
// return 0;
|
||||||
|
// } else if constexpr (N == 1) {
|
||||||
|
// return 1;
|
||||||
|
// } else {
|
||||||
|
// return fib<N - 1>() + fib<N - 2>();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Call the function
|
||||||
|
// constexpr int waldo = fib<7>();
|
||||||
|
public void testConstexprFibonacciConstexprIf_527427() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo", 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constexpr int g(int x) {
|
||||||
|
// return x * 2;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// template <int N>
|
||||||
|
// constexpr int foo() {
|
||||||
|
// if constexpr (constexpr auto x = g(N)) {
|
||||||
|
// return 14 / x;
|
||||||
|
// } else {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Call the function
|
||||||
|
// constexpr int waldo = foo<2>();
|
||||||
|
public void testConstexprIfDeclarationTrueBranch_527427() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo", 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constexpr int g(int x) {
|
||||||
|
// return x * 2;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// template <int N>
|
||||||
|
// constexpr int foo() {
|
||||||
|
// if constexpr (constexpr auto x = g(N)) {
|
||||||
|
// return 14 / x;
|
||||||
|
// } else {
|
||||||
|
// return 42;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Call the function
|
||||||
|
// constexpr int waldo = foo<0>();
|
||||||
|
public void testConstexprIfDeclarationFalseBranch_527427() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo", 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constexpr auto foo() {
|
||||||
|
// if constexpr (false) {
|
||||||
|
// return "Error";
|
||||||
|
// } else {
|
||||||
|
// return 42;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Call the function
|
||||||
|
// constexpr auto waldo = foo();
|
||||||
|
public void testReturnAutoConstexprIfDeclarationFalseBranchValueExpression_527427() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo", 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constexpr auto foo() {
|
||||||
|
// if constexpr (true) {
|
||||||
|
// return 42;
|
||||||
|
// } else {
|
||||||
|
// return "Error";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Call the function
|
||||||
|
// constexpr auto waldo = foo();
|
||||||
|
public void testReturnAutoConstexprIfDeclarationTrueBranchValueExpression_527427() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
helper.assertVariableValue("waldo", 42);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -703,6 +703,56 @@ public class DOMLocationTests extends AST2TestBase {
|
||||||
assertSoleLocation(declarator, code.indexOf(rawDeclarator), rawDeclarator.length());
|
assertSoleLocation(declarator, code.indexOf(rawDeclarator), rawDeclarator.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIfInitStatement_1() throws Exception {
|
||||||
|
String code = "void foo() { if (int i = 1; i == 1) {} }"; //$NON-NLS-1$
|
||||||
|
IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
|
||||||
|
ICPPASTFunctionDefinition definition = (ICPPASTFunctionDefinition) tu.getDeclarations()[0];
|
||||||
|
IASTCompoundStatement body = (IASTCompoundStatement) definition.getBody();
|
||||||
|
IASTIfStatement statement = (IASTIfStatement) body.getStatements()[0];
|
||||||
|
String rawDeclarator = "if (int i = 1; i == 1) {}"; //$NON-NLS-1$
|
||||||
|
assertSoleLocation(statement, code.indexOf(rawDeclarator), rawDeclarator.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIfInitStatement_2() throws Exception {
|
||||||
|
String code = "void foo() { if (; bool b = true) {} }"; //$NON-NLS-1$
|
||||||
|
IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
|
||||||
|
ICPPASTFunctionDefinition definition = (ICPPASTFunctionDefinition) tu.getDeclarations()[0];
|
||||||
|
IASTCompoundStatement body = (IASTCompoundStatement) definition.getBody();
|
||||||
|
IASTIfStatement statement = (IASTIfStatement) body.getStatements()[0];
|
||||||
|
String rawDeclarator = "if (; bool b = true) {}"; //$NON-NLS-1$
|
||||||
|
assertSoleLocation(statement, code.indexOf(rawDeclarator), rawDeclarator.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConstexprIf_1() throws Exception {
|
||||||
|
String code = "void foo() { if constexpr (true) {} }"; //$NON-NLS-1$
|
||||||
|
IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
|
||||||
|
ICPPASTFunctionDefinition definition = (ICPPASTFunctionDefinition) tu.getDeclarations()[0];
|
||||||
|
IASTCompoundStatement body = (IASTCompoundStatement) definition.getBody();
|
||||||
|
IASTIfStatement statement = (IASTIfStatement) body.getStatements()[0];
|
||||||
|
String rawDeclarator = "if constexpr (true) {}"; //$NON-NLS-1$
|
||||||
|
assertSoleLocation(statement, code.indexOf(rawDeclarator), rawDeclarator.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConstexprIf_2() throws Exception {
|
||||||
|
String code = "void foo() { if constexpr (constexpr int i = 1; i == 1) {} }"; //$NON-NLS-1$
|
||||||
|
IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
|
||||||
|
ICPPASTFunctionDefinition definition = (ICPPASTFunctionDefinition) tu.getDeclarations()[0];
|
||||||
|
IASTCompoundStatement body = (IASTCompoundStatement) definition.getBody();
|
||||||
|
IASTIfStatement statement = (IASTIfStatement) body.getStatements()[0];
|
||||||
|
String rawDeclarator = "if constexpr (constexpr int i = 1; i == 1) {}"; //$NON-NLS-1$
|
||||||
|
assertSoleLocation(statement, code.indexOf(rawDeclarator), rawDeclarator.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConstexprIf_3() throws Exception {
|
||||||
|
String code = "void foo() { if constexpr (; constexpr bool b = true) {} }"; //$NON-NLS-1$
|
||||||
|
IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
|
||||||
|
ICPPASTFunctionDefinition definition = (ICPPASTFunctionDefinition) tu.getDeclarations()[0];
|
||||||
|
IASTCompoundStatement body = (IASTCompoundStatement) definition.getBody();
|
||||||
|
IASTIfStatement statement = (IASTIfStatement) body.getStatements()[0];
|
||||||
|
String rawDeclarator = "if constexpr (; constexpr bool b = true) {}"; //$NON-NLS-1$
|
||||||
|
assertSoleLocation(statement, code.indexOf(rawDeclarator), rawDeclarator.length());
|
||||||
|
}
|
||||||
|
|
||||||
// int main(void){
|
// int main(void){
|
||||||
// #define one 1
|
// #define one 1
|
||||||
// int integer = one;
|
// int integer = one;
|
||||||
|
|
|
@ -194,4 +194,69 @@ public class IfStatementTests extends TestBase {
|
||||||
public void testDeclarationInIfStatementCondition3() throws Exception {
|
public void testDeclarationInIfStatementCondition3() throws Exception {
|
||||||
assertEvaluationEquals(7);
|
assertEvaluationEquals(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constexpr int g(int x) {
|
||||||
|
// return x * 2;
|
||||||
|
// }
|
||||||
|
// constexpr int f(int y) {
|
||||||
|
// if(int x = g(y); x == 2) {
|
||||||
|
// return 14 / x;
|
||||||
|
// } else {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// constexpr int x = f(1);
|
||||||
|
public void testInitStatementInIfStatementCondition1() throws Exception {
|
||||||
|
assertEvaluationEquals(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constexpr int g(int x) {
|
||||||
|
// return x * 2;
|
||||||
|
// }
|
||||||
|
// constexpr int f(int y) {
|
||||||
|
// if(int x = g(y); x != 2) {
|
||||||
|
// return 14 / x;
|
||||||
|
// } else {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// constexpr int x = f(1);
|
||||||
|
public void testInitStatementInIfStatementCondition2() throws Exception {
|
||||||
|
assertEvaluationEquals(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constexpr int g(int x) {
|
||||||
|
// return x * 2;
|
||||||
|
// }
|
||||||
|
// constexpr int f() {
|
||||||
|
// if constexpr (constexpr int x = g(1); x != 2) {
|
||||||
|
// return 14 / x;
|
||||||
|
// } else {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// constexpr int x = f();
|
||||||
|
public void testInitStatementInIfStatementCondition3() throws Exception {
|
||||||
|
assertEvaluationEquals(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// constexpr int g(int x) {
|
||||||
|
// return x * 2;
|
||||||
|
// }
|
||||||
|
// constexpr int f(int y) {
|
||||||
|
// int x = g(y);
|
||||||
|
// if(; x == 2) {
|
||||||
|
// return 14 / x;
|
||||||
|
// } else {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// constexpr int x = f(1);
|
||||||
|
public void testEmptyInitStatementInIfStatementCondition1() throws Exception {
|
||||||
|
assertEvaluationEquals(7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,7 +146,7 @@ int f()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//!IfStatementTest
|
//!BasicNoBraceIfStatementTest
|
||||||
//%CPP
|
//%CPP
|
||||||
int g()
|
int g()
|
||||||
{
|
{
|
||||||
|
@ -210,7 +210,7 @@ int foo()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//!SwitchStatementTest
|
//!CSwitchStatementTest
|
||||||
//%C
|
//%C
|
||||||
void foo()
|
void foo()
|
||||||
{
|
{
|
||||||
|
@ -240,7 +240,7 @@ int foo(int a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//!GNUSwitchStatementTest
|
//!GNUCSwitchStatementTest
|
||||||
//%C
|
//%C
|
||||||
int foo(int a)
|
int foo(int a)
|
||||||
{
|
{
|
||||||
|
@ -323,8 +323,81 @@ int foo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//!ArrayDeclarationStatementTest
|
//!ArrayDeclarationStatementTest
|
||||||
//%CPP
|
//%CPP
|
||||||
string* newElements = new string[m_capacity];
|
string* newElements = new string[m_capacity];
|
||||||
|
|
||||||
|
//!Basic Constexpr If
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
constexpr bool b{false};
|
||||||
|
if constexpr (b){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Constexpr If with init-statement
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
if constexpr (constexpr bool b{false};b){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Constexpr If with init-statement and declaration
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
if constexpr (constexpr bool b{false};int k = 42){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!If with init-statement
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
if (bool b{false};b == true){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!If with init-statement and declaration
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
if (bool b{false};int k = 42){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!If with constexpr init-statement and declaration
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
if (constexpr bool b{false};int k = 42){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!If with empty init-statement and declaration
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
if (;int k = 42){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!If with empty init-statement and expression
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
int k{42};
|
||||||
|
if (;k == 42){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Constexpr If with empty init-statement and expression
|
||||||
|
//%CPP
|
||||||
|
void f()
|
||||||
|
{
|
||||||
|
constexpr int k{42};
|
||||||
|
if constexpr (;k == 42){
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,10 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +23,15 @@ import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTIfStatement extends IASTIfStatement {
|
public interface ICPPASTIfStatement extends IASTIfStatement {
|
||||||
|
/**
|
||||||
|
* {@code INIT_STATEMENT} represents the relationship between an
|
||||||
|
* {@code ICPPASTIfStatement} and its nested {@code IASTStatement}.
|
||||||
|
*
|
||||||
|
* @since 6.5
|
||||||
|
*/
|
||||||
|
public static final ASTNodeProperty INIT_STATEMENT = new ASTNodeProperty(
|
||||||
|
"ICPPASTIfStatement.INIT_STATEMENT - IASTStatement init-statement for ICPPASTIfStatement"); //$NON-NLS-1$
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the condition declaration. The condition declaration and the condition expression are
|
* Returns the condition declaration. The condition declaration and the condition expression are
|
||||||
* mutually exclusive.
|
* mutually exclusive.
|
||||||
|
@ -34,7 +45,43 @@ public interface ICPPASTIfStatement extends IASTIfStatement {
|
||||||
* Sets the condition declaration.
|
* Sets the condition declaration.
|
||||||
*/
|
*/
|
||||||
public void setConditionDeclaration(IASTDeclaration d);
|
public void setConditionDeclaration(IASTDeclaration d);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the isConstxpr member variable.
|
||||||
|
*
|
||||||
|
* @since 6.5
|
||||||
|
*/
|
||||||
|
public void setIsConstexpr(boolean isConstexpr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether this if statement is a constexpr if statement.
|
||||||
|
*
|
||||||
|
* @return true iff this if statement is a constexpr if.
|
||||||
|
*
|
||||||
|
* @since 6.5
|
||||||
|
*/
|
||||||
|
public boolean isConstexpr();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the init-statement for an if.
|
||||||
|
*
|
||||||
|
* @return the init-statement, or <code>null</code> if the 'if' statement doesn't
|
||||||
|
* have one.
|
||||||
|
*
|
||||||
|
* @since 6.5
|
||||||
|
*/
|
||||||
|
public IASTStatement getInitializerStatement();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the optional init-statement of an if.
|
||||||
|
*
|
||||||
|
* @param statement this statement should either be a <code>IASTSimpleDeclaration</code> or a
|
||||||
|
* <code>IASTExpressionStatement</code>.
|
||||||
|
*
|
||||||
|
* @since 6.5
|
||||||
|
*/
|
||||||
|
public void setInitializerStatement(IASTStatement statement);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the implicit <code>IScope</code> represented by this if statement
|
* Returns the implicit <code>IScope</code> represented by this if statement
|
||||||
*
|
*
|
||||||
|
|
|
@ -2379,13 +2379,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
protected abstract IASTAmbiguousExpression createAmbiguousBinaryVsCastExpression(IASTBinaryExpression binary, IASTCastExpression castExpr);
|
protected abstract IASTAmbiguousExpression createAmbiguousBinaryVsCastExpression(IASTBinaryExpression binary, IASTCastExpression castExpr);
|
||||||
protected abstract IASTAmbiguousExpression createAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall);
|
protected abstract IASTAmbiguousExpression createAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall);
|
||||||
|
|
||||||
protected IASTStatement forInitStatement() throws BacktrackException, EndOfFileException {
|
protected IASTStatement initStatement() throws BacktrackException, EndOfFileException {
|
||||||
if (LT(1) == IToken.tSEMI)
|
if (LT(1) == IToken.tSEMI)
|
||||||
return parseNullStatement();
|
return parseNullStatement();
|
||||||
try {
|
try {
|
||||||
return parseDeclarationOrExpressionStatement();
|
return parseDeclarationOrExpressionStatement();
|
||||||
} catch (BacktrackException e) {
|
} catch (BacktrackException e) {
|
||||||
// Missing semicolon within for loop does not make a complete for-statement
|
// A init statement always terminates with a semicolon
|
||||||
IASTNode before = e.getNodeBeforeProblem();
|
IASTNode before = e.getNodeBeforeProblem();
|
||||||
if (before != null) {
|
if (before != null) {
|
||||||
e.initialize(e.getProblem());
|
e.initialize(e.getProblem());
|
||||||
|
|
|
@ -2144,7 +2144,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
int startOffset;
|
int startOffset;
|
||||||
startOffset = consume().getOffset();
|
startOffset = consume().getOffset();
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
IASTStatement init = forInitStatement();
|
IASTStatement init = initStatement();
|
||||||
IASTExpression for_condition = null;
|
IASTExpression for_condition = null;
|
||||||
switch (LT(1)) {
|
switch (LT(1)) {
|
||||||
case IToken.tSEMI:
|
case IToken.tSEMI:
|
||||||
|
|
|
@ -29,6 +29,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSimpleDeclarat
|
||||||
* If statement in C++
|
* If statement in C++
|
||||||
*/
|
*/
|
||||||
public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIfStatement, ICPPExecutionOwner {
|
public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIfStatement, ICPPExecutionOwner {
|
||||||
|
private boolean isConstexpr;
|
||||||
|
private IASTStatement initStatement;
|
||||||
private IASTExpression condition;
|
private IASTExpression condition;
|
||||||
private IASTStatement thenClause;
|
private IASTStatement thenClause;
|
||||||
private IASTStatement elseClause;
|
private IASTStatement elseClause;
|
||||||
|
@ -44,7 +46,7 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
|
||||||
setElseClause(elseClause);
|
setElseClause(elseClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CPPASTIfStatement(IASTExpression condition, IASTStatement thenClause, IASTStatement elseClause) {
|
public CPPASTIfStatement(IASTExpression condition, IASTStatement thenClause, IASTStatement elseClause) {
|
||||||
setConditionExpression(condition);
|
setConditionExpression(condition);
|
||||||
setThenClause(thenClause);
|
setThenClause(thenClause);
|
||||||
setElseClause(elseClause);
|
setElseClause(elseClause);
|
||||||
|
@ -58,6 +60,8 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
|
||||||
@Override
|
@Override
|
||||||
public CPPASTIfStatement copy(CopyStyle style) {
|
public CPPASTIfStatement copy(CopyStyle style) {
|
||||||
CPPASTIfStatement copy = new CPPASTIfStatement();
|
CPPASTIfStatement copy = new CPPASTIfStatement();
|
||||||
|
copy.setIsConstexpr(isConstexpr);
|
||||||
|
copy.setInitializerStatement(initStatement == null ? null : initStatement.copy(style));
|
||||||
copy.setConditionDeclaration(condDecl == null ? null : condDecl.copy(style));
|
copy.setConditionDeclaration(condDecl == null ? null : condDecl.copy(style));
|
||||||
copy.setConditionExpression(condition == null ? null : condition.copy(style));
|
copy.setConditionExpression(condition == null ? null : condition.copy(style));
|
||||||
copy.setThenClause(thenClause == null ? null : thenClause.copy(style));
|
copy.setThenClause(thenClause == null ? null : thenClause.copy(style));
|
||||||
|
@ -137,7 +141,10 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
|
||||||
|
|
||||||
if (!((CPPASTIfStatement) stmt).acceptByAttributeSpecifiers(action)) return false;
|
if (!((CPPASTIfStatement) stmt).acceptByAttributeSpecifiers(action)) return false;
|
||||||
|
|
||||||
IASTNode child = stmt.getConditionExpression();
|
IASTNode child = stmt.getInitializerStatement();
|
||||||
|
if (child != null && !child.accept(action))
|
||||||
|
return false;
|
||||||
|
child = stmt.getConditionExpression();
|
||||||
if (child != null && !child.accept(action))
|
if (child != null && !child.accept(action))
|
||||||
return false;
|
return false;
|
||||||
child= stmt.getConditionDeclaration();
|
child= stmt.getConditionDeclaration();
|
||||||
|
@ -175,17 +182,28 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void replace(IASTNode child, IASTNode other) {
|
public void replace(IASTNode child, IASTNode other) {
|
||||||
|
if (initStatement == child) {
|
||||||
|
other.setParent(child.getParent());
|
||||||
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
|
initStatement = (IASTStatement) other;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (thenClause == child) {
|
if (thenClause == child) {
|
||||||
other.setParent(child.getParent());
|
other.setParent(child.getParent());
|
||||||
other.setPropertyInParent(child.getPropertyInParent());
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
thenClause = (IASTStatement) other;
|
thenClause = (IASTStatement) other;
|
||||||
return;
|
return;
|
||||||
} else if (elseClause == child) {
|
}
|
||||||
|
|
||||||
|
if (elseClause == child) {
|
||||||
other.setParent(child.getParent());
|
other.setParent(child.getParent());
|
||||||
other.setPropertyInParent(child.getPropertyInParent());
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
elseClause = (IASTStatement) other;
|
elseClause = (IASTStatement) other;
|
||||||
return;
|
return;
|
||||||
} else if (condition == child || condDecl == child) {
|
}
|
||||||
|
|
||||||
|
if (condition == child || condDecl == child) {
|
||||||
if (other instanceof IASTExpression) {
|
if (other instanceof IASTExpression) {
|
||||||
setConditionExpression((IASTExpression) other);
|
setConditionExpression((IASTExpression) other);
|
||||||
} else if (other instanceof IASTDeclaration) {
|
} else if (other instanceof IASTDeclaration) {
|
||||||
|
@ -193,6 +211,7 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.replace(child, other);
|
super.replace(child, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,6 +231,33 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConstexpr() {
|
||||||
|
return isConstexpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIsConstexpr(boolean isConstexpr) {
|
||||||
|
assertNotFrozen();
|
||||||
|
this.isConstexpr = isConstexpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IASTStatement getInitializerStatement() {
|
||||||
|
return initStatement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInitializerStatement(IASTStatement statement) {
|
||||||
|
assertNotFrozen();
|
||||||
|
this.initStatement = statement;
|
||||||
|
if (statement != null) {
|
||||||
|
statement.setParent(this);
|
||||||
|
statement.setPropertyInParent(INIT_STATEMENT);
|
||||||
|
statement = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IScope getScope() {
|
public IScope getScope() {
|
||||||
if (scope == null)
|
if (scope == null)
|
||||||
|
@ -221,12 +267,13 @@ public class CPPASTIfStatement extends CPPASTAttributeOwner implements ICPPASTIf
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPExecution getExecution() {
|
public ICPPExecution getExecution() {
|
||||||
|
ICPPExecution initStmtExec = EvalUtil.getExecutionFromStatement(getInitializerStatement());
|
||||||
ICPPASTExpression conditionExpr = (ICPPASTExpression) getConditionExpression();
|
ICPPASTExpression conditionExpr = (ICPPASTExpression) getConditionExpression();
|
||||||
ICPPExecutionOwner conditionDecl = (ICPPExecutionOwner) getConditionDeclaration();
|
ICPPExecutionOwner conditionDecl = (ICPPExecutionOwner) getConditionDeclaration();
|
||||||
ICPPEvaluation conditionExprEval = conditionExpr != null ? conditionExpr.getEvaluation() : null;
|
ICPPEvaluation conditionExprEval = conditionExpr != null ? conditionExpr.getEvaluation() : null;
|
||||||
ExecSimpleDeclaration conditionDeclExec = conditionDecl != null ? (ExecSimpleDeclaration) conditionDecl.getExecution() : null;
|
ExecSimpleDeclaration conditionDeclExec = conditionDecl != null ? (ExecSimpleDeclaration) conditionDecl.getExecution() : null;
|
||||||
ICPPExecution thenClauseExec = EvalUtil.getExecutionFromStatement(getThenClause());
|
ICPPExecution thenClauseExec = EvalUtil.getExecutionFromStatement(getThenClause());
|
||||||
ICPPExecution elseClauseExec = getElseClause() != null ? EvalUtil.getExecutionFromStatement(getElseClause()) : null;
|
ICPPExecution elseClauseExec = EvalUtil.getExecutionFromStatement(getElseClause());
|
||||||
return new ExecIf(conditionExprEval, conditionDeclExec, thenClauseExec, elseClauseExec);
|
return new ExecIf(isConstexpr, initStmtExec, conditionExprEval, conditionDeclExec, thenClauseExec, elseClauseExec);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5270,26 +5270,38 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
int start = LA(1).getOffset();
|
int start = LA(1).getOffset();
|
||||||
if_loop: while (true) {
|
if_loop: while (true) {
|
||||||
int so = consume(IToken.t_if).getOffset();
|
int so = consume(IToken.t_if).getOffset();
|
||||||
|
ICPPASTIfStatement new_if_statement = getNodeFactory().newIfStatement();
|
||||||
|
// constexpr if
|
||||||
|
if (LT(1) == IToken.t_constexpr) {
|
||||||
|
consume();
|
||||||
|
new_if_statement.setIsConstexpr(true);
|
||||||
|
}
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
|
// init-statement
|
||||||
|
IToken mark= mark();
|
||||||
|
try {
|
||||||
|
IASTStatement statement = initStatement();
|
||||||
|
new_if_statement.setInitializerStatement(statement);
|
||||||
|
} catch (BacktrackException e) {
|
||||||
|
backup(mark);
|
||||||
|
}
|
||||||
// condition
|
// condition
|
||||||
IASTNode condition= cppStyleCondition(IToken.tRPAREN);
|
IASTNode condition= cppStyleCondition(IToken.tRPAREN);
|
||||||
if (LT(1) == IToken.tEOC) {
|
if (LT(1) == IToken.tEOC) {
|
||||||
// Completing in the condition
|
// Completing in the condition
|
||||||
ICPPASTIfStatement new_if = getNodeFactory().newIfStatement();
|
|
||||||
if (condition instanceof IASTExpression)
|
if (condition instanceof IASTExpression)
|
||||||
new_if.setConditionExpression((IASTExpression) condition);
|
new_if_statement.setConditionExpression((IASTExpression) condition);
|
||||||
else if (condition instanceof IASTDeclaration)
|
else if (condition instanceof IASTDeclaration)
|
||||||
new_if.setConditionDeclaration((IASTDeclaration) condition);
|
new_if_statement.setConditionDeclaration((IASTDeclaration) condition);
|
||||||
|
|
||||||
if (if_statement != null) {
|
if (if_statement != null) {
|
||||||
if_statement.setElseClause(new_if);
|
if_statement.setElseClause(new_if_statement);
|
||||||
}
|
}
|
||||||
return result != null ? result : new_if;
|
return result != null ? result : new_if_statement;
|
||||||
}
|
}
|
||||||
consume(IToken.tRPAREN);
|
consume(IToken.tRPAREN);
|
||||||
|
|
||||||
IASTStatement thenClause = statement();
|
IASTStatement thenClause = statement();
|
||||||
ICPPASTIfStatement new_if_statement = getNodeFactory().newIfStatement();
|
|
||||||
((ASTNode) new_if_statement).setOffset(so);
|
((ASTNode) new_if_statement).setOffset(so);
|
||||||
if (condition != null && (condition instanceof IASTExpression || condition instanceof IASTDeclaration))
|
if (condition != null && (condition instanceof IASTExpression || condition instanceof IASTDeclaration))
|
||||||
// shouldn't be possible but failure in condition() makes it so
|
// shouldn't be possible but failure in condition() makes it so
|
||||||
|
@ -5447,7 +5459,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTForStatement startTraditionalForLoop() throws BacktrackException, EndOfFileException {
|
private IASTForStatement startTraditionalForLoop() throws BacktrackException, EndOfFileException {
|
||||||
final IASTStatement initStmt = forInitStatement();
|
final IASTStatement initStmt = initStatement();
|
||||||
IASTNode condition= null;
|
IASTNode condition= null;
|
||||||
IASTExpression iterExpr= null;
|
IASTExpression iterExpr= null;
|
||||||
|
|
||||||
|
|
|
@ -1624,7 +1624,14 @@ public class CPPSemantics {
|
||||||
} else if (parent instanceof ICPPASTSwitchStatement) {
|
} else if (parent instanceof ICPPASTSwitchStatement) {
|
||||||
nodes = new IASTNode[] { ((ICPPASTSwitchStatement) parent).getControllerDeclaration() };
|
nodes = new IASTNode[] { ((ICPPASTSwitchStatement) parent).getControllerDeclaration() };
|
||||||
} else if (parent instanceof ICPPASTIfStatement) {
|
} else if (parent instanceof ICPPASTIfStatement) {
|
||||||
nodes = new IASTNode[] { ((ICPPASTIfStatement) parent).getConditionDeclaration() };
|
ICPPASTIfStatement ifStatement = (ICPPASTIfStatement) parent;
|
||||||
|
final IASTStatement initStatement = ifStatement.getInitializerStatement();
|
||||||
|
final IASTDeclaration conditionDeclaration = ifStatement.getConditionDeclaration();
|
||||||
|
if (initStatement != null) {
|
||||||
|
nodes = new IASTNode[] {initStatement, conditionDeclaration};
|
||||||
|
} else {
|
||||||
|
nodes = new IASTNode[] {conditionDeclaration};
|
||||||
|
}
|
||||||
} else if (parent instanceof ICPPASTWhileStatement) {
|
} else if (parent instanceof ICPPASTWhileStatement) {
|
||||||
nodes = new IASTNode[] { ((ICPPASTWhileStatement) parent).getConditionDeclaration() };
|
nodes = new IASTNode[] { ((ICPPASTWhileStatement) parent).getConditionDeclaration() };
|
||||||
} else if (parent instanceof ICPPASTRangeBasedForStatement) {
|
} else if (parent instanceof ICPPASTRangeBasedForStatement) {
|
||||||
|
|
|
@ -16,28 +16,41 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
public class ExecIf implements ICPPExecution {
|
public class ExecIf implements ICPPExecution {
|
||||||
|
private final boolean isConstexpr;
|
||||||
|
private final ICPPExecution initStmtExec;
|
||||||
private final ICPPEvaluation conditionExprEval;
|
private final ICPPEvaluation conditionExprEval;
|
||||||
private final ExecSimpleDeclaration conditionDeclExec;
|
private final ExecSimpleDeclaration conditionDeclExec;
|
||||||
private final ICPPExecution thenClauseExec;
|
private final ICPPExecution thenClauseExec;
|
||||||
private final ICPPExecution elseClauseExec;
|
private final ICPPExecution elseClauseExec;
|
||||||
|
|
||||||
public ExecIf(ICPPEvaluation conditionExprEval, ExecSimpleDeclaration conditionDeclExec, ICPPExecution thenClauseExec, ICPPExecution elseClauseExec) {
|
public ExecIf(boolean isConstexpr, ICPPExecution initStmtExec, ICPPEvaluation conditionExprEval, ExecSimpleDeclaration conditionDeclExec, ICPPExecution thenClauseExec, ICPPExecution elseClauseExec) {
|
||||||
|
this.isConstexpr = isConstexpr;
|
||||||
|
this.initStmtExec = initStmtExec;
|
||||||
this.conditionExprEval = conditionExprEval;
|
this.conditionExprEval = conditionExprEval;
|
||||||
this.conditionDeclExec = conditionDeclExec;
|
this.conditionDeclExec = conditionDeclExec;
|
||||||
this.thenClauseExec = thenClauseExec;
|
this.thenClauseExec = thenClauseExec;
|
||||||
this.elseClauseExec = elseClauseExec;
|
this.elseClauseExec = elseClauseExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void executeInitStatement(ActivationRecord record, ConstexprEvaluationContext context) {
|
||||||
|
if (initStmtExec != null) {
|
||||||
|
EvalUtil.executeStatement(initStmtExec, record, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean conditionSatisfied(ActivationRecord record, ConstexprEvaluationContext context) {
|
||||||
|
if (conditionExprEval != null) {
|
||||||
|
return EvalUtil.conditionExprSatisfied(conditionExprEval, record, context);
|
||||||
|
} else if (conditionDeclExec != null) {
|
||||||
|
return EvalUtil.conditionDeclSatisfied(conditionDeclExec, record, context);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPExecution executeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) {
|
public ICPPExecution executeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) {
|
||||||
boolean conditionSatisfied = false;
|
executeInitStatement(record, context);
|
||||||
if (conditionExprEval != null) {
|
if (conditionSatisfied(record, context)) {
|
||||||
conditionSatisfied = EvalUtil.conditionExprSatisfied(conditionExprEval, record, context);
|
|
||||||
} else if (conditionDeclExec != null) {
|
|
||||||
conditionSatisfied = EvalUtil.conditionDeclSatisfied(conditionDeclExec, record, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conditionSatisfied) {
|
|
||||||
return EvalUtil.executeStatement(thenClauseExec, record, context);
|
return EvalUtil.executeStatement(thenClauseExec, record, context);
|
||||||
} else if (elseClauseExec != null) {
|
} else if (elseClauseExec != null) {
|
||||||
return EvalUtil.executeStatement(elseClauseExec, record, context);
|
return EvalUtil.executeStatement(elseClauseExec, record, context);
|
||||||
|
@ -47,19 +60,44 @@ public class ExecIf implements ICPPExecution {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPExecution instantiate(InstantiationContext context, int maxDepth) {
|
public ICPPExecution instantiate(InstantiationContext context, int maxDepth) {
|
||||||
|
ICPPExecution newInitStmtExec = initStmtExec != null ? initStmtExec.instantiate(context, maxDepth) : null;
|
||||||
ICPPEvaluation newConditionExprEval = conditionExprEval != null ? conditionExprEval.instantiate(context, maxDepth) : null;
|
ICPPEvaluation newConditionExprEval = conditionExprEval != null ? conditionExprEval.instantiate(context, maxDepth) : null;
|
||||||
ExecSimpleDeclaration newConditionDeclExec = conditionDeclExec != null ? (ExecSimpleDeclaration) conditionDeclExec.instantiate(context, maxDepth) : null;
|
ExecSimpleDeclaration newConditionDeclExec = conditionDeclExec != null ? (ExecSimpleDeclaration) conditionDeclExec.instantiate(context, maxDepth) : null;
|
||||||
ICPPExecution newThenClauseExec = thenClauseExec.instantiate(context, maxDepth);
|
|
||||||
ICPPExecution newElseClauseExec = elseClauseExec != null ? elseClauseExec.instantiate(context, maxDepth) : null;
|
ICPPExecution newThenClauseExec = null;
|
||||||
if (newConditionExprEval == conditionExprEval && newConditionDeclExec == conditionDeclExec && newThenClauseExec == thenClauseExec && newElseClauseExec == elseClauseExec) {
|
ICPPExecution newElseClauseExec = null;
|
||||||
|
|
||||||
|
if (isConstexpr && newConditionExprEval != null && newConditionExprEval.getValue().numberValue() != null) {
|
||||||
|
if (newConditionExprEval.getValue().numberValue().intValue() != 0) {
|
||||||
|
/*
|
||||||
|
* We can't just "return newThenClauseExec" here, because the condition
|
||||||
|
* might have side effects so it needs to be preserved in the instantiated
|
||||||
|
* execution even if one of its branch has become null
|
||||||
|
*/
|
||||||
|
newThenClauseExec = thenClauseExec.instantiate(context, maxDepth);
|
||||||
|
} else {
|
||||||
|
newElseClauseExec = elseClauseExec != null ? elseClauseExec.instantiate(context, maxDepth) : null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newThenClauseExec = thenClauseExec.instantiate(context, maxDepth);
|
||||||
|
newElseClauseExec = elseClauseExec != null ? elseClauseExec.instantiate(context, maxDepth) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newInitStmtExec == initStmtExec && newConditionExprEval == conditionExprEval && newConditionDeclExec == conditionDeclExec
|
||||||
|
&& newThenClauseExec == thenClauseExec && newElseClauseExec == elseClauseExec) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return new ExecIf(newConditionExprEval, newConditionDeclExec, newThenClauseExec, newElseClauseExec);
|
return new ExecIf(isConstexpr, newInitStmtExec, newConditionExprEval, newConditionDeclExec, newThenClauseExec, newElseClauseExec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
|
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
|
||||||
buffer.putShort(ITypeMarshalBuffer.EXEC_IF);
|
short firstBytes = ITypeMarshalBuffer.EXEC_IF;
|
||||||
|
if (isConstexpr) {
|
||||||
|
firstBytes |= ITypeMarshalBuffer.FLAG1;
|
||||||
|
}
|
||||||
|
buffer.putShort(firstBytes);
|
||||||
|
buffer.marshalExecution(initStmtExec, includeValue);
|
||||||
buffer.marshalEvaluation(conditionExprEval, includeValue);
|
buffer.marshalEvaluation(conditionExprEval, includeValue);
|
||||||
buffer.marshalExecution(conditionDeclExec, includeValue);
|
buffer.marshalExecution(conditionDeclExec, includeValue);
|
||||||
buffer.marshalExecution(thenClauseExec, includeValue);
|
buffer.marshalExecution(thenClauseExec, includeValue);
|
||||||
|
@ -67,10 +105,12 @@ public class ExecIf implements ICPPExecution {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ICPPExecution unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
|
public static ICPPExecution unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
|
||||||
|
boolean isConstexpr = (firstBytes & ITypeMarshalBuffer.FLAG1) != 0;
|
||||||
|
ICPPExecution initStmtExec = buffer.unmarshalExecution();
|
||||||
ICPPEvaluation conditionExprEval = buffer.unmarshalEvaluation();
|
ICPPEvaluation conditionExprEval = buffer.unmarshalEvaluation();
|
||||||
ExecSimpleDeclaration conditionDeclExec = (ExecSimpleDeclaration) buffer.unmarshalExecution();
|
ExecSimpleDeclaration conditionDeclExec = (ExecSimpleDeclaration) buffer.unmarshalExecution();
|
||||||
ICPPExecution thenClauseExec = buffer.unmarshalExecution();
|
ICPPExecution thenClauseExec = buffer.unmarshalExecution();
|
||||||
ICPPExecution elseClauseExec = buffer.unmarshalExecution();
|
ICPPExecution elseClauseExec = buffer.unmarshalExecution();
|
||||||
return new ExecIf(conditionExprEval, conditionDeclExec, thenClauseExec, elseClauseExec);
|
return new ExecIf(isConstexpr, initStmtExec, conditionExprEval, conditionDeclExec, thenClauseExec, elseClauseExec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,8 @@ public class StatementWriter extends NodeWriter {
|
||||||
private static final String CONTINUE = "continue"; //$NON-NLS-1$
|
private static final String CONTINUE = "continue"; //$NON-NLS-1$
|
||||||
private static final String BREAK = "break"; //$NON-NLS-1$
|
private static final String BREAK = "break"; //$NON-NLS-1$
|
||||||
private static final String ELSE = "else"; //$NON-NLS-1$
|
private static final String ELSE = "else"; //$NON-NLS-1$
|
||||||
private static final String IF = "if ("; //$NON-NLS-1$
|
private static final String IF = "if "; //$NON-NLS-1$
|
||||||
|
private static final String CONSTEXPR = "constexpr "; //$NON-NLS-1$
|
||||||
private static final String FOR = "for ("; //$NON-NLS-1$
|
private static final String FOR = "for ("; //$NON-NLS-1$
|
||||||
private static final String DO_WHILE = " while ("; //$NON-NLS-1$
|
private static final String DO_WHILE = " while ("; //$NON-NLS-1$
|
||||||
private static final String DO = "do"; //$NON-NLS-1$
|
private static final String DO = "do"; //$NON-NLS-1$
|
||||||
|
@ -216,10 +217,18 @@ public class StatementWriter extends NodeWriter {
|
||||||
|
|
||||||
private void writeIfStatement(IASTIfStatement ifStatement) {
|
private void writeIfStatement(IASTIfStatement ifStatement) {
|
||||||
scribe.print(IF);
|
scribe.print(IF);
|
||||||
|
final boolean isCPPIfStatement = ifStatement instanceof ICPPASTIfStatement;
|
||||||
|
if (isCPPIfStatement && ((ICPPASTIfStatement) ifStatement).isConstexpr()) {
|
||||||
|
scribe.print(CONSTEXPR);
|
||||||
|
}
|
||||||
|
scribe.print('(');
|
||||||
scribe.noNewLines();
|
scribe.noNewLines();
|
||||||
if (ifStatement instanceof ICPPASTIfStatement) {
|
if (isCPPIfStatement) {
|
||||||
ICPPASTIfStatement cppIfStatment = (ICPPASTIfStatement) ifStatement;
|
ICPPASTIfStatement cppIfStatment = (ICPPASTIfStatement) ifStatement;
|
||||||
|
IASTStatement initStatement = cppIfStatment.getInitializerStatement();
|
||||||
|
if (initStatement != null) {
|
||||||
|
writeStatement(initStatement, false);
|
||||||
|
}
|
||||||
if (cppIfStatment.getConditionDeclaration() == null) {
|
if (cppIfStatment.getConditionDeclaration() == null) {
|
||||||
cppIfStatment.getConditionExpression().accept(visitor);
|
cppIfStatment.getConditionExpression().accept(visitor);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -289,10 +289,13 @@ public class PDOM extends PlatformObject implements IPDOM {
|
||||||
* 209.0 - Alias templates and their instances take up more space than required, bug 516385.
|
* 209.0 - Alias templates and their instances take up more space than required, bug 516385.
|
||||||
* 210.0 - Return type deduction, bug 408470.
|
* 210.0 - Return type deduction, bug 408470.
|
||||||
* 211.0 - Change representation of alias template instances, bug 516338.
|
* 211.0 - Change representation of alias template instances, bug 516338.
|
||||||
|
*
|
||||||
|
* CDT 9.5 development (version not supported on the 9.4.x branch)
|
||||||
|
* 212.0 - C++ constexpr if and if init-statement evaluation
|
||||||
*/
|
*/
|
||||||
private static final int MIN_SUPPORTED_VERSION= version(211, 0);
|
private static final int MIN_SUPPORTED_VERSION= version(212, 0);
|
||||||
private static final int MAX_SUPPORTED_VERSION= version(211, Short.MAX_VALUE);
|
private static final int MAX_SUPPORTED_VERSION= version(212, Short.MAX_VALUE);
|
||||||
private static final int DEFAULT_VERSION = version(211, 0);
|
private static final int DEFAULT_VERSION = version(212, 0);
|
||||||
|
|
||||||
private static int version(int major, int minor) {
|
private static int version(int major, int minor) {
|
||||||
return (major << 16) + minor;
|
return (major << 16) + minor;
|
||||||
|
|
|
@ -268,7 +268,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
private class TrailingSemicolonFormatter extends TrailingTokenFormatter {
|
private class TrailingSemicolonFormatter extends TrailingTokenFormatter {
|
||||||
TrailingSemicolonFormatter(IASTNode node) {
|
TrailingSemicolonFormatter(IASTNode node) {
|
||||||
super(Token.tSEMI, getLastNodeCharacterPosition(node),
|
super(Token.tSEMI, getLastNodeCharacterPosition(node),
|
||||||
fInsideFor ? preferences.insert_space_before_semicolon_in_for :
|
fHasClauseInitStatement ? preferences.insert_space_before_semicolon_in_for :
|
||||||
preferences.insert_space_before_semicolon,
|
preferences.insert_space_before_semicolon,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
final DefaultCodeFormatterOptions preferences;
|
final DefaultCodeFormatterOptions preferences;
|
||||||
private final Scribe scribe;
|
private final Scribe scribe;
|
||||||
|
|
||||||
private boolean fInsideFor;
|
private boolean fHasClauseInitStatement;
|
||||||
private boolean fInsideMacroArguments;
|
private boolean fInsideMacroArguments;
|
||||||
private boolean fExpectSemicolonAfterDeclaration= true;
|
private boolean fExpectSemicolonAfterDeclaration= true;
|
||||||
|
|
||||||
|
@ -3134,7 +3134,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private int visit(IASTNullStatement node) {
|
private int visit(IASTNullStatement node) {
|
||||||
if (!fInsideFor && nodeOffset(node) == getCurrentPosition()) {
|
if (!fHasClauseInitStatement && nodeOffset(node) == getCurrentPosition()) {
|
||||||
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon);
|
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon);
|
||||||
scribe.printTrailingComment();
|
scribe.printTrailingComment();
|
||||||
}
|
}
|
||||||
|
@ -3143,7 +3143,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
private int visit(IASTDeclarationStatement node) {
|
private int visit(IASTDeclarationStatement node) {
|
||||||
node.getDeclaration().accept(this);
|
node.getDeclaration().accept(this);
|
||||||
if (!fInsideFor) {
|
if (!fHasClauseInitStatement) {
|
||||||
scribe.startNewLine();
|
scribe.startNewLine();
|
||||||
}
|
}
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
|
@ -3151,7 +3151,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
private int visit(IASTExpressionStatement node) {
|
private int visit(IASTExpressionStatement node) {
|
||||||
Runnable semicolonFormatter = null;
|
Runnable semicolonFormatter = null;
|
||||||
if (!fInsideFor) {
|
if (!fHasClauseInitStatement) {
|
||||||
semicolonFormatter = new TrailingSemicolonFormatter(node);
|
semicolonFormatter = new TrailingSemicolonFormatter(node);
|
||||||
scribe.setTailFormatter(semicolonFormatter);
|
scribe.setTailFormatter(semicolonFormatter);
|
||||||
}
|
}
|
||||||
|
@ -3160,7 +3160,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
semicolonFormatter.run();
|
semicolonFormatter.run();
|
||||||
scribe.setTailFormatter(null);
|
scribe.setTailFormatter(null);
|
||||||
}
|
}
|
||||||
if (!fInsideFor) {
|
if (!fHasClauseInitStatement) {
|
||||||
scribe.startNewLine();
|
scribe.startNewLine();
|
||||||
}
|
}
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
|
@ -3176,7 +3176,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
Runnable tailFormatter = null;
|
Runnable tailFormatter = null;
|
||||||
if (!doNodesHaveSameOffset(node, initializerStmt)) {
|
if (!doNodesHaveSameOffset(node, initializerStmt)) {
|
||||||
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for);
|
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for);
|
||||||
fInsideFor= true;
|
fHasClauseInitStatement = true;
|
||||||
if (preferences.insert_space_after_opening_paren_in_for) {
|
if (preferences.insert_space_after_opening_paren_in_for) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
|
@ -3240,7 +3240,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.setTailFormatter(null);
|
scribe.setTailFormatter(null);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
fInsideFor= false;
|
fHasClauseInitStatement= false;
|
||||||
}
|
}
|
||||||
ok = true;
|
ok = true;
|
||||||
} catch (AlignmentException e) {
|
} catch (AlignmentException e) {
|
||||||
|
@ -3271,7 +3271,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.printNextToken(Token.t_for);
|
scribe.printNextToken(Token.t_for);
|
||||||
final int line = scribe.line;
|
final int line = scribe.line;
|
||||||
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for);
|
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for);
|
||||||
fInsideFor= true;
|
fHasClauseInitStatement= true;
|
||||||
try {
|
try {
|
||||||
if (preferences.insert_space_after_opening_paren_in_for) {
|
if (preferences.insert_space_after_opening_paren_in_for) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
|
@ -3285,7 +3285,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
initializer.accept(this);
|
initializer.accept(this);
|
||||||
} finally {
|
} finally {
|
||||||
fInsideFor= false;
|
fHasClauseInitStatement= false;
|
||||||
}
|
}
|
||||||
if (peekNextToken() == Token.tRPAREN) {
|
if (peekNextToken() == Token.tRPAREN) {
|
||||||
scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for);
|
scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for);
|
||||||
|
@ -3295,24 +3295,46 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void beginIfClause() {
|
||||||
|
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_if);
|
||||||
|
if (preferences.insert_space_after_opening_paren_in_if) {
|
||||||
|
scribe.space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int visit(IASTIfStatement node) {
|
private int visit(IASTIfStatement node) {
|
||||||
if (!startsWithMacroExpansion(node)) {
|
if (!startsWithMacroExpansion(node)) {
|
||||||
scribe.printNextToken(Token.t_if);
|
scribe.printNextToken(Token.t_if);
|
||||||
}
|
}
|
||||||
final int line = scribe.line;
|
|
||||||
IASTNode condition = node.getConditionExpression();
|
IASTNode condition = node.getConditionExpression();
|
||||||
if (condition == null && node instanceof ICPPASTIfStatement) {
|
|
||||||
condition = ((ICPPASTIfStatement) node).getConditionDeclaration();
|
|
||||||
}
|
|
||||||
final IASTStatement thenStatement = node.getThenClause();
|
final IASTStatement thenStatement = node.getThenClause();
|
||||||
final IASTStatement elseStatement = node.getElseClause();
|
final IASTStatement elseStatement = node.getElseClause();
|
||||||
|
|
||||||
fExpectSemicolonAfterDeclaration= false;
|
fExpectSemicolonAfterDeclaration = false;
|
||||||
try {
|
try {
|
||||||
if (condition == null || !doNodesHaveSameOffset(node, condition)) {
|
if (node instanceof ICPPASTIfStatement) {
|
||||||
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_if);
|
ICPPASTIfStatement cppIfStatment = (ICPPASTIfStatement) node;
|
||||||
if (preferences.insert_space_after_opening_paren_in_if) {
|
if (cppIfStatment.isConstexpr()) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
|
scribe.printNextToken(Token.t_constexpr);
|
||||||
|
scribe.space();
|
||||||
|
}
|
||||||
|
IASTStatement initStatement = cppIfStatment.getInitializerStatement();
|
||||||
|
if (initStatement != null) {
|
||||||
|
beginIfClause();
|
||||||
|
fHasClauseInitStatement = true;
|
||||||
|
initStatement.accept(this);
|
||||||
|
if (preferences.insert_space_after_semicolon_in_for) {
|
||||||
|
scribe.space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (condition == null) {
|
||||||
|
condition = ((ICPPASTIfStatement) node).getConditionDeclaration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (condition == null || !doNodesHaveSameOffset(node, condition)) {
|
||||||
|
if (!fHasClauseInitStatement) {
|
||||||
|
beginIfClause();
|
||||||
}
|
}
|
||||||
Runnable tailFormatter = null;
|
Runnable tailFormatter = null;
|
||||||
if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) &&
|
if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) &&
|
||||||
|
@ -3334,7 +3356,8 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
condition.accept(this);
|
condition.accept(this);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
fExpectSemicolonAfterDeclaration= true;
|
fHasClauseInitStatement = false;
|
||||||
|
fExpectSemicolonAfterDeclaration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean thenStatementIsBlock = false;
|
boolean thenStatementIsBlock = false;
|
||||||
|
@ -3357,7 +3380,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.printTrailingComment();
|
scribe.printTrailingComment();
|
||||||
} else {
|
} else {
|
||||||
if (getCurrentPosition() <= nodeOffset(thenStatement)) {
|
if (getCurrentPosition() <= nodeOffset(thenStatement)) {
|
||||||
formatLeftCurlyBrace(line, preferences.brace_position_for_block);
|
formatLeftCurlyBrace(scribe.line, preferences.brace_position_for_block);
|
||||||
}
|
}
|
||||||
thenStatement.accept(this);
|
thenStatement.accept(this);
|
||||||
if (elseStatement != null && preferences.insert_new_line_before_else_in_if_statement) {
|
if (elseStatement != null && preferences.insert_new_line_before_else_in_if_statement) {
|
||||||
|
|
|
@ -888,6 +888,7 @@ public class SimpleScanner {
|
||||||
fgKeywords.put("compl", Integer.valueOf(Token.t_compl)); //$NON-NLS-1$
|
fgKeywords.put("compl", Integer.valueOf(Token.t_compl)); //$NON-NLS-1$
|
||||||
fgKeywords.put("const", Integer.valueOf(Token.t_const)); //$NON-NLS-1$
|
fgKeywords.put("const", Integer.valueOf(Token.t_const)); //$NON-NLS-1$
|
||||||
fgKeywords.put("const_cast", Integer.valueOf(Token.t_const_cast)); //$NON-NLS-1$
|
fgKeywords.put("const_cast", Integer.valueOf(Token.t_const_cast)); //$NON-NLS-1$
|
||||||
|
fgKeywords.put("constexpr", Integer.valueOf(Token.t_constexpr)); //$NON-NLS-1$
|
||||||
fgKeywords.put("continue", Integer.valueOf(Token.t_continue)); //$NON-NLS-1$
|
fgKeywords.put("continue", Integer.valueOf(Token.t_continue)); //$NON-NLS-1$
|
||||||
fgKeywords.put("default", Integer.valueOf(Token.t_default)); //$NON-NLS-1$
|
fgKeywords.put("default", Integer.valueOf(Token.t_default)); //$NON-NLS-1$
|
||||||
fgKeywords.put("delete", Integer.valueOf(Token.t_delete)); //$NON-NLS-1$
|
fgKeywords.put("delete", Integer.valueOf(Token.t_delete)); //$NON-NLS-1$
|
||||||
|
|
|
@ -505,4 +505,5 @@ public class Token {
|
||||||
static public final int t_byte = 214;
|
static public final int t_byte = 214;
|
||||||
static public final int t_transient = 215;
|
static public final int t_transient = 215;
|
||||||
static public final int t_native = 216;
|
static public final int t_native = 216;
|
||||||
|
static public final int t_constexpr = 5400;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3209,4 +3209,107 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
public void testSizeofParameterPackFormat_464498() throws Exception {
|
public void testSizeofParameterPackFormat_464498() throws Exception {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if constexpr (constexpr bool k = true) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if constexpr (constexpr bool k = true) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public void testConstexprIfFormat_1() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if
|
||||||
|
// constexpr (constexpr bool k = true) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if constexpr (constexpr bool k = true) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public void testConstexprIfFormat_2() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if
|
||||||
|
//
|
||||||
|
// constexpr
|
||||||
|
// (constexpr bool k = true) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if
|
||||||
|
//
|
||||||
|
// constexpr (constexpr bool k = true) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public void testConstexprIfFormat_3() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if constexpr (constexpr bool k = true; k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if constexpr (constexpr bool k = true; k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public void testIfInitStatementFormat_1() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if
|
||||||
|
// constexpr (constexpr bool k = true; k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if constexpr (constexpr bool k = true; k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public void testIfInitStatementFormat_2() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if
|
||||||
|
//
|
||||||
|
// constexpr
|
||||||
|
// (constexpr bool k = true; k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if
|
||||||
|
//
|
||||||
|
// constexpr (constexpr bool k = true; k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public void testIfInitStatementFormat_3() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if (constexpr bool k = true;k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void foo() {
|
||||||
|
// if (constexpr bool k = true; k) {
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
public void testIfInitStatementFormat_4() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue