]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/repo.c
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / repo.c
CommitLineData
faae18ab 1/* Code to maintain a C++ template repository.
818ab71a 2 Copyright (C) 1995-2016 Free Software Foundation, Inc.
faae18ab
MS
3 Contributed by Jason Merrill (jason@cygnus.com)
4
f5adbb8d 5This file is part of GCC.
faae18ab 6
f5adbb8d 7GCC is free software; you can redistribute it and/or modify
faae18ab 8it under the terms of the GNU General Public License as published by
e77f031d 9the Free Software Foundation; either version 3, or (at your option)
faae18ab
MS
10any later version.
11
f5adbb8d 12GCC is distributed in the hope that it will be useful,
faae18ab
MS
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
e77f031d
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
faae18ab
MS
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
b19b4a78 25 explicit code. */
faae18ab 26
b19b4a78 27#include "config.h"
8d052bc7 28#include "system.h"
4977bab6 29#include "coretypes.h"
faae18ab 30#include "cp-tree.h"
2adfab87 31#include "stringpool.h"
54f92bfb 32#include "toplev.h"
faae18ab 33
86373e7e 34static const char *extract_string (const char **);
848eed92 35static const char *get_base_filename (const char *);
b2a06efa 36static FILE *open_repo_file (const char *);
848eed92 37static char *afgets (FILE *);
b2a06efa 38static FILE *reopen_repo_file_for_write (void);
faae18ab 39
9771b263 40static GTY(()) vec<tree, va_gc> *pending_repo;
e8abc66f 41static char *repo_name;
faae18ab 42
e65e6212 43static const char *old_args, *old_dir, *old_main;
6633d636 44
1f8f4a0b 45static struct obstack temporary_obstack;
4684cd27 46static bool temporary_obstack_initialized_p;
44a8d0b3 47
6633d636
MS
48/* Parse a reasonable subset of shell quoting syntax. */
49
86373e7e
JM
50static const char *
51extract_string (const char **pp)
6633d636 52{
86373e7e 53 const char *p = *pp;
6633d636
MS
54 int backquote = 0;
55 int inside = 0;
56
57 for (;;)
58 {
59 char c = *p;
60 if (c == '\0')
61 break;
62 ++p;
63 if (backquote)
6154f4fd
AN
64 {
65 obstack_1grow (&temporary_obstack, c);
66 backquote = 0;
67 }
6633d636
MS
68 else if (! inside && c == ' ')
69 break;
70 else if (! inside && c == '\\')
71 backquote = 1;
72 else if (c == '\'')
73 inside = !inside;
74 else
75 obstack_1grow (&temporary_obstack, c);
76 }
77
78 obstack_1grow (&temporary_obstack, '\0');
79 *pp = p;
373477bb 80 return (char *) obstack_finish (&temporary_obstack);
6633d636
MS
81}
82
8ce33230 83static const char *
848eed92 84get_base_filename (const char *filename)
b19b4a78 85{
86373e7e 86 const char *p = getenv ("COLLECT_GCC_OPTIONS");
2153915d 87 const char *output = NULL;
b19b4a78
MS
88 int compiling = 0;
89
6633d636
MS
90 while (p && *p)
91 {
86373e7e 92 const char *q = extract_string (&p);
b19b4a78 93
6633d636 94 if (strcmp (q, "-o") == 0)
2153915d
AO
95 {
96 if (flag_compare_debug)
97 /* Just in case aux_base_name was based on a name with two
98 or more '.'s, add an arbitrary extension that will be
99 stripped by the caller. */
100 output = concat (aux_base_name, ".o", NULL);
101 else
102 output = extract_string (&p);
103 }
6633d636
MS
104 else if (strcmp (q, "-c") == 0)
105 compiling = 1;
6154f4fd 106 }
b19b4a78
MS
107
108 if (compiling && output)
109 return output;
110
79ff2c6c
MS
111 if (p && ! compiling)
112 {
d4ee4d25 113 warning (0, "-frepo must be used with -c");
79ff2c6c
MS
114 flag_use_repository = 0;
115 return NULL;
116 }
117
b3e68a79 118 return lbasename (filename);
c8094d83 119}
b19b4a78 120
b2a06efa 121static FILE *
848eed92 122open_repo_file (const char *filename)
faae18ab 123{
926ce8bd 124 const char *p;
d8e178a0 125 const char *s = get_base_filename (filename);
79ff2c6c 126
e8abc66f 127 if (s == NULL)
b2a06efa 128 return NULL;
79ff2c6c 129
b3e68a79 130 p = lbasename (s);
9473c522 131 p = strrchr (p, '.');
e8abc66f
MS
132 if (! p)
133 p = s + strlen (s);
faae18ab 134
0ac1b889 135 repo_name = XNEWVEC (char, p - s + 5);
6d9f628e
GK
136 memcpy (repo_name, s, p - s);
137 memcpy (repo_name + (p - s), ".rpo", 5);
faae18ab 138
b2a06efa 139 return fopen (repo_name, "r");
faae18ab
MS
140}
141
e8abc66f 142static char *
848eed92 143afgets (FILE *stream)
e8abc66f
MS
144{
145 int c;
146 while ((c = getc (stream)) != EOF && c != '\n')
147 obstack_1grow (&temporary_obstack, c);
148 if (obstack_object_size (&temporary_obstack) == 0)
149 return NULL;
150 obstack_1grow (&temporary_obstack, '\0');
373477bb 151 return (char *) obstack_finish (&temporary_obstack);
e8abc66f
MS
152}
153
faae18ab 154void
4684cd27 155init_repo (void)
faae18ab 156{
e8abc66f 157 char *buf;
86373e7e 158 const char *p;
b2a06efa 159 FILE *repo_file;
faae18ab
MS
160
161 if (! flag_use_repository)
162 return;
163
4684cd27
MM
164 /* When a PCH file is loaded, the entire identifier table is
165 replaced, with the result that IDENTIFIER_REPO_CHOSEN is cleared.
166 So, we have to reread the repository file. */
167 lang_post_pch_load = init_repo;
168
169 if (!temporary_obstack_initialized_p)
170 gcc_obstack_init (&temporary_obstack);
9cd64686 171
b2a06efa 172 repo_file = open_repo_file (main_input_filename);
faae18ab
MS
173
174 if (repo_file == 0)
175 return;
176
a703fb38 177 while ((buf = afgets (repo_file)))
faae18ab 178 {
faae18ab
MS
179 switch (buf[0])
180 {
181 case 'A':
6d9f628e 182 old_args = ggc_strdup (buf + 2);
6633d636 183 break;
e8abc66f 184 case 'D':
6d9f628e 185 old_dir = ggc_strdup (buf + 2);
6633d636 186 break;
faae18ab 187 case 'M':
6d9f628e 188 old_main = ggc_strdup (buf + 2);
faae18ab 189 break;
faae18ab 190 case 'O':
4684cd27
MM
191 /* A symbol that we were able to define the last time this
192 file was compiled. */
193 break;
194 case 'C':
195 /* A symbol that the prelinker has requested that we
196 define. */
faae18ab 197 {
e8abc66f 198 tree id = get_identifier (buf + 2);
4684cd27 199 IDENTIFIER_REPO_CHOSEN (id) = 1;
faae18ab
MS
200 }
201 break;
202 default:
8251199e 203 error ("mysterious repository information in %s", repo_name);
faae18ab 204 }
e8abc66f 205 obstack_free (&temporary_obstack, buf);
faae18ab 206 }
4684cd27 207 fclose (repo_file);
403d4851
AO
208
209 if (old_args && !get_random_seed (true)
86373e7e
JM
210 && (p = strstr (old_args, "'-frandom-seed=")))
211 set_random_seed (extract_string (&p) + strlen ("-frandom-seed="));
faae18ab
MS
212}
213
b2a06efa 214static FILE *
848eed92 215reopen_repo_file_for_write (void)
faae18ab 216{
b2a06efa 217 FILE *repo_file = fopen (repo_name, "w");
faae18ab
MS
218
219 if (repo_file == 0)
220 {
d8a07487 221 error ("can%'t create repository information file %qs", repo_name);
faae18ab
MS
222 flag_use_repository = 0;
223 }
b2a06efa
JJ
224
225 return repo_file;
faae18ab
MS
226}
227
228/* Emit any pending repos. */
229
230void
848eed92 231finish_repo (void)
faae18ab 232{
53337422 233 tree val;
6633d636 234 char *dir, *args;
b2a06efa 235 FILE *repo_file;
53337422 236 unsigned ix;
faae18ab 237
2153915d 238 if (!flag_use_repository || flag_compare_debug)
faae18ab
MS
239 return;
240
1da2ed5f 241 if (seen_error ())
b2a06efa 242 return;
faae18ab 243
b2a06efa 244 repo_file = reopen_repo_file_for_write ();
faae18ab
MS
245 if (repo_file == 0)
246 goto out;
247
b19b4a78 248 fprintf (repo_file, "M %s\n", main_input_filename);
4684cd27 249 dir = getpwd ();
6633d636 250 fprintf (repo_file, "D %s\n", dir);
4684cd27 251 args = getenv ("COLLECT_GCC_OPTIONS");
6633d636 252 if (args)
19843834
MM
253 {
254 fprintf (repo_file, "A %s", args);
255 /* If -frandom-seed is not among the ARGS, then add the value
256 that we chose. That will ensure that the names of types from
257 anonymous namespaces will get the same mangling when this
258 file is recompiled. */
259 if (!strstr (args, "'-frandom-seed="))
dde8b360
AK
260 fprintf (repo_file, " '-frandom-seed=" HOST_WIDE_INT_PRINT_HEX_PURE "'",
261 get_random_seed (false));
19843834
MM
262 fprintf (repo_file, "\n");
263 }
b19b4a78 264
9771b263 265 FOR_EACH_VEC_SAFE_ELT_REVERSE (pending_repo, ix, val)
faae18ab 266 {
4684cd27
MM
267 tree name = DECL_ASSEMBLER_NAME (val);
268 char type = IDENTIFIER_REPO_CHOSEN (name) ? 'C' : 'O';
269 fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (name));
faae18ab
MS
270 }
271
272 out:
273 if (repo_file)
274 fclose (repo_file);
275}
e2500fed 276
4684cd27
MM
277/* DECL is a FUNCTION_DECL or VAR_DECL with vague linkage whose
278 definition is available in this translation unit. Returns 0 if
279 this definition should not be emitted in this translation unit
280 because it will be emitted elsewhere. Returns 1 if the repository
281 file indicates that that DECL should be emitted in this translation
282 unit, or 2 if the repository file is not in use. */
283
284int
285repo_emit_p (tree decl)
286{
0ac69b47 287 int ret = 0;
50bc768d 288 gcc_assert (TREE_PUBLIC (decl));
cb6da767 289 gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
e1ef8aa9
JM
290 gcc_assert (!DECL_REALLY_EXTERN (decl)
291 /* A clone might not have its linkage flags updated yet
292 because we call import_export_decl before
293 maybe_clone_body. */
294 || DECL_ABSTRACT_ORIGIN (decl));
4684cd27
MM
295
296 /* When not using the repository, emit everything. */
297 if (!flag_use_repository)
298 return 2;
299
300 /* Only template instantiations are managed by the repository. This
301 is an artificial restriction; the code in the prelinker and here
302 will work fine if all entities with vague linkage are managed by
303 the repository. */
5a6ccc94 304 if (VAR_P (decl))
4684cd27
MM
305 {
306 tree type = NULL_TREE;
307 if (DECL_VTABLE_OR_VTT_P (decl))
308 type = DECL_CONTEXT (decl);
309 else if (DECL_TINFO_P (decl))
310 type = TREE_TYPE (DECL_NAME (decl));
311 if (!DECL_TEMPLATE_INSTANTIATION (decl)
6f4434b3
MM
312 && (!TYPE_LANG_SPECIFIC (type)
313 || !CLASSTYPE_TEMPLATE_INSTANTIATION (type)))
4684cd27 314 return 2;
23372b3f 315 /* Const static data members initialized by constant expressions must
862e1e62 316 be processed where needed so that their definitions are
0ac69b47
JJ
317 available. Still record them into *.rpo files, so if they
318 weren't actually emitted and collect2 requests them, they can
319 be provided. */
aef4a215 320 if (decl_maybe_constant_var_p (decl)
862e1e62 321 && DECL_CLASS_SCOPE_P (decl))
0ac69b47 322 ret = 2;
4684cd27
MM
323 }
324 else if (!DECL_TEMPLATE_INSTANTIATION (decl))
325 return 2;
326
23372b3f
JJ
327 if (DECL_EXPLICIT_INSTANTIATION (decl))
328 return 2;
329
4684cd27
MM
330 /* For constructors and destructors, the repository contains
331 information about the clones -- not the original function --
332 because only the clones are emitted in the object file. */
333 if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
334 || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
335 {
336 int emit_p = 0;
337 tree clone;
338 /* There is no early exit from this loop because we want to
339 ensure that all of the clones are marked as available in this
340 object file. */
341 FOR_EACH_CLONE (clone, decl)
342 /* The only possible results from the recursive call to
343 repo_emit_p are 0 or 1. */
344 if (repo_emit_p (clone))
345 emit_p = 1;
346 return emit_p;
347 }
348
349 /* Keep track of all available entities. */
350 if (!DECL_REPO_AVAILABLE_P (decl))
351 {
352 DECL_REPO_AVAILABLE_P (decl) = 1;
9771b263 353 vec_safe_push (pending_repo, decl);
4684cd27
MM
354 }
355
0ac69b47 356 return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret;
4684cd27
MM
357}
358
359/* Returns true iff the prelinker has explicitly marked CLASS_TYPE for
360 export from this translation unit. */
361
362bool
58f9752a 363repo_export_class_p (const_tree class_type)
4684cd27
MM
364{
365 if (!flag_use_repository)
366 return false;
367 if (!CLASSTYPE_VTABLES (class_type))
368 return false;
369 /* If the virtual table has been assigned to this translation unit,
370 export the class. */
c8094d83 371 return (IDENTIFIER_REPO_CHOSEN
4684cd27
MM
372 (DECL_ASSEMBLER_NAME (CLASSTYPE_VTABLES (class_type))));
373}
374
e2500fed 375#include "gt-cp-repo.h"