2 * This file is part of cparser.
3 * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 #include <libfirm/firm.h>
29 #include "diagnostic.h"
31 #include "lang_features.h"
32 #include "adt/error.h"
34 static ident *id_underscore;
36 static symbol_t *sym_C;
37 static struct obstack obst;
39 static void mangle_type(type_t *type);
41 static char get_atomic_type_mangle(atomic_type_kind_t kind)
44 case ATOMIC_TYPE_INVALID: break;
45 case ATOMIC_TYPE_VOID: return 'v';
46 case ATOMIC_TYPE_BOOL: return 'b';
47 case ATOMIC_TYPE_CHAR: return 'c';
48 case ATOMIC_TYPE_SCHAR: return 'a';
49 case ATOMIC_TYPE_UCHAR: return 'h';
50 case ATOMIC_TYPE_INT: return 'i';
51 case ATOMIC_TYPE_UINT: return 'j';
52 case ATOMIC_TYPE_SHORT: return 's';
53 case ATOMIC_TYPE_USHORT: return 't';
54 case ATOMIC_TYPE_LONG: return 'l';
55 case ATOMIC_TYPE_ULONG: return 'm';
56 case ATOMIC_TYPE_LONGLONG: return 'x';
57 case ATOMIC_TYPE_ULONGLONG: return 'y';
58 case ATOMIC_TYPE_LONG_DOUBLE: return 'e';
59 case ATOMIC_TYPE_FLOAT: return 'f';
60 case ATOMIC_TYPE_DOUBLE: return 'd';
62 panic("invalid atomic type in mangler");
65 static void mangle_atomic_type(const atomic_type_t *type)
67 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
70 static void mangle_pointer_type(const pointer_type_t *type)
72 obstack_1grow(&obst, 'P');
73 mangle_type(type->points_to);
76 static void mangle_function_type(const function_type_t *type)
78 obstack_1grow(&obst, 'F');
79 if (type->linkage == sym_C) {
80 obstack_1grow(&obst, 'Y');
83 mangle_type(type->return_type);
85 function_parameter_t *parameter = type->parameters;
86 for ( ; parameter != NULL; parameter = parameter->next) {
87 mangle_type(parameter->type);
90 obstack_1grow(&obst, 'z');
92 if (type->unspecified_parameters)
93 panic("can't mangle unspecified parameter types");
94 if (type->kr_style_parameters)
95 panic("can't mangle kr_style_parameters type");
97 obstack_1grow(&obst, 'E');
100 static void mangle_qualifiers(type_qualifiers_t qualifiers)
102 if (qualifiers & TYPE_QUALIFIER_CONST)
103 obstack_1grow(&obst, 'K');
104 if (qualifiers & TYPE_QUALIFIER_VOLATILE)
105 obstack_1grow(&obst, 'V');
106 if (qualifiers & TYPE_QUALIFIER_RESTRICT)
107 obstack_1grow(&obst, 'r');
109 /* handle MS extended qualifiers? */
112 static void mangle_type(type_t *orig_type)
114 type_t *type = skip_typeref(orig_type);
116 mangle_qualifiers(type->base.qualifiers);
118 switch (type->kind) {
120 mangle_atomic_type(&type->atomic);
123 mangle_pointer_type(&type->pointer);
126 mangle_function_type(&type->function);
129 panic("invalid type encountered while mangling");
131 panic("error type encountered while mangling");
135 panic("typeref not resolved while manging?!?");
140 case TYPE_COMPOUND_STRUCT:
141 case TYPE_COMPOUND_UNION:
144 panic("no mangling for this type implemented yet");
147 panic("invalid type encountered while mangling");
150 static void mangle_entity(entity_t *entity)
152 obstack_1grow(&obst, '_');
153 obstack_1grow(&obst, 'Z');
155 /* TODO: mangle scope */
157 symbol_t *symbol = entity->base.symbol;
158 obstack_printf(&obst, "%u%s", strlen(symbol->string), symbol->string);
160 if (entity->kind == ENTITY_FUNCTION) {
161 mangle_type(entity->declaration.type);
166 * Mangles an entity linker (ld) name for win32 usage.
168 * @param ent the entity to be mangled
169 * @param declaration the declaration
171 ident *create_name_win32(entity_t *entity)
173 struct obstack *o = &obst;
175 assert(is_declaration(entity));
177 if (entity->declaration.modifiers & DM_DLLIMPORT) {
178 /* add prefix for imported symbols */
179 obstack_printf(o, "__imp_");
182 if (entity->kind == ENTITY_FUNCTION) {
183 cc_kind_t cc = entity->declaration.type->function.calling_convention;
185 /* calling convention prefix */
189 case CC_STDCALL: obstack_1grow(o, '_'); break;
190 case CC_FASTCALL: obstack_1grow(o, '@'); break;
191 default: panic("unhandled calling convention");
194 if (c_mode & _CXX && entity->declaration.type->function.linkage == NULL) {
195 mangle_entity(entity);
197 obstack_printf(o, "%s", entity->base.symbol->string);
200 /* calling convention suffix */
208 ir_type *irtype = get_ir_type(entity->declaration.type);
210 for (int i = get_method_n_params(irtype) - 1; i >= 0; --i) {
211 size += get_type_size_bytes(get_method_param_type(irtype, i));
213 obstack_printf(o, "@%zu\n", size);
218 panic("unhandled calling convention");
221 obstack_printf(o, "_%s", entity->base.symbol->string);
224 size_t size = obstack_object_size(o);
225 char *str = obstack_finish(o);
226 ident *id = new_id_from_chars(str, size);
227 obstack_free(o, str);
232 * Mangles an entity linker (ld) name for Linux ELF usage.
234 * @param ent the entity to be mangled
235 * @param declaration the declaration
237 ident *create_name_linux_elf(entity_t *entity)
239 bool needs_mangling = false;
241 if (entity->kind == ENTITY_FUNCTION && (c_mode & _CXX)) {
242 symbol_t *linkage = entity->declaration.type->function.linkage;
244 if (linkage == NULL) {
245 needs_mangling = true;
246 } else if (linkage != sym_C) {
247 errorf(&entity->base.source_position,
248 "Unknown linkage type \"%Y\" found\n", linkage);
252 if (needs_mangling) {
253 mangle_entity(entity);
254 obstack_1grow(&obst, '\0');
255 char *str = obstack_finish(&obst);
257 ident *id = new_id_from_str(str);
258 obstack_free(&obst, str);
263 return new_id_from_str(entity->base.symbol->string);
267 * Mangles an entity linker (ld) name for Mach-O usage.
269 * @param ent the entity to be mangled
270 * @param declaration the declaration
272 ident *create_name_macho(entity_t *entity)
274 ident *id = new_id_from_str(entity->base.symbol->string);
275 return id_mangle(id_underscore, id);
278 void init_mangle(void)
280 id_underscore = new_id_from_chars("_", 1);
281 id_imp = new_id_from_chars("__imp_", 6);
282 sym_C = symbol_table_insert("C");
287 void exit_mangle(void)
289 obstack_free(&obst, NULL);