summaryrefslogtreecommitdiffhomepage
path: root/ir/be/begnuas.c
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2015-05-25 23:22:09 +0200
committerMatthias Braun <matze@braunis.de>2015-05-26 01:38:32 +0200
commit86ac628189b9dd3d27fdf80869aac36a4544a96c (patch)
treee93811411bc9023ee8f5f5423fb1346a30ebcc74 /ir/be/begnuas.c
parentd8d48197a502e6445a3a51aa1fcfb8a092dfb84f (diff)
Introduce external_private visibility
Diffstat (limited to 'ir/be/begnuas.c')
-rw-r--r--ir/be/begnuas.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/ir/be/begnuas.c b/ir/be/begnuas.c
index 10ab734..5080e5a 100644
--- a/ir/be/begnuas.c
+++ b/ir/be/begnuas.c
@@ -470,6 +470,31 @@ static void emit_weak(const ir_entity *entity)
emit_symbol_directive(directive, entity);
}
+static const char *get_visibility_directive(const ir_entity *entity,
+ bool *output_global)
+{
+ switch (get_entity_visibility(entity)) {
+ case ir_visibility_external: return NULL;
+ case ir_visibility_external_private: {
+ switch (be_gas_object_file_format) {
+ case OBJECT_FILE_FORMAT_MACH_O:
+ *output_global = false;
+ return ".private_extern";
+ case OBJECT_FILE_FORMAT_ELF:
+ return ".hidden";
+ case OBJECT_FILE_FORMAT_COFF:
+ panic("ir_visibility_external_private not supported for COFF");
+ }
+ panic("invalid object file format");
+ }
+ case ir_visibility_local:
+ case ir_visibility_private:
+ *output_global = false;
+ return NULL;
+ }
+ panic("invalid visibility");
+}
+
static void emit_visibility(const ir_entity *entity, bool implicit_globl)
{
ir_linkage const linkage = get_entity_linkage(entity);
@@ -478,15 +503,13 @@ static void emit_visibility(const ir_entity *entity, bool implicit_globl)
emit_weak(entity);
if (entity_has_definition(entity)) {
- switch (get_entity_visibility(entity)) {
- case ir_visibility_external:
- if (!implicit_globl)
- emit_symbol_directive(".globl", entity);
- break;
- case ir_visibility_local:
- case ir_visibility_private:
- break;
- }
+ bool output_global = !implicit_globl;
+ const char *const directive
+ = get_visibility_directive(entity, &output_global);
+ if (output_global)
+ emit_symbol_directive(".globl", entity);
+ if (directive != NULL)
+ emit_symbol_directive(directive, entity);
}
if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O