PageRenderTime 31ms CodeModel.GetById 19ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/usr.bin/xlint/lint1/scan.l

https://bitbucket.org/freebsd/freebsd-head/
LEX | 1475 lines | 1049 code | 139 blank | 287 comment | 0 complexity | 96a6366d9419c4b2ccf27bc789942a0e MD5 | raw file
   1%{
   2/* $NetBSD: scan.l,v 1.26 2002/01/31 22:30:21 tv Exp $ */
   3
   4/*
   5 * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
   6 * Copyright (c) 1994, 1995 Jochen Pohl
   7 * All Rights Reserved.
   8 *
   9 * Redistribution and use in source and binary forms, with or without
  10 * modification, are permitted provided that the following conditions
  11 * are met:
  12 * 1. Redistributions of source code must retain the above copyright
  13 *    notice, this list of conditions and the following disclaimer.
  14 * 2. Redistributions in binary form must reproduce the above copyright
  15 *    notice, this list of conditions and the following disclaimer in the
  16 *    documentation and/or other materials provided with the distribution.
  17 * 3. All advertising materials mentioning features or use of this software
  18 *    must display the following acknowledgement:
  19 *      This product includes software developed by Jochen Pohl for
  20 *      The NetBSD Project.
  21 * 4. The name of the author may not be used to endorse or promote products
  22 *    derived from this software without specific prior written permission.
  23 *
  24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34 */
  35
  36#include <sys/cdefs.h>
  37#if defined(__RCSID) && !defined(lint)
  38__RCSID("$NetBSD: scan.l,v 1.26 2002/01/31 22:30:21 tv Exp $");
  39#endif
  40__FBSDID("$FreeBSD$");
  41
  42#include <stdlib.h>
  43#include <string.h>
  44#include <limits.h>
  45#include <float.h>
  46#include <ctype.h>
  47#include <errno.h>
  48#include <err.h>
  49#include <math.h>
  50
  51#include "lint1.h"
  52#include "cgram.h"
  53
  54#define CHAR_MASK	(~(~0 << CHAR_BIT))
  55#define YY_NO_UNPUT
  56
  57/* Current position (its also updated when an included file is parsed) */
  58pos_t	curr_pos = { 1, "", 0 };
  59
  60/*
  61 * Current position in C source (not updated when an included file is
  62 * parsed).
  63 */
  64pos_t	csrc_pos = { 1, "", 0 };
  65
  66static	void	incline(void);
  67static	void	badchar(int);
  68static	sbuf_t	*allocsb(void);
  69static	void	freesb(sbuf_t *);
  70static	int	inpc(void);
  71static	int	hash(const char *);
  72static	sym_t	*search(sbuf_t *);
  73static	int	name(void);
  74static	int	keyw(sym_t *);
  75static	int	icon(int);
  76static	int	fcon(void);
  77static	int	operator(int, op_t);
  78static	int	ccon(void);
  79static	int	wccon(void);
  80static	int	getescc(int);
  81static	void	directive(void);
  82static	void	comment(void);
  83static	void	slashslashcomment(void);
  84static	int	string(void);
  85static	int	wcstrg(void);
  86
  87%}
  88
  89L	[_A-Za-z]
  90D	[0-9]
  91NZD	[1-9]
  92OD	[0-7]
  93HD	[0-9A-Fa-f]
  94EX	([eE][+-]?[0-9]+)
  95
  96%%
  97
  98{L}({L}|{D})*		 	return (name());
  990{OD}*[lLuU]*			return (icon(8));
 100{NZD}{D}*[lLuU]*		return (icon(10));
 1010[xX]{HD}+[lLuU]*		return (icon(16));
 102{D}+\.{D}*{EX}?[fFlL]?		|
 103{D}+{EX}[fFlL]?			|
 104\.{D}+{EX}?[fFlL]?		return (fcon());
 105"="				return (operator(T_ASSIGN, ASSIGN));
 106"*="				return (operator(T_OPASS, MULASS));
 107"/="				return (operator(T_OPASS, DIVASS));
 108"%="				return (operator(T_OPASS, MODASS));
 109"+="				return (operator(T_OPASS, ADDASS));
 110"-="				return (operator(T_OPASS, SUBASS));
 111"<<="				return (operator(T_OPASS, SHLASS));
 112">>="				return (operator(T_OPASS, SHRASS));
 113"&="				return (operator(T_OPASS, ANDASS));
 114"^="				return (operator(T_OPASS, XORASS));
 115"|="				return (operator(T_OPASS, ORASS));
 116"||"				return (operator(T_LOGOR, LOGOR));
 117"&&"				return (operator(T_LOGAND, LOGAND));
 118"|"				return (operator(T_OR, OR));
 119"&"				return (operator(T_AND, AND));
 120"^"				return (operator(T_XOR, XOR));
 121"=="				return (operator(T_EQOP, EQ));
 122"!="				return (operator(T_EQOP, NE));
 123"<"				return (operator(T_RELOP, LT));
 124">"				return (operator(T_RELOP, GT));
 125"<="				return (operator(T_RELOP, LE));
 126">="				return (operator(T_RELOP, GE));
 127"<<"				return (operator(T_SHFTOP, SHL));
 128">>"				return (operator(T_SHFTOP, SHR));
 129"++"				return (operator(T_INCDEC, INC));
 130"--"				return (operator(T_INCDEC, DEC));
 131"->"				return (operator(T_STROP, ARROW));
 132"."				return (operator(T_STROP, POINT));
 133"+"				return (operator(T_ADDOP, PLUS));
 134"-"				return (operator(T_ADDOP, MINUS));
 135"*"				return (operator(T_MULT, MULT));
 136"/"				return (operator(T_DIVOP, DIV));
 137"%"				return (operator(T_DIVOP, MOD));
 138"!"				return (operator(T_UNOP, NOT));
 139"~"				return (operator(T_UNOP, COMPL));
 140"\""				return (string());
 141"L\""				return (wcstrg());
 142";"				return (T_SEMI);
 143"{"				return (T_LBRACE);
 144"}"				return (T_RBRACE);
 145","				return (T_COMMA);
 146":"				return (T_COLON);
 147"?"				return (T_QUEST);
 148"["				return (T_LBRACK);
 149"]"				return (T_RBRACK);
 150"("				return (T_LPARN);
 151")"				return (T_RPARN);
 152"..."				return (T_ELLIPSE);
 153"'"				return (ccon());
 154"L'"				return (wccon());
 155^#.*$				directive();
 156\n				incline();
 157\t|" "|\f|\v			;
 158"/*"				comment();
 159"//"				slashslashcomment();
 160.				badchar(yytext[0]);
 161
 162%%
 163
 164static void
 165incline(void)
 166{
 167	curr_pos.p_line++;
 168	curr_pos.p_uniq = 0;
 169	if (curr_pos.p_file == csrc_pos.p_file) {
 170		csrc_pos.p_line++;
 171		csrc_pos.p_uniq = 0;
 172	}
 173}
 174
 175static void
 176badchar(int c)
 177{
 178
 179	/* unknown character \%o */
 180	error(250, c);
 181}
 182
 183/*
 184 * Keywords.
 185 * During initialisation they are written to the symbol table.
 186 */
 187static	struct	kwtab {
 188	const	char *kw_name;	/* keyword */
 189	int	kw_token;	/* token returned by yylex() */
 190	scl_t	kw_scl;		/* storage class if kw_token T_SCLASS */
 191	tspec_t	kw_tspec;	/* type spec. if kw_token T_TYPE or T_SOU */
 192	tqual_t	kw_tqual;	/* type qual. fi kw_token T_QUAL */
 193	u_int	kw_stdc : 1;	/* STDC keyword */
 194	u_int	kw_gcc : 1;	/* GCC keyword */
 195} kwtab[] = {
 196	{ "asm",	T_ASM,		0,	0,	0,	  0, 1 },
 197	{ "__asm",	T_ASM,		0,	0,	0,	  0, 0 },
 198	{ "__asm__",	T_ASM,		0,	0,	0,	  0, 0 },
 199	{ "auto",	T_SCLASS,	AUTO,	0,	0,	  0, 0 },
 200	{ "break",	T_BREAK,	0,	0,	0,	  0, 0 },
 201	{ "case",	T_CASE,		0,	0,	0,	  0, 0 },
 202	{ "char",	T_TYPE,		0,	CHAR,	0,	  0, 0 },
 203	{ "const",	T_QUAL,		0,	0,	CONST,	  1, 0 },
 204	{ "__const__",	T_QUAL,		0,	0,	CONST,	  0, 0 },
 205	{ "__const",	T_QUAL,		0,	0,	CONST,	  0, 0 },
 206	{ "continue",	T_CONTINUE,	0,	0,	0,	  0, 0 },
 207	{ "default",	T_DEFAULT,	0,	0,	0,	  0, 0 },
 208	{ "do",		T_DO,		0,	0,	0,	  0, 0 },
 209	{ "double",	T_TYPE,		0,	DOUBLE,	0,	  0, 0 },
 210	{ "else",	T_ELSE,		0,	0,	0,	  0, 0 },
 211	{ "enum",	T_ENUM,		0,	0,	0,	  0, 0 },
 212	{ "extern",	T_SCLASS,	EXTERN,	0,	0,	  0, 0 },
 213	{ "float",	T_TYPE,		0,	FLOAT,	0,	  0, 0 },
 214	{ "for",	T_FOR,		0,	0,	0,	  0, 0 },
 215	{ "goto",	T_GOTO,		0,	0,	0,	  0, 0 },
 216	{ "if",		T_IF,		0,	0,	0,	  0, 0 },
 217	{ "inline",	T_SCLASS,	INLINE,	0,	0,	  0, 1 },
 218	{ "__inline__",	T_SCLASS,	INLINE,	0,	0,	  0, 0 },
 219	{ "__inline",	T_SCLASS,	INLINE,	0,	0,	  0, 0 },
 220	{ "int",	T_TYPE,		0,	INT,	0,	  0, 0 },
 221	{ "__symbolrename", T_SYMBOLRENAME, 0,	0,	0,	  0, 0 },
 222	{ "long",	T_TYPE,		0,	LONG,	0,	  0, 0 },
 223	{ "register",	T_SCLASS,	REG,	0,	0,	  0, 0 },
 224	{ "return",	T_RETURN,	0,	0,	0,	  0, 0 },
 225	{ "short",	T_TYPE,		0,	SHORT,	0,	  0, 0 },
 226	{ "signed",	T_TYPE,		0,	SIGNED,	0,	  1, 0 },
 227	{ "__signed__",	T_TYPE,		0,	SIGNED,	0,	  0, 0 },
 228	{ "__signed",	T_TYPE,		0,	SIGNED,	0,	  0, 0 },
 229	{ "sizeof",	T_SIZEOF,	0,	0,	0,	  0, 0 },
 230	{ "static",	T_SCLASS,	STATIC,	0,	0,	  0, 0 },
 231	{ "struct",	T_SOU,		0,	STRUCT,	0,	  0, 0 },
 232	{ "switch",	T_SWITCH,	0,	0,	0,	  0, 0 },
 233	{ "typedef",	T_SCLASS,	TYPEDEF, 0,	0,	  0, 0 },
 234	{ "union",	T_SOU,		0,	UNION,	0,	  0, 0 },
 235	{ "unsigned",	T_TYPE,		0,	UNSIGN,	0,	  0, 0 },
 236	{ "void",	T_TYPE,		0,	VOID,	0,	  0, 0 },
 237	{ "volatile",	T_QUAL,		0,	0,	VOLATILE, 1, 0 },
 238	{ "__volatile__", T_QUAL,	0,	0,	VOLATILE, 0, 0 },
 239	{ "__volatile",	T_QUAL,		0,	0,	VOLATILE, 0, 0 },
 240	{ "while",	T_WHILE,	0,	0,	0,	  0, 0 },
 241	{ NULL,		0,		0,	0,	0,	  0, 0 }
 242};
 243
 244/* Symbol table */
 245static	sym_t	*symtab[HSHSIZ1];
 246
 247/* bit i of the entry with index i is set */
 248uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT];
 249
 250/* least significant i bits are set in the entry with index i */
 251uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1];
 252
 253/* least significant i bits are not set in the entry with index i */
 254uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1];
 255
 256/* free list for sbuf structures */
 257static	sbuf_t	 *sbfrlst;
 258
 259/* Typ of next expected symbol */
 260symt_t	symtyp;
 261
 262
 263/*
 264 * All keywords are written to the symbol table. This saves us looking
 265 * in an extra table for each name we found.
 266 */
 267void
 268initscan(void)
 269{
 270	struct	kwtab *kw;
 271	sym_t	*sym;
 272	int	h, i;
 273	uint64_t uq;
 274
 275	for (kw = kwtab; kw->kw_name != NULL; kw++) {
 276		if (kw->kw_stdc && tflag)
 277			continue;
 278		if (kw->kw_gcc && !gflag)
 279			continue;
 280		sym = getblk(sizeof (sym_t));
 281		sym->s_name = kw->kw_name;
 282		sym->s_keyw = 1;
 283		sym->s_value.v_quad = kw->kw_token;
 284		if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) {
 285			sym->s_tspec = kw->kw_tspec;
 286		} else if (kw->kw_token == T_SCLASS) {
 287			sym->s_scl = kw->kw_scl;
 288		} else if (kw->kw_token == T_QUAL) {
 289			sym->s_tqual = kw->kw_tqual;
 290		}
 291		h = hash(sym->s_name);
 292		if ((sym->s_link = symtab[h]) != NULL)
 293			symtab[h]->s_rlink = &sym->s_link;
 294		(symtab[h] = sym)->s_rlink = &symtab[h];
 295	}
 296
 297	/* initialize bit-masks for quads */
 298	for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) {
 299		qbmasks[i] = (uint64_t)1 << i;
 300		uq = ~(uint64_t)0 << i;
 301		qumasks[i] = uq;
 302		qlmasks[i] = ~uq;
 303	}
 304	qumasks[i] = 0;
 305	qlmasks[i] = ~(uint64_t)0;
 306}
 307
 308/*
 309 * Get a free sbuf structure, if possible from the free list
 310 */
 311static sbuf_t *
 312allocsb(void)
 313{
 314	sbuf_t	*sb;
 315
 316	if ((sb = sbfrlst) != NULL) {
 317		sbfrlst = sb->sb_nxt;
 318	} else {
 319		if ((sb = malloc(sizeof (sbuf_t))) == NULL)
 320			nomem();
 321	}
 322	(void)memset(sb, 0, sizeof (*sb));
 323	return (sb);
 324}
 325
 326/*
 327 * Put a sbuf structure to the free list
 328 */
 329static void
 330freesb(sbuf_t *sb)
 331{
 332
 333	sb->sb_nxt = sbfrlst;
 334	sbfrlst = sb;
 335}
 336
 337/*
 338 * Read a character and ensure that it is positive (except EOF).
 339 * Increment line count(s) if necessary.
 340 */
 341static int
 342inpc(void)
 343{
 344	int	c;
 345
 346	if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n')
 347		incline();
 348	return (c);
 349}
 350
 351static int
 352hash(const char *s)
 353{
 354	u_int	v;
 355	const	u_char *us;
 356
 357	v = 0;
 358	for (us = (const u_char *)s; *us != '\0'; us++) {
 359		v = (v << sizeof (v)) + *us;
 360		v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
 361	}
 362	return (v % HSHSIZ1);
 363}
 364
 365/*
 366 * Lex has found a letter followed by zero or more letters or digits.
 367 * It looks for a symbol in the symbol table with the same name. This
 368 * symbol must either be a keyword or a symbol of the type required by
 369 * symtyp (label, member, tag, ...).
 370 *
 371 * If it is a keyword, the token is returned. In some cases it is described
 372 * more deeply by data written to yylval.
 373 *
 374 * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct
 375 * is stored in yylval. This struct contains the name of the symbol, it's
 376 * length and hash value. If there is already a symbol of the same name
 377 * and type in the symbol table, the sbuf struct also contains a pointer
 378 * to the symbol table entry.
 379 */
 380static int
 381name(void)
 382{
 383	char	*s;
 384	sbuf_t	*sb;
 385	sym_t	*sym;
 386	int	tok;
 387
 388	sb = allocsb();
 389	sb->sb_name = yytext;
 390	sb->sb_len = yyleng;
 391	sb->sb_hash = hash(yytext);
 392
 393	if ((sym = search(sb)) != NULL && sym->s_keyw) {
 394		freesb(sb);
 395		return (keyw(sym));
 396	}
 397
 398	sb->sb_sym = sym;
 399
 400	if (sym != NULL) {
 401		if (blklev < sym->s_blklev)
 402			lerror("name() 1");
 403		sb->sb_name = sym->s_name;
 404		sb->sb_len = strlen(sym->s_name);
 405		tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME;
 406	} else {
 407		s = getblk(yyleng + 1);
 408		(void)memcpy(s, yytext, yyleng + 1);
 409		sb->sb_name = s;
 410		sb->sb_len = yyleng;
 411		tok = T_NAME;
 412	}
 413
 414	yylval.y_sb = sb;
 415	return (tok);
 416}
 417
 418static sym_t *
 419search(sbuf_t *sb)
 420{
 421	sym_t	*sym;
 422
 423	for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) {
 424		if (strcmp(sym->s_name, sb->sb_name) == 0) {
 425			if (sym->s_keyw || sym->s_kind == symtyp)
 426				return (sym);
 427		}
 428	}
 429
 430	return (NULL);
 431}
 432
 433static int
 434keyw(sym_t *sym)
 435{
 436	int	t;
 437
 438	if ((t = (int)sym->s_value.v_quad) == T_SCLASS) {
 439		yylval.y_scl = sym->s_scl;
 440	} else if (t == T_TYPE || t == T_SOU) {
 441		yylval.y_tspec = sym->s_tspec;
 442	} else if (t == T_QUAL) {
 443		yylval.y_tqual = sym->s_tqual;
 444	}
 445	return (t);
 446}
 447
 448/*
 449 * Convert a string representing an integer into internal representation.
 450 * The value is returned in yylval. icon() (and yylex()) returns T_CON.
 451 */
 452static int
 453icon(int base)
 454{
 455	int	l_suffix, u_suffix;
 456	int	len;
 457	const	char *cp;
 458	char	c, *eptr;
 459	tspec_t	typ;
 460	u_long	ul = 0;
 461	uint64_t uq = 0;
 462	int	ansiu;
 463	static	tspec_t contypes[2][3] = {
 464		{ INT,  LONG,  QUAD },
 465		{ UINT, ULONG, UQUAD }
 466	};
 467
 468	cp = yytext;
 469	len = yyleng;
 470
 471	/* skip 0x */
 472	if (base == 16) {
 473		cp += 2;
 474		len -= 2;
 475	}
 476
 477	/* read suffixes */
 478	l_suffix = u_suffix = 0;
 479	for ( ; ; ) {
 480		if ((c = cp[len - 1]) == 'l' || c == 'L') {
 481			l_suffix++;
 482		} else if (c == 'u' || c == 'U') {
 483			u_suffix++;
 484		} else {
 485			break;
 486		}
 487		len--;
 488	}
 489	if (l_suffix > 2 || u_suffix > 1) {
 490		/* malformed integer constant */
 491		warning(251);
 492		if (l_suffix > 2)
 493			l_suffix = 2;
 494		if (u_suffix > 1)
 495			u_suffix = 1;
 496	}
 497	if (tflag && u_suffix != 0) {
 498		/* suffix U is illegal in traditional C */
 499		warning(97);
 500	}
 501	typ = contypes[u_suffix][l_suffix];
 502
 503	errno = 0;
 504	if (l_suffix < 2) {
 505		ul = strtoul(cp, &eptr, base);
 506	} else {
 507		uq = strtouq(cp, &eptr, base);
 508	}
 509	if (eptr != cp + len)
 510		lerror("icon() 1");
 511	if (errno != 0)
 512		/* integer constant out of range */
 513		warning(252);
 514
 515	/*
 516	 * If the value is to big for the current type, we must choose
 517	 * another type.
 518	 */
 519	ansiu = 0;
 520	switch (typ) {
 521	case INT:
 522		if (ul <= INT_MAX) {
 523			/* ok */
 524		} else if (ul <= (unsigned)UINT_MAX && base != 10) {
 525			typ = UINT;
 526		} else if (ul <= LONG_MAX) {
 527			typ = LONG;
 528		} else {
 529			typ = ULONG;
 530		}
 531		if (typ == UINT || typ == ULONG) {
 532			if (tflag) {
 533				typ = LONG;
 534			} else if (!sflag) {
 535				/*
 536				 * Remember that the constant is unsigned
 537				 * only in ANSI C
 538				 */
 539				ansiu = 1;
 540			}
 541		}
 542		break;
 543	case UINT:
 544		if (ul > (u_int)UINT_MAX)
 545			typ = ULONG;
 546		break;
 547	case LONG:
 548		if (ul > LONG_MAX && !tflag) {
 549			typ = ULONG;
 550			if (!sflag)
 551				ansiu = 1;
 552		}
 553		break;
 554	case QUAD:
 555		if (uq > QUAD_MAX && !tflag) {
 556			typ = UQUAD;
 557			if (!sflag)
 558				ansiu = 1;
 559		}
 560		break;
 561		/* LINTED (enumeration values not handled in switch) */
 562	case STRUCT:
 563	case VOID:
 564	case LDOUBLE:
 565	case FUNC:
 566	case ARRAY:
 567	case PTR:
 568	case ENUM:
 569	case UNION:
 570	case SIGNED:
 571	case NOTSPEC:
 572	case DOUBLE:
 573	case FLOAT:
 574	case UQUAD:
 575	case ULONG:
 576	case USHORT:
 577	case SHORT:
 578	case UCHAR:
 579	case SCHAR:
 580	case CHAR:
 581	case UNSIGN:
 582		break;
 583	}
 584
 585	if (typ != QUAD && typ != UQUAD) {
 586		if (isutyp(typ)) {
 587			uq = ul;
 588		} else {
 589			uq = (int64_t)(long)ul;
 590		}
 591	}
 592
 593	uq = (uint64_t)xsign((int64_t)uq, typ, -1);
 594
 595	if ((yylval.y_val = calloc(1, sizeof(val_t))) == NULL)
 596		nomem();
 597	yylval.y_val->v_tspec = typ;
 598	yylval.y_val->v_ansiu = ansiu;
 599	yylval.y_val->v_quad = (int64_t)uq;
 600
 601	return (T_CON);
 602}
 603
 604/*
 605 * Returns 1 if t is a signed type and the value is negative.
 606 *
 607 * len is the number of significant bits. If len is -1, len is set
 608 * to the width of type t.
 609 */
 610int
 611sign(int64_t q, tspec_t t, int len)
 612{
 613
 614	if (t == PTR || isutyp(t))
 615		return (0);
 616	return (msb(q, t, len));
 617}
 618
 619int
 620msb(int64_t q, tspec_t t, int len)
 621{
 622
 623	if (len <= 0)
 624		len = size(t);
 625	return ((q & qbmasks[len - 1]) != 0);
 626}
 627
 628/*
 629 * Extends the sign of q.
 630 */
 631int64_t
 632xsign(int64_t q, tspec_t t, int len)
 633{
 634
 635	if (len <= 0)
 636		len = size(t);
 637
 638	if (t == PTR || isutyp(t) || !sign(q, t, len)) {
 639		q &= qlmasks[len];
 640	} else {
 641		q |= qumasks[len];
 642	}
 643	return (q);
 644}
 645
 646/*
 647 * Convert a string representing a floating point value into its interal
 648 * representation. Type and value are returned in yylval. fcon()
 649 * (and yylex()) returns T_CON.
 650 * XXX Currently it is not possible to convert constants of type
 651 * long double which are greater than DBL_MAX.
 652 */
 653static int
 654fcon(void)
 655{
 656	const	char *cp;
 657	int	len;
 658	tspec_t typ;
 659	char	c, *eptr;
 660	double	d;
 661	float	f = 0;
 662
 663	cp = yytext;
 664	len = yyleng;
 665
 666	if ((c = cp[len - 1]) == 'f' || c == 'F') {
 667		typ = FLOAT;
 668		len--;
 669	} else if (c == 'l' || c == 'L') {
 670		typ = LDOUBLE;
 671		len--;
 672	} else {
 673		typ = DOUBLE;
 674	}
 675
 676	if (tflag && typ != DOUBLE) {
 677		/* suffixes F and L are illegal in traditional C */
 678		warning(98);
 679	}
 680
 681	errno = 0;
 682	d = strtod(cp, &eptr);
 683	if (eptr != cp + len)
 684		lerror("fcon() 1");
 685	if (errno != 0)
 686		/* floating-point constant out of range */
 687		warning(248);
 688
 689	if (typ == FLOAT) {
 690		f = (float)d;
 691		if (!finite(f)) {
 692			/* floating-point constant out of range */
 693			warning(248);
 694			f = f > 0 ? FLT_MAX : -FLT_MAX;
 695		}
 696	}
 697
 698	if ((yylval.y_val = calloc(1, sizeof (val_t))) == NULL)
 699		nomem();
 700	yylval.y_val->v_tspec = typ;
 701	if (typ == FLOAT) {
 702		yylval.y_val->v_ldbl = f;
 703	} else {
 704		yylval.y_val->v_ldbl = d;
 705	}
 706
 707	return (T_CON);
 708}
 709
 710static int
 711operator(int t, op_t o)
 712{
 713
 714	yylval.y_op = o;
 715	return (t);
 716}
 717
 718/*
 719 * Called if lex found a leading \'.
 720 */
 721static int
 722ccon(void)
 723{
 724	int	n, val, c;
 725	char	cv;
 726
 727	n = 0;
 728	val = 0;
 729	while ((c = getescc('\'')) >= 0) {
 730		val = (val << CHAR_BIT) + c;
 731		n++;
 732	}
 733	if (c == -2) {
 734		/* unterminated character constant */
 735		error(253);
 736	} else {
 737		if (n > sizeof (int) || (n > 1 && (pflag || hflag))) {
 738			/* too many characters in character constant */
 739			error(71);
 740		} else if (n > 1) {
 741			/* multi-character character constant */
 742			warning(294);
 743		} else if (n == 0) {
 744			/* empty character constant */
 745			error(73);
 746		}
 747	}
 748	if (n == 1) {
 749		cv = (char)val;
 750		val = cv;
 751	}
 752
 753	yylval.y_val = xcalloc(1, sizeof (val_t));
 754	yylval.y_val->v_tspec = INT;
 755	yylval.y_val->v_quad = val;
 756
 757	return (T_CON);
 758}
 759
 760/*
 761 * Called if lex found a leading L\'
 762 */
 763static int
 764wccon(void)
 765{
 766	static	char buf[MB_LEN_MAX + 1];
 767	int	i, c;
 768	wchar_t	wc;
 769
 770	i = 0;
 771	while ((c = getescc('\'')) >= 0) {
 772		if (i < MB_CUR_MAX)
 773			buf[i] = (char)c;
 774		i++;
 775	}
 776
 777	wc = 0;
 778
 779	if (c == -2) {
 780		/* unterminated character constant */
 781		error(253);
 782	} else if (c == 0) {
 783		/* empty character constant */
 784		error(73);
 785	} else {
 786		if (i > MB_CUR_MAX) {
 787			i = MB_CUR_MAX;
 788			/* too many characters in character constant */
 789			error(71);
 790		} else {
 791			buf[i] = '\0';
 792			(void)mbtowc(NULL, NULL, 0);
 793			if (mbtowc(&wc, buf, MB_CUR_MAX) < 0)
 794				/* invalid multibyte character */
 795				error(291);
 796		}
 797	}
 798
 799	if ((yylval.y_val = calloc(1, sizeof (val_t))) == NULL)
 800		nomem();
 801	yylval.y_val->v_tspec = WCHAR;
 802	yylval.y_val->v_quad = wc;
 803
 804	return (T_CON);
 805}
 806
 807/*
 808 * Read a character which is part of a character constant or of a string
 809 * and handle escapes.
 810 *
 811 * The Argument is the character which delimits the character constant or
 812 * string.
 813 *
 814 * Returns -1 if the end of the character constant or string is reached,
 815 * -2 if the EOF is reached, and the character otherwise.
 816 */
 817static int
 818getescc(int d)
 819{
 820	static	int pbc = -1;
 821	int	n, c, v;
 822
 823	if (pbc == -1) {
 824		c = inpc();
 825	} else {
 826		c = pbc;
 827		pbc = -1;
 828	}
 829	if (c == d)
 830		return (-1);
 831	switch (c) {
 832	case '\n':
 833		if (tflag) {
 834			/* newline in string or char constant */
 835			error(254);
 836			return (-2);
 837		}
 838		return (c);
 839	case EOF:
 840		return (-2);
 841	case '\\':
 842		switch (c = inpc()) {
 843		case '"':
 844			if (tflag && d == '\'')
 845				/* \" inside character constant undef. ... */
 846				warning(262);
 847			return ('"');
 848		case '\'':
 849			return ('\'');
 850		case '?':
 851			if (tflag)
 852				/* \? undefined in traditional C */
 853				warning(263);
 854			return ('?');
 855		case '\\':
 856			return ('\\');
 857		case 'a':
 858			if (tflag)
 859				/* \a undefined in traditional C */
 860				warning(81);
 861			return ('\a');
 862		case 'b':
 863			return ('\b');
 864		case 'f':
 865			return ('\f');
 866		case 'n':
 867			return ('\n');
 868		case 'r':
 869			return ('\r');
 870		case 't':
 871			return ('\t');
 872		case 'v':
 873			if (tflag)
 874				/* \v undefined in traditional C */
 875				warning(264);
 876			return ('\v');
 877		case '8': case '9':
 878			/* bad octal digit %c */
 879			warning(77, c);
 880			/* FALLTHROUGH */
 881		case '0': case '1': case '2': case '3':
 882		case '4': case '5': case '6': case '7':
 883			n = 3;
 884			v = 0;
 885			do {
 886				v = (v << 3) + (c - '0');
 887				c = inpc();
 888			} while (--n && isdigit(c) && (tflag || c <= '7'));
 889			if (tflag && n > 0 && isdigit(c))
 890				/* bad octal digit %c */
 891				warning(77, c);
 892			pbc = c;
 893			if (v > UCHAR_MAX) {
 894				/* character escape does not fit in char. */
 895				warning(76);
 896				v &= CHAR_MASK;
 897			}
 898			return (v);
 899		case 'x':
 900			if (tflag)
 901				/* \x undefined in traditional C */
 902				warning(82);
 903			v = 0;
 904			n = 0;
 905			while ((c = inpc()) >= 0 && isxdigit(c)) {
 906				c = isdigit(c) ?
 907					c - '0' : toupper(c) - 'A' + 10;
 908				v = (v << 4) + c;
 909				if (n >= 0) {
 910					if ((v & ~CHAR_MASK) != 0) {
 911						/* overflow in hex escape */
 912						warning(75);
 913						n = -1;
 914					} else {
 915						n++;
 916					}
 917				}
 918			}
 919			pbc = c;
 920			if (n == 0) {
 921				/* no hex digits follow \x */
 922				error(74);
 923			} if (n == -1) {
 924				v &= CHAR_MASK;
 925			}
 926			return (v);
 927		case '\n':
 928			return (getescc(d));
 929		case EOF:
 930			return (-2);
 931		default:
 932			if (isprint(c)) {
 933				/* dubious escape \%c */
 934				warning(79, c);
 935			} else {
 936				/* dubious escape \%o */
 937				warning(80, c);
 938			}
 939		}
 940	}
 941	return (c);
 942}
 943
 944/*
 945 * Called for preprocessor directives. Currently implemented are:
 946 *	# lineno
 947 *	# lineno "filename"
 948 */
 949static void
 950directive(void)
 951{
 952	const	char *cp, *fn;
 953	char	c, *eptr;
 954	size_t	fnl;
 955	long	ln;
 956	static	int first = 1;
 957
 958	/* Go to first non-whitespace after # */
 959	for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++)
 960		continue;
 961
 962	if (!isdigit((unsigned char)c)) {
 963	error:
 964		/* undefined or invalid # directive */
 965		warning(255);
 966		return;
 967	}
 968	ln = strtol(--cp, &eptr, 10);
 969	if (cp == eptr)
 970		goto error;
 971	if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
 972		goto error;
 973	while ((c = *cp++) == ' ' || c == '\t')
 974		continue;
 975	if (c != '\0') {
 976		if (c != '"')
 977			goto error;
 978		fn = cp;
 979		while ((c = *cp) != '"' && c != '\0')
 980			cp++;
 981		if (c != '"')
 982			goto error;
 983		if ((fnl = cp++ - fn) > PATH_MAX)
 984			goto error;
 985		while ((c = *cp++) == ' ' || c == '\t')
 986			continue;
 987#if 0
 988		if (c != '\0')
 989			warning("extra character(s) after directive");
 990#endif
 991
 992		/* empty string means stdin */
 993		if (fnl == 0) {
 994			fn = "{standard input}";
 995			fnl = 16;			/* strlen (fn) */
 996		}
 997		curr_pos.p_file = fnnalloc(fn, fnl);
 998		/*
 999		 * If this is the first directive, the name is the name
1000		 * of the C source file as specified at the command line.
1001		 * It is written to the output file.
1002		 */
1003		if (first) {
1004			csrc_pos.p_file = curr_pos.p_file;
1005			outsrc(curr_pos.p_file);
1006			first = 0;
1007		}
1008	}
1009	curr_pos.p_line = (int)ln - 1;
1010	curr_pos.p_uniq = 0;
1011	if (curr_pos.p_file == csrc_pos.p_file) {
1012		csrc_pos.p_line = (int)ln - 1;
1013		csrc_pos.p_uniq = 0;
1014	}
1015}
1016
1017/*
1018 * Handle lint comments. Following comments are currently understood:
1019 *	ARGSUSEDn
1020 *	BITFIELDTYPE
1021 *	CONSTCOND CONSTANTCOND CONSTANTCONDITION
1022 *	FALLTHRU FALLTHROUGH
1023 *	LINTLIBRARY
1024 *	LINTED NOSTRICT
1025 *	LONGLONG
1026 *	NOTREACHED
1027 *	PRINTFLIKEn
1028 *	PROTOLIB
1029 *	SCANFLIKEn
1030 *	VARARGSn
1031 * If one of this comments is recognized, the arguments, if any, are
1032 * parsed and a function which handles this comment is called.
1033 */
1034static void
1035comment(void)
1036{
1037	int	c, lc;
1038	static struct {
1039		const	char *keywd;
1040		int	arg;
1041		void	(*func)(int);
1042	} keywtab[] = {
1043		{ "ARGSUSED",		1,	argsused	},
1044		{ "BITFIELDTYPE",	0,	bitfieldtype	},
1045		{ "CONSTCOND",		0,	constcond	},
1046		{ "CONSTANTCOND",	0,	constcond	},
1047		{ "CONSTANTCONDITION",	0,	constcond	},
1048		{ "FALLTHRU",		0,	fallthru	},
1049		{ "FALLTHROUGH",	0,	fallthru	},
1050		{ "LINTLIBRARY",	0,	lintlib		},
1051		{ "LINTED",		0,	linted		},
1052		{ "LONGLONG",		0,	longlong	},
1053		{ "NOSTRICT",		0,	linted		},
1054		{ "NOTREACHED",		0,	notreach	},
1055		{ "PRINTFLIKE",		1,	printflike	},
1056		{ "PROTOLIB",		1,	protolib	},
1057		{ "SCANFLIKE",		1,	scanflike	},
1058		{ "VARARGS",		1,	varargs		},
1059	};
1060	char	keywd[32];
1061	char	arg[32];
1062	int	l, i, a;
1063	int	eoc;
1064
1065	eoc = 0;
1066
1067	/* Skip white spaces after the start of the comment */
1068	while ((c = inpc()) != EOF && isspace(c))
1069		continue;
1070
1071	/* Read the potential keyword to keywd */
1072	l = 0;
1073	while (c != EOF && isupper(c) && l < sizeof (keywd) - 1) {
1074		keywd[l++] = (char)c;
1075		c = inpc();
1076	}
1077	keywd[l] = '\0';
1078
1079	/* look for the keyword */
1080	for (i = 0; i < sizeof (keywtab) / sizeof (keywtab[0]); i++) {
1081		if (strcmp(keywtab[i].keywd, keywd) == 0)
1082			break;
1083	}
1084	if (i == sizeof (keywtab) / sizeof (keywtab[0]))
1085		goto skip_rest;
1086
1087	/* skip white spaces after the keyword */
1088	while (c != EOF && isspace(c))
1089		c = inpc();
1090
1091	/* read the argument, if the keyword accepts one and there is one */
1092	l = 0;
1093	if (keywtab[i].arg) {
1094		while (c != EOF && isdigit(c) && l < sizeof (arg) - 1) {
1095			arg[l++] = (char)c;
1096			c = inpc();
1097		}
1098	}
1099	arg[l] = '\0';
1100	a = l != 0 ? atoi(arg) : -1;
1101
1102	/* skip white spaces after the argument */
1103	while (c != EOF && isspace(c))
1104		c = inpc();
1105
1106	if (c != '*' || (c = inpc()) != '/') {
1107		if (keywtab[i].func != linted)
1108			/* extra characters in lint comment */
1109			warning(257);
1110	} else {
1111		/*
1112		 * remember that we have already found the end of the
1113		 * comment
1114		 */
1115		eoc = 1;
1116	}
1117
1118	if (keywtab[i].func != NULL)
1119		(*keywtab[i].func)(a);
1120
1121 skip_rest:
1122	while (!eoc) {
1123		lc = c;
1124		if ((c = inpc()) == EOF) {
1125			/* unterminated comment */
1126			error(256);
1127			break;
1128		}
1129		if (lc == '*' && c == '/')
1130			eoc = 1;
1131	}
1132}
1133
1134/*
1135 * Handle // style comments
1136 */
1137static void
1138slashslashcomment(void)
1139{
1140	int c;
1141
1142	if (sflag < 2 && !gflag)
1143		/* // comments only supported in C99 */
1144		(void)gnuism(312, tflag ? "traditional" : "ANSI");
1145
1146	while ((c = inpc()) != EOF && c != '\n')
1147		continue;
1148}
1149
1150/*
1151 * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
1152 * clrwflgs() is called after function definitions and global and
1153 * local declarations and definitions. It is also called between
1154 * the controlling expression and the body of control statements
1155 * (if, switch, for, while).
1156 */
1157void
1158clrwflgs(void)
1159{
1160
1161	nowarn = 0;
1162	quadflg = 0;
1163	ccflg = 0;
1164}
1165
1166/*
1167 * Strings are stored in a dynamically alloceted buffer and passed
1168 * in yylval.y_xstrg to the parser. The parser or the routines called
1169 * by the parser are responsible for freeing this buffer.
1170 */
1171static int
1172string(void)
1173{
1174	u_char	*s;
1175	int	c;
1176	size_t	len, max;
1177	strg_t	*strg;
1178
1179	if ((s = malloc(max = 64)) == NULL)
1180		nomem();
1181
1182	len = 0;
1183	while ((c = getescc('"')) >= 0) {
1184		/* +1 to reserve space for a trailing NUL character */
1185		if (len + 1 == max)
1186			if ((s = realloc(s, max *= 2)) == NULL)
1187				nomem();
1188		s[len++] = (char)c;
1189	}
1190	s[len] = '\0';
1191	if (c == -2)
1192		/* unterminated string constant */
1193		error(258);
1194
1195	if ((strg = calloc(1, sizeof (strg_t))) == NULL)
1196		nomem();
1197	strg->st_tspec = CHAR;
1198	strg->st_len = len;
1199	strg->st_cp = s;
1200
1201	yylval.y_strg = strg;
1202	return (T_STRING);
1203}
1204
1205static int
1206wcstrg(void)
1207{
1208	char	*s;
1209	int	c, i, n, wi;
1210	size_t	len, max, wlen;
1211	wchar_t	*ws;
1212	strg_t	*strg;
1213
1214	if ((s = malloc(max = 64)) == NULL)
1215		nomem();
1216	len = 0;
1217	while ((c = getescc('"')) >= 0) {
1218		/* +1 to save space for a trailing NUL character */
1219		if (len + 1 >= max)
1220			if ((s = realloc(s, max *= 2)) == NULL)
1221				nomem();
1222		s[len++] = (char)c;
1223	}
1224	s[len] = '\0';
1225	if (c == -2)
1226		/* unterminated string constant */
1227		error(258);
1228
1229	/* get length of wide character string */
1230	(void)mblen(NULL, 0);
1231	for (i = 0, wlen = 0; i < len; i += n, wlen++) {
1232		if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
1233			/* invalid multibyte character */
1234			error(291);
1235			break;
1236		}
1237		if (n == 0)
1238			n = 1;
1239	}
1240
1241	if ((ws = malloc((wlen + 1) * sizeof (wchar_t))) == NULL)
1242		nomem();
1243
1244	/* convert from multibyte to wide char */
1245	(void)mbtowc(NULL, NULL, 0);
1246	for (i = 0, wi = 0; i < len; i += n, wi++) {
1247		if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
1248			break;
1249		if (n == 0)
1250			n = 1;
1251	}
1252	ws[wi] = 0;
1253	free(s);
1254
1255	if ((strg = calloc(1, sizeof (strg_t))) == NULL)
1256		nomem();
1257	strg->st_tspec = WCHAR;
1258	strg->st_len = wlen;
1259	strg->st_wcp = ws;
1260
1261	yylval.y_strg = strg;
1262	return (T_STRING);
1263}
1264
1265/*
1266 * As noted above the scanner does not create new symbol table entries
1267 * for symbols it cannot find in the symbol table. This is to avoid
1268 * putting undeclared symbols into the symbol table if a syntax error
1269 * occurs.
1270 *
1271 * getsym() is called as soon as it is probably ok to put the symbol to
1272 * the symbol table. This does not mean that it is not possible that
1273 * symbols are put to the symbol table which are than not completely
1274 * declared due to syntax errors. To avoid too many problems in this
1275 * case symbols get type int in getsym().
1276 *
1277 * XXX calls to getsym() should be delayed until decl1*() is called
1278 */
1279sym_t *
1280getsym(sbuf_t *sb)
1281{
1282	dinfo_t	*di;
1283	char	*s;
1284	sym_t	*sym;
1285
1286	sym = sb->sb_sym;
1287
1288	/*
1289	 * During member declaration it is possible that name() looked
1290	 * for symbols of type FVFT, although it should have looked for
1291	 * symbols of type FTAG. Same can happen for labels. Both cases
1292	 * are compensated here.
1293	 */
1294	if (symtyp == FMOS || symtyp == FLAB) {
1295		if (sym == NULL || sym->s_kind == FVFT)
1296			sym = search(sb);
1297	}
1298
1299	if (sym != NULL) {
1300		if (sym->s_kind != symtyp)
1301			lerror("storesym() 1");
1302		symtyp = FVFT;
1303		freesb(sb);
1304		return (sym);
1305	}
1306
1307	/* create a new symbol table entry */
1308
1309	/* labels must always be allocated at level 1 (outhermost block) */
1310	if (symtyp == FLAB) {
1311		sym = getlblk(1, sizeof (sym_t));
1312		s = getlblk(1, sb->sb_len + 1);
1313		(void)memcpy(s, sb->sb_name, sb->sb_len + 1);
1314		sym->s_name = s;
1315		sym->s_blklev = 1;
1316		di = dcs;
1317		while (di->d_nxt != NULL && di->d_nxt->d_nxt != NULL)
1318			di = di->d_nxt;
1319		if (di->d_ctx != AUTO)
1320			lerror("storesym() 2");
1321	} else {
1322		sym = getblk(sizeof (sym_t));
1323		sym->s_name = sb->sb_name;
1324		sym->s_blklev = blklev;
1325		di = dcs;
1326	}
1327
1328	UNIQUE_CURR_POS(sym->s_dpos);
1329	if ((sym->s_kind = symtyp) != FLAB)
1330		sym->s_type = gettyp(INT);
1331
1332	symtyp = FVFT;
1333
1334	if ((sym->s_link = symtab[sb->sb_hash]) != NULL)
1335		symtab[sb->sb_hash]->s_rlink = &sym->s_link;
1336	(symtab[sb->sb_hash] = sym)->s_rlink = &symtab[sb->sb_hash];
1337
1338	*di->d_ldlsym = sym;
1339	di->d_ldlsym = &sym->s_dlnxt;
1340
1341	freesb(sb);
1342	return (sym);
1343}
1344
1345/*
1346 * Remove a symbol forever from the symbol table. s_blklev
1347 * is set to -1 to avoid that the symbol will later be put
1348 * back to the symbol table.
1349 */
1350void
1351rmsym(sym_t *sym)
1352{
1353
1354	if ((*sym->s_rlink = sym->s_link) != NULL)
1355		sym->s_link->s_rlink = sym->s_rlink;
1356	sym->s_blklev = -1;
1357	sym->s_link = NULL;
1358}
1359
1360/*
1361 * Remove a list of symbols declared at one level from the symbol
1362 * table.
1363 */
1364void
1365rmsyms(sym_t *syms)
1366{
1367	sym_t	*sym;
1368
1369	for (sym = syms; sym != NULL; sym = sym->s_dlnxt) {
1370		if (sym->s_blklev != -1) {
1371			if ((*sym->s_rlink = sym->s_link) != NULL)
1372				sym->s_link->s_rlink = sym->s_rlink;
1373			sym->s_link = NULL;
1374			sym->s_rlink = NULL;
1375		}
1376	}
1377}
1378
1379/*
1380 * Put a symbol into the symbol table
1381 */
1382void
1383inssym(int bl, sym_t *sym)
1384{
1385	int	h;
1386
1387	h = hash(sym->s_name);
1388	if ((sym->s_link = symtab[h]) != NULL)
1389		symtab[h]->s_rlink = &sym->s_link;
1390	(symtab[h] = sym)->s_rlink = &symtab[h];
1391	sym->s_blklev = bl;
1392	if (sym->s_link != NULL && sym->s_blklev < sym->s_link->s_blklev)
1393		lerror("inssym()");
1394}
1395
1396/*
1397 * Called at level 0 after syntax errors
1398 * Removes all symbols which are not declared at level 0 from the
1399 * symbol table. Also frees all memory which is not associated with
1400 * level 0.
1401 */
1402void
1403cleanup(void)
1404{
1405	sym_t	*sym, *nsym;
1406	int	i;
1407
1408	for (i = 0; i < HSHSIZ1; i++) {
1409		for (sym = symtab[i]; sym != NULL; sym = nsym) {
1410			nsym = sym->s_link;
1411			if (sym->s_blklev >= 1) {
1412				if ((*sym->s_rlink = nsym) != NULL)
1413					nsym->s_rlink = sym->s_rlink;
1414			}
1415		}
1416	}
1417
1418	for (i = mblklev; i > 0; i--)
1419		freelblk(i);
1420}
1421
1422/*
1423 * Create a new symbol with the name of an existing symbol.
1424 */
1425sym_t *
1426pushdown(sym_t *sym)
1427{
1428	int	h;
1429	sym_t	*nsym;
1430
1431	h = hash(sym->s_name);
1432	nsym = getblk(sizeof (sym_t));
1433	if (sym->s_blklev > blklev)
1434		lerror("pushdown()");
1435	nsym->s_name = sym->s_name;
1436	UNIQUE_CURR_POS(nsym->s_dpos);
1437	nsym->s_kind = sym->s_kind;
1438	nsym->s_blklev = blklev;
1439
1440	if ((nsym->s_link = symtab[h]) != NULL)
1441		symtab[h]->s_rlink = &nsym->s_link;
1442	(symtab[h] = nsym)->s_rlink = &symtab[h];
1443
1444	*dcs->d_ldlsym = nsym;
1445	dcs->d_ldlsym = &nsym->s_dlnxt;
1446
1447	return (nsym);
1448}
1449
1450/*
1451 * Free any dynamically allocated memory referenced by
1452 * the value stack or yylval.
1453 * The type of information in yylval is described by tok.
1454 */
1455void
1456freeyyv(void *sp, int tok)
1457{
1458	if (tok == T_NAME || tok == T_TYPENAME) {
1459		sbuf_t *sb = *(sbuf_t **)sp;
1460		freesb(sb);
1461	} else if (tok == T_CON) {
1462		val_t *val = *(val_t **)sp;
1463		free(val);
1464	} else if (tok == T_STRING) {
1465		strg_t *strg = *(strg_t **)sp;
1466		if (strg->st_tspec == CHAR) {
1467			free(strg->st_cp);
1468		} else if (strg->st_tspec == WCHAR) {
1469			free(strg->st_wcp);
1470		} else {
1471			lerror("fryylv() 1");
1472		}
1473		free(strg);
1474	}
1475}