1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

Support for function-style assembler and sizeof-extension, bug 237066+237068.

This commit is contained in:
Markus Schorn 2008-06-30 13:06:07 +00:00
parent 030bdf48c4
commit 58ada354ae
14 changed files with 452 additions and 146 deletions

View file

@ -87,7 +87,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
*/
public class AST2BaseTest extends BaseTestCase {
private static final IParserLogService NULL_LOG = new NullLogService();
protected static final IParserLogService NULL_LOG = new NullLogService();
public AST2BaseTest() {
super();

View file

@ -5741,7 +5741,7 @@ public class AST2CPPTests extends AST2BaseTest {
// namespace ns {
// void test() {}
// +error
// +
// }
public void testTrailingSyntaxErrorInNamespace() throws Exception {
final String comment= getAboveComment();
@ -5749,12 +5749,12 @@ public class AST2CPPTests extends AST2BaseTest {
ICPPASTNamespaceDefinition ns= getDeclaration(tu, 0);
IASTDeclaration decl= getDeclaration(ns, 0);
IASTProblemDeclaration pdecl= getDeclaration(ns, 1);
assertEquals("+error", pdecl.getRawSignature());
assertEquals("+", pdecl.getRawSignature());
}
// extern "C" {
// void test() {}
// +error
// +
// }
public void testTrailingSyntaxErrorInLinkageSpec() throws Exception {
final String comment= getAboveComment();
@ -5762,7 +5762,7 @@ public class AST2CPPTests extends AST2BaseTest {
ICPPASTLinkageSpecification ls= getDeclaration(tu, 0);
IASTDeclaration decl= getDeclaration(ls, 0);
IASTProblemDeclaration pdecl= getDeclaration(ls, 1);
assertEquals("+error", pdecl.getRawSignature());
assertEquals("+", pdecl.getRawSignature());
}
// class C;

View file

@ -27,9 +27,7 @@ import org.eclipse.cdt.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.NullLogService;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerInfo;
@ -43,8 +41,6 @@ import org.eclipse.cdt.internal.core.parser.ParserException;
* @author dsteffle
*/
public class AST2SpecBaseTest extends AST2BaseTest {
private static final IParserLogService NULL_LOG = new NullLogService();
public AST2SpecBaseTest() {
super();
}

View file

@ -4961,20 +4961,20 @@ public class AST2Tests extends AST2BaseTest {
}
// void test() {}
// +error
// +
public void testTrailingSyntaxErrorInTU() throws Exception {
final String comment= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parse(comment, lang, false, false);
IASTDeclaration decl= getDeclaration(tu, 0);
IASTProblemDeclaration pdecl= getDeclaration(tu, 1);
assertEquals("+error", pdecl.getRawSignature());
assertEquals("+", pdecl.getRawSignature());
}
}
// struct X {
// int test;
// +error
// +
// };
public void testTrailingSyntaxErrorInCompositeType() throws Exception {
final String comment= getAboveComment();
@ -4983,14 +4983,14 @@ public class AST2Tests extends AST2BaseTest {
IASTCompositeTypeSpecifier ct= getCompositeType(tu, 0);
IASTDeclaration decl= getDeclaration(ct, 0);
IASTProblemDeclaration pdecl= getDeclaration(ct, 1);
assertEquals("+error", pdecl.getRawSignature());
assertEquals("+", pdecl.getRawSignature());
}
}
// void func() {
// {
// int test;
// +error
// +
// }
// }
public void testTrailingSyntaxErrorInCompoundStatements() throws Exception {
@ -5001,7 +5001,7 @@ public class AST2Tests extends AST2BaseTest {
IASTCompoundStatement compStmt= getStatement(def, 0);
IASTDeclarationStatement dstmt= getStatement(compStmt, 0);
IASTProblemStatement pstmt= getStatement(compStmt, 1);
assertEquals("+error", pstmt.getRawSignature());
assertEquals("+", pstmt.getRawSignature());
}
}

View file

@ -51,6 +51,7 @@ public class DOMParserTestSuite extends TestCase {
suite.addTest(CompletionTestSuite.suite());
suite.addTestSuite(CharArrayMapTest.class);
suite.addTest(FaultToleranceTests.suite());
suite.addTest(LanguageExtensionsTest.suite());
return suite;
}
}

View file

@ -0,0 +1,220 @@
/*******************************************************************************
* Copyright (c) 2008 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.parser.tests.ast2;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.ISourceCodeParser;
import org.eclipse.cdt.core.dom.parser.c.GCCParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.c.GCCScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.c.ICParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.GPPScannerExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.POPCPPParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.POPCPPScannerExtensionConfiguration;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.tests.scanner.FileCodeReaderFactory;
import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
/**
* Testcases for non-gnu language extensions.
*/
public class LanguageExtensionsTest extends AST2BaseTest {
protected static final int SIZEOF_EXTENSION = 0x1;
protected static final int FUNCTION_STYLE_ASM = 0x2;
public static TestSuite suite() {
return suite(LanguageExtensionsTest.class);
}
public LanguageExtensionsTest() {
super();
}
public LanguageExtensionsTest(String name) {
super(name);
}
private IASTTranslationUnit parse(ISourceCodeParser parser) {
IASTTranslationUnit tu= parser.parse();
assertFalse(parser.encounteredError());
assertEquals(0, tu.getPreprocessorProblemsCount());
assertEquals(0, CPPVisitor.getProblems(tu).length);
return tu;
}
protected IASTTranslationUnit parse(String code, IScannerExtensionConfiguration sext,
ICPPParserExtensionConfiguration pext) throws Exception {
IScanner scanner=
new CPreprocessor(new CodeReader(code.toCharArray()), new ScannerInfo(), ParserLanguage.CPP, NULL_LOG,
sext, FileCodeReaderFactory.getInstance());
GNUCPPSourceParser parser= new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, pext);
return parse(parser);
}
protected IASTTranslationUnit parse(String code, IScannerExtensionConfiguration sext,
ICParserExtensionConfiguration pext) throws Exception {
IScanner scanner=
new CPreprocessor(new CodeReader(code.toCharArray()), new ScannerInfo(), ParserLanguage.C, NULL_LOG,
sext, FileCodeReaderFactory.getInstance());
GNUCSourceParser parser= new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, pext);
return parse(parser);
}
protected IASTTranslationUnit parseCPPWithExtension(String code, final int extensions) throws Exception {
return parse(code, GPPScannerExtensionConfiguration.getInstance(),
new GPPParserExtensionConfiguration() {
@Override
public boolean supportExtendedSizeofOperator() {
return (extensions & SIZEOF_EXTENSION) != 0;
}
@Override
public boolean supportFunctionStyleAssembler() {
return (extensions & FUNCTION_STYLE_ASM) != 0;
}
}
);
}
protected IASTTranslationUnit parseCWithExtension(String code, final int extensions) throws Exception {
return parse(code, GCCScannerExtensionConfiguration.getInstance(),
new GCCParserExtensionConfiguration() {
@Override
public boolean supportExtendedSizeofOperator() {
return (extensions & SIZEOF_EXTENSION) != 0;
}
@Override
public boolean supportFunctionStyleAssembler() {
return (extensions & FUNCTION_STYLE_ASM) != 0;
}
}
);
}
// parclass ExampleClass {
// };
public void testPOP_parclass() throws Exception {
IASTTranslationUnit tu= parse(getAboveComment(),
POPCPPScannerExtensionConfiguration.getInstance(),
POPCPPParserExtensionConfiguration.getInstance()
);
ICPPASTCompositeTypeSpecifier comp= getCompositeType(tu, 0);
}
// parclass Table {
// void sort([in, out, size=n] int *data, int n);
// };
public void testPOP_marshallingData() throws Exception {
IASTTranslationUnit tu= parse(getAboveComment(),
POPCPPScannerExtensionConfiguration.getInstance(),
POPCPPParserExtensionConfiguration.getInstance()
);
ICPPASTCompositeTypeSpecifier comp= getCompositeType(tu, 0);
IASTSimpleDeclaration sd= getDeclaration(comp, 0);
assertInstance(sd.getDeclarators()[0], IASTFunctionDeclarator.class);
}
// parclass Bird {
// public:
// Bird(float P) @{ od.power(P);
// od.memory(100,60);
// od.protocol("socket http"); };
// };
public void testPOP_objectDescriptor() throws Exception {
IASTTranslationUnit tu= parse(getAboveComment(),
POPCPPScannerExtensionConfiguration.getInstance(),
POPCPPParserExtensionConfiguration.getInstance()
);
ICPPASTCompositeTypeSpecifier comp= getCompositeType(tu, 0);
IASTSimpleDeclaration sd= getDeclaration(comp, 1);
assertInstance(sd.getDeclarators()[0], IASTFunctionDeclarator.class);
}
// @pack(Stack, Queue, List)
// int a();
public void testPOP_packDirective() throws Exception {
IASTTranslationUnit tu= parse(getAboveComment(),
POPCPPScannerExtensionConfiguration.getInstance(),
POPCPPParserExtensionConfiguration.getInstance()
);
IASTSimpleDeclaration sd= getDeclaration(tu, 0);
assertInstance(sd.getDeclarators()[0], IASTFunctionDeclarator.class);
}
// void test() {
// sizeof(int, 1);
// sizeof(int, 2, 2);
// }
public void testSizeofExtension() throws Exception {
IASTTranslationUnit tu= parseCWithExtension(getAboveComment(), SIZEOF_EXTENSION);
IASTFunctionDefinition fdef= getDeclaration(tu, 0);
IASTUnaryExpression expr= getExpressionOfStatement(fdef, 0);
assertEquals(IASTUnaryExpression.op_sizeof, expr.getOperator());
assertInstance(expr.getOperand(), IASTExpressionList.class);
expr= getExpressionOfStatement(fdef, 1);
assertEquals(IASTUnaryExpression.op_sizeof, expr.getOperator());
assertInstance(expr.getOperand(), IASTExpressionList.class);
tu= parseCPPWithExtension(getAboveComment(), SIZEOF_EXTENSION);
fdef= getDeclaration(tu, 0);
expr= getExpressionOfStatement(fdef, 0);
assertEquals(IASTUnaryExpression.op_sizeof, expr.getOperator());
assertInstance(expr.getOperand(), IASTExpressionList.class);
expr= getExpressionOfStatement(fdef, 1);
assertEquals(IASTUnaryExpression.op_sizeof, expr.getOperator());
assertInstance(expr.getOperand(), IASTExpressionList.class);
}
// asm volatile int a1() {
// assembler code here
// }
// asm int a2() {
// assembler code here
// }
// asm volatile a3(int) {
// assembler code here
// }
// asm a4() {
// assembler code here
// }
public void testFunctionStyleAssembler() throws Exception {
IASTTranslationUnit tu= parseCWithExtension(getAboveComment(), FUNCTION_STYLE_ASM);
IASTFunctionDefinition fdef= getDeclaration(tu, 0);
fdef= getDeclaration(tu, 1);
fdef= getDeclaration(tu, 2);
fdef= getDeclaration(tu, 3);
tu= parseCPPWithExtension(getAboveComment(), FUNCTION_STYLE_ASM);
fdef= getDeclaration(tu, 0);
fdef= getDeclaration(tu, 1);
fdef= getDeclaration(tu, 2);
fdef= getDeclaration(tu, 3);
}
}

View file

@ -95,4 +95,20 @@ public abstract class AbstractCParserExtensionConfiguration implements ICParserE
public boolean supportParameterInfoBlock() {
return false;
}
/**
* {@inheritDoc}
* @since 5.1
*/
public boolean supportExtendedSizeofOperator() {
return false;
}
/**
* {@inheritDoc}
* @since 5.1
*/
public boolean supportFunctionStyleAssembler() {
return false;
}
}

View file

@ -102,6 +102,20 @@ public interface ICParserExtensionConfiguration {
*/
public boolean supportParameterInfoBlock();
/**
* Support additional parameters for the sizeof operator:
* 'sizeof' '(' typeid ',' expression-list ')'
* @since 5.1
*/
public boolean supportExtendedSizeofOperator();
/**
* Support function style assembler definitions:
* 'asm' ['volatile'] [return-type] name '(' parameter-list ')' '{' assembler-code '}'
* @since 5.1
*/
public boolean supportFunctionStyleAssembler();
/**
* See http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for more
* information on GCC's Other Built-in Symbols.

View file

@ -123,6 +123,22 @@ public abstract class AbstractCPPParserExtensionConfiguration implements ICPPPar
return false;
}
/**
* {@inheritDoc}
* @since 5.1
*/
public boolean supportExtendedSizeofOperator() {
return false;
}
/**
* {@inheritDoc}
* @since 5.1
*/
public boolean supportFunctionStyleAssembler() {
return false;
}
/*
* @see org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration#getBuiltinBindingsProvider()
*/

View file

@ -143,6 +143,20 @@ public interface ICPPParserExtensionConfiguration {
*/
public boolean supportParameterInfoBlock();
/**
* Support additional parameters for the sizeof operator:
* 'sizeof' '(' typeid ',' expression-list ')'
* @since 5.1
*/
public boolean supportExtendedSizeofOperator();
/**
* Support function style assembler definitions:
* 'asm' ['volatile'] [return-type] name '(' parameter-list ')' '{' assembler-code '}'
* @since 5.1
*/
public boolean supportFunctionStyleAssembler();
/**
* @deprecated configure extra keywords, via {@link IScannerExtensionConfiguration#getAdditionalKeywords()}
*/

View file

@ -39,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
@ -76,6 +77,7 @@ import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
/**
@ -93,6 +95,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected final boolean supportAttributeSpecifiers;
protected final boolean supportDeclspecSpecifiers;
protected boolean supportParameterInfoBlock;
protected boolean supportFunctionStyleAsm;
protected boolean supportExtendedSizeofOperator;
protected final IBuiltinBindingsProvider builtinBindingsProvider;
/**
@ -1297,6 +1301,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTExpressionStatement createExpressionStatement();
protected abstract IASTFunctionDefinition createFunctionDefinition();
protected abstract IASTLabelStatement createLabelStatement();
@ -1332,6 +1339,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTCaseStatement createCaseStatement();
protected abstract IASTDeclaration declaration(DeclarationOptions option) throws BacktrackException, EndOfFileException;
protected abstract IASTDeclSpecifier declSpecifierSeq(DeclarationOptions option) throws BacktrackException, EndOfFileException, FoundDeclaratorException;
protected IASTDeclaration[] problemDeclaration(int offset, BacktrackException bt, DeclarationOptions option) {
failParse();
@ -1395,19 +1403,64 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTDeclaration asmDeclaration() throws EndOfFileException,
BacktrackException {
IToken first = consume(); // t_asm
IToken next= LA(1);
if (next.getType() == IToken.t_volatile) {
final int offset= consume().getOffset(); // t_asm
if (LT(1) == IToken.t_volatile) {
consume();
}
if (supportFunctionStyleAsm && LT(1) != IToken.tLPAREN) {
return functionStyleAsmDeclaration();
}
StringBuilder buffer= new StringBuilder();
asmExpression(buffer);
int lastOffset = consume(IToken.tSEMI).getEndOffset();
return buildASMDirective(first.getOffset(), buffer.toString(), lastOffset);
return buildASMDirective(offset, buffer.toString(), lastOffset);
}
protected IASTDeclaration functionStyleAsmDeclaration() throws BacktrackException, EndOfFileException {
final int offset= LA(1).getOffset();
IASTDeclSpecifier declSpec;
IASTDeclarator dtor;
try {
declSpec = declSpecifierSeq(DeclarationOptions.FUNCTION_STYLE_ASM);
dtor = initDeclarator(DeclarationOptions.FUNCTION_STYLE_ASM);
} catch (FoundDeclaratorException e) {
if (e.altSpec != null) {
declSpec= e.altSpec;
dtor= e.altDeclarator;
} else {
declSpec = e.declSpec;
dtor= e.declarator;
}
backup( e.currToken );
}
if (LT(1) != IToken.tLBRACE)
throwBacktrack(LA(1));
final IASTDeclarator fdtor= CVisitor.findTypeRelevantDeclarator(dtor);
if (dtor instanceof IASTFunctionDeclarator == false)
throwBacktrack(offset, LA(1).getEndOffset() - offset);
IASTFunctionDefinition funcDefinition = createFunctionDefinition();
funcDefinition.setDeclSpecifier(declSpec);
funcDefinition.setDeclarator((IASTFunctionDeclarator) fdtor);
final int compoundOffset= LA(1).getOffset();
final int endOffset= skipOverCompoundStatement().getEndOffset();
IASTCompoundStatement cs = createCompoundStatement();
((ASTNode)cs).setOffsetAndLength(compoundOffset, endOffset - compoundOffset);
funcDefinition.setBody(cs);
((ASTNode) funcDefinition).setOffsetAndLength(offset, endOffset - offset);
return funcDefinition;
}
protected IToken asmExpression(StringBuilder content) throws EndOfFileException, BacktrackException {
IToken t= consume(IToken.tLPAREN);
boolean needspace= false;
@ -1883,97 +1936,103 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
throwBacktrack(token.getOffset(), token.getLength());
}
protected IASTNode[] parseTypeIdOrUnaryExpression(boolean typeIdWithParentheses) throws EndOfFileException {
return parseTypeIdOrUnaryExpression(typeIdWithParentheses, new int[1]);
}
protected IASTExpression parseTypeidInParenthesisOrUnaryExpression(boolean exprIsLimitedToParenthesis, int offset, int typeExprKind, int unaryExprKind) throws BacktrackException, EndOfFileException {
IASTTypeId typeid;
IASTExpression expr= null;
IToken typeidLA= null;
IToken mark = mark();
int endOffset1= -1;
int endOffset2= -1;
protected IASTNode[] parseTypeIdOrUnaryExpression(boolean typeIdWithParentheses, int[] endoffset) throws EndOfFileException {
IASTTypeId typeId = null;
IToken typeIdLA = null;
IToken mark = mark();
try {
if (typeIdWithParentheses)
consume(IToken.tLPAREN);
typeId = typeId(DeclarationOptions.TYPEID);
if (typeId != null) {
if (typeIdWithParentheses) {
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
endoffset[0]= consume().getEndOffset();
typeIdLA = LA(1);
break;
default:
typeId = null;
consume(IToken.tLPAREN);
int typeidOffset= LA(1).getOffset();
typeid= typeId(DeclarationOptions.TYPEID);
if (typeid != null) {
switch(LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
endOffset1= consume().getEndOffset();
typeidLA= LA(1);
break;
case IToken.tCOMMA:
if (supportExtendedSizeofOperator && typeExprKind == IASTTypeIdExpression.op_sizeof) {
consume();
IASTExpression expr2= expression();
endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset();
expr= buildTypeIdExpression(IASTTypeIdExpression.op_typeid, typeid, typeidOffset, calculateEndOffset(typeid));
IASTExpressionList expressionList = createExpressionList();
((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset);
expressionList.addExpression(expr);
if (expr2 instanceof IASTExpressionList) {
for (IASTExpression e : ((IASTExpressionList) expr2).getExpressions()) {
expressionList.addExpression(e);
}
} else {
expressionList.addExpression(expr2);
}
return buildUnaryExpression(unaryExprKind, expressionList, offset, endOffset1);
}
}
else {
endoffset[0]= calculateEndOffset(typeId);
typeIdLA = LA(1);
typeid= null;
break;
default:
typeid= null;
break;
}
}
} catch (BacktrackException e) { }
backup(mark);
} catch (BacktrackException e) {
typeid= null;
}
IToken unaryExpressionLA = null;
IASTExpression unaryExpression = null;
backup(mark);
try {
unaryExpression = unaryExpression(); // throws BacktrackException
unaryExpressionLA = LA(1);
} catch (BacktrackException bte) { }
if (unaryExpression == null && typeId != null) {
backup(typeIdLA);
return new IASTNode[] {typeId};
}
if (unaryExpression != null && typeId == null) {
backup(unaryExpressionLA);
endoffset[0]= calculateEndOffset(unaryExpression);
return new IASTNode[] {unaryExpression};
}
if (unaryExpression != null && typeId != null) {
if (typeIdLA == unaryExpressionLA) {
return new IASTNode[] {typeId, unaryExpression};
if (exprIsLimitedToParenthesis) {
consume(IToken.tLPAREN);
}
return new IASTNode[] {unaryExpression};
expr= unaryExpression();
if (exprIsLimitedToParenthesis) {
endOffset2= consumeOrEOC(IToken.tRPAREN).getEndOffset();
} else {
endOffset2= calculateEndOffset(expr);
}
} catch (BacktrackException bte) {
if (typeid == null)
throw bte;
}
return IASTNode.EMPTY_NODE_ARRAY;
IASTExpression result1= null;
if (typeid != null && endOffset1 >= endOffset2) {
result1= buildTypeIdExpression(typeExprKind, typeid, offset, endOffset1);
backup(typeidLA);
if (expr == null || endOffset1 > endOffset2)
return result1;
}
IASTExpression result2= buildUnaryExpression(unaryExprKind, expr, offset, endOffset2);
if (result1 == null)
return result2;
IASTAmbiguousExpression ambExpr = createAmbiguousExpression();
ambExpr.addExpression(result1);
ambExpr.addExpression(result2);
((ASTNode) ambExpr).setOffsetAndLength((ASTNode) result1);
return ambExpr;
}
protected abstract IASTAmbiguousExpression createAmbiguousExpression();
protected IASTExpression parseSizeofExpression() throws BacktrackException, EndOfFileException {
int startingOffset = consume().getOffset(); // t_sizeof
int[] endoffset= new int[] {0};
IASTNode[] choice = parseTypeIdOrUnaryExpression(true, endoffset);
switch (choice.length) {
case 1:
if (choice[0] instanceof IASTExpression)
return buildUnaryExpression(IASTUnaryExpression.op_sizeof,
(IASTExpression) choice[0], startingOffset, endoffset[0]);
else if (choice[0] instanceof IASTTypeId)
return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof,
(IASTTypeId) choice[0], startingOffset, endoffset[0]);
throwBacktrack(LA(1));
break;
case 2:
IASTAmbiguousExpression ambExpr = createAmbiguousExpression();
IASTExpression e1 = buildTypeIdExpression(
IASTTypeIdExpression.op_sizeof, (IASTTypeId) choice[0],
startingOffset, endoffset[0]);
IASTExpression e2 = buildUnaryExpression(
IASTUnaryExpression.op_sizeof, (IASTExpression) choice[1],
startingOffset, endoffset[0]);
ambExpr.addExpression(e1);
ambExpr.addExpression(e2);
((ASTNode) ambExpr).setOffsetAndLength((ASTNode) e2);
return ambExpr;
default:
final int offset = consume().getOffset(); // t_sizeof
if (LT(1) != IToken.tLPAREN) {
IASTExpression unary= unaryExpression();
return buildUnaryExpression(IASTUnaryExpression.op_sizeof, unary, offset, calculateEndOffset(unary));
}
throwBacktrack(LA(1));
return null;
return parseTypeidInParenthesisOrUnaryExpression(false, offset, IASTTypeIdExpression.op_sizeof, IASTUnaryExpression.op_sizeof);
}
/**

View file

@ -27,6 +27,7 @@ public class DeclarationOptions {
public static final DeclarationOptions
GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_CONSTRUCTOR_INITIALIZER),
FUNCTION_STYLE_ASM= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | NO_INITIALIZER),
C_MEMBER= new DeclarationOptions(ALLOW_BITFIELD),
CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | ALLOW_CONSTRUCTOR_INITIALIZER),
LOCAL= new DeclarationOptions(ALLOW_CONSTRUCTOR_INITIALIZER),

View file

@ -147,6 +147,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
config.getBuiltinBindingsProvider());
supportGCCStyleDesignators = config.supportGCCStyleDesignators();
supportParameterInfoBlock= config.supportParameterInfoBlock();
supportExtendedSizeofOperator= config.supportExtendedSizeofOperator();
supportFunctionStyleAsm= config.supportFunctionStyleAssembler();
this.index= index;
}
@ -503,7 +505,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
}
protected IASTFunctionDefinition createFunctionDefinition() {
@Override
protected IASTFunctionDefinition createFunctionDefinition() {
return new CASTFunctionDefinition();
}
@ -1066,7 +1069,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
private final static int INLINE=0x1, CONST=0x2, RESTRICT=0x4, VOLATILE=0x8,
SHORT=0x10, UNSIGNED= 0x20, SIGNED=0x40, COMPLEX=0x80, IMAGINARY=0x100;
protected IASTDeclSpecifier declSpecifierSeq(final DeclarationOptions declOption)
@Override
protected IASTDeclSpecifier declSpecifierSeq(final DeclarationOptions declOption)
throws BacktrackException, EndOfFileException, FoundDeclaratorException {
final int offset= LA(1).getOffset();
@ -1381,7 +1385,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tCOMMA:
return true;
case IToken.tLBRACE:
if (option == DeclarationOptions.GLOBAL || option == DeclarationOptions.C_MEMBER) {
if (option == DeclarationOptions.GLOBAL || option == DeclarationOptions.C_MEMBER
|| option == DeclarationOptions.FUNCTION_STYLE_ASM) {
if (CVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) {
return true;
}

View file

@ -1304,16 +1304,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
firstExpression = specialCastExpression(ICPPASTCastExpression.op_const_cast);
break;
case IToken.t_typeid:
int lastOffset;
int so = consume().getOffset();
consume(IToken.tLPAREN);
if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN);
}
IASTNode[] n;
try {
n= parseTypeIdOrUnaryExpression(false);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
return parseTypeidInParenthesisOrUnaryExpression(true, so, ICPPASTTypeIdExpression.op_typeid, ICPPASTUnaryExpression.op_typeid);
}
finally {
if (templateIdScopes.size() > 0) {
@ -1321,47 +1317,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
}
switch (n.length) {
case 0:
throwBacktrack(LA(1));
return null; // line is never reached, hint for the parser
case 1:
if (n[0] instanceof IASTTypeId) {
firstExpression = buildTypeIdExpression(
ICPPASTTypeIdExpression.op_typeid,
(IASTTypeId) n[0], so, lastOffset);
} else if (n[0] instanceof IASTExpression) {
firstExpression = buildUnaryExpression(
ICPPASTUnaryExpression.op_typeid,
(IASTExpression) n[0], so, lastOffset);
} else {
throwBacktrack(LA(1));
return null; // line is never reached, hint for the parser
}
break;
case 2:
IASTAmbiguousExpression ambExpr = createAmbiguousExpression();
IASTExpression e1 = buildTypeIdExpression(
ICPPASTTypeIdExpression.op_typeid, (IASTTypeId) n[0],
so, lastOffset);
IASTExpression e2 = buildUnaryExpression(
ICPPASTUnaryExpression.op_typeid,
(IASTExpression) n[1], so, lastOffset);
ambExpr.addExpression(e1);
ambExpr.addExpression(e2);
((ASTNode) ambExpr).setOffsetAndLength((ASTNode) e2);
firstExpression = ambExpr;
break;
default:
assert false;
throwBacktrack(LA(1));
return null; // line is never reached, hint for the parser
}
break;
default:
firstExpression = primaryExpression();
break;
}
IASTExpression secondExpression = null;
for (;;) {
@ -1776,6 +1734,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
supportMinAndMaxOperators = config.supportMinAndMaxOperators();
supportLongLong = config.supportLongLongs();
supportParameterInfoBlock= config.supportParameterInfoBlock();
supportExtendedSizeofOperator= config.supportExtendedSizeofOperator();
supportFunctionStyleAsm= config.supportFunctionStyleAssembler();
this.index= index;
}
@ -2608,7 +2568,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (declSpec instanceof IASTEnumerationSpecifier)
return true;
return false;
return option == DeclarationOptions.FUNCTION_STYLE_ASM;
}
private IASTDeclaration functionDefinition(final int firstOffset, IASTDeclSpecifier declSpec,
@ -2675,7 +2635,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
protected IASTFunctionDefinition createFunctionDefinition() {
@Override
protected IASTFunctionDefinition createFunctionDefinition() {
return new CPPASTFunctionDefinition();
}
@ -2807,7 +2768,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* { "class" | "struct" | "union" } classSpecifier |
* {"enum"} enumSpecifier
*/
protected ICPPASTDeclSpecifier declSpecifierSeq(final DeclarationOptions option)
@Override
protected ICPPASTDeclSpecifier declSpecifierSeq(final DeclarationOptions option)
throws BacktrackException, EndOfFileException, FoundDeclaratorException {
int storageClass = IASTDeclSpecifier.sc_unspecified;
int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
@ -2995,7 +2957,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
lookAheadForDeclarator(option);
}
} catch (FoundDeclaratorException e) {
if (e.currToken.getType() == IToken.tEOC || canBeConstructorDestructorOrConversion(option, storageClass, options, e.declarator)) {
if (e.currToken.getType() == IToken.tEOC || option == DeclarationOptions.FUNCTION_STYLE_ASM
|| canBeConstructorDestructorOrConversion(option, storageClass, options, e.declarator)) {
e.declSpec= createSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
throw e;
}
@ -3188,7 +3151,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tLBRACE:
case IToken.t_const:
case IToken.t_volatile:
if (option == DeclarationOptions.GLOBAL || option == DeclarationOptions.CPP_MEMBER) {
if (option == DeclarationOptions.GLOBAL || option == DeclarationOptions.CPP_MEMBER
|| option == DeclarationOptions.FUNCTION_STYLE_ASM) {
if (CVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) {
return true;
}