[cfe-commits] r39351 - in /cfe/cfe/trunk: AST/SemaExpr.cpp Lex/LiteralSupport.cpp Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/AST/Expr.h include/clang/Lex/LiteralSupport.h
snaroff at cs.uiuc.edu
snaroff at cs.uiuc.edu
Wed Jul 11 09:43:29 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:43:29 2007
New Revision: 39351
URL: http://llvm.org/viewvc/llvm-project?rev=39351&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Moved numeric literal support from SemaExpr.cpp to LiteralSupport.[h,cpp]
in Lex. This will allow it to be used by both Sema and Preprocessor (and
should be the last major refactoring of this sub-system).. Over
time, it will be reused by anyone implementing an actions module (i.e.
any subclass of llvm::clang::Action. Minor changes to IntegerLiteral in Expr.h.
More to come...
Added:
cfe/cfe/trunk/Lex/LiteralSupport.cpp (with props)
cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h (with props)
Modified:
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
cfe/cfe/trunk/include/clang/AST/Expr.h
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39351&r1=39350&r2=39351&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:29 2007
@@ -16,6 +16,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LiteralSupport.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
@@ -24,7 +25,7 @@
using namespace llvm;
using namespace clang;
-
+#include <iostream>
/// HexDigitValue - Return the value of the specified hex digit, or -1 if it's
/// not valid.
@@ -285,68 +286,6 @@
}
}
-/// SkipHexDigits - Read and skip over any hex digits, up to End.
-/// Return a pointer to the first non-hex digit or End.
-static const char *SkipHexDigits(const char *ptr, const char *end) {
- while (ptr != end && isxdigit(*ptr))
- ptr++;
- return ptr;
-}
-
-/// SkipOctalDigits - Read and skip over any octal digits, up to End.
-/// Return a pointer to the first non-hex digit or End.
-static const char *SkipOctalDigits(const char *ptr, const char *end) {
- while (ptr != end && ((*ptr >= '0') && (*ptr <= '7')))
- ptr++;
- return ptr;
-}
-
-/// SkipDigits - Read and skip over any digits, up to End.
-/// Return a pointer to the first non-hex digit or End.
-static const char *SkipDigits(const char *ptr, const char *end) {
- while (ptr != end && isdigit(*ptr))
- ptr++;
- return ptr;
-}
-
-/// 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());
@@ -360,148 +299,37 @@
// 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());
+ if (ActualLength == 1)
+ return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
+
+ NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
+ Tok.getLocation(), PP, Context.Target);
+ if (Literal.hadError) {
+ return ExprResult(true);
}
- 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]) || s[1] == '.')) {
- s++;
- radix = 16;
- s = SkipHexDigits(s, ThisTokEnd);
- if (s == ThisTokEnd) {
- } else if (*s == '.') {
- s++;
- saw_period = true;
- s = SkipHexDigits(s, ThisTokEnd);
- }
- // A binary exponent can appear with or with a '.'. If dotted, the
- // binary exponent is required.
- if (*s == 'p' || *s == 'P') {
- s++;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s, ThisTokEnd);
- if (first_non_digit == s) {
- Diag(Tok, diag::err_exponent_has_no_digits);
- return ExprResult(true);
- } else {
- s = first_non_digit;
- }
- } else if (saw_period) {
- Diag(Tok, diag::err_hexconstant_requires_exponent);
- return ExprResult(true);
- }
+ Expr *literal_expr;
+
+ if (Literal.isIntegerLiteral()) {
+ TypeRef t;
+ if (Literal.hasSuffix()) {
+ if (Literal.isLong)
+ t = Literal.isUnsigned ? Context.UnsignedLongTy : Context.LongTy;
+ else if (Literal.isLongLong)
+ t = Literal.isUnsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
+ else
+ t = Context.UnsignedIntTy;
} 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;
- s = SkipOctalDigits(s, ThisTokEnd);
- if (s == ThisTokEnd) {
- } else if (*s == '.') {
- s++;
- radix = 10;
- saw_period = true;
- s = SkipDigits(s, ThisTokEnd);
- }
- if (*s == 'e' || *s == 'E') { // exponent
- s++;
- radix = 10;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s, ThisTokEnd);
- if (first_non_digit == s) {
- Diag(Tok, diag::err_exponent_has_no_digits);
- return ExprResult(true);
- } else {
- s = first_non_digit;
- }
- }
+ t = Context.IntTy; // implicit type is "int"
}
- } else { // the first digit is non-zero
- radix = 10;
- s = SkipDigits(s, ThisTokEnd);
- if (s == ThisTokEnd) {
- } else if (*s == '.') {
- s++;
- saw_period = true;
- s = SkipDigits(s, ThisTokEnd);
+ intmax_t val;
+ if (Literal.GetValue(val)) {
+ literal_expr = new IntegerLiteral(val, t);
}
- if (*s == 'e' || *s == 'E') { // exponent
- s++;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s, ThisTokEnd);
- if (first_non_digit == s) {
- Diag(Tok, diag::err_exponent_has_no_digits);
- return ExprResult(true);
- } else {
- s = first_non_digit;
- }
- }
- }
-
- const char *suffix_start = s;
-
- if (saw_period || saw_exponent) {
- bool saw_float_suffix = false, saw_long_suffix = false;
-
- if (s < ThisTokEnd) { // parse size suffix (float, long double)
- if (*s == 'f' || *s == 'F') {
- saw_float_suffix = true;
- s++;
- } else if (*s == 'l' || *s == 'L') {
- saw_long_suffix = true;
- s++;
- }
- if (s != ThisTokEnd) {
- 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, saw_long = false, saw_longlong = false;
-
- // 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) break; // only allowed to have one
- saw_unsigned = true;
- s++;
- } else if (*s == 'l' || *s == 'L') {
- if (saw_long || saw_longlong) break; // only allowed to have one
- s++;
- if (s < ThisTokEnd && (*s == *(s-1))) {
- saw_longlong = true; // l's need to be adjacent and same case.
- s++;
- } else {
- saw_long = true;
- }
- } else {
- break;
- }
- }
- if (s != ThisTokEnd) {
- Diag(Tok, diag::err_invalid_suffix_integer_constant,
- std::string(suffix_start, ThisTokEnd));
- return ExprResult(true);
- }
- literal_expr = new IntegerLiteral();
+ } else if (Literal.isFloatingLiteral()) {
+ // TODO: add floating point processing...
}
- return ExprResult(literal_expr);
}
Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,
Added: cfe/cfe/trunk/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/LiteralSupport.cpp?rev=39351&view=auto
==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (added)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:43:29 2007
@@ -0,0 +1,244 @@
+//===--- LiteralSupport.cpp - Code to parse and process literals-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Steve Naroff and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the NumericLiteralParser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Diagnostic.h"
+
+using namespace llvm;
+using namespace clang;
+
+/// 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...
+///
+
+NumericLiteralParser::
+NumericLiteralParser(const char *begin, const char *end,
+ SourceLocation TokLoc, Preprocessor &pp, TargetInfo &t) :
+ PP(pp), Target(t), ThisTokBegin(begin), ThisTokEnd(end)
+{
+ s = DigitsBegin = begin;
+ saw_exponent = false;
+ saw_period = false;
+ saw_float_suffix = false;
+ isLong = false;
+ isUnsigned = false;
+ isLongLong = false;
+ hadError = false;
+
+ if (*s == '0') { // parse radix
+ s++;
+ if ((*s == 'x' || *s == 'X') && (isxdigit(s[1]) || s[1] == '.')) {
+ s++;
+ radix = 16;
+ DigitsBegin = s;
+ s = SkipHexDigits(s);
+ if (s == ThisTokEnd) {
+ } else if (*s == '.') {
+ s++;
+ saw_period = true;
+ s = SkipHexDigits(s);
+ }
+ // A binary exponent can appear with or with a '.'. If dotted, the
+ // binary exponent is required.
+ if (*s == 'p' || *s == 'P') {
+ s++;
+ saw_exponent = true;
+ if (*s == '+' || *s == '-') s++; // sign
+ const char *first_non_digit = SkipDigits(s);
+ if (first_non_digit == s) {
+ Diag(TokLoc, diag::err_exponent_has_no_digits);
+ return;
+ } else {
+ s = first_non_digit;
+ }
+ } else if (saw_period) {
+ Diag(TokLoc, diag::err_hexconstant_requires_exponent);
+ return;
+ }
+ } 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;
+ DigitsBegin = s;
+ s = SkipOctalDigits(s);
+ if (s == ThisTokEnd) {
+ } else if (*s == '.') {
+ s++;
+ radix = 10;
+ saw_period = true;
+ s = SkipDigits(s);
+ }
+ if (*s == 'e' || *s == 'E') { // exponent
+ s++;
+ radix = 10;
+ saw_exponent = true;
+ if (*s == '+' || *s == '-') s++; // sign
+ const char *first_non_digit = SkipDigits(s);
+ if (first_non_digit == s) {
+ Diag(TokLoc, diag::err_exponent_has_no_digits);
+ return;
+ } else {
+ s = first_non_digit;
+ }
+ }
+ }
+ } else { // the first digit is non-zero
+ radix = 10;
+ s = SkipDigits(s);
+ if (s == ThisTokEnd) {
+ } else if (*s == '.') {
+ s++;
+ saw_period = true;
+ s = SkipDigits(s);
+ }
+ if (*s == 'e' || *s == 'E') { // exponent
+ s++;
+ saw_exponent = true;
+ if (*s == '+' || *s == '-') s++; // sign
+ const char *first_non_digit = SkipDigits(s);
+ if (first_non_digit == s) {
+ Diag(TokLoc, diag::err_exponent_has_no_digits);
+ return;
+ } else {
+ s = first_non_digit;
+ }
+ }
+ }
+
+ SuffixBegin = s;
+
+ if (saw_period || saw_exponent) {
+ if (s < ThisTokEnd) { // parse size suffix (float, long double)
+ if (*s == 'f' || *s == 'F') {
+ saw_float_suffix = true;
+ s++;
+ } else if (*s == 'l' || *s == 'L') {
+ isLong = true;
+ s++;
+ }
+ if (s != ThisTokEnd) {
+ Diag(TokLoc, diag::err_invalid_suffix_float_constant,
+ std::string(SuffixBegin, ThisTokEnd));
+ return;
+ }
+ }
+ } else {
+ if (s < ThisTokEnd) {
+ // parse int suffix - they can appear in any order ("ul", "lu", "llu").
+ if (*s == 'u' || *s == 'U') {
+ s++;
+ isUnsigned = true; // unsigned
+
+ if ((s < ThisTokEnd) && (*s == 'l' || *s == 'L')) {
+ s++;
+ // handle "long long" type - l's need to be adjacent and same case.
+ if ((s < ThisTokEnd) && (*s == *(s-1))) {
+ isLongLong = true; // unsigned long long
+ s++;
+ } else {
+ isLong = true; // unsigned long
+ }
+ }
+ } else if (*s == 'l' || *s == 'L') {
+ s++;
+ // handle "long long" types - l's need to be adjacent and same case.
+ if ((s < ThisTokEnd) && (*s == *(s-1))) {
+ s++;
+ if ((s < ThisTokEnd) && (*s == 'u' || *s == 'U')) {
+ isUnsigned = true; // unsigned long long
+ s++;
+ } else {
+ isLongLong = true; // long long
+ }
+ } else { // handle "long" types
+ if ((s < ThisTokEnd) && (*s == 'u' || *s == 'U')) {
+ isUnsigned = true; // unsigned long
+ s++;
+ } else {
+ isLong = true; // long
+ }
+ }
+ }
+ if (s != ThisTokEnd) {
+ Diag(TokLoc, diag::err_invalid_suffix_integer_constant,
+ std::string(SuffixBegin, ThisTokEnd));
+ return;
+ }
+ }
+ }
+}
+
+bool NumericLiteralParser::GetValue(intmax_t &val) {
+ intmax_t cutoff = INTMAX_MAX;
+ int cutlim = cutoff % radix;
+ char c;
+
+ val = 0;
+ cutoff /= radix;
+ s = DigitsBegin;
+ while (s < SuffixBegin) {
+ c = *s++;
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'F') // 10...15
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'f') // 10...15
+ c -= 'a' - 10;
+
+ if (val > cutoff || (val == cutoff && c > cutlim)) {
+ return false; // Overflow!
+ } else {
+ val *= radix;
+ val += c;
+ }
+ }
+ return true;
+}
Propchange: cfe/cfe/trunk/Lex/LiteralSupport.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/cfe/trunk/Lex/LiteralSupport.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39351&r1=39350&r2=39351&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:29 2007
@@ -16,6 +16,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LiteralSupport.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
@@ -24,7 +25,7 @@
using namespace llvm;
using namespace clang;
-
+#include <iostream>
/// HexDigitValue - Return the value of the specified hex digit, or -1 if it's
/// not valid.
@@ -285,68 +286,6 @@
}
}
-/// SkipHexDigits - Read and skip over any hex digits, up to End.
-/// Return a pointer to the first non-hex digit or End.
-static const char *SkipHexDigits(const char *ptr, const char *end) {
- while (ptr != end && isxdigit(*ptr))
- ptr++;
- return ptr;
-}
-
-/// SkipOctalDigits - Read and skip over any octal digits, up to End.
-/// Return a pointer to the first non-hex digit or End.
-static const char *SkipOctalDigits(const char *ptr, const char *end) {
- while (ptr != end && ((*ptr >= '0') && (*ptr <= '7')))
- ptr++;
- return ptr;
-}
-
-/// SkipDigits - Read and skip over any digits, up to End.
-/// Return a pointer to the first non-hex digit or End.
-static const char *SkipDigits(const char *ptr, const char *end) {
- while (ptr != end && isdigit(*ptr))
- ptr++;
- return ptr;
-}
-
-/// 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());
@@ -360,148 +299,37 @@
// 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());
+ if (ActualLength == 1)
+ return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
+
+ NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
+ Tok.getLocation(), PP, Context.Target);
+ if (Literal.hadError) {
+ return ExprResult(true);
}
- 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]) || s[1] == '.')) {
- s++;
- radix = 16;
- s = SkipHexDigits(s, ThisTokEnd);
- if (s == ThisTokEnd) {
- } else if (*s == '.') {
- s++;
- saw_period = true;
- s = SkipHexDigits(s, ThisTokEnd);
- }
- // A binary exponent can appear with or with a '.'. If dotted, the
- // binary exponent is required.
- if (*s == 'p' || *s == 'P') {
- s++;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s, ThisTokEnd);
- if (first_non_digit == s) {
- Diag(Tok, diag::err_exponent_has_no_digits);
- return ExprResult(true);
- } else {
- s = first_non_digit;
- }
- } else if (saw_period) {
- Diag(Tok, diag::err_hexconstant_requires_exponent);
- return ExprResult(true);
- }
+ Expr *literal_expr;
+
+ if (Literal.isIntegerLiteral()) {
+ TypeRef t;
+ if (Literal.hasSuffix()) {
+ if (Literal.isLong)
+ t = Literal.isUnsigned ? Context.UnsignedLongTy : Context.LongTy;
+ else if (Literal.isLongLong)
+ t = Literal.isUnsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
+ else
+ t = Context.UnsignedIntTy;
} 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;
- s = SkipOctalDigits(s, ThisTokEnd);
- if (s == ThisTokEnd) {
- } else if (*s == '.') {
- s++;
- radix = 10;
- saw_period = true;
- s = SkipDigits(s, ThisTokEnd);
- }
- if (*s == 'e' || *s == 'E') { // exponent
- s++;
- radix = 10;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s, ThisTokEnd);
- if (first_non_digit == s) {
- Diag(Tok, diag::err_exponent_has_no_digits);
- return ExprResult(true);
- } else {
- s = first_non_digit;
- }
- }
+ t = Context.IntTy; // implicit type is "int"
}
- } else { // the first digit is non-zero
- radix = 10;
- s = SkipDigits(s, ThisTokEnd);
- if (s == ThisTokEnd) {
- } else if (*s == '.') {
- s++;
- saw_period = true;
- s = SkipDigits(s, ThisTokEnd);
+ intmax_t val;
+ if (Literal.GetValue(val)) {
+ literal_expr = new IntegerLiteral(val, t);
}
- if (*s == 'e' || *s == 'E') { // exponent
- s++;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s, ThisTokEnd);
- if (first_non_digit == s) {
- Diag(Tok, diag::err_exponent_has_no_digits);
- return ExprResult(true);
- } else {
- s = first_non_digit;
- }
- }
- }
-
- const char *suffix_start = s;
-
- if (saw_period || saw_exponent) {
- bool saw_float_suffix = false, saw_long_suffix = false;
-
- if (s < ThisTokEnd) { // parse size suffix (float, long double)
- if (*s == 'f' || *s == 'F') {
- saw_float_suffix = true;
- s++;
- } else if (*s == 'l' || *s == 'L') {
- saw_long_suffix = true;
- s++;
- }
- if (s != ThisTokEnd) {
- 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, saw_long = false, saw_longlong = false;
-
- // 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) break; // only allowed to have one
- saw_unsigned = true;
- s++;
- } else if (*s == 'l' || *s == 'L') {
- if (saw_long || saw_longlong) break; // only allowed to have one
- s++;
- if (s < ThisTokEnd && (*s == *(s-1))) {
- saw_longlong = true; // l's need to be adjacent and same case.
- s++;
- } else {
- saw_long = true;
- }
- } else {
- break;
- }
- }
- if (s != ThisTokEnd) {
- Diag(Tok, diag::err_invalid_suffix_integer_constant,
- std::string(suffix_start, ThisTokEnd));
- return ExprResult(true);
- }
- literal_expr = new IntegerLiteral();
+ } else if (Literal.isFloatingLiteral()) {
+ // TODO: add floating point processing...
}
- 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=39351&r1=39350&r2=39351&view=diff
==============================================================================
--- cfe/cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/cfe/trunk/clang.xcodeproj/project.pbxproj Wed Jul 11 11:43:29 2007
@@ -8,6 +8,8 @@
/* Begin PBXBuildFile section */
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
+ 1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
+ 1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06B73D0A8307640050E87E /* LangOptions.h */; };
DE06BECB0A854E4B0050E87E /* Scope.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06BECA0A854E4B0050E87E /* Scope.h */; };
@@ -145,6 +147,7 @@
DED67AEE0B6DB92A00AAD4A3 /* X86Builtins.def in CopyFiles */,
DED67AF00B6DB92F00AAD4A3 /* PPCBuiltins.def in CopyFiles */,
1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */,
+ 1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
@@ -152,6 +155,8 @@
/* Begin PBXFileReference section */
1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
+ 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
+ 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
@@ -415,6 +420,7 @@
DED7D73F0A524295003AD0FB /* Pragma.h */,
DED7D7400A524295003AD0FB /* Preprocessor.h */,
DED7D9170A52518C003AD0FB /* ScratchBuffer.h */,
+ 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */,
);
name = Lex;
path = clang/Lex;
@@ -436,6 +442,7 @@
DED7D78C0A5242E6003AD0FB /* Lex */ = {
isa = PBXGroup;
children = (
+ 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */,
DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */,
DED7D79D0A5242E6003AD0FB /* IdentifierTable.cpp */,
DED7D79E0A5242E6003AD0FB /* Lexer.cpp */,
@@ -534,6 +541,7 @@
DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */,
DE1737A90B0847BC0080B521 /* SemaType.cpp in Sources */,
DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */,
+ 1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39351&r1=39350&r2=39351&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:43:29 2007
@@ -60,9 +60,30 @@
static bool classof(const DeclRefExpr *) { return true; }
};
+
+// FIXME: The "type" will eventually be moved to Stmt.
class IntegerLiteral : public Expr {
-public:
- IntegerLiteral() : Expr(IntegerLiteralClass) {}
+ TypeRef Type; // IntTy, LongTy, LongLongTy
+ // UnsignedIntTy, UnsignedLongTy, UnsignedLongLongTy
+ intmax_t Value;
+public:
+ // FIXME: To satisfy some of the current adhoc usage...
+ IntegerLiteral() : Expr(IntegerLiteralClass),
+ Type(0), Value(0) {
+ }
+ // constructor for the single digit case
+ IntegerLiteral(intmax_t value) : Expr(IntegerLiteralClass),
+ Type(0), Value(value) {
+ }
+ IntegerLiteral(intmax_t value, TypeRef type)
+ : Expr(IntegerLiteralClass), Type(type), Value(value) {
+#if 0
+ std::cout << "Value=" << Value;
+ std::cout << " Type= ";
+ std::cout << static_cast<BuiltinType *>(type.getTypePtr())->getName();
+ std::cout << "\n";
+#endif
+ }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == IntegerLiteralClass;
Added: cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=39351&view=auto
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h (added)
+++ cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h Wed Jul 11 11:43:29 2007
@@ -0,0 +1,101 @@
+//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Steve Naroff and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the NumericLiteralParser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LITERALSUPPORT_H
+#define LLVM_CLANG_LITERALSUPPORT_H
+
+#include "clang/Lex/Preprocessor.h"
+
+namespace llvm {
+namespace clang {
+
+class Diagnostic;
+class Preprocessor;
+class TargetInfo;
+
+struct NumericLiteralParser {
+ NumericLiteralParser(const char *begin, const char *end,
+ SourceLocation Loc, Preprocessor &PP, TargetInfo &T);
+private:
+ Preprocessor &PP; // needed for diagnostics
+ TargetInfo &Target; // needed to compute the size
+
+ const char *const ThisTokBegin;
+ const char *const ThisTokEnd;
+ const char *DigitsBegin, *SuffixBegin; // markers
+ const char *s; // cursor
+
+ unsigned int radix;
+
+ bool saw_exponent, saw_period;
+ bool saw_float_suffix;
+
+public:
+ bool hadError;
+ bool isUnsigned;
+ bool isLong;
+ bool isLongLong;
+
+ bool isIntegerLiteral() {
+ return !saw_period && !saw_exponent ? true : false;
+ }
+ bool isFloatingLiteral() {
+ return saw_period || saw_exponent ? true : false;
+ }
+ bool hasSuffix() {
+ return SuffixBegin != ThisTokEnd;
+ }
+ /// getValue - Convert the string into a number. At this point, we know
+ /// the digit characters are valid (0...9, a...f, A...F). We don't know
+ /// how many bits are needed to store the number. We return true if the
+ /// value fit into intmax_t (typically 64-bit's), false otherwise. This
+ /// API will likely be replaced by sizing hooks and APInt. Nevertheless,
+ /// this provides basic conversion support for now.
+ bool GetValue(intmax_t &val);
+
+private:
+ void Diag(SourceLocation Loc, unsigned DiagID,
+ const std::string &M = std::string()) {
+ PP.Diag(Loc, DiagID, M);
+ hadError = true;
+ }
+
+ /// SkipHexDigits - Read and skip over any hex digits, up to End.
+ /// Return a pointer to the first non-hex digit or End.
+ const char *SkipHexDigits(const char *ptr) {
+ while (ptr != ThisTokEnd && isxdigit(*ptr))
+ ptr++;
+ return ptr;
+ }
+
+ /// SkipOctalDigits - Read and skip over any octal digits, up to End.
+ /// Return a pointer to the first non-hex digit or End.
+ const char *SkipOctalDigits(const char *ptr) {
+ while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7')))
+ ptr++;
+ return ptr;
+ }
+
+ /// SkipDigits - Read and skip over any digits, up to End.
+ /// Return a pointer to the first non-hex digit or End.
+ const char *SkipDigits(const char *ptr) {
+ while (ptr != ThisTokEnd && isdigit(*ptr))
+ ptr++;
+ return ptr;
+ }
+};
+
+} // end namespace clang
+} // end namespace llvm
+
+#endif
\ No newline at end of file
Propchange: cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
More information about the cfe-commits
mailing list