OSDN Git Service

cp/
[pf3gnuchains/gcc-fork.git] / gcc / cp / repo.c
index 227c1ea..aa97078 100644 (file)
@@ -1,6 +1,6 @@
 /* Code to maintain a C++ template repository.
    Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007  Free Software Foundation, Inc.
+   2006, 2007, 2008  Free Software Foundation, Inc.
    Contributed by Jason Merrill (jason@cygnus.com)
 
 This file is part of GCC.
@@ -37,7 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic.h"
 #include "flags.h"
 
-static char *extract_string (char **);
+static const char *extract_string (const char **);
 static const char *get_base_filename (const char *);
 static FILE *open_repo_file (const char *);
 static char *afgets (FILE *);
@@ -53,10 +53,10 @@ static bool temporary_obstack_initialized_p;
 
 /* Parse a reasonable subset of shell quoting syntax.  */
 
-static char *
-extract_string (char **pp)
+static const char *
+extract_string (const char **pp)
 {
-  char *p = *pp;
+  const char *p = *pp;
   int backquote = 0;
   int inside = 0;
 
@@ -89,16 +89,24 @@ extract_string (char **pp)
 static const char *
 get_base_filename (const char *filename)
 {
-  char *p = getenv ("COLLECT_GCC_OPTIONS");
-  char *output = NULL;
+  const char *p = getenv ("COLLECT_GCC_OPTIONS");
+  const char *output = NULL;
   int compiling = 0;
 
   while (p && *p)
     {
-      char *q = extract_string (&p);
+      const char *q = extract_string (&p);
 
       if (strcmp (q, "-o") == 0)
-       output = extract_string (&p);
+       {
+         if (flag_compare_debug)
+           /* Just in case aux_base_name was based on a name with two
+              or more '.'s, add an arbitrary extension that will be
+              stripped by the caller.  */
+           output = concat (aux_base_name, ".o", NULL);
+         else
+           output = extract_string (&p);
+       }
       else if (strcmp (q, "-c") == 0)
        compiling = 1;
     }
@@ -153,6 +161,7 @@ void
 init_repo (void)
 {
   char *buf;
+  const char *p;
   FILE *repo_file;
 
   if (! flag_use_repository)
@@ -204,8 +213,8 @@ init_repo (void)
   fclose (repo_file);
 
   if (old_args && !get_random_seed (true)
-      && (buf = strstr (old_args, "'-frandom-seed=")))
-    set_random_seed (extract_string (&buf) + strlen ("-frandom-seed="));
+      && (p = strstr (old_args, "'-frandom-seed=")))
+    set_random_seed (extract_string (&p) + strlen ("-frandom-seed="));
 }
 
 static FILE *
@@ -231,7 +240,7 @@ finish_repo (void)
   char *dir, *args;
   FILE *repo_file;
 
-  if (!flag_use_repository)
+  if (!flag_use_repository || flag_compare_debug)
     return;
 
   if (errorcount || sorrycount)
@@ -280,6 +289,7 @@ finish_repo (void)
 int
 repo_emit_p (tree decl)
 {
+  int ret = 0;
   gcc_assert (TREE_PUBLIC (decl));
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
              || TREE_CODE (decl) == VAR_DECL);
@@ -304,16 +314,21 @@ repo_emit_p (tree decl)
          && (!TYPE_LANG_SPECIFIC (type)
              || !CLASSTYPE_TEMPLATE_INSTANTIATION (type)))
        return 2;
-      /* Static data members initialized by constant expressions must
+      /* Const static data members initialized by constant expressions must
         be processed where needed so that their definitions are
-        available.  */
-      if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
+        available.  Still record them into *.rpo files, so if they
+        weren't actually emitted and collect2 requests them, they can
+        be provided.  */
+      if (DECL_INTEGRAL_CONSTANT_VAR_P (decl)
          && DECL_CLASS_SCOPE_P (decl))
-       return 2;
+       ret = 2;
     }
   else if (!DECL_TEMPLATE_INSTANTIATION (decl))
     return 2;
 
+  if (DECL_EXPLICIT_INSTANTIATION (decl))
+    return 2;
+
   /* For constructors and destructors, the repository contains
      information about the clones -- not the original function --
      because only the clones are emitted in the object file.  */
@@ -340,14 +355,14 @@ repo_emit_p (tree decl)
       pending_repo = tree_cons (NULL_TREE, decl, pending_repo);
     }
 
-  return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl));
+  return IDENTIFIER_REPO_CHOSEN (DECL_ASSEMBLER_NAME (decl)) ? 1 : ret;
 }
 
 /* Returns true iff the prelinker has explicitly marked CLASS_TYPE for
    export from this translation unit.  */
 
 bool
-repo_export_class_p (tree class_type)
+repo_export_class_p (const_tree class_type)
 {
   if (!flag_use_repository)
     return false;