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:
parent
4fb814778b
commit
434637bb10
3 changed files with 68 additions and 1 deletions
|
@ -1334,4 +1334,30 @@ public class PreprocessorTests extends PreprocessorTestsBase {
|
||||||
validateEOF();
|
validateEOF();
|
||||||
validateProblemCount(0);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -640,6 +640,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
final char[] image= number.getCharImage();
|
final char[] image= number.getCharImage();
|
||||||
boolean hasExponent = false;
|
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 isHex = false;
|
||||||
boolean isOctal = false;
|
boolean isOctal = false;
|
||||||
boolean hasDot= false;
|
boolean hasDot= false;
|
||||||
|
@ -648,6 +654,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (image.length > 1) {
|
if (image.length > 1) {
|
||||||
if (image[0] == '0') {
|
if (image[0] == '0') {
|
||||||
switch (image[++pos]) {
|
switch (image[++pos]) {
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
isBin = true;
|
||||||
|
++pos;
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
isHex = true;
|
isHex = true;
|
||||||
|
@ -665,6 +676,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
loop: for (; pos < image.length; pos++) {
|
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]) {
|
switch (image[pos]) {
|
||||||
// octal digits
|
// octal digits
|
||||||
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
|
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;
|
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());
|
handleProblem(IProblem.SCANNER_BAD_FLOATING_POINT, image, number.getOffset(), number.getEndOffset());
|
||||||
}
|
}
|
||||||
else if (isHex) {
|
else if (isHex) {
|
||||||
|
|
|
@ -332,6 +332,13 @@ class ExpressionEvaluator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getNumber(char[] image) throws EvalException {
|
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 isHex = false;
|
||||||
boolean isOctal = false;
|
boolean isOctal = false;
|
||||||
|
|
||||||
|
@ -339,6 +346,11 @@ class ExpressionEvaluator {
|
||||||
if (image.length > 1) {
|
if (image.length > 1) {
|
||||||
if (image[0] == '0') {
|
if (image[0] == '0') {
|
||||||
switch (image[++pos]) {
|
switch (image[++pos]) {
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
isBin = true;
|
||||||
|
++pos;
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
case 'X':
|
||||||
isHex = true;
|
isHex = true;
|
||||||
|
@ -351,6 +363,9 @@ class ExpressionEvaluator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isBin) {
|
||||||
|
return getNumber(image, 2, image.length, 2, IProblem.SCANNER_BAD_BINARY_FORMAT);
|
||||||
|
}
|
||||||
if (isHex) {
|
if (isHex) {
|
||||||
return getNumber(image, 2, image.length, 16, IProblem.SCANNER_BAD_HEX_FORMAT);
|
return getNumber(image, 2, image.length, 16, IProblem.SCANNER_BAD_HEX_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue