Commit 6d4587f7 by Zack Weinberg

cppinit.c (cpp_post_options): Shut off macro expansion if -fpreprocessed.

	* cppinit.c (cpp_post_options): Shut off macro expansion if
	-fpreprocessed.
	* cpplib.c (_cpp_handle_directive): If -fpreprocessed, accept
	IN_I directives only if the # is in column 1 and the directive
	name begins in column 2.
	* cppmain.c (scan_buffer): Insert a space between # and an
	identifier, when that identifier is a directive name.

	* tradcpp.c (struct file_buf): Add a pointer to the next entry
	in the header search path.
	(enum node_type): Add T_INCLUDE_NEXT.
	(directive_table): Add entry for include_next.
	(do_include_next): New function.
	(process_include): New routine, broken out of do_include.
	(finclude): Insert 'nhd' argument, to be copied into
	next_header_dir of the new buffer.
	(main): Adjust to match.
	* gsyslimits.h, limity.h: Un-indent #include_next.

testsuite:
	* gcc.dg/cpp/direct2.c: New test.
	* gcc.dg/cpp/direct2s.c: New test.

	* gcc.c-torture/execute/920730-1t.c: #undef __GNUC__ at head.

From-SVN: r41932
parent 6ebe3121
2001-05-09 Zack Weinberg <zackw@stanford.edu>
* cppinit.c (cpp_post_options): Shut off macro expansion if
-fpreprocessed.
* cpplib.c (_cpp_handle_directive): If -fpreprocessed, accept
IN_I directives only if the # is in column 1 and the directive
name begins in column 2.
* cppmain.c (scan_buffer): Insert a space between # and an
identifier, when that identifier is a directive name.
* tradcpp.c (struct file_buf): Add a pointer to the next entry
in the header search path.
(enum node_type): Add T_INCLUDE_NEXT.
(directive_table): Add entry for include_next.
(do_include_next): New function.
(process_include): New routine, broken out of do_include.
(finclude): Insert 'nhd' argument, to be copied into
next_header_dir of the new buffer.
(main): Adjust to match.
* gsyslimits.h, limity.h: Un-indent #include_next.
2001-05-09 Joseph S. Myers <jsm28@cam.ac.uk>
* objc.texi: Move from ../libobjc/objc-features.texi. Adjust for
......@@ -466,7 +487,7 @@ Fri May 4 13:10:03 CEST 2001 Jan Hubicka <jh@suse.cz>
(REG_OK_FOR_INDEX_P): Use INT_REG_OK_FOR_INDEX_P.
(REG_OK_FOR_BASE_P): Use INT_REG_OK_FOR_BASE_P.
(LEGITIMATE_OFFSET_ADDRESS_P): Use INT_REG_OK_FOR_INDEX_P and
INT_REG_OK_FOR_BASE_P instead of REG_OK_FOR_INDEX_P and
INT_REG_OK_FOR_BASE_P instead of REG_OK_FOR_INDEX_P and
REG_OK_FOR_BASE_P. Take an additional parameter.
(LEGITIMATE_INDEXED_ADDRESS_P): Likeewise.
(LEGITIMATE_INDIRECT_ADDRESS_P): Likewise.
......
......@@ -1716,6 +1716,11 @@ cpp_post_options (pfile)
if (CPP_OPTION (pfile, user_label_prefix) == NULL)
CPP_OPTION (pfile, user_label_prefix) = USER_LABEL_PREFIX;
/* Permanently disable macro expansion if we are rescanning
preprocessed text. */
if (CPP_OPTION (pfile, preprocessed))
pfile->state.prevent_expansion = 1;
/* We need to do this after option processing and before
cpp_start_read, as cppmain.c relies on the options->no_output to
set its callbacks correctly before calling cpp_start_read. */
......
......@@ -311,7 +311,32 @@ _cpp_handle_directive (pfile, indented)
/* If we are rescanning preprocessed input, only directives tagged
with IN_I are honored, and the warnings below are suppressed. */
if (! CPP_OPTION (pfile, preprocessed) || dir->flags & IN_I)
if (CPP_OPTION (pfile, preprocessed))
{
/* Kluge alert. In order to be sure that code like this
#define HASH #
HASH define foo bar
does not cause '#define foo bar' to get executed when
compiled with -save-temps, we recognize directives in
-fpreprocessed mode only if the # is in column 1 and the
directive name starts in column 2. This output can only
be generated by the directive callbacks in cppmain.c (see
also the special case in scan_buffer). */
if (dir->flags & IN_I && !indented && !(dname.flags & PREV_WHITE))
(*dir->handler) (pfile);
/* That check misses '# 123' linemarkers. Let them through too. */
else if (dname.type == CPP_NUMBER)
(*dir->handler) (pfile);
else
{
/* We don't want to process this directive. Put back the
tokens so caller will see them (and issue an error,
probably). */
_cpp_push_token (pfile, &dname, &pfile->directive_pos);
skip = 0;
}
}
else
{
/* Traditionally, a directive is ignored unless its # is in
column 1. Therefore in code intended to work with K+R
......
......@@ -238,6 +238,13 @@ scan_buffer (pfile)
== AVOID_LPASTE
&& cpp_avoid_paste (pfile, &tokens[1 - index], token))
token->flags |= PREV_WHITE;
/* Special case '# <directive name>': insert a space between
the # and the token. This will prevent it from being
treated as a directive when this code is re-preprocessed.
XXX Should do this only at the beginning of a line, but how? */
else if (token->type == CPP_NAME && token->val.node->directive_index
&& tokens[1 - index].type == CPP_HASH)
token->flags |= PREV_WHITE;
cpp_output_token (token, print.outf);
print.printed = 1;
......
......@@ -4,5 +4,5 @@
instead of this text. */
#define _GCC_NEXT_LIMITS_H /* tell gcc's limits.h to recurse */
#include_next <limits.h>
#include_next <limits.h>
#undef _GCC_NEXT_LIMITS_H
......@@ -4,7 +4,7 @@
#else /* not _GCC_LIMITS_H_ */
#ifdef _GCC_NEXT_LIMITS_H
#include_next <limits.h> /* recurse down to the real one */
#include_next <limits.h> /* recurse down to the real one */
#endif
#endif /* not _GCC_LIMITS_H_ */
/* This is just 920730-1.c compiled with -traditional.
See 920730-1t.x. */
/* It is necessary to undefine __GNUC__ in order to prevent glibc 2.2's
sys/cdefs.h from issuing an #error. Do Not Ask. */
#undef __GNUC__
#include "920730-1.c"
/* Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Nathan Sidwell 8 May 2001 <nathan@codesourcery.com> */
/* Test of prohibition on directives which result from macro expansion.
See also direct2s.c */
/* { dg-do compile } */
#define HASH #
#define HASHDEFINE #define
#define HASHINCLUDE #include
HASH include "somerandomfile" /*{ dg-error "syntax|parse" "non-include" }*/
/*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 13 }*/
HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 15 }*/
void g ()
{
HASH define X 1 /* { dg-error "syntax error" "# from macro" } */
HASHDEFINE Y 1 /* { dg-error "syntax error" "#define from macro" } */
}
#pragma GCC dependency "direct2.c"
#
void f ()
{
int i = X; /* { dg-error "undeclared|for each" "no macro X" } */
int j = Y; /* { dg-error "undeclared|for each" "no macro Y" } */
}
#define slashstar /##*
#define starslash *##/
slashstar starslash /* { dg-error "parse error" "not a comment" } */
/* { dg-warning "does not give" "paste warning(s)" { target *-*-* } 36 } */
/* Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Nathan Sidwell 8 May 2001 <nathan@codesourcery.com> */
/* Test of prohibition on directives which result from macro
expansion. Same as direct2.c, with -save-temps applied; results
should be identical. */
/* { dg-do compile } */
/* { dg-options "-save-temps -ansi -pedantic-errors" } */
#define HASH #
#define HASHDEFINE #define
#define HASHINCLUDE #include
HASH include "somerandomfile" /*{ dg-error "syntax|parse" "non-include" }*/
/*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 15 }*/
HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/
/*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 17 }*/
void g ()
{
HASH define X 1 /* { dg-error "syntax error" "# from macro" } */
HASHDEFINE Y 1 /* { dg-error "syntax error" "#define from macro" } */
}
#pragma GCC dependency "direct2s.c"
#
void f ()
{
int i = X; /* { dg-error "undeclared|for each" "no macro X" } */
int j = Y; /* { dg-error "undeclared|for each" "no macro Y" } */
}
#define slashstar /##*
#define starslash *##/
slashstar starslash /* { dg-error "parse error" "not a comment" } */
/* { dg-warning "does not give" "paste warning(s)" { target *-*-* } 38 } */
......@@ -105,6 +105,7 @@ static const char *user_label_prefix;
It is zero for rescanning results of macro expansion
and for expanding macro arguments. */
#define INPUT_STACK_MAX 200
struct file_name_list;
struct file_buf {
const char *fname;
int lineno;
......@@ -120,6 +121,8 @@ struct file_buf {
struct if_stack *if_stack;
/* Object to be freed at end of input at this level. */
U_CHAR *free_ptr;
/* Position to start scanning for #include_next in this file. */
struct file_name_list *next_header_dir;
} instack[INPUT_STACK_MAX];
typedef struct file_buf FILE_BUF;
......@@ -240,6 +243,7 @@ union hashval {
enum node_type {
T_DEFINE = 1, /* `#define' */
T_INCLUDE, /* `#include' */
T_INCLUDE_NEXT,/* `#include_next' */
T_IFDEF, /* `#ifdef' */
T_IFNDEF, /* `#ifndef' */
T_IF, /* `#if' */
......@@ -358,6 +362,7 @@ static void do_error PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
static void do_warning PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
static void do_line PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
static void do_include PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
static void do_include_next PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
static void do_undef PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
static void do_if PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
static void do_ifdef PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
......@@ -415,7 +420,10 @@ static void make_assertion PARAMS ((const char *));
static void grow_outbuf PARAMS ((FILE_BUF *, int));
static int handle_directive PARAMS ((FILE_BUF *, FILE_BUF *));
static void finclude PARAMS ((int, const char *, FILE_BUF *));
static void process_include PARAMS ((struct file_name_list *,
const U_CHAR *, int, int, FILE_BUF *));
static void finclude PARAMS ((int, const char *,
struct file_name_list *, FILE_BUF *));
static void init_dependency_output PARAMS ((void));
static void rescan PARAMS ((FILE_BUF *, int));
static void newline_fix PARAMS ((U_CHAR *));
......@@ -450,6 +458,7 @@ struct directive directive_table[] = {
{ 4, do_elif, "elif", T_ELIF },
{ 5, do_error, "error", T_ERROR },
{ 7, do_warning, "warning", T_WARNING },
{ 12, do_include_next, "include_next", T_INCLUDE_NEXT },
{ 6, do_assert, "assert", T_ASSERT },
{ 8, do_unassert,"unassert",T_UNASSERT},
{ -1, 0, "", T_UNUSED},
......@@ -853,7 +862,7 @@ main (argc, argv)
if (print_deps)
deps_add_dep (deps, pend[i].arg);
finclude (fd, pend[i].arg, &outbuf);
finclude (fd, pend[i].arg, 0, &outbuf);
}
indepth--;
no_output--;
......@@ -2278,22 +2287,17 @@ do_include (buf, limit, op)
U_CHAR *buf, *limit;
FILE_BUF *op;
{
char *fname; /* Dynamically allocated fname buffer */
U_CHAR *fbeg, *fend; /* Beginning and end of fname */
struct file_name_list *stackp = include; /* Chain of dirs to search */
struct file_name_list dsp[1]; /* First in chain, if #include "..." */
int flen;
int f; /* file number */
int retried = 0; /* Have already tried macro
expanding the include line*/
FILE_BUF trybuf; /* It got expanded into here */
int system_header_p = 0; /* 0 for "...", 1 for <...> */
f= -1; /* JF we iz paranoid! */
get_filename:
fbeg = buf;
......@@ -2374,6 +2378,90 @@ get_filename:
}
flen = fend - fbeg;
process_include (stackp, fbeg, flen, system_header_p, op);
}
static void
do_include_next (buf, limit, op)
U_CHAR *buf, *limit;
FILE_BUF *op;
{
U_CHAR *fbeg, *fend; /* Beginning and end of fname */
struct file_name_list *stackp; /* Chain of dirs to search */
int flen;
int retried = 0; /* Have already tried macro
expanding the include line*/
FILE_BUF trybuf; /* It got expanded into here */
int system_header_p = 0; /* 0 for "...", 1 for <...> */
/* Treat as plain #include if we don't know where to start
looking. */
stackp = instack[indepth].next_header_dir;
if (stackp == 0)
{
do_include (buf, limit, op);
return;
}
get_filename:
fbeg = buf;
SKIP_WHITE_SPACE (fbeg);
/* Discard trailing whitespace so we can easily see
if we have parsed all the significant chars we were given. */
while (limit != fbeg && is_nvspace (limit[-1])) limit--;
switch (*fbeg++) {
case '\"':
fend = fbeg;
while (fend != limit && *fend != '\"')
fend++;
if (*fend == '\"' && fend + 1 == limit)
break;
goto fail;
case '<':
fend = fbeg;
while (fend != limit && *fend != '>') fend++;
if (*fend == '>' && fend + 1 == limit) {
system_header_p = 1;
break;
}
goto fail;
default:
fail:
if (retried) {
error ("#include expects \"fname\" or <fname>");
return;
} else {
trybuf = expand_to_temp_buffer (buf, limit, 0);
buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
memcpy (buf, trybuf.buf, trybuf.bufp - trybuf.buf);
limit = buf + (trybuf.bufp - trybuf.buf);
free (trybuf.buf);
retried++;
goto get_filename;
}
}
flen = fend - fbeg;
process_include (stackp, fbeg, flen, system_header_p, op);
}
static void
process_include (stackp, fbeg, flen, system_header_p, op)
struct file_name_list *stackp;
const U_CHAR *fbeg;
int flen;
int system_header_p;
FILE_BUF *op;
{
char *fname;
int f = -1; /* file number */
fname = (char *) alloca (max_include_len + flen + 2);
/* + 2 above for slash and terminating null. */
......@@ -2472,7 +2560,7 @@ get_filename:
system_include_depth++;
/* Actually process the file. */
finclude (f, fname, op);
finclude (f, fname, stackp->next, op);
if (system_header_p)
system_include_depth--;
......@@ -2485,9 +2573,10 @@ get_filename:
with output to OP. */
static void
finclude (f, fname, op)
finclude (f, fname, nhd, op)
int f;
const char *fname;
struct file_name_list *nhd;
FILE_BUF *op;
{
int st_mode;
......@@ -2506,6 +2595,7 @@ finclude (f, fname, op)
fp->length = 0;
fp->lineno = 1;
fp->if_stack = if_stack;
fp->next_header_dir = nhd;
if (S_ISREG (st_mode)) {
fp->buf = (U_CHAR *) xmalloc (st_size + 2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment