if (modifiers & DM_USED) {
add_entity_linkage(irentity, IR_LINKAGE_HIDDEN_USER);
}
+ if (modifiers & DM_WEAK) {
+ add_entity_linkage(irentity, IR_LINKAGE_WEAK);
+ }
}
static bool is_main(entity_t *entity)
ir_entity *irentity = entitymap_get(&entitymap, symbol);
bool const has_body = entity->function.statement != NULL;
if (irentity != NULL) {
- if ((get_entity_linkage(irentity) & IR_LINKAGE_EXTERN) && has_body) {
- remove_entity_linkage(irentity, IR_LINKAGE_EXTERN);
+ if (get_entity_visibility(irentity) == ir_visibility_external
+ && has_body) {
+ set_entity_visibility(irentity, ir_visibility_default);
}
goto entity_created;
}
bool const is_inline = entity->function.is_inline;
if (is_inline && storage_class == STORAGE_CLASS_NONE && has_body) {
+ set_entity_visibility(irentity, ir_visibility_default);
} else if (storage_class == STORAGE_CLASS_STATIC ||
(is_inline && has_body)) {
- add_entity_linkage(irentity, IR_LINKAGE_LOCAL);
+ set_entity_visibility(irentity, ir_visibility_local);
} else if (has_body) {
+ set_entity_visibility(irentity, ir_visibility_default);
} else {
- add_entity_linkage(irentity, IR_LINKAGE_EXTERN);
+ set_entity_visibility(irentity, ir_visibility_external);
}
} else {
/* nested functions are always local */
- add_entity_linkage(irentity, IR_LINKAGE_LOCAL);
+ set_entity_visibility(irentity, ir_visibility_local);
}
/* We should check for file scope here, but as long as we compile C only
ident *const id = id_unique(id_prefix);
ir_entity *const entity = new_d_entity(global_type, id, type, dbgi);
set_entity_ld_ident(entity, id);
- add_entity_linkage(entity, IR_LINKAGE_CONSTANT | IR_LINKAGE_LOCAL);
+ set_entity_visibility(entity, ir_visibility_local);
+ add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
ir_type *const elem_type = ir_type_const_char;
ir_mode *const mode = get_type_mode(elem_type);
ident *const id = id_unique("Lstr.%u");
ir_entity *const entity = new_d_entity(global_type, id, type, dbgi);
set_entity_ld_ident(entity, id);
- add_entity_linkage(entity, IR_LINKAGE_CONSTANT | IR_LINKAGE_LOCAL);
+ set_entity_visibility(entity, ir_visibility_local);
+ add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
ir_mode *const mode = get_type_mode(elem_type);
}
case bk_gnu_builtin_huge_val:
+ case bk_gnu_builtin_huge_valf:
+ case bk_gnu_builtin_huge_vall:
case bk_gnu_builtin_inf:
case bk_gnu_builtin_inff:
case bk_gnu_builtin_infl: {
ir_entity *const init_entity = new_d_entity(global_type, id, irtype, dbgi);
set_entity_ld_ident(init_entity, id);
- add_entity_linkage(init_entity, IR_LINKAGE_LOCAL|IR_LINKAGE_CONSTANT);
+ set_entity_visibility(init_entity, ir_visibility_local);
+ add_entity_linkage(init_entity, IR_LINKAGE_CONSTANT);
set_entity_initializer(init_entity, irinitializer);
ir_entity *irentity = entity->variable.v.entity;
- if (tq & TYPE_QUALIFIER_CONST) {
+ if (tq & TYPE_QUALIFIER_CONST
+ && get_entity_owner(irentity) != get_tls_type()) {
add_entity_linkage(irentity, IR_LINKAGE_CONSTANT);
}
set_atomic_ent_value(irentity, value);
size_t l = strlen(entity->base.symbol->string);
char buf[l + sizeof(".%u")];
snprintf(buf, sizeof(buf), "%s.%%u", entity->base.symbol->string);
- ident *const id = id_unique(buf);
-
+ ident *const id = id_unique(buf);
ir_entity *const irentity = new_d_entity(var_type, id, irtype, dbgi);
if (type->base.qualifiers & TYPE_QUALIFIER_VOLATILE) {
entity->variable.v.entity = irentity;
set_entity_ld_ident(irentity, id);
- add_entity_linkage(irentity, IR_LINKAGE_LOCAL);
+ set_entity_visibility(irentity, ir_visibility_local);
ir_graph *const old_current_ir_graph = current_ir_graph;
current_ir_graph = get_const_code_irg();
static void create_global_variable(entity_t *entity)
{
- ir_linkage linkage = 0;
+ ir_linkage linkage = 0;
+ ir_visibility visibility = ir_visibility_default;
+ ir_entity *irentity;
assert(entity->kind == ENTITY_VARIABLE);
switch ((storage_class_tag_t)entity->declaration.storage_class) {
- case STORAGE_CLASS_STATIC: linkage |= IR_LINKAGE_LOCAL; break;
- case STORAGE_CLASS_EXTERN: linkage |= IR_LINKAGE_EXTERN; break;
+ case STORAGE_CLASS_EXTERN: visibility = ir_visibility_external; break;
+ case STORAGE_CLASS_STATIC: visibility = ir_visibility_local; break;
+ case STORAGE_CLASS_NONE:
+ visibility = ir_visibility_default;
+ /* uninitialized globals get merged in C */
+ if (entity->variable.initializer == NULL)
+ linkage |= IR_LINKAGE_MERGE;
+ break;
case STORAGE_CLASS_TYPEDEF:
case STORAGE_CLASS_AUTO:
case STORAGE_CLASS_REGISTER:
- case STORAGE_CLASS_NONE: break;
+ panic("invalid storage class for global var");
}
- ir_type *var_type = entity->variable.thread_local ?
- get_tls_type() : get_glob_type();
+ ir_type *var_type = get_glob_type();
+ if (entity->variable.thread_local) {
+ var_type = get_tls_type();
+ /* LINKAGE_MERGE not supported by current linkers */
+ linkage &= ~IR_LINKAGE_MERGE;
+ }
create_variable_entity(entity, DECLARATION_KIND_GLOBAL_VARIABLE, var_type);
- add_entity_linkage(entity->variable.v.entity, linkage);
+ irentity = entity->variable.v.entity;
+ add_entity_linkage(irentity, linkage);
+ set_entity_visibility(irentity, visibility);
}
static void create_local_declaration(entity_t *entity)
ir_type *method_type = get_entity_type(method);
ir_type *ptr_type = new_type_pointer(method_type);
+ /* these entities don't really have a name but firm only allows
+ * "" in ld_ident.
+ * Note that we mustn't give these entities a name since for example
+ * Mach-O doesn't allow them. */
ident *ide = id_unique(unique_template);
ir_entity *ptr = new_entity(segment, ide, ptr_type);
ir_graph *irg = get_const_code_irg();
ir_node *val = new_rd_SymConst_addr_ent(NULL, irg, mode_P_code,
method, NULL);
+ set_entity_ld_ident(ptr, new_id_from_chars("", 0));
set_entity_compiler_generated(ptr, 1);
- add_entity_linkage(ptr, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT);
+ set_entity_visibility(ptr, ir_visibility_local);
+ add_entity_linkage(ptr, IR_LINKAGE_CONSTANT|IR_LINKAGE_HIDDEN_USER);
set_atomic_ent_value(ptr, val);
}