aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/expression.c
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-10-08 09:40:53 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:03:33 -0700
commit744bd80a0bc48ecd4fccb745cb357550a83101fd (patch)
tree0fb53b32e31a64950da4ac7d0fac674de3875792 /expression.c
parent30fbaa8a02f8c726a6faf1be1e346c038f929dfb (diff)
downloadsparse-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.
Diffstat (limited to 'expression.c')
-rw-r--r--expression.c59
1 files changed, 59 insertions, 0 deletions
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;