Handle GNU extension __REDIRECT
authorAndreas Zwinkau <zwinkau@kit.edu>
Thu, 24 Feb 2011 09:59:09 +0000 (09:59 +0000)
committerAndreas Zwinkau <zwinkau@kit.edu>
Thu, 24 Feb 2011 09:59:09 +0000 (09:59 +0000)
Used to specify a different ld_name than function name.
E.g. use to redirect fstat to fstat64 in GNU.

Fixes C/gnu99/redirect

[r28437]

attribute.c
entity_t.h
mangle.c

index 1ea8f1d..5190ac1 100644 (file)
@@ -275,6 +275,22 @@ static void handle_attribute_packed(const attribute_t *attribute, type_t *type)
        handle_attribute_packed_e(attribute, (entity_t*) type->compound.compound);
 }
 
+static void handle_attribute_asm(const attribute_t *attribute,
+                                      entity_t *entity)
+{
+       attribute_argument_t *argument = attribute->a.arguments;
+       assert (argument->kind == ATTRIBUTE_ARGUMENT_EXPRESSION);
+       expression_t *expression = argument->v.expression;
+       if (expression->kind != EXPR_STRING_LITERAL)
+               errorf(&attribute->source_position,
+                      "Invalid asm attribute expression");
+       string_literal_expression_t *strexpr = (string_literal_expression_t*)expression;
+       symbol_t *sym = symbol_table_insert(strexpr->value.begin);
+       entity->function.actual_name = sym;
+       assert (argument->next == NULL);
+       return;
+}
+
 void handle_entity_attributes(const attribute_t *attributes, entity_t *entity)
 {
        if (entity->kind == ENTITY_TYPEDEF) {
@@ -329,6 +345,10 @@ void handle_entity_attributes(const attribute_t *attributes, entity_t *entity)
                        handle_attribute_packed_e(attribute, entity);
                        break;
 
+               case ATTRIBUTE_GNU_ASM:
+                       handle_attribute_asm(attribute, entity);
+                       break;
+
                case ATTRIBUTE_MS_ALIGN:
                case ATTRIBUTE_GNU_ALIGNED:
                        handle_attribute_aligned(attribute, entity);
index c9670f0..d6d3702 100644 (file)
@@ -252,6 +252,7 @@ struct function_t {
        builtin_kind_t btk;
        scope_t        parameters;
        statement_t   *statement;
+       symbol_t      *actual_name;        /**< gnu extension __REDIRECT */
 
        /* ast2firm info */
        ir_entity     *irentity;
index 636159f..4aacb56 100644 (file)
--- a/mangle.c
+++ b/mangle.c
@@ -344,7 +344,7 @@ ident *create_name_win32(entity_t *entity)
  */
 ident *create_name_linux_elf(entity_t *entity)
 {
-       bool needs_mangling = false;
+       const char *name = entity->base.symbol->string;
 
        if (entity->kind == ENTITY_FUNCTION) {
                type_t *type = skip_typeref(entity->declaration.type);
@@ -352,18 +352,18 @@ ident *create_name_linux_elf(entity_t *entity)
                switch (type->function.linkage) {
                        case LINKAGE_INVALID:
                                panic("linkage type of function is invalid");
-
-                       case LINKAGE_C:   break;
-                       case LINKAGE_CXX: needs_mangling = true; break;
+                       case LINKAGE_C:
+                               if (entity->function.actual_name != NULL)
+                                       name = entity->function.actual_name->string;
+                               break;
+                       case LINKAGE_CXX:
+                               // TODO What about __REDIRECT/actual_name with mangling?
+                               mangle_entity(entity);
+                               return make_id_from_obst();
                }
        }
 
-       if (needs_mangling) {
-               mangle_entity(entity);
-               return make_id_from_obst();
-       }
-
-       return new_id_from_str(entity->base.symbol->string);
+       return new_id_from_str(name);
 }
 
 /**