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