OSDN Git Service

Tue Nov 10 12:34:03 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / mangle.c
1 /* Functions related to mangling class names for the GNU compiler
2    for the Java(TM) language.
3    Copyright (C) 1998 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 
21
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
25
26 /* Written by Per Bothner <bothner@cygnus.com> */
27
28 #include "config.h"
29 #include "system.h"
30 #include "jcf.h"
31 #include "obstack.h"
32
33 /* Assuming (NAME, LEN) is a Utf8-encoding string, calculate
34    the length of the string as mangled (a la g++) including Unicode escapes.
35    If no escapes are needed, return 0. */
36
37 int
38 unicode_mangling_length (name, len)
39      char *name; 
40      int len; 
41 {
42   unsigned char *ptr;
43   unsigned char *limit = (unsigned char *)name + len;
44   int need_escapes = 0;
45   int num_chars = 0;
46   int underscores = 0;
47   for (ptr = (unsigned char *) name;  ptr < limit;  )
48     {
49       int ch = UTF8_GET(ptr, limit);
50       if (ch < 0)
51         error ("internal error - invalid Utf8 name");
52       if (ch >= '0' && ch <= '9')
53         need_escapes += num_chars == 0;
54       else if (ch == '_')
55         underscores++;
56       else if ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))
57         need_escapes++;
58       num_chars++;
59     }
60   if (need_escapes)
61     return num_chars + 4 * (need_escapes + underscores);
62   else
63     return 0;
64 }
65
66 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
67    appropriately mangled (with Unicode escapes) to OBSTACK. */
68
69 void
70 emit_unicode_mangled_name (obstack, name, len)
71      struct obstack *obstack;
72      char *name;
73 {
74   unsigned char *ptr;
75   unsigned char *limit = (unsigned char *)name + len;
76   for (ptr = (unsigned char *) name;  ptr < limit;  )
77     {
78       int ch = UTF8_GET(ptr, limit);
79       int emit_escape;
80       if (ch < 0)
81         {
82           error ("internal error - bad Utf8 string");
83           break;
84         }
85       if (ch >= '0' && ch <= '9')
86         emit_escape = (ptr == (unsigned char*) name);
87       else
88         emit_escape = (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z');
89       if (emit_escape)
90         {
91           char buf[6];
92           sprintf (buf, "_%04x", ch);
93           obstack_grow (obstack, buf, 5);
94         }
95       else
96         {
97           obstack_1grow (obstack, ch);
98         }
99     }
100 }
101
102 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
103    appropriately mangled (with Unicode escapes if needed) to OBSTACK. */
104
105 void
106 append_gpp_mangled_name (obstack, name, len)
107      struct obstack *obstack;
108      char *name;
109      int len;
110 {
111   int encoded_len = unicode_mangling_length (name, len);
112   int needs_escapes = encoded_len > 0;
113   char buf[6];
114   if (needs_escapes)
115     {
116       sprintf (buf, "U%d", encoded_len);
117       obstack_grow (obstack, buf, strlen(buf));
118       emit_unicode_mangled_name (obstack, name, len);
119     }
120   else
121     {
122       sprintf (buf, "%d", len);
123       obstack_grow (obstack, buf, strlen(buf));
124       obstack_grow (obstack, name, len);
125     }
126 }
127
128 /* Append the mangled name of a class named CLASSNAME onto OBSTACK. */
129
130 void
131 append_gpp_mangled_classtype (obstack, class_name)
132      struct obstack *obstack;
133      char *class_name;
134 {
135   char *ptr;
136   int qualifications = 0;
137
138   for (ptr = class_name; *ptr != '\0'; ptr++)
139     {
140       if (*ptr == '.')
141         qualifications++;
142     }
143   if (qualifications)
144     {
145       char buf[8];
146       if (qualifications >= 9)
147         sprintf (buf, "Q_%d_", qualifications + 1);
148       else
149         sprintf (buf, "Q%d", qualifications + 1);
150       obstack_grow (obstack, buf, strlen (buf));
151     }
152   for (ptr = class_name; ; ptr++)
153     {
154       if (ptr[0] == '.' || ptr[0] == '\0')
155         {
156           append_gpp_mangled_name (obstack, class_name, ptr - class_name);
157           if (ptr[0] == '\0')
158             break;
159           class_name = ptr + 1;
160         }
161     }
162 }