1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Support for static assertions, bug 294730.

This commit is contained in:
Markus Schorn 2009-11-18 17:02:01 +00:00
parent 30fe21353c
commit 6ce54bb401
11 changed files with 212 additions and 11 deletions

View file

@ -7733,5 +7733,22 @@ public class AST2CPPTests extends AST2BaseTest {
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// const unsigned int EIGHT= 8;
// static_assert(sizeof(long) >= EIGHT, "no 64-bit support");
// namespace ns {
// static_assert(sizeof(long) >= 4, "no 32-bit support");
// }
// template <typename T> class basic_string {
// static_assert(T::value, "bla");
// };
// void do_something() {
// struct VMPage {
// };
// static_assert(sizeof(VMPage) == 1, "bla");
// }
public void testStaticAssertions_294730() throws Exception {
final String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
}

View file

@ -57,6 +57,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
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.ICPPASTQualifiedName;
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.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
@ -332,6 +333,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// TODO [cmodel] asm declaration?
} else if (declaration instanceof IASTProblemDeclaration) {
// TODO [cmodel] problem declaration?
} else if (declaration instanceof ICPPASTStaticAssertDeclaration) {
// ignore
} else {
assert false : "TODO: " + declaration.getClass().getName(); //$NON-NLS-1$
}

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
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.IASTExpression;
/**
* Models static assertions: <code> static_assert(false, "message");</code>
*
* @since 5.2
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPASTStaticAssertDeclaration extends IASTDeclaration {
public static final ASTNodeProperty CONDITION = new ASTNodeProperty(
"ICPPASTStaticAssertDeclaration.CONDITION [IASTExpression]"); //$NON-NLS-1$
public static final ASTNodeProperty MESSAGE = new ASTNodeProperty(
"ICPPASTStaticAssertDeclaration.MESSAGE [ICPPASTLiteralExpression]"); //$NON-NLS-1$
/**
* Returns the condition of the assertion
*/
IASTExpression getCondition();
/**
* Returns the message of the assertion, or potentially <code>null</code> when using content assist.
*/
ICPPASTLiteralExpression getMessage();
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -175,5 +176,11 @@ public interface ICPPNodeFactory extends INodeFactory {
public ICPPASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript);
public ICPPASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList);
/**
* Creates a new static assertion declaration with the given condition and message.
* @since 5.2
*/
public ICPPASTStaticAssertDeclaration newStaticAssertion(IASTExpression condition, ICPPASTLiteralExpression message);
}

View file

@ -30,11 +30,6 @@ public interface IToken {
public void setNext(IToken t);
public void setType(int i);
/**
* @noreference This method is not intended to be referenced by clients.
*/
@Deprecated
public boolean isOperator();
// Token types
int FIRST_RESERVED_PREPROCESSOR= -200;
@ -99,6 +94,7 @@ public interface IToken {
* @since 5.2
*/
int tGT_in_SHIFTR= 53;
/** @deprecated use {@link #tAND} */ @Deprecated int t_and = 54;
/** @deprecated use {@link #tAMPERASSIGN} */ @Deprecated int t_and_eq = 55;
int t_asm = 56;
@ -153,6 +149,7 @@ public interface IToken {
int t_short = 104;
int t_sizeof = 105;
int t_static = 106;
/** @since 5.2 */ int t_static_assert = 5010;
int t_static_cast = 107;
int t_signed = 108;
int t_struct = 109;
@ -210,4 +207,9 @@ public interface IToken {
int LAST_RESERVED_IExtensionToken = 299;
/**
* @noreference This method is not intended to be referenced by clients.
*/
@Deprecated
public boolean isOperator();
}

View file

@ -82,6 +82,8 @@ public class Keywords {
public static final String SIGNED = "signed"; //$NON-NLS-1$
public static final String SIZEOF = "sizeof"; //$NON-NLS-1$
public static final String STATIC = "static"; //$NON-NLS-1$
/** @since 5.2 */
public static final String STATIC_ASSERT = "static_assert"; //$NON-NLS-1$
public static final String STATIC_CAST = "static_cast"; //$NON-NLS-1$
public static final String STRUCT = "struct"; //$NON-NLS-1$
public static final String SWITCH = "switch"; //$NON-NLS-1$
@ -162,6 +164,8 @@ public class Keywords {
public static final char[] cSIGNED = "signed".toCharArray(); //$NON-NLS-1$
public static final char[] cSIZEOF = "sizeof".toCharArray(); //$NON-NLS-1$
public static final char[] cSTATIC = "static".toCharArray(); //$NON-NLS-1$
/** @since 5.2 */
public static final char[] cSTATIC_ASSERT = "static_assert".toCharArray(); //$NON-NLS-1$
public static final char[] cSTATIC_CAST = "static_cast".toCharArray(); //$NON-NLS-1$
public static final char[] cSTRUCT = "struct".toCharArray(); //$NON-NLS-1$
public static final char[] cSWITCH = "switch".toCharArray(); //$NON-NLS-1$
@ -339,6 +343,7 @@ public class Keywords {
cppkeywords.put(Keywords.cPROTECTED, IToken.t_protected);
cppkeywords.put(Keywords.cPUBLIC, IToken.t_public);
cppkeywords.put(Keywords.cREINTERPRET_CAST, IToken.t_reinterpret_cast);
cppkeywords.put(Keywords.cSTATIC_ASSERT, IToken.t_static_assert);
cppkeywords.put(Keywords.cSTATIC_CAST, IToken.t_static_cast);
cppkeywords.put(Keywords.cTEMPLATE, IToken.t_template);
cppkeywords.put(Keywords.cTHIS, IToken.t_this);

View file

@ -509,12 +509,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return node.getOffset() + node.getLength();
}
protected final void setRange(IASTNode n, IASTNode from) {
protected final <T extends IASTNode> T setRange(T n, IASTNode from) {
((ASTNode) n).setOffsetAndLength((ASTNode) from);
return n;
}
protected final void setRange(IASTNode n, int offset, int endOffset) {
protected final <T extends IASTNode> T setRange(T n, int offset, int endOffset) {
((ASTNode) n).setOffsetAndLength(offset, endOffset-offset);
return n;
}
protected final void adjustLength(IASTNode n, IASTNode endNode) {

View file

@ -0,0 +1,82 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStaticAssertDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
public class CPPASTStaticAssertionDeclaration extends ASTNode implements ICPPASTStaticAssertDeclaration, IASTAmbiguityParent {
private IASTExpression fCondition;
private final ICPPASTLiteralExpression fMessage;
public CPPASTStaticAssertionDeclaration(IASTExpression condition, ICPPASTLiteralExpression message) {
fCondition= condition;
fMessage= message;
if (condition != null) {
condition.setParent(this);
condition.setPropertyInParent(CONDITION);
}
if (message != null) {
message.setParent(this);
message.setPropertyInParent(MESSAGE);
}
}
public IASTExpression getCondition() {
return fCondition;
}
public ICPPASTLiteralExpression getMessage() {
return fMessage;
}
public CPPASTStaticAssertionDeclaration copy() {
final IASTExpression condCopy = fCondition == null ? null : fCondition.copy();
final ICPPASTLiteralExpression msgCopy = fMessage == null ? null : fMessage.copy();
CPPASTStaticAssertionDeclaration copy = new CPPASTStaticAssertionDeclaration(condCopy, msgCopy);
copy.setOffsetAndLength(this);
return copy;
}
@Override
public boolean accept( ASTVisitor action ){
if (action.shouldVisitDeclarations) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
}
}
if (fCondition != null && !fCondition.accept(action))
return false;
if (fMessage != null && !fMessage.accept(action))
return false;
if (action.shouldVisitDeclarations && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
return true;
}
public void replace(IASTNode child, IASTNode other) {
if (child == fCondition) {
fCondition= (IASTExpression) other;
other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent());
}
}
}

View file

@ -83,6 +83,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStaticAssertDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@ -513,4 +514,8 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
return new CPPASTProblemTypeId(problem);
}
public ICPPASTStaticAssertDeclaration newStaticAssertion(IASTExpression condition,
ICPPASTLiteralExpression message) {
return new CPPASTStaticAssertionDeclaration(condition, message);
}
}

View file

@ -77,6 +77,7 @@ 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.ICPPASTIfStatement;
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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
@ -88,6 +89,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTStaticAssertDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@ -1293,10 +1295,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tLSTRING:
case IToken.tUTF16STRING:
case IToken.tUTF32STRING:
t = consume();
literalExpression = nodeFactory.newLiteralExpression(IASTLiteralExpression.lk_string_literal, t.getImage());
((ASTNode) literalExpression).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset());
return literalExpression;
return stringLiteral();
case IToken.tCHAR:
case IToken.tLCHAR:
case IToken.tUTF16CHAR:
@ -1357,6 +1356,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
private ICPPASTLiteralExpression stringLiteral() throws EndOfFileException, BacktrackException {
switch(LT(1)) {
case IToken.tSTRING:
case IToken.tLSTRING:
case IToken.tUTF16STRING:
case IToken.tUTF32STRING:
break;
default:
throwBacktrack(LA(1));
}
IToken t= consume();
ICPPASTLiteralExpression r= nodeFactory.newLiteralExpression(IASTLiteralExpression.lk_string_literal, t.getImage());
setRange(r, t.getOffset(), t.getEndOffset());
return r;
}
protected IASTExpression specialCastExpression(int kind) throws EndOfFileException, BacktrackException {
final int offset = LA(1).getOffset();
final int optype= consume().getType();
@ -1458,6 +1473,25 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
/**
* static_assert-declaration:
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) {
consume(IToken.tCOMMA);
lit= stringLiteral();
consume(IToken.tRPAREN);
endOffset= consume(IToken.tSEMI).getEndOffset();
}
ICPPASTStaticAssertDeclaration assertion = nodeFactory.newStaticAssertion(e, lit);
return setRange(assertion, offset, endOffset);
}
/**
* Implements Linkage specification in the ANSI C++ grammar.
@ -1690,6 +1724,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return namespaceDefinitionOrAlias();
case IToken.t_using:
return usingClause();
case IToken.t_static_assert:
return staticAssertDeclaration();
case IToken.t_export:
case IToken.t_template:
return templateDeclaration(option);

View file

@ -151,6 +151,7 @@ public class KeywordSets {
DECLARATION_CPP.add( Keywords.USING );
DECLARATION_CPP.add( Keywords.NAMESPACE );
DECLARATION_CPP.add( Keywords.EXPORT );
DECLARATION_CPP.add( Keywords.STATIC_ASSERT );
}
private static final Set<String> DECLARATION_C;
@ -453,6 +454,7 @@ public class KeywordSets {
ALL_CPP.add( Keywords.SIGNED);
ALL_CPP.add( Keywords.SIZEOF);
ALL_CPP.add( Keywords.STATIC);
ALL_CPP.add( Keywords.STATIC_ASSERT);
ALL_CPP.add( Keywords.STATIC_CAST);
ALL_CPP.add( Keywords.STRUCT);
ALL_CPP.add( Keywords.SWITCH);
@ -534,6 +536,7 @@ public class KeywordSets {
KEYWORDS_CPP.add( Keywords.RETURN );
KEYWORDS_CPP.add( Keywords.SIZEOF );
KEYWORDS_CPP.add( Keywords.STATIC );
KEYWORDS_CPP.add( Keywords.STATIC_ASSERT );
KEYWORDS_CPP.add( Keywords.STATIC_CAST );
KEYWORDS_CPP.add( Keywords.STRUCT );
KEYWORDS_CPP.add( Keywords.SWITCH );