Fixed the last fix again:
[libfirm] / ir / tr / mangle.c
1 /*
2  * Copyright (C) 1995-2007 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 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_STDIO_H
31 # include <stdio.h>
32 #endif
33
34 #include "mangle.h"
35 #include "obst.h"
36
37 /* Make types visible to allow most efficient access */
38 #include "entity_t.h"
39 #include "type_t.h"
40 #include "tpop_t.h"
41
42 /** An obstack used for temporary space */
43 static struct obstack mangle_obst;
44
45 /** returned a mangled type name, currently no mangling */
46 static INLINE ident *mangle_type(ir_type *tp) {
47         assert(tp->kind == k_type);
48         return tp->name;
49 }
50
51 ident *mangle_entity(ir_entity *ent) {
52         ident *type_id;
53         char *cp;
54         int len;
55         ident *res;
56
57         type_id = mangle_type(ent->owner);
58         obstack_grow(&mangle_obst, get_id_str(type_id), get_id_strlen(type_id));
59         obstack_1grow(&mangle_obst,'_');
60         obstack_grow(&mangle_obst,get_id_str(ent->name),get_id_strlen(ent->name));
61         len = obstack_object_size (&mangle_obst);
62         cp = obstack_finish (&mangle_obst);
63         res = new_id_from_chars(cp, len);
64         obstack_free (&mangle_obst, cp);
65         return res;
66 }
67
68
69 /* Returns a new ident that represents 'firstscnd'. */
70 ident *mangle(ident *first, ident *scnd) {
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 = 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 static ident *mangle3(const char *prefix, ident *scnd, const char *suffix) {
86         char *cp;
87         int len;
88         ident *res;
89
90         obstack_grow(&mangle_obst, prefix, strlen(prefix));
91         obstack_grow(&mangle_obst, get_id_str(scnd), get_id_strlen(scnd));
92         obstack_grow(&mangle_obst, suffix, strlen(suffix));
93         len = obstack_object_size (&mangle_obst);
94         cp  = obstack_finish (&mangle_obst);
95         res = new_id_from_chars (cp, len);
96         obstack_free (&mangle_obst, cp);
97         return res;
98 }
99
100 /** Returns a new ident that represents first<c>scnd. */
101 static ident *mangle_3(ident *first, char c, ident* scnd) {
102         char *cp;
103         int len;
104         ident *res;
105
106         obstack_grow(&mangle_obst, get_id_str(first), get_id_strlen(first));
107         obstack_1grow(&mangle_obst, c);
108         obstack_grow(&mangle_obst,get_id_str(scnd),get_id_strlen(scnd));
109         len = obstack_object_size (&mangle_obst);
110         cp = obstack_finish (&mangle_obst);
111         res = new_id_from_chars (cp, len);
112         obstack_free (&mangle_obst, cp);
113         return res;
114 }
115
116 /* Returns a new ident that represents first_scnd. */
117 ident *mangle_u(ident *first, ident* scnd) {
118         return mangle_3(first, '_', scnd);
119 }
120
121 /* Returns a new ident that represents first.scnd. */
122 ident *mangle_dot(ident *first, ident* scnd) {
123         return mangle_3(first, '.', scnd);
124 }
125
126 /* returns a mangled name for a Win32 function using it's calling convention */
127 ident *decorate_win32_c_fkt(ir_entity *ent, ident *id) {
128         ir_type *tp      = get_entity_type(ent);
129         unsigned cc_mask = get_method_calling_convention(tp);
130         char buf[16];
131         int size, i;
132
133         if (IS_CDECL(cc_mask))
134                 return mangle3("_", id, "");
135         else if (IS_STDCALL(cc_mask)) {
136                 size = 0;
137                 for (i = get_method_n_params(tp) - 1; i >= 0; --i) {
138                         size += get_type_size_bytes(get_method_param_type(tp, i));
139                 }
140
141                 snprintf(buf, sizeof(buf), "@%d", size);
142
143                 if (cc_mask & cc_reg_param)
144                         return mangle3("@", id, buf);
145                 else
146                         return mangle3("_", id, buf);
147         }
148         return id;
149 }
150
151 void firm_init_mangle(void) {
152         obstack_init(&mangle_obst);
153 }