diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index d8b931c4842..0402f2bcabd 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -12705,4 +12705,9 @@ public class AST2CPPTests extends AST2CPPTestBase { // does not throw an exception. var.getInitialValue(); } + + //static_assert(true); + public void testStaticAssertWithoutMessage_534808() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts index 9958fc479cb..206c80cece2 100644 --- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts +++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclarationTestSource.awts @@ -159,3 +159,8 @@ int main() } ; } + +//!static_asserts with and without message +//%CPP +static_assert(true, "Should always pass"); +static_assert(sizeof (int) == 4); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTStaticAssertDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTStaticAssertDeclaration.java index a7e44084b91..678572f992b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTStaticAssertDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTStaticAssertDeclaration.java @@ -33,7 +33,8 @@ public interface ICPPASTStaticAssertDeclaration extends IASTDeclaration { IASTExpression getCondition(); /** - * Returns the message of the assertion, or potentially null when using content assist. + * Returns the message of the assertion. Potentially null when message is omitted + * or using content assist. */ ICPPASTLiteralExpression getMessage(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java index 1abf3349655..659b040f4d9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java @@ -333,6 +333,11 @@ public interface ICPPNodeFactory extends INodeFactory { */ public ICPPASTStaticAssertDeclaration newStaticAssertion(IASTExpression condition, ICPPASTLiteralExpression message); + /** + * @since 6.5 + */ + public ICPPASTStaticAssertDeclaration newStaticAssertion(IASTExpression condition); + public ICPPASTSwitchStatement newSwitchStatement(); public ICPPASTSwitchStatement newSwitchStatement(IASTDeclaration controller, IASTStatement body); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTStaticAssertionDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTStaticAssertionDeclaration.java index 030c0030b34..1ffcc0d54e2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTStaticAssertionDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTStaticAssertionDeclaration.java @@ -23,6 +23,15 @@ public class CPPASTStaticAssertionDeclaration extends ASTNode implements ICPPAST private IASTExpression fCondition; private final ICPPASTLiteralExpression fMessage; + /** + * Constructor for C++17 static_assert with only a condition. + * + * @param condition The condition of the static assertion + */ + public CPPASTStaticAssertionDeclaration(IASTExpression condition) { + this(condition, null); + } + public CPPASTStaticAssertionDeclaration(IASTExpression condition, ICPPASTLiteralExpression message) { fCondition= condition; fMessage= message; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java index e2d0ab790c4..a95a3ebb0cb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java @@ -736,6 +736,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { return new CPPASTStaticAssertionDeclaration(condition, message); } + @Override + public ICPPASTStaticAssertDeclaration newStaticAssertion(IASTExpression condition) { + return newStaticAssertion(condition, null); + } + @Override public ICPPASTSwitchStatement newSwitchStatement() { return new CPPASTSwitchStatement(); 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 f4564c30b10..b0404798d45 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 @@ -2308,21 +2308,25 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * static_assert-declaration: - static_assert (constant-expression , string-literal ) ; + * static_assert (constant-expression); + * OR + * static_assert (constant-expression , string-literal); */ private ICPPASTStaticAssertDeclaration staticAssertDeclaration() throws EndOfFileException, BacktrackException { int offset= consume(IToken.t_static_assert).getOffset(); consume(IToken.tLPAREN); IASTExpression e= constantExpression(); int endOffset= calculateEndOffset(e); - ICPPASTLiteralExpression lit= null; - if (LT(1) != IToken.tEOC) { + ICPPASTLiteralExpression message = null; + if (LT(1) == IToken.tCOMMA) { consume(IToken.tCOMMA); - lit= stringLiteral(); - consume(IToken.tRPAREN); - endOffset= consume(IToken.tSEMI).getEndOffset(); + message = stringLiteral(); + } + ICPPASTStaticAssertDeclaration assertion = getNodeFactory().newStaticAssertion(e, message); + if (LT(1) != IToken.tEOC) { + consume(IToken.tRPAREN); + endOffset = consume(IToken.tSEMI).getEndOffset(); } - ICPPASTStaticAssertDeclaration assertion = getNodeFactory().newStaticAssertion(e, lit); return setRange(assertion, offset, endOffset); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java index bca52929c1c..7d7b6111869 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclarationWriter.java @@ -34,8 +34,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStaticAssertDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; @@ -56,10 +58,12 @@ import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; * @author Emanuel Graf IFS */ public class DeclarationWriter extends NodeWriter { - private static final String ASM_END = ")"; //$NON-NLS-1$ - private static final String ASM_START = "asm("; //$NON-NLS-1$ + private static final char OPEN_PAREN = '('; + private static final char CLOSE_PAREN = ')'; + private static final String ASM_START = "asm" + OPEN_PAREN; //$NON-NLS-1$ private static final String TEMPLATE_DECLARATION = "template<"; //$NON-NLS-1$ - private static final String TEMPLATE_SPECIALIZATION = "template <> "; //$NON-NLS-1$ + private static final String TEMPLATE_SPECIALIZATION = "template<> "; //$NON-NLS-1$ + private static final char COMMA = ','; private boolean printSemicolon; public DeclarationWriter(Scribe scribe, ASTWriterVisitor visitor, NodeCommentMap commentMap) { @@ -103,6 +107,8 @@ public class DeclarationWriter extends NodeWriter { writeVisibilityLabel((ICPPASTVisibilityLabel) declaration); } else if (declaration instanceof ICPPASTAliasDeclaration) { writeAliasDeclaration((ICPPASTAliasDeclaration) declaration); + } else if (declaration instanceof ICPPASTStaticAssertDeclaration) { + writeStaticAssertDeclaration((ICPPASTStaticAssertDeclaration)declaration); } writeTrailingComments(declaration, addNewLine); @@ -272,7 +278,7 @@ public class DeclarationWriter extends NodeWriter { private void writeASMDeclatation(IASTASMDeclaration asmDeclaration) { scribe.print(ASM_START); scribe.print(asmDeclaration.getAssembly()); - scribe.print(ASM_END); + scribe.print(CLOSE_PAREN); printSemicolon(); } @@ -378,4 +384,20 @@ public class DeclarationWriter extends NodeWriter { printSemicolon(); } + + private void writeStaticAssertDeclaration(ICPPASTStaticAssertDeclaration staticAssertDeclaration) { + scribe.print(Keywords.STATIC_ASSERT); + scribe.print(OPEN_PAREN); + staticAssertDeclaration.getCondition().accept(visitor); + + ICPPASTLiteralExpression message = staticAssertDeclaration.getMessage(); + if (message != null) { + scribe.print(COMMA); + scribe.printSpace(); + message.accept(visitor); + } + + scribe.print(CLOSE_PAREN); + scribe.printSemicolon(); + } }