fix cmp_ASM_attr
[libfirm] / ir / ident / mangle.c
1 /*
2  * Copyright (C) 1995-2010 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_t.h"
31 #include "obst.h"
32 #include "irprintf.h"
33
34 /* Make types visible to allow most efficient access */
35 #include "entity_t.h"
36 #include "type_t.h"
37 #include "tpop_t.h"
38
39 /** An obstack used for temporary space */
40 static struct obstack mangle_obst;
41
42 /** returned a mangled type name, currently no mangling */
43 static inline ident *mangle_type(const ir_type *tp)
44 {
45         assert(tp->kind == k_type);
46         return tp->name;
47 }
48
49 ident *id_mangle_entity(const ir_entity *ent)
50 {
51         ident *type_id;
52         char *cp;
53         int len;
54         ident *res;
55
56         type_id = mangle_type(ent->owner);
57         obstack_grow(&mangle_obst, get_id_str(type_id), get_id_strlen(type_id));
58         obstack_1grow(&mangle_obst,'_');
59         obstack_grow(&mangle_obst, get_id_str(ent->name), get_id_strlen(ent->name));
60         len = obstack_object_size(&mangle_obst);
61         cp = (char*)obstack_finish(&mangle_obst);
62         res = new_id_from_chars(cp, len);
63         obstack_free(&mangle_obst, cp);
64         return res;
65 }
66
67
68 /* Returns a new ident that represents 'firstscnd'. */
69 ident *id_mangle(ident *first, ident *scnd)
70 {
71         char *cp;
72         int len;
73         ident *res;
74
75         obstack_grow(&mangle_obst, get_id_str(first), get_id_strlen(first));
76         obstack_grow(&mangle_obst, get_id_str(scnd), get_id_strlen(scnd));
77         len = obstack_object_size(&mangle_obst);
78         cp = (char*)obstack_finish(&mangle_obst);
79         res = new_id_from_chars(cp, len);
80         obstack_free(&mangle_obst, cp);
81         return res;
82 }
83
84 /** Returns a new ident that represents 'prefixscndsuffix'. */
85 ident *id_mangle3(const char *prefix, ident *scnd, const char *suffix)
86 {
87         char *cp;
88         int len;
89         ident *res;
90
91         obstack_grow(&mangle_obst, prefix, strlen(prefix));
92         obstack_grow(&mangle_obst, get_id_str(scnd), get_id_strlen(scnd));
93         obstack_grow(&mangle_obst, suffix, strlen(suffix));
94         len = obstack_object_size(&mangle_obst);
95         cp  = (char*)obstack_finish(&mangle_obst);
96         res = new_id_from_chars(cp, len);
97         obstack_free(&mangle_obst, cp);
98         return res;
99 }
100
101 /** Returns a new ident that represents first<c>scnd. */
102 static ident *id_mangle_3(ident *first, char c, ident *scnd)
103 {
104         char *cp;
105         int len;
106         ident *res;
107
108         obstack_grow(&mangle_obst, get_id_str(first), get_id_strlen(first));
109         obstack_1grow(&mangle_obst, c);
110         obstack_grow(&mangle_obst,get_id_str(scnd),get_id_strlen(scnd));
111         len = obstack_object_size(&mangle_obst);
112         cp = (char*)obstack_finish(&mangle_obst);
113         res = new_id_from_chars(cp, len);
114         obstack_free(&mangle_obst, cp);
115         return res;
116 }
117
118 /* Returns a new ident that represents first_scnd. */
119 ident *id_mangle_u(ident *first, ident* scnd)
120 {
121         return id_mangle_3(first, '_', scnd);
122 }
123
124 /* Returns a new ident that represents first.scnd. */
125 ident *id_mangle_dot(ident *first, ident *scnd)
126 {
127         return id_mangle_3(first, '.', scnd);
128 }
129
130 /* returns a mangled name for a Win32 function using its calling convention */
131 ident *id_decorate_win32_c_fkt(const ir_entity *ent, ident *id)
132 {
133         ir_type *tp      = get_entity_type(ent);
134         unsigned cc_mask = get_method_calling_convention(tp);
135         char buf[16];
136
137         if (IS_CDECL(cc_mask))
138                 return id_mangle3("_", id, "");
139         else if (IS_STDCALL(cc_mask)) {
140                 size_t i, size = 0;
141
142                 for (i = get_method_n_params(tp); i > 0;) {
143                         size += get_type_size_bytes(get_method_param_type(tp, --i));
144                 }
145
146                 ir_snprintf(buf, sizeof(buf), "@%zu", size);
147
148                 if (cc_mask & cc_reg_param)
149                         return id_mangle3("@", id, buf);
150                 else
151                         return id_mangle3("_", id, buf);
152         }
153         return id;
154 }
155
156 void firm_init_mangle(void)
157 {
158         obstack_init(&mangle_obst);
159 }