diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java index 66cca9ab846..7e18f4f3463 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java @@ -700,6 +700,7 @@ public class CompletionParseTest extends CompletionParseBaseTest { results.add("__builtin_ctzll"); //$NON-NLS-1$ results.add("__builtin_popcountll"); //$NON-NLS-1$ results.add("__builtin_parityll"); //$NON-NLS-1$ + results.add("__builtin_types_compatible_p"); //$NON-NLS-1$ } validateLookupResult(result, results ); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java index bd1416b02ea..cd1348462ca 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/GCCCompleteParseExtensionsTest.java @@ -222,4 +222,17 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest { parse( writer.toString() ); } + public void testBug73954B() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "#define foo(x) \\\n"); //$NON-NLS-1$ + writer.write( " __builtin_choose_expr( 1, foo_d(x), (void)0 ) \n"); //$NON-NLS-1$ + writer.write( "int foo_d( int x ); \n"); //$NON-NLS-1$ + writer.write( "int main() { \n"); //$NON-NLS-1$ + writer.write( " if( __builtin_constant_p(1) && \n"); //$NON-NLS-1$ + writer.write( " __builtin_types_compatible_p( 1, 'c') ) \n"); //$NON-NLS-1$ + writer.write( " foo(1); \n"); //$NON-NLS-1$ + writer.write( "} \n"); //$NON-NLS-1$ + + parse( writer.toString(), true, ParserLanguage.C ); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/GCCScannerExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/GCCScannerExtensionsTest.java index fdbb7ac71a1..887d14d9b4f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/GCCScannerExtensionsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/GCCScannerExtensionsTest.java @@ -10,8 +10,12 @@ ***********************************************************************/ package org.eclipse.cdt.core.parser.tests.scanner2; +import java.io.StringWriter; +import java.io.Writer; + import org.eclipse.cdt.core.parser.IGCCToken; import org.eclipse.cdt.core.parser.IToken; +import org.eclipse.cdt.core.parser.ParserLanguage; /** * @author jcamelon @@ -42,4 +46,20 @@ public class GCCScannerExtensionsTest extends BaseScanner2Test { validateEOF(); } + public void testBug73954B() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "#define foo(x) \\\n"); //$NON-NLS-1$ + writer.write( " __builtin_choose_expr( \\\n"); //$NON-NLS-1$ + writer.write( " __builtin_types_compatible_p( typeof(x), double ), \\\n"); //$NON-NLS-1$ + writer.write( " foo_double( x ), (void)0 ) \n"); //$NON-NLS-1$ + writer.write( "__builtin_constant_p(1) \n"); //$NON-NLS-1$ + writer.write( "foo( 1 ) \n"); //$NON-NLS-1$ + + initializeScanner( writer.toString(), ParserLanguage.C ); + validateInteger( "0" ); //$NON-NLS-1$ + validateToken( IToken.tLPAREN ); + validateToken( IToken.t_void ); + validateToken( IToken.tRPAREN ); + validateInteger( "0" ); //$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index b61e133c232..e0abeb8de32 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -4571,17 +4571,17 @@ public class Parser implements IParserData, IParser sdw.setLong(true); break; case IToken.t__Complex : - consume(IToken.t__Complex); if (typeNameBegin == null) typeNameBegin = LA(1); typeNameEnd = LA(1); + consume(IToken.t__Complex); sdw.setComplex(true); break; case IToken.t__Imaginary : - consume(IToken.t__Imaginary); if (typeNameBegin == null) typeNameBegin = LA(1); typeNameEnd = LA(1); + consume(IToken.t__Imaginary); sdw.setImaginary(true); break; case IToken.t_char : diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index e684a568f45..4d38dfda01d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -71,6 +71,7 @@ import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind; import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type; import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter.ParamKind; import org.eclipse.cdt.core.parser.extension.IASTFactoryExtension; +import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.parser.ast.ASTAbstractDeclaration; import org.eclipse.cdt.internal.core.parser.ast.ASTDesignator; @@ -119,8 +120,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto private final ParserMode mode; private static final int BUILTIN_TYPE_SIZE = 64; - private final Hashtable typeIdCache = new Hashtable( BUILTIN_TYPE_SIZE ); - private final Hashtable simpleTypeSpecCache = new Hashtable( BUILTIN_TYPE_SIZE ); + private final CharArrayObjectMap typeIdCache = new CharArrayObjectMap( BUILTIN_TYPE_SIZE ); + private final CharArrayObjectMap simpleTypeSpecCache = new CharArrayObjectMap( BUILTIN_TYPE_SIZE ); private static final int DEFAULT_QUALIFIEDNAME_REFERENCE_SIZE = 4; private char[] filename; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java index 0eacc8a63f6..00e8ac1c0ce 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java @@ -41,11 +41,14 @@ import org.eclipse.cdt.internal.core.parser.Declarator; import org.eclipse.cdt.internal.core.parser.ast.GCCASTExtension; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTBinaryExpression; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTEmptyExpression; +import org.eclipse.cdt.internal.core.parser.ast.complete.ASTSimpleTypeSpecifier; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTypeIdExpression; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTUnaryExpression; import org.eclipse.cdt.internal.core.parser.ast.complete.ExpressionFactory; +import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo; import org.eclipse.cdt.internal.core.parser.token.ImagedToken; import org.eclipse.cdt.internal.core.parser.token.SimpleToken; +import org.eclipse.cdt.internal.core.parser.token.TokenFactory; /** * @author aniefer @@ -82,6 +85,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { private static final char [] __BUILTIN_CTZLL = "__builtin_ctzll".toCharArray(); //$NON-NLS-1$ private static final char [] __BUILTIN_POPCOUNTLL = "__builtin_popcountll".toCharArray(); //$NON-NLS-1$ private static final char [] __BUILTIN_PARITYLL = "__builtin_parityll".toCharArray(); //$NON-NLS-1$ + private static final char [] __BUILTIN_TYPES_COMPATIBLE_P = "__builtin_types_compatible_p".toCharArray(); //$NON-NLS-1$ /** * @param mode @@ -181,6 +185,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { __builtin_unsigned_int( factory, compilationUnit ); __builtin_unsigned_long( factory, compilationUnit ); __builtin_unsigned_long_long( factory, compilationUnit ); + __builtin_types_compatible_p( factory, compilationUnit ); } /** @@ -191,7 +196,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //double __builtin_inf (void) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -209,7 +214,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //float __builtin_inff (void) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_float, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -227,7 +232,11 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //long double __builtin_infl (void) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IToken t1 = new SimpleToken( IToken.t_long, -1, EMPTY_STRING, -1 ); + IToken t2 = new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ); + t1.setNext( t2 ); + ITokenDuple duple = TokenFactory.createTokenDuple( t1, t2 ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, duple, false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -251,7 +260,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //double __builtin_huge_val (void) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -269,7 +278,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //float __builtin_huge_valf (void) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_float, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -287,7 +296,11 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //long double __builtin_huge_vall (void) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IToken t1 = new SimpleToken( IToken.t_long, -1, EMPTY_STRING, -1 ); + IToken t2 = new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ); + t1.setNext( t2 ); + ITokenDuple duple = TokenFactory.createTokenDuple( t1, t2 ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, duple, false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -376,7 +389,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { //const char * DeclarationWrapper param = new DeclarationWrapper( compilationUnit, 0, 0, null, EMPTY_STRING ); try { - param.setTypeSpecifier( factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.CHAR, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ) ); + param.setTypeSpecifier( factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.CHAR, new SimpleToken( IToken.t_char, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ) ); } catch ( ASTSemanticException e1 ) {//nothing } Declarator paramDecl = new Declarator( param ); @@ -387,7 +400,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //double __builtin_nan (const char * str) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -402,7 +415,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //float __builtin_nanf (const char * str) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_float, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -417,7 +430,11 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //long double __builtin_nanl (const char * str) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IToken t1 = new SimpleToken( IToken.t_long, -1, EMPTY_STRING, -1 ); + IToken t2 = new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ); + t1.setNext( t2 ); + ITokenDuple duple = TokenFactory.createTokenDuple( t1, t2 ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, duple, false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -432,7 +449,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //double __builtin_nans (const char * str) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -447,7 +464,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //float __builtin_nansf (const char * str) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.FLOAT, new SimpleToken( IToken.t_float, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -462,7 +479,11 @@ public class GCCASTCompleteExtension extends GCCASTExtension { try { //long double __builtin_nansl (const char * str) DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IToken t1 = new SimpleToken( IToken.t_long, -1, EMPTY_STRING, -1 ); + IToken t2 = new SimpleToken( IToken.t_double, -1, EMPTY_STRING, -1 ); + t1.setNext( t2 ); + ITokenDuple duple = TokenFactory.createTokenDuple( t1, t2 ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.DOUBLE, duple, false, true, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); Declarator d = new Declarator(sdw); d.setIsFunction( true ); @@ -479,7 +500,11 @@ public class GCCASTCompleteExtension extends GCCASTExtension { //unsigned int DeclarationWrapper param = new DeclarationWrapper( compilationUnit, 0, 0, null, EMPTY_STRING ); try { - param.setTypeSpecifier( factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, true, false, false, false, false, Collections.EMPTY_MAP ) ); + IToken t1 = new SimpleToken( IToken.t_unsigned, -1, EMPTY_STRING, -1 ); + IToken t2 = new SimpleToken( IToken.t_int, -1, EMPTY_STRING, -1 ); + t1.setNext( t2 ); + ITokenDuple duple = TokenFactory.createTokenDuple( t1, t2 ); + param.setTypeSpecifier( factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, duple, false, false, false, true, false, false, false, false, Collections.EMPTY_MAP ) ); param.addDeclarator( new Declarator( param ) ); } catch ( ASTSemanticException e1 ) {//nothing } @@ -492,7 +517,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { sdw.addDeclarator( d ); try { - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_int, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); } catch ( ASTSemanticException e ) { //nothing } @@ -536,7 +561,11 @@ public class GCCASTCompleteExtension extends GCCASTExtension { //unsigned long DeclarationWrapper param = new DeclarationWrapper( compilationUnit, 0, 0, null, EMPTY_STRING ); try { - param.setTypeSpecifier( factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, true, false, true, false, false, false, false, Collections.EMPTY_MAP ) ); + IToken t1 = new SimpleToken( IToken.t_unsigned, -1, EMPTY_STRING, -1 ); + IToken t2 = new SimpleToken( IToken.t_long, -1, EMPTY_STRING, -1 ); + t1.setNext( t2 ); + ITokenDuple duple = TokenFactory.createTokenDuple( t1, t2 ); + param.setTypeSpecifier( factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, duple, false, true, false, true, false, false, false, false, Collections.EMPTY_MAP ) ); param.addDeclarator( new Declarator( param ) ); } catch ( ASTSemanticException e1 ) {//nothing } @@ -549,7 +578,7 @@ public class GCCASTCompleteExtension extends GCCASTExtension { sdw.addDeclarator( d ); try { - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_int, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); } catch ( ASTSemanticException e ) { //nothing } @@ -593,8 +622,16 @@ public class GCCASTCompleteExtension extends GCCASTExtension { //unsigned long long DeclarationWrapper param = new DeclarationWrapper( compilationUnit, 0, 0, null, EMPTY_STRING ); try { - //TODO: this is just a long, we need to make it long long] - IASTSimpleTypeSpecifier spec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, true, false, true, false, false, false, false, Collections.EMPTY_MAP ); + IToken t1 = new SimpleToken( IToken.t_unsigned, -1, EMPTY_STRING, -1 ); + IToken t2 = new SimpleToken( IToken.t_long, -1, EMPTY_STRING, -1 ); + IToken t3 = new SimpleToken( IToken.t_long, -1, EMPTY_STRING, -1 ); + t1.setNext( t2 ); + t2.setNext( t3 ); + ITokenDuple duple = TokenFactory.createTokenDuple( t1, t3 ); + IASTSimpleTypeSpecifier spec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, duple, false, true, false, true, false, false, false, false, Collections.EMPTY_MAP ); + //TODO modify the typeSpec to be long long instead of long, this won't be necessary once we parse long long properly + ((ASTSimpleTypeSpecifier)spec).getSymbol().getTypeInfo().setBit( false, ITypeInfo.isLong ); + ((ASTSimpleTypeSpecifier)spec).getSymbol().getTypeInfo().setBit( true, ITypeInfo.isLongLong ); param.setTypeSpecifier( spec ); param.addDeclarator( new Declarator( param ) ); } catch ( ASTSemanticException e1 ) {//nothing @@ -608,43 +645,63 @@ public class GCCASTCompleteExtension extends GCCASTExtension { sdw.addDeclarator( d ); try { - IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_void, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_int, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); sdw.setTypeSpecifier( typeSpec ); } catch ( ASTSemanticException e ) { //nothing } - try {//int __builtin_ffsll(unsigned int x) + try {//int __builtin_ffsll(unsigned long long x) d.setName( new ImagedToken( IToken.tIDENTIFIER, __BUILTIN_FFSLL, __BUILTIN_FFSLL.length, EMPTY_STRING, 0 ) ); sdw.createASTNodes( factory ); } catch ( ASTSemanticException e2 ) { //nothing } catch ( BacktrackException e2 ) {//nothing } - try {//int __builtin_clsll(unsigned int x) + try {//int __builtin_clsll(unsigned long long x) d.setName( new ImagedToken( IToken.tIDENTIFIER, __BUILTIN_CLZLL, __BUILTIN_CLZLL.length, EMPTY_STRING, 0 ) ); sdw.createASTNodes( factory ); } catch ( ASTSemanticException e2 ) {//nothing } catch ( BacktrackException e2 ) {//nothing } - try {//int __builtin_ctzll(unsigned int x) + try {//int __builtin_ctzll(unsigned long long x) d.setName( new ImagedToken( IToken.tIDENTIFIER, __BUILTIN_CTZLL, __BUILTIN_CTZLL.length, EMPTY_STRING, 0 ) ); sdw.createASTNodes( factory ); } catch ( ASTSemanticException e2 ) {//nothing } catch ( BacktrackException e2 ) {//nothing } - try {//int __builtin_popcountll(unsigned int x) + try {//int __builtin_popcountll(unsigned long long x) d.setName( new ImagedToken( IToken.tIDENTIFIER, __BUILTIN_POPCOUNTLL, __BUILTIN_POPCOUNTLL.length, EMPTY_STRING, 0 ) ); sdw.createASTNodes( factory ); } catch ( ASTSemanticException e2 ) {//nothing } catch ( BacktrackException e2 ) {//nothing } - try {//int __builtin_parityll(unsigned int x) + try {//int __builtin_parityll(unsigned long long x) d.setName( new ImagedToken( IToken.tIDENTIFIER, __BUILTIN_PARITYLL, __BUILTIN_PARITYLL.length, EMPTY_STRING, 0 ) ); sdw.createASTNodes( factory ); } catch ( ASTSemanticException e2 ) {//nothing } catch ( BacktrackException e2 ) {//nothing } } + private void __builtin_types_compatible_p( IASTFactory factory, IASTCompilationUnit compilationUnit ) { + DeclarationWrapper sdw = new DeclarationWrapper(compilationUnit, 0, 0, null, EMPTY_STRING ); + Declarator d = new Declarator(sdw); + d.setIsFunction( true ); + d.setIsVarArgs( true ); + sdw.addDeclarator( d ); + + try { + IASTSimpleTypeSpecifier typeSpec = factory.createSimpleTypeSpecifier( compilationUnit, IASTSimpleTypeSpecifier.Type.INT, new SimpleToken( IToken.t_int, -1, EMPTY_STRING, -1 ), false, false, false, false, false, false, false, false, Collections.EMPTY_MAP ); + sdw.setTypeSpecifier( typeSpec ); + } catch ( ASTSemanticException e ) { //nothing + } + + try {//int __builtin_types_compatible_p( type1, type2 ) implemented via ( ... ) + d.setName( new ImagedToken( IToken.tIDENTIFIER, __BUILTIN_TYPES_COMPATIBLE_P, __BUILTIN_TYPES_COMPATIBLE_P.length, EMPTY_STRING, 0 ) ); + sdw.createASTNodes( factory ); + } catch ( ASTSemanticException e2 ) { //nothing + } catch ( BacktrackException e2 ) {//nothing + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DynamicFunctionStyleMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DynamicFunctionStyleMacro.java new file mode 100644 index 00000000000..87876c410ad --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/DynamicFunctionStyleMacro.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Oct 5, 2004 + */ +package org.eclipse.cdt.internal.core.parser.scanner2; + +import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; + +/** + * @author aniefer + */ +abstract public class DynamicFunctionStyleMacro extends FunctionStyleMacro { + + public DynamicFunctionStyleMacro( char[] name, char[][] arglist ) { + super( name, "".toCharArray(), arglist ); //$NON-NLS-1$ + } + + public abstract char [] execute( CharArrayObjectMap argmap ); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ExpressionEvaluator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ExpressionEvaluator.java index b1757d068ba..69df17a94cf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ExpressionEvaluator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ExpressionEvaluator.java @@ -33,7 +33,7 @@ public class ExpressionEvaluator { public long evaluate(char[] buffer, int pos, int length, CharArrayObjectMap defs) { bufferStack[++bufferStackPos] = buffer; - bufferPos[bufferStackPos] = pos; + bufferPos[bufferStackPos] = pos - 1; bufferLimit[bufferStackPos] = pos + length; this.definitions = defs; tokenType = 0; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/GCCScannerExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/GCCScannerExtension.java index a98b4574e7a..8c962bc3e37 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/GCCScannerExtension.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/GCCScannerExtension.java @@ -17,6 +17,7 @@ import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.extension.IScannerExtension; import org.eclipse.cdt.core.parser.util.CharArrayIntMap; +import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.internal.core.parser.token.ImagedToken; /** @@ -95,6 +96,30 @@ public class GCCScannerExtension implements IScannerExtension { "__builtin_va_arg".toCharArray(), //$NON-NLS-1$ "*(type *)ap".toCharArray(), //$NON-NLS-1$ new char[][] { "ap".toCharArray(), "type".toCharArray() } ); //$NON-NLS-1$//$NON-NLS-2$ + + private static final FunctionStyleMacro __builtin_constant_p + = new FunctionStyleMacro( + "__builtin_constant_p".toCharArray(), //$NON-NLS-1$ + "0".toCharArray(), //$NON-NLS-1$ + new char[][] {"exp".toCharArray()} ); //$NON-NLS-1$//$NON-NLS-2$ + + private final DynamicFunctionStyleMacro __builtin_choose_expr = + new DynamicFunctionStyleMacro( "__builtin_choose_expr".toCharArray(), //$NON-NLS-1$ + new char[][] { "const_exp".toCharArray(), "exp1".toCharArray(), "exp2".toCharArray() } ) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + { + public char [] execute( CharArrayObjectMap argmap ){ + ExpressionEvaluator evaluator = new ExpressionEvaluator(); + char[] const_exp = (char[]) argmap.get( arglist[0] ); + long exp = 0; + if( const_exp != null) + exp = evaluator.evaluate( const_exp, 0, const_exp.length, CharArrayObjectMap.EMPTY_MAP ); + + if( exp != 0 ) + return (char[])argmap.get( arglist[1] ); + return (char[])argmap.get( arglist[2] ); + } + }; + /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IScannerExtension#setupBuiltInMacros() */ @@ -115,10 +140,13 @@ public class GCCScannerExtension implements IScannerExtension { scannerData.getRealDefinitions().put(__imag__.name, __imag__ ); scannerData.getRealDefinitions().put(__real__.name, __real__ ); scannerData.getRealDefinitions().put( __builtin_va_arg.name, __builtin_va_arg ); + scannerData.getRealDefinitions().put( __builtin_constant_p.name, __builtin_constant_p ); if( scannerData.getLanguage() == ParserLanguage.CPP ) scannerData.getRealDefinitions().put(__asm__.name, __asm__); - else + else{ scannerData.getRealDefinitions().put(_Pragma.name, _Pragma ); + scannerData.getRealDefinitions().put( __builtin_choose_expr.name, __builtin_choose_expr ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java index 6aa05ca39a1..c0266786f10 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java @@ -1432,7 +1432,7 @@ public class Scanner2 implements IScanner, IScannerData { handlePPIfdef(false); return; case ppIf: - start = bufferPos[bufferStackPos]; + start = bufferPos[bufferStackPos] + 1; skipToNewLine(); len = bufferPos[bufferStackPos] - start; if( isLimitReached() ) @@ -2036,7 +2036,7 @@ public class Scanner2 implements IScanner, IScannerData { if( branchState( BRANCH_ELIF ) ){ if (checkelse && nesting == 0) { // check the condition - start = bufferPos[bufferStackPos]; + start = bufferPos[bufferStackPos] + 1; skipToNewLine(); len = bufferPos[bufferStackPos] - start; if (expressionEvaluator.evaluate(buffer, start, len, definitions) != 0) @@ -2490,9 +2490,14 @@ public class Scanner2 implements IScanner, IScannerData { handleProblem( IProblem.PREPROCESSOR_MACRO_USAGE_ERROR, bufferPos[bufferStackPos], macro.name ); } - int size = expandFunctionStyleMacro(macro.expansion, argmap, null); - char[] result = new char[size]; - expandFunctionStyleMacro(macro.expansion, argmap, result); + char[] result = null; + if( macro instanceof DynamicFunctionStyleMacro ){ + result = ((DynamicFunctionStyleMacro)macro).execute( argmap ); + } else { + int size = expandFunctionStyleMacro(macro.expansion, argmap, null); + result = new char[size]; + expandFunctionStyleMacro(macro.expansion, argmap, result); + } if( pushContext ) pushContext(result, new MacroData( start, bufferPos[bufferStackPos], macro ) ); return result;