1204076Spjd/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack. 2204076Spjd Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 3219351Spjd 2006 Free Software Foundation, Inc. 4204076Spjd 5204076SpjdThis file is part of GCC. 6204076Spjd 7204076SpjdGCC is free software; you can redistribute it and/or modify it under 8204076Spjdthe terms of the GNU General Public License as published by the Free 9204076SpjdSoftware Foundation; either version 2, or (at your option) any later 10204076Spjdversion. 11204076Spjd 12204076SpjdGCC is distributed in the hope that it will be useful, but WITHOUT ANY 13204076SpjdWARRANTY; without even the implied warranty of MERCHANTABILITY or 14204076SpjdFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15204076Spjdfor more details. 16204076Spjd 17204076SpjdYou should have received a copy of the GNU General Public License 18204076Spjdalong with GCC; see the file COPYING. If not, write to the Free 19204076SpjdSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20204076Spjd02110-1301, USA. */ 21204076Spjd 22204076Spjd#include "config.h" 23204076Spjd#include "system.h" 24204076Spjd#include "coretypes.h" 25204076Spjd#include "tm.h" 26204076Spjd#include "rtl.h" 27204076Spjd#include "tree.h" 28204076Spjd#include "function.h" 29204076Spjd#include "cpplib.h" 30204076Spjd#include "c-pragma.h" 31204076Spjd#include "flags.h" 32204076Spjd#include "toplev.h" 33204076Spjd#include "ggc.h" 34204076Spjd#include "c-common.h" 35204076Spjd#include "output.h" 36204076Spjd#include "tm_p.h" 37218044Spjd#include "vec.h" 38204076Spjd#include "target.h" 39204076Spjd#include "diagnostic.h" 40204076Spjd#include "opts.h" 41204076Spjd 42204076Spjd#define GCC_BAD(gmsgid) \ 43204076Spjd do { warning (OPT_Wpragmas, gmsgid); return; } while (0) 44204076Spjd#define GCC_BAD2(gmsgid, arg) \ 45204076Spjd do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0) 46204076Spjd 47204076Spjdtypedef struct align_stack GTY(()) 48204076Spjd{ 49219813Spjd int alignment; 50204076Spjd tree id; 51204076Spjd struct align_stack * prev; 52204076Spjd} align_stack; 53204076Spjd 54204076Spjdstatic GTY(()) struct align_stack * alignment_stack; 55204076Spjd 56212038Spjd#ifdef HANDLE_PRAGMA_PACK 57204076Spjdstatic void handle_pragma_pack (cpp_reader *); 58204076Spjd 59204076Spjd#ifdef HANDLE_PRAGMA_PACK_PUSH_POP 60211977Spjd/* If we have a "global" #pragma pack(<n>) in effect when the first 61204076Spjd #pragma pack(push,<n>) is encountered, this stores the value of 62204076Spjd maximum_field_alignment in effect. When the final pop_alignment() 63204076Spjd happens, we restore the value to this, not to a value of 0 for 64210886Spjd maximum_field_alignment. Value is in bits. */ 65204076Spjdstatic int default_alignment; 66204076Spjd#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \ 67204076Spjd ? &default_alignment \ 68204076Spjd : &alignment_stack->alignment) = (ALIGN)) 69233679Strociny 70233679Strocinystatic void push_alignment (int, tree); 71246922Spjdstatic void pop_alignment (tree); 72204076Spjd 73229944Spjd/* Push an alignment value onto the stack. */ 74229944Spjdstatic void 75204076Spjdpush_alignment (int alignment, tree id) 76211977Spjd{ 77213430Spjd align_stack * entry; 78211977Spjd 79204076Spjd entry = GGC_NEW (align_stack); 80204076Spjd 81204076Spjd entry->alignment = alignment; 82204076Spjd entry->id = id; 83204076Spjd entry->prev = alignment_stack; 84204076Spjd 85204076Spjd /* The current value of maximum_field_alignment is not necessarily 86204076Spjd 0 since there may be a #pragma pack(<n>) in effect; remember it 87204076Spjd so that we can restore it after the final #pragma pop(). */ 88204076Spjd if (alignment_stack == NULL) 89204076Spjd default_alignment = maximum_field_alignment; 90204076Spjd 91204076Spjd alignment_stack = entry; 92204076Spjd 93204076Spjd maximum_field_alignment = alignment; 94204076Spjd} 95204076Spjd 96204076Spjd/* Undo a push of an alignment onto the stack. */ 97204076Spjdstatic void 98204076Spjdpop_alignment (tree id) 99204076Spjd{ 100204076Spjd align_stack * entry; 101218041Spjd 102218041Spjd if (alignment_stack == NULL) 103218041Spjd GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)"); 104230457Spjd 105222108Spjd /* If we got an identifier, strip away everything above the target 106218041Spjd entry so that the next step will restore the state just below it. */ 107230457Spjd if (id) 108218041Spjd { 109218041Spjd for (entry = alignment_stack; entry; entry = entry->prev) 110218041Spjd if (entry->id == id) 111218041Spjd { 112218041Spjd alignment_stack = entry; 113218041Spjd break; 114218041Spjd } 115218041Spjd if (entry == NULL) 116218041Spjd warning (OPT_Wpragmas, "\ 117218041Spjd#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)" 118218370Spjd , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id)); 119218370Spjd } 120218370Spjd 121218370Spjd entry = alignment_stack->prev; 122218370Spjd 123218370Spjd maximum_field_alignment = entry ? entry->alignment : default_alignment; 124230457Spjd 125230457Spjd alignment_stack = entry; 126218041Spjd} 127218041Spjd#else /* not HANDLE_PRAGMA_PACK_PUSH_POP */ 128218041Spjd#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN)) 129218041Spjd#define push_alignment(ID, N) \ 130230457Spjd GCC_BAD ("#pragma pack(push[, id], <n>) is not supported on this target") 131230457Spjd#define pop_alignment(ID) \ 132222108Spjd GCC_BAD ("#pragma pack(pop[, id], <n>) is not supported on this target") 133222108Spjd#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ 134230457Spjd 135222108Spjd/* #pragma pack () 136218041Spjd #pragma pack (N) 137218041Spjd 138218041Spjd #pragma pack (push) 139218041Spjd #pragma pack (push, N) 140218041Spjd #pragma pack (push, ID) 141218044Spjd #pragma pack (push, ID, N) 142218044Spjd #pragma pack (pop) 143218044Spjd #pragma pack (pop, ID) */ 144218044Spjdstatic void 145218044Spjdhandle_pragma_pack (cpp_reader * ARG_UNUSED (dummy)) 146218044Spjd{ 147219864Spjd tree x, id = 0; 148218044Spjd int align = -1; 149219864Spjd enum cpp_ttype token; 150218044Spjd enum { set, push, pop } action; 151218044Spjd 152218044Spjd if (pragma_lex (&x) != CPP_OPEN_PAREN) 153219864Spjd GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored"); 154218044Spjd 155219864Spjd token = pragma_lex (&x); 156218044Spjd if (token == CPP_CLOSE_PAREN) 157218044Spjd { 158218044Spjd action = set; 159219864Spjd align = initial_max_fld_align; 160218044Spjd } 161218044Spjd else if (token == CPP_NUMBER) 162218044Spjd { 163218044Spjd if (TREE_CODE (x) != INTEGER_CST) 164218044Spjd GCC_BAD ("invalid constant in %<#pragma pack%> - ignored"); 165218044Spjd align = TREE_INT_CST_LOW (x); 166218044Spjd action = set; 167218044Spjd if (pragma_lex (&x) != CPP_CLOSE_PAREN) 168218044Spjd GCC_BAD ("malformed %<#pragma pack%> - ignored"); 169218044Spjd } 170218044Spjd else if (token == CPP_NAME) 171218044Spjd { 172218044Spjd#define GCC_BAD_ACTION do { if (action != pop) \ 173218044Spjd GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \ 174218044Spjd else \ 175218044Spjd GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \ 176218044Spjd } while (0) 177218044Spjd 178218044Spjd const char *op = IDENTIFIER_POINTER (x); 179218044Spjd if (!strcmp (op, "push")) 180218044Spjd action = push; 181218044Spjd else if (!strcmp (op, "pop")) 182218044Spjd action = pop; 183229945Spjd else 184218373Spjd GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op); 185218373Spjd 186218373Spjd while ((token = pragma_lex (&x)) == CPP_COMMA) 187218044Spjd { 188218373Spjd token = pragma_lex (&x); 189218044Spjd if (token == CPP_NAME && id == 0) 190218044Spjd { 191218044Spjd id = x; 192218044Spjd } 193218044Spjd else if (token == CPP_NUMBER && action == push && align == -1) 194218044Spjd { 195218044Spjd if (TREE_CODE (x) != INTEGER_CST) 196218044Spjd GCC_BAD ("invalid constant in %<#pragma pack%> - ignored"); 197218044Spjd align = TREE_INT_CST_LOW (x); 198218044Spjd if (align == -1) 199218375Spjd action = set; 200218044Spjd } 201218044Spjd else 202218374Spjd GCC_BAD_ACTION; 203218044Spjd } 204218044Spjd 205218044Spjd if (token != CPP_CLOSE_PAREN) 206218044Spjd GCC_BAD_ACTION; 207218375Spjd#undef GCC_BAD_ACTION 208218044Spjd } 209218044Spjd else 210218044Spjd GCC_BAD ("malformed %<#pragma pack%> - ignored"); 211218044Spjd 212218044Spjd if (pragma_lex (&x) != CPP_EOF) 213218044Spjd warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>"); 214218044Spjd 215218375Spjd if (flag_pack_struct) 216218044Spjd GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored"); 217218044Spjd 218218044Spjd if (action != pop) 219218044Spjd switch (align) 220218044Spjd { 221218375Spjd case 0: 222218044Spjd case 1: 223218044Spjd case 2: 224218044Spjd case 4: 225218044Spjd case 8: 226218044Spjd case 16: 227218044Spjd align *= BITS_PER_UNIT; 228218375Spjd break; 229218044Spjd case -1: 230218044Spjd if (action == push) 231218044Spjd { 232218044Spjd align = maximum_field_alignment; 233218044Spjd break; 234218375Spjd } 235218044Spjd default: 236218044Spjd GCC_BAD2 ("alignment must be a small power of two, not %d", align); 237218044Spjd } 238218044Spjd 239219900Spjd switch (action) 240219900Spjd { 241218218Spjd case set: SET_GLOBAL_ALIGNMENT (align); break; 242218375Spjd case push: push_alignment (align, id); break; 243218218Spjd case pop: pop_alignment (id); break; 244218218Spjd } 245218218Spjd} 246218218Spjd#endif /* HANDLE_PRAGMA_PACK */ 247218218Spjd 248218375Spjdstatic GTY(()) tree pending_weaks; 249218218Spjd 250218218Spjd#ifdef HANDLE_PRAGMA_WEAK 251218218Spjdstatic void apply_pragma_weak (tree, tree); 252218218Spjdstatic void handle_pragma_weak (cpp_reader *); 253218044Spjd 254219900Spjdstatic void 255219900Spjdapply_pragma_weak (tree decl, tree value) 256219900Spjd{ 257219900Spjd if (value) 258219900Spjd { 259219900Spjd value = build_string (IDENTIFIER_LENGTH (value), 260219900Spjd IDENTIFIER_POINTER (value)); 261219900Spjd decl_attributes (&decl, build_tree_list (get_identifier ("alias"), 262219900Spjd build_tree_list (NULL, value)), 263218044Spjd 0); 264218044Spjd } 265218375Spjd 266218044Spjd if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl) 267218044Spjd && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */ 268218044Spjd && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 269218044Spjd warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use " 270218044Spjd "results in unspecified behavior", decl); 271218375Spjd 272218044Spjd declare_weak (decl); 273218044Spjd} 274218044Spjd 275218044Spjdvoid 276218044Spjdmaybe_apply_pragma_weak (tree decl) 277218044Spjd{ 278218044Spjd tree *p, t, id; 279218375Spjd 280218044Spjd /* Avoid asking for DECL_ASSEMBLER_NAME when it's not needed. */ 281218044Spjd 282218044Spjd /* No weak symbols pending, take the short-cut. */ 283218044Spjd if (!pending_weaks) 284218044Spjd return; 285218375Spjd /* If it's not visible outside this file, it doesn't matter whether 286218044Spjd it's weak. */ 287218044Spjd if (!DECL_EXTERNAL (decl) && !TREE_PUBLIC (decl)) 288218044Spjd return; 289218044Spjd /* If it's not a function or a variable, it can't be weak. 290218044Spjd FIXME: what kinds of things are visible outside this file but 291218044Spjd aren't functions or variables? Should this be an assert instead? */ 292218375Spjd if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) 293218044Spjd return; 294218044Spjd 295218044Spjd id = DECL_ASSEMBLER_NAME (decl); 296218044Spjd 297218044Spjd for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t)) 298218044Spjd if (id == TREE_PURPOSE (t)) 299218044Spjd { 300218044Spjd apply_pragma_weak (decl, TREE_VALUE (t)); 301218044Spjd *p = TREE_CHAIN (t); 302218044Spjd break; 303218044Spjd } 304218044Spjd} 305218044Spjd 306218044Spjd/* Process all "#pragma weak A = B" directives where we have not seen 307204076Spjd a decl for A. */ 308207372Spjdvoid 309207372Spjdmaybe_apply_pending_pragma_weaks (void) 310207372Spjd{ 311207372Spjd tree *p, t, alias_id, id, decl, *next; 312207372Spjd 313207372Spjd for (p = &pending_weaks; (t = *p) ; p = next) 314207372Spjd { 315207372Spjd next = &TREE_CHAIN (t); 316207372Spjd alias_id = TREE_PURPOSE (t); 317207372Spjd id = TREE_VALUE (t); 318207372Spjd 319207372Spjd if (TREE_VALUE (t) == NULL) 320207372Spjd continue; 321207372Spjd 322207372Spjd decl = build_decl (FUNCTION_DECL, alias_id, default_function_type); 323207372Spjd 324204076Spjd DECL_ARTIFICIAL (decl) = 1; 325204076Spjd TREE_PUBLIC (decl) = 1; 326204076Spjd DECL_EXTERNAL (decl) = 1; 327204076Spjd DECL_WEAK (decl) = 1; 328204076Spjd 329204076Spjd assemble_alias (decl, id); 330204076Spjd } 331204076Spjd} 332204076Spjd 333204076Spjd/* #pragma weak name [= value] */ 334204076Spjdstatic void 335204076Spjdhandle_pragma_weak (cpp_reader * ARG_UNUSED (dummy)) 336204076Spjd{ 337204076Spjd tree name, value, x, decl; 338204076Spjd enum cpp_ttype t; 339211977Spjd 340211977Spjd value = 0; 341204076Spjd 342211977Spjd if (pragma_lex (&name) != CPP_NAME) 343204076Spjd GCC_BAD ("malformed #pragma weak, ignored"); 344204076Spjd t = pragma_lex (&x); 345204076Spjd if (t == CPP_EQ) 346204076Spjd { 347207372Spjd if (pragma_lex (&value) != CPP_NAME) 348213006Spjd GCC_BAD ("malformed #pragma weak, ignored"); 349204076Spjd t = pragma_lex (&x); 350207372Spjd } 351207372Spjd if (t != CPP_EOF) 352207372Spjd warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>"); 353207372Spjd 354207372Spjd decl = identifier_global_value (name); 355207372Spjd if (decl && DECL_P (decl)) 356207372Spjd { 357207348Spjd apply_pragma_weak (decl, value); 358207348Spjd if (value) 359207348Spjd assemble_alias (decl, value); 360207348Spjd } 361207348Spjd else 362207348Spjd pending_weaks = tree_cons (name, value, pending_weaks); 363207348Spjd} 364207348Spjd#else 365204076Spjdvoid 366204076Spjdmaybe_apply_pragma_weak (tree ARG_UNUSED (decl)) 367204076Spjd{ 368204076Spjd} 369204076Spjd 370210886Spjdvoid 371210886Spjdmaybe_apply_pending_pragma_weaks (void) 372210886Spjd{ 373210886Spjd} 374210886Spjd#endif /* HANDLE_PRAGMA_WEAK */ 375218138Spjd 376210886Spjd/* GCC supports two #pragma directives for renaming the external 377210886Spjd symbol associated with a declaration (DECL_ASSEMBLER_NAME), for 378210886Spjd compatibility with the Solaris and Tru64 system headers. GCC also 379210886Spjd has its own notation for this, __asm__("name") annotations. 380210886Spjd 381210886Spjd Corner cases of these features and their interaction: 382210886Spjd 383210886Spjd 1) Both pragmas silently apply only to declarations with external 384210886Spjd linkage (that is, TREE_PUBLIC || DECL_EXTERNAL). Asm labels 385219818Spjd do not have this restriction. 386219818Spjd 387210886Spjd 2) In C++, both #pragmas silently apply only to extern "C" declarations. 388210886Spjd Asm labels do not have this restriction. 389219351Spjd 390219351Spjd 3) If any of the three ways of changing DECL_ASSEMBLER_NAME is 391219354Spjd applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the 392219354Spjd new name is different, a warning issues and the name does not change. 393210886Spjd 394210886Spjd 4) The "source name" for #pragma redefine_extname is the DECL_NAME, 395211886Spjd *not* the DECL_ASSEMBLER_NAME. 396211886Spjd 397225830Spjd 5) If #pragma extern_prefix is in effect and a declaration occurs 398225830Spjd with an __asm__ name, the #pragma extern_prefix is silently 399225830Spjd ignored for that declaration. 400225830Spjd 401225830Spjd 6) If #pragma extern_prefix and #pragma redefine_extname apply to 402225830Spjd the same declaration, whichever triggered first wins, and a warning 403210886Spjd is issued. (We would like to have #pragma redefine_extname always 404210886Spjd win, but it can appear either before or after the declaration, and 405210886Spjd if it appears afterward, we have no way of knowing whether a modified 406210886Spjd DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */ 407210886Spjd 408210886Spjdstatic GTY(()) tree pending_redefine_extname; 409210886Spjd 410210886Spjdstatic void handle_pragma_redefine_extname (cpp_reader *); 411210886Spjd 412218138Spjd/* #pragma redefine_extname oldname newname */ 413218138Spjdstatic void 414218138Spjdhandle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy)) 415210886Spjd{ 416210886Spjd tree oldname, newname, decl, x; 417210886Spjd enum cpp_ttype t; 418210886Spjd 419210886Spjd if (pragma_lex (&oldname) != CPP_NAME) 420210886Spjd GCC_BAD ("malformed #pragma redefine_extname, ignored"); 421219818Spjd if (pragma_lex (&newname) != CPP_NAME) 422219818Spjd GCC_BAD ("malformed #pragma redefine_extname, ignored"); 423210886Spjd t = pragma_lex (&x); 424210886Spjd if (t != CPP_EOF) 425219351Spjd warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>"); 426219351Spjd 427219354Spjd if (!flag_mudflap && !targetm.handle_pragma_redefine_extname) 428219354Spjd { 429210886Spjd if (warn_unknown_pragmas > in_system_header) 430210886Spjd warning (OPT_Wunknown_pragmas, 431211886Spjd "#pragma redefine_extname not supported on this target"); 432211886Spjd return; 433225830Spjd } 434225830Spjd 435210886Spjd decl = identifier_global_value (oldname); 436210886Spjd if (decl 437210886Spjd && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)) 438204076Spjd && (TREE_CODE (decl) == FUNCTION_DECL 439217784Spjd || TREE_CODE (decl) == VAR_DECL) 440217784Spjd && has_c_linkage (decl)) 441217784Spjd { 442217784Spjd if (DECL_ASSEMBLER_NAME_SET_P (decl)) 443217784Spjd { 444218138Spjd const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 445217784Spjd name = targetm.strip_name_encoding (name); 446217784Spjd 447221076Strociny if (strcmp (name, IDENTIFIER_POINTER (newname))) 448217784Spjd warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " 449219818Spjd "conflict with previous rename"); 450217784Spjd } 451219351Spjd else 452219354Spjd change_decl_assembler_name (decl, newname); 453217784Spjd } 454217784Spjd else 455225830Spjd /* We have to add this to the rename list even if there's already 456217784Spjd a global value that doesn't meet the above criteria, because in 457217784Spjd C++ "struct foo {...};" puts "foo" in the current namespace but 458217784Spjd does *not* conflict with a subsequent declaration of a function 459217784Spjd or variable foo. See g++.dg/other/pragma-re-2.C. */ 460217784Spjd add_to_renaming_pragma_list (oldname, newname); 461229945Spjd} 462217784Spjd 463217784Spjd/* This is called from here and from ia64.c. */ 464217784Spjdvoid 465217784Spjdadd_to_renaming_pragma_list (tree oldname, tree newname) 466217784Spjd{ 467217784Spjd tree previous = purpose_member (oldname, pending_redefine_extname); 468217784Spjd if (previous) 469229945Spjd { 470217784Spjd if (TREE_VALUE (previous) != newname) 471217784Spjd warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " 472217784Spjd "conflict with previous #pragma redefine_extname"); 473217784Spjd return; 474217784Spjd } 475217784Spjd 476217784Spjd pending_redefine_extname 477217784Spjd = tree_cons (oldname, newname, pending_redefine_extname); 478217784Spjd} 479217784Spjd 480217784Spjdstatic GTY(()) tree pragma_extern_prefix; 481217784Spjd 482204076Spjd/* #pragma extern_prefix "prefix" */ 483204076Spjdstatic void 484210886Spjdhandle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy)) 485210886Spjd{ 486222108Spjd tree prefix, x; 487226463Spjd enum cpp_ttype t; 488222108Spjd 489210886Spjd if (pragma_lex (&prefix) != CPP_STRING) 490226463Spjd GCC_BAD ("malformed #pragma extern_prefix, ignored"); 491204076Spjd t = pragma_lex (&x); 492210886Spjd if (t != CPP_EOF) 493210886Spjd warning (OPT_Wpragmas, "junk at end of %<#pragma extern_prefix%>"); 494226463Spjd 495226463Spjd if (targetm.handle_pragma_extern_prefix) 496210886Spjd /* Note that the length includes the null terminator. */ 497210886Spjd pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL); 498210886Spjd else if (warn_unknown_pragmas > in_system_header) 499210886Spjd warning (OPT_Wunknown_pragmas, 500210886Spjd "#pragma extern_prefix not supported on this target"); 501210886Spjd} 502210886Spjd 503210886Spjd/* Hook from the front ends to apply the results of one of the preceding 504210886Spjd pragmas that rename variables. */ 505229945Spjd 506210886Spjdtree 507210886Spjdmaybe_apply_renaming_pragma (tree decl, tree asmname) 508210886Spjd{ 509210886Spjd tree *p, t; 510210886Spjd 511210886Spjd /* The renaming pragmas are only applied to declarations with 512210886Spjd external linkage. */ 513222108Spjd if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL) 514210886Spjd || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) 515222108Spjd || !has_c_linkage (decl)) 516222108Spjd return asmname; 517222108Spjd 518222108Spjd /* If the DECL_ASSEMBLER_NAME is already set, it does not change, 519222108Spjd but we may warn about a rename that conflicts. */ 520210886Spjd if (DECL_ASSEMBLER_NAME_SET_P (decl)) 521222108Spjd { 522222108Spjd const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 523222108Spjd oldname = targetm.strip_name_encoding (oldname); 524222108Spjd 525222108Spjd if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname)) 526222108Spjd warning (OPT_Wpragmas, "asm declaration ignored due to " 527222108Spjd "conflict with previous rename"); 528222108Spjd 529222108Spjd /* Take any pending redefine_extname off the list. */ 530222108Spjd for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t)) 531222108Spjd if (DECL_NAME (decl) == TREE_PURPOSE (t)) 532222108Spjd { 533222108Spjd /* Only warn if there is a conflict. */ 534210886Spjd if (strcmp (IDENTIFIER_POINTER (TREE_VALUE (t)), oldname)) 535222108Spjd warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " 536222108Spjd "conflict with previous rename"); 537222108Spjd 538222108Spjd *p = TREE_CHAIN (t); 539226463Spjd break; 540226463Spjd } 541226463Spjd return 0; 542233679Strociny } 543233679Strociny 544226463Spjd /* Find out if we have a pending #pragma redefine_extname. */ 545226463Spjd for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t)) 546226463Spjd if (DECL_NAME (decl) == TREE_PURPOSE (t)) 547226463Spjd { 548226463Spjd tree newname = TREE_VALUE (t); 549226463Spjd *p = TREE_CHAIN (t); 550226463Spjd 551226463Spjd /* If we already have an asmname, #pragma redefine_extname is 552226463Spjd ignored (with a warning if it conflicts). */ 553226463Spjd if (asmname) 554226463Spjd { 555229945Spjd if (strcmp (TREE_STRING_POINTER (asmname), 556226463Spjd IDENTIFIER_POINTER (newname)) != 0) 557226463Spjd warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to " 558226463Spjd "conflict with __asm__ declaration"); 559226463Spjd return asmname; 560226463Spjd } 561226463Spjd 562226463Spjd /* Otherwise we use what we've got; #pragma extern_prefix is 563226463Spjd silently ignored. */ 564226463Spjd return build_string (IDENTIFIER_LENGTH (newname), 565222108Spjd IDENTIFIER_POINTER (newname)); 566222108Spjd } 567222108Spjd 568210886Spjd /* If we've got an asmname, #pragma extern_prefix is silently ignored. */ 569222108Spjd if (asmname) 570210886Spjd return asmname; 571210886Spjd 572210886Spjd /* If #pragma extern_prefix is in effect, apply it. */ 573210886Spjd if (pragma_extern_prefix) 574210886Spjd { 575210886Spjd const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix); 576210886Spjd size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1; 577210886Spjd 578210886Spjd const char *id = IDENTIFIER_POINTER (DECL_NAME (decl)); 579210886Spjd size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl)); 580222108Spjd 581226463Spjd char *newname = (char *) alloca (plen + ilen + 1); 582226463Spjd 583229946Spjd memcpy (newname, prefix, plen); 584229946Spjd memcpy (newname + plen, id, ilen + 1); 585229946Spjd 586229946Spjd return build_string (plen + ilen, newname); 587229946Spjd } 588229946Spjd 589229946Spjd /* Nada. */ 590229946Spjd return 0; 591226463Spjd} 592222108Spjd 593222108Spjd 594222108Spjd#ifdef HANDLE_PRAGMA_VISIBILITY 595222108Spjdstatic void handle_pragma_visibility (cpp_reader *); 596222108Spjd 597222108Spjdtypedef enum symbol_visibility visibility; 598222108SpjdDEF_VEC_I (visibility); 599222108SpjdDEF_VEC_ALLOC_I (visibility, heap); 600222108Spjdstatic VEC (visibility, heap) *visstack; 601222108Spjd 602222108Spjd/* Push the visibility indicated by STR onto the top of the #pragma 603222108Spjd visibility stack. */ 604222108Spjd 605222108Spjdvoid 606210886Spjdpush_visibility (const char *str) 607222108Spjd{ 608210886Spjd VEC_safe_push (visibility, heap, visstack, 609210886Spjd default_visibility); 610210886Spjd if (!strcmp (str, "default")) 611210886Spjd default_visibility = VISIBILITY_DEFAULT; 612210886Spjd else if (!strcmp (str, "internal")) 613210886Spjd default_visibility = VISIBILITY_INTERNAL; 614210886Spjd else if (!strcmp (str, "hidden")) 615210886Spjd default_visibility = VISIBILITY_HIDDEN; 616210886Spjd else if (!strcmp (str, "protected")) 617210886Spjd default_visibility = VISIBILITY_PROTECTED; 618210886Spjd else 619210886Spjd GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected"); 620210886Spjd visibility_options.inpragma = 1; 621210886Spjd} 622210886Spjd 623210886Spjd/* Pop a level of the #pragma visibility stack. */ 624210886Spjd 625210886Spjdvoid 626210886Spjdpop_visibility (void) 627210886Spjd{ 628210886Spjd default_visibility = VEC_pop (visibility, visstack); 629210886Spjd visibility_options.inpragma 630210886Spjd = VEC_length (visibility, visstack) != 0; 631210886Spjd} 632210886Spjd 633210886Spjd/* Sets the default visibility for symbols to something other than that 634210886Spjd specified on the command line. */ 635210886Spjd 636210886Spjdstatic void 637210886Spjdhandle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED) 638210886Spjd{ 639210886Spjd /* Form is #pragma GCC visibility push(hidden)|pop */ 640210886Spjd tree x; 641210886Spjd enum cpp_ttype token; 642210886Spjd enum { bad, push, pop } action = bad; 643210886Spjd 644210886Spjd token = pragma_lex (&x); 645210886Spjd if (token == CPP_NAME) 646210886Spjd { 647210886Spjd const char *op = IDENTIFIER_POINTER (x); 648210886Spjd if (!strcmp (op, "push")) 649210886Spjd action = push; 650210886Spjd else if (!strcmp (op, "pop")) 651210886Spjd action = pop; 652225830Spjd } 653225830Spjd if (bad == action) 654225830Spjd GCC_BAD ("#pragma GCC visibility must be followed by push or pop"); 655210886Spjd else 656225830Spjd { 657225830Spjd if (pop == action) 658225830Spjd { 659210886Spjd if (!VEC_length (visibility, visstack)) 660210886Spjd GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>"); 661210886Spjd else 662210886Spjd pop_visibility (); 663210886Spjd } 664210886Spjd else 665218138Spjd { 666210886Spjd if (pragma_lex (&x) != CPP_OPEN_PAREN) 667210886Spjd GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); 668210886Spjd token = pragma_lex (&x); 669210886Spjd if (token != CPP_NAME) 670210886Spjd GCC_BAD ("malformed #pragma GCC visibility push"); 671210886Spjd else 672210886Spjd push_visibility (IDENTIFIER_POINTER (x)); 673210886Spjd if (pragma_lex (&x) != CPP_CLOSE_PAREN) 674210886Spjd GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); 675210886Spjd } 676210886Spjd } 677210886Spjd if (pragma_lex (&x) != CPP_EOF) 678210886Spjd warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>"); 679210886Spjd} 680210886Spjd 681219818Spjd#endif 682219818Spjd 683210886Spjdstatic void 684219351Spjdhandle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) 685219354Spjd{ 686210886Spjd const char *kind_string, *option_string; 687217729Spjd unsigned int option_index; 688217729Spjd enum cpp_ttype token; 689225830Spjd diagnostic_t kind; 690217784Spjd tree x; 691217784Spjd 692210886Spjd if (cfun) 693210886Spjd { 694210886Spjd error ("#pragma GCC diagnostic not allowed inside functions"); 695210886Spjd return; 696210886Spjd } 697210886Spjd 698210886Spjd token = pragma_lex (&x); 699210886Spjd if (token != CPP_NAME) 700210886Spjd GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>"); 701210886Spjd kind_string = IDENTIFIER_POINTER (x); 702222108Spjd if (strcmp (kind_string, "error") == 0) 703222108Spjd kind = DK_ERROR; 704222108Spjd else if (strcmp (kind_string, "warning") == 0) 705222108Spjd kind = DK_WARNING; 706222108Spjd else if (strcmp (kind_string, "ignored") == 0) 707222108Spjd kind = DK_IGNORED; 708222108Spjd else 709222108Spjd GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>"); 710222108Spjd 711222108Spjd token = pragma_lex (&x); 712222108Spjd if (token != CPP_STRING) 713222108Spjd GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind"); 714222108Spjd option_string = TREE_STRING_POINTER (x); 715222108Spjd for (option_index = 0; option_index < cl_options_count; option_index++) 716210886Spjd if (strcmp (cl_options[option_index].opt_text, option_string) == 0) 717210886Spjd { 718226463Spjd /* This overrides -Werror, for example. */ 719226463Spjd diagnostic_classify_diagnostic (global_dc, option_index, kind); 720210886Spjd /* This makes sure the option is enabled, like -Wfoo would do. */ 721204076Spjd if (cl_options[option_index].var_type == CLVC_BOOLEAN 722204076Spjd && cl_options[option_index].flag_var 723204076Spjd && kind != DK_IGNORED) 724211899Spjd *(int *) cl_options[option_index].flag_var = 1; 725211899Spjd return; 726211899Spjd } 727211899Spjd GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind"); 728211899Spjd} 729211899Spjd 730211899Spjd/* A vector of registered pragma callbacks. */ 731211899Spjd 732211899SpjdDEF_VEC_O (pragma_handler); 733211899SpjdDEF_VEC_ALLOC_O (pragma_handler, heap); 734211899Spjd 735211899Spjdstatic VEC(pragma_handler, heap) *registered_pragmas; 736211899Spjd 737211899Spjd/* Front-end wrappers for pragma registration to avoid dragging 738211899Spjd cpplib.h in almost everywhere. */ 739211899Spjd 740211899Spjdstatic void 741211899Spjdc_register_pragma_1 (const char *space, const char *name, 742211899Spjd pragma_handler handler, bool allow_expansion) 743222108Spjd{ 744204076Spjd unsigned id; 745204076Spjd 746204076Spjd VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler); 747204076Spjd id = VEC_length (pragma_handler, registered_pragmas); 748204076Spjd id += PRAGMA_FIRST_EXTERNAL - 1; 749204076Spjd 750204076Spjd /* The C++ front end allocates 6 bits in cp_token; the C front end 751246922Spjd allocates 7 bits in c_token. At present this is sufficient. */ 752204076Spjd gcc_assert (id < 64); 753204076Spjd 754204076Spjd cpp_register_deferred_pragma (parse_in, space, name, id, 755204076Spjd allow_expansion, false); 756222108Spjd} 757204076Spjd 758204076Spjdvoid 759229945Spjdc_register_pragma (const char *space, const char *name, pragma_handler handler) 760204076Spjd{ 761204076Spjd c_register_pragma_1 (space, name, handler, false); 762204076Spjd} 763204076Spjd 764204076Spjdvoid 765204076Spjdc_register_pragma_with_expansion (const char *space, const char *name, 766209185Spjd pragma_handler handler) 767204076Spjd{ 768207371Spjd c_register_pragma_1 (space, name, handler, true); 769229945Spjd} 770207371Spjd 771207371Spjdvoid 772204076Spjdc_invoke_pragma_handler (unsigned int id) 773204076Spjd{ 774204076Spjd pragma_handler handler; 775204076Spjd 776204076Spjd id -= PRAGMA_FIRST_EXTERNAL; 777204076Spjd handler = *VEC_index (pragma_handler, registered_pragmas, id); 778204076Spjd 779204076Spjd handler (parse_in); 780204076Spjd} 781204076Spjd 782204076Spjd/* Set up front-end pragmas. */ 783204076Spjdvoid 784204076Spjdinit_pragma (void) 785204076Spjd{ 786204076Spjd if (flag_openmp && !flag_preprocess_only) 787204076Spjd { 788229945Spjd struct omp_pragma_def { const char *name; unsigned int id; }; 789204076Spjd static const struct omp_pragma_def omp_pragmas[] = { 790204076Spjd { "atomic", PRAGMA_OMP_ATOMIC }, 791204076Spjd { "barrier", PRAGMA_OMP_BARRIER }, 792204076Spjd { "critical", PRAGMA_OMP_CRITICAL }, 793204076Spjd { "flush", PRAGMA_OMP_FLUSH }, 794204076Spjd { "for", PRAGMA_OMP_FOR }, 795204076Spjd { "master", PRAGMA_OMP_MASTER }, 796204076Spjd { "ordered", PRAGMA_OMP_ORDERED }, 797204076Spjd { "parallel", PRAGMA_OMP_PARALLEL }, 798204076Spjd { "section", PRAGMA_OMP_SECTION }, 799204076Spjd { "sections", PRAGMA_OMP_SECTIONS }, 800204076Spjd { "single", PRAGMA_OMP_SINGLE }, 801246922Spjd { "threadprivate", PRAGMA_OMP_THREADPRIVATE } 802246922Spjd }; 803246922Spjd 804246922Spjd const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas); 805246922Spjd int i; 806246922Spjd 807246922Spjd for (i = 0; i < n_omp_pragmas; ++i) 808246922Spjd cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name, 809204076Spjd omp_pragmas[i].id, true, true); 810204076Spjd } 811229778Suqs 812204076Spjd cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess", 813204076Spjd PRAGMA_GCC_PCH_PREPROCESS, false, false); 814204076Spjd 815204076Spjd#ifdef HANDLE_PRAGMA_PACK 816204076Spjd#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION 817204076Spjd c_register_pragma_with_expansion (0, "pack", handle_pragma_pack); 818204076Spjd#else 819204076Spjd c_register_pragma (0, "pack", handle_pragma_pack); 820204076Spjd#endif 821204076Spjd#endif 822204076Spjd#ifdef HANDLE_PRAGMA_WEAK 823204076Spjd c_register_pragma (0, "weak", handle_pragma_weak); 824204076Spjd#endif 825204076Spjd#ifdef HANDLE_PRAGMA_VISIBILITY 826204076Spjd c_register_pragma ("GCC", "visibility", handle_pragma_visibility); 827204076Spjd#endif 828204076Spjd 829204076Spjd c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic); 830204076Spjd 831204076Spjd c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname); 832204076Spjd c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix); 833204076Spjd 834204076Spjd#ifdef REGISTER_TARGET_PRAGMAS 835204076Spjd REGISTER_TARGET_PRAGMAS (); 836204076Spjd#endif 837204076Spjd} 838204076Spjd 839204076Spjd#include "gt-c-pragma.h" 840204076Spjd