diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-30 21:12:53 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-30 21:12:53 +0000 |
commit | 3fa3949da38e56a88feef5467a58ea52c3fea3be (patch) | |
tree | f8ad58ad599c110a4cb386319a9c1e0f7f184b64 /gcc/c-pragma.c | |
parent | 6e9e3dbec65a8f70bf8c2db0047ee92349a14cd2 (diff) | |
download | gcc-3fa3949da38e56a88feef5467a58ea52c3fea3be.tar.gz |
libcpp/
* directives.c (lex_macro_node_from_str): New.
(cpp_push_definition, cpp_pop_definition): New.
* include/cpplib.h (cpp_push_definition, cpp_pop_definition): Declare.
gcc/
* c-pragma.c (struct def_pragma_macro_value): New.
(struct def_pragma_macro): New.
(pushed_macro_table): New.
(dpm_hash, dpm_eq): New.
(handle_pragma_push_macro, handle_pragma_pop_macro): New.
(init_pragma): Install them.
* doc/tm.texi (HANDLE_PRAGMA_PUSH_POP_MACRO): New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123370 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-pragma.c')
-rw-r--r-- | gcc/c-pragma.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c index b2712acc937..65da61838f7 100644 --- a/gcc/c-pragma.c +++ b/gcc/c-pragma.c @@ -245,6 +245,144 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy)) } #endif /* HANDLE_PRAGMA_PACK */ +struct def_pragma_macro_value GTY(()) +{ + struct def_pragma_macro_value *prev; + cpp_macro *value; +}; + +struct def_pragma_macro GTY(()) +{ + hashval_t hash; + const char *name; + struct def_pragma_macro_value value; +}; + +static GTY((param_is (struct def_pragma_macro))) htab_t pushed_macro_table; + +#ifdef HANDLE_PRAGMA_PUSH_POP_MACRO +/* Hash table control functions for pushed_macro_table. */ +static hashval_t +dpm_hash (const void *p) +{ + return ((const struct def_pragma_macro *)p)->hash; +} + +static int +dpm_eq (const void *pa, const void *pb) +{ + const struct def_pragma_macro *a = pa, *b = pb; + return a->hash == b->hash && strcmp (a->name, b->name) == 0; +} + +/* #pragma push_macro("MACRO_NAME") + #pragma pop_macro("MACRO_NAME") */ + +static void +handle_pragma_push_macro (cpp_reader *reader) +{ + tree x, id = 0; + enum cpp_ttype token; + struct def_pragma_macro dummy, *c; + const char *macroname; + void **slot; + + if (pragma_lex (&x) != CPP_OPEN_PAREN) + GCC_BAD ("missing %<(%> after %<#pragma push_macro%> - ignored"); + + token = pragma_lex (&id); + + /* Silently ignore */ + if (token == CPP_CLOSE_PAREN) + return; + if (token != CPP_STRING) + GCC_BAD ("invalid constant in %<#pragma push_macro%> - ignored"); + + if (pragma_lex (&x) != CPP_CLOSE_PAREN) + GCC_BAD ("missing %<)%> after %<#pragma push_macro%> - ignored"); + + if (pragma_lex (&x) != CPP_EOF) + warning (OPT_Wpragmas, "junk at end of %<#pragma push_macro%>"); + + /* Check for empty string, and silently ignore. */ + if (TREE_STRING_LENGTH (id) < 1) + return; + macroname = TREE_STRING_POINTER (id); + + if (pushed_macro_table == NULL) + pushed_macro_table = htab_create_ggc (15, dpm_hash, dpm_eq, 0); + + dummy.hash = htab_hash_string (macroname); + dummy.name = macroname; + slot = htab_find_slot_with_hash (pushed_macro_table, &dummy, + dummy.hash, INSERT); + c = *slot; + if (c == NULL) + { + *slot = c = ggc_alloc (sizeof (struct def_pragma_macro)); + c->hash = dummy.hash; + c->name = ggc_alloc_string (macroname, TREE_STRING_LENGTH (id) - 1); + c->value.prev = NULL; + } + else + { + struct def_pragma_macro_value *v; + v = ggc_alloc (sizeof (struct def_pragma_macro_value)); + *v = c->value; + c->value.prev = v; + } + + c->value.value = cpp_push_definition (reader, macroname); +} + +static void +handle_pragma_pop_macro (cpp_reader *reader) +{ + tree x, id = 0; + enum cpp_ttype token; + struct def_pragma_macro dummy, *c; + const char *macroname; + void **slot; + + if (pragma_lex (&x) != CPP_OPEN_PAREN) + GCC_BAD ("missing %<(%> after %<#pragma pop_macro%> - ignored"); + + token = pragma_lex (&id); + + /* Silently ignore */ + if (token == CPP_CLOSE_PAREN) + return; + if (token != CPP_STRING) + GCC_BAD ("invalid constant in %<#pragma pop_macro%> - ignored"); + + if (pragma_lex (&x) != CPP_CLOSE_PAREN) + GCC_BAD ("missing %<)%> after %<#pragma pop_macro%> - ignored"); + + if (pragma_lex (&x) != CPP_EOF) + warning (OPT_Wpragmas, "junk at end of %<#pragma pop_macro%>"); + + /* Check for empty string, and silently ignore. */ + if (TREE_STRING_LENGTH (id) < 1) + return; + macroname = TREE_STRING_POINTER (id); + + dummy.hash = htab_hash_string (macroname); + dummy.name = macroname; + slot = htab_find_slot_with_hash (pushed_macro_table, &dummy, + dummy.hash, NO_INSERT); + if (slot == NULL) + return; + c = *slot; + + cpp_pop_definition (reader, c->name, c->value.value); + + if (c->value.prev) + c->value = *c->value.prev; + else + htab_clear_slot (pushed_macro_table, slot); +} +#endif /* HANDLE_PRAGMA_PUSH_POP_MACRO */ + static GTY(()) tree pending_weaks; #ifdef HANDLE_PRAGMA_WEAK @@ -819,6 +957,10 @@ init_pragma (void) c_register_pragma (0, "pack", handle_pragma_pack); #endif #endif +#ifdef HANDLE_PRAGMA_PUSH_POP_MACRO + c_register_pragma (0 ,"push_macro", handle_pragma_push_macro); + c_register_pragma (0 ,"pop_macro", handle_pragma_pop_macro); +#endif #ifdef HANDLE_PRAGMA_WEAK c_register_pragma (0, "weak", handle_pragma_weak); #endif |