2 * This file is part of cparser.
3 * Copyright (C) 2012 Matthias Braun <matze@braunis.de>
7 #include <libfirm/firm.h>
15 #include "lang_features.h"
16 #include "adt/error.h"
18 static struct obstack obst;
20 static void mangle_type(type_t *type);
22 static char get_atomic_type_mangle(atomic_type_kind_t kind)
25 case ATOMIC_TYPE_VOID: return 'v';
26 case ATOMIC_TYPE_WCHAR_T: return 'w';
27 case ATOMIC_TYPE_BOOL: return 'b';
28 case ATOMIC_TYPE_CHAR: return 'c';
29 case ATOMIC_TYPE_SCHAR: return 'a';
30 case ATOMIC_TYPE_UCHAR: return 'h';
31 case ATOMIC_TYPE_INT: return 'i';
32 case ATOMIC_TYPE_UINT: return 'j';
33 case ATOMIC_TYPE_SHORT: return 's';
34 case ATOMIC_TYPE_USHORT: return 't';
35 case ATOMIC_TYPE_LONG: return 'l';
36 case ATOMIC_TYPE_ULONG: return 'm';
37 case ATOMIC_TYPE_LONGLONG: return 'x';
38 case ATOMIC_TYPE_ULONGLONG: return 'y';
39 case ATOMIC_TYPE_LONG_DOUBLE: return 'e';
40 case ATOMIC_TYPE_FLOAT: return 'f';
41 case ATOMIC_TYPE_DOUBLE: return 'd';
43 panic("invalid atomic type");
46 static void mangle_atomic_type(const atomic_type_t *type)
48 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
51 static void mangle_pointer_type(const pointer_type_t *type)
53 obstack_1grow(&obst, 'P');
54 mangle_type(type->points_to);
57 static void mangle_reference_type(const reference_type_t *type)
59 obstack_1grow(&obst, 'R');
60 mangle_type(type->refers_to);
63 static void mangle_parameters(const function_type_t *type)
65 if (type->unspecified_parameters)
66 panic("can't mangle unspecified parameter types");
67 if (type->kr_style_parameters)
68 panic("can't mangle kr_style_parameters type");
70 const function_parameter_t *parameter = type->parameters;
71 if (parameter != NULL) {
72 for ( ; parameter != NULL; parameter = parameter->next) {
73 mangle_type(parameter->type);
76 obstack_1grow(&obst, 'z');
79 obstack_1grow(&obst, 'v');
83 static void mangle_function_type(const function_type_t *type)
85 obstack_1grow(&obst, 'F');
86 if (type->linkage == LINKAGE_C) {
87 obstack_1grow(&obst, 'Y');
90 mangle_type(type->return_type);
91 mangle_parameters(type);
93 obstack_1grow(&obst, 'E');
96 static void print_name(const char* name)
98 obstack_printf(&obst, "%u%s", (unsigned)strlen(name), name);
101 static void mangle_class_type(const compound_type_t *type)
103 const symbol_t *sym = type->compound->base.symbol;
105 if (type->compound->alias == NULL)
106 panic("mangling anonymous type");
107 sym = type->compound->alias->base.symbol;
109 print_name(sym->string);
112 static void mangle_enum_type(const enum_type_t *type)
114 const symbol_t *sym = type->enume->base.symbol;
116 if (type->enume->alias == NULL)
117 panic("mangling anonymous type");
118 sym = type->enume->alias->base.symbol;
120 print_name(sym->string);
123 static void mangle_array_type(const array_type_t *type)
126 obstack_1grow(&obst, 'A');
127 obstack_1grow(&obst, '_');
128 } else if (type->size_constant) {
129 obstack_printf(&obst, "A%u_", (unsigned) type->size);
131 panic("mangling of non-constant sized array types not implemented yet");
133 mangle_type(type->element_type);
136 static void mangle_complex_type(const atomic_type_t *type)
138 obstack_1grow(&obst, 'C');
139 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
142 static void mangle_imaginary_type(const atomic_type_t *type)
144 obstack_1grow(&obst, 'G');
145 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
148 static void mangle_qualifiers(type_qualifiers_t qualifiers)
150 #if 0 /* Do not mangle restrict qualifiers. GCC doesn't either */
151 if (qualifiers & TYPE_QUALIFIER_RESTRICT)
152 obstack_1grow(&obst, 'r');
154 if (qualifiers & TYPE_QUALIFIER_VOLATILE)
155 obstack_1grow(&obst, 'V');
156 if (qualifiers & TYPE_QUALIFIER_CONST)
157 obstack_1grow(&obst, 'K');
159 /* handle MS extended qualifiers? */
162 static void mangle_type(type_t *orig_type)
164 type_t *type = skip_typeref(orig_type);
166 mangle_qualifiers(type->base.qualifiers);
168 switch (type->kind) {
170 mangle_atomic_type(&type->atomic);
173 mangle_pointer_type(&type->pointer);
176 mangle_reference_type(&type->reference);
179 mangle_function_type(&type->function);
181 case TYPE_COMPOUND_STRUCT:
182 case TYPE_COMPOUND_UNION:
183 mangle_class_type(&type->compound);
186 mangle_enum_type(&type->enumt);
189 mangle_array_type(&type->array);
192 mangle_complex_type(&type->atomic);
195 mangle_imaginary_type(&type->atomic);
198 panic("error type encountered while mangling");
201 panic("typeref not resolved while manging?!?");
203 panic("invalid type encountered while mangling");
206 static void mangle_namespace(entity_t *entity)
208 for (entity_t *e = entity->base.parent_entity; e != NULL;
209 e = e->base.parent_entity) {
210 /* TODO: we need something similar (or the same?) for classes */
211 if (e->kind == ENTITY_NAMESPACE) {
213 print_name(e->base.symbol->string);
219 static void mangle_entity(entity_t *entity)
221 obstack_1grow(&obst, '_');
222 obstack_1grow(&obst, 'Z');
224 if (entity->base.parent_entity != NULL) {
225 obstack_1grow(&obst, 'N');
226 mangle_namespace(entity);
229 print_name(entity->base.symbol->string);
231 if (entity->kind == ENTITY_FUNCTION) {
232 mangle_parameters(&entity->declaration.type->function);
236 static ident *make_id_from_obst(void)
238 size_t size = obstack_object_size(&obst);
239 char *str = obstack_finish(&obst);
240 ident *id = new_id_from_chars(str, size);
241 obstack_free(&obst, str);
246 * Mangles an entity linker (ld) name for win32 usage.
248 * @param ent the entity to be mangled
249 * @param declaration the declaration
251 ident *create_name_win32(entity_t *entity)
253 struct obstack *o = &obst;
255 assert(is_declaration(entity));
257 if (entity->kind == ENTITY_FUNCTION) {
258 type_t *type = skip_typeref(entity->declaration.type);
259 assert(is_type_function(type));
261 if (entity->declaration.modifiers & DM_DLLIMPORT)
262 /* add prefix for imported symbols */
263 obstack_printf(o, "__imp_");
265 cc_kind_t cc = type->function.calling_convention;
267 /* calling convention prefix */
271 case CC_STDCALL: obstack_1grow(o, '_'); break;
272 case CC_FASTCALL: obstack_1grow(o, '@'); break;
273 default: panic("unhandled calling convention");
276 switch (type->function.linkage) {
278 obstack_printf(o, "%s", entity->base.symbol->string);
282 mangle_entity(entity);
286 /* calling convention suffix */
295 for (function_parameter_t const* i = type->function.parameters; i; i = i->next) {
296 size += get_type_size(i->type);
298 obstack_printf(o, "@%u", size);
303 panic("unhandled calling convention");
306 obstack_printf(o, "_%s", entity->base.symbol->string);
309 return make_id_from_obst();
313 * Mangles an entity linker (ld) name for Linux ELF usage.
315 * @param ent the entity to be mangled
316 * @param declaration the declaration
318 ident *create_name_linux_elf(entity_t *entity)
320 const char *name = entity->base.symbol->string;
322 if (entity->kind == ENTITY_FUNCTION) {
323 type_t *type = skip_typeref(entity->declaration.type);
324 assert(is_type_function(type));
325 switch (type->function.linkage) {
327 if (entity->function.actual_name != NULL)
328 name = entity->function.actual_name->string;
331 // TODO What about __REDIRECT/actual_name with mangling?
332 mangle_entity(entity);
333 return make_id_from_obst();
337 return new_id_from_str(name);
341 * Mangles an entity linker (ld) name for Mach-O usage.
343 * @param ent the entity to be mangled
344 * @param declaration the declaration
346 ident *create_name_macho(entity_t *entity)
348 if (entity->kind == ENTITY_FUNCTION) {
349 type_t *type = skip_typeref(entity->declaration.type);
350 assert(is_type_function(type));
352 switch (type->function.linkage) {
354 if (entity->function.actual_name != NULL)
355 return new_id_from_str(entity->function.actual_name->string);
360 obstack_printf(&obst, "_%s", entity->base.symbol->string);
361 return make_id_from_obst();
364 void init_mangle(void)
369 void exit_mangle(void)
371 obstack_free(&obst, NULL);