diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index bd330870184..0b4f4b4e9bd 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -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(); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index bad33dca9c0..88e30cce75c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -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; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java index 2762fd8a300..cfe1fa7c108 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java @@ -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(); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index a393c3250f9..f50232bf7f2 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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()); } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java index 716312420ea..e702b25ea3e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/LanguageExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/LanguageExtensionsTest.java new file mode 100644 index 00000000000..4d0f757c191 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/LanguageExtensionsTest.java @@ -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); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCParserExtensionConfiguration.java index 42d1d3819b8..50bbe44c14d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCParserExtensionConfiguration.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/ICParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/ICParserExtensionConfiguration.java index 52a6109ad1f..40293173c67 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/ICParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/ICParserExtensionConfiguration.java @@ -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. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPParserExtensionConfiguration.java index e0f5baa02e3..236b5d658c2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPParserExtensionConfiguration.java @@ -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() */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/ICPPParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/ICPPParserExtensionConfiguration.java index 917ddc16351..45c7be93fd8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/ICPPParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/ICPPParserExtensionConfiguration.java @@ -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()} */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index cb25fdfb445..a87ca414439 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -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); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java index 9fab6865c7f..2204345a5b6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java @@ -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), diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index c7677251ed5..e59eb29e950 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index e3a27b08014..2413d9c035b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -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; }