00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "tree.h"
00031 #include "cp-tree.h"
00032 #include "input.h"
00033 #include "obstack.h"
00034 #include "toplev.h"
00035 #include "ggc.h"
00036 #include "diagnostic.h"
00037
00038 static tree repo_get_id PARAMS ((tree));
00039 static char *extract_string PARAMS ((char **));
00040 static const char *get_base_filename PARAMS ((const char *));
00041 static void open_repo_file PARAMS ((const char *));
00042 static char *afgets PARAMS ((FILE *));
00043 static void reopen_repo_file_for_write PARAMS ((void));
00044
00045 static GTY(()) tree pending_repo;
00046 static GTY(()) tree original_repo;
00047 static char *repo_name;
00048 static FILE *repo_file;
00049
00050 static const char *old_args, *old_dir, *old_main;
00051
00052 static struct obstack temporary_obstack;
00053
00054 #define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
00055 #define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
00056
00057 #if 0
00058
00059
00060 void
00061 repo_compile_flags (argc, argv)
00062 int argc;
00063 char **argv;
00064 {
00065 }
00066
00067
00068
00069
00070
00071 void
00072 repo_template_declared (t)
00073 tree t;
00074 {}
00075
00076
00077
00078
00079 void
00080 repo_template_defined (t)
00081 tree t;
00082 {}
00083
00084
00085
00086
00087 void
00088 repo_class_defined (t)
00089 tree t;
00090 {}
00091 #endif
00092
00093 static tree
00094 repo_get_id (t)
00095 tree t;
00096 {
00097 if (TYPE_P (t))
00098 {
00099 tree vtable;
00100
00101
00102
00103
00104 if (!COMPLETE_TYPE_P (t) || TYPE_BEING_DEFINED (t))
00105 abort ();
00106
00107 vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (t));
00108
00109 t = vtable;
00110 if (t == NULL_TREE)
00111 return t;
00112 }
00113 return DECL_ASSEMBLER_NAME (t);
00114 }
00115
00116
00117
00118
00119 void
00120 repo_template_used (t)
00121 tree t;
00122 {
00123 tree id;
00124
00125 if (! flag_use_repository)
00126 return;
00127
00128 id = repo_get_id (t);
00129 if (id == NULL_TREE)
00130 return;
00131
00132 if (TYPE_P (t))
00133 {
00134 if (IDENTIFIER_REPO_CHOSEN (id))
00135 mark_class_instantiated (t, 0);
00136 }
00137 else if (DECL_P (t))
00138 {
00139 if (IDENTIFIER_REPO_CHOSEN (id))
00140
00141
00142
00143
00144 mark_decl_instantiated (DECL_CLONED_FUNCTION_P (t)
00145 ? DECL_CLONED_FUNCTION (t) : t,
00146 0);
00147 }
00148 else
00149 abort ();
00150
00151 if (! IDENTIFIER_REPO_USED (id))
00152 {
00153 IDENTIFIER_REPO_USED (id) = 1;
00154 pending_repo = tree_cons (NULL_TREE, id, pending_repo);
00155 }
00156 }
00157
00158 #if 0
00159
00160
00161 static void
00162 repo_vtable_used (t)
00163 tree t;
00164 {
00165 if (! flag_use_repository)
00166 return;
00167
00168 pending_repo = tree_cons (NULL_TREE, t, pending_repo);
00169 }
00170
00171
00172
00173
00174 void
00175 repo_inline_used (fn)
00176 tree fn;
00177 {
00178 if (! flag_use_repository)
00179 return;
00180
00181
00182 if (DECL_FUNCTION_MEMBER_P (fn)
00183 && TYPE_POLYMORPHIC_P (DECL_CONTEXT (fn)))
00184 {
00185 repo_vtable_used (DECL_CONTEXT (fn));
00186 return;
00187 }
00188
00189 pending_repo = tree_cons (NULL_TREE, fn, pending_repo);
00190 }
00191
00192
00193
00194
00195 void
00196 repo_tinfo_used (ti)
00197 tree ti;
00198 {
00199 }
00200 #endif
00201
00202 void
00203 repo_template_instantiated (t, extern_p)
00204 tree t;
00205 int extern_p;
00206 {
00207 if (! extern_p)
00208 {
00209 tree id = repo_get_id (t);
00210 if (id)
00211 IDENTIFIER_REPO_CHOSEN (id) = 1;
00212 }
00213 }
00214
00215
00216
00217 static char *
00218 extract_string (pp)
00219 char **pp;
00220 {
00221 char *p = *pp;
00222 int backquote = 0;
00223 int inside = 0;
00224
00225 for (;;)
00226 {
00227 char c = *p;
00228 if (c == '\0')
00229 break;
00230 ++p;
00231 if (backquote)
00232 obstack_1grow (&temporary_obstack, c);
00233 else if (! inside && c == ' ')
00234 break;
00235 else if (! inside && c == '\\')
00236 backquote = 1;
00237 else if (c == '\'')
00238 inside = !inside;
00239 else
00240 obstack_1grow (&temporary_obstack, c);
00241 }
00242
00243 obstack_1grow (&temporary_obstack, '\0');
00244 *pp = p;
00245 return obstack_finish (&temporary_obstack);
00246 }
00247
00248 const char *
00249 get_base_filename (filename)
00250 const char *filename;
00251 {
00252 char *p = getenv ("COLLECT_GCC_OPTIONS");
00253 char *output = NULL;
00254 int compiling = 0;
00255
00256 while (p && *p)
00257 {
00258 char *q = extract_string (&p);
00259
00260 if (strcmp (q, "-o") == 0)
00261 output = extract_string (&p);
00262 else if (strcmp (q, "-c") == 0)
00263 compiling = 1;
00264 }
00265
00266 if (compiling && output)
00267 return output;
00268
00269 if (p && ! compiling)
00270 {
00271 warning ("-frepo must be used with -c");
00272 flag_use_repository = 0;
00273 return NULL;
00274 }
00275
00276 return lbasename (filename);
00277 }
00278
00279 static void
00280 open_repo_file (filename)
00281 const char *filename;
00282 {
00283 register const char *p;
00284 const char *s = get_base_filename (filename);
00285
00286 if (s == NULL)
00287 return;
00288
00289 p = lbasename (s);
00290 p = strrchr (p, '.');
00291 if (! p)
00292 p = s + strlen (s);
00293
00294 repo_name = xmalloc (p - s + 5);
00295 memcpy (repo_name, s, p - s);
00296 memcpy (repo_name + (p - s), ".rpo", 5);
00297
00298 repo_file = fopen (repo_name, "r");
00299 }
00300
00301 static char *
00302 afgets (stream)
00303 FILE *stream;
00304 {
00305 int c;
00306 while ((c = getc (stream)) != EOF && c != '\n')
00307 obstack_1grow (&temporary_obstack, c);
00308 if (obstack_object_size (&temporary_obstack) == 0)
00309 return NULL;
00310 obstack_1grow (&temporary_obstack, '\0');
00311 return obstack_finish (&temporary_obstack);
00312 }
00313
00314 void
00315 init_repo (filename)
00316 const char *filename;
00317 {
00318 char *buf;
00319
00320 if (! flag_use_repository)
00321 return;
00322
00323 gcc_obstack_init (&temporary_obstack);
00324
00325 open_repo_file (filename);
00326
00327 if (repo_file == 0)
00328 return;
00329
00330 while ((buf = afgets (repo_file)))
00331 {
00332 switch (buf[0])
00333 {
00334 case 'A':
00335 old_args = ggc_strdup (buf + 2);
00336 break;
00337 case 'D':
00338 old_dir = ggc_strdup (buf + 2);
00339 break;
00340 case 'M':
00341 old_main = ggc_strdup (buf + 2);
00342 break;
00343 case 'C':
00344 case 'O':
00345 {
00346 tree id = get_identifier (buf + 2);
00347 tree orig;
00348
00349 if (buf[0] == 'C')
00350 {
00351 IDENTIFIER_REPO_CHOSEN (id) = 1;
00352 orig = integer_one_node;
00353 }
00354 else
00355 orig = NULL_TREE;
00356
00357 original_repo = tree_cons (orig, id, original_repo);
00358 }
00359 break;
00360 default:
00361 error ("mysterious repository information in %s", repo_name);
00362 }
00363 obstack_free (&temporary_obstack, buf);
00364 }
00365 }
00366
00367 static void
00368 reopen_repo_file_for_write ()
00369 {
00370 if (repo_file)
00371 fclose (repo_file);
00372 repo_file = fopen (repo_name, "w");
00373
00374 if (repo_file == 0)
00375 {
00376 error ("can't create repository information file `%s'", repo_name);
00377 flag_use_repository = 0;
00378 }
00379 }
00380
00381
00382
00383 void
00384 finish_repo ()
00385 {
00386 tree t;
00387 int repo_changed = 0;
00388 char *dir, *args;
00389
00390 if (! flag_use_repository)
00391 return;
00392
00393
00394
00395
00396
00397
00398 for (t = original_repo; t; t = TREE_CHAIN (t))
00399 {
00400 if (! IDENTIFIER_REPO_USED (TREE_VALUE (t))
00401 || (! TREE_PURPOSE (t) && IDENTIFIER_REPO_CHOSEN (TREE_VALUE (t))))
00402 {
00403 repo_changed = 1;
00404 break;
00405 }
00406 IDENTIFIER_REPO_USED (TREE_VALUE (t)) = 0;
00407 }
00408
00409
00410
00411 if (! repo_changed)
00412 for (t = pending_repo; t; t = TREE_CHAIN (t))
00413 {
00414 if (IDENTIFIER_REPO_USED (TREE_VALUE (t)))
00415 {
00416 repo_changed = 1;
00417 break;
00418 }
00419 }
00420
00421 dir = getpwd ();
00422 args = getenv ("COLLECT_GCC_OPTIONS");
00423
00424 if (! repo_changed && pending_repo)
00425 if (strcmp (old_main, main_input_filename) != 0
00426 || strcmp (old_dir, dir) != 0
00427 || (args == NULL) != (old_args == NULL)
00428 || (args && strcmp (old_args, args) != 0))
00429 repo_changed = 1;
00430
00431 if (! repo_changed || errorcount || sorrycount)
00432 goto out;
00433
00434 reopen_repo_file_for_write ();
00435
00436 if (repo_file == 0)
00437 goto out;
00438
00439 fprintf (repo_file, "M %s\n", main_input_filename);
00440 fprintf (repo_file, "D %s\n", dir);
00441 if (args)
00442 fprintf (repo_file, "A %s\n", args);
00443
00444 for (t = pending_repo; t; t = TREE_CHAIN (t))
00445 {
00446 tree val = TREE_VALUE (t);
00447 char type = IDENTIFIER_REPO_CHOSEN (val) ? 'C' : 'O';
00448
00449 fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (val));
00450 }
00451
00452 out:
00453 if (repo_file)
00454 fclose (repo_file);
00455 }
00456
00457 #include "gt-cp-repo.h"