]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/repo.c
(call_internal_reg): Fix typos in length calculation.
[thirdparty/gcc.git] / gcc / cp / repo.c
CommitLineData
bb09dca5 1/* Code to maintain a C++ template repository.
2 Copyright (C) 1995 Free Software Foundation, Inc.
3 Contributed by Jason Merrill (jason@cygnus.com)
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* My strategy here is as follows:
22
23 Everything should be emitted in a translation unit where it is used.
24 The results of the automatic process should be easily reproducible with
11682839 25 explicit code. */
bb09dca5 26
27#include <stdio.h>
11682839 28#include "config.h"
bb09dca5 29#include "tree.h"
30#include "cp-tree.h"
31#include "input.h"
3e1ffd94 32#include "obstack.h"
bb09dca5 33
34extern char * rindex ();
11682839 35extern char * getenv ();
bb09dca5 36
37static tree pending_repo;
3e1ffd94 38static tree original_repo;
bb09dca5 39static char repo_name[1024];
40static FILE *repo_file;
41
42extern int flag_use_repository;
43extern int errorcount, sorrycount;
44
bb09dca5 45#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
46#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
47
48/* Record the flags used to compile this translation unit. */
49
50void
51repo_compile_flags (argc, argv)
52 int argc;
53 char **argv;
54{
55}
56
57/* If this template has not been seen before, add a note to the repository
58 saying where the declaration was. This may be used to find the
59 definition at link time. */
60
61void
62repo_template_declared (t)
63 tree t;
64{}
65
66/* Note where the definition of a template lives so that instantiations can
67 be generated later. */
68
69void
70repo_template_defined (t)
71 tree t;
72{}
73
74/* Note where the definition of a class lives to that template
75 instantiations can use it. */
76
77void
78repo_class_defined (t)
79 tree t;
80{}
81
dc76caae 82tree
83repo_get_id (t)
84 tree t;
85{
86 if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
87 {
88 t = TYPE_BINFO_VTABLE (t);
89 if (t == NULL_TREE)
90 return t;
91 }
92 return DECL_ASSEMBLER_NAME (t);
93}
94
bb09dca5 95/* Note that a template has been used. If we can see the definition, offer
96 to emit it. */
97
98void
99repo_template_used (t)
100 tree t;
101{
102 tree id;
103
104 if (! flag_use_repository)
105 return;
106
dc76caae 107 id = repo_get_id (t);
108 if (id == NULL_TREE)
109 return;
110
bb09dca5 111 if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
112 {
bb09dca5 113 if (IDENTIFIER_REPO_CHOSEN (id))
114 mark_class_instantiated (t, 0);
115 }
116 else if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
117 {
bb09dca5 118 if (IDENTIFIER_REPO_CHOSEN (id))
119 mark_function_instantiated (t, 0);
120 }
121 else
122 my_friendly_abort (1);
123
124 if (! IDENTIFIER_REPO_USED (id))
125 {
bb09dca5 126 IDENTIFIER_REPO_USED (id) = 1;
3e1ffd94 127 pending_repo = perm_tree_cons (NULL_TREE, id, pending_repo);
bb09dca5 128 }
bb09dca5 129}
130
131/* Note that the vtable for a class has been used, and offer to emit it. */
132
133void
134repo_vtable_used (t)
135 tree t;
136{
137 if (! flag_use_repository)
138 return;
139
140 pending_repo = perm_tree_cons (NULL_TREE, t, pending_repo);
141}
142
143/* Note that an inline with external linkage has been used, and offer to
144 emit it. */
145
146void
147repo_inline_used (fn)
148 tree fn;
149{
150 if (! flag_use_repository)
151 return;
152
153 /* Member functions of polymorphic classes go with their vtables. */
154 if (DECL_FUNCTION_MEMBER_P (fn) && TYPE_VIRTUAL_P (DECL_CLASS_CONTEXT (fn)))
155 {
156 repo_vtable_used (DECL_CLASS_CONTEXT (fn));
157 return;
158 }
159
160 pending_repo = perm_tree_cons (NULL_TREE, fn, pending_repo);
161}
162
163/* Note that a particular typeinfo node has been used, and offer to
164 emit it. */
165
166void
167repo_tinfo_used (ti)
168 tree ti;
169{
170}
171
dc76caae 172void
173repo_template_instantiated (t, extern_p)
174 tree t;
175 int extern_p;
176{
177 if (! extern_p)
178 {
179 tree id = repo_get_id (t);
180 if (id)
181 IDENTIFIER_REPO_CHOSEN (id) = 1;
182 }
183}
184
11682839 185static char *
186save_string (s, len)
187 char *s;
188 int len;
189{
3e1ffd94 190 extern struct obstack temporary_obstack;
191 return obstack_copy0 (&temporary_obstack, s, len);
11682839 192}
193
194static char *
195get_base_filename (filename)
196 char *filename;
197{
198 char *p = getenv ("COLLECT_GCC_OPTIONS");
199 char *output = 0;
200 int compiling = 0;
201
202 if (p)
203 while (*p)
204 {
205 char *q = p;
206 while (*q && *q != ' ') q++;
207 if (*p == '-' && p[1] == 'o')
208 {
209 p += 2;
210 if (p == q)
211 {
212 p++; q++;
213 if (*q)
214 while (*q && *q != ' ') q++;
215 }
216
217 output = save_string (p, q - p);
218 }
219 else if (*p == '-' && p[1] == 'c')
220 compiling = 1;
221 if (*q) q++;
222 p = q;
223 }
224
225 if (compiling && output)
226 return output;
227
3e1ffd94 228 if (p && ! compiling)
229 {
230 warning ("-frepo must be used with -c");
231 flag_use_repository = 0;
232 return NULL;
233 }
234
235 p = rindex (filename, '/');
236 if (p)
237 return p+1;
238 else
239 return filename;
11682839 240}
241
bb09dca5 242static void
243open_repo_file (filename)
244 char *filename;
245{
246 register char *p, *q;
11682839 247 char *file = get_base_filename (filename);
3e1ffd94 248 char *s;
249
250 if (file == NULL)
251 return;
252
253 s = rindex (file, '/');
bb09dca5 254 if (s == NULL)
255 s = file;
256 else
257 ++s;
258
259 for (p = repo_name, q = file; q < s; )
260 *p++ = *q++;
3e1ffd94 261/* *p++ = '.'; */
11682839 262 if ((s = rindex (q, '.')) == NULL)
263 strcpy (p, q);
264 else
265 for (; q < s;)
266 *p++ = *q++;
3e1ffd94 267 strcat (p, ".rpo");
bb09dca5 268
269 repo_file = fopen (repo_name, "r");
270}
271
272void
273init_repo (filename)
274 char *filename;
275{
276 char buf[1024];
277
278 if (! flag_use_repository)
279 return;
280
3e1ffd94 281 open_repo_file (filename);
bb09dca5 282
283 if (repo_file == 0)
284 return;
285
286 while (fgets (buf, 1024, repo_file))
287 {
bb09dca5 288 switch (buf[0])
289 {
290 case 'A':
11682839 291 case 'G':
bb09dca5 292 case 'M':
293 break;
294 case 'C':
295 case 'O':
296 {
3e1ffd94 297 char *q;
dc76caae 298 tree id, orig;
3e1ffd94 299
300 for (q = &buf[2]; *q && *q != ' ' && *q != '\n'; ++q) ;
301 q = save_string (&buf[2], q - &buf[2]);
302 id = get_identifier (q);
303
bb09dca5 304 if (buf[0] == 'C')
dc76caae 305 {
306 IDENTIFIER_REPO_CHOSEN (id) = 1;
307 orig = integer_one_node;
308 }
309 else
310 orig = NULL_TREE;
311
312 original_repo = perm_tree_cons (orig, id, original_repo);
bb09dca5 313 }
314 break;
315 default:
316 error ("mysterious repository information in %s", repo_name);
317 }
318 }
319}
320
321static void
322reopen_repo_file_for_write ()
323{
324 if (repo_file)
325 fclose (repo_file);
326 repo_file = fopen (repo_name, "w");
327
328 if (repo_file == 0)
329 {
11682839 330 error ("can't create repository information file `%s'", repo_name);
bb09dca5 331 flag_use_repository = 0;
332 }
333}
334
335/* Emit any pending repos. */
336
337void
338finish_repo ()
339{
340 tree t;
11682839 341 char *p;
3e1ffd94 342 int repo_changed = 0;
bb09dca5 343
344 if (! flag_use_repository)
345 return;
346
347 /* Do we have to write out a new info file? */
348
dc76caae 349 /* Are there any old templates that aren't used any longer or that are
350 newly chosen? */
3e1ffd94 351
352 for (t = original_repo; t; t = TREE_CHAIN (t))
353 {
dc76caae 354 if (! IDENTIFIER_REPO_USED (TREE_VALUE (t))
355 || (! TREE_PURPOSE (t) && IDENTIFIER_REPO_CHOSEN (TREE_VALUE (t))))
3e1ffd94 356 {
357 repo_changed = 1;
358 break;
359 }
360 IDENTIFIER_REPO_USED (TREE_VALUE (t)) = 0;
361 }
362
363 /* Are there any templates that are newly used? */
364
365 if (! repo_changed)
366 for (t = pending_repo; t; t = TREE_CHAIN (t))
367 {
368 if (IDENTIFIER_REPO_USED (TREE_VALUE (t)))
369 {
370 repo_changed = 1;
371 break;
372 }
373 }
374
bb09dca5 375 if (! repo_changed || errorcount || sorrycount)
376 goto out;
377
378 reopen_repo_file_for_write ();
379
380 if (repo_file == 0)
381 goto out;
382
11682839 383 fprintf (repo_file, "M %s\n", main_input_filename);
384
385 p = getenv ("COLLECT_GCC");
386 if (p != 0)
387 fprintf (repo_file, "G %s\n", p);
388
389 p = getenv ("COLLECT_GCC_OPTIONS");
390 if (p != 0)
391 fprintf (repo_file, "A %s\n", p);
392
bb09dca5 393 for (t = pending_repo; t; t = TREE_CHAIN (t))
394 {
395 tree val = TREE_VALUE (t);
3e1ffd94 396 char type = IDENTIFIER_REPO_CHOSEN (val) ? 'C' : 'O';
bb09dca5 397
3e1ffd94 398 fprintf (repo_file, "%c %s ", type, IDENTIFIER_POINTER (val));
399 ASM_OUTPUT_LABELREF (repo_file, IDENTIFIER_POINTER (val));
400 putc ('\n', repo_file);
bb09dca5 401 }
402
403 out:
404 if (repo_file)
405 fclose (repo_file);
406}