2 * This file is part of cparser.
3 * Copyright (C) 2007-2009 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_WCHAR_T: return 'w';
44 case ATOMIC_TYPE_BOOL: return 'b';
45 case ATOMIC_TYPE_CHAR: return 'c';
46 case ATOMIC_TYPE_SCHAR: return 'a';
47 case ATOMIC_TYPE_UCHAR: return 'h';
48 case ATOMIC_TYPE_INT: return 'i';
49 case ATOMIC_TYPE_UINT: return 'j';
50 case ATOMIC_TYPE_SHORT: return 's';
51 case ATOMIC_TYPE_USHORT: return 't';
52 case ATOMIC_TYPE_LONG: return 'l';
53 case ATOMIC_TYPE_ULONG: return 'm';
54 case ATOMIC_TYPE_LONGLONG: return 'x';
55 case ATOMIC_TYPE_ULONGLONG: return 'y';
56 case ATOMIC_TYPE_LONG_DOUBLE: return 'e';
57 case ATOMIC_TYPE_FLOAT: return 'f';
58 case ATOMIC_TYPE_DOUBLE: return 'd';
60 panic("invalid atomic type in mangler");
63 static void mangle_atomic_type(const atomic_type_t *type)
65 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
68 static void mangle_pointer_type(const pointer_type_t *type)
70 obstack_1grow(&obst, 'P');
71 mangle_type(type->points_to);
74 static void mangle_reference_type(const reference_type_t *type)
76 obstack_1grow(&obst, 'R');
77 mangle_type(type->refers_to);
80 static void mangle_parameters(const function_type_t *type)
82 if (type->unspecified_parameters)
83 panic("can't mangle unspecified parameter types");
84 if (type->kr_style_parameters)
85 panic("can't mangle kr_style_parameters type");
87 const function_parameter_t *parameter = type->parameters;
88 if (parameter != NULL) {
89 for ( ; parameter != NULL; parameter = parameter->next) {
90 mangle_type(parameter->type);
93 obstack_1grow(&obst, 'z');
96 obstack_1grow(&obst, 'v');
100 static void mangle_function_type(const function_type_t *type)
102 obstack_1grow(&obst, 'F');
103 if (type->linkage == LINKAGE_C) {
104 obstack_1grow(&obst, 'Y');
107 mangle_type(type->return_type);
108 mangle_parameters(type);
110 obstack_1grow(&obst, 'E');
113 static void print_name(const char* name)
115 obstack_printf(&obst, "%u%s", (unsigned)strlen(name), name);
118 static void mangle_class_type(const compound_type_t *type)
120 const symbol_t *sym = type->compound->base.symbol;
122 if (type->compound->alias == NULL)
123 panic("mangling anonymous type");
124 sym = type->compound->alias->base.symbol;
126 print_name(sym->string);
129 static void mangle_enum_type(const enum_type_t *type)
131 const symbol_t *sym = type->enume->base.symbol;
133 if (type->enume->alias == NULL)
134 panic("mangling anonymous type");
135 sym = type->enume->alias->base.symbol;
137 print_name(sym->string);
140 static void mangle_array_type(const array_type_t *type)
143 obstack_1grow(&obst, 'A');
144 obstack_1grow(&obst, '_');
145 } else if (type->size_constant) {
146 obstack_printf(&obst, "A%u_", (unsigned) type->size);
148 panic("mangling of non-constant sized array types not implemented yet");
150 mangle_type(type->element_type);
153 static void mangle_complex_type(const complex_type_t *type)
155 obstack_1grow(&obst, 'C');
156 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
159 static void mangle_imaginary_type(const imaginary_type_t *type)
161 obstack_1grow(&obst, 'G');
162 obstack_1grow(&obst, get_atomic_type_mangle(type->akind));
165 static void mangle_qualifiers(type_qualifiers_t qualifiers)
167 #if 0 /* Do not mangle restrict qualifiers. GCC doesn't either */
168 if (qualifiers & TYPE_QUALIFIER_RESTRICT)
169 obstack_1grow(&obst, 'r');
171 if (qualifiers & TYPE_QUALIFIER_VOLATILE)
172 obstack_1grow(&obst, 'V');
173 if (qualifiers & TYPE_QUALIFIER_CONST)
174 obstack_1grow(&obst, 'K');
176 /* handle MS extended qualifiers? */
179 static void mangle_type(type_t *orig_type)
181 type_t *type = skip_typeref(orig_type);
183 mangle_qualifiers(type->base.qualifiers);
185 switch (type->kind) {
187 mangle_atomic_type(&type->atomic);
190 mangle_pointer_type(&type->pointer);
193 mangle_reference_type(&type->reference);
196 mangle_function_type(&type->function);
198 case TYPE_COMPOUND_STRUCT:
199 case TYPE_COMPOUND_UNION:
200 mangle_class_type(&type->compound);
203 mangle_enum_type(&type->enumt);
206 mangle_array_type(&type->array);
209 mangle_complex_type(&type->complex);
212 mangle_imaginary_type(&type->imaginary);
215 panic("invalid type encountered while mangling");
217 panic("error type encountered while mangling");
220 panic("typeref not resolved while manging?!?");
222 panic("invalid type encountered while mangling");
225 static void mangle_namespace(entity_t *entity)
227 for (entity_t *e = entity->base.parent_entity; e != NULL;
228 e = e->base.parent_entity) {
229 /* TODO: we need something similar (or the same?) for classes */
230 if (e->kind == ENTITY_NAMESPACE) {
232 print_name(e->base.symbol->string);
238 static void mangle_entity(entity_t *entity)
240 obstack_1grow(&obst, '_');
241 obstack_1grow(&obst, 'Z');
243 if (entity->base.parent_entity != NULL) {
244 obstack_1grow(&obst, 'N');
245 mangle_namespace(entity);
248 print_name(entity->base.symbol->string);
250 if (entity->kind == ENTITY_FUNCTION) {
251 mangle_parameters(&entity->declaration.type->function);
255 static ident *make_id_from_obst(void)
257 size_t size = obstack_object_size(&obst);
258 char *str = obstack_finish(&obst);
259 ident *id = new_id_from_chars(str, size);
260 obstack_free(&obst, str);
265 * Mangles an entity linker (ld) name for win32 usage.
267 * @param ent the entity to be mangled
268 * @param declaration the declaration
270 ident *create_name_win32(entity_t *entity)
272 struct obstack *o = &obst;
274 assert(is_declaration(entity));
276 if (entity->kind == ENTITY_FUNCTION) {
277 type_t *type = skip_typeref(entity->declaration.type);
278 assert(is_type_function(type));
280 if (entity->declaration.modifiers & DM_DLLIMPORT)
281 /* add prefix for imported symbols */
282 obstack_printf(o, "__imp_");
284 cc_kind_t cc = type->function.calling_convention;
286 /* calling convention prefix */
290 case CC_STDCALL: obstack_1grow(o, '_'); break;
291 case CC_FASTCALL: obstack_1grow(o, '@'); break;
292 default: panic("unhandled calling convention");
295 switch (type->function.linkage) {
296 case LINKAGE_INVALID:
297 panic("linkage type of function is invalid");
300 obstack_printf(o, "%s", entity->base.symbol->string);
304 mangle_entity(entity);
308 /* calling convention suffix */
316 ir_type *irtype = get_ir_type(entity->declaration.type);
318 for (int i = get_method_n_params(irtype) - 1; i >= 0; --i) {
319 size += get_type_size_bytes(get_method_param_type(irtype, i));
321 obstack_printf(o, "@%u", size);
326 panic("unhandled calling convention");
329 obstack_printf(o, "_%s", entity->base.symbol->string);
332 return make_id_from_obst();
336 * Mangles an entity linker (ld) name for Linux ELF usage.
338 * @param ent the entity to be mangled
339 * @param declaration the declaration
341 ident *create_name_linux_elf(entity_t *entity)
343 const char *name = entity->base.symbol->string;
345 if (entity->kind == ENTITY_FUNCTION) {
346 type_t *type = skip_typeref(entity->declaration.type);
347 assert(is_type_function(type));
348 switch (type->function.linkage) {
349 case LINKAGE_INVALID:
350 panic("linkage type of function is invalid");
352 if (entity->function.actual_name != NULL)
353 name = entity->function.actual_name->string;
356 // TODO What about __REDIRECT/actual_name with mangling?
357 mangle_entity(entity);
358 return make_id_from_obst();
362 return new_id_from_str(name);
366 * Mangles an entity linker (ld) name for Mach-O usage.
368 * @param ent the entity to be mangled
369 * @param declaration the declaration
371 ident *create_name_macho(entity_t *entity)
373 if (entity->kind == ENTITY_FUNCTION) {
374 type_t *type = skip_typeref(entity->declaration.type);
375 assert(is_type_function(type));
377 switch (type->function.linkage) {
378 case LINKAGE_INVALID:
379 panic("linkage type of function is invalid");
382 if (entity->function.actual_name != NULL)
383 return new_id_from_str(entity->function.actual_name->string);
388 obstack_printf(&obst, "_%s", entity->base.symbol->string);
389 return make_id_from_obst();
392 void init_mangle(void)
397 void exit_mangle(void)
399 obstack_free(&obst, NULL);