1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 23:05:47 +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 { public class AST2BaseTest extends BaseTestCase {
private static final IParserLogService NULL_LOG = new NullLogService(); protected static final IParserLogService NULL_LOG = new NullLogService();
public AST2BaseTest() { public AST2BaseTest() {
super(); super();

View file

@ -5741,7 +5741,7 @@ public class AST2CPPTests extends AST2BaseTest {
// namespace ns { // namespace ns {
// void test() {} // void test() {}
// +error // +
// } // }
public void testTrailingSyntaxErrorInNamespace() throws Exception { public void testTrailingSyntaxErrorInNamespace() throws Exception {
final String comment= getAboveComment(); final String comment= getAboveComment();
@ -5749,12 +5749,12 @@ public class AST2CPPTests extends AST2BaseTest {
ICPPASTNamespaceDefinition ns= getDeclaration(tu, 0); ICPPASTNamespaceDefinition ns= getDeclaration(tu, 0);
IASTDeclaration decl= getDeclaration(ns, 0); IASTDeclaration decl= getDeclaration(ns, 0);
IASTProblemDeclaration pdecl= getDeclaration(ns, 1); IASTProblemDeclaration pdecl= getDeclaration(ns, 1);
assertEquals("+error", pdecl.getRawSignature()); assertEquals("+", pdecl.getRawSignature());
} }
// extern "C" { // extern "C" {
// void test() {} // void test() {}
// +error // +
// } // }
public void testTrailingSyntaxErrorInLinkageSpec() throws Exception { public void testTrailingSyntaxErrorInLinkageSpec() throws Exception {
final String comment= getAboveComment(); final String comment= getAboveComment();
@ -5762,7 +5762,7 @@ public class AST2CPPTests extends AST2BaseTest {
ICPPASTLinkageSpecification ls= getDeclaration(tu, 0); ICPPASTLinkageSpecification ls= getDeclaration(tu, 0);
IASTDeclaration decl= getDeclaration(ls, 0); IASTDeclaration decl= getDeclaration(ls, 0);
IASTProblemDeclaration pdecl= getDeclaration(ls, 1); IASTProblemDeclaration pdecl= getDeclaration(ls, 1);
assertEquals("+error", pdecl.getRawSignature()); assertEquals("+", pdecl.getRawSignature());
} }
// class C; // 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.GPPParserExtensionConfiguration;
import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration;
import org.eclipse.cdt.core.parser.CodeReader; 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.IScanner;
import org.eclipse.cdt.core.parser.NullLogService;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ScannerInfo;
@ -43,8 +41,6 @@ import org.eclipse.cdt.internal.core.parser.ParserException;
* @author dsteffle * @author dsteffle
*/ */
public class AST2SpecBaseTest extends AST2BaseTest { public class AST2SpecBaseTest extends AST2BaseTest {
private static final IParserLogService NULL_LOG = new NullLogService();
public AST2SpecBaseTest() { public AST2SpecBaseTest() {
super(); super();
} }

View file

@ -4961,20 +4961,20 @@ public class AST2Tests extends AST2BaseTest {
} }
// void test() {} // void test() {}
// +error // +
public void testTrailingSyntaxErrorInTU() throws Exception { public void testTrailingSyntaxErrorInTU() throws Exception {
final String comment= getAboveComment(); final String comment= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) { for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parse(comment, lang, false, false); IASTTranslationUnit tu= parse(comment, lang, false, false);
IASTDeclaration decl= getDeclaration(tu, 0); IASTDeclaration decl= getDeclaration(tu, 0);
IASTProblemDeclaration pdecl= getDeclaration(tu, 1); IASTProblemDeclaration pdecl= getDeclaration(tu, 1);
assertEquals("+error", pdecl.getRawSignature()); assertEquals("+", pdecl.getRawSignature());
} }
} }
// struct X { // struct X {
// int test; // int test;
// +error // +
// }; // };
public void testTrailingSyntaxErrorInCompositeType() throws Exception { public void testTrailingSyntaxErrorInCompositeType() throws Exception {
final String comment= getAboveComment(); final String comment= getAboveComment();
@ -4983,14 +4983,14 @@ public class AST2Tests extends AST2BaseTest {
IASTCompositeTypeSpecifier ct= getCompositeType(tu, 0); IASTCompositeTypeSpecifier ct= getCompositeType(tu, 0);
IASTDeclaration decl= getDeclaration(ct, 0); IASTDeclaration decl= getDeclaration(ct, 0);
IASTProblemDeclaration pdecl= getDeclaration(ct, 1); IASTProblemDeclaration pdecl= getDeclaration(ct, 1);
assertEquals("+error", pdecl.getRawSignature()); assertEquals("+", pdecl.getRawSignature());
} }
} }
// void func() { // void func() {
// { // {
// int test; // int test;
// +error // +
// } // }
// } // }
public void testTrailingSyntaxErrorInCompoundStatements() throws Exception { public void testTrailingSyntaxErrorInCompoundStatements() throws Exception {
@ -5001,7 +5001,7 @@ public class AST2Tests extends AST2BaseTest {
IASTCompoundStatement compStmt= getStatement(def, 0); IASTCompoundStatement compStmt= getStatement(def, 0);
IASTDeclarationStatement dstmt= getStatement(compStmt, 0); IASTDeclarationStatement dstmt= getStatement(compStmt, 0);
IASTProblemStatement pstmt= getStatement(compStmt, 1); 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.addTest(CompletionTestSuite.suite());
suite.addTestSuite(CharArrayMapTest.class); suite.addTestSuite(CharArrayMapTest.class);
suite.addTest(FaultToleranceTests.suite()); suite.addTest(FaultToleranceTests.suite());
suite.addTest(LanguageExtensionsTest.suite());
return 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() { public boolean supportParameterInfoBlock() {
return false; 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(); 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 * See http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html for more
* information on GCC's Other Built-in Symbols. * information on GCC's Other Built-in Symbols.

View file

@ -123,6 +123,22 @@ public abstract class AbstractCPPParserExtensionConfiguration implements ICPPPar
return false; 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() * @see org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration#getBuiltinBindingsProvider()
*/ */

View file

@ -143,6 +143,20 @@ public interface ICPPParserExtensionConfiguration {
*/ */
public boolean supportParameterInfoBlock(); 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()} * @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.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; 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.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement; 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.OffsetLimitReachedException;
import org.eclipse.cdt.core.parser.ParseError; import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserMode; 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; 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 supportAttributeSpecifiers;
protected final boolean supportDeclspecSpecifiers; protected final boolean supportDeclspecSpecifiers;
protected boolean supportParameterInfoBlock; protected boolean supportParameterInfoBlock;
protected boolean supportFunctionStyleAsm;
protected boolean supportExtendedSizeofOperator;
protected final IBuiltinBindingsProvider builtinBindingsProvider; protected final IBuiltinBindingsProvider builtinBindingsProvider;
/** /**
@ -1299,6 +1303,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTExpressionStatement createExpressionStatement(); protected abstract IASTExpressionStatement createExpressionStatement();
protected abstract IASTFunctionDefinition createFunctionDefinition();
protected abstract IASTLabelStatement createLabelStatement(); protected abstract IASTLabelStatement createLabelStatement();
@ -1332,6 +1339,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTCaseStatement createCaseStatement(); protected abstract IASTCaseStatement createCaseStatement();
protected abstract IASTDeclaration declaration(DeclarationOptions option) throws BacktrackException, EndOfFileException; 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) { protected IASTDeclaration[] problemDeclaration(int offset, BacktrackException bt, DeclarationOptions option) {
failParse(); failParse();
@ -1395,19 +1403,64 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTDeclaration asmDeclaration() throws EndOfFileException, protected IASTDeclaration asmDeclaration() throws EndOfFileException,
BacktrackException { BacktrackException {
IToken first = consume(); // t_asm final int offset= consume().getOffset(); // t_asm
IToken next= LA(1); if (LT(1) == IToken.t_volatile) {
if (next.getType() == IToken.t_volatile) {
consume(); consume();
} }
if (supportFunctionStyleAsm && LT(1) != IToken.tLPAREN) {
return functionStyleAsmDeclaration();
}
StringBuilder buffer= new StringBuilder(); StringBuilder buffer= new StringBuilder();
asmExpression(buffer); asmExpression(buffer);
int lastOffset = consume(IToken.tSEMI).getEndOffset(); 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 { protected IToken asmExpression(StringBuilder content) throws EndOfFileException, BacktrackException {
IToken t= consume(IToken.tLPAREN); IToken t= consume(IToken.tLPAREN);
boolean needspace= false; boolean needspace= false;
@ -1883,97 +1936,103 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
throwBacktrack(token.getOffset(), token.getLength()); throwBacktrack(token.getOffset(), token.getLength());
} }
protected IASTNode[] parseTypeIdOrUnaryExpression(boolean typeIdWithParentheses) throws EndOfFileException { protected IASTExpression parseTypeidInParenthesisOrUnaryExpression(boolean exprIsLimitedToParenthesis, int offset, int typeExprKind, int unaryExprKind) throws BacktrackException, EndOfFileException {
return parseTypeIdOrUnaryExpression(typeIdWithParentheses, new int[1]); 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 { try {
if (typeIdWithParentheses) consume(IToken.tLPAREN);
consume(IToken.tLPAREN); int typeidOffset= LA(1).getOffset();
typeId = typeId(DeclarationOptions.TYPEID); typeid= typeId(DeclarationOptions.TYPEID);
if (typeId != null) { if (typeid != null) {
if (typeIdWithParentheses) { switch(LT(1)) {
switch (LT(1)) { case IToken.tRPAREN:
case IToken.tRPAREN: case IToken.tEOC:
case IToken.tEOC: endOffset1= consume().getEndOffset();
endoffset[0]= consume().getEndOffset(); typeidLA= LA(1);
typeIdLA = LA(1); break;
break; case IToken.tCOMMA:
default: if (supportExtendedSizeofOperator && typeExprKind == IASTTypeIdExpression.op_sizeof) {
typeId = null; 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);
} }
} typeid= null;
else { break;
endoffset[0]= calculateEndOffset(typeId); default:
typeIdLA = LA(1); typeid= null;
break;
} }
} }
} catch (BacktrackException e) { } } catch (BacktrackException e) {
typeid= null;
}
backup(mark); backup(mark);
IToken unaryExpressionLA = null;
IASTExpression unaryExpression = null;
try { try {
unaryExpression = unaryExpression(); // throws BacktrackException if (exprIsLimitedToParenthesis) {
unaryExpressionLA = LA(1); consume(IToken.tLPAREN);
} 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};
} }
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 abstract IASTAmbiguousExpression createAmbiguousExpression();
protected IASTExpression parseSizeofExpression() throws BacktrackException, EndOfFileException { protected IASTExpression parseSizeofExpression() throws BacktrackException, EndOfFileException {
int startingOffset = consume().getOffset(); // t_sizeof final int offset = consume().getOffset(); // t_sizeof
int[] endoffset= new int[] {0}; if (LT(1) != IToken.tLPAREN) {
IASTNode[] choice = parseTypeIdOrUnaryExpression(true, endoffset); IASTExpression unary= unaryExpression();
switch (choice.length) { return buildUnaryExpression(IASTUnaryExpression.op_sizeof, unary, offset, calculateEndOffset(unary));
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:
} }
throwBacktrack(LA(1)); return parseTypeidInParenthesisOrUnaryExpression(false, offset, IASTTypeIdExpression.op_sizeof, IASTUnaryExpression.op_sizeof);
return null;
} }
/** /**

View file

@ -27,6 +27,7 @@ public class DeclarationOptions {
public static final DeclarationOptions public static final DeclarationOptions
GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_CONSTRUCTOR_INITIALIZER), 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), C_MEMBER= new DeclarationOptions(ALLOW_BITFIELD),
CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | ALLOW_CONSTRUCTOR_INITIALIZER), CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | ALLOW_CONSTRUCTOR_INITIALIZER),
LOCAL= new DeclarationOptions(ALLOW_CONSTRUCTOR_INITIALIZER), LOCAL= new DeclarationOptions(ALLOW_CONSTRUCTOR_INITIALIZER),

View file

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

View file

@ -1304,16 +1304,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
firstExpression = specialCastExpression(ICPPASTCastExpression.op_const_cast); firstExpression = specialCastExpression(ICPPASTCastExpression.op_const_cast);
break; break;
case IToken.t_typeid: case IToken.t_typeid:
int lastOffset;
int so = consume().getOffset(); int so = consume().getOffset();
consume(IToken.tLPAREN);
if (templateIdScopes.size() > 0) { if (templateIdScopes.size() > 0) {
templateIdScopes.push(IToken.tLPAREN); templateIdScopes.push(IToken.tLPAREN);
} }
IASTNode[] n;
try { try {
n= parseTypeIdOrUnaryExpression(false); return parseTypeidInParenthesisOrUnaryExpression(true, so, ICPPASTTypeIdExpression.op_typeid, ICPPASTUnaryExpression.op_typeid);
lastOffset = consume(IToken.tRPAREN).getEndOffset();
} }
finally { finally {
if (templateIdScopes.size() > 0) { 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: default:
firstExpression = primaryExpression(); firstExpression = primaryExpression();
break;
} }
IASTExpression secondExpression = null; IASTExpression secondExpression = null;
for (;;) { for (;;) {
@ -1776,6 +1734,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
supportMinAndMaxOperators = config.supportMinAndMaxOperators(); supportMinAndMaxOperators = config.supportMinAndMaxOperators();
supportLongLong = config.supportLongLongs(); supportLongLong = config.supportLongLongs();
supportParameterInfoBlock= config.supportParameterInfoBlock(); supportParameterInfoBlock= config.supportParameterInfoBlock();
supportExtendedSizeofOperator= config.supportExtendedSizeofOperator();
supportFunctionStyleAsm= config.supportFunctionStyleAssembler();
this.index= index; this.index= index;
} }
@ -2608,7 +2568,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (declSpec instanceof IASTEnumerationSpecifier) if (declSpec instanceof IASTEnumerationSpecifier)
return true; return true;
return false; return option == DeclarationOptions.FUNCTION_STYLE_ASM;
} }
private IASTDeclaration functionDefinition(final int firstOffset, IASTDeclSpecifier declSpec, 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(); return new CPPASTFunctionDefinition();
} }
@ -2807,7 +2768,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* { "class" | "struct" | "union" } classSpecifier | * { "class" | "struct" | "union" } classSpecifier |
* {"enum"} enumSpecifier * {"enum"} enumSpecifier
*/ */
protected ICPPASTDeclSpecifier declSpecifierSeq(final DeclarationOptions option) @Override
protected ICPPASTDeclSpecifier declSpecifierSeq(final DeclarationOptions option)
throws BacktrackException, EndOfFileException, FoundDeclaratorException { throws BacktrackException, EndOfFileException, FoundDeclaratorException {
int storageClass = IASTDeclSpecifier.sc_unspecified; int storageClass = IASTDeclSpecifier.sc_unspecified;
int simpleType = IASTSimpleDeclSpecifier.t_unspecified; int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
@ -2995,7 +2957,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
lookAheadForDeclarator(option); lookAheadForDeclarator(option);
} }
} catch (FoundDeclaratorException e) { } 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); e.declSpec= createSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
throw e; throw e;
} }
@ -3188,7 +3151,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tLBRACE: case IToken.tLBRACE:
case IToken.t_const: case IToken.t_const:
case IToken.t_volatile: 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) { if (CVisitor.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) {
return true; return true;
} }