calling convetions are now read from the method type
[libfirm] / ir / tr / mangle.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/tr/mangle.c
4  * Purpose:     Methods to manipulate names.
5  * Author:      Martin Trapp, Christian Schaefer
6  * Modified by: Goetz Lindenmaier
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #include "mangle.h"
17 #include "obst.h"
18
19 /* Make types visible to allow most efficient access */
20 #include "entity_t.h"
21 #include "type_t.h"
22 #include "tpop_t.h"
23
24 /** a obstack used for temporary space */
25 static struct obstack mangle_obst;
26
27 /** returned a mangled type name, currently no mangling */
28 static INLINE ident *
29 mangle_type (type *tp)
30 {
31   assert (tp->kind == k_type);
32   return tp->name;
33 }
34
35 ident *
36 mangle_entity (entity *ent)
37 {
38   ident *type_id;
39   char *cp;
40   int len;
41   ident *res;
42
43   type_id = mangle_type(ent->owner);
44   obstack_grow(&mangle_obst, get_id_str(type_id), get_id_strlen(type_id));
45   obstack_1grow(&mangle_obst,'_');
46   obstack_grow(&mangle_obst,get_id_str(ent->name),get_id_strlen(ent->name));
47   len = obstack_object_size (&mangle_obst);
48   cp = obstack_finish (&mangle_obst);
49   res = new_id_from_chars(cp, len);
50   obstack_free (&mangle_obst, cp);
51   return res;
52 }
53
54
55 /* Returns a new ident that represents 'firstscnd'. */
56 ident *mangle (ident *first, ident *scnd) {
57   char *cp;
58   int len;
59   ident *res;
60
61   obstack_grow(&mangle_obst, get_id_str(first), get_id_strlen(first));
62   obstack_grow(&mangle_obst, get_id_str(scnd), get_id_strlen(scnd));
63   len = obstack_object_size (&mangle_obst);
64   cp = obstack_finish (&mangle_obst);
65   res = new_id_from_chars (cp, len);
66   obstack_free (&mangle_obst, cp);
67   return res;
68 }
69
70 /* Returns a new ident that represents 'prefixscndsuffix'. */
71 static ident *mangle3(const char *prefix, ident *scnd, const char *suffix) {
72   char *cp;
73   int len;
74   ident *res;
75
76   obstack_grow(&mangle_obst, prefix, strlen(prefix));
77   obstack_grow(&mangle_obst, get_id_str(scnd), get_id_strlen(scnd));
78   obstack_grow(&mangle_obst, suffix, strlen(suffix));
79   len = obstack_object_size (&mangle_obst);
80   cp  = obstack_finish (&mangle_obst);
81   res = new_id_from_chars (cp, len);
82   obstack_free (&mangle_obst, cp);
83   return res;
84 }
85
86 /* Returns a new ident that represents first_scnd. */
87 ident *mangle_u (ident *first, ident* scnd) {
88   char *cp;
89   int len;
90   ident *res;
91
92   obstack_grow(&mangle_obst, get_id_str(first), get_id_strlen(first));
93   obstack_1grow(&mangle_obst,'_');
94   obstack_grow(&mangle_obst,get_id_str(scnd),get_id_strlen(scnd));
95   len = obstack_object_size (&mangle_obst);
96   cp = obstack_finish (&mangle_obst);
97   res = new_id_from_chars (cp, len);
98   obstack_free (&mangle_obst, cp);
99   return res;
100 }
101
102 /* returns a mangled name for a Win32 function using it's calling convention */
103 ident *decorate_win32_c_fkt(entity *ent) {
104   type *tp         = get_entity_type(ent);
105   unsigned cc_mask = get_method_calling_convention(tp);
106   char buf[16];
107   int size, i;
108
109   if (IS_CDECL(cc_mask))
110     return mangle3("_", get_entity_ident(ent), "");
111   else if (IS_STDCALL(cc_mask)) {
112
113     size = 0;
114     for (i = get_method_n_params(tp) - 1; i >= 0; --i) {
115       size += get_type_size_bytes(get_method_param_type(tp, i));
116     }
117
118     snprintf(buf, sizeof(buf), "@%d", size);
119
120     if (cc_mask & cc_reg_param)
121       return mangle3("@", get_entity_ident(ent), buf);
122     else
123       return mangle3("_", get_entity_ident(ent), buf);
124   }
125   return get_entity_ident(ent);
126 }
127
128 void
129 firm_init_mangle (void)
130 {
131   obstack_init(&mangle_obst);
132 }