diff --git a/clang/Lex/LiteralSupport.cpp b/clang/Lex/LiteralSupport.cpp index 3ac9837efc1f..dd4ac3d524b3 100644 --- a/clang/Lex/LiteralSupport.cpp +++ b/clang/Lex/LiteralSupport.cpp @@ -215,6 +215,7 @@ NumericLiteralParser(const char *begin, const char *end, DigitsBegin = s; s = SkipHexDigits(s); if (s == ThisTokEnd) { + // Done. } else if (*s == '.') { s++; saw_period = true; @@ -237,6 +238,19 @@ NumericLiteralParser(const char *begin, const char *end, Diag(TokLoc, diag::err_hexconstant_requires_exponent); return; } + } else if (*s == 'b' || *s == 'B') { + // 0b101010 is a GCC extension. + ++s; + radix = 2; + DigitsBegin = s; + s = SkipBinaryDigits(s); + if (s == ThisTokEnd) { + // Done. + } else if (isxdigit(*s)) { + Diag(TokLoc, diag::err_invalid_binary_digit, std::string(s, s+1)); + return; + } + PP.Diag(TokLoc, diag::ext_binary_literal); } else { // For now, the radix is set to 8. If we discover that we have a // floating point constant, the radix will change to 10. Octal floating diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index a1773ea93ebe..046ad8735ec1 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -530,6 +530,10 @@ DIAG(warn_integer_too_large_for_signed, WARNING, "integer constant is so large that it is unsigned") DIAG(err_exponent_has_no_digits, ERROR, "exponent has no digits") +DIAG(ext_binary_literal, EXTENSION, + "binary integer literals are an extension") +DIAG(err_invalid_binary_digit, ERROR, + "invalid digit '%0' in binary constant") DIAG(err_invalid_octal_digit, ERROR, "invalid digit '%0' in octal constant") DIAG(err_invalid_decimal_digit, ERROR, diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index bfb5ef67ceab..cf8c3156f326 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -97,6 +97,15 @@ private: ptr++; return ptr; } + + /// SkipBinaryDigits - Read and skip over any binary digits, up to End. + /// Return a pointer to the first non-binary digit or End. + const char *SkipBinaryDigits(const char *ptr) { + while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1')) + ptr++; + return ptr; + } + }; /// CharLiteralParser - Perform interpretation and semantic analysis of a