2008-01-24 Jakub Jelinek * 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)" } } */