OSDN Git Service

* hashtable.c (calc_hash): Fix HASHSTEP definition.
[pf3gnuchains/gcc-fork.git] / gcc / stringpool.c
1 /* String pool for GCC.
2    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU CC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.  */
20
21 /* String text, identifer text and identifier node allocator.  Strings
22    allocated by ggc_alloc_string are stored in an obstack which is
23    never shrunk.  Identifiers are uniquely stored in a hash table.
24
25    We have our own private hash table implementation.  libiberty's
26    hashtab.c is not used because it requires 100% average space
27    overhead per string, which is unacceptable.  Also, this algorithm
28    is faster.  */
29
30 #include "config.h"
31 #include "system.h"
32 #include "ggc.h"
33 #include "tree.h"
34 #include "hashtable.h"
35 #include "flags.h"
36 #include "toplev.h"
37
38 #define IS_FE_IDENT(NODE) (TREE_CODE (NODE) == IDENTIFIER_NODE)
39
40 /* The "" allocated string.  */
41 const char empty_string[] = "";
42
43 /* Character strings, each containing a single decimal digit.
44    Written this way to save space.  */
45 const char digit_vector[] = {
46   '0', 0, '1', 0, '2', 0, '3', 0, '4', 0,
47   '5', 0, '6', 0, '7', 0, '8', 0, '9', 0
48 };
49
50 struct ht *ident_hash;
51 static struct obstack string_stack;
52 static int do_identifier_warnings;
53
54 static hashnode alloc_node PARAMS ((hash_table *));
55 static int mark_ident PARAMS ((struct cpp_reader *, hashnode, const PTR));
56 static void mark_ident_hash PARAMS ((void *));
57 static int scan_for_clashes PARAMS ((struct cpp_reader *, hashnode,
58                                      const char *));
59
60 /* Initialize the string pool.  */
61 void
62 init_stringpool ()
63 {
64   /* Create with 16K (2^14) entries.  */
65   ident_hash = ht_create (14);
66   ident_hash->alloc_node = alloc_node;
67   gcc_obstack_init (&string_stack);
68   ggc_add_root (&ident_hash, 1, sizeof ident_hash, mark_ident_hash);
69 }
70
71 /* Allocate a hash node.  */
72 static hashnode
73 alloc_node (table)
74      hash_table *table ATTRIBUTE_UNUSED;
75 {
76   return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE));
77 }
78
79 /* Allocate and return a string constant of length LENGTH, containing
80    CONTENTS.  If LENGTH is -1, CONTENTS is assumed to be a
81    nul-terminated string, and the length is calculated using strlen.
82    If the same string constant has been allocated before, that copy is
83    returned this time too.  */
84
85 const char *
86 ggc_alloc_string (contents, length)
87      const char *contents;
88      int length;
89 {
90   if (length == -1)
91     length = strlen (contents);
92
93   if (length == 0)
94     return empty_string;
95   if (length == 1 && contents[0] >= '0' && contents[0] <= '9')
96     return digit_string (contents[0] - '0');
97
98   obstack_grow0 (&string_stack, contents, length);
99   return obstack_finish (&string_stack);
100 }
101
102 /* NODE is an identifier known to the preprocessor.  Make it known to
103    the front ends as well.  */
104
105 void
106 make_identifier (node)
107      tree node;
108 {
109   /* If this identifier is longer than the clash-warning length,
110      do a brute force search of the entire table for clashes.  */
111   if (warn_id_clash && do_identifier_warnings
112       && IDENTIFIER_LENGTH (node) >= id_clash_len)
113     ht_forall (ident_hash, (ht_cb) scan_for_clashes,
114                IDENTIFIER_POINTER (node));
115
116   TREE_SET_CODE (node, IDENTIFIER_NODE);
117 }
118
119 /* Return an IDENTIFIER_NODE whose name is TEXT (a null-terminated string).
120    If an identifier with that name has previously been referred to,
121    the same node is returned this time.  */
122
123 tree
124 get_identifier (text)
125      const char *text;
126 {
127   hashnode ht_node = ht_lookup (ident_hash,
128                                 (const unsigned char *) text,
129                                 strlen (text), HT_ALLOC);
130
131   /* ht_node can't be NULL here.  */
132   return HT_IDENT_TO_GCC_IDENT (ht_node);
133 }
134
135 /* If an identifier with the name TEXT (a null-terminated string) has
136    previously been referred to, return that node; otherwise return
137    NULL_TREE.  */
138
139 tree
140 maybe_get_identifier (text)
141      const char *text;
142 {
143   hashnode ht_node;
144   tree node;
145   size_t length = strlen (text);
146
147   ht_node = ht_lookup (ident_hash, (const unsigned char *) text,
148                        length, HT_NO_INSERT);
149   if (ht_node)
150     {
151       node = HT_IDENT_TO_GCC_IDENT (ht_node);
152       if (IS_FE_IDENT (node))
153         return node;
154     }
155
156   return NULL_TREE;
157 }
158
159 /* If this identifier is longer than the clash-warning length,
160    do a brute force search of the entire table for clashes.  */
161
162 static int
163 scan_for_clashes (pfile, h, text)
164      struct cpp_reader *pfile ATTRIBUTE_UNUSED;
165      hashnode h;
166      const char *text;
167 {
168   tree node = HT_IDENT_TO_GCC_IDENT (h);
169
170   if (IS_FE_IDENT (node)
171       && IDENTIFIER_LENGTH (node) >= id_clash_len
172       && !memcmp (IDENTIFIER_POINTER (node), text, id_clash_len))
173     {
174       warning ("\"%s\" and \"%s\" identical in first %d characters",
175                text, IDENTIFIER_POINTER (node), id_clash_len);
176       return 0;
177     }
178
179   return 1;
180 }
181
182 /* Record the size of an identifier node for the language in use.
183    SIZE is the total size in bytes.
184    This is called by the language-specific files.  This must be
185    called before allocating any identifiers.  */
186
187 void
188 set_identifier_size (size)
189      int size;
190 {
191   tree_code_length[(int) IDENTIFIER_NODE]
192     = (size - sizeof (struct tree_common)) / sizeof (tree);
193 }
194
195 /* Enable warnings on similar identifiers (if requested).
196    Done after the built-in identifiers are created.  */
197
198 void
199 start_identifier_warnings ()
200 {
201   do_identifier_warnings = 1;
202 }
203
204 /* Report some basic statistics about the string pool.  */
205
206 void
207 stringpool_statistics ()
208 {
209   ht_dump_statistics (ident_hash);
210 }
211
212 /* Mark an identifier for GC.  */
213
214 static int
215 mark_ident (pfile, h, v)
216      struct cpp_reader *pfile ATTRIBUTE_UNUSED;
217      hashnode h;
218      const PTR v ATTRIBUTE_UNUSED;
219 {
220   ggc_mark_nonnull_tree (HT_IDENT_TO_GCC_IDENT (h));
221   return 1;
222 }
223
224 /* Mark all identifiers for GC.  */
225
226 static void
227 mark_ident_hash (arg)
228      PTR arg ATTRIBUTE_UNUSED;
229 {
230   ht_forall (ident_hash, mark_ident, NULL);
231 }