2000-02-09 Zack Weinberg <zack@wolery.cumb.org>
+ * cpplib.h: Provide HASHNODE typedef and forward decl of
+ struct hashnode only. Kill cpp_hashnode typedef. MACRODEF,
+ DEFINITION, struct hashnode, struct macrodef, struct
+ definition, scan_decls prototype, default defn of
+ INCLUDE_LEN_FUDGE moved elsewhere.
+
+ * cpphash.h: MACRODEF, DEFINITION, struct macrodef, struct
+ definition, and struct hashnode moved here. Remove the unused
+ 'predefined' field from struct definition. Replace the 'args'
+ union with its sole member. All users updated (cpphash.c).
+ Delete HASHSTEP and MAKE_POS macros, and hashf prototype. Add
+ multiple include guard.
+
+ * cpphash.c (hashf): Make static; use better algorithm; drop
+ HASHSIZE parameter; return an unsigned int.
+ (cpp_lookup): Drop HASH parameter. PFILE parameter is
+ used. Calculate HASHSIZE modulus here.
+ (cpp_install): Drop HASH parameter. Calculate HASHSIZE modulus
+ here.
+ (create_definition): Drop PREDEFINITION parameter.
+ * cpplib.c (do_define): Don't calculate a hash value here.
+ Don't pass (keyword == NULL) to create_definition.
+
+ * scan.h: Prototype scan_decls here.
+ * cppfiles.c: Move INCLUDE_LEN_FUDGE default defn here.
+ * cppexp.c, cppfiles.c, cppinit.c, cpplib.c, fix-header.c: All
+ callers of cpp_lookup and cpp_install updated.
+
* cpphash.c (macarg): Hoist all the flag diddling out of the
function...
(macroexpand): ... and out of the loop that calls macarg.
num_bits = num_chars * width;
if (cpp_lookup (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__",
- sizeof ("__CHAR_UNSIGNED__")-1, -1)
+ sizeof ("__CHAR_UNSIGNED__")-1)
|| ((result >> (num_bits - 1)) & 1) == 0)
op.value = result & ((unsigned HOST_WIDEST_INT) ~0
>> (HOST_BITS_PER_WIDEST_INT - num_bits));
goto oops;
++ip->cur;
}
- hp = cpp_lookup (pfile, tok, len, -1);
+ hp = cpp_lookup (pfile, tok, len);
if (hp != NULL)
{
if (hp->type == T_POISON)
#define INO_T_EQ(a, b) ((a) == (b))
#endif
+#ifndef INCLUDE_LEN_FUDGE
+#define INCLUDE_LEN_FUDGE 0
+#endif
+
/* Merge the four include chains together in the order quote, bracket,
system, after. Remove duplicate dirs (as determined by
INO_T_EQ()). The system_include and after_include chains are never
included again if the string is the name of a defined macro. */
return (i->control_macro
&& (i->control_macro[0] == '\0'
- || cpp_lookup (pfile, i->control_macro, -1, -1)))
+ || cpp_lookup (pfile, i->control_macro, -1)))
? (struct include_hash *)-1 : i;
return 0;
#include "cpphash.h"
#undef abort
+static unsigned int hashf PARAMS ((const U_CHAR *, int));
static int comp_def_part PARAMS ((int, U_CHAR *, int, U_CHAR *,
int, int));
static void push_macro_expansion PARAMS ((cpp_reader *,
/* Return hash function on name. must be compatible with the one
computed a step at a time, elsewhere */
-int
-hashf (name, len, hashsize)
- register const U_CHAR *name;
+static unsigned int
+hashf (s, len)
+ register const U_CHAR *s;
register int len;
- int hashsize;
{
- register int r = 0;
-
- while (len--)
- r = HASHSTEP (r, *name++);
+ unsigned int n = len;
+ unsigned int r = 0;
- return MAKE_POS (r) % hashsize;
+ do
+ r = r * 67 + (*s++ - 113);
+ while (--n);
+ return r + len;
}
/* Find the most recent hash node for name "name" (ending with first
non-identifier char) installed by cpp_install
If LEN is >= 0, it is the length of the name.
- Otherwise, compute the length by scanning the entire name.
-
- If HASH is >= 0, it is the precomputed hash code.
- Otherwise, compute the hash code. */
+ Otherwise, compute the length by scanning the entire name. */
HASHNODE *
-cpp_lookup (pfile, name, len, hash)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+cpp_lookup (pfile, name, len)
+ cpp_reader *pfile;
const U_CHAR *name;
int len;
- int hash;
{
register const U_CHAR *bp;
register HASHNODE *bucket;
+ register unsigned int hash;
if (len < 0)
{
len = bp - name;
}
- if (hash < 0)
- hash = hashf (name, len, HASHSIZE);
+ hash = hashf (name, len) % HASHSIZE;
bucket = pfile->hashtab[hash];
while (bucket)
free (ap);
}
if (d->nargs >= 0)
- free (d->args.argnames);
+ free (d->argnames);
free (d);
}
Otherwise, compute the hash code. */
HASHNODE *
-cpp_install (pfile, name, len, type, value, hash)
+cpp_install (pfile, name, len, type, value)
cpp_reader *pfile;
const U_CHAR *name;
int len;
enum node_type type;
const char *value;
- int hash;
{
register HASHNODE *hp;
register int i, bucket;
register const U_CHAR *p;
+ unsigned int hash;
if (len < 0)
{
len = p - name;
}
- if (hash < 0)
- hash = hashf (name, len, HASHSIZE);
+ hash = hashf (name, len) % HASHSIZE;
i = sizeof (HASHNODE) + len + 1;
hp = (HASHNODE *) xmalloc (i);
as for do_define. */
MACRODEF
-create_definition (buf, limit, pfile, predefinition)
+create_definition (buf, limit, pfile)
U_CHAR *buf, *limit;
cpp_reader *pfile;
- int predefinition;
{
U_CHAR *bp; /* temp ptr into input buffer */
U_CHAR *symname; /* remember where symbol name starts */
defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
defn->rest_args = rest_args;
- /* Now set defn->args.argnames to the result of concatenating
+ /* Now set defn->argnames to the result of concatenating
the argument names in reverse order
with comma-space between them. */
- defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
+ defn->argnames = (U_CHAR *) xmalloc (arglengths + 1);
{
struct arglist *temp;
int i = 0;
for (temp = arg_ptrs; temp; temp = temp->next)
{
- bcopy (temp->name, &defn->args.argnames[i], temp->length);
+ bcopy (temp->name, &defn->argnames[i], temp->length);
i += temp->length;
if (temp->next != 0)
{
- defn->args.argnames[i++] = ',';
- defn->args.argnames[i++] = ' ';
+ defn->argnames[i++] = ',';
+ defn->argnames[i++] = ' ';
}
}
- defn->args.argnames[i] = 0;
+ defn->argnames[i] = 0;
}
}
else
}
/* now everything from bp before limit is the definition. */
defn = collect_expansion (pfile, bp, limit, -1, NULL_PTR);
- defn->args.argnames = (U_CHAR *) "";
+ defn->argnames = (U_CHAR *) "";
}
defn->line = line;
defn->file = file;
- /* OP is null if this is a predefinition */
- defn->predefined = predefinition;
mdef.defn = defn;
mdef.symnam = symname;
mdef.symlen = sym_length;
if (d1->nargs != d2->nargs)
return 1;
if (CPP_PEDANTIC (pfile)
- && strcmp ((char *) d1->args.argnames, (char *) d2->args.argnames))
+ && strcmp ((char *) d1->argnames, (char *) d2->argnames))
return 1;
for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
a1 = a1->next, a2 = a2->next)
else
{
struct reflist *r;
- unsigned char *argnames = (unsigned char *) xstrdup (defn->args.argnames);
+ unsigned char *argnames = (unsigned char *) xstrdup (defn->argnames);
unsigned char **argv = (unsigned char **) alloca (defn->nargs *
sizeof(char *));
int *argl = (int *) alloca (defn->nargs * sizeof(int));
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#ifndef __GCC_CPPHASH__
+#define __GCC_CPPHASH__
+
+/* Structure returned by create_definition */
+typedef struct macrodef MACRODEF;
+struct macrodef
+{
+ struct definition *defn;
+ const U_CHAR *symnam;
+ int symlen;
+};
+
+/* Structure allocated for every #define. For a simple replacement
+ such as
+ #define foo bar ,
+ nargs = -1, the `pattern' list is null, and the expansion is just
+ the replacement text. Nargs = 0 means a functionlike macro with no args,
+ e.g.,
+ #define getchar() getc (stdin) .
+ When there are args, the expansion is the replacement text with the
+ args squashed out, and the reflist is a list describing how to
+ build the output from the input: e.g., "3 chars, then the 1st arg,
+ then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
+ The chars here come from the expansion. Whatever is left of the
+ expansion after the last arg-occurrence is copied after that arg.
+ Note that the reflist can be arbitrarily long---
+ its length depends on the number of times the arguments appear in
+ the replacement text, not how many args there are. Example:
+ #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
+ pattern list
+ { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
+ where (x, y) means (nchars, argno). */
+
+typedef struct definition DEFINITION;
+struct definition {
+ int nargs;
+ int length; /* length of expansion string */
+ unsigned char *expansion;
+ int line; /* Line number of definition */
+ const char *file; /* File of definition */
+ char rest_args; /* Nonzero if last arg. absorbs the rest */
+ struct reflist {
+ struct reflist *next;
+ char stringify; /* nonzero if this arg was preceded by a
+ # operator. */
+ char raw_before; /* Nonzero if a ## operator before arg. */
+ char raw_after; /* Nonzero if a ## operator after arg. */
+ char rest_args; /* Nonzero if this arg. absorbs the rest */
+ int nchars; /* Number of literal chars to copy before
+ this arg occurrence. */
+ int argno; /* Number of arg to substitute (origin-0) */
+ } *pattern;
+ /* Names of macro args, concatenated in reverse order
+ with comma-space between them.
+ The only use of this is that we warn on redefinition
+ if this differs between the old and new definitions. */
+ unsigned char *argnames;
+};
+
/* different kinds of things that can appear in the value field
of a hash node. */
union hashval
union hashval value; /* pointer to expansion, or whatever */
};
-typedef struct hashnode HASHNODE;
-
-/* Some definitions for the hash table. The hash function MUST be
- computed as shown in hashf () below. That is because the rescan
- loop computes the hash value `on the fly' for most tokens,
- in order to avoid the overhead of a lot of procedure calls to
- the hashf () function. Hashf () only exists for the sake of
- politeness, for use when speed isn't so important. */
-
-#define HASHSTEP(old, c) ((old << 2) + c)
-#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
-
extern HASHNODE *cpp_install PARAMS ((cpp_reader *, const U_CHAR *, int,
- enum node_type, const char *, int));
-extern int hashf PARAMS ((const U_CHAR *, int, int));
+ enum node_type, const char *));
extern void delete_macro PARAMS ((HASHNODE *));
extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *,
- cpp_reader *, int));
+ cpp_reader *));
extern int compare_defs PARAMS ((cpp_reader *, DEFINITION *,
DEFINITION *));
extern void macroexpand PARAMS ((cpp_reader *, HASHNODE *));
extern void dump_definition PARAMS ((cpp_reader *, MACRODEF));
+
+#endif
val = (b->flags & ULP) ? user_label_prefix : b->value;
len = strlen (b->name);
- cpp_install (pfile, b->name, len, b->type, val, -1);
+ cpp_install (pfile, b->name, len, b->type, val);
if ((b->flags & DUMP) && CPP_OPTIONS (pfile)->debug_output)
dump_special_to_buffer (pfile, b->name);
}
cpp_reader *pfile;
const struct directive *keyword;
{
- int hashcode;
MACRODEF mdef;
HASHNODE *hp;
long here;
CPP_SET_WRITTEN (pfile, here);
- mdef = create_definition (macro, end, pfile, keyword == NULL);
+ mdef = create_definition (macro, end, pfile);
if (mdef.defn == 0)
return 0;
- hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
-
- if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen, hashcode)) != NULL)
+ if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen)) != NULL)
{
int ok = 0;
/* Redefining a precompiled key is ok. */
}
}
else
- cpp_install (pfile, mdef.symnam, mdef.symlen, new_type,
- (char *) mdef.defn, hashcode);
+ cpp_install (pfile, mdef.symnam, mdef.symlen, new_type, (char *)mdef.defn);
if (keyword != NULL && keyword->type == T_DEFINE)
{
sym_length = check_macro_name (pfile, buf);
- while ((hp = cpp_lookup (pfile, name, sym_length, -1)) != NULL)
+ while ((hp = cpp_lookup (pfile, name, sym_length)) != NULL)
{
/* If we are generating additional info for debugging (with -g) we
need to pass through all effective #undef commands. */
}
else if (token == CPP_NAME)
{
- HASHNODE *hp = cpp_lookup (pfile, ident, ident_length, -1);
+ HASHNODE *hp = cpp_lookup (pfile, ident, ident_length);
skip = (hp == NULL) ^ (keyword->type == T_IFNDEF);
if (start_of_file && !skip)
{
return CPP_NAME;
ident = pfile->token_buffer + before_name_written;
ident_len = CPP_PWRITTEN (pfile) - ident;
- hp = cpp_lookup (pfile, ident, ident_len, -1);
+ hp = cpp_lookup (pfile, ident, ident_len);
if (!hp)
return CPP_NAME;
if (hp->type == T_DISABLED)
thislen = strlen (sym);
baselen = index (sym, '(') - sym;
- this = cpp_lookup (pfile, sym, thislen, -1);
+ this = cpp_lookup (pfile, sym, thislen);
if (this)
{
cpp_warning (pfile, "`%s' re-asserted", sym);
goto error;
}
- base = cpp_lookup (pfile, sym, baselen, -1);
+ base = cpp_lookup (pfile, sym, baselen);
if (! base)
- base = cpp_install (pfile, sym, baselen, T_ASSERT, 0, -1);
+ base = cpp_install (pfile, sym, baselen, T_ASSERT, 0);
else if (base->type != T_ASSERT)
{
/* Token clash - but with what?! */
}
this = cpp_install (pfile, sym, thislen, T_ASSERT,
- (char *)base->value.aschain, -1);
+ (char *)base->value.aschain);
base->value.aschain = this;
pfile->limit = (unsigned char *) sym; /* Pop */
thislen = strlen (sym);
if (ret == 1)
{
- base = cpp_lookup (pfile, sym, thislen, -1);
+ base = cpp_lookup (pfile, sym, thislen);
if (! base)
goto error; /* It isn't an error to #undef what isn't #defined,
so it isn't an error to #unassert what isn't
else
{
baselen = index (sym, '(') - sym;
- base = cpp_lookup (pfile, sym, baselen, -1);
+ base = cpp_lookup (pfile, sym, baselen);
if (! base) goto error;
- this = cpp_lookup (pfile, sym, thislen, -1);
+ this = cpp_lookup (pfile, sym, thislen);
if (! this) goto error;
next = base;
result = 0;
else
{
- hp = cpp_lookup (pfile, name, CPP_PWRITTEN (pfile) - name, -1);
+ hp = cpp_lookup (pfile, name, CPP_PWRITTEN (pfile) - name);
result = (hp != 0);
}
typedef struct cpp_reader cpp_reader;
typedef struct cpp_buffer cpp_buffer;
typedef struct cpp_options cpp_options;
-typedef struct hashnode cpp_hashnode;
enum cpp_token {
CPP_EOF = -1,
Applying cpp_get_token repeatedly yields a stream of pre-processor
tokens. Usually, there is only one cpp_reader object active. */
+struct hashnode;
+typedef struct hashnode HASHNODE;
+
struct cpp_reader
{
parse_underflow_t get_token;
/* Hash table of macros and assertions. See cpphash.c */
#define HASHSIZE 1403
- struct hashnode **hashtab;
+ HASHNODE **hashtab;
/* Hash table of other included files. See cppfiles.c */
#define ALL_INCLUDE_HASHSIZE 71
T_UNUSED /* Used for something not defined. */
};
-/* Structure returned by create_definition */
-typedef struct macrodef MACRODEF;
-struct macrodef
-{
- struct definition *defn;
- const U_CHAR *symnam;
- int symlen;
-};
-
-/* Structure allocated for every #define. For a simple replacement
- such as
- #define foo bar ,
- nargs = -1, the `pattern' list is null, and the expansion is just
- the replacement text. Nargs = 0 means a functionlike macro with no args,
- e.g.,
- #define getchar() getc (stdin) .
- When there are args, the expansion is the replacement text with the
- args squashed out, and the reflist is a list describing how to
- build the output from the input: e.g., "3 chars, then the 1st arg,
- then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
- The chars here come from the expansion. Whatever is left of the
- expansion after the last arg-occurrence is copied after that arg.
- Note that the reflist can be arbitrarily long---
- its length depends on the number of times the arguments appear in
- the replacement text, not how many args there are. Example:
- #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
- pattern list
- { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
- where (x, y) means (nchars, argno). */
-
-typedef struct definition DEFINITION;
-struct definition {
- int nargs;
- int length; /* length of expansion string */
- int predefined; /* True if the macro was builtin or */
- /* came from the command line */
- unsigned char *expansion;
- int line; /* Line number of definition */
- const char *file; /* File of definition */
- char rest_args; /* Nonzero if last arg. absorbs the rest */
- struct reflist {
- struct reflist *next;
- char stringify; /* nonzero if this arg was preceded by a
- # operator. */
- char raw_before; /* Nonzero if a ## operator before arg. */
- char raw_after; /* Nonzero if a ## operator after arg. */
- char rest_args; /* Nonzero if this arg. absorbs the rest */
- int nchars; /* Number of literal chars to copy before
- this arg occurrence. */
- int argno; /* Number of arg to substitute (origin-0) */
- } *pattern;
- union {
- /* Names of macro args, concatenated in reverse order
- with comma-space between them.
- The only use of this is that we warn on redefinition
- if this differs between the old and new definitions. */
- unsigned char *argnames;
- } args;
-};
-
/* Character classes.
If the definition of `numchar' looks odd to you, please look up the
definition of a pp-number in the C standard [section 6.4.8 of C99] */
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
unsigned char *, long));
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
+extern HASHNODE *cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int));
-extern cpp_hashnode *cpp_lookup PARAMS ((cpp_reader *, const unsigned char *,
- int, int));
extern void cpp_reader_init PARAMS ((cpp_reader *));
extern void cpp_options_init PARAMS ((cpp_options *));
extern int cpp_start_read PARAMS ((cpp_reader *, char *));
extern int cpp_read_check_assertion PARAMS ((cpp_reader *));
-extern int scan_decls PARAMS ((cpp_reader *, int, char **));
extern void skip_rest_of_line PARAMS ((cpp_reader *));
extern void cpp_finish PARAMS ((cpp_reader *));
const char *, int));
extern struct include_hash *include_hash PARAMS ((cpp_reader *, const char *, int));
-#ifndef INCLUDE_LEN_FUDGE
-#define INCLUDE_LEN_FUDGE 0
-#endif
-
-
#ifdef __cplusplus
}
#endif
{
while (*names)
{
- if (cpp_lookup (pfile, names, -1, -1))
+ if (cpp_lookup (pfile, names, -1))
recognized_macro (names);
names += strlen (names) + 1;
}
extern void recognized_extern _PARAMS((const char *, int, const char *, int));
extern unsigned int hashstr _PARAMS((const char *, unsigned int));
+struct cpp_reader;
+extern int scan_decls _PARAMS((struct cpp_reader *, int, char **));
+
/* get_token is a simple C lexer. */
#define IDENTIFIER_TOKEN 300
#define CHAR_TOKEN 301