OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [cp/] [repo.c] - Blame information for rev 797

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.