diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java index e5e82ab1cbf..d7cfee4bbe1 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java @@ -1737,14 +1737,48 @@ public class Scanner2Test extends BaseScanner2Test StringWriter writer = new StringWriter(); writer.write( "#define DoSuperMethodA IDoSuperMethodA\n" ); //$NON-NLS-1$ writer.write( "#define IDoSuperMethodA(a,b,c) IIntuition->IDoSuperMethodA(a,b,c)\n" ); //$NON-NLS-1$ - writer.write( "void hang(void)\n" ); //$NON-NLS-1$ - writer.write( "{\n" ); //$NON-NLS-1$ writer.write( "DoSuperMethodA(0,0,0);\n" ); //$NON-NLS-1$ - writer.write( "}\n" ); //$NON-NLS-1$ + initializeScanner( writer.toString() ); - fullyTokenize(); + + validateIdentifier( "IIntuition" ); //$NON-NLS-1$ + validateToken( IToken.tARROW ); + validateIdentifier( "IDoSuperMethodA" ); //$NON-NLS-1$ + validateToken( IToken.tLPAREN ); + validateInteger( "0" ); //$NON-NLS-1$ + validateToken( IToken.tCOMMA ); + validateInteger( "0" ); //$NON-NLS-1$ + validateToken( IToken.tCOMMA ); + validateInteger( "0" ); //$NON-NLS-1$ + validateToken( IToken.tRPAREN ); + validateToken( IToken.tSEMI ); + validateEOF(); } + public void testBug73652_2() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "#define DoSuperMethodA DoSuperMethodB //doobalie\n" ); //$NON-NLS-1$ + writer.write( "#define DoSuperMethodB DoSuperMethodC /*oogalie*/ \n" ); //$NON-NLS-1$ + writer.write( "#define DoSuperMethodC IDoSuperMethodA \\\n\n" ); //$NON-NLS-1$ + writer.write( "#define IDoSuperMethodA(a,b,c) IIntuition->IDoSuperMethodA(a,b,c)\n" ); //$NON-NLS-1$ + writer.write( "DoSuperMethodA (0,0,0);\n" ); //$NON-NLS-1$ + + initializeScanner( writer.toString() ); + + validateIdentifier( "IIntuition" ); //$NON-NLS-1$ + validateToken( IToken.tARROW ); + validateIdentifier( "IDoSuperMethodA" ); //$NON-NLS-1$ + validateToken( IToken.tLPAREN ); + validateInteger( "0" ); //$NON-NLS-1$ + validateToken( IToken.tCOMMA ); + validateInteger( "0" ); //$NON-NLS-1$ + validateToken( IToken.tCOMMA ); + validateInteger( "0" ); //$NON-NLS-1$ + validateToken( IToken.tRPAREN ); + validateToken( IToken.tSEMI ); + validateEOF(); + + } public void testBug72997() throws Exception { initializeScanner( "'\\\\'"); //$NON-NLS-1$ 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 ef5b606ee82..6aa05ca39a1 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 @@ -2139,6 +2139,51 @@ public class Scanner2 implements IScanner, IScannerData { return encounteredMultiLineComment; } + private int indexOfNextNonWhiteSpace( char[] buffer, int start, int limit ) { + if( start < 0 || start >= buffer.length || limit > buffer.length ) + return -1; + + int pos = start + 1; + while( pos < limit ) { + switch (buffer[pos++]) { + case ' ': + case '\t': + case '\r': + continue; + case '/': + if( pos < limit) { + if( buffer[pos] == '/') { + // C++ comment, skip rest of line + while( ++pos < limit ){ + switch( buffer[pos] ){ + case '\\' : ++pos; break; + case '\n' : break; + } + } + } else if (buffer[pos] == '*') { + // C comment, find closing */ + while( ++pos < limit ){ + if( buffer[pos] == '*' && pos + 1 < limit && buffer[pos+1] == '/' ) + { + pos += 2; + break; + } + } + } + } + continue; + case '\\': + if (pos < limit && (buffer[pos] == '\n' || buffer[pos] == '\r') ) { + ++pos; + continue; + } + } + // fell out of switch without continuing, we're done + return --pos; + } + return pos; + } + private void skipOverNonWhiteSpace(){ skipOverNonWhiteSpace( false ); } @@ -2367,8 +2412,36 @@ public class Scanner2 implements IScanner, IScannerData { skipOverWhiteSpace(); } - if (++bufferPos[bufferStackPos] >= limit - || buffer[bufferPos[bufferStackPos]] != '(' ) + if( ++bufferPos[bufferStackPos] >= limit ){ + //allow a macro boundary cross here, but only if the caller was prepared to accept a bufferStackPos change + if( pushContext ) + { + int idx = -1; + int stackpPos = bufferStackPos; + while( bufferData[stackpPos] != null && bufferData[stackpPos] instanceof MacroData ){ + stackpPos--; + if( stackpPos < 0 ) return emptyCharArray; + idx = indexOfNextNonWhiteSpace( bufferStack[stackpPos], bufferPos[stackpPos], bufferLimit[stackpPos] ); + if( idx >= bufferLimit[stackpPos] ) continue; + if( idx > 0 && bufferStack[stackpPos][idx] == '(' ) break; + return emptyCharArray; + } + if( idx == -1 ) + return emptyCharArray; + + MacroData data = (MacroData) bufferData[stackpPos+1]; + for( int i = bufferStackPos; i > stackpPos; i-- ) + popContext(); + + bufferPos[bufferStackPos] = idx; + buffer = bufferStack[bufferStackPos]; + limit = bufferLimit[bufferStackPos]; + start = data.startOffset; + } else { + return emptyCharArray; + } + } + if( buffer[bufferPos[bufferStackPos]] != '(' ) return emptyCharArray; char[][] arglist = macro.arglist;