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.IASTNullStatement;
|
||||
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.IASTProblemDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||
|
@ -3526,4 +3527,56 @@ public class AST2Tests extends AST2BaseTest {
|
|||
StringBuffer sb= getContents(1)[0];
|
||||
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 varArgDefinitionInd = -1;
|
||||
|
||||
boolean encounteredMultilineComment = false;
|
||||
boolean encounteredComment = false;
|
||||
boolean usesVarArgInDefinition = false;
|
||||
while (bufferPos[bufferStackPos] + 1 < limit
|
||||
&& buffer[bufferPos[bufferStackPos] + 1] != '\n') {
|
||||
|
@ -2146,7 +2146,7 @@ abstract class BaseScanner implements IScanner {
|
|||
if (arglist != null && !skipOverNonWhiteSpace(true)) {
|
||||
++bufferPos[bufferStackPos]; //advances us to the #
|
||||
if (skipOverWhiteSpace())
|
||||
encounteredMultilineComment = true;
|
||||
encounteredComment = true;
|
||||
|
||||
boolean isArg = false;
|
||||
if (bufferPos[bufferStackPos] + 1 < limit) {
|
||||
|
@ -2195,7 +2195,7 @@ abstract class BaseScanner implements IScanner {
|
|||
}
|
||||
textend = bufferPos[bufferStackPos];
|
||||
if (skipOverWhiteSpace())
|
||||
encounteredMultilineComment = true;
|
||||
encounteredComment = true;
|
||||
}
|
||||
|
||||
int textlen = textend - textstart + 1;
|
||||
|
@ -2208,8 +2208,8 @@ abstract class BaseScanner implements IScanner {
|
|||
// System.out.println(countIt);
|
||||
}
|
||||
|
||||
if (encounteredMultilineComment)
|
||||
text = removeMultilineCommentFromBuffer(text);
|
||||
if (encounteredComment)
|
||||
text = removeCommentFromBuffer(text);
|
||||
text = removedEscapedNewline(text, 0, text.length);
|
||||
|
||||
IMacro result = null;
|
||||
|
@ -2333,16 +2333,22 @@ abstract class BaseScanner implements IScanner {
|
|||
* @param text
|
||||
* @return
|
||||
*/
|
||||
protected char[] removeMultilineCommentFromBuffer(char[] text) {
|
||||
protected char[] removeCommentFromBuffer(char[] text) {
|
||||
char[] result = new char[text.length];
|
||||
Arrays.fill(result, ' ');
|
||||
int resultCount = 0;
|
||||
// either a single-line or multi-line comment was found
|
||||
for (int i = 0; i < text.length; ++i) {
|
||||
if (text[i] == '/' && (i + 1 < text.length) && text[i + 1] == '*') {
|
||||
i += 2;
|
||||
while (i < text.length
|
||||
&& !(text[i] == '*' && i + 1 < text.length && text[i + 1] == '/'))
|
||||
++i;
|
||||
if (text[i] == '/' && (i + 1 < text.length) && (text[i + 1] == '*' || text[i + 1] == '/')) {
|
||||
if (text[i + 1] == '/') {
|
||||
// done
|
||||
break;
|
||||
} else {
|
||||
i += 2;
|
||||
while (i < text.length
|
||||
&& !(text[i] == '*' && i + 1 < text.length && text[i + 1] == '/'))
|
||||
++i;
|
||||
}
|
||||
++i;
|
||||
} else
|
||||
result[resultCount++] = text[i];
|
||||
|
@ -2619,7 +2625,7 @@ abstract class BaseScanner implements IScanner {
|
|||
// if( pos > 0 && pos < limit && buffer[pos] == '\n')
|
||||
// return false;
|
||||
|
||||
boolean encounteredMultiLineComment = false;
|
||||
boolean encounteredComment = false;
|
||||
while (++bufferPos[bufferStackPos] < limit) {
|
||||
pos = bufferPos[bufferStackPos];
|
||||
switch (buffer[pos]) {
|
||||
|
@ -2632,7 +2638,8 @@ abstract class BaseScanner implements IScanner {
|
|||
if (buffer[pos + 1] == '/') {
|
||||
// C++ comment, skip rest of line
|
||||
skipToNewLine(true);
|
||||
return false;
|
||||
encounteredComment = true;
|
||||
return encounteredComment;
|
||||
} else if (buffer[pos + 1] == '*') {
|
||||
// C comment, find closing */
|
||||
for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) {
|
||||
|
@ -2640,7 +2647,7 @@ abstract class BaseScanner implements IScanner {
|
|||
if (buffer[pos] == '*' && pos + 1 < limit
|
||||
&& buffer[pos + 1] == '/') {
|
||||
++bufferPos[bufferStackPos];
|
||||
encounteredMultiLineComment = true;
|
||||
encounteredComment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2665,10 +2672,10 @@ abstract class BaseScanner implements IScanner {
|
|||
|
||||
// fell out of switch without continuing, we're done
|
||||
--bufferPos[bufferStackPos];
|
||||
return encounteredMultiLineComment;
|
||||
return encounteredComment;
|
||||
}
|
||||
--bufferPos[bufferStackPos];
|
||||
return encounteredMultiLineComment;
|
||||
return encounteredComment;
|
||||
}
|
||||
|
||||
protected int indexOfNextNonWhiteSpace(char[] buffer, int start, int limit) {
|
||||
|
|
Loading…
Add table
Reference in a new issue