Blob Blame History Raw
2008-01-24  Jakub Jelinek  <jakub@redhat.com>

	* c-ppoutput.c (scan_translation_unit): Handle CPP_PRAGMA
	and CPP_PRAGMA_EOL.
	* c-pragma.c (pragma_ns_name): New typedef.
	(registered_pp_pragmas): New variable.
	(c_pp_lookup_pragma): New function.
	(c_register_pragma_1): If flag_preprocess_only, do nothing
	for non-expanded pragmas, for expanded ones push pragma's
	namespace and name into registered_pp_pragmas vector.
	(c_invoke_pragma_handler): Register OpenMP pragmas even when
	flag_preprocess_only, don't register GCC pch_preprocess
	pragma if flag_preprocess_only.
	* c-opts.c (c_common_init): Call init_pragma even if
	flag_preprocess_only.
	* c-pragma.c (c_pp_lookup_pragma): New prototype.
	* config/darwin.h (DARWIN_REGISTER_TARGET_PRAGMAS): Don't call
	cpp_register_pragma if flag_preprocess_only.

	* gcc.dg/gomp/preprocess-1.c: New test.

--- gcc/c-ppoutput.c.jj	2007-09-07 10:29:37.000000000 +0200
+++ gcc/c-ppoutput.c	2008-01-24 12:27:31.000000000 +0100
@@ -1,6 +1,6 @@
 /* Preprocess only, using cpplib.
-   Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007,
+   2008 Free Software Foundation, Inc.
    Written by Per Bothner, 1994-95.
 
    This program is free software; you can redistribute it and/or modify it
@@ -177,7 +177,24 @@ scan_translation_unit (cpp_reader *pfile
       avoid_paste = false;
       print.source = NULL;
       print.prev = token;
-      cpp_output_token (token, print.outf);
+      if (token->type == CPP_PRAGMA)
+	{
+	  const char *space;
+	  const char *name;
+
+	  maybe_print_line (token->src_loc);
+	  fputs ("#pragma ", print.outf);
+	  c_pp_lookup_pragma (token->val.pragma, &space, &name);
+	  if (space)
+	    fprintf (print.outf, "%s %s", space, name);
+	  else
+	    fprintf (print.outf, "%s", name);
+	  print.printed = 1;
+	}
+      else if (token->type == CPP_PRAGMA_EOL)
+	maybe_print_line (token->src_loc);
+      else
+	cpp_output_token (token, print.outf);
 
       if (token->type == CPP_COMMENT)
 	account_for_newlines (token->val.str.text, token->val.str.len);
--- gcc/c-pragma.c.jj	2007-08-13 15:11:18.000000000 +0200
+++ gcc/c-pragma.c	2008-01-24 11:58:18.000000000 +0100
@@ -1,6 +1,6 @@
 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
    Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007 Free Software Foundation, Inc.
+   2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -871,6 +871,59 @@ DEF_VEC_ALLOC_O (pragma_handler, heap);
 
 static VEC(pragma_handler, heap) *registered_pragmas;
 
+typedef struct
+{
+  const char *space;
+  const char *name;
+} pragma_ns_name;
+
+DEF_VEC_O (pragma_ns_name);
+DEF_VEC_ALLOC_O (pragma_ns_name, heap);
+
+static VEC(pragma_ns_name, heap) *registered_pp_pragmas;
+
+void
+c_pp_lookup_pragma (unsigned int id, const char **space, const char **name)
+{
+  *space = NULL;
+  *name = NULL;
+  switch (id)
+    {
+    case PRAGMA_OMP_ATOMIC: *name = "atomic"; break;
+    case PRAGMA_OMP_BARRIER: *name = "barrier"; break;
+    case PRAGMA_OMP_CRITICAL: *name = "critical"; break;
+    case PRAGMA_OMP_FLUSH: *name = "flush"; break;
+    case PRAGMA_OMP_FOR: *name = "for"; break;
+    case PRAGMA_OMP_MASTER: *name = "master"; break;
+    case PRAGMA_OMP_ORDERED: *name = "ordered"; break;
+    case PRAGMA_OMP_PARALLEL: *name = "parallel"; break;
+    case PRAGMA_OMP_SECTION: *name = "section"; break;
+    case PRAGMA_OMP_SECTIONS: *name = "sections"; break;
+    case PRAGMA_OMP_SINGLE: *name = "single"; break;
+    case PRAGMA_OMP_THREADPRIVATE: *name = "threadprivate"; break;
+    default: break;
+    }
+
+  if (*name)
+    {
+      *space = "omp";
+      return;
+    }
+
+  if (id >= PRAGMA_FIRST_EXTERNAL
+      && (id < PRAGMA_FIRST_EXTERNAL
+	  + VEC_length (pragma_ns_name, registered_pp_pragmas)))
+    {
+      *space = VEC_index (pragma_ns_name, registered_pp_pragmas,
+			  id - PRAGMA_FIRST_EXTERNAL)->space;
+      *name = VEC_index (pragma_ns_name, registered_pp_pragmas,
+			 id - PRAGMA_FIRST_EXTERNAL)->name;
+      return;
+    }
+
+  gcc_unreachable ();
+}
+
 /* Front-end wrappers for pragma registration to avoid dragging
    cpplib.h in almost everywhere.  */
 
@@ -880,13 +933,29 @@ c_register_pragma_1 (const char *space, 
 {
   unsigned id;
 
-  VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
-  id = VEC_length (pragma_handler, registered_pragmas);
-  id += PRAGMA_FIRST_EXTERNAL - 1;
-
-  /* The C++ front end allocates 6 bits in cp_token; the C front end
-     allocates 7 bits in c_token.  At present this is sufficient.  */
-  gcc_assert (id < 64);
+  if (flag_preprocess_only)
+    {
+      pragma_ns_name ns_name;
+
+      if (!allow_expansion)
+	return;
+
+      ns_name.space = space;
+      ns_name.name = name;
+      VEC_safe_push (pragma_ns_name, heap, registered_pp_pragmas, &ns_name);
+      id = VEC_length (pragma_ns_name, registered_pp_pragmas);
+      id += PRAGMA_FIRST_EXTERNAL - 1;
+    }
+  else
+    {
+      VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
+      id = VEC_length (pragma_handler, registered_pragmas);
+      id += PRAGMA_FIRST_EXTERNAL - 1;
+
+      /* The C++ front end allocates 6 bits in cp_token; the C front end
+	 allocates 7 bits in c_token.  At present this is sufficient.  */
+      gcc_assert (id < 64);
+    }
 
   cpp_register_deferred_pragma (parse_in, space, name, id,
 				allow_expansion, false);
@@ -920,7 +989,7 @@ c_invoke_pragma_handler (unsigned int id
 void
 init_pragma (void)
 {
-  if (flag_openmp && !flag_preprocess_only)
+  if (flag_openmp)
     {
       struct omp_pragma_def { const char *name; unsigned int id; };
       static const struct omp_pragma_def omp_pragmas[] = {
@@ -946,8 +1015,9 @@ init_pragma (void)
 				      omp_pragmas[i].id, true, true);
     }
 
-  cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
-				PRAGMA_GCC_PCH_PREPROCESS, false, false);
+  if (!flag_preprocess_only)
+    cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
+				  PRAGMA_GCC_PCH_PREPROCESS, false, false);
 
 #ifdef HANDLE_PRAGMA_PACK
 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
--- gcc/c-opts.c.jj	2008-01-22 15:12:11.000000000 +0100
+++ gcc/c-opts.c	2008-01-24 11:50:39.000000000 +0100
@@ -1,5 +1,5 @@
 /* C/ObjC/C++ command line option handling.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
@@ -1238,6 +1238,9 @@ c_common_init (void)
   if (version_flag)
     c_common_print_pch_checksum (stderr);
 
+  /* Has to wait until now so that cpplib has its hash table.  */
+  init_pragma ();
+
   if (flag_preprocess_only)
     {
       finish_options ();
@@ -1245,9 +1248,6 @@ c_common_init (void)
       return false;
     }
 
-  /* Has to wait until now so that cpplib has its hash table.  */
-  init_pragma ();
-
   return true;
 }
 
--- gcc/c-pragma.h.jj	2007-09-14 11:54:36.000000000 +0200
+++ gcc/c-pragma.h	2008-01-24 11:50:28.000000000 +0100
@@ -1,6 +1,6 @@
 /* Pragma related interfaces.
    Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2007  Free Software Foundation, Inc.
+   2007, 2008  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -124,4 +124,6 @@ extern enum cpp_ttype pragma_lex (tree *
 extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *,
 					int);
 
+extern void c_pp_lookup_pragma (unsigned int, const char **, const char **);
+
 #endif /* GCC_C_PRAGMA_H */
--- gcc/config/darwin.h.jj	2007-10-11 10:54:22.000000000 +0200
+++ gcc/config/darwin.h	2008-01-24 11:48:48.000000000 +0100
@@ -892,8 +892,9 @@ enum machopic_addr_class {
 
 #define DARWIN_REGISTER_TARGET_PRAGMAS()			\
   do {								\
-    cpp_register_pragma (parse_in, NULL, "mark",		\
-			 darwin_pragma_ignore, false);		\
+    if (!flag_preprocess_only)					\
+      cpp_register_pragma (parse_in, NULL, "mark",		\
+			   darwin_pragma_ignore, false);	\
     c_register_pragma (0, "options", darwin_pragma_options);	\
     c_register_pragma (0, "segment", darwin_pragma_ignore);	\
     c_register_pragma (0, "unused", darwin_pragma_unused);	\
--- gcc/testsuite/gcc.dg/gomp/preprocess-1.c.jj	2008-01-24 12:32:02.000000000 +0100
+++ gcc/testsuite/gcc.dg/gomp/preprocess-1.c	2008-01-24 12:35:40.000000000 +0100
@@ -0,0 +1,16 @@
+/* { dg-do preprocess } */
+
+void foo (void)
+{
+  int i1, j1, k1;
+#define p parallel
+#define P(x) private (x##1)
+#define S(x) shared (x##1)
+#define F(x) firstprivate (x##1)
+#pragma omp p P(i) \
+  S(j) \
+  F(k)
+  ;
+}
+
+/* { dg-final { scan-file preprocess-1.i "(^|\n)#pragma omp parallel private \\(i1\\) shared \\(j1\\) firstprivate \\(k1\\)($|\n)" } } */