diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-10-08 09:40:53 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:03:33 -0700 |
| commit | 744bd80a0bc48ecd4fccb745cb357550a83101fd (patch) | |
| tree | 0fb53b32e31a64950da4ac7d0fac674de3875792 | |
| parent | 30fbaa8a02f8c726a6faf1be1e346c038f929dfb (diff) | |
| download | sparse-dev-744bd80a0bc48ecd4fccb745cb357550a83101fd.tar.gz | |
Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ the same
way, and give them a real string.
This means that __func__ actually works as a constant string,
not as a pseudo-symbol, which is wrong. But hey, sue me.
| -rw-r--r-- | evaluate.c | 2 | ||||
| -rw-r--r-- | expression.c | 59 | ||||
| -rw-r--r-- | ident-list.h | 2 | ||||
| -rw-r--r-- | lib.c | 5 | ||||
| -rw-r--r-- | parse.c | 29 | ||||
| -rw-r--r-- | symbol.h | 3 |
6 files changed, 68 insertions, 32 deletions
@@ -25,7 +25,7 @@ #include "target.h" #include "expression.h" -static struct symbol *current_fn; +struct symbol *current_fn; static int current_context, current_contextmask; static struct symbol *degenerate(struct expression *expr); diff --git a/expression.c b/expression.c index f0ec5721..b450b677 100644 --- a/expression.c +++ b/expression.c @@ -59,11 +59,66 @@ struct token *parens_expression(struct token *token, struct expression **expr, c return expect(token, ')', where); } +/* + * Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ token + * conversion + */ +static int convert_one_fn_token(struct token *token) +{ + struct symbol *sym = current_fn; + + if (sym) { + struct ident *ident = sym->ident; + if (ident) { + int len = ident->len; + struct string *string; + + string = __alloc_string(len+1); + memcpy(string->data, ident->name, len); + string->data[len] = 0; + string->length = len+1; + token_type(token) = TOKEN_STRING; + token->string = string; + return 1; + } + } + return 0; +} + +static int convert_function(struct token *next) +{ + int retval = 0; + for (;;) { + struct token *token = next; + next = next->next; + switch (token_type(token)) { + case TOKEN_STRING: + continue; + case TOKEN_IDENT: + if (token->ident == &__func___ident || + token->ident == &__FUNCTION___ident || + token->ident == &__PRETTY_FUNCTION___ident) { + if (!convert_one_fn_token(token)) + break; + retval = 1; + continue; + } + /* Fall through */ + default: + break; + } + break; + } + return retval; +} + static struct token *string_expression(struct token *token, struct expression *expr) { struct string *string = token->string; struct token *next = token->next; + convert_function(token); + if (token_type(next) == TOKEN_STRING) { int totlen = string->length-1; char *data; @@ -248,6 +303,9 @@ struct token *primary_expression(struct token *token, struct expression **tree) struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF); struct token *next = token->next; + if (!sym && convert_function(token)) + goto handle_string; + expr = alloc_expression(token->pos, EXPR_SYMBOL); /* @@ -267,6 +325,7 @@ struct token *primary_expression(struct token *token, struct expression **tree) } case TOKEN_STRING: { + handle_string: expr = alloc_expression(token->pos, EXPR_STRING); token = string_expression(token, expr); break; diff --git a/ident-list.h b/ident-list.h index e7eed0c2..67374581 100644 --- a/ident-list.h +++ b/ident-list.h @@ -59,6 +59,8 @@ __IDENT(__VA_ARGS___ident, "__VA_ARGS__", 0); __IDENT(__LINE___ident, "__LINE__", 0); __IDENT(__FILE___ident, "__FILE__", 0); __IDENT(__func___ident, "__func__", 0); +__IDENT(__FUNCTION___ident, "__FUNCTION__", 0); +__IDENT(__PRETTY_FUNCTION___ident, "__PRETTY_FUNCTION__", 0); #undef __IDENT #undef IDENT @@ -786,9 +786,4 @@ void create_builtin_stream(void) add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); add_pre_buffer("#define __builtin_va_arg(arg,type) ((type)0)\n"); add_pre_buffer("#define __builtin_va_end(arg)\n"); - // These live somewhere between parse-land (they need to know the - // function name) and pre-processor-land (they concatenate with - // strings). Punt. - add_pre_buffer("#define __FUNCTION__ \"function\"\n"); - add_pre_buffer("#define __PRETTY_FUNCTION__ \"function\"\n"); } @@ -1043,38 +1043,15 @@ static struct statement *start_function(struct symbol *sym) stmt->ret = ret; fn_local_symbol(ret); - // static const char __func__[] = "function-name"; - if (sym->ident) { - struct symbol *funcname = alloc_symbol(sym->pos, SYM_NODE); - struct symbol *array = alloc_symbol(sym->pos, SYM_ARRAY); - struct expression *expr = alloc_expression(sym->pos, EXPR_STRING); - int len = sym->ident->len; - struct string *string = __alloc_string(len+1); - - array->ctype.base_type = &char_ctype; - array->ctype.modifiers = MOD_CONST | MOD_STATIC; - - memcpy(string->data, sym->ident->name, len); - string->data[len] = '\0'; - string->length = len + 1; - - expr->string = string; - - funcname->initializer = expr; - funcname->ctype.modifiers = array->ctype.modifiers; - funcname->ctype.base_type = array; - funcname->ident = &__func___ident; - bind_symbol(funcname, &__func___ident, NS_SYMBOL); - - add_symbol(&stmt->syms, funcname); - fn_local_symbol(funcname); - } + // Currently parsed symbol for __func__/__FUNCTION__/__PRETTY_FUNCTION__ + current_fn = sym; return stmt; } static void end_function(struct symbol *sym) { + current_fn = NULL; end_function_scope(); } @@ -156,6 +156,9 @@ struct symbol { #define MOD_EXPLICITLY_SIGNED 0x40000000 #define MOD_BITWISE 0x80000000 +/* Current parsing/evaluation function */ +extern struct symbol *current_fn; + /* Basic types */ extern struct symbol void_type, int_type, |
