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:
parent
030bdf48c4
commit
58ada354ae
14 changed files with 452 additions and 146 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
*/
|
||||
|
|
|
@ -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()}
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue