OSDN Git Service

Added Java 1.1 language features.
[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, 1999 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 "tree.h"
32 #include "java-tree.h"
33 #include "obstack.h"
34 #include "toplev.h"
35
36 /* Assuming (NAME, LEN) is a Utf8-encoding string, calculate
37    the length of the string as mangled (a la g++) including Unicode escapes.
38    If no escapes are needed, return 0. */
39
40 int
41 unicode_mangling_length (name, len)
42      const char *name; 
43      int len; 
44 {
45   const unsigned char *ptr;
46   const unsigned char *limit = (const unsigned char *)name + len;
47   int need_escapes = 0;
48   int num_chars = 0;
49   int underscores = 0;
50   for (ptr = (const unsigned char *) name;  ptr < limit;  )
51     {
52       int ch = UTF8_GET(ptr, limit);
53       if (ch < 0)
54         error ("internal error - invalid Utf8 name");
55       if (ch >= '0' && ch <= '9')
56         need_escapes += num_chars == 0;
57       else if (ch == '_')
58         underscores++;
59       else if (ch != '$' && (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))
60         need_escapes++;
61       num_chars++;
62     }
63   if (need_escapes)
64     return num_chars + 4 * (need_escapes + underscores);
65   else
66     return 0;
67 }
68
69 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
70    appropriately mangled (with Unicode escapes) to OBSTACK. */
71
72 void
73 emit_unicode_mangled_name (obstack, name, len)
74      struct obstack *obstack;
75      const char *name;
76      int len;
77 {
78   const unsigned char *ptr;
79   const unsigned char *limit = (const unsigned char *)name + len;
80   for (ptr = (const unsigned char *) name;  ptr < limit;  )
81     {
82       int ch = UTF8_GET(ptr, limit);
83       int emit_escape;
84       if (ch < 0)
85         {
86           error ("internal error - bad Utf8 string");
87           break;
88         }
89       if (ch >= '0' && ch <= '9')
90         emit_escape = (ptr == (const unsigned char *) name);
91       else
92         emit_escape = (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z');
93       if (emit_escape)
94         {
95           char buf[6];
96           sprintf (buf, "_%04x", ch);
97           obstack_grow (obstack, buf, 5);
98         }
99       else
100         {
101           obstack_1grow (obstack, ch);
102         }
103     }
104 }
105
106 /* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
107    appropriately mangled (with Unicode escapes if needed) to OBSTACK. */
108
109 void
110 append_gpp_mangled_name (obstack, name, len)
111      struct obstack *obstack;
112      const char *name;
113      int len;
114 {
115   int encoded_len = unicode_mangling_length (name, len);
116   int needs_escapes = encoded_len > 0;
117   char buf[6];
118   if (needs_escapes)
119     {
120       sprintf (buf, "U%d", encoded_len);
121       obstack_grow (obstack, buf, strlen(buf));
122       emit_unicode_mangled_name (obstack, name, len);
123     }
124   else
125     {
126       sprintf (buf, "%d", len);
127       obstack_grow (obstack, buf, strlen(buf));
128       obstack_grow (obstack, name, len);
129     }
130 }
131
132 /* Append the mangled name of a class named CLASSNAME onto OBSTACK. */
133
134 void
135 append_gpp_mangled_classtype (obstack, class_name)
136      struct obstack *obstack;
137      const char *class_name;
138 {
139   const char *ptr;
140   int qualifications = 0;
141
142   for (ptr = class_name; *ptr != '\0'; ptr++)
143     {
144       if (*ptr == '.')
145         qualifications++;
146     }
147   if (qualifications)
148     {
149       char buf[8];
150       if (qualifications >= 9)
151         sprintf (buf, "Q_%d_", qualifications + 1);
152       else
153         sprintf (buf, "Q%d", qualifications + 1);
154       obstack_grow (obstack, buf, strlen (buf));
155     }
156   for (ptr = class_name; ; ptr++)
157     {
158       if (ptr[0] == '.' || ptr[0] == '\0')
159         {
160           append_gpp_mangled_name (obstack, class_name, ptr - class_name);
161           if (ptr[0] == '\0')
162             break;
163           class_name = ptr + 1;
164         }
165     }
166 }