1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Devin (the maniac) Steffler.

Fixed Bug 102376 	Parser Errors in DOM with mingw
This commit is contained in:
John Camelon 2005-07-15 14:08:16 +00:00
parent 57ed8aa474
commit 756a6b3a51
22 changed files with 433 additions and 27 deletions

View file

@ -106,6 +106,24 @@ public class GCCQuickParseExtensionsTest extends BaseASTTest {
assertEquals( f.getName(), "func2"); //$NON-NLS-1$ assertEquals( f.getName(), "func2"); //$NON-NLS-1$
} }
public void testBug39704E() throws Exception
{
IASTVariable d = (IASTVariable)assertSoleDeclaration("extern int * __attribute__((dllimport)) (* import) (void);"); //$NON-NLS-1$
assertEquals( d.getName(), "import"); // false assertion //$NON-NLS-1$
}
public void testBug39704F() throws Exception
{
IASTVariable d = (IASTVariable)assertSoleDeclaration("extern int __attribute__((dllimport)) (* import) (void);"); //$NON-NLS-1$
assertEquals( d.getName(), "import"); // false assertion //$NON-NLS-1$
}
public void testBug39704G() throws Exception
{
IASTVariable d = (IASTVariable)assertSoleDeclaration("int x __attribute__ ((aligned (16))) = 0;"); //$NON-NLS-1$
assertEquals( d.getName(), "x"); // false assertion //$NON-NLS-1$
}
public void testBug39686() throws Exception public void testBug39686() throws Exception
{ {
Writer code = new StringWriter(); Writer code = new StringWriter();

View file

@ -2162,7 +2162,109 @@ public class CompleteParser2Tests extends TestCase {
public void testPredefinedSymbol_bug70928() throws Exception { public void testPredefinedSymbol_bug70928() throws Exception {
// GNU builtin storage class type __cdecl preceded by a custom return type // GNU builtin storage class type __cdecl preceded by a custom return type
parse("typedef int size_t; \n int __cdecl foo(); \n");//$NON-NLS-1$ Writer writer = new StringWriter();
writer.write( "#define __cdecl __attribute__ ((__cdecl__))\n" ); //$NON-NLS-1$
writer.write( "typedef int size_t; \n int __cdecl foo(); \n" ); //$NON-NLS-1$
parse(writer.toString(), true, ParserLanguage.CPP, true);//$NON-NLS-1$
}
public void testPredefinedSymbol_bug70928_infinite_loop_test1() throws Exception {
// GNU builtin storage class type __cdecl preceded by a custom return type
Writer writer = new StringWriter();
writer.write( "#define __cdecl __attribute__ ((__cdecl__))\n" ); //$NON-NLS-1$
writer.write( "typedef int size_t; \n int __cdecl foo(); \n" ); //$NON-NLS-1$
parse(writer.toString(), false, ParserLanguage.CPP, false);//$NON-NLS-1$ // test for an infinite loop if the GCC extensions aren't supported
parse(writer.toString(), false, ParserLanguage.C, false);//$NON-NLS-1$ // test for an infinite loop if the GCC extensions aren't supported
}
public void testPredefinedSymbol_bug70928_infinite_loop_test2() throws Exception {
// GNU builtin storage class type __cdecl preceded by a custom return type
Writer writer = new StringWriter();
writer.write( "int x __attribute__ ((aligned (16))) = 0;\n" ); //$NON-NLS-1$
parse(writer.toString(), false, ParserLanguage.CPP, false);//$NON-NLS-1$ // test for an infinite loop if the GCC extensions aren't supported
parse(writer.toString(), false, ParserLanguage.C, false);//$NON-NLS-1$ // test for an infinite loop if the GCC extensions aren't supported
}
public void testBug102376() throws Exception {
Writer writer = new StringWriter();
writer.write( "int func1 (void) __attribute__((,id2,id (,,),,,));\n" ); //$NON-NLS-1$
writer.write( "int func2 (void) __attribute__((id,id (id)));\n" ); //$NON-NLS-1$
writer.write( "int func3 (void) __attribute__((id,id (3)));\n" ); //$NON-NLS-1$
writer.write( "int func4 (void) __attribute__((id,id (1+2)));\n" ); //$NON-NLS-1$
writer.write( "void (****f1)(void) __attribute__((noreturn));\n" ); //$NON-NLS-1$
/* not yet supported by the GCC compiler:
* writer.write( "void (__attribute__((noreturn)) ****f2) (void);\n" ); //$NON-NLS-1$
* writer.write( "char *__attribute__((aligned(8))) *f3;\n" ); //$NON-NLS-1$
* writer.write( "char * __attribute__((aligned(8))) * f3;\n" ); //$NON-NLS-1$
*/ writer.write( "void fatal1 () __attribute__ ((noreturn));\n" ); //$NON-NLS-1$
writer.write( "int square1 (int) __attribute__ ((pure));\n" ); //$NON-NLS-1$
writer.write( "extern int\n" ); //$NON-NLS-1$
writer.write( "my_printf1 (void *my_object, const char *my_format, ...)\n" ); //$NON-NLS-1$
writer.write( "__attribute__ ((format (printf, 2, 3)));\n" ); //$NON-NLS-1$
writer.write( "extern char *\n" ); //$NON-NLS-1$
writer.write( "my_dgettext1 (char *my_domain, const char *my_format)\n" ); //$NON-NLS-1$
writer.write( "__attribute__ ((format_arg (2)));\n" ); //$NON-NLS-1$
writer.write( "extern void *\n" ); //$NON-NLS-1$
writer.write( "my_memcpy1 (void *dest, const void *src, size_t len)\n" ); //$NON-NLS-1$
writer.write( "__attribute__((nonnull (1, 2)));\n" ); //$NON-NLS-1$
writer.write( "extern void *\n" ); //$NON-NLS-1$
writer.write( "my_memcpy2 (void *dest, const void *src, size_t len)\n" ); //$NON-NLS-1$
writer.write( "__attribute__((nonnull));\n" ); //$NON-NLS-1$
writer.write( "extern void foobar3 (void) __attribute__ ((section (\"bar\")));\n" ); //$NON-NLS-1$
writer.write( "int old_fn () __attribute__ ((deprecated));\n" ); //$NON-NLS-1$
writer.write( "void f5 () __attribute__ ((weak, alias (\"__f\")));\n" ); //$NON-NLS-1$
writer.write( "void __attribute__ ((visibility (\"protected\")))\n" ); //$NON-NLS-1$
writer.write( "f6 () { /* Do something. */; }\n" ); //$NON-NLS-1$
writer.write( "int i2 __attribute__ ((visibility (\"hidden\")));\n" ); //$NON-NLS-1$
writer.write( "void f7 () __attribute__ ((interrupt (\"IRQ\")));\n" ); //$NON-NLS-1$
writer.write( "void *alt_stack9;\n" ); //$NON-NLS-1$
writer.write( "void f8 () __attribute__ ((interrupt_handler,\n" ); //$NON-NLS-1$
writer.write( "sp_switch (\"alt_stack\")));\n" ); //$NON-NLS-1$
writer.write( "int x1 __attribute__ ((aligned (16))) = 0;\n" ); //$NON-NLS-1$
writer.write( "struct foo11 { int x[2] __attribute__ ((aligned (8))); };\n" ); //$NON-NLS-1$
writer.write( "short array12[3] __attribute__ ((aligned));\n" ); //$NON-NLS-1$
writer.write( "extern int old_var14 __attribute__ ((deprecated));\n" ); //$NON-NLS-1$
writer.write( "struct foo13\n" ); //$NON-NLS-1$
writer.write( "{\n" ); //$NON-NLS-1$
writer.write( "char a15;\n" ); //$NON-NLS-1$
writer.write( "int x16[2] __attribute__ ((packed));\n" ); //$NON-NLS-1$
writer.write( "};\n" ); //$NON-NLS-1$
writer.write( "struct duart15 a16 __attribute__ ((section (\"DUART_A\"))) = { 0 };\n" ); //$NON-NLS-1$
writer.write( "struct duart15 b17 __attribute__ ((section (\"DUART_B\"))) = { 0 };\n" ); //$NON-NLS-1$
writer.write( "char stack18[10000] __attribute__ ((section (\"STACK\"))) = { 0 };\n" ); //$NON-NLS-1$
writer.write( "int init_data19 __attribute__ ((section (\"INITDATA\"))) = 0;\n" ); //$NON-NLS-1$
writer.write( "int foo20 __attribute__((section (\"shared\"), shared)) = 0;\n" ); //$NON-NLS-1$
writer.write( "int foo21 __attribute__ ((vector_size (16)));\n" ); //$NON-NLS-1$
writer.write( "struct S22 { int a23; };\n" ); //$NON-NLS-1$
writer.write( "struct S24 __attribute__ ((vector_size (16))) foo;\n" ); //$NON-NLS-1$
writer.write( "struct S25 { short f27[3]; } __attribute__ ((aligned (8)));\n" ); //$NON-NLS-1$
writer.write( "typedef int more_aligned_int __attribute__ ((aligned (8)));\n" ); //$NON-NLS-1$
writer.write( "struct S26 { short f28[3]; } __attribute__ ((aligned));\n" ); //$NON-NLS-1$
writer.write( "\n" ); //$NON-NLS-1$
writer.write( "struct my_unpacked_struct29\n" ); //$NON-NLS-1$
writer.write( "{\n" ); //$NON-NLS-1$
writer.write( "char c;\n" ); //$NON-NLS-1$
writer.write( "int i;\n" ); //$NON-NLS-1$
writer.write( "};\n" ); //$NON-NLS-1$
writer.write( " \n" ); //$NON-NLS-1$
writer.write( "struct my_packed_struct __attribute__ ((__packed__))\n" ); //$NON-NLS-1$
writer.write( "{\n" ); //$NON-NLS-1$
writer.write( "char c;\n" ); //$NON-NLS-1$
writer.write( "int i;\n" ); //$NON-NLS-1$
writer.write( "struct my_unpacked_struct29 s;\n" ); //$NON-NLS-1$
writer.write( "};\n" ); //$NON-NLS-1$
writer.write( "\n" ); //$NON-NLS-1$
writer.write( "typedef union\n" ); //$NON-NLS-1$
writer.write( "{\n" ); //$NON-NLS-1$
writer.write( "int *__ip;\n" ); //$NON-NLS-1$
writer.write( "union wait *__up;\n" ); //$NON-NLS-1$
writer.write( "} wait_status_ptr_t __attribute__ ((__transparent_union__));\n" ); //$NON-NLS-1$
writer.write( "\n" ); //$NON-NLS-1$
writer.write( "typedef int T1 __attribute__ ((deprecated));\n" ); //$NON-NLS-1$
writer.write( "typedef short __attribute__((__may_alias__)) short_a;\n" ); //$NON-NLS-1$
writer.write( "extern const unsigned short int ** __ctype_b_loc (void) __attribute__ ((__const));" ); //$NON-NLS-1$
parse( writer.toString(), true, ParserLanguage.C, true );
parse( writer.toString(), true, ParserLanguage.CPP, true );
} }
public void testBug73652() throws Exception public void testBug73652() throws Exception

View file

@ -222,16 +222,17 @@ public class DOMLocationMacroTests extends AST2BaseTest {
public void testStdioBug() throws ParserException public void testStdioBug() throws ParserException
{ {
StringBuffer buffer = new StringBuffer( "#define _PTR void *\n"); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer( "#define _PTR void *\n"); //$NON-NLS-1$
buffer.append( "#define __cdecl __attribute__ ((__cdecl__))\n" ); //$NON-NLS-1$
buffer.append( "#define _EXFUN(name, proto) __cdecl name proto\n"); //$NON-NLS-1$ buffer.append( "#define _EXFUN(name, proto) __cdecl name proto\n"); //$NON-NLS-1$
buffer.append( "_PTR _EXFUN(memchr,(const _PTR, int, size_t));\n"); //$NON-NLS-1$ buffer.append( "_PTR _EXFUN(memchr,(const _PTR, int, size_t));\n"); //$NON-NLS-1$
String code = buffer.toString(); String code = buffer.toString();
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) { : null) {
IASTTranslationUnit tu = parse(code, p); IASTTranslationUnit tu = parse(code, p, true, true);
final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions(); final IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
IASTPreprocessorObjectStyleMacroDefinition _PTR = (IASTPreprocessorObjectStyleMacroDefinition) macroDefinitions[0]; IASTPreprocessorObjectStyleMacroDefinition _PTR = (IASTPreprocessorObjectStyleMacroDefinition) macroDefinitions[0];
IASTPreprocessorFunctionStyleMacroDefinition _EXFUN = (IASTPreprocessorFunctionStyleMacroDefinition) macroDefinitions[1]; IASTPreprocessorFunctionStyleMacroDefinition _EXFUN = (IASTPreprocessorFunctionStyleMacroDefinition) macroDefinitions[2];
IASTSimpleDeclaration memchr = (IASTSimpleDeclaration) tu.getDeclarations()[0]; IASTSimpleDeclaration memchr = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTNodeLocation [] locations = memchr.getNodeLocations(); IASTNodeLocation [] locations = memchr.getNodeLocations();
assertEquals( locations.length, 4 ); assertEquals( locations.length, 4 );

View file

@ -1459,11 +1459,17 @@ public class QuickParser2Tests extends TestCase {
} }
public void testBug39704A() throws Exception { public void testBug39704A() throws Exception {
parse("__declspec (dllimport) int foo;"); //$NON-NLS-1$ StringWriter writer = new StringWriter();
writer.write("#define __declspec(x) __attribute__((x))"); //$NON-NLS-1$
writer.write("__declspec (dllimport) int foo;"); //$NON-NLS-1$
parse( writer.toString() );
} }
public void testBug39704D() throws Exception { public void testBug39704D() throws Exception {
parse("__declspec(dllexport) int func1 (int a) {}"); //$NON-NLS-1$ StringWriter writer = new StringWriter();
writer.write("#define __declspec(x) __attribute__((x))"); //$NON-NLS-1$
writer.write("__declspec(dllexport) int func1 (int a) {}"); //$NON-NLS-1$
parse( writer.toString() );
} }
public void testBug39695() throws Exception { public void testBug39695() throws Exception {

View file

@ -42,6 +42,12 @@ public class GCCScannerExtensionsTest extends BaseScanner2Test {
initializeScanner( initializeScanner(
"#define __cdecl __attribute__((cdecl))\n" + //$NON-NLS-1$ "#define __cdecl __attribute__((cdecl))\n" + //$NON-NLS-1$
"__cdecl;"); //$NON-NLS-1$ "__cdecl;"); //$NON-NLS-1$
validateToken(IGCCToken.t__attribute__);
validateToken(IToken.tLPAREN);
validateToken(IToken.tLPAREN);
validateToken(IToken.tIDENTIFIER);
validateToken(IToken.tRPAREN);
validateToken(IToken.tRPAREN);
validateToken(IToken.tSEMI); validateToken(IToken.tSEMI);
validateEOF(); validateEOF();
} }

View file

@ -19,8 +19,10 @@ public class GCCKeywords {
public static final String TYPEOF = "typeof"; //$NON-NLS-1$ public static final String TYPEOF = "typeof"; //$NON-NLS-1$
public static final String __ALIGNOF__ = "__alignof__"; //$NON-NLS-1$ public static final String __ALIGNOF__ = "__alignof__"; //$NON-NLS-1$
public static final String __ATTRIBUTE__ = "__attribute__"; //$NON-NLS-1$
public static final char [] cpTYPEOF = TYPEOF.toCharArray(); public static final char [] cpTYPEOF = TYPEOF.toCharArray();
public static final char [] cp__ALIGNOF__ = __ALIGNOF__.toCharArray(); public static final char [] cp__ALIGNOF__ = __ALIGNOF__.toCharArray();
public static final char [] cp__ATTRIBUTE__ = __ATTRIBUTE__.toCharArray();
} }

View file

@ -21,5 +21,6 @@ public interface IGCCToken extends IToken {
public static final int t___alignof__ = tLAST + 2; public static final int t___alignof__ = tLAST + 2;
public static final int tMAX = tLAST + 3; public static final int tMAX = tLAST + 3;
public static final int tMIN = tLAST + 4; public static final int tMIN = tLAST + 4;
public static final int t__attribute__ = tLAST + 5;
} }

View file

@ -24,8 +24,8 @@ import org.eclipse.cdt.internal.core.parser.QuickParseCallback;
import org.eclipse.cdt.internal.core.parser.StructuralParseCallback; import org.eclipse.cdt.internal.core.parser.StructuralParseCallback;
import org.eclipse.cdt.internal.core.parser.ast.complete.CompleteParseASTFactory; import org.eclipse.cdt.internal.core.parser.ast.complete.CompleteParseASTFactory;
import org.eclipse.cdt.internal.core.parser.ast.quick.QuickParseASTFactory; import org.eclipse.cdt.internal.core.parser.ast.quick.QuickParseASTFactory;
import org.eclipse.cdt.internal.core.parser.scanner2.GCCScannerExtensionConfiguration; import org.eclipse.cdt.internal.core.parser.scanner2.GCCOldScannerExtensionConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerExtensionConfiguration; import org.eclipse.cdt.internal.core.parser.scanner2.GPPOldScannerExtensionConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerExtensionConfiguration; import org.eclipse.cdt.internal.core.parser.scanner2.IScannerExtensionConfiguration;
import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2; import org.eclipse.cdt.internal.core.parser.scanner2.Scanner2;
import org.eclipse.cdt.internal.core.parser.token.KeywordSets; import org.eclipse.cdt.internal.core.parser.token.KeywordSets;
@ -89,9 +89,9 @@ public class ParserFactory {
ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor ); ISourceElementRequestor ourRequestor = (( requestor == null) ? new NullSourceElementRequestor() : requestor );
IScannerExtensionConfiguration configuration = null; IScannerExtensionConfiguration configuration = null;
if( language == ParserLanguage.C ) if( language == ParserLanguage.C )
configuration = new GCCScannerExtensionConfiguration(); configuration = new GCCOldScannerExtensionConfiguration();
else else
configuration = new GPPScannerExtensionConfiguration(); configuration = new GPPOldScannerExtensionConfiguration();
return new Scanner2( code, config, ourRequestor, ourMode, language, logService, workingCopies, configuration ); return new Scanner2( code, config, ourRequestor, ourMode, language, logService, workingCopies, configuration );
} }

View file

@ -87,12 +87,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected final boolean supportKnRC; protected final boolean supportKnRC;
protected final boolean supportGCCOtherBuiltinSymbols; protected final boolean supportGCCOtherBuiltinSymbols;
protected final boolean supportAttributeSpecifiers;
protected AbstractGNUSourceCodeParser(IScanner scanner, protected AbstractGNUSourceCodeParser(IScanner scanner,
IParserLogService logService, ParserMode parserMode, IParserLogService logService, ParserMode parserMode,
boolean supportStatementsInExpressions, boolean supportStatementsInExpressions,
boolean supportTypeOfUnaries, boolean supportAlignOfUnaries, boolean supportTypeOfUnaries, boolean supportAlignOfUnaries,
boolean supportKnRC, boolean supportGCCOtherBuiltinSymbols) { boolean supportKnRC, boolean supportGCCOtherBuiltinSymbols,
boolean supportAttributeSpecifiers) {
this.scanner = scanner; this.scanner = scanner;
this.log = logService; this.log = logService;
this.mode = parserMode; this.mode = parserMode;
@ -101,6 +104,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
this.supportAlignOfUnaries = supportAlignOfUnaries; this.supportAlignOfUnaries = supportAlignOfUnaries;
this.supportKnRC = supportKnRC; this.supportKnRC = supportKnRC;
this.supportGCCOtherBuiltinSymbols = supportGCCOtherBuiltinSymbols; this.supportGCCOtherBuiltinSymbols = supportGCCOtherBuiltinSymbols;
this.supportAttributeSpecifiers = supportAttributeSpecifiers;
} }
protected boolean parsePassed = true; protected boolean parsePassed = true;
@ -2125,4 +2129,88 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return parseDeclarationOrExpressionStatement(); return parseDeclarationOrExpressionStatement();
} }
protected void __attribute__() throws BacktrackException, EndOfFileException {
IToken token = LA(1);
if (token.getType() == IGCCToken.t__attribute__) {
consume();
token = LA(1);
if (token.getType() == IToken.tLPAREN) {
consume();
while(true) {
token = LA(1);
switch(token.getType()) {
case IToken.tLPAREN:
consume();
boolean ident=false;
boolean comma1=false;
boolean first=true;
whileLoop: while(true) {
token = LA(1);
switch(token.getType()) {
case IToken.tIDENTIFIER:
if (comma1 || first) {
ident=true;
first=false;
} else {
throwBacktrack(token.getOffset(), token.getLength());
}
consume();
break;
case IToken.tLPAREN:
consume();
if (ident) {
token = LA(1);
// consume the parameters
whileLoop2: while(true) {
try {
expression();
} catch (BacktrackException be) {
switch(LT(1)) {
case IToken.tCOMMA:
consume();
break;
case IToken.tRPAREN:
consume();
break whileLoop2;
default:
throwBacktrack(be);
}
}
}
} else {
throwBacktrack(token.getOffset(), token.getLength()); // can't have __attribute((()))
}
break;
case IToken.tRPAREN:
consume();
break whileLoop;
case IToken.tCOMMA:
if (ident) {
ident=false;
comma1=true;
}
consume();
break;
case IToken.t_const:
consume();
break;
default:
throwBacktrack(token.getOffset(), token.getLength());
break;
}
}
break;
case IToken.tRPAREN: // finished
consume();
return;
default:
throwBacktrack(token.getOffset(), token.getLength());
}
}
}
}
}
} }

View file

@ -58,4 +58,11 @@ public class ANSICParserExtensionConfiguration implements
return false; return false;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser2.c.ICParserExtensionConfiguration#supportAttributeSpecifiers()
*/
public boolean supportAttributeSpecifiers() {
return false;
}
} }

View file

@ -58,4 +58,11 @@ public class GCCParserExtensionConfiguration implements
return true; return true;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser2.c.ICParserExtensionConfiguration#supportAttributeSpecifiers()
*/
public boolean supportAttributeSpecifiers() {
return true;
}
} }

View file

@ -135,7 +135,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
.supportStatementsInExpressions(), config .supportStatementsInExpressions(), config
.supportTypeofUnaryExpressions(), config .supportTypeofUnaryExpressions(), config
.supportAlignOfUnaryExpression(), config .supportAlignOfUnaryExpression(), config
.supportKnRC(), config.supportGCCOtherBuiltinSymbols()); .supportKnRC(), config.supportGCCOtherBuiltinSymbols(),
config.supportAttributeSpecifiers());
supportGCCStyleDesignators = config.supportGCCStyleDesignators(); supportGCCStyleDesignators = config.supportGCCStyleDesignators();
} }
@ -1324,6 +1325,10 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
protected void consumePointerOperators(List pointerOps) protected void consumePointerOperators(List pointerOps)
throws EndOfFileException, BacktrackException { throws EndOfFileException, BacktrackException {
for (;;) { for (;;) {
// having __attribute__ inbetween pointers is not yet supported by the GCC compiler
// if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after a *
// __attribute__();
IToken mark = mark(); IToken mark = mark();
IToken last = null; IToken last = null;
@ -1578,6 +1583,12 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
flags.setEncounteredTypename(true); flags.setEncounteredTypename(true);
break; break;
} }
case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec
if (supportAttributeSpecifiers)
__attribute__();
else
throwBacktrack(LA(1).getOffset(), LA(1).getLength());
break;
default: default:
if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) { if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) {
typeofExpression = unaryTypeofExpression(); typeofExpression = unaryTypeofExpression();
@ -1734,6 +1745,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
nameToken = identifier(); nameToken = identifier();
} }
if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ occurs after struct/union/class identifier and before the { or ;
__attribute__();
if (LT(1) != IToken.tLBRACE) { if (LT(1) != IToken.tLBRACE) {
IToken errorPoint = LA(1); IToken errorPoint = LA(1);
backup(mark); backup(mark);
@ -1876,6 +1890,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
overallLoop: do { overallLoop: do {
consumePointerOperators(pointerOps); consumePointerOperators(pointerOps);
// if __attribute__ is after the pointer ops and before the declarator ex: void * __attribute__((__cdecl__)) foo();
if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters
__attribute__();
if (!pointerOps.isEmpty()) { if (!pointerOps.isEmpty()) {
finalOffset = calculateEndOffset((IASTPointerOperator) pointerOps finalOffset = calculateEndOffset((IASTPointerOperator) pointerOps
.get(pointerOps.size() - 1)); .get(pointerOps.size() - 1));
@ -2035,6 +2054,13 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.tCOLON); consume(IToken.tCOLON);
bitField = constantExpression(); bitField = constantExpression();
finalOffset = calculateEndOffset(bitField); finalOffset = calculateEndOffset(bitField);
break;
case IGCCToken.t__attribute__: // if __attribute__ is after the declarator
if(supportAttributeSpecifiers)
__attribute__();
else
throwBacktrack(LA(1).getOffset(), LA(1).getLength());
break;
default: default:
break; break;
} }
@ -2043,6 +2069,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
} while (false); } while (false);
if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters
__attribute__();
IASTDeclarator d = null; IASTDeclarator d = null;
if (numKnRCParms > 0) { if (numKnRCParms > 0) {
ICASTKnRFunctionDeclarator functionDecltor = createKnRFunctionDeclarator(); ICASTKnRFunctionDeclarator functionDecltor = createKnRFunctionDeclarator();

View file

@ -27,5 +27,12 @@ public interface ICParserExtensionConfiguration {
* @return * @return
*/ */
public boolean supportGCCOtherBuiltinSymbols(); public boolean supportGCCOtherBuiltinSymbols();
/**
* See http://gcc.gnu.org/onlinedocs/gcc-3.4.4/gcc/Attribute-Syntax.html#Attribute-Syntax
* for more information on GCC's Attribute Specifiers.
* @return
*/
public boolean supportAttributeSpecifiers();
} }

View file

@ -93,4 +93,11 @@ public class ANSICPPParserExtensionConfiguration implements
return false; return false;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser2.cpp.ICPPParserExtensionConfiguration#supportAttributeSpecifiers()
*/
public boolean supportAttributeSpecifiers() {
return false;
}
} }

View file

@ -535,6 +535,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
throws EndOfFileException, BacktrackException { throws EndOfFileException, BacktrackException {
for (;;) { for (;;) {
// having __attribute__ inbetween pointers is not yet supported by the GCC compiler
// if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after a *
// __attribute__();
if (LT(1) == IToken.tAMPER) { if (LT(1) == IToken.tAMPER) {
int length = LA(1).getEndOffset() - LA(1).getOffset(); int length = LA(1).getEndOffset() - LA(1).getOffset();
int o = consume(IToken.tAMPER).getOffset(); int o = consume(IToken.tAMPER).getOffset();
@ -1965,7 +1969,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
super(scanner, log, mode, config.supportStatementsInExpressions(), super(scanner, log, mode, config.supportStatementsInExpressions(),
config.supportTypeofUnaryExpressions(), config config.supportTypeofUnaryExpressions(), config
.supportAlignOfUnaryExpression(), config.supportKnRC(), .supportAlignOfUnaryExpression(), config.supportKnRC(),
config.supportGCCOtherBuiltinSymbols()); config.supportGCCOtherBuiltinSymbols(), config.supportAttributeSpecifiers());
allowCPPRestrict = config.allowRestrictPointerOperators(); allowCPPRestrict = config.allowRestrictPointerOperators();
supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax(); supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax();
supportMinAndMaxOperators = config.supportMinAndMaxOperators(); supportMinAndMaxOperators = config.supportMinAndMaxOperators();
@ -3456,6 +3460,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
flags.setEncounteredTypename(true); flags.setEncounteredTypename(true);
break; break;
} }
case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec
if (supportAttributeSpecifiers)
__attribute__();
else
throwBacktrack(LA(1).getOffset(), LA(1).getLength());
break;
default: default:
if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) { if (supportTypeOfUnaries && LT(1) == IGCCToken.t_typeof) {
typeofExpression = unaryTypeofExpression(); typeofExpression = unaryTypeofExpression();
@ -3833,6 +3843,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
overallLoop: do { overallLoop: do {
consumePointerOperators(pointerOps); consumePointerOperators(pointerOps);
// if __attribute__ is after the pointer ops and before the declarator ex: void * __attribute__((__cdecl__)) foo();
if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters
__attribute__();
if (!pointerOps.isEmpty()) if (!pointerOps.isEmpty())
finalOffset = calculateEndOffset((IASTNode) pointerOps finalOffset = calculateEndOffset((IASTNode) pointerOps
.get(pointerOps.size() - 1)); .get(pointerOps.size() - 1));
@ -3945,6 +3960,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
tryEncountered = true; tryEncountered = true;
break overallLoop; break overallLoop;
} }
if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ is after the parameters
__attribute__();
IToken beforeCVModifier = mark(); IToken beforeCVModifier = mark();
IToken[] cvModifiers = new IToken[2]; IToken[] cvModifiers = new IToken[2];
@ -4044,6 +4062,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
bitField = constantExpression(); bitField = constantExpression();
finalOffset = calculateEndOffset(bitField); finalOffset = calculateEndOffset(bitField);
break; break;
case IGCCToken.t__attribute__: // if __attribute__ is after the declarator
if(supportAttributeSpecifiers)
__attribute__();
else
throwBacktrack(LA(1).getOffset(), LA(1).getLength());
break;
default: default:
break; break;
} }
@ -4253,6 +4277,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
name = createName(name()); name = createName(name());
else else
name = createName(); name = createName();
if (LT(1) == IGCCToken.t__attribute__ && supportAttributeSpecifiers) // if __attribute__ occurs after struct/union/class identifier and before the { or ;
__attribute__();
if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) { if (LT(1) != IToken.tCOLON && LT(1) != IToken.tLBRACE) {
IToken errorPoint = LA(1); IToken errorPoint = LA(1);

View file

@ -93,4 +93,11 @@ public class GPPParserExtensionConfiguration implements
return true; return true;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser2.cpp.ICPPParserExtensionConfiguration#supportAttributeSpecifiers()
*/
public boolean supportAttributeSpecifiers() {
return true;
}
} }

View file

@ -31,5 +31,6 @@ public interface ICPPParserExtensionConfiguration {
public boolean supportLongLongs(); public boolean supportLongLongs();
public boolean supportKnRC(); public boolean supportKnRC();
public boolean supportGCCOtherBuiltinSymbols(); public boolean supportGCCOtherBuiltinSymbols();
public boolean supportAttributeSpecifiers();
} }

View file

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2002, 2005 IBM Corporation 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:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
/**
* The main purpose of this class is to provide a subclass of GCCScannerExtensionConfiguration
* for exclusive use in the old parser (ParserFactory.createScanner()) so that as old
* hacks are removed when fixed in the new parser, they can still apply to the old parser. This
* way the old parser will not have to be maintained as it's no longer being tested.
*
* @author dsteffle
*/
public class GCCOldScannerExtensionConfiguration extends
GCCScannerExtensionConfiguration {
private static final ObjectStyleMacro __cdecl = new ObjectStyleMacro(
"__cdecl".toCharArray(), emptyCharArray); //$NON-NLS-1$
private static final FunctionStyleMacro __attribute__ = new FunctionStyleMacro(
"__attribute__".toCharArray(), //$NON-NLS-1$
emptyCharArray, new char[][] { "arg".toCharArray() }); //$NON-NLS-1$
private static final FunctionStyleMacro __declspec = new FunctionStyleMacro(
"__declspec".toCharArray(), //$NON-NLS-1$
emptyCharArray, new char[][] { "arg".toCharArray() }); //$NON-NLS-1$
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#getAdditionalMacros()
*/
public CharArrayObjectMap getAdditionalMacros() {
CharArrayObjectMap result = super.getAdditionalMacros();
result.put(__cdecl.name, __cdecl);
result.put(__attribute__.name, __attribute__);
result.put(__declspec.name, __declspec);
return result;
}
}

View file

@ -68,6 +68,7 @@ public class GCCScannerExtensionConfiguration extends GNUScannerExtensionConfigu
CharArrayIntMap result = new CharArrayIntMap( 4, -1 ); CharArrayIntMap result = new CharArrayIntMap( 4, -1 );
result.put( GCCKeywords.cp__ALIGNOF__, IGCCToken.t___alignof__ ); result.put( GCCKeywords.cp__ALIGNOF__, IGCCToken.t___alignof__ );
result.put( GCCKeywords.cpTYPEOF, IGCCToken.t_typeof ); result.put( GCCKeywords.cpTYPEOF, IGCCToken.t_typeof );
result.put( GCCKeywords.cp__ATTRIBUTE__, IGCCToken.t__attribute__ );
return result; return result;
} }

View file

@ -60,9 +60,6 @@ public abstract class GNUScannerExtensionConfiguration implements IScannerExtens
private static final ObjectStyleMacro __signed__ = new ObjectStyleMacro( private static final ObjectStyleMacro __signed__ = new ObjectStyleMacro(
"__signed__".toCharArray(), "signed".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$ "__signed__".toCharArray(), "signed".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$
private static final ObjectStyleMacro __cdecl = new ObjectStyleMacro(
"__cdecl".toCharArray(), emptyCharArray); //$NON-NLS-1$
private static final ObjectStyleMacro __complex__ = new ObjectStyleMacro( private static final ObjectStyleMacro __complex__ = new ObjectStyleMacro(
"__complex__".toCharArray(), "_Complex".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$ "__complex__".toCharArray(), "_Complex".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$
@ -75,15 +72,6 @@ public abstract class GNUScannerExtensionConfiguration implements IScannerExtens
private static final ObjectStyleMacro __null = new ObjectStyleMacro( private static final ObjectStyleMacro __null = new ObjectStyleMacro(
"__null".toCharArray(), "(void *)0".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$ "__null".toCharArray(), "(void *)0".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$
private static final FunctionStyleMacro __attribute__ = new FunctionStyleMacro(
"__attribute__".toCharArray(), //$NON-NLS-1$
emptyCharArray, new char[][] { "arg".toCharArray() }); //$NON-NLS-1$
private static final FunctionStyleMacro __declspec = new FunctionStyleMacro(
"__declspec".toCharArray(), //$NON-NLS-1$
emptyCharArray, new char[][] { "arg".toCharArray() }); //$NON-NLS-1$
private static final FunctionStyleMacro __builtin_va_arg = new FunctionStyleMacro( private static final FunctionStyleMacro __builtin_va_arg = new FunctionStyleMacro(
"__builtin_va_arg".toCharArray(), //$NON-NLS-1$ "__builtin_va_arg".toCharArray(), //$NON-NLS-1$
"*(type *)ap".toCharArray(), //$NON-NLS-1$ "*(type *)ap".toCharArray(), //$NON-NLS-1$
@ -100,12 +88,9 @@ public abstract class GNUScannerExtensionConfiguration implements IScannerExtens
public CharArrayObjectMap getAdditionalMacros() { public CharArrayObjectMap getAdditionalMacros() {
CharArrayObjectMap realDefinitions = new CharArrayObjectMap(16); CharArrayObjectMap realDefinitions = new CharArrayObjectMap(16);
realDefinitions.put(__inline__.name, __inline__); realDefinitions.put(__inline__.name, __inline__);
realDefinitions.put(__cdecl.name, __cdecl);
realDefinitions.put(__const__.name, __const__); realDefinitions.put(__const__.name, __const__);
realDefinitions.put(__const.name, __const); realDefinitions.put(__const.name, __const);
realDefinitions.put(__extension__.name, __extension__); realDefinitions.put(__extension__.name, __extension__);
realDefinitions.put(__attribute__.name, __attribute__);
realDefinitions.put(__declspec.name, __declspec);
realDefinitions.put(__restrict__.name, __restrict__); realDefinitions.put(__restrict__.name, __restrict__);
realDefinitions.put(__restrict.name, __restrict); realDefinitions.put(__restrict.name, __restrict);
realDefinitions.put(__volatile__.name, __volatile__); realDefinitions.put(__volatile__.name, __volatile__);

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2002, 2005 IBM Corporation 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:
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
/**
* The main purpose of this class is to provide a subclass of GPPScannerExtensionConfiguration
* for exclusive use in the old parser (ParserFactory.createScanner()) so that as old
* hacks are removed when fixed in the new parser, they can still apply to the old parser. This
* way the old parser will not have to be maintained as it's no longer being tested.
*
* @author dsteffle
*/
public class GPPOldScannerExtensionConfiguration extends
GPPScannerExtensionConfiguration {
private static final ObjectStyleMacro __cdecl = new ObjectStyleMacro(
"__cdecl".toCharArray(), emptyCharArray); //$NON-NLS-1$
private static final FunctionStyleMacro __attribute__ = new FunctionStyleMacro(
"__attribute__".toCharArray(), //$NON-NLS-1$
emptyCharArray, new char[][] { "arg".toCharArray() }); //$NON-NLS-1$
private static final FunctionStyleMacro __declspec = new FunctionStyleMacro(
"__declspec".toCharArray(), //$NON-NLS-1$
emptyCharArray, new char[][] { "arg".toCharArray() }); //$NON-NLS-1$
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerConfiguration#getAdditionalMacros()
*/
public CharArrayObjectMap getAdditionalMacros() {
CharArrayObjectMap result = super.getAdditionalMacros();
result.put(__cdecl.name, __cdecl);
result.put(__attribute__.name, __attribute__);
result.put(__declspec.name, __declspec);
return result;
}
}

View file

@ -36,6 +36,7 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
CharArrayIntMap additionalCPPKeywords = new CharArrayIntMap( 8, -1 ); CharArrayIntMap additionalCPPKeywords = new CharArrayIntMap( 8, -1 );
additionalCPPKeywords.put( GCCKeywords.cp__ALIGNOF__, IGCCToken.t___alignof__ ); additionalCPPKeywords.put( GCCKeywords.cp__ALIGNOF__, IGCCToken.t___alignof__ );
additionalCPPKeywords.put( GCCKeywords.cpTYPEOF, IGCCToken.t_typeof ); additionalCPPKeywords.put( GCCKeywords.cpTYPEOF, IGCCToken.t_typeof );
additionalCPPKeywords.put( GCCKeywords.cp__ATTRIBUTE__, IGCCToken.t__attribute__ );
additionalCPPKeywords.put( Keywords.cRESTRICT, IToken.t_restrict ); additionalCPPKeywords.put( Keywords.cRESTRICT, IToken.t_restrict );
additionalCPPKeywords.put( Keywords.c_COMPLEX, IToken.t__Complex ); additionalCPPKeywords.put( Keywords.c_COMPLEX, IToken.t__Complex );
additionalCPPKeywords.put( Keywords.c_IMAGINARY, IToken.t__Imaginary ); additionalCPPKeywords.put( Keywords.c_IMAGINARY, IToken.t__Imaginary );