[EXPR_CLASSIFY_TYPE] = PREC_UNARY,
[EXPR_ALIGNOF] = PREC_UNARY,
- [EXPR_FUNCTION] = PREC_PRIM,
- [EXPR_PRETTY_FUNCTION] = PREC_PRIM,
+ [EXPR_FUNCNAME] = PREC_PRIM,
[EXPR_BUILTIN_SYMBOL] = PREC_PRIM,
[EXPR_BUILTIN_CONSTANT_P] = PREC_PRIM,
[EXPR_BUILTIN_PREFETCH] = PREC_PRIM,
print_quoted_string(&string_literal->value, '"');
}
+/**
+ * Prints a predefined symbol.
+ */
+static void print_funcname(
+ const funcname_expression_t *funcname)
+{
+ const char *s = "";
+ switch(funcname->kind) {
+ case FUNCNAME_FUNCTION: s = (c_mode & _C99) ? "__func__" : "__FUNCTION__"; break;
+ case FUNCNAME_PRETTY_FUNCTION: s = "__PRETTY_FUNCTION__"; break;
+ case FUNCNAME_FUNCSIG: s = "__FUNCSIG__"; break;
+ case FUNCNAME_FUNCDNAME: s = "__FUNCDNAME__"; break;
+ }
+ fputc('"', out);
+ fputs(s, out);
+ fputc('"', out);
+}
+
static void print_wide_string_literal(
const wide_string_literal_expression_t *const wstr)
{
case EXPR_CONST:
print_const(&expression->conste);
break;
- case EXPR_FUNCTION:
- case EXPR_PRETTY_FUNCTION:
+ case EXPR_FUNCNAME:
+ print_funcname(&expression->funcname);
+ break;
case EXPR_STRING_LITERAL:
print_string_literal(&expression->string);
break;
case EXPR_WIDE_STRING_LITERAL:
case EXPR_SIZEOF:
case EXPR_CLASSIFY_TYPE:
- case EXPR_FUNCTION:
- case EXPR_FUNCSIG:
- case EXPR_FUNCDNAME:
- case EXPR_PRETTY_FUNCTION:
+ case EXPR_FUNCNAME:
case EXPR_OFFSETOF:
case EXPR_ALIGNOF:
case EXPR_BUILTIN_CONSTANT_P:
typedef struct expression_base_t expression_base_t;
typedef struct const_expression_t const_expression_t;
typedef struct string_literal_expression_t string_literal_expression_t;
+typedef struct funcname_expression_t funcname_expression_t;
typedef struct wide_string_literal_expression_t wide_string_literal_expression_t;
typedef struct compound_literal_expression_t compound_literal_expression_t;
typedef struct reference_expression_t reference_expression_t;
}
static ir_node *function_name_to_firm(
- const string_literal_expression_t *const expr)
-{
- if (current_function_name == NULL) {
- const source_position_t *const src_pos = &expr->base.source_position;
- const char *const name = current_function_decl->symbol->string;
- const string_t string = { name, strlen(name) + 1 };
- current_function_name = string_to_firm(src_pos, "__func__", &string);
- }
-
- return current_function_name;
-}
-
-static ir_node *funcsig_to_firm(
- const string_literal_expression_t *const expr)
-{
- if (current_funcsig == NULL) {
- const source_position_t *const src_pos = &expr->base.source_position;
- ir_entity *ent = get_irg_entity(current_ir_graph);
- const char *const name = get_entity_ld_name(ent);
- const string_t string = { name, strlen(name) + 1 };
- current_funcsig = string_to_firm(src_pos, "__FUNCSIG__", &string);
+ const funcname_expression_t *const expr)
+{
+ switch(expr->kind) {
+ case FUNCNAME_FUNCTION:
+ case FUNCNAME_PRETTY_FUNCTION:
+ case FUNCNAME_FUNCDNAME:
+ if (current_function_name == NULL) {
+ const source_position_t *const src_pos = &expr->base.source_position;
+ const char *const name = current_function_decl->symbol->string;
+ const string_t string = { name, strlen(name) + 1 };
+ current_function_name = string_to_firm(src_pos, "__func__", &string);
+ }
+ return current_function_name;
+ case FUNCNAME_FUNCSIG:
+ if (current_funcsig == NULL) {
+ const source_position_t *const src_pos = &expr->base.source_position;
+ ir_entity *ent = get_irg_entity(current_ir_graph);
+ const char *const name = get_entity_ld_name(ent);
+ const string_t string = { name, strlen(name) + 1 };
+ current_funcsig = string_to_firm(src_pos, "__FUNCSIG__", &string);
+ }
+ return current_funcsig;
}
-
- return current_funcsig;
+ panic("Unsupported function name");
}
static ir_node *statement_expression_to_firm(const statement_expression_t *expr)
return select_to_firm(&expression->select);
case EXPR_CLASSIFY_TYPE:
return classify_type_to_firm(&expression->classify_type);
- case EXPR_FUNCTION:
- case EXPR_PRETTY_FUNCTION:
- case EXPR_FUNCDNAME:
- return function_name_to_firm(&expression->string);
- case EXPR_FUNCSIG:
- return funcsig_to_firm(&expression->string);
+ case EXPR_FUNCNAME:
+ return function_name_to_firm(&expression->funcname);
case EXPR_STATEMENT:
return statement_expression_to_firm(&expression->statement);
case EXPR_VA_START:
case EXPR_WIDE_CHARACTER_CONSTANT:
case EXPR_STRING_LITERAL:
case EXPR_WIDE_STRING_LITERAL:
- case EXPR_FUNCTION:
- case EXPR_PRETTY_FUNCTION:
- case EXPR_FUNCSIG:
- case EXPR_FUNCDNAME:
+ case EXPR_FUNCNAME:
case EXPR_BUILTIN_SYMBOL:
case EXPR_VA_START:
case EXPR_VA_ARG:
EXPR_CLASSIFY_TYPE,
EXPR_ALIGNOF,
- EXPR_FUNCTION,
- EXPR_PRETTY_FUNCTION,
- EXPR_FUNCSIG, /**< MS function signature, aka ld_name */
- EXPR_FUNCDNAME, /**< MS decorated name of a function */
+ EXPR_FUNCNAME,
EXPR_BUILTIN_SYMBOL,
EXPR_BUILTIN_CONSTANT_P,
EXPR_BUILTIN_PREFETCH,
EXPR_BINARY_LAST = EXPR_BINARY_ISUNORDERED,
} expression_kind_t;
+typedef enum {
+ FUNCNAME_FUNCTION, /**< C99 __func__, older __FUNCTION__ */
+ FUNCNAME_PRETTY_FUNCTION, /**< GNUC __PRETTY_FUNCTION__ */
+ FUNCNAME_FUNCSIG, /**< MS __FUNCSIG__ */
+ FUNCNAME_FUNCDNAME /**< MS __FUNCDNAME__ */
+} funcname_kind_t;
+
/* convenience macros */
#define EXPR_BINARY_CASES \
case EXPR_BINARY_ADD: \
string_t value;
};
+struct funcname_expression_t {
+ expression_base_t base;
+ funcname_kind_t kind;
+ string_t value; /**< the value once assigned. */
+};
+
struct wide_string_literal_expression_t {
expression_base_t base;
wide_string_t value;
expression_kind_t kind;
expression_base_t base;
const_expression_t conste;
+ funcname_expression_t funcname;
string_literal_expression_t string;
wide_string_literal_expression_t wide_string;
compound_literal_expression_t compound_literal;
[EXPR_SIZEOF] = sizeof(typeprop_expression_t),
[EXPR_ALIGNOF] = sizeof(typeprop_expression_t),
[EXPR_CLASSIFY_TYPE] = sizeof(classify_type_expression_t),
- [EXPR_FUNCTION] = sizeof(string_literal_expression_t),
- [EXPR_PRETTY_FUNCTION] = sizeof(string_literal_expression_t),
- [EXPR_FUNCSIG] = sizeof(string_literal_expression_t),
- [EXPR_FUNCDNAME] = sizeof(string_literal_expression_t),
+ [EXPR_FUNCNAME] = sizeof(funcname_expression_t),
[EXPR_BUILTIN_SYMBOL] = sizeof(builtin_symbol_expression_t),
[EXPR_BUILTIN_CONSTANT_P] = sizeof(builtin_constant_expression_t),
[EXPR_BUILTIN_PREFETCH] = sizeof(builtin_prefetch_expression_t),
errorf(HERE, "'__func__' used outside of a function");
}
- expression_t *expression = allocate_expression_zero(EXPR_FUNCTION);
- expression->base.type = type_char_ptr;
+ expression_t *expression = allocate_expression_zero(EXPR_FUNCNAME);
+ expression->base.type = type_char_ptr;
+ expression->funcname.kind = FUNCNAME_FUNCTION;
return expression;
}
errorf(HERE, "'__PRETTY_FUNCTION__' used outside of a function");
}
- expression_t *expression = allocate_expression_zero(EXPR_PRETTY_FUNCTION);
- expression->base.type = type_char_ptr;
+ expression_t *expression = allocate_expression_zero(EXPR_FUNCNAME);
+ expression->base.type = type_char_ptr;
+ expression->funcname.kind = FUNCNAME_PRETTY_FUNCTION;
return expression;
}
static expression_t *parse_funcsig_keyword(void)
{
- next_token();
+ eat(T___FUNCSIG__);
if (current_function == NULL) {
errorf(HERE, "'__FUNCSIG__' used outside of a function");
}
- expression_t *expression = allocate_expression_zero(EXPR_FUNCSIG);
- expression->base.type = type_char_ptr;
+ expression_t *expression = allocate_expression_zero(EXPR_FUNCNAME);
+ expression->base.type = type_char_ptr;
+ expression->funcname.kind = FUNCNAME_FUNCSIG;
return expression;
}
static expression_t *parse_funcdname_keyword(void)
{
- next_token();
+ eat(T___FUNCDNAME__);
if (current_function == NULL) {
errorf(HERE, "'__FUNCDNAME__' used outside of a function");
}
- expression_t *expression = allocate_expression_zero(EXPR_FUNCDNAME);
- expression->base.type = type_char_ptr;
+ expression_t *expression = allocate_expression_zero(EXPR_FUNCNAME);
+ expression->base.type = type_char_ptr;
+ expression->funcname.kind = FUNCNAME_FUNCDNAME;
return expression;
}
case EXPR_CLASSIFY_TYPE: return false;
case EXPR_ALIGNOF: return false;
- case EXPR_FUNCTION: return false;
- case EXPR_PRETTY_FUNCTION: return false;
- case EXPR_FUNCSIG: return false;
- case EXPR_FUNCDNAME: return false;
+ case EXPR_FUNCNAME: return false;
case EXPR_BUILTIN_SYMBOL: break; /* handled in EXPR_CALL */
case EXPR_BUILTIN_CONSTANT_P: return false;
case EXPR_BUILTIN_PREFETCH: return true;
S(defined)
T(_ALL, va_args, "__VA_ARGS__",)
+T(_MS, __COUNTER__, "__COUNTER__",)
+T(_MS, __TIMESTAMP__, "__TIMESTAMP__",)
S(STDC)
S(ON)