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

Binary constants contributed by Thomas Holland. Bug 249698.

This commit is contained in:
Sergey Prigogin 2008-10-06 05:15:43 +00:00
parent 4fb814778b
commit 434637bb10
3 changed files with 68 additions and 1 deletions

View file

@ -1334,4 +1334,30 @@ public class PreprocessorTests extends PreprocessorTestsBase {
validateEOF();
validateProblemCount(0);
}
// #define BIN 0b10101010
// #define HEX 0xAA
// #define OCT 0252
// #define DEC 170
// #if (BIN == HEX && HEX == OCT && OCT == DEC)
// int foo = BIN;
// #endif
public void testGCC43BinaryNumbers() throws Exception {
initializeScanner();
validateToken(IToken.t_int);
validateIdentifier("foo");
validateToken(IToken.tASSIGN);
validateInteger("0b10101010");
validateToken(IToken.tSEMI);
validateEOF();
validateProblemCount(0);
String badbinary = "{0b012, 0b01b, 0b1111e01, 0b1111p10, 0b10010.10010}";
initializeScanner(badbinary);
fullyTokenize();
validateProblemCount(5);
for (int i = 0; i < 5; i++) {
validateProblem(i, IProblem.SCANNER_BAD_BINARY_FORMAT, null);
}
}
}

View file

@ -640,6 +640,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final char[] image= number.getCharImage();
boolean hasExponent = false;
// Integer constants written in binary are a non-standard extension
// supported by GCC since 4.3 and by some other C compilers
// They consist of a prefix 0b or 0B, followed by a sequence of 0 and 1 digits
// see http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html
boolean isBin = false;
boolean isHex = false;
boolean isOctal = false;
boolean hasDot= false;
@ -648,6 +654,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
if (image.length > 1) {
if (image[0] == '0') {
switch (image[++pos]) {
case 'b':
case 'B':
isBin = true;
++pos;
break;
case 'x':
case 'X':
isHex = true;
@ -665,6 +676,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
loop: for (; pos < image.length; pos++) {
if (isBin) {
switch (image[pos]) {
case '0': case'1':
continue;
default:
// 0 and 1 are the only allowed digits for binary integers
// No floating point, exponents etc. are allowed
break loop;
}
}
switch (image[pos]) {
// octal digits
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
@ -743,7 +764,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
continue loop;
}
}
if (isFloat) {
if (isBin) {
// The check for bin has to come before float, otherwise binary integers
// with float components get flagged as BAD_FLOATING_POINT
handleProblem(IProblem.SCANNER_BAD_BINARY_FORMAT, image, number.getOffset(), number.getEndOffset());
}
else if (isFloat) {
handleProblem(IProblem.SCANNER_BAD_FLOATING_POINT, image, number.getOffset(), number.getEndOffset());
}
else if (isHex) {

View file

@ -332,6 +332,13 @@ class ExpressionEvaluator {
}
private long getNumber(char[] image) throws EvalException {
// Integer constants written in binary are a non-standard extension
// supported by GCC since 4.3 and by some other C compilers
// They consist of a prefix 0b or 0B, followed by a sequence of 0 and 1 digits
// see http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html
boolean isBin = false;
boolean isHex = false;
boolean isOctal = false;
@ -339,6 +346,11 @@ class ExpressionEvaluator {
if (image.length > 1) {
if (image[0] == '0') {
switch (image[++pos]) {
case 'b':
case 'B':
isBin = true;
++pos;
break;
case 'x':
case 'X':
isHex = true;
@ -351,6 +363,9 @@ class ExpressionEvaluator {
}
}
}
if (isBin) {
return getNumber(image, 2, image.length, 2, IProblem.SCANNER_BAD_BINARY_FORMAT);
}
if (isHex) {
return getNumber(image, 2, image.length, 16, IProblem.SCANNER_BAD_HEX_FORMAT);
}