mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Fix for 177154: [patch] single-line comments incorrectly retained in macros (Patch by Ed Swartz)
This commit is contained in:
parent
4a8670a767
commit
f15cdb515b
2 changed files with 76 additions and 16 deletions
|
@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||||
|
@ -3526,4 +3527,56 @@ public class AST2Tests extends AST2BaseTest {
|
||||||
StringBuffer sb= getContents(1)[0];
|
StringBuffer sb= getContents(1)[0];
|
||||||
parse(sb.toString(), ParserLanguage.C, false, false);
|
parse(sb.toString(), ParserLanguage.C, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bug in not removing single-line comments from macros.
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void testMacroCommentsBug_177154() throws Exception {
|
||||||
|
// simple case
|
||||||
|
String simple =
|
||||||
|
"#define LIT 1 // my value\r\n" +
|
||||||
|
"int func(int x) {\r\n" +
|
||||||
|
"}\r\n" +
|
||||||
|
"int main() {\r\n" +
|
||||||
|
" return func(LIT); // fails to parse\r\n" +
|
||||||
|
"}\r\n";
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = parse( simple, ParserLanguage.CPP, true, true );
|
||||||
|
|
||||||
|
// actual reduced test case, plus extra cases
|
||||||
|
String text =
|
||||||
|
"#define KBOOT 1 //0x00000002\r\n" +
|
||||||
|
"#define KBOOT2 /* value */ 1 /* another */ //0x00000002\r\n" +
|
||||||
|
"#define KBOOT3 /* value \r\n" +
|
||||||
|
" multi line\r\n"+
|
||||||
|
" comment */ 1 \\\r\n"+
|
||||||
|
"/* another */ + \\\r\n"+
|
||||||
|
"2 //0x00000002\r\n" +
|
||||||
|
"#define DEBUGNUM(x) (KDebugNum(x))\r\n" +
|
||||||
|
"bool KDebugNum(int aBitNum);\r\n" +
|
||||||
|
"#define __KTRACE_OPT(a,p) {if((DEBUGNUM(a)))p;}\r\n" +
|
||||||
|
"void fail();\r\n"+
|
||||||
|
"void test() {\r\n"+
|
||||||
|
"__KTRACE_OPT(KBOOT,fail());\r\n" +
|
||||||
|
"__KTRACE_OPT(KBOOT2,fail());\r\n" +
|
||||||
|
"}\r\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
// essential test: this code should be parseable
|
||||||
|
tu = parse( text, ParserLanguage.CPP, true, true );
|
||||||
|
|
||||||
|
// verify macros
|
||||||
|
IASTPreprocessorMacroDefinition[] macroDefinitions = tu.getMacroDefinitions();
|
||||||
|
assertEquals(5, macroDefinitions.length);
|
||||||
|
assertEquals("1", macroDefinitions[0].getExpansion());
|
||||||
|
assertEquals("1", macroDefinitions[1].getExpansion());
|
||||||
|
// regression test for #64268 and #71733 which also handle comments
|
||||||
|
assertEquals("1 + 2", macroDefinitions[2].getExpansion());
|
||||||
|
assertEquals("(KDebugNum(x))", macroDefinitions[3].getExpansion());
|
||||||
|
assertEquals("{if((DEBUGNUM(a)))p;}", macroDefinitions[4].getExpansion());
|
||||||
|
|
||||||
|
// TODO: exhaustive macro testing
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2127,7 +2127,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
int textend = textstart - 1;
|
int textend = textstart - 1;
|
||||||
int varArgDefinitionInd = -1;
|
int varArgDefinitionInd = -1;
|
||||||
|
|
||||||
boolean encounteredMultilineComment = false;
|
boolean encounteredComment = false;
|
||||||
boolean usesVarArgInDefinition = false;
|
boolean usesVarArgInDefinition = false;
|
||||||
while (bufferPos[bufferStackPos] + 1 < limit
|
while (bufferPos[bufferStackPos] + 1 < limit
|
||||||
&& buffer[bufferPos[bufferStackPos] + 1] != '\n') {
|
&& buffer[bufferPos[bufferStackPos] + 1] != '\n') {
|
||||||
|
@ -2146,7 +2146,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (arglist != null && !skipOverNonWhiteSpace(true)) {
|
if (arglist != null && !skipOverNonWhiteSpace(true)) {
|
||||||
++bufferPos[bufferStackPos]; //advances us to the #
|
++bufferPos[bufferStackPos]; //advances us to the #
|
||||||
if (skipOverWhiteSpace())
|
if (skipOverWhiteSpace())
|
||||||
encounteredMultilineComment = true;
|
encounteredComment = true;
|
||||||
|
|
||||||
boolean isArg = false;
|
boolean isArg = false;
|
||||||
if (bufferPos[bufferStackPos] + 1 < limit) {
|
if (bufferPos[bufferStackPos] + 1 < limit) {
|
||||||
|
@ -2195,7 +2195,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
}
|
}
|
||||||
textend = bufferPos[bufferStackPos];
|
textend = bufferPos[bufferStackPos];
|
||||||
if (skipOverWhiteSpace())
|
if (skipOverWhiteSpace())
|
||||||
encounteredMultilineComment = true;
|
encounteredComment = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int textlen = textend - textstart + 1;
|
int textlen = textend - textstart + 1;
|
||||||
|
@ -2208,8 +2208,8 @@ abstract class BaseScanner implements IScanner {
|
||||||
// System.out.println(countIt);
|
// System.out.println(countIt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encounteredMultilineComment)
|
if (encounteredComment)
|
||||||
text = removeMultilineCommentFromBuffer(text);
|
text = removeCommentFromBuffer(text);
|
||||||
text = removedEscapedNewline(text, 0, text.length);
|
text = removedEscapedNewline(text, 0, text.length);
|
||||||
|
|
||||||
IMacro result = null;
|
IMacro result = null;
|
||||||
|
@ -2333,16 +2333,22 @@ abstract class BaseScanner implements IScanner {
|
||||||
* @param text
|
* @param text
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected char[] removeMultilineCommentFromBuffer(char[] text) {
|
protected char[] removeCommentFromBuffer(char[] text) {
|
||||||
char[] result = new char[text.length];
|
char[] result = new char[text.length];
|
||||||
Arrays.fill(result, ' ');
|
Arrays.fill(result, ' ');
|
||||||
int resultCount = 0;
|
int resultCount = 0;
|
||||||
|
// either a single-line or multi-line comment was found
|
||||||
for (int i = 0; i < text.length; ++i) {
|
for (int i = 0; i < text.length; ++i) {
|
||||||
if (text[i] == '/' && (i + 1 < text.length) && text[i + 1] == '*') {
|
if (text[i] == '/' && (i + 1 < text.length) && (text[i + 1] == '*' || text[i + 1] == '/')) {
|
||||||
i += 2;
|
if (text[i + 1] == '/') {
|
||||||
while (i < text.length
|
// done
|
||||||
&& !(text[i] == '*' && i + 1 < text.length && text[i + 1] == '/'))
|
break;
|
||||||
++i;
|
} else {
|
||||||
|
i += 2;
|
||||||
|
while (i < text.length
|
||||||
|
&& !(text[i] == '*' && i + 1 < text.length && text[i + 1] == '/'))
|
||||||
|
++i;
|
||||||
|
}
|
||||||
++i;
|
++i;
|
||||||
} else
|
} else
|
||||||
result[resultCount++] = text[i];
|
result[resultCount++] = text[i];
|
||||||
|
@ -2619,7 +2625,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
// if( pos > 0 && pos < limit && buffer[pos] == '\n')
|
// if( pos > 0 && pos < limit && buffer[pos] == '\n')
|
||||||
// return false;
|
// return false;
|
||||||
|
|
||||||
boolean encounteredMultiLineComment = false;
|
boolean encounteredComment = false;
|
||||||
while (++bufferPos[bufferStackPos] < limit) {
|
while (++bufferPos[bufferStackPos] < limit) {
|
||||||
pos = bufferPos[bufferStackPos];
|
pos = bufferPos[bufferStackPos];
|
||||||
switch (buffer[pos]) {
|
switch (buffer[pos]) {
|
||||||
|
@ -2632,7 +2638,8 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (buffer[pos + 1] == '/') {
|
if (buffer[pos + 1] == '/') {
|
||||||
// C++ comment, skip rest of line
|
// C++ comment, skip rest of line
|
||||||
skipToNewLine(true);
|
skipToNewLine(true);
|
||||||
return false;
|
encounteredComment = true;
|
||||||
|
return encounteredComment;
|
||||||
} else if (buffer[pos + 1] == '*') {
|
} else if (buffer[pos + 1] == '*') {
|
||||||
// C comment, find closing */
|
// C comment, find closing */
|
||||||
for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) {
|
for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) {
|
||||||
|
@ -2640,7 +2647,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
if (buffer[pos] == '*' && pos + 1 < limit
|
if (buffer[pos] == '*' && pos + 1 < limit
|
||||||
&& buffer[pos + 1] == '/') {
|
&& buffer[pos + 1] == '/') {
|
||||||
++bufferPos[bufferStackPos];
|
++bufferPos[bufferStackPos];
|
||||||
encounteredMultiLineComment = true;
|
encounteredComment = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2665,10 +2672,10 @@ abstract class BaseScanner implements IScanner {
|
||||||
|
|
||||||
// fell out of switch without continuing, we're done
|
// fell out of switch without continuing, we're done
|
||||||
--bufferPos[bufferStackPos];
|
--bufferPos[bufferStackPos];
|
||||||
return encounteredMultiLineComment;
|
return encounteredComment;
|
||||||
}
|
}
|
||||||
--bufferPos[bufferStackPos];
|
--bufferPos[bufferStackPos];
|
||||||
return encounteredMultiLineComment;
|
return encounteredComment;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int indexOfNextNonWhiteSpace(char[] buffer, int start, int limit) {
|
protected int indexOfNextNonWhiteSpace(char[] buffer, int start, int limit) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue