aboutsummaryrefslogtreecommitdiff
path: root/gcc/cpplib.c
diff options
context:
space:
mode:
authorGeoff Keating <geoffk@cygnus.com>1999-09-09 04:00:37 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>1999-09-09 04:00:37 +0000
commitfc009f966c98317401b51127f59de4ad37bb7d19 (patch)
treeadfb849ae0813b5bacab43fb7a7ab5ec23bc7fb6 /gcc/cpplib.c
parentd60f72aec57414b8339eecb25c33b423af7e6946 (diff)
downloadgcc-fc009f966c98317401b51127f59de4ad37bb7d19.zip
gcc-fc009f966c98317401b51127f59de4ad37bb7d19.tar.gz
gcc-fc009f966c98317401b51127f59de4ad37bb7d19.tar.bz2
Makefile.in (cppexp.o): Depend on cpphash.h.
* Makefile.in (cppexp.o): Depend on cpphash.h. * cppexp.c (cpp_lex): Handle `defined (xxx)' for poisoned xxx. Include cpphash.h. * cpphash.c (special_symbol): Handle plain `xxx' for poisoned xxx. * cpplib.c (do_define): Generalise to handle poisoned definitions, redefining poisoned identifiers, etc. (do_undef): Don't allow poisoned identifiers to be undefined. (do_pragma): Add #pragma poison. (do_xifdef): Handle `#ifdef xxx' for poisoned xxx. * cccp.c: Add T_POISON node type. (special_symbol): Handle `defined(xxx)' and plain `xxx' for poisoned xxx. (do_define): Generalise to handle poisoned definitions, redefining poisoned identifiers, etc. (do_undef): Don't allow poisoned identifiers to be undefined. (do_pragma): Add #pragma poison. (do_xifdef): Handle `#ifdef xxx' for poisoned xxx. * c-pragma.c (handle_pragma_token): Ignore #pragma poison. * c-pragma.h: Add ps_poison state. We now always have generic pragmas. From-SVN: r29224
Diffstat (limited to 'gcc/cpplib.c')
-rw-r--r--gcc/cpplib.c112
1 files changed, 99 insertions, 13 deletions
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index 4ac7f51..e274df9 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -625,8 +625,9 @@ check_macro_name (pfile, symname, assertion)
}
/* Process a #define command.
-KEYWORD is the keyword-table entry for #define,
-or NULL for a "predefined" macro. */
+ KEYWORD is the keyword-table entry for #define,
+ or NULL for a "predefined" macro,
+ or the keyword-table entry for #pragma in the case of a #pragma poison. */
static int
do_define (pfile, keyword)
@@ -638,10 +639,16 @@ do_define (pfile, keyword)
HASHNODE *hp;
long here;
U_CHAR *macro, *buf, *end;
+ enum node_type new_type;
here = CPP_WRITTEN (pfile);
copy_rest_of_line (pfile);
+ if (keyword == NULL || keyword->type == T_DEFINE)
+ new_type = T_MACRO;
+ else
+ new_type = T_POISON;
+
/* Copy out the line so we can pop the token buffer. */
buf = pfile->token_buffer + here;
end = CPP_PWRITTEN (pfile);
@@ -663,30 +670,40 @@ do_define (pfile, keyword)
/* Redefining a precompiled key is ok. */
if (hp->type == T_PCSTRING)
ok = 1;
+ /* Redefining a poisoned identifier is even worse than `not ok'. */
+ else if (hp->type == T_POISON)
+ ok = -1;
/* Redefining a macro is ok if the definitions are the same. */
else if (hp->type == T_MACRO)
ok = ! compare_defs (pfile, mdef.defn, hp->value.defn);
/* Redefining a constant is ok with -D. */
else if (hp->type == T_CONST || hp->type == T_STDC)
ok = ! CPP_OPTIONS (pfile)->done_initializing;
- /* Print the warning if it's not ok. */
- if (!ok)
+ /* Print the warning or error if it's not ok. */
+ if (ok <= 0)
{
- cpp_pedwarn (pfile, "`%.*s' redefined", mdef.symlen, mdef.symnam);
+ if (hp->type == T_POISON)
+ cpp_error (pfile, "redefining poisoned `%.*s'",
+ mdef.symlen, mdef.symnam);
+ else
+ cpp_pedwarn (pfile, "`%.*s' redefined", mdef.symlen, mdef.symnam);
if (hp->type == T_MACRO)
cpp_pedwarn_with_file_and_line (pfile, hp->value.defn->file,
hp->value.defn->line,
"this is the location of the previous definition");
}
- /* Replace the old definition. */
- hp->type = T_MACRO;
- hp->value.defn = mdef.defn;
+ if (hp->type != T_POISON)
+ {
+ /* Replace the old definition. */
+ hp->type = new_type;
+ hp->value.defn = mdef.defn;
+ }
}
else
- cpp_install (pfile, mdef.symnam, mdef.symlen, T_MACRO,
+ cpp_install (pfile, mdef.symnam, mdef.symlen, new_type,
(char *) mdef.defn, hashcode);
- if (keyword)
+ if (keyword != NULL && keyword->type == T_DEFINE)
{
if (CPP_OPTIONS (pfile)->debug_output
|| CPP_OPTIONS (pfile)->dump_macros == dump_definitions)
@@ -1425,9 +1442,14 @@ do_undef (pfile, keyword)
need to pass through all effective #undef commands. */
if (CPP_OPTIONS (pfile)->debug_output && keyword)
pass_thru_directive (name, sym_length, pfile, keyword);
- if (hp->type != T_MACRO)
- cpp_warning (pfile, "undefining `%s'", hp->name);
- delete_macro (hp);
+ if (hp->type == T_POISON)
+ cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name);
+ else
+ {
+ if (hp->type != T_MACRO)
+ cpp_warning (pfile, "undefining `%s'", hp->name);
+ delete_macro (hp);
+ }
}
return 0;
@@ -1579,6 +1601,65 @@ do_pragma (pfile, keyword)
"`#pragma implementation' for `%s' appears after file is included",
fcopy);
}
+ else if (!strncmp (buf, "poison", 6))
+ {
+ /* Poison these symbols so that all subsequent usage produces an
+ error message. */
+ U_CHAR *p = buf + 6;
+ size_t plen;
+ U_CHAR *syms;
+ int writeit;
+
+ SKIP_WHITE_SPACE (p);
+ plen = strlen(p) + 1;
+
+ syms = (U_CHAR *) alloca (plen);
+ memcpy (syms, p, plen);
+
+ /* As a rule, don't include #pragma poison commands in output,
+ unless the user asks for them. */
+ writeit = (CPP_OPTIONS (pfile)->debug_output
+ || CPP_OPTIONS (pfile)->dump_macros == dump_definitions
+ || CPP_OPTIONS (pfile)->dump_macros == dump_names);
+
+ if (writeit)
+ CPP_SET_WRITTEN (pfile, here);
+ else
+ CPP_SET_WRITTEN (pfile, here-8);
+
+ if (writeit)
+ {
+ CPP_RESERVE (pfile, plen + 7);
+ CPP_PUTS_Q (pfile, "poison", 7);
+ }
+
+ while (*syms != '\0')
+ {
+ U_CHAR *end = syms;
+
+ while (is_idchar[*end])
+ end++;
+
+ if (!is_hor_space[*end] && *end != '\0')
+ {
+ cpp_error (pfile, "invalid #pragma poison directive");
+ return 1;
+ }
+
+ if (cpp_push_buffer (pfile, syms, end - syms) != NULL)
+ {
+ do_define (pfile, keyword);
+ cpp_pop_buffer (pfile);
+ }
+ if (writeit)
+ {
+ CPP_PUTC_Q (pfile, ' ');
+ CPP_PUTS_Q (pfile, syms, end - syms);
+ }
+ syms = end;
+ SKIP_WHITE_SPACE (syms);
+ }
+ }
return 0;
}
@@ -1807,6 +1888,11 @@ do_xifdef (pfile, keyword)
control_macro = (U_CHAR *) xmalloc (ident_length + 1);
bcopy (ident, control_macro, ident_length + 1);
}
+ if (hp != NULL && hp->type == T_POISON)
+ {
+ cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
+ skip = !skip;
+ }
}
else
{