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:
parent
30fe21353c
commit
6ce54bb401
11 changed files with 212 additions and 11 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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$
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Add table
Reference in a new issue