+/**
+ * Mangles an entity linker (ld) name for Linux ELF usage.
+ *
+ * @param ent the entity to be mangled
+ * @param declaration the declaration
+ */
+static ident *create_ld_ident_linux_elf(ir_entity *entity,
+ declaration_t *declaration)
+{
+ (void) declaration;
+ return get_entity_ident(entity);
+}
+
+/**
+ * Mangles an entity linker (ld) name for Mach-O usage.
+ *
+ * @param ent the entity to be mangled
+ * @param declaration the declaration
+ */
+static ident *create_ld_ident_macho(ir_entity *ent, declaration_t *declaration)
+{
+ (void) declaration;
+ ident *id = mangle(id_underscore, get_entity_ident(ent));
+ return id;
+}
+
+typedef ident* (*create_ld_ident_func)(ir_entity *entity,
+ declaration_t *declaration);
+create_ld_ident_func create_ld_ident = create_ld_ident_linux_elf;
+
+/**
+ * Handle GNU attributes for entities
+ *
+ * @param ent the entity
+ * @param decl the routine declaration
+ */
+static void handle_gnu_attributes_ent(ir_entity *ent, declaration_t *decl)
+{
+ if (decl->modifiers & DM_PURE) {
+ /* TRUE if the declaration includes the GNU
+ __attribute__((pure)) specifier. */
+ set_entity_additional_property(ent, mtp_property_pure);
+ }
+ if (decl->modifiers & DM_USED) {
+ /* TRUE if the declaration includes the GNU
+ __attribute__((used)) specifier. */
+ set_entity_stickyness(ent, stickyness_sticky);
+ }
+}
+
+/**
+ * Creates an entity representing a function.
+ *
+ * @param declaration the function declaration
+ */
+static ir_entity *get_function_entity(declaration_t *declaration)
+{
+ if (declaration->declaration_kind == DECLARATION_KIND_FUNCTION)
+ return declaration->v.entity;
+ assert(declaration->declaration_kind == DECLARATION_KIND_UNKNOWN);
+
+ symbol_t *symbol = declaration->symbol;
+ ident *id = new_id_from_str(symbol->string);
+
+ ir_type *global_type = get_glob_type();
+ ir_type *ir_type_method = get_ir_type(declaration->type);
+ assert(is_Method_type(ir_type_method));
+
+ /* already an entity defined? */
+ ir_entity *entity = entitymap_get(&entitymap, symbol);
+ if (entity != NULL) {
+ if (get_entity_visibility(entity) == visibility_external_allocated
+ && declaration->init.statement != NULL) {
+ set_entity_visibility(entity, visibility_external_visible);
+ }
+ goto entity_created;
+ }
+
+ dbg_info *const dbgi = get_dbg_info(&declaration->source_position);
+ entity = new_d_entity(global_type, id, ir_type_method, dbgi);
+ set_entity_ld_ident(entity, create_ld_ident(entity, declaration));
+
+ handle_gnu_attributes_ent(entity, declaration);
+
+ /* static inline => local
+ * extern inline => local
+ * inline without definition => local
+ * inline with definition => external_visible */
+ storage_class_tag_t const storage_class = declaration->storage_class;
+ bool const is_inline = declaration->is_inline;
+ bool const has_body = declaration->init.statement != NULL;
+ if (is_inline && storage_class == STORAGE_CLASS_NONE && has_body) {
+ set_entity_visibility(entity, visibility_external_visible);
+ } else if (storage_class == STORAGE_CLASS_STATIC ||
+ (is_inline && has_body)) {
+ if (!has_body) {
+ /* this entity was declared, but is defined nowhere */
+ set_entity_peculiarity(entity, peculiarity_description);
+ }
+ set_entity_visibility(entity, visibility_local);
+ } else if (has_body) {
+ set_entity_visibility(entity, visibility_external_visible);
+ } else {
+ set_entity_visibility(entity, visibility_external_allocated);
+ }
+ set_entity_allocation(entity, allocation_static);
+
+ /* We should check for file scope here, but as long as we compile C only
+ this is not needed. */
+ if (! firm_opt.freestanding) {
+ /* check for a known runtime function */
+ for (size_t i = 0; i < sizeof(rts_data) / sizeof(rts_data[0]); ++i) {
+ if (id != rts_idents[i])
+ continue;
+
+ /* ignore those rts functions not necessary needed for current mode */
+ if ((c_mode & rts_data[i].flags) == 0)
+ continue;
+ assert(rts_entities[rts_data[i].id] == NULL);
+ rts_entities[rts_data[i].id] = entity;
+ }
+ }
+
+ entitymap_insert(&entitymap, symbol, entity);
+
+entity_created:
+ declaration->declaration_kind = DECLARATION_KIND_FUNCTION;
+ declaration->v.entity = entity;
+
+ return entity;
+}
+
+/**
+ * Creates a Const node representing a constant.
+ */
+static ir_node *const_to_firm(const const_expression_t *cnst)
+{
+ dbg_info *dbgi = get_dbg_info(&cnst->base.source_position);