[cfe-commits] r39349 - in /cfe/cfe/trunk: AST/Sema.cpp AST/Sema.h AST/SemaExpr.cpp Parse/ParseExpr.cpp Sema/Sema.cpp Sema/Sema.h Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h include/clang/Parse/Parser.h
snaroff at cs.uiuc.edu
snaroff at cs.uiuc.edu
Wed Jul 11 09:43:27 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:43:27 2007
New Revision: 39349
URL: http://llvm.org/viewvc/llvm-project?rev=39349&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
More code to parse numeric constants. This checkin includes:
- Feedback from Chris.
- Support for parsing floating point constants.
- Moved the code to "Sema". Changed API in Action.
- More/better error diagnostics.
At this point, the parsing support should be largely complete. Next step
is to work on filling in sensible values (in IntegerLiteral/FloatLiteral).
Modified:
cfe/cfe/trunk/AST/Sema.cpp
cfe/cfe/trunk/AST/Sema.h
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/Parse/ParseExpr.cpp
cfe/cfe/trunk/Sema/Sema.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/cfe/trunk/include/clang/Parse/Action.h
cfe/cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/cfe/trunk/AST/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.cpp?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Sema.cpp (original)
+++ cfe/cfe/trunk/AST/Sema.cpp Wed Jul 11 11:43:27 2007
@@ -30,6 +30,10 @@
PP.Diag(Loc, DiagID, Msg);
}
+void Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
+ Diag(Tok.getLocation(), DiagID, M);
+}
+
const LangOptions &Sema::getLangOptions() const {
return PP.getLangOptions();
}
Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:43:27 2007
@@ -30,6 +30,7 @@
class TypeRef;
class LangOptions;
class DeclaratorChunk;
+ class LexerToken;
/// Sema - This implements semantic analysis and AST building for C.
class Sema : public Action {
@@ -53,6 +54,8 @@
void Diag(SourceLocation Loc, unsigned DiagID,
const std::string &Msg = std::string());
+ void Diag(const LexerToken &Tok, unsigned DiagID,
+ const std::string &M = std::string());
//===--------------------------------------------------------------------===//
// Type Analysis / Processing: SemaType.cpp.
@@ -155,8 +158,7 @@
bool HasTrailingLParen);
virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
tok::TokenKind Kind);
- virtual ExprResult ParseIntegerLiteral(SourceLocation Loc);
- virtual ExprResult ParseFloatingLiteral(SourceLocation Loc);
+ virtual ExprResult ParseNumericConstant(const LexerToken &);
virtual ExprResult ParseParenExpr(SourceLocation L, SourceLocation R,
ExprTy *Val);
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:27 2007
@@ -285,11 +285,234 @@
}
}
-Sema::ExprResult Sema::ParseIntegerLiteral(SourceLocation Loc) {
- return new IntegerLiteral();
-}
-Sema::ExprResult Sema::ParseFloatingLiteral(SourceLocation Loc) {
- return new FloatingLiteral();
+/// integer-constant: [C99 6.4.4.1]
+/// decimal-constant integer-suffix
+/// octal-constant integer-suffix
+/// hexadecimal-constant integer-suffix
+/// decimal-constant:
+/// nonzero-digit
+/// decimal-constant digit
+/// octal-constant:
+/// 0
+/// octal-constant octal-digit
+/// hexadecimal-constant:
+/// hexadecimal-prefix hexadecimal-digit
+/// hexadecimal-constant hexadecimal-digit
+/// hexadecimal-prefix: one of
+/// 0x 0X
+/// integer-suffix:
+/// unsigned-suffix [long-suffix]
+/// unsigned-suffix [long-long-suffix]
+/// long-suffix [unsigned-suffix]
+/// long-long-suffix [unsigned-sufix]
+/// nonzero-digit:
+/// 1 2 3 4 5 6 7 8 9
+/// octal-digit:
+/// 0 1 2 3 4 5 6 7
+/// hexadecimal-digit:
+/// 0 1 2 3 4 5 6 7 8 9
+/// a b c d e f
+/// A B C D E F
+/// unsigned-suffix: one of
+/// u U
+/// long-suffix: one of
+/// l L
+/// long-long-suffix: one of
+/// ll LL
+///
+/// floating-constant: [C99 6.4.4.2]
+/// TODO: add rules...
+///
+Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
+ SmallString<512> IntegerBuffer;
+ IntegerBuffer.resize(Tok.getLength());
+ const char *ThisTokBegin = &IntegerBuffer[0];
+
+ // Get the spelling of the token, which eliminates trigraphs, etc. Notes:
+ // - We know that ThisTokBuf points to a buffer that is big enough for the
+ // whole token and 'spelled' tokens can only shrink.
+ // - In practice, the local buffer is only used when the spelling doesn't
+ // match the original token (which is rare). The common case simply returns
+ // a pointer to a *constant* buffer (avoiding a copy).
+
+ unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
+ ExprResult Res;
+
+ // This is an optimization for single digits (which are very common).
+ if (ActualLength == 1) {
+ return ExprResult(new IntegerLiteral());
+ }
+ const char *ThisTokEnd = ThisTokBegin+ActualLength;
+ const char *s = ThisTokBegin;
+ unsigned int radix;
+ bool saw_exponent = false, saw_period = false;
+ Expr *literal_expr = 0;
+
+ if (*s == '0') { // parse radix
+ s++;
+ if ((*s == 'x' || *s == 'X') && isxdigit(s[1])) { // need 1 digit
+ s++;
+ radix = 16;
+ while (s < ThisTokEnd) {
+ if (isxdigit(*s)) {
+ s++;
+ } else if (*s == '.') {
+ s++;
+ if (saw_period) {
+ Diag(Tok, diag::err_too_many_decimal_points);
+ return ExprResult(true);
+ } else
+ saw_period = true;
+ } else if (*s == 'p' || *s == 'P') { // binary exponent
+ saw_exponent = true;
+ s++;
+ if (*s == '+' || *s == '-') s++; // sign is optional
+ if (isdigit(*s)) {
+ do { s++; } while (isdigit(*s)); // a decimal integer
+ } else {
+ Diag(Tok, diag::err_exponent_has_no_digits);
+ return ExprResult(true);
+ }
+ break;
+ } else
+ break;
+ }
+ if (saw_period && !saw_exponent) {
+ Diag(Tok, diag::err_hexconstant_requires_exponent);
+ return ExprResult(true);
+ }
+ } 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
+ // point constants are not permitted (only decimal and hexadecimal).
+ radix = 8;
+ while (s < ThisTokEnd) {
+ if ((*s >= '0') && (*s <= '7')) {
+ s++;
+ } else if (*s == '.') {
+ s++;
+ if (saw_period) {
+ Diag(Tok, diag::err_too_many_decimal_points);
+ return ExprResult(true);
+ }
+ saw_period = true;
+ radix = 10;
+ } else if (*s == 'e' || *s == 'E') { // exponent
+ saw_exponent = true;
+ s++;
+ if (*s == '+' || *s == '-') s++; // sign
+ if (isdigit(*s)) {
+ do { s++; } while (isdigit(*s)); // a decimal integer
+ } else {
+ Diag(Tok, diag::err_exponent_has_no_digits);
+ return ExprResult(true);
+ }
+ radix = 10;
+ break;
+ } else
+ break;
+ }
+ }
+ } else { // the first digit is non-zero
+ radix = 10;
+ while (s < ThisTokEnd) {
+ if (isdigit(*s)) {
+ s++;
+ } else if (*s == '.') {
+ s++;
+ if (saw_period) {
+ Diag(Tok, diag::err_too_many_decimal_points);
+ return ExprResult(true);
+ } else
+ saw_period = true;
+ } else if (*s == 'e' || *s == 'E') { // exponent
+ saw_exponent = true;
+ s++;
+ if (*s == '+' || *s == '-') s++; // sign
+ if (isdigit(*s)) {
+ do { s++; } while (isdigit(*s)); // a decimal integer
+ } else {
+ Diag(Tok, diag::err_exponent_has_no_digits);
+ return ExprResult(true);
+ }
+ break;
+ } else
+ break;
+ }
+ }
+
+ const char *suffix_start = s;
+ bool invalid_suffix = false;
+
+ if (saw_period || saw_exponent) {
+ bool saw_float_suffix = false, saw_long_suffix = false;
+
+ while (s < ThisTokEnd) {
+ // parse float suffix - they can appear in any order.
+ if (*s == 'f' || *s == 'F') {
+ if (saw_float_suffix) {
+ invalid_suffix = true;
+ break;
+ } else {
+ saw_float_suffix = true;
+ s++;
+ }
+ } else if (*s == 'l' || *s == 'L') {
+ if (saw_long_suffix) {
+ invalid_suffix = true;
+ break;
+ } else {
+ saw_long_suffix = true;
+ s++;
+ }
+ } else {
+ invalid_suffix = true;
+ break;
+ }
+ }
+ if (invalid_suffix) {
+ Diag(Tok, diag::err_invalid_suffix_float_constant,
+ std::string(suffix_start, ThisTokEnd));
+ return ExprResult(true);
+ }
+ literal_expr = new FloatingLiteral();
+ } else {
+ bool saw_unsigned = false;
+ int long_cnt = 0;
+
+ // if there is no suffix, this loop won't be executed (s == ThisTokEnd)
+ while (s < ThisTokEnd) {
+ // parse int suffix - they can appear in any order ("ul", "lu", "llu").
+ if (*s == 'u' || *s == 'U') {
+ if (saw_unsigned) {
+ invalid_suffix = true;
+ break;
+ } else {
+ saw_unsigned = true;
+ s++;
+ }
+ } else if (*s == 'l' || *s == 'L') {
+ long_cnt++;
+ // l's need to be adjacent and the same case.
+ if ((long_cnt == 2 && (*s != *(s-1))) || long_cnt == 3) {
+ invalid_suffix = true;
+ break;
+ } else {
+ s++;
+ }
+ } else {
+ invalid_suffix = true;
+ break;
+ }
+ }
+ if (invalid_suffix) {
+ Diag(Tok, diag::err_invalid_suffix_integer_constant,
+ std::string(suffix_start, ThisTokEnd));
+ return ExprResult(true);
+ }
+ literal_expr = new IntegerLiteral();
+ }
+ return ExprResult(literal_expr);
}
Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,
Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:43:27 2007
@@ -473,7 +473,7 @@
// constant: integer-constant
// constant: floating-constant
- ParseNumericConstant();
+ Actions.ParseNumericConstant(Tok);
ConsumeToken();
// These can be followed by postfix-expr pieces.
@@ -925,114 +925,3 @@
// Pass the set of string tokens, ready for concatenation, to the actions.
return Actions.ParseStringLiteral(&StringToks[0], StringToks.size());
}
-
-/// integer-constant: [C99 6.4.4.1]
-/// decimal-constant integer-suffix
-/// octal-constant integer-suffix
-/// hexidecimal-constant integer-suffix
-/// decimal-constant:
-/// nonzero-digit
-/// decimal-constant digit
-/// octal-constant:
-/// 0
-/// octal-constant octal-digit
-/// hexidecimal-constant:
-/// hexidecimal-prefix hexidecimal-digit
-/// hexidecimal-constant hexidecimal-digit
-/// hexidecimal-prefix: one of
-/// 0x 0X
-/// integer-suffix:
-/// unsigned-suffix [long-suffix]
-/// unsigned-suffix [long-long-suffix]
-/// long-suffix [unsigned-suffix]
-/// long-long-suffix [unsigned-sufix]
-/// nonzero-digit:
-/// 1 2 3 4 5 6 7 8 9
-/// octal-digit:
-/// 0 1 2 3 4 5 6 7
-/// hexadecimal-digit:
-/// 0 1 2 3 4 5 6 7 8 9
-/// a b c d e f
-/// A B C D E F
-/// unsigned-suffix: one of
-/// u U
-/// long-suffix: one of
-/// l L
-/// long-long-suffix: one of
-/// ll LL
-///
-/// floating-constant: [C99 6.4.4.2]
-///
-Parser::ExprResult Parser::ParseNumericConstant() {
- SmallString<512> IntegerBuffer;
- IntegerBuffer.resize(Tok.getLength());
- const char *ThisTokBegin = &IntegerBuffer[0];
-
- // Get the spelling of the token, which eliminates trigraphs, etc. Notes:
- // - We know that ThisTokBuf points to a buffer that is big enough for the
- // whole token and 'spelled' tokens can only shrink.
- // - In practice, the local buffer is only used when the spelling doesn't
- // match the original token (which is rare). The common case simply returns
- // a pointer to a *constant* buffer (avoiding a copy).
-
- unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
- ExprResult Res;
-
- if (ActualLength == 1) {
- // need to change interface...just a placeholder
- Res = Actions.ParseIntegerLiteral(Tok.getLocation());
- } else if (ActualLength > 1) {
- const char *ThisTokEnd = ThisTokBegin+ActualLength;
- const char *s = ThisTokBegin;
- unsigned int radix;
-
- if (*s == '0') { // parse radix
- s++;
- if (*s == 'x' || *s == 'X') {
- s++;
- radix = 16;
- while (s < ThisTokEnd && isxdigit(*s)) *s++;
- } else {
- radix = 8;
- while (s < ThisTokEnd && ((*s >= '0') && (*s <= '7'))) *s++;
- }
- } else { // the first digit is non-zero
- radix = 10;
- while (s < ThisTokEnd && isdigit(*s)) *s++;
- }
-
- if (*s == '.') { // TODO: Parse Floats...
- Res = Actions.ParseFloatingLiteral(Tok.getLocation());
- } else {
- int unsigned_cnt = 0, long_cnt = 0, invalid_suffix = 0;
-
- // if there is no suffix, this loop won't be executed (s == ThisTokEnd)
- while (s < ThisTokEnd && !invalid_suffix) {
- // parse type suffix - they can appear in any order "ul", "lu", "llu"
- if (*s == 'u' || *s == 'U') {
- unsigned_cnt++;
- if (unsigned_cnt == 2)
- invalid_suffix = 1;
- else
- s++;
- } else if (*s == 'l' || *s == 'L') {
- long_cnt++;
- // l's need to be adjacent and the same case
- if ((long_cnt == 2 && (*s != *(s-1))) || long_cnt == 3)
- invalid_suffix = 1;
- else
- s++;
- } else {
- invalid_suffix = 1;
- }
- }
- if (invalid_suffix) {
- Diag(Tok, diag::err_invalid_suffix_integer_constant);
- return ExprResult(true);
- } else {
- // need to change interface...just a placeholder
- Res = Actions.ParseIntegerLiteral(Tok.getLocation());
- }
- }
- }
-}
Modified: cfe/cfe/trunk/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.cpp?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.cpp (original)
+++ cfe/cfe/trunk/Sema/Sema.cpp Wed Jul 11 11:43:27 2007
@@ -30,6 +30,10 @@
PP.Diag(Loc, DiagID, Msg);
}
+void Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
+ Diag(Tok.getLocation(), DiagID, M);
+}
+
const LangOptions &Sema::getLangOptions() const {
return PP.getLangOptions();
}
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:43:27 2007
@@ -30,6 +30,7 @@
class TypeRef;
class LangOptions;
class DeclaratorChunk;
+ class LexerToken;
/// Sema - This implements semantic analysis and AST building for C.
class Sema : public Action {
@@ -53,6 +54,8 @@
void Diag(SourceLocation Loc, unsigned DiagID,
const std::string &Msg = std::string());
+ void Diag(const LexerToken &Tok, unsigned DiagID,
+ const std::string &M = std::string());
//===--------------------------------------------------------------------===//
// Type Analysis / Processing: SemaType.cpp.
@@ -155,8 +158,7 @@
bool HasTrailingLParen);
virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
tok::TokenKind Kind);
- virtual ExprResult ParseIntegerLiteral(SourceLocation Loc);
- virtual ExprResult ParseFloatingLiteral(SourceLocation Loc);
+ virtual ExprResult ParseNumericConstant(const LexerToken &);
virtual ExprResult ParseParenExpr(SourceLocation L, SourceLocation R,
ExprTy *Val);
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:27 2007
@@ -285,11 +285,234 @@
}
}
-Sema::ExprResult Sema::ParseIntegerLiteral(SourceLocation Loc) {
- return new IntegerLiteral();
-}
-Sema::ExprResult Sema::ParseFloatingLiteral(SourceLocation Loc) {
- return new FloatingLiteral();
+/// integer-constant: [C99 6.4.4.1]
+/// decimal-constant integer-suffix
+/// octal-constant integer-suffix
+/// hexadecimal-constant integer-suffix
+/// decimal-constant:
+/// nonzero-digit
+/// decimal-constant digit
+/// octal-constant:
+/// 0
+/// octal-constant octal-digit
+/// hexadecimal-constant:
+/// hexadecimal-prefix hexadecimal-digit
+/// hexadecimal-constant hexadecimal-digit
+/// hexadecimal-prefix: one of
+/// 0x 0X
+/// integer-suffix:
+/// unsigned-suffix [long-suffix]
+/// unsigned-suffix [long-long-suffix]
+/// long-suffix [unsigned-suffix]
+/// long-long-suffix [unsigned-sufix]
+/// nonzero-digit:
+/// 1 2 3 4 5 6 7 8 9
+/// octal-digit:
+/// 0 1 2 3 4 5 6 7
+/// hexadecimal-digit:
+/// 0 1 2 3 4 5 6 7 8 9
+/// a b c d e f
+/// A B C D E F
+/// unsigned-suffix: one of
+/// u U
+/// long-suffix: one of
+/// l L
+/// long-long-suffix: one of
+/// ll LL
+///
+/// floating-constant: [C99 6.4.4.2]
+/// TODO: add rules...
+///
+Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
+ SmallString<512> IntegerBuffer;
+ IntegerBuffer.resize(Tok.getLength());
+ const char *ThisTokBegin = &IntegerBuffer[0];
+
+ // Get the spelling of the token, which eliminates trigraphs, etc. Notes:
+ // - We know that ThisTokBuf points to a buffer that is big enough for the
+ // whole token and 'spelled' tokens can only shrink.
+ // - In practice, the local buffer is only used when the spelling doesn't
+ // match the original token (which is rare). The common case simply returns
+ // a pointer to a *constant* buffer (avoiding a copy).
+
+ unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
+ ExprResult Res;
+
+ // This is an optimization for single digits (which are very common).
+ if (ActualLength == 1) {
+ return ExprResult(new IntegerLiteral());
+ }
+ const char *ThisTokEnd = ThisTokBegin+ActualLength;
+ const char *s = ThisTokBegin;
+ unsigned int radix;
+ bool saw_exponent = false, saw_period = false;
+ Expr *literal_expr = 0;
+
+ if (*s == '0') { // parse radix
+ s++;
+ if ((*s == 'x' || *s == 'X') && isxdigit(s[1])) { // need 1 digit
+ s++;
+ radix = 16;
+ while (s < ThisTokEnd) {
+ if (isxdigit(*s)) {
+ s++;
+ } else if (*s == '.') {
+ s++;
+ if (saw_period) {
+ Diag(Tok, diag::err_too_many_decimal_points);
+ return ExprResult(true);
+ } else
+ saw_period = true;
+ } else if (*s == 'p' || *s == 'P') { // binary exponent
+ saw_exponent = true;
+ s++;
+ if (*s == '+' || *s == '-') s++; // sign is optional
+ if (isdigit(*s)) {
+ do { s++; } while (isdigit(*s)); // a decimal integer
+ } else {
+ Diag(Tok, diag::err_exponent_has_no_digits);
+ return ExprResult(true);
+ }
+ break;
+ } else
+ break;
+ }
+ if (saw_period && !saw_exponent) {
+ Diag(Tok, diag::err_hexconstant_requires_exponent);
+ return ExprResult(true);
+ }
+ } 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
+ // point constants are not permitted (only decimal and hexadecimal).
+ radix = 8;
+ while (s < ThisTokEnd) {
+ if ((*s >= '0') && (*s <= '7')) {
+ s++;
+ } else if (*s == '.') {
+ s++;
+ if (saw_period) {
+ Diag(Tok, diag::err_too_many_decimal_points);
+ return ExprResult(true);
+ }
+ saw_period = true;
+ radix = 10;
+ } else if (*s == 'e' || *s == 'E') { // exponent
+ saw_exponent = true;
+ s++;
+ if (*s == '+' || *s == '-') s++; // sign
+ if (isdigit(*s)) {
+ do { s++; } while (isdigit(*s)); // a decimal integer
+ } else {
+ Diag(Tok, diag::err_exponent_has_no_digits);
+ return ExprResult(true);
+ }
+ radix = 10;
+ break;
+ } else
+ break;
+ }
+ }
+ } else { // the first digit is non-zero
+ radix = 10;
+ while (s < ThisTokEnd) {
+ if (isdigit(*s)) {
+ s++;
+ } else if (*s == '.') {
+ s++;
+ if (saw_period) {
+ Diag(Tok, diag::err_too_many_decimal_points);
+ return ExprResult(true);
+ } else
+ saw_period = true;
+ } else if (*s == 'e' || *s == 'E') { // exponent
+ saw_exponent = true;
+ s++;
+ if (*s == '+' || *s == '-') s++; // sign
+ if (isdigit(*s)) {
+ do { s++; } while (isdigit(*s)); // a decimal integer
+ } else {
+ Diag(Tok, diag::err_exponent_has_no_digits);
+ return ExprResult(true);
+ }
+ break;
+ } else
+ break;
+ }
+ }
+
+ const char *suffix_start = s;
+ bool invalid_suffix = false;
+
+ if (saw_period || saw_exponent) {
+ bool saw_float_suffix = false, saw_long_suffix = false;
+
+ while (s < ThisTokEnd) {
+ // parse float suffix - they can appear in any order.
+ if (*s == 'f' || *s == 'F') {
+ if (saw_float_suffix) {
+ invalid_suffix = true;
+ break;
+ } else {
+ saw_float_suffix = true;
+ s++;
+ }
+ } else if (*s == 'l' || *s == 'L') {
+ if (saw_long_suffix) {
+ invalid_suffix = true;
+ break;
+ } else {
+ saw_long_suffix = true;
+ s++;
+ }
+ } else {
+ invalid_suffix = true;
+ break;
+ }
+ }
+ if (invalid_suffix) {
+ Diag(Tok, diag::err_invalid_suffix_float_constant,
+ std::string(suffix_start, ThisTokEnd));
+ return ExprResult(true);
+ }
+ literal_expr = new FloatingLiteral();
+ } else {
+ bool saw_unsigned = false;
+ int long_cnt = 0;
+
+ // if there is no suffix, this loop won't be executed (s == ThisTokEnd)
+ while (s < ThisTokEnd) {
+ // parse int suffix - they can appear in any order ("ul", "lu", "llu").
+ if (*s == 'u' || *s == 'U') {
+ if (saw_unsigned) {
+ invalid_suffix = true;
+ break;
+ } else {
+ saw_unsigned = true;
+ s++;
+ }
+ } else if (*s == 'l' || *s == 'L') {
+ long_cnt++;
+ // l's need to be adjacent and the same case.
+ if ((long_cnt == 2 && (*s != *(s-1))) || long_cnt == 3) {
+ invalid_suffix = true;
+ break;
+ } else {
+ s++;
+ }
+ } else {
+ invalid_suffix = true;
+ break;
+ }
+ }
+ if (invalid_suffix) {
+ Diag(Tok, diag::err_invalid_suffix_integer_constant,
+ std::string(suffix_start, ThisTokEnd));
+ return ExprResult(true);
+ }
+ literal_expr = new IntegerLiteral();
+ }
+ return ExprResult(literal_expr);
}
Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,
Modified: cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/cfe/trunk/clang.xcodeproj/project.pbxproj Wed Jul 11 11:43:27 2007
@@ -94,23 +94,6 @@
DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
/* End PBXBuildFile section */
-/* Begin PBXBuildStyle section */
- 842065AF0B98D65200CA7A69 /* Development */ = {
- isa = PBXBuildStyle;
- buildSettings = {
- COPY_PHASE_STRIP = NO;
- };
- name = Development;
- };
- 842065B00B98D65200CA7A69 /* Deployment */ = {
- isa = PBXBuildStyle;
- buildSettings = {
- COPY_PHASE_STRIP = YES;
- };
- name = Deployment;
- };
-/* End PBXBuildStyle section */
-
/* Begin PBXCopyFilesBuildPhase section */
8DD76F690486A84900D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
@@ -493,15 +476,12 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
- buildSettings = {
- };
- buildStyles = (
- 842065AF0B98D65200CA7A69 /* Development */,
- 842065B00B98D65200CA7A69 /* Deployment */,
- );
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
+ projectRoot = "";
+ shouldCheckCompatibility = 1;
targets = (
8DD76F620486A84900D96B5E /* clang */,
);
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:27 2007
@@ -471,7 +471,15 @@
DIAG(err_alignof_incomplete_type, ERROR,
"invalid application of '__alignof' to an incomplete type '%s'")
DIAG(err_invalid_suffix_integer_constant, ERROR,
- "invalid suffix on integer constant")
+ "invalid suffix '%s' on integer constant")
+DIAG(err_invalid_suffix_float_constant, ERROR,
+ "invalid suffix '%s' on floating constant")
+DIAG(err_exponent_has_no_digits, ERROR,
+ "exponent has no digits")
+DIAG(err_too_many_decimal_points, ERROR,
+ "too many decimal points in number")
+DIAG(err_hexconstant_requires_exponent, ERROR,
+ "hexadecimal floating constants require an exponent")
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
Modified: cfe/cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Action.h?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:43:27 2007
@@ -263,8 +263,7 @@
tok::TokenKind Kind) {
return 0;
}
- virtual ExprResult ParseIntegerLiteral(SourceLocation Loc) { return 0; }
- virtual ExprResult ParseFloatingLiteral(SourceLocation Loc) { return 0; }
+ virtual ExprResult ParseNumericConstant(const LexerToken &) { return 0; }
/// ParseStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz").
Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=39349&r1=39348&r2=39349&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:43:27 2007
@@ -291,7 +291,6 @@
return ParseParenExpression(Op, CastTy, RParenLoc);
}
ExprResult ParseStringLiteralExpression();
- ExprResult ParseNumericConstant();
//===--------------------------------------------------------------------===//
// C++ 5.2p1: C++ Casts
More information about the cfe-commits
mailing list