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 struct obstack obst;
36 static void mangle_type(type_t *type);
38 static char get_atomic_type_mangle(atomic_type_kind_t kind)
41 case ATOMIC_TYPE_INVALID: break;
42 case ATOMIC_TYPE_VOID: return 'v';
43 case ATOMIC_TYPE_BOOL: return 'b';
44 case ATOMIC_TYPE_CHAR: return 'c';
45 case ATOMIC_TYPE_SCHAR: return 'a';
46 case ATOMIC_TYPE_UCHAR: return 'h';
47 case ATOMIC_TYPE_INT: return 'i';
48 case ATOMIC_TYPE_UINT: return 'j';
49 case ATOMIC_TYPE_SHORT: return 's';
50 case ATOMIC_TYPE_USHORT: return 't';
51 case ATOMIC_TYPE_LONG: return 'l';
52 case ATOMIC_TYPE_ULONG: return 'm';
53 case ATOMIC_TYPE_LONGLONG: return 'x';
54 case ATOMIC_TYPE_ULONGLONG: return 'y';
55 case ATOMIC_TYPE_LONG_DOUBLE: return 'e';
56 case ATOMIC_TYPE_FLOAT: return 'f';
57 case ATOMIC_TYPE_DOUBLE: return 'd';
59 panic("invalid atomic type in mangler");
62 static void mangle_atomic_type(const atomic_type_t *type)
64 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
67 static void mangle_pointer_type(const pointer_type_t *type)
69 obstack_1grow(&obst, 'P');
70 mangle_type(type->points_to);
73 static void mangle_parameters(const function_type_t *type)
75 if (type->unspecified_parameters)
76 panic("can't mangle unspecified parameter types");
77 if (type->kr_style_parameters)
78 panic("can't mangle kr_style_parameters type");
80 const function_parameter_t *parameter = type->parameters;
81 if (parameter != NULL) {
82 for ( ; parameter != NULL; parameter = parameter->next) {
83 mangle_type(parameter->type);
86 obstack_1grow(&obst, 'z');
89 obstack_1grow(&obst, 'v');
93 static void mangle_function_type(const function_type_t *type)
95 obstack_1grow(&obst, 'F');
96 if (type->linkage == LINKAGE_C) {
97 obstack_1grow(&obst, 'Y');
100 mangle_type(type->return_type);
101 mangle_parameters(type);
103 obstack_1grow(&obst, 'E');
106 static void mangle_class_enum_type(const entity_base_t *ent)
108 const symbol_t *sym = ent->symbol;
110 const char *name = sym->string;
111 obstack_printf(&obst, "%u%s", (unsigned) strlen(name), name);
113 /* TODO need the first typedef name here */
114 panic("mangling of unnamed class/enum types not implemented yet");
118 static void mangle_array_type(const array_type_t *type)
121 obstack_1grow(&obst, 'A');
122 obstack_1grow(&obst, '_');
123 } else if (type->size_constant) {
124 obstack_printf(&obst, "A%u_", (unsigned) type->size);
126 panic("mangling of non-constant sized array types not implemented yet");
128 mangle_type(type->element_type);
131 static void mangle_complex_type(const complex_type_t *type)
133 obstack_1grow(&obst, 'C');
134 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
137 static void mangle_imaginary_type(const imaginary_type_t *type)
139 obstack_1grow(&obst, 'G');
140 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
143 static void mangle_qualifiers(type_qualifiers_t qualifiers)
145 if (qualifiers & TYPE_QUALIFIER_RESTRICT)
146 obstack_1grow(&obst, 'r');
147 if (qualifiers & TYPE_QUALIFIER_VOLATILE)
148 obstack_1grow(&obst, 'V');
149 if (qualifiers & TYPE_QUALIFIER_CONST)
150 obstack_1grow(&obst, 'K');
152 /* handle MS extended qualifiers? */
155 static void mangle_type(type_t *orig_type)
157 type_t *type = skip_typeref(orig_type);
159 mangle_qualifiers(type->base.qualifiers);
161 switch (type->kind) {
163 mangle_atomic_type(&type->atomic);
166 mangle_pointer_type(&type->pointer);
169 mangle_function_type(&type->function);
171 case TYPE_COMPOUND_STRUCT:
172 case TYPE_COMPOUND_UNION:
173 mangle_class_enum_type(&type->compound.compound->base);
176 mangle_class_enum_type(&type->enumt.enume->base);
179 mangle_array_type(&type->array);
182 mangle_complex_type(&type->complex);
185 mangle_imaginary_type(&type->imaginary);
188 panic("invalid type encountered while mangling");
190 panic("error type encountered while mangling");
194 panic("typeref not resolved while manging?!?");
197 panic("no mangling for this type implemented yet");
200 panic("invalid type encountered while mangling");
203 static void mangle_entity(entity_t *entity)
205 obstack_1grow(&obst, '_');
206 obstack_1grow(&obst, 'Z');
208 /* TODO: mangle scope */
210 const char *name = entity->base.symbol->string;
211 obstack_printf(&obst, "%u%s", (unsigned) strlen(name), name);
213 if (entity->kind == ENTITY_FUNCTION) {
214 mangle_parameters(&entity->declaration.type->function);
218 static ident *make_id_from_obst(void)
220 size_t size = obstack_object_size(&obst);
221 char *str = obstack_finish(&obst);
222 ident *id = new_id_from_chars(str, size);
223 obstack_free(&obst, str);
228 * Mangles an entity linker (ld) name for win32 usage.
230 * @param ent the entity to be mangled
231 * @param declaration the declaration
233 ident *create_name_win32(entity_t *entity)
235 struct obstack *o = &obst;
237 assert(is_declaration(entity));
239 if (entity->declaration.modifiers & DM_DLLIMPORT) {
240 /* add prefix for imported symbols */
241 obstack_printf(o, "__imp_");
244 if (entity->kind == ENTITY_FUNCTION) {
245 cc_kind_t cc = entity->declaration.type->function.calling_convention;
247 /* calling convention prefix */
251 case CC_STDCALL: obstack_1grow(o, '_'); break;
252 case CC_FASTCALL: obstack_1grow(o, '@'); break;
253 default: panic("unhandled calling convention");
256 switch (entity->declaration.type->function.linkage) {
257 case LINKAGE_INVALID:
261 obstack_printf(o, "%s", entity->base.symbol->string);
265 mangle_entity(entity);
269 /* calling convention suffix */
277 ir_type *irtype = get_ir_type(entity->declaration.type);
279 for (int i = get_method_n_params(irtype) - 1; i >= 0; --i) {
280 size += get_type_size_bytes(get_method_param_type(irtype, i));
282 obstack_printf(o, "@%u", size);
287 panic("unhandled calling convention");
290 obstack_printf(o, "_%s", entity->base.symbol->string);
293 return make_id_from_obst();
297 * Mangles an entity linker (ld) name for Linux ELF usage.
299 * @param ent the entity to be mangled
300 * @param declaration the declaration
302 ident *create_name_linux_elf(entity_t *entity)
304 bool needs_mangling = false;
306 if (entity->kind == ENTITY_FUNCTION) {
307 switch (entity->declaration.type->function.linkage) {
308 case LINKAGE_INVALID: break;
309 case LINKAGE_C: break;
310 case LINKAGE_CXX: needs_mangling = true; break;
314 if (needs_mangling) {
315 mangle_entity(entity);
316 return make_id_from_obst();
319 return new_id_from_str(entity->base.symbol->string);
323 * Mangles an entity linker (ld) name for Mach-O usage.
325 * @param ent the entity to be mangled
326 * @param declaration the declaration
328 ident *create_name_macho(entity_t *entity)
330 obstack_printf(&obst, "_%s", entity->base.symbol->string);
331 return make_id_from_obst();
334 void init_mangle(void)
339 void exit_mangle(void)
341 obstack_free(&obst, NULL);