Implement binary emitter for Perm.
[libfirm] / ir / ident / mangle.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Methods to manipulate names.
23  * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Michael Beck
24  * @version $Id$
25  */
26 #include "config.h"
27
28 # include <stdio.h>
29
30 #include "ident.h"
31 #include "obst.h"
32
33 /* Make types visible to allow most efficient access */
34 #include "entity_t.h"
35 #include "type_t.h"
36 #include "tpop_t.h"
37
38 /** An obstack used for temporary space */
39 static struct obstack mangle_obst;
40
41 /** returned a mangled type name, currently no mangling */
42 static inline ident *mangle_type(ir_type *tp) {
43         assert(tp->kind == k_type);
44         return tp->name;
45 }
46
47 ident *id_mangle_entity(ir_entity *ent) {
48         ident *type_id;
49         char *cp;
50         int len;
51         ident *res;
52
53         type_id = mangle_type(ent->owner);
54         obstack_grow(&mangle_obst, get_id_str(type_id), get_id_strlen(type_id));
55         obstack_1grow(&mangle_obst,'_');
56         obstack_grow(&mangle_obst,get_id_str(ent->name),get_id_strlen(ent->name));
57         len = obstack_object_size (&mangle_obst);
58         cp = obstack_finish (&mangle_obst);
59         res = new_id_from_chars(cp, len);
60         obstack_free (&mangle_obst, cp);
61         return res;
62 }
63
64
65 /* Returns a new ident that represents 'firstscnd'. */
66 ident *id_mangle(ident *first, ident *scnd) {
67         char *cp;
68         int len;
69         ident *res;
70
71         obstack_grow(&mangle_obst, get_id_str(first), get_id_strlen(first));
72         obstack_grow(&mangle_obst, get_id_str(scnd), get_id_strlen(scnd));
73         len = obstack_object_size (&mangle_obst);
74         cp = obstack_finish (&mangle_obst);
75         res = new_id_from_chars (cp, len);
76         obstack_free (&mangle_obst, cp);
77         return res;
78 }
79
80 /** Returns a new ident that represents 'prefixscndsuffix'. */
81 ident *id_mangle3(const char *prefix, ident *scnd, const char *suffix) {
82         char *cp;
83         int len;
84         ident *res;
85
86         obstack_grow(&mangle_obst, prefix, strlen(prefix));
87         obstack_grow(&mangle_obst, get_id_str(scnd), get_id_strlen(scnd));
88         obstack_grow(&mangle_obst, suffix, strlen(suffix));
89         len = obstack_object_size (&mangle_obst);
90         cp  = obstack_finish (&mangle_obst);
91         res = new_id_from_chars (cp, len);
92         obstack_free (&mangle_obst, cp);
93         return res;
94 }
95
96 /** Returns a new ident that represents first<c>scnd. */
97 static ident *id_mangle_3(ident *first, char c, ident* scnd) {
98         char *cp;
99         int len;
100         ident *res;
101
102         obstack_grow(&mangle_obst, get_id_str(first), get_id_strlen(first));
103         obstack_1grow(&mangle_obst, c);
104         obstack_grow(&mangle_obst,get_id_str(scnd),get_id_strlen(scnd));
105         len = obstack_object_size (&mangle_obst);
106         cp = obstack_finish (&mangle_obst);
107         res = new_id_from_chars (cp, len);
108         obstack_free (&mangle_obst, cp);
109         return res;
110 }
111
112 /* Returns a new ident that represents first_scnd. */
113 ident *id_mangle_u(ident *first, ident* scnd) {
114         return id_mangle_3(first, '_', scnd);
115 }
116
117 /* Returns a new ident that represents first.scnd. */
118 ident *id_mangle_dot(ident *first, ident* scnd) {
119         return id_mangle_3(first, '.', scnd);
120 }
121
122 /* returns a mangled name for a Win32 function using it's calling convention */
123 ident *id_decorate_win32_c_fkt(ir_entity *ent, ident *id) {
124         ir_type *tp      = get_entity_type(ent);
125         unsigned cc_mask = get_method_calling_convention(tp);
126         char buf[16];
127         int size, i;
128
129         if (IS_CDECL(cc_mask))
130                 return id_mangle3("_", id, "");
131         else if (IS_STDCALL(cc_mask)) {
132                 size = 0;
133                 for (i = get_method_n_params(tp) - 1; i >= 0; --i) {
134                         size += get_type_size_bytes(get_method_param_type(tp, i));
135                 }
136
137                 snprintf(buf, sizeof(buf), "@%d", size);
138
139                 if (cc_mask & cc_reg_param)
140                         return id_mangle3("@", id, buf);
141                 else
142                         return id_mangle3("_", id, buf);
143         }
144         return id;
145 }
146
147 void firm_init_mangle(void) {
148         obstack_init(&mangle_obst);
149 }