]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/repo.c
c-common.h (lang_post_pch_load): New variable.
[thirdparty/gcc.git] / gcc / cp / repo.c
CommitLineData
faae18ab 1/* Code to maintain a C++ template repository.
43c6a96a
SB
2 Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
faae18ab
MS
4 Contributed by Jason Merrill (jason@cygnus.com)
5
f5adbb8d 6This file is part of GCC.
faae18ab 7
f5adbb8d 8GCC is free software; you can redistribute it and/or modify
faae18ab
MS
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
f5adbb8d 13GCC is distributed in the hope that it will be useful,
faae18ab
MS
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
f5adbb8d 19along with GCC; see the file COPYING. If not, write to
e9fa0c7c
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
faae18ab
MS
22
23/* My strategy here is as follows:
24
25 Everything should be emitted in a translation unit where it is used.
26 The results of the automatic process should be easily reproducible with
b19b4a78 27 explicit code. */
faae18ab 28
b19b4a78 29#include "config.h"
8d052bc7 30#include "system.h"
4977bab6
ZW
31#include "coretypes.h"
32#include "tm.h"
faae18ab
MS
33#include "tree.h"
34#include "cp-tree.h"
35#include "input.h"
79ff2c6c 36#include "obstack.h"
54f92bfb 37#include "toplev.h"
2a2b2d43 38#include "diagnostic.h"
faae18ab 39
848eed92
GDR
40static char *extract_string (char **);
41static const char *get_base_filename (const char *);
42static void open_repo_file (const char *);
43static char *afgets (FILE *);
44static void reopen_repo_file_for_write (void);
faae18ab 45
e2500fed 46static GTY(()) tree pending_repo;
e8abc66f 47static char *repo_name;
faae18ab
MS
48static FILE *repo_file;
49
e65e6212 50static const char *old_args, *old_dir, *old_main;
6633d636 51
1f8f4a0b 52static struct obstack temporary_obstack;
4684cd27 53static bool temporary_obstack_initialized_p;
44a8d0b3 54
6633d636
MS
55/* Parse a reasonable subset of shell quoting syntax. */
56
57static char *
848eed92 58extract_string (char **pp)
6633d636
MS
59{
60 char *p = *pp;
61 int backquote = 0;
62 int inside = 0;
63
64 for (;;)
65 {
66 char c = *p;
67 if (c == '\0')
68 break;
69 ++p;
70 if (backquote)
71 obstack_1grow (&temporary_obstack, c);
72 else if (! inside && c == ' ')
73 break;
74 else if (! inside && c == '\\')
75 backquote = 1;
76 else if (c == '\'')
77 inside = !inside;
78 else
79 obstack_1grow (&temporary_obstack, c);
80 }
81
82 obstack_1grow (&temporary_obstack, '\0');
83 *pp = p;
84 return obstack_finish (&temporary_obstack);
85}
86
8ce33230 87static const char *
848eed92 88get_base_filename (const char *filename)
b19b4a78
MS
89{
90 char *p = getenv ("COLLECT_GCC_OPTIONS");
6633d636 91 char *output = NULL;
b19b4a78
MS
92 int compiling = 0;
93
6633d636
MS
94 while (p && *p)
95 {
96 char *q = extract_string (&p);
b19b4a78 97
6633d636
MS
98 if (strcmp (q, "-o") == 0)
99 output = extract_string (&p);
100 else if (strcmp (q, "-c") == 0)
101 compiling = 1;
b19b4a78
MS
102 }
103
104 if (compiling && output)
105 return output;
106
79ff2c6c
MS
107 if (p && ! compiling)
108 {
8251199e 109 warning ("-frepo must be used with -c");
79ff2c6c
MS
110 flag_use_repository = 0;
111 return NULL;
112 }
113
b3e68a79 114 return lbasename (filename);
b19b4a78
MS
115}
116
faae18ab 117static void
848eed92 118open_repo_file (const char *filename)
faae18ab 119{
926ce8bd 120 const char *p;
d8e178a0 121 const char *s = get_base_filename (filename);
79ff2c6c 122
e8abc66f 123 if (s == NULL)
79ff2c6c
MS
124 return;
125
b3e68a79 126 p = lbasename (s);
9473c522 127 p = strrchr (p, '.');
e8abc66f
MS
128 if (! p)
129 p = s + strlen (s);
faae18ab 130
6d9f628e
GK
131 repo_name = xmalloc (p - s + 5);
132 memcpy (repo_name, s, p - s);
133 memcpy (repo_name + (p - s), ".rpo", 5);
faae18ab
MS
134
135 repo_file = fopen (repo_name, "r");
136}
137
e8abc66f 138static char *
848eed92 139afgets (FILE *stream)
e8abc66f
MS
140{
141 int c;
142 while ((c = getc (stream)) != EOF && c != '\n')
143 obstack_1grow (&temporary_obstack, c);
144 if (obstack_object_size (&temporary_obstack) == 0)
145 return NULL;
146 obstack_1grow (&temporary_obstack, '\0');
147 return obstack_finish (&temporary_obstack);
148}
149
faae18ab 150void
4684cd27 151init_repo (void)
faae18ab 152{
e8abc66f 153 char *buf;
faae18ab
MS
154
155 if (! flag_use_repository)
156 return;
157
4684cd27
MM
158 /* When a PCH file is loaded, the entire identifier table is
159 replaced, with the result that IDENTIFIER_REPO_CHOSEN is cleared.
160 So, we have to reread the repository file. */
161 lang_post_pch_load = init_repo;
162
163 if (!temporary_obstack_initialized_p)
164 gcc_obstack_init (&temporary_obstack);
9cd64686 165
4684cd27 166 open_repo_file (main_input_filename);
faae18ab
MS
167
168 if (repo_file == 0)
169 return;
170
a703fb38 171 while ((buf = afgets (repo_file)))
faae18ab 172 {
faae18ab
MS
173 switch (buf[0])
174 {
175 case 'A':
6d9f628e 176 old_args = ggc_strdup (buf + 2);
6633d636 177 break;
e8abc66f 178 case 'D':
6d9f628e 179 old_dir = ggc_strdup (buf + 2);
6633d636 180 break;
faae18ab 181 case 'M':
6d9f628e 182 old_main = ggc_strdup (buf + 2);
faae18ab 183 break;
faae18ab 184 case 'O':
4684cd27
MM
185 /* A symbol that we were able to define the last time this
186 file was compiled. */
187 break;
188 case 'C':
189 /* A symbol that the prelinker has requested that we
190 define. */
faae18ab 191 {
e8abc66f 192 tree id = get_identifier (buf + 2);
4684cd27 193 IDENTIFIER_REPO_CHOSEN (id) = 1;
faae18ab
MS
194 }
195 break;
196 default:
8251199e 197 error ("mysterious repository information in %s", repo_name);
faae18ab 198 }
e8abc66f 199 obstack_free (&temporary_obstack, buf);
faae18ab 200 }
4684cd27 201 fclose (repo_file);
faae18ab
MS
202}
203
204static void
848eed92 205reopen_repo_file_for_write (void)
faae18ab 206{
faae18ab
MS
207 repo_file = fopen (repo_name, "w");
208
209 if (repo_file == 0)
210 {
8251199e 211 error ("can't create repository information file `%s'", repo_name);
faae18ab
MS
212 flag_use_repository = 0;
213 }
214}
215
216/* Emit any pending repos. */
217
218void
848eed92 219finish_repo (void)
faae18ab
MS
220{
221 tree t;
6633d636 222 char *dir, *args;
faae18ab 223
848eed92 224 if (!flag_use_repository)
faae18ab
MS
225 return;
226
4684cd27 227 if (errorcount || sorrycount)
faae18ab
MS
228 goto out;
229
230 reopen_repo_file_for_write ();
faae18ab
MS
231 if (repo_file == 0)
232 goto out;
233
b19b4a78 234 fprintf (repo_file, "M %s\n", main_input_filename);
4684cd27 235 dir = getpwd ();
6633d636 236 fprintf (repo_file, "D %s\n", dir);
4684cd27 237 args = getenv ("COLLECT_GCC_OPTIONS");
6633d636
MS
238 if (args)
239 fprintf (repo_file, "A %s\n", args);
b19b4a78 240
faae18ab
MS
241 for (t = pending_repo; t; t = TREE_CHAIN (t))
242 {
243 tree val = TREE_VALUE (t);
4684cd27
MM
244 tree name = DECL_ASSEMBLER_NAME (val);
245 char type = IDENTIFIER_REPO_CHOSEN (name) ? 'C' : 'O';
246 fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (name));
faae18ab
MS
247 }
248
249 out:
250 if (repo_file)
251 fclose (repo_file);
252}
e2500fed 253
4684cd27
MM
254/* DECL is a FUNCTION_DECL or VAR_DECL with vague linkage whose
255 definition is available in this translation unit. Returns 0 if
256 this definition should not be emitted in this translation unit
257 because it will be emitted elsewhere. Returns 1 if the repository
258 file indicates that that DECL should be emitted in this translation
259 unit, or 2 if the repository file is not in use. */
260
261int
262repo_emit_p (tree decl)
263{
264 my_friendly_assert (TREE_PUBLIC (decl), 20040725);
265 my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL
266 || TREE_CODE (decl) == VAR_DECL,
267 20040725);
268 my_friendly_assert (!DECL_REALLY_EXTERN (decl), 20040725);
269
270 /* When not using the repository, emit everything. */
271 if (!flag_use_repository)
272 return 2;
273
274 /* Only template instantiations are managed by the repository. This
275 is an artificial restriction; the code in the prelinker and here
276 will work fine if all entities with vague linkage are managed by
277 the repository. */
278 if (TREE_CODE (decl) == VAR_DECL)
279 {
280 tree type = NULL_TREE;
281 if (DECL_VTABLE_OR_VTT_P (decl))
282 type = DECL_CONTEXT (decl);
283 else if (DECL_TINFO_P (decl))
284 type = TREE_TYPE (DECL_NAME (decl));
285 if (!DECL_TEMPLATE_INSTANTIATION (decl)
286 && !CLASSTYPE_TEMPLATE_INSTANTIATION (type))
287 return 2;
288 }
289 else if (!DECL_TEMPLATE_INSTANTIATION (decl))
290 return 2;
291
292 /* For constructors and destructors, the repository contains
293 information about the clones -- not the original function --
294 because only the clones are emitted in the object file. */
295 if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
296 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
297 {
298 int emit_p = 0;
299 tree clone;
300 /* There is no early exit from this loop because we want to
301 ensure that all of the clones are marked as available in this
302 object file. */
303 FOR_EACH_CLONE (clone, decl)
304 /* The only possible results from the recursive call to
305 repo_emit_p are 0 or 1. */
306 if (repo_emit_p (clone))
307 emit_p = 1;
308 return emit_p;
309 }
310
311 /* Keep track of all available entities. */
312 if (!DECL_REPO_AVAILABLE_P (decl))
313 {
314 DECL_REPO_AVAILABLE_P (decl) = 1;
315 pending_repo = tree_cons (NULL_TREE, decl, pending_repo);
316 }
317
318 return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl));
319}
320
321/* Returns true iff the prelinker has explicitly marked CLASS_TYPE for
322 export from this translation unit. */
323
324bool
325repo_export_class_p (tree class_type)
326{
327 if (!flag_use_repository)
328 return false;
329 if (!CLASSTYPE_VTABLES (class_type))
330 return false;
331 /* If the virtual table has been assigned to this translation unit,
332 export the class. */
333 return (IDENTIFIER_REPO_CHOSEN
334 (DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (class_type))));
335}
336
e2500fed 337#include "gt-cp-repo.h"