aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family/c-lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-family/c-lex.c')
-rw-r--r--gcc/c-family/c-lex.c63
1 files changed, 57 insertions, 6 deletions
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index b151564..baee8eb 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -45,7 +45,7 @@ int pending_lang_change; /* If we need to switch languages - C++ only */
int c_header_level; /* depth in C headers - C++ only */
static tree interpret_integer (const cpp_token *, unsigned int);
-static tree interpret_float (const cpp_token *, unsigned int);
+static tree interpret_float (const cpp_token *, unsigned int, const char *);
static tree interpret_fixed (const cpp_token *, unsigned int);
static enum integer_type_kind narrowest_unsigned_type
(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
@@ -314,7 +314,8 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
case CPP_NUMBER:
{
- unsigned int flags = cpp_classify_number (parse_in, tok);
+ const char *suffix = NULL;
+ unsigned int flags = cpp_classify_number (parse_in, tok, &suffix);
switch (flags & CPP_N_CATEGORY)
{
@@ -332,12 +333,27 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
break;
case CPP_N_FLOATING:
- *value = interpret_float (tok, flags);
+ *value = interpret_float (tok, flags, suffix);
break;
default:
gcc_unreachable ();
}
+
+ if (flags & CPP_N_USERDEF)
+ {
+ tree suffix_id = get_identifier (suffix);
+ int len = tok->val.str.len - strlen (suffix);
+ tree num_string = build_string (len + 1,
+ (const char *) tok->val.str.text);
+ TREE_TYPE (num_string) = char_array_type_node;
+ num_string = fix_string_type (num_string);
+ char *str = CONST_CAST (char *, TREE_STRING_POINTER (num_string));
+ str[len] = '\0';
+ tree literal = build_userdef_literal (suffix_id, *value,
+ num_string);
+ *value = literal;
+ }
}
break;
@@ -415,6 +431,22 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
}
goto retry;
+ case CPP_CHAR_USERDEF:
+ case CPP_WCHAR_USERDEF:
+ case CPP_CHAR16_USERDEF:
+ case CPP_CHAR32_USERDEF:
+ {
+ tree literal;
+ cpp_token temp_tok = *tok;
+ const char *suffix = cpp_get_userdef_suffix (tok);
+ temp_tok.val.str.len -= strlen (suffix);
+ temp_tok.type = cpp_userdef_char_remove_type (type);
+ literal = build_userdef_literal (get_identifier (suffix),
+ lex_charconst (&temp_tok), NULL_TREE);
+ *value = literal;
+ }
+ break;
+
case CPP_CHAR:
case CPP_WCHAR:
case CPP_CHAR16:
@@ -422,6 +454,22 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
*value = lex_charconst (tok);
break;
+ case CPP_STRING_USERDEF:
+ case CPP_WSTRING_USERDEF:
+ case CPP_STRING16_USERDEF:
+ case CPP_STRING32_USERDEF:
+ case CPP_UTF8STRING_USERDEF:
+ {
+ tree literal, string;
+ const char *suffix = cpp_get_userdef_suffix (tok);
+ string = build_string (tok->val.str.len - strlen (suffix),
+ (const char *) tok->val.str.text);
+ literal = build_userdef_literal (get_identifier (suffix),
+ string, NULL_TREE);
+ *value = literal;
+ }
+ break;
+
case CPP_STRING:
case CPP_WSTRING:
case CPP_STRING16:
@@ -621,9 +669,10 @@ interpret_integer (const cpp_token *token, unsigned int flags)
}
/* Interpret TOKEN, a floating point number with FLAGS as classified
- by cpplib. */
+ by cpplib. For C++0X SUFFIX may contain a user-defined literal suffix. */
static tree
-interpret_float (const cpp_token *token, unsigned int flags)
+interpret_float (const cpp_token *token, unsigned int flags,
+ const char *suffix)
{
tree type;
tree const_type;
@@ -702,7 +751,9 @@ interpret_float (const cpp_token *token, unsigned int flags)
has any suffixes, cut them off; REAL_VALUE_ATOF/ REAL_VALUE_HTOF
can't handle them. */
copylen = token->val.str.len;
- if (flags & CPP_N_DFLOAT)
+ if (flags & CPP_N_USERDEF)
+ copylen -= strlen (suffix);
+ else if (flags & CPP_N_DFLOAT)
copylen -= 2;
else
{