00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "rtl.h"
00027 #include "tree.h"
00028 #include "function.h"
00029 #include "cpplib.h"
00030 #include "c-pragma.h"
00031 #include "flags.h"
00032 #include "toplev.h"
00033 #include "ggc.h"
00034 #include "c-common.h"
00035 #include "output.h"
00036 #include "tm_p.h"
00037 #include "vec.h"
00038 #include "target.h"
00039 #include "diagnostic.h"
00040 #include "opts.h"
00041
00042 #define GCC_BAD(gmsgid) \
00043 do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
00044 #define GCC_BAD2(gmsgid, arg) \
00045 do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
00046
00047 typedef struct align_stack GTY(())
00048 {
00049 int alignment;
00050 tree id;
00051 struct align_stack * prev;
00052 } align_stack;
00053
00054 static GTY(()) struct align_stack * alignment_stack;
00055
00056 #ifdef HANDLE_PRAGMA_PACK
00057 static void handle_pragma_pack (cpp_reader *);
00058
00059 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
00060
00061
00062
00063
00064
00065 static int default_alignment;
00066 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
00067 ? &default_alignment \
00068 : &alignment_stack->alignment) = (ALIGN))
00069
00070 static void push_alignment (int, tree);
00071 static void pop_alignment (tree);
00072
00073
00074 static void
00075 push_alignment (int alignment, tree id)
00076 {
00077 align_stack * entry;
00078
00079 entry = GGC_NEW (align_stack);
00080
00081 entry->alignment = alignment;
00082 entry->id = id;
00083 entry->prev = alignment_stack;
00084
00085
00086
00087
00088 if (alignment_stack == NULL)
00089 default_alignment = maximum_field_alignment;
00090
00091 alignment_stack = entry;
00092
00093 maximum_field_alignment = alignment;
00094 }
00095
00096
00097 static void
00098 pop_alignment (tree id)
00099 {
00100 align_stack * entry;
00101
00102 if (alignment_stack == NULL)
00103 GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)");
00104
00105
00106
00107 if (id)
00108 {
00109 for (entry = alignment_stack; entry; entry = entry->prev)
00110 if (entry->id == id)
00111 {
00112 alignment_stack = entry;
00113 break;
00114 }
00115 if (entry == NULL)
00116 warning (OPT_Wpragmas, "\
00117 #pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)"
00118 , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
00119 }
00120
00121 entry = alignment_stack->prev;
00122
00123 maximum_field_alignment = entry ? entry->alignment : default_alignment;
00124
00125 alignment_stack = entry;
00126 }
00127 #else
00128 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
00129 #define push_alignment(ID, N) \
00130 GCC_BAD ("#pragma pack(push[, id], <n>) is not supported on this target")
00131 #define pop_alignment(ID) \
00132 GCC_BAD ("#pragma pack(pop[, id], <n>) is not supported on this target")
00133 #endif
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 static void
00145 handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
00146 {
00147 tree x, id = 0;
00148 int align = -1;
00149 enum cpp_ttype token;
00150 enum { set, push, pop } action;
00151
00152 if (pragma_lex (&x) != CPP_OPEN_PAREN)
00153 GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
00154
00155 token = pragma_lex (&x);
00156 if (token == CPP_CLOSE_PAREN)
00157 {
00158 action = set;
00159 align = initial_max_fld_align;
00160 }
00161 else if (token == CPP_NUMBER)
00162 {
00163 if (TREE_CODE (x) != INTEGER_CST)
00164 GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
00165 align = TREE_INT_CST_LOW (x);
00166 action = set;
00167 if (pragma_lex (&x) != CPP_CLOSE_PAREN)
00168 GCC_BAD ("malformed %<#pragma pack%> - ignored");
00169 }
00170 else if (token == CPP_NAME)
00171 {
00172 #define GCC_BAD_ACTION do { if (action != pop) \
00173 GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
00174 else \
00175 GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
00176 } while (0)
00177
00178 const char *op = IDENTIFIER_POINTER (x);
00179 if (!strcmp (op, "push"))
00180 action = push;
00181 else if (!strcmp (op, "pop"))
00182 action = pop;
00183 else
00184 GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op);
00185
00186 while ((token = pragma_lex (&x)) == CPP_COMMA)
00187 {
00188 token = pragma_lex (&x);
00189 if (token == CPP_NAME && id == 0)
00190 {
00191 id = x;
00192 }
00193 else if (token == CPP_NUMBER && action == push && align == -1)
00194 {
00195 if (TREE_CODE (x) != INTEGER_CST)
00196 GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
00197 align = TREE_INT_CST_LOW (x);
00198 if (align == -1)
00199 action = set;
00200 }
00201 else
00202 GCC_BAD_ACTION;
00203 }
00204
00205 if (token != CPP_CLOSE_PAREN)
00206 GCC_BAD_ACTION;
00207 #undef GCC_BAD_ACTION
00208 }
00209 else
00210 GCC_BAD ("malformed %<#pragma pack%> - ignored");
00211
00212 if (pragma_lex (&x) != CPP_EOF)
00213 warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>");
00214
00215 if (flag_pack_struct)
00216 GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored");
00217
00218 if (action != pop)
00219 switch (align)
00220 {
00221 case 0:
00222 case 1:
00223 case 2:
00224 case 4:
00225 case 8:
00226 case 16:
00227 align *= BITS_PER_UNIT;
00228 break;
00229 case -1:
00230 if (action == push)
00231 {
00232 align = maximum_field_alignment;
00233 break;
00234 }
00235 default:
00236 GCC_BAD2 ("alignment must be a small power of two, not %d", align);
00237 }
00238
00239 switch (action)
00240 {
00241 case set: SET_GLOBAL_ALIGNMENT (align); break;
00242 case push: push_alignment (align, id); break;
00243 case pop: pop_alignment (id); break;
00244 }
00245 }
00246 #endif
00247
00248 static GTY(()) tree pending_weaks;
00249
00250 #ifdef HANDLE_PRAGMA_WEAK
00251 static void apply_pragma_weak (tree, tree);
00252 static void handle_pragma_weak (cpp_reader *);
00253
00254 static void
00255 apply_pragma_weak (tree decl, tree value)
00256 {
00257 if (value)
00258 {
00259 value = build_string (IDENTIFIER_LENGTH (value),
00260 IDENTIFIER_POINTER (value));
00261 decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
00262 build_tree_list (NULL, value)),
00263 0);
00264 }
00265
00266 if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
00267 && !DECL_WEAK (decl)
00268 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
00269 warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use "
00270 "results in unspecified behavior", decl);
00271
00272 declare_weak (decl);
00273 }
00274
00275 void
00276 maybe_apply_pragma_weak (tree decl)
00277 {
00278 tree *p, t, id;
00279
00280
00281
00282
00283 if (!pending_weaks)
00284 return;
00285
00286
00287 if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl))
00288 return;
00289
00290
00291
00292 if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
00293 return;
00294
00295 id = DECL_ASSEMBLER_NAME (decl);
00296
00297 for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
00298 if (id == TREE_PURPOSE (t))
00299 {
00300 apply_pragma_weak (decl, TREE_VALUE (t));
00301 *p = TREE_CHAIN (t);
00302 break;
00303 }
00304 }
00305
00306
00307
00308 void
00309 maybe_apply_pending_pragma_weaks (void)
00310 {
00311 tree *p, t, alias_id, id, decl, *next;
00312
00313 for (p = &pending_weaks; (t = *p) ; p = next)
00314 {
00315 next = &TREE_CHAIN (t);
00316 alias_id = TREE_PURPOSE (t);
00317 id = TREE_VALUE (t);
00318
00319 if (TREE_VALUE (t) == NULL)
00320 continue;
00321
00322 decl = build_decl (FUNCTION_DECL, alias_id, default_function_type);
00323
00324 DECL_ARTIFICIAL (decl) = 1;
00325 TREE_PUBLIC (decl) = 1;
00326 DECL_EXTERNAL (decl) = 1;
00327 DECL_WEAK (decl) = 1;
00328
00329 assemble_alias (decl, id);
00330 }
00331 }
00332
00333
00334 static void
00335 handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
00336 {
00337 tree name, value, x, decl;
00338 enum cpp_ttype t;
00339
00340 value = 0;
00341
00342 if (pragma_lex (&name) != CPP_NAME)
00343 GCC_BAD ("malformed #pragma weak, ignored");
00344 t = pragma_lex (&x);
00345 if (t == CPP_EQ)
00346 {
00347 if (pragma_lex (&value) != CPP_NAME)
00348 GCC_BAD ("malformed #pragma weak, ignored");
00349 t = pragma_lex (&x);
00350 }
00351 if (t != CPP_EOF)
00352 warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
00353
00354 decl = identifier_global_value (name);
00355 if (decl && DECL_P (decl))
00356 {
00357 apply_pragma_weak (decl, value);
00358 if (value)
00359 assemble_alias (decl, value);
00360 }
00361 else
00362 pending_weaks = tree_cons (name, value, pending_weaks);
00363 }
00364 #else
00365 void
00366 maybe_apply_pragma_weak (tree ARG_UNUSED (decl))
00367 {
00368 }
00369
00370 void
00371 maybe_apply_pending_pragma_weaks (void)
00372 {
00373 }
00374 #endif
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 static GTY(()) tree pending_redefine_extname;
00409
00410 static void handle_pragma_redefine_extname (cpp_reader *);
00411
00412
00413 static void
00414 handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
00415 {
00416 tree oldname, newname, decl, x;
00417 enum cpp_ttype t;
00418
00419 if (pragma_lex (&oldname) != CPP_NAME)
00420 GCC_BAD ("malformed #pragma redefine_extname, ignored");
00421 if (pragma_lex (&newname) != CPP_NAME)
00422 GCC_BAD ("malformed #pragma redefine_extname, ignored");
00423 t = pragma_lex (&x);
00424 if (t != CPP_EOF)
00425 warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
00426
00427 if (!flag_mudflap && !targetm.handle_pragma_redefine_extname)
00428 {
00429 if (warn_unknown_pragmas > in_system_header)
00430 warning (OPT_Wunknown_pragmas,
00431 "#pragma redefine_extname not supported on this target");
00432 return;
00433 }
00434
00435 decl = identifier_global_value (oldname);
00436 if (decl
00437 && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
00438 && (TREE_CODE (decl) == FUNCTION_DECL
00439 || TREE_CODE (decl) == VAR_DECL)
00440 && has_c_linkage (decl))
00441 {
00442 if (DECL_ASSEMBLER_NAME_SET_P (decl))
00443 {
00444 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
00445 name = targetm.strip_name_encoding (name);
00446
00447 if (strcmp (name, IDENTIFIER_POINTER (newname)))
00448 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
00449 "conflict with previous rename");
00450 }
00451 else
00452 change_decl_assembler_name (decl, newname);
00453 }
00454 else
00455
00456
00457
00458
00459
00460 add_to_renaming_pragma_list (oldname, newname);
00461 }
00462
00463
00464 void
00465 add_to_renaming_pragma_list (tree oldname, tree newname)
00466 {
00467 tree previous = purpose_member (oldname, pending_redefine_extname);
00468 if (previous)
00469 {
00470 if (TREE_VALUE (previous) != newname)
00471 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
00472 "conflict with previous #pragma redefine_extname");
00473 return;
00474 }
00475
00476 pending_redefine_extname
00477 = tree_cons (oldname, newname, pending_redefine_extname);
00478 }
00479
00480 static GTY(()) tree pragma_extern_prefix;
00481
00482
00483 static void
00484 handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
00485 {
00486 tree prefix, x;
00487 enum cpp_ttype t;
00488
00489 if (pragma_lex (&prefix) != CPP_STRING)
00490 GCC_BAD ("malformed #pragma extern_prefix, ignored");
00491 t = pragma_lex (&x);
00492 if (t != CPP_EOF)
00493 warning (OPT_Wpragmas, "junk at end of %<#pragma extern_prefix%>");
00494
00495 if (targetm.handle_pragma_extern_prefix)
00496
00497 pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
00498 else if (warn_unknown_pragmas > in_system_header)
00499 warning (OPT_Wunknown_pragmas,
00500 "#pragma extern_prefix not supported on this target");
00501 }
00502
00503
00504
00505
00506 tree
00507 maybe_apply_renaming_pragma (tree decl, tree asmname)
00508 {
00509 tree *p, t;
00510
00511
00512
00513 if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
00514 || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
00515 || !has_c_linkage (decl))
00516 return asmname;
00517
00518
00519
00520 if (DECL_ASSEMBLER_NAME_SET_P (decl))
00521 {
00522 const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
00523 oldname = targetm.strip_name_encoding (oldname);
00524
00525 if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
00526 warning (OPT_Wpragmas, "asm declaration ignored due to "
00527 "conflict with previous rename");
00528
00529
00530 for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
00531 if (DECL_NAME (decl) == TREE_PURPOSE (t))
00532 {
00533
00534 if (strcmp (IDENTIFIER_POINTER (TREE_VALUE (t)), oldname))
00535 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
00536 "conflict with previous rename");
00537
00538 *p = TREE_CHAIN (t);
00539 break;
00540 }
00541 return 0;
00542 }
00543
00544
00545 for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
00546 if (DECL_NAME (decl) == TREE_PURPOSE (t))
00547 {
00548 tree newname = TREE_VALUE (t);
00549 *p = TREE_CHAIN (t);
00550
00551
00552
00553 if (asmname)
00554 {
00555 if (strcmp (TREE_STRING_POINTER (asmname),
00556 IDENTIFIER_POINTER (newname)) != 0)
00557 warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
00558 "conflict with __asm__ declaration");
00559 return asmname;
00560 }
00561
00562
00563
00564 return build_string (IDENTIFIER_LENGTH (newname),
00565 IDENTIFIER_POINTER (newname));
00566 }
00567
00568
00569 if (asmname)
00570 return asmname;
00571
00572
00573 if (pragma_extern_prefix)
00574 {
00575 const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
00576 size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
00577
00578 const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
00579 size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
00580
00581 char *newname = (char *) alloca (plen + ilen + 1);
00582
00583 memcpy (newname, prefix, plen);
00584 memcpy (newname + plen, id, ilen + 1);
00585
00586 return build_string (plen + ilen, newname);
00587 }
00588
00589
00590 return 0;
00591 }
00592
00593
00594 #ifdef HANDLE_PRAGMA_VISIBILITY
00595 static void handle_pragma_visibility (cpp_reader *);
00596
00597 typedef enum symbol_visibility visibility;
00598 DEF_VEC_I (visibility);
00599 DEF_VEC_ALLOC_I (visibility, heap);
00600 static VEC (visibility, heap) *visstack;
00601
00602
00603
00604
00605 void
00606 push_visibility (const char *str)
00607 {
00608 VEC_safe_push (visibility, heap, visstack,
00609 default_visibility);
00610 if (!strcmp (str, "default"))
00611 default_visibility = VISIBILITY_DEFAULT;
00612 else if (!strcmp (str, "internal"))
00613 default_visibility = VISIBILITY_INTERNAL;
00614 else if (!strcmp (str, "hidden"))
00615 default_visibility = VISIBILITY_HIDDEN;
00616 else if (!strcmp (str, "protected"))
00617 default_visibility = VISIBILITY_PROTECTED;
00618 else
00619 GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected");
00620 visibility_options.inpragma = 1;
00621 }
00622
00623
00624
00625 void
00626 pop_visibility (void)
00627 {
00628 default_visibility = VEC_pop (visibility, visstack);
00629 visibility_options.inpragma
00630 = VEC_length (visibility, visstack) != 0;
00631 }
00632
00633
00634
00635
00636 static void
00637 handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
00638 {
00639
00640 tree x;
00641 enum cpp_ttype token;
00642 enum { bad, push, pop } action = bad;
00643
00644 token = pragma_lex (&x);
00645 if (token == CPP_NAME)
00646 {
00647 const char *op = IDENTIFIER_POINTER (x);
00648 if (!strcmp (op, "push"))
00649 action = push;
00650 else if (!strcmp (op, "pop"))
00651 action = pop;
00652 }
00653 if (bad == action)
00654 GCC_BAD ("#pragma GCC visibility must be followed by push or pop");
00655 else
00656 {
00657 if (pop == action)
00658 {
00659 if (!VEC_length (visibility, visstack))
00660 GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
00661 else
00662 pop_visibility ();
00663 }
00664 else
00665 {
00666 if (pragma_lex (&x) != CPP_OPEN_PAREN)
00667 GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
00668 token = pragma_lex (&x);
00669 if (token != CPP_NAME)
00670 GCC_BAD ("malformed #pragma GCC visibility push");
00671 else
00672 push_visibility (IDENTIFIER_POINTER (x));
00673 if (pragma_lex (&x) != CPP_CLOSE_PAREN)
00674 GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
00675 }
00676 }
00677 if (pragma_lex (&x) != CPP_EOF)
00678 warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
00679 }
00680
00681 #endif
00682
00683 static void
00684 handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
00685 {
00686 const char *kind_string, *option_string;
00687 unsigned int option_index;
00688 enum cpp_ttype token;
00689 diagnostic_t kind;
00690 tree x;
00691
00692 if (cfun)
00693 {
00694 error ("#pragma GCC diagnostic not allowed inside functions");
00695 return;
00696 }
00697
00698 token = pragma_lex (&x);
00699 if (token != CPP_NAME)
00700 GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
00701 kind_string = IDENTIFIER_POINTER (x);
00702 if (strcmp (kind_string, "error") == 0)
00703 kind = DK_ERROR;
00704 else if (strcmp (kind_string, "warning") == 0)
00705 kind = DK_WARNING;
00706 else if (strcmp (kind_string, "ignored") == 0)
00707 kind = DK_IGNORED;
00708 else
00709 GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>");
00710
00711 token = pragma_lex (&x);
00712 if (token != CPP_STRING)
00713 GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
00714 option_string = TREE_STRING_POINTER (x);
00715 for (option_index = 0; option_index < cl_options_count; option_index++)
00716 if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
00717 {
00718
00719 diagnostic_classify_diagnostic (global_dc, option_index, kind);
00720
00721 if (cl_options[option_index].var_type == CLVC_BOOLEAN
00722 && cl_options[option_index].flag_var
00723 && kind != DK_IGNORED)
00724 *(int *) cl_options[option_index].flag_var = 1;
00725 return;
00726 }
00727 GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
00728 }
00729
00730
00731
00732 DEF_VEC_O (pragma_handler);
00733 DEF_VEC_ALLOC_O (pragma_handler, heap);
00734
00735 static VEC(pragma_handler, heap) *registered_pragmas;
00736
00737
00738
00739
00740 static void
00741 c_register_pragma_1 (const char *space, const char *name,
00742 pragma_handler handler, bool allow_expansion)
00743 {
00744 unsigned id;
00745
00746 VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
00747 id = VEC_length (pragma_handler, registered_pragmas);
00748 id += PRAGMA_FIRST_EXTERNAL - 1;
00749
00750
00751
00752 gcc_assert (id < 64);
00753
00754 cpp_register_deferred_pragma (parse_in, space, name, id,
00755 allow_expansion, false);
00756 }
00757
00758 void
00759 c_register_pragma (const char *space, const char *name, pragma_handler handler)
00760 {
00761 c_register_pragma_1 (space, name, handler, false);
00762 }
00763
00764 void
00765 c_register_pragma_with_expansion (const char *space, const char *name,
00766 pragma_handler handler)
00767 {
00768 c_register_pragma_1 (space, name, handler, true);
00769 }
00770
00771 void
00772 c_invoke_pragma_handler (unsigned int id)
00773 {
00774 pragma_handler handler;
00775
00776 id -= PRAGMA_FIRST_EXTERNAL;
00777 handler = *VEC_index (pragma_handler, registered_pragmas, id);
00778
00779 handler (parse_in);
00780 }
00781
00782
00783 void
00784 init_pragma (void)
00785 {
00786 if (flag_openmp && !flag_preprocess_only)
00787 {
00788 struct omp_pragma_def { const char *name; unsigned int id; };
00789 static const struct omp_pragma_def omp_pragmas[] = {
00790 { "atomic", PRAGMA_OMP_ATOMIC },
00791 { "barrier", PRAGMA_OMP_BARRIER },
00792 { "critical", PRAGMA_OMP_CRITICAL },
00793 { "flush", PRAGMA_OMP_FLUSH },
00794 { "for", PRAGMA_OMP_FOR },
00795 { "master", PRAGMA_OMP_MASTER },
00796 { "ordered", PRAGMA_OMP_ORDERED },
00797 { "parallel", PRAGMA_OMP_PARALLEL },
00798 { "section", PRAGMA_OMP_SECTION },
00799 { "sections", PRAGMA_OMP_SECTIONS },
00800 { "single", PRAGMA_OMP_SINGLE },
00801 { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
00802 };
00803
00804 const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
00805 int i;
00806
00807 for (i = 0; i < n_omp_pragmas; ++i)
00808 cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
00809 omp_pragmas[i].id, true, true);
00810 }
00811
00812 cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
00813 PRAGMA_GCC_PCH_PREPROCESS, false, false);
00814
00815 #ifdef HANDLE_PRAGMA_PACK
00816 #ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
00817 c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
00818 #else
00819 c_register_pragma (0, "pack", handle_pragma_pack);
00820 #endif
00821 #endif
00822 #ifdef HANDLE_PRAGMA_WEAK
00823 c_register_pragma (0, "weak", handle_pragma_weak);
00824 #endif
00825 #ifdef HANDLE_PRAGMA_VISIBILITY
00826 c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
00827 #endif
00828
00829 c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
00830
00831 c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
00832 c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
00833
00834 #ifdef REGISTER_TARGET_PRAGMAS
00835 REGISTER_TARGET_PRAGMAS ();
00836 #endif
00837 }
00838
00839 #include "gt-c-pragma.h"