aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@home.transmeta.com>2003-03-30 22:30:28 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 20:59:55 -0700
commit9d2258c5def38d3c161e8c2750b6e9fe62449bb3 (patch)
tree1c07cd993957263d15f36b4122e85d103ff4c294
parentc6555e8346ccaadb00d1fbe1e2ac83c452f4750b (diff)
downloadsparse-dev-9d2258c5def38d3c161e8c2750b6e9fe62449bb3.tar.gz
Start doing constant strings right: do proper concatenation of strings,
and evaluate their type to be arrays of char rather than just a pointer.
-rw-r--r--evaluate.c31
-rw-r--r--expression.c41
-rw-r--r--expression.h4
-rw-r--r--show-parse.c3
-rw-r--r--token.h1
-rw-r--r--tokenize.c34
6 files changed, 91 insertions, 23 deletions
diff --git a/evaluate.c b/evaluate.c
index 475ed525..56dad071 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -124,6 +124,21 @@ static int get_int_value(struct expression *expr, const char *str)
return 1;
}
+static int evaluate_string(struct expression *expr)
+{
+ struct symbol *sym = alloc_symbol(expr->pos, SYM_ARRAY);
+ int length = expr->string->length;
+
+ sym->array_size = length;
+ sym->bit_size = BITS_IN_CHAR * length;
+ sym->alignment = 1;
+
+ sym->ctype.modifiers = MOD_CONST;
+ sym->ctype.base_type = &char_ctype;
+ expr->ctype = sym;
+ return 1;
+}
+
static int evaluate_constant(struct expression *expr)
{
struct token *token = expr->token;
@@ -720,6 +735,11 @@ int evaluate_expression(struct expression *expr)
switch (expr->type) {
case EXPR_CONSTANT:
return evaluate_constant(expr);
+ case EXPR_VALUE:
+ warn(expr->pos, "value expression without a type");
+ return 0;
+ case EXPR_STRING:
+ return evaluate_string(expr);
case EXPR_SYMBOL:
return evaluate_symbol(expr);
case EXPR_BINOP:
@@ -762,8 +782,15 @@ int evaluate_expression(struct expression *expr)
return evaluate_dereference(expr);
case EXPR_CALL:
return evaluate_call(expr);
- default:
- break;
+ case EXPR_BITFIELD:
+ warn(expr->pos, "bitfield generated by parser");
+ return 0;
+ case EXPR_CONDITIONAL:
+ // FIXME!! Conditional expression
+ return 0;
+ case EXPR_STATEMENT:
+ // FIXME!! Statement expression
+ return 0;
}
return 0;
}
diff --git a/expression.c b/expression.c
index aff176b1..e2d41ccf 100644
--- a/expression.c
+++ b/expression.c
@@ -53,6 +53,37 @@ struct token *parens_expression(struct token *token, struct expression **expr, c
return expect(token, ')', where);
}
+static struct token *string_expression(struct token *token, struct expression *expr)
+{
+ struct string *string = token->string;
+ struct token *next = token->next;
+
+ if (token_type(next) == TOKEN_STRING) {
+ int totlen = string->length;
+ char *data;
+
+ do {
+ totlen += next->string->length-1;
+ next = next->next;
+ } while (token_type(next) == TOKEN_STRING);
+
+ string = __alloc_string(totlen);
+ string->length = totlen;
+ data = string->data;
+ next = token;
+ do {
+ struct string *s = next->string;
+ int len = s->length;
+
+ next = next->next;
+ memcpy(data, s->data, len);
+ data += len-1;
+ } while (token_type(next) == TOKEN_STRING);
+ }
+ expr->string = string;
+ return next;
+}
+
struct token *primary_expression(struct token *token, struct expression **tree)
{
struct expression *expr = NULL;
@@ -74,13 +105,11 @@ struct token *primary_expression(struct token *token, struct expression **tree)
break;
}
- case TOKEN_STRING:
- expr = alloc_expression(token->pos, EXPR_CONSTANT);
- expr->token = token;
- do {
- token = token->next;
- } while (token_type(token) == TOKEN_STRING);
+ case TOKEN_STRING: {
+ expr = alloc_expression(token->pos, EXPR_STRING);
+ token = string_expression(token, expr);
break;
+ }
case TOKEN_SPECIAL:
if (token->special == '(') {
diff --git a/expression.h b/expression.h
index f7be851f..21297b58 100644
--- a/expression.h
+++ b/expression.h
@@ -13,6 +13,7 @@ struct expression_list;
enum expression_type {
EXPR_CONSTANT,
EXPR_VALUE,
+ EXPR_STRING,
EXPR_SYMBOL,
EXPR_BINOP,
EXPR_ASSIGNMENT,
@@ -41,6 +42,9 @@ struct expression {
// EXPR_VALUE
unsigned long long value;
+ // EXPR_STRING
+ struct string *string;
+
// EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP
struct expression *unop;
diff --git a/show-parse.c b/show-parse.c
index 0a55a21b..7e720933 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -445,6 +445,9 @@ void show_expression(struct expression *expr)
case EXPR_VALUE:
printf("(%lld)", expr->value);
break;
+ case EXPR_STRING:
+ printf("%s", show_string(expr->string));
+ break;
case EXPR_SIZEOF:
printf("sizeof(");
if (expr->cast_type)
diff --git a/token.h b/token.h
index 89305753..b34d648c 100644
--- a/token.h
+++ b/token.h
@@ -143,6 +143,7 @@ extern struct ident *built_in_ident(const char *);
extern struct token *built_in_token(int, const char *);
extern const char *show_special(int);
extern const char *show_ident(const struct ident *);
+extern const char *show_string(const struct string *string);
extern const char *show_token(const struct token *);
extern struct token * tokenize(const char *, int, struct token *);
extern struct token * tokenize_buffer(unsigned char *, unsigned long, struct token *);
diff --git a/tokenize.c b/tokenize.c
index 8169ec65..27fc8354 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -78,6 +78,23 @@ char *charstr(char *ptr, unsigned char c, unsigned char escape, unsigned char ne
return ptr + sprintf(ptr, "%03o", c);
}
+const char *show_string(const struct string *string)
+{
+ static char buffer[256];
+ char *ptr;
+ int i;
+
+ ptr = buffer;
+ *ptr++ = '"';
+ for (i = 0; i < string->length-1; i++) {
+ const unsigned char *p = string->data + i;
+ ptr = charstr(ptr, p[0], '"', p[1]);
+ }
+ *ptr++ = '"';
+ *ptr = '\0';
+ return buffer;
+}
+
const char *show_token(const struct token *token)
{
static char buffer[256];
@@ -94,21 +111,8 @@ const char *show_token(const struct token *token)
case TOKEN_IDENT:
return show_ident(token->ident);
- case TOKEN_STRING: {
- char *ptr;
- int i;
- struct string *string = token->string;
-
- ptr = buffer;
- *ptr++ = '"';
- for (i = 0; i < string->length-1; i++) {
- unsigned char *p = string->data + i;
- ptr = charstr(ptr, p[0], '"', p[1]);
- }
- *ptr++ = '"';
- *ptr = '\0';
- return buffer;
- }
+ case TOKEN_STRING:
+ return show_string(token->string);
case TOKEN_INTEGER: {
const char *p = token->integer;