1 1.93 rillig /* $NetBSD: read.c,v 1.93 2024/11/30 18:17:12 rillig Exp $ */ 2 1.2 cgd 3 1.1 cgd /* 4 1.3 cgd * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 5 1.1 cgd * Copyright (c) 1994, 1995 Jochen Pohl 6 1.1 cgd * All Rights Reserved. 7 1.1 cgd * 8 1.1 cgd * Redistribution and use in source and binary forms, with or without 9 1.1 cgd * modification, are permitted provided that the following conditions 10 1.1 cgd * are met: 11 1.1 cgd * 1. Redistributions of source code must retain the above copyright 12 1.1 cgd * notice, this list of conditions and the following disclaimer. 13 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 cgd * notice, this list of conditions and the following disclaimer in the 15 1.1 cgd * documentation and/or other materials provided with the distribution. 16 1.1 cgd * 3. All advertising materials mentioning features or use of this software 17 1.1 cgd * must display the following acknowledgement: 18 1.87 rillig * This product includes software developed by Jochen Pohl for 19 1.1 cgd * The NetBSD Project. 20 1.1 cgd * 4. The name of the author may not be used to endorse or promote products 21 1.1 cgd * derived from this software without specific prior written permission. 22 1.1 cgd * 23 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 1.1 cgd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 1.1 cgd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 1.1 cgd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 1.1 cgd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 1.1 cgd * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 1.1 cgd * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 1.1 cgd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 1.1 cgd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 1.1 cgd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 cgd */ 34 1.1 cgd 35 1.14 jmc #if HAVE_NBTOOL_CONFIG_H 36 1.14 jmc #include "nbtool_config.h" 37 1.14 jmc #endif 38 1.14 jmc 39 1.5 christos #include <sys/cdefs.h> 40 1.76 rillig #if defined(__RCSID) 41 1.93 rillig __RCSID("$NetBSD: read.c,v 1.93 2024/11/30 18:17:12 rillig Exp $"); 42 1.1 cgd #endif 43 1.1 cgd 44 1.12 tv #include <ctype.h> 45 1.12 tv #include <limits.h> 46 1.29 rillig #include <stdarg.h> 47 1.1 cgd #include <stdio.h> 48 1.1 cgd #include <stdlib.h> 49 1.1 cgd #include <string.h> 50 1.1 cgd 51 1.1 cgd #include "lint2.h" 52 1.1 cgd 53 1.1 cgd 54 1.1 cgd /* index of current (included) source file */ 55 1.90 rillig static int srcfile; 56 1.1 cgd 57 1.1 cgd /* 58 1.1 cgd * The array pointed to by inpfns maps the file name indices of input files 59 1.1 cgd * to the file name indices used in lint2 60 1.1 cgd */ 61 1.90 rillig static short *inpfns; 62 1.90 rillig static size_t ninpfns; 63 1.1 cgd 64 1.1 cgd /* 65 1.36 rillig * The array pointed to by *fnames maps file name indices to file names. 66 1.1 cgd * Indices of type short are used instead of pointers to save memory. 67 1.1 cgd */ 68 1.90 rillig const char **fnames; 69 1.90 rillig static size_t *flines; 70 1.90 rillig static size_t nfnames; 71 1.1 cgd 72 1.1 cgd /* 73 1.1 cgd * Types are shared (to save memory for the types itself) and accessed 74 1.1 cgd * via indices (to save memory for references to types (indices are short)). 75 1.67 rillig * To share types, an equal type must be located fast. This is done by a 76 1.1 cgd * hash table. Access by indices is done via an array of pointers to the 77 1.1 cgd * types. 78 1.1 cgd */ 79 1.1 cgd typedef struct thtab { 80 1.56 rillig const char *th_name; 81 1.56 rillig unsigned short th_idx; 82 1.56 rillig struct thtab *th_next; 83 1.1 cgd } thtab_t; 84 1.90 rillig static thtab_t *thtab[1009]; /* hash table */ 85 1.90 rillig type_t **tlst; /* array for indexed access */ 86 1.90 rillig static size_t tlstlen; /* length of tlst */ 87 1.1 cgd 88 1.90 rillig static hte_t **renametab; 89 1.4 cgd 90 1.36 rillig /* index of current C source file (as specified at the command line) */ 91 1.90 rillig static int csrcfile; 92 1.1 cgd 93 1.90 rillig static const char *readfile_line; 94 1.1 cgd 95 1.90 rillig static void inperr(const char *, ...) 96 1.79 rillig __printflike(1, 2) __attribute__((noreturn)); 97 1.90 rillig static void setsrc(const char *); 98 1.90 rillig static void setfnid(int, const char *); 99 1.90 rillig static void funccall(pos_t, const char *); 100 1.90 rillig static void decldef(pos_t, const char *); 101 1.90 rillig static void usedsym(pos_t, const char *); 102 1.90 rillig static unsigned short inptype(const char *, const char **); 103 1.90 rillig static size_t gettlen(const char *, const char **); 104 1.90 rillig static unsigned short findtype(const char *, size_t, int); 105 1.90 rillig static unsigned short storetyp(type_t *, const char *, size_t, int); 106 1.90 rillig static unsigned int thash(const char *, size_t); 107 1.90 rillig static char *inpqstrg(const char *, const char **); 108 1.90 rillig static const char *inpname(const char *, const char **); 109 1.90 rillig static int getfnidx(const char *); 110 1.1 cgd 111 1.77 rillig /* Allocate zero-initialized memory that doesn't need to be freed. */ 112 1.77 rillig static void * 113 1.77 rillig xalloc(size_t sz) 114 1.77 rillig { 115 1.77 rillig 116 1.77 rillig void *ptr = xmalloc(sz); 117 1.77 rillig (void)memset(ptr, 0, sz); 118 1.77 rillig return ptr; 119 1.77 rillig } 120 1.77 rillig 121 1.44 rillig static bool 122 1.44 rillig try_parse_int(const char **p, int *num) 123 1.44 rillig { 124 1.44 rillig char *end; 125 1.44 rillig 126 1.44 rillig *num = (int)strtol(*p, &end, 10); 127 1.44 rillig if (end == *p) 128 1.44 rillig return false; 129 1.44 rillig *p = end; 130 1.44 rillig return true; 131 1.44 rillig } 132 1.44 rillig 133 1.44 rillig static int 134 1.44 rillig parse_int(const char **p) 135 1.44 rillig { 136 1.44 rillig char *end; 137 1.44 rillig int n; 138 1.44 rillig 139 1.44 rillig n = (int)strtol(*p, &end, 10); 140 1.44 rillig if (end == *p) 141 1.44 rillig inperr("not a number: %s", *p); 142 1.44 rillig *p = end; 143 1.44 rillig return n; 144 1.44 rillig } 145 1.44 rillig 146 1.44 rillig static short 147 1.44 rillig parse_short(const char **p) 148 1.44 rillig { 149 1.61 rillig return (short)parse_int(p); 150 1.44 rillig } 151 1.44 rillig 152 1.66 rillig static void 153 1.73 rillig read_ln_line(const char *line) 154 1.66 rillig { 155 1.66 rillig const char *cp; 156 1.66 rillig int cline, isrc, iline; 157 1.66 rillig char rt; 158 1.66 rillig pos_t pos; 159 1.66 rillig 160 1.66 rillig cp = line; 161 1.66 rillig 162 1.66 rillig /* line number in csrcfile */ 163 1.66 rillig if (!try_parse_int(&cp, &cline)) 164 1.66 rillig cline = -1; 165 1.66 rillig 166 1.66 rillig /* record type */ 167 1.66 rillig if (*cp == '\0') 168 1.66 rillig inperr("missing record type"); 169 1.66 rillig rt = *cp++; 170 1.66 rillig 171 1.66 rillig if (rt == 'S') { 172 1.66 rillig setsrc(cp); 173 1.66 rillig return; 174 1.66 rillig } 175 1.66 rillig if (rt == 's') { 176 1.66 rillig setfnid(cline, cp); 177 1.66 rillig return; 178 1.66 rillig } 179 1.66 rillig 180 1.66 rillig /* 181 1.89 rillig * Index of (included) source file. If this index is different from 182 1.89 rillig * csrcfile, it refers to an included file. 183 1.66 rillig */ 184 1.66 rillig isrc = parse_int(&cp); 185 1.66 rillig isrc = inpfns[isrc]; 186 1.66 rillig 187 1.66 rillig /* line number in isrc */ 188 1.66 rillig if (*cp++ != '.') 189 1.66 rillig inperr("bad line number"); 190 1.66 rillig iline = parse_int(&cp); 191 1.66 rillig 192 1.66 rillig pos.p_src = (unsigned short)csrcfile; 193 1.66 rillig pos.p_line = (unsigned short)cline; 194 1.66 rillig pos.p_isrc = (unsigned short)isrc; 195 1.66 rillig pos.p_iline = (unsigned short)iline; 196 1.66 rillig 197 1.66 rillig /* process rest of this record */ 198 1.66 rillig switch (rt) { 199 1.66 rillig case 'c': 200 1.74 rillig funccall(pos, cp); 201 1.66 rillig break; 202 1.66 rillig case 'd': 203 1.74 rillig decldef(pos, cp); 204 1.66 rillig break; 205 1.66 rillig case 'u': 206 1.74 rillig usedsym(pos, cp); 207 1.66 rillig break; 208 1.66 rillig default: 209 1.66 rillig inperr("bad record type %c", rt); 210 1.66 rillig } 211 1.66 rillig } 212 1.66 rillig 213 1.1 cgd void 214 1.9 lukem readfile(const char *name) 215 1.1 cgd { 216 1.81 rillig FILE *inp; 217 1.81 rillig size_t len; 218 1.81 rillig char *line; 219 1.1 cgd 220 1.1 cgd if (inpfns == NULL) 221 1.42 rillig inpfns = xcalloc(ninpfns = 128, sizeof(*inpfns)); 222 1.1 cgd if (fnames == NULL) 223 1.42 rillig fnames = xcalloc(nfnames = 256, sizeof(*fnames)); 224 1.20 christos if (flines == NULL) 225 1.42 rillig flines = xcalloc(nfnames, sizeof(*flines)); 226 1.1 cgd if (tlstlen == 0) 227 1.42 rillig tlst = xcalloc(tlstlen = 256, sizeof(*tlst)); 228 1.1 cgd 229 1.68 rillig renametab = htab_new(); 230 1.4 cgd 231 1.1 cgd srcfile = getfnidx(name); 232 1.1 cgd 233 1.1 cgd if ((inp = fopen(name, "r")) == NULL) 234 1.1 cgd err(1, "cannot open %s", name); 235 1.1 cgd 236 1.70 rillig while ((line = fgetln(inp, &len)) != NULL) { 237 1.72 rillig flines[srcfile]++; 238 1.72 rillig 239 1.71 rillig readfile_line = line; 240 1.70 rillig if (len == 0 || line[len - 1] != '\n') 241 1.72 rillig inperr("missing newline after '%s'", &line[len - 1]); 242 1.70 rillig line[len - 1] = '\0'; 243 1.70 rillig 244 1.73 rillig read_ln_line(line); 245 1.71 rillig readfile_line = NULL; 246 1.70 rillig } 247 1.1 cgd 248 1.85 rillig hash_free(renametab); 249 1.4 cgd 250 1.37 rillig if (ferror(inp) != 0) 251 1.1 cgd err(1, "read error on %s", name); 252 1.1 cgd 253 1.1 cgd (void)fclose(inp); 254 1.1 cgd } 255 1.1 cgd 256 1.1 cgd 257 1.67 rillig static void 258 1.67 rillig inperr(const char *fmt, ...) 259 1.1 cgd { 260 1.20 christos va_list ap; 261 1.20 christos char buf[1024]; 262 1.9 lukem 263 1.20 christos va_start(ap, fmt); 264 1.42 rillig (void)vsnprintf(buf, sizeof(buf), fmt, ap); 265 1.20 christos va_end(ap); 266 1.20 christos 267 1.71 rillig errx(1, "error: %s:%zu: %s (for '%s')", 268 1.71 rillig fnames[srcfile], flines[srcfile], buf, readfile_line); 269 1.1 cgd } 270 1.1 cgd 271 1.1 cgd /* 272 1.1 cgd * Set the name of the C source file of the .ln file which is 273 1.1 cgd * currently read. 274 1.1 cgd */ 275 1.1 cgd static void 276 1.9 lukem setsrc(const char *cp) 277 1.1 cgd { 278 1.9 lukem 279 1.1 cgd csrcfile = getfnidx(cp); 280 1.1 cgd } 281 1.1 cgd 282 1.1 cgd /* 283 1.1 cgd * setfnid() gets as input an index as used in an input file and the 284 1.10 wiz * associated file name. If necessary, it creates a new lint2 file 285 1.1 cgd * name index for this file name and creates the mapping of the index 286 1.1 cgd * as used in the input file to the index used in lint2. 287 1.1 cgd */ 288 1.1 cgd static void 289 1.9 lukem setfnid(int fid, const char *cp) 290 1.1 cgd { 291 1.9 lukem 292 1.25 christos if (fid < 0) 293 1.20 christos inperr("bad fid"); 294 1.1 cgd 295 1.25 christos if ((size_t)fid >= ninpfns) { 296 1.42 rillig inpfns = xrealloc(inpfns, (ninpfns * 2) * sizeof(*inpfns)); 297 1.42 rillig (void)memset(inpfns + ninpfns, 0, ninpfns * sizeof(*inpfns)); 298 1.1 cgd ninpfns *= 2; 299 1.1 cgd } 300 1.1 cgd /* 301 1.89 rillig * Should always be true because indices written in the output file by 302 1.89 rillig * lint1 are always the previous index + 1. 303 1.1 cgd */ 304 1.25 christos if ((size_t)fid >= ninpfns) 305 1.78 rillig errx(1, "internal error: setfnid"); 306 1.56 rillig inpfns[fid] = (unsigned short)getfnidx(cp); 307 1.1 cgd } 308 1.1 cgd 309 1.1 cgd /* 310 1.1 cgd * Process a function call record (c-record). 311 1.1 cgd */ 312 1.1 cgd static void 313 1.74 rillig funccall(pos_t pos, const char *cp) 314 1.1 cgd { 315 1.1 cgd arginf_t *ai, **lai; 316 1.81 rillig char c; 317 1.81 rillig bool rused, rdisc; 318 1.81 rillig hte_t *hte; 319 1.81 rillig fcall_t *fcall; 320 1.4 cgd const char *name; 321 1.1 cgd 322 1.42 rillig fcall = xalloc(sizeof(*fcall)); 323 1.74 rillig fcall->f_pos = pos; 324 1.1 cgd 325 1.1 cgd /* read flags */ 326 1.37 rillig rused = rdisc = false; 327 1.1 cgd lai = &fcall->f_args; 328 1.64 rillig 329 1.64 rillig again: 330 1.64 rillig c = *cp++; 331 1.64 rillig switch (c) { 332 1.64 rillig case 'u': 333 1.64 rillig if (rused || rdisc) 334 1.64 rillig inperr("used or discovered: %c", c); 335 1.64 rillig rused = true; 336 1.64 rillig goto again; 337 1.64 rillig case 'i': 338 1.64 rillig if (rused || rdisc) 339 1.64 rillig inperr("used or discovered: %c", c); 340 1.64 rillig goto again; 341 1.64 rillig case 'd': 342 1.64 rillig if (rused || rdisc) 343 1.64 rillig inperr("used or discovered: %c", c); 344 1.64 rillig rdisc = true; 345 1.64 rillig goto again; 346 1.64 rillig case 'z': 347 1.64 rillig case 'p': 348 1.64 rillig case 'n': 349 1.64 rillig case 's': 350 1.64 rillig ai = xalloc(sizeof(*ai)); 351 1.64 rillig ai->a_num = parse_int(&cp); 352 1.75 rillig if (c == 'z') 353 1.64 rillig ai->a_pcon = ai->a_zero = true; 354 1.75 rillig else if (c == 'p') 355 1.64 rillig ai->a_pcon = true; 356 1.75 rillig else if (c == 'n') 357 1.64 rillig ai->a_ncon = true; 358 1.75 rillig else { 359 1.64 rillig ai->a_fmt = true; 360 1.64 rillig ai->a_fstrg = inpqstrg(cp, &cp); 361 1.1 cgd } 362 1.64 rillig *lai = ai; 363 1.64 rillig lai = &ai->a_next; 364 1.64 rillig goto again; 365 1.64 rillig default: 366 1.64 rillig cp--; 367 1.1 cgd } 368 1.64 rillig 369 1.1 cgd fcall->f_rused = rused; 370 1.1 cgd fcall->f_rdisc = rdisc; 371 1.1 cgd 372 1.1 cgd /* read name of function */ 373 1.4 cgd name = inpname(cp, &cp); 374 1.4 cgd 375 1.4 cgd /* first look it up in the renaming table, then in the normal table */ 376 1.85 rillig hte = hash_search(renametab, name, false); 377 1.4 cgd if (hte != NULL) 378 1.4 cgd hte = hte->h_hte; 379 1.4 cgd else 380 1.85 rillig hte = htab_search(name, true); 381 1.37 rillig hte->h_used = true; 382 1.1 cgd 383 1.1 cgd fcall->f_type = inptype(cp, &cp); 384 1.1 cgd 385 1.1 cgd *hte->h_lcall = fcall; 386 1.33 rillig hte->h_lcall = &fcall->f_next; 387 1.1 cgd 388 1.1 cgd if (*cp != '\0') 389 1.20 christos inperr("trailing line data: %s", cp); 390 1.1 cgd } 391 1.1 cgd 392 1.63 rillig static bool 393 1.63 rillig parse_function_attribute(const char **pp, sym_t *sym, bool *used) 394 1.63 rillig { 395 1.63 rillig 396 1.63 rillig switch (*(*pp)++) { 397 1.63 rillig case 'd': 398 1.63 rillig if (sym->s_def != NODECL) 399 1.63 rillig inperr("def"); 400 1.63 rillig sym->s_def = DEF; 401 1.63 rillig break; 402 1.63 rillig case 'e': 403 1.63 rillig if (sym->s_def != NODECL) 404 1.63 rillig inperr("decl"); 405 1.63 rillig sym->s_def = DECL; 406 1.63 rillig break; 407 1.63 rillig case 'i': 408 1.63 rillig if (sym->s_inline) 409 1.63 rillig inperr("inline"); 410 1.63 rillig sym->s_inline = true; 411 1.63 rillig break; 412 1.63 rillig case 'o': 413 1.63 rillig if (sym->s_old_style_function) 414 1.63 rillig inperr("osdef"); 415 1.63 rillig sym->s_old_style_function = true; 416 1.63 rillig break; 417 1.63 rillig case 'r': 418 1.63 rillig if (sym->s_function_has_return_value) 419 1.63 rillig inperr("r"); 420 1.63 rillig sym->s_function_has_return_value = true; 421 1.63 rillig break; 422 1.63 rillig case 's': 423 1.63 rillig if (sym->s_static) 424 1.63 rillig inperr("static"); 425 1.63 rillig sym->s_static = true; 426 1.63 rillig break; 427 1.63 rillig case 't': 428 1.63 rillig if (sym->s_def != NODECL) 429 1.63 rillig inperr("tdef"); 430 1.63 rillig sym->s_def = TDEF; 431 1.63 rillig break; 432 1.63 rillig case 'u': 433 1.63 rillig if (*used) 434 1.63 rillig inperr("used"); 435 1.63 rillig *used = true; 436 1.63 rillig break; 437 1.63 rillig case 'v': 438 1.63 rillig if (sym->s_check_only_first_args) 439 1.63 rillig inperr("v"); 440 1.63 rillig sym->s_check_only_first_args = true; 441 1.63 rillig sym->s_check_num_args = parse_short(pp); 442 1.63 rillig break; 443 1.63 rillig case 'P': 444 1.63 rillig if (sym->s_printflike) 445 1.63 rillig inperr("P"); 446 1.63 rillig sym->s_printflike = true; 447 1.63 rillig sym->s_printflike_arg = parse_short(pp); 448 1.63 rillig break; 449 1.63 rillig case 'S': 450 1.63 rillig if (sym->s_scanflike) 451 1.63 rillig inperr("S"); 452 1.63 rillig sym->s_scanflike = true; 453 1.63 rillig sym->s_scanflike_arg = parse_short(pp); 454 1.63 rillig break; 455 1.63 rillig default: 456 1.63 rillig (*pp)--; 457 1.63 rillig return false; 458 1.63 rillig } 459 1.63 rillig return true; 460 1.63 rillig } 461 1.63 rillig 462 1.1 cgd /* 463 1.1 cgd * Process a declaration or definition (d-record). 464 1.1 cgd */ 465 1.1 cgd static void 466 1.74 rillig decldef(pos_t pos, const char *cp) 467 1.1 cgd { 468 1.81 rillig sym_t *symp, sym; 469 1.86 rillig char *tname; 470 1.81 rillig bool used, renamed; 471 1.81 rillig hte_t *hte, *renamehte = NULL; 472 1.24 lukem const char *name, *newname; 473 1.1 cgd 474 1.42 rillig (void)memset(&sym, 0, sizeof(sym)); 475 1.74 rillig sym.s_pos = pos; 476 1.1 cgd sym.s_def = NODECL; 477 1.1 cgd 478 1.37 rillig used = false; 479 1.1 cgd 480 1.63 rillig while (parse_function_attribute(&cp, &sym, &used)) 481 1.63 rillig continue; 482 1.1 cgd 483 1.4 cgd /* read symbol name, doing renaming if necessary */ 484 1.4 cgd name = inpname(cp, &cp); 485 1.37 rillig renamed = false; 486 1.4 cgd if (*cp == 'r') { 487 1.4 cgd cp++; 488 1.24 lukem tname = xstrdup(name); 489 1.24 lukem newname = inpname(cp, &cp); 490 1.4 cgd 491 1.4 cgd /* enter it and see if it's already been renamed */ 492 1.85 rillig renamehte = hash_search(renametab, tname, true); 493 1.4 cgd if (renamehte->h_hte == NULL) { 494 1.85 rillig hte = htab_search(newname, true); 495 1.4 cgd renamehte->h_hte = hte; 496 1.37 rillig renamed = true; 497 1.37 rillig } else if (hte = renamehte->h_hte, 498 1.37 rillig strcmp(hte->h_name, newname) != 0) { 499 1.93 rillig /* %s is renamed multiple times in %s and %s */ 500 1.86 rillig msg(18, tname, mkpos(&renamehte->h_syms->s_pos), 501 1.86 rillig mkpos(&sym.s_pos)); 502 1.4 cgd } 503 1.24 lukem free(tname); 504 1.4 cgd } else { 505 1.4 cgd /* it might be a previously-done rename */ 506 1.85 rillig hte = hash_search(renametab, name, false); 507 1.4 cgd if (hte != NULL) 508 1.4 cgd hte = hte->h_hte; 509 1.4 cgd else 510 1.85 rillig hte = htab_search(name, true); 511 1.4 cgd } 512 1.1 cgd hte->h_used |= used; 513 1.1 cgd if (sym.s_def == DEF || sym.s_def == TDEF) 514 1.37 rillig hte->h_def = true; 515 1.1 cgd 516 1.1 cgd sym.s_type = inptype(cp, &cp); 517 1.1 cgd 518 1.1 cgd /* 519 1.89 rillig * Allocate memory for this symbol only if it was not already declared 520 1.89 rillig * or tentatively defined at the same location with the same type. 521 1.89 rillig * Works only for symbols with external linkage, because static 522 1.89 rillig * symbols, tentatively defined at the same location but in different 523 1.89 rillig * translation units are really different symbols. 524 1.1 cgd */ 525 1.32 rillig for (symp = hte->h_syms; symp != NULL; symp = symp->s_next) { 526 1.1 cgd if (symp->s_pos.p_isrc == sym.s_pos.p_isrc && 527 1.1 cgd symp->s_pos.p_iline == sym.s_pos.p_iline && 528 1.1 cgd symp->s_type == sym.s_type && 529 1.1 cgd ((symp->s_def == DECL && sym.s_def == DECL) || 530 1.1 cgd (!sflag && symp->s_def == TDEF && sym.s_def == TDEF)) && 531 1.75 rillig !symp->s_static && !sym.s_static) 532 1.1 cgd break; 533 1.1 cgd } 534 1.1 cgd 535 1.1 cgd if (symp == NULL) { 536 1.57 rillig if (sym.s_check_only_first_args || 537 1.57 rillig sym.s_printflike || sym.s_scanflike) { 538 1.42 rillig symp = xalloc(sizeof(*symp)); 539 1.34 rillig *symp = sym; 540 1.1 cgd } else { 541 1.57 rillig /* no need to allocate memory for unused members */ 542 1.42 rillig symp = xalloc(sizeof(symp->s_s)); 543 1.34 rillig symp->s_s = sym.s_s; 544 1.1 cgd } 545 1.1 cgd *hte->h_lsym = symp; 546 1.32 rillig hte->h_lsym = &symp->s_next; 547 1.4 cgd 548 1.4 cgd /* XXX hack so we can remember where a symbol was renamed */ 549 1.4 cgd if (renamed) 550 1.4 cgd renamehte->h_syms = symp; 551 1.1 cgd } 552 1.1 cgd 553 1.1 cgd if (*cp != '\0') 554 1.20 christos inperr("trailing line: %s", cp); 555 1.1 cgd } 556 1.1 cgd 557 1.1 cgd /* 558 1.36 rillig * Read an u-record (emitted by lint1 if a symbol was used). 559 1.1 cgd */ 560 1.1 cgd static void 561 1.74 rillig usedsym(pos_t pos, const char *cp) 562 1.1 cgd { 563 1.81 rillig usym_t *usym; 564 1.81 rillig hte_t *hte; 565 1.4 cgd const char *name; 566 1.1 cgd 567 1.42 rillig usym = xalloc(sizeof(*usym)); 568 1.74 rillig usym->u_pos = pos; 569 1.1 cgd 570 1.1 cgd /* needed as delimiter between two numbers */ 571 1.1 cgd if (*cp++ != 'x') 572 1.20 christos inperr("bad delim %c", cp[-1]); 573 1.1 cgd 574 1.4 cgd name = inpname(cp, &cp); 575 1.85 rillig hte = hash_search(renametab, name, false); 576 1.4 cgd if (hte != NULL) 577 1.4 cgd hte = hte->h_hte; 578 1.4 cgd else 579 1.85 rillig hte = htab_search(name, true); 580 1.37 rillig hte->h_used = true; 581 1.1 cgd 582 1.1 cgd *hte->h_lusym = usym; 583 1.33 rillig hte->h_lusym = &usym->u_next; 584 1.1 cgd } 585 1.1 cgd 586 1.50 rillig static tspec_t 587 1.50 rillig parse_tspec(const char **pp, char c, bool *osdef) 588 1.50 rillig { 589 1.50 rillig char s; 590 1.50 rillig 591 1.50 rillig switch (c) { 592 1.89 rillig case 's': /* 'signed' or 'struct' or 'float' */ 593 1.89 rillig case 'u': /* 'unsigned' or 'union' */ 594 1.89 rillig case 'l': /* 'long double' */ 595 1.89 rillig case 'e': /* 'enum' */ 596 1.50 rillig s = c; 597 1.50 rillig c = *(*pp)++; 598 1.50 rillig break; 599 1.50 rillig default: 600 1.50 rillig s = '\0'; 601 1.50 rillig break; 602 1.50 rillig } 603 1.50 rillig 604 1.50 rillig switch (c) { 605 1.50 rillig case 'B': 606 1.50 rillig return BOOL; 607 1.50 rillig case 'C': 608 1.50 rillig return s == 's' ? SCHAR : (s == 'u' ? UCHAR : CHAR); 609 1.50 rillig case 'S': 610 1.50 rillig return s == 'u' ? USHORT : SHORT; 611 1.50 rillig case 'I': 612 1.50 rillig return s == 'u' ? UINT : INT; 613 1.50 rillig case 'L': 614 1.50 rillig return s == 'u' ? ULONG : LONG; 615 1.50 rillig case 'Q': 616 1.82 rillig return s == 'u' ? ULLONG : LLONG; 617 1.50 rillig #ifdef INT128_SIZE 618 1.50 rillig case 'J': 619 1.50 rillig return s == 'u' ? UINT128 : INT128; 620 1.50 rillig #endif 621 1.50 rillig case 'D': 622 1.50 rillig return s == 's' ? FLOAT : (s == 'l' ? LDOUBLE : DOUBLE); 623 1.50 rillig case 'V': 624 1.50 rillig return VOID; 625 1.50 rillig case 'P': 626 1.50 rillig return PTR; 627 1.50 rillig case 'A': 628 1.50 rillig return ARRAY; 629 1.50 rillig case 'F': 630 1.50 rillig case 'f': 631 1.50 rillig *osdef = c == 'f'; 632 1.50 rillig return FUNC; 633 1.50 rillig case 'T': 634 1.50 rillig return s == 'e' ? ENUM : (s == 's' ? STRUCT : UNION); 635 1.50 rillig case 'X': 636 1.50 rillig return s == 's' ? FCOMPLEX 637 1.88 rillig : (s == 'l' ? LCOMPLEX : DCOMPLEX); 638 1.50 rillig default: 639 1.50 rillig inperr("tspec '%c'", c); 640 1.65 rillig /* NOTREACHED */ 641 1.50 rillig } 642 1.50 rillig } 643 1.50 rillig 644 1.1 cgd /* 645 1.1 cgd * Read a type and return the index of this type. 646 1.1 cgd */ 647 1.56 rillig static unsigned short 648 1.9 lukem inptype(const char *cp, const char **epp) 649 1.1 cgd { 650 1.81 rillig char c; 651 1.81 rillig const char *ep; 652 1.81 rillig type_t *tp; 653 1.81 rillig int narg, i; 654 1.81 rillig bool osdef = false; 655 1.81 rillig size_t tlen; 656 1.56 rillig unsigned short tidx; 657 1.81 rillig int h; 658 1.1 cgd 659 1.26 snj /* If we have this type already, return its index. */ 660 1.1 cgd tlen = gettlen(cp, &ep); 661 1.1 cgd h = thash(cp, tlen); 662 1.1 cgd if ((tidx = findtype(cp, tlen, h)) != 0) { 663 1.1 cgd *epp = ep; 664 1.30 rillig return tidx; 665 1.1 cgd } 666 1.1 cgd 667 1.1 cgd /* No, we must create a new type. */ 668 1.42 rillig tp = xalloc(sizeof(*tp)); 669 1.1 cgd 670 1.1 cgd tidx = storetyp(tp, cp, tlen, h); 671 1.1 cgd 672 1.1 cgd c = *cp++; 673 1.1 cgd 674 1.53 rillig if (c == 'c') { 675 1.53 rillig tp->t_const = true; 676 1.53 rillig c = *cp++; 677 1.53 rillig } 678 1.53 rillig if (c == 'v') { 679 1.53 rillig tp->t_volatile = true; 680 1.1 cgd c = *cp++; 681 1.1 cgd } 682 1.1 cgd 683 1.50 rillig tp->t_tspec = parse_tspec(&cp, c, &osdef); 684 1.1 cgd 685 1.1 cgd switch (tp->t_tspec) { 686 1.1 cgd case ARRAY: 687 1.44 rillig tp->t_dim = parse_int(&cp); 688 1.51 rillig tp->t_subt = TP(inptype(cp, &cp)); 689 1.1 cgd break; 690 1.1 cgd case PTR: 691 1.51 rillig tp->t_subt = TP(inptype(cp, &cp)); 692 1.1 cgd break; 693 1.1 cgd case FUNC: 694 1.1 cgd c = *cp; 695 1.92 rillig if (ch_isdigit(c)) { 696 1.1 cgd if (!osdef) 697 1.37 rillig tp->t_proto = true; 698 1.44 rillig narg = parse_int(&cp); 699 1.51 rillig tp->t_args = xcalloc((size_t)narg + 1, 700 1.88 rillig sizeof(*tp->t_args)); 701 1.1 cgd for (i = 0; i < narg; i++) { 702 1.1 cgd if (i == narg - 1 && *cp == 'E') { 703 1.37 rillig tp->t_vararg = true; 704 1.1 cgd cp++; 705 1.75 rillig } else 706 1.51 rillig tp->t_args[i] = TP(inptype(cp, &cp)); 707 1.1 cgd } 708 1.1 cgd } 709 1.51 rillig tp->t_subt = TP(inptype(cp, &cp)); 710 1.1 cgd break; 711 1.1 cgd case ENUM: 712 1.1 cgd tp->t_tspec = INT; 713 1.39 rillig tp->t_is_enum = true; 714 1.1 cgd /* FALLTHROUGH */ 715 1.1 cgd case STRUCT: 716 1.1 cgd case UNION: 717 1.1 cgd switch (*cp++) { 718 1.1 cgd case '1': 719 1.37 rillig tp->t_istag = true; 720 1.85 rillig tp->t_tag = htab_search(inpname(cp, &cp), true); 721 1.1 cgd break; 722 1.1 cgd case '2': 723 1.37 rillig tp->t_istynam = true; 724 1.85 rillig tp->t_tynam = htab_search(inpname(cp, &cp), true); 725 1.1 cgd break; 726 1.3 cgd case '3': 727 1.37 rillig tp->t_isuniqpos = true; 728 1.44 rillig tp->t_uniqpos.p_line = parse_int(&cp); 729 1.3 cgd cp++; 730 1.3 cgd /* xlate to 'global' file name. */ 731 1.83 rillig tp->t_uniqpos.p_file = (short) 732 1.44 rillig addoutfile(inpfns[parse_int(&cp)]); 733 1.3 cgd cp++; 734 1.44 rillig tp->t_uniqpos.p_uniq = parse_int(&cp); 735 1.3 cgd break; 736 1.1 cgd } 737 1.1 cgd break; 738 1.52 rillig default: 739 1.5 christos break; 740 1.1 cgd } 741 1.1 cgd 742 1.1 cgd *epp = cp; 743 1.30 rillig return tidx; 744 1.1 cgd } 745 1.1 cgd 746 1.1 cgd /* 747 1.1 cgd * Get the length of a type string. 748 1.1 cgd */ 749 1.65 rillig static size_t 750 1.9 lukem gettlen(const char *cp, const char **epp) 751 1.1 cgd { 752 1.81 rillig const char *cp1; 753 1.81 rillig char c, s; 754 1.81 rillig tspec_t t; 755 1.81 rillig int narg, i; 756 1.1 cgd 757 1.1 cgd cp1 = cp; 758 1.1 cgd 759 1.1 cgd c = *cp++; 760 1.1 cgd 761 1.53 rillig if (c == 'c') 762 1.53 rillig c = *cp++; 763 1.53 rillig if (c == 'v') 764 1.1 cgd c = *cp++; 765 1.1 cgd 766 1.22 christos switch (c) { 767 1.22 christos case 's': 768 1.22 christos case 'u': 769 1.22 christos case 'l': 770 1.22 christos case 'e': 771 1.1 cgd s = c; 772 1.1 cgd c = *cp++; 773 1.22 christos break; 774 1.22 christos default: 775 1.1 cgd s = '\0'; 776 1.22 christos break; 777 1.1 cgd } 778 1.1 cgd 779 1.80 rillig t = NO_TSPEC; 780 1.1 cgd 781 1.1 cgd switch (c) { 782 1.15 yamt case 'B': 783 1.15 yamt if (s == '\0') 784 1.15 yamt t = BOOL; 785 1.15 yamt break; 786 1.1 cgd case 'C': 787 1.75 rillig if (s == 's') 788 1.1 cgd t = SCHAR; 789 1.75 rillig else if (s == 'u') 790 1.1 cgd t = UCHAR; 791 1.75 rillig else if (s == '\0') 792 1.1 cgd t = CHAR; 793 1.1 cgd break; 794 1.1 cgd case 'S': 795 1.75 rillig if (s == 'u') 796 1.1 cgd t = USHORT; 797 1.75 rillig else if (s == '\0') 798 1.1 cgd t = SHORT; 799 1.1 cgd break; 800 1.1 cgd case 'I': 801 1.75 rillig if (s == 'u') 802 1.1 cgd t = UINT; 803 1.75 rillig else if (s == '\0') 804 1.1 cgd t = INT; 805 1.1 cgd break; 806 1.1 cgd case 'L': 807 1.75 rillig if (s == 'u') 808 1.1 cgd t = ULONG; 809 1.75 rillig else if (s == '\0') 810 1.1 cgd t = LONG; 811 1.1 cgd break; 812 1.1 cgd case 'Q': 813 1.75 rillig if (s == 'u') 814 1.82 rillig t = ULLONG; 815 1.75 rillig else if (s == '\0') 816 1.82 rillig t = LLONG; 817 1.1 cgd break; 818 1.47 rillig #ifdef INT128_SIZE 819 1.47 rillig case 'J': 820 1.75 rillig if (s == 'u') 821 1.47 rillig t = UINT128; 822 1.75 rillig else if (s == '\0') 823 1.47 rillig t = INT128; 824 1.47 rillig break; 825 1.47 rillig #endif 826 1.1 cgd case 'D': 827 1.75 rillig if (s == 's') 828 1.1 cgd t = FLOAT; 829 1.75 rillig else if (s == 'l') 830 1.1 cgd t = LDOUBLE; 831 1.75 rillig else if (s == '\0') 832 1.1 cgd t = DOUBLE; 833 1.1 cgd break; 834 1.1 cgd case 'V': 835 1.1 cgd if (s == '\0') 836 1.1 cgd t = VOID; 837 1.1 cgd break; 838 1.1 cgd case 'P': 839 1.1 cgd if (s == '\0') 840 1.1 cgd t = PTR; 841 1.1 cgd break; 842 1.1 cgd case 'A': 843 1.1 cgd if (s == '\0') 844 1.1 cgd t = ARRAY; 845 1.1 cgd break; 846 1.1 cgd case 'F': 847 1.1 cgd case 'f': 848 1.1 cgd if (s == '\0') 849 1.1 cgd t = FUNC; 850 1.1 cgd break; 851 1.1 cgd case 'T': 852 1.75 rillig if (s == 'e') 853 1.1 cgd t = ENUM; 854 1.75 rillig else if (s == 's') 855 1.1 cgd t = STRUCT; 856 1.75 rillig else if (s == 'u') 857 1.1 cgd t = UNION; 858 1.1 cgd break; 859 1.20 christos case 'X': 860 1.75 rillig if (s == 's') 861 1.22 christos t = FCOMPLEX; 862 1.75 rillig else if (s == 'l') 863 1.23 matt t = LCOMPLEX; 864 1.75 rillig else if (s == '\0') 865 1.20 christos t = DCOMPLEX; 866 1.20 christos break; 867 1.1 cgd default: 868 1.52 rillig break; 869 1.1 cgd } 870 1.1 cgd 871 1.80 rillig if (t == NO_TSPEC) 872 1.52 rillig inperr("bad type: %c %c", c, s); 873 1.1 cgd 874 1.1 cgd switch (t) { 875 1.1 cgd case ARRAY: 876 1.44 rillig (void)parse_int(&cp); 877 1.1 cgd (void)gettlen(cp, &cp); 878 1.1 cgd break; 879 1.1 cgd case PTR: 880 1.1 cgd (void)gettlen(cp, &cp); 881 1.1 cgd break; 882 1.1 cgd case FUNC: 883 1.1 cgd c = *cp; 884 1.92 rillig if (ch_isdigit(c)) { 885 1.44 rillig narg = parse_int(&cp); 886 1.1 cgd for (i = 0; i < narg; i++) { 887 1.75 rillig if (i == narg - 1 && *cp == 'E') 888 1.1 cgd cp++; 889 1.75 rillig else 890 1.1 cgd (void)gettlen(cp, &cp); 891 1.1 cgd } 892 1.1 cgd } 893 1.1 cgd (void)gettlen(cp, &cp); 894 1.1 cgd break; 895 1.1 cgd case ENUM: 896 1.1 cgd case STRUCT: 897 1.1 cgd case UNION: 898 1.1 cgd switch (*cp++) { 899 1.1 cgd case '1': 900 1.1 cgd case '2': 901 1.1 cgd (void)inpname(cp, &cp); 902 1.3 cgd break; 903 1.3 cgd case '3': 904 1.3 cgd /* unique position: line.file.uniquifier */ 905 1.44 rillig (void)parse_int(&cp); 906 1.3 cgd if (*cp++ != '.') 907 1.20 christos inperr("not dot: %c", cp[-1]); 908 1.44 rillig (void)parse_int(&cp); 909 1.3 cgd if (*cp++ != '.') 910 1.20 christos inperr("not dot: %c", cp[-1]); 911 1.44 rillig (void)parse_int(&cp); 912 1.1 cgd break; 913 1.1 cgd default: 914 1.55 rillig inperr("bad value: %c", cp[-1]); 915 1.1 cgd } 916 1.1 cgd break; 917 1.52 rillig default: 918 1.5 christos break; 919 1.1 cgd } 920 1.1 cgd 921 1.1 cgd *epp = cp; 922 1.65 rillig return (size_t)(cp - cp1); 923 1.1 cgd } 924 1.1 cgd 925 1.1 cgd /* 926 1.26 snj * Search a type by its type string. 927 1.1 cgd */ 928 1.56 rillig static unsigned short 929 1.9 lukem findtype(const char *cp, size_t len, int h) 930 1.1 cgd { 931 1.81 rillig thtab_t *thte; 932 1.1 cgd 933 1.33 rillig for (thte = thtab[h]; thte != NULL; thte = thte->th_next) { 934 1.1 cgd if (strncmp(thte->th_name, cp, len) != 0) 935 1.1 cgd continue; 936 1.1 cgd if (thte->th_name[len] == '\0') 937 1.30 rillig return thte->th_idx; 938 1.1 cgd } 939 1.1 cgd 940 1.30 rillig return 0; 941 1.1 cgd } 942 1.1 cgd 943 1.1 cgd /* 944 1.51 rillig * Store a type and its type string, so we can later share this type 945 1.1 cgd * if we read the same type string from the input file. 946 1.1 cgd */ 947 1.56 rillig static unsigned short 948 1.9 lukem storetyp(type_t *tp, const char *cp, size_t len, int h) 949 1.1 cgd { 950 1.56 rillig static unsigned int tidx = 1; /* 0 is reserved */ 951 1.81 rillig thtab_t *thte; 952 1.81 rillig char *name; 953 1.1 cgd 954 1.1 cgd if (tidx >= USHRT_MAX) 955 1.1 cgd errx(1, "sorry, too many types"); 956 1.1 cgd 957 1.1 cgd if (tidx == tlstlen - 1) { 958 1.42 rillig tlst = xrealloc(tlst, (tlstlen * 2) * sizeof(*tlst)); 959 1.42 rillig (void)memset(tlst + tlstlen, 0, tlstlen * sizeof(*tlst)); 960 1.1 cgd tlstlen *= 2; 961 1.1 cgd } 962 1.1 cgd 963 1.1 cgd tlst[tidx] = tp; 964 1.1 cgd 965 1.1 cgd /* create a hash table entry */ 966 1.1 cgd name = xalloc(len + 1); 967 1.1 cgd (void)memcpy(name, cp, len); 968 1.1 cgd name[len] = '\0'; 969 1.1 cgd 970 1.42 rillig thte = xalloc(sizeof(*thte)); 971 1.1 cgd thte->th_name = name; 972 1.83 rillig thte->th_idx = (unsigned short)tidx; 973 1.33 rillig thte->th_next = thtab[h]; 974 1.1 cgd thtab[h] = thte; 975 1.1 cgd 976 1.56 rillig return (unsigned short)tidx++; 977 1.1 cgd } 978 1.1 cgd 979 1.1 cgd /* 980 1.1 cgd * Hash function for types 981 1.1 cgd */ 982 1.69 rillig static unsigned int 983 1.9 lukem thash(const char *s, size_t len) 984 1.1 cgd { 985 1.56 rillig unsigned int v; 986 1.1 cgd 987 1.1 cgd v = 0; 988 1.1 cgd while (len-- != 0) { 989 1.56 rillig v = (v << sizeof(v)) + (unsigned char)*s++; 990 1.42 rillig v ^= v >> (sizeof(v) * CHAR_BIT - sizeof(v)); 991 1.1 cgd } 992 1.84 rillig return v % (sizeof(thtab) / sizeof(thtab[0])); 993 1.1 cgd } 994 1.1 cgd 995 1.1 cgd /* 996 1.1 cgd * Read a string enclosed by "". This string may contain quoted chars. 997 1.1 cgd */ 998 1.1 cgd static char * 999 1.9 lukem inpqstrg(const char *src, const char **epp) 1000 1.1 cgd { 1001 1.81 rillig char *strg, *dst; 1002 1.81 rillig size_t slen; 1003 1.81 rillig char c; 1004 1.81 rillig int v; 1005 1.1 cgd 1006 1.1 cgd dst = strg = xmalloc(slen = 32); 1007 1.1 cgd 1008 1.1 cgd if ((c = *src++) != '"') 1009 1.20 christos inperr("not quote: %c", c); 1010 1.1 cgd if ((c = *src++) == '\0') 1011 1.20 christos inperr("trailing data: %c", c); 1012 1.1 cgd 1013 1.1 cgd while (c != '"') { 1014 1.1 cgd if (c == '\\') { 1015 1.1 cgd if ((c = *src++) == '\0') 1016 1.20 christos inperr("missing after \\"); 1017 1.1 cgd switch (c) { 1018 1.1 cgd case 'n': 1019 1.1 cgd c = '\n'; 1020 1.1 cgd break; 1021 1.1 cgd case 't': 1022 1.1 cgd c = '\t'; 1023 1.1 cgd break; 1024 1.1 cgd case 'v': 1025 1.1 cgd c = '\v'; 1026 1.1 cgd break; 1027 1.1 cgd case 'b': 1028 1.1 cgd c = '\b'; 1029 1.1 cgd break; 1030 1.1 cgd case 'r': 1031 1.1 cgd c = '\r'; 1032 1.1 cgd break; 1033 1.1 cgd case 'f': 1034 1.1 cgd c = '\f'; 1035 1.1 cgd break; 1036 1.1 cgd case 'a': 1037 1.1 cgd c = '\a'; 1038 1.1 cgd break; 1039 1.1 cgd case '\\': 1040 1.1 cgd c = '\\'; 1041 1.1 cgd break; 1042 1.1 cgd case '"': 1043 1.1 cgd c = '"'; 1044 1.1 cgd break; 1045 1.1 cgd case '\'': 1046 1.1 cgd c = '\''; 1047 1.1 cgd break; 1048 1.1 cgd case '0': case '1': case '2': case '3': 1049 1.1 cgd v = (c - '0') << 6; 1050 1.1 cgd if ((c = *src++) < '0' || c > '7') 1051 1.20 christos inperr("not octal: %c", c); 1052 1.1 cgd v |= (c - '0') << 3; 1053 1.1 cgd if ((c = *src++) < '0' || c > '7') 1054 1.20 christos inperr("not octal: %c", c); 1055 1.1 cgd v |= c - '0'; 1056 1.48 rillig c = (char)v; 1057 1.1 cgd break; 1058 1.1 cgd default: 1059 1.20 christos inperr("bad \\ escape: %c", c); 1060 1.1 cgd } 1061 1.1 cgd } 1062 1.1 cgd /* keep space for trailing '\0' */ 1063 1.25 christos if ((size_t)(dst - strg) == slen - 1) { 1064 1.1 cgd strg = xrealloc(strg, slen * 2); 1065 1.1 cgd dst = strg + (slen - 1); 1066 1.1 cgd slen *= 2; 1067 1.1 cgd } 1068 1.48 rillig *dst++ = c; 1069 1.1 cgd if ((c = *src++) == '\0') 1070 1.20 christos inperr("missing closing quote"); 1071 1.1 cgd } 1072 1.1 cgd *dst = '\0'; 1073 1.1 cgd 1074 1.1 cgd *epp = src; 1075 1.30 rillig return strg; 1076 1.1 cgd } 1077 1.1 cgd 1078 1.1 cgd /* 1079 1.1 cgd * Read the name of a symbol in static memory. 1080 1.1 cgd */ 1081 1.1 cgd static const char * 1082 1.9 lukem inpname(const char *cp, const char **epp) 1083 1.1 cgd { 1084 1.81 rillig static char *buf; 1085 1.81 rillig static size_t blen = 0; 1086 1.81 rillig size_t len, i; 1087 1.81 rillig char c; 1088 1.1 cgd 1089 1.44 rillig len = parse_int(&cp); 1090 1.1 cgd if (len + 1 > blen) 1091 1.1 cgd buf = xrealloc(buf, blen = len + 1); 1092 1.1 cgd for (i = 0; i < len; i++) { 1093 1.1 cgd c = *cp++; 1094 1.92 rillig if (!ch_isalnum(c) && c != '_') 1095 1.20 christos inperr("not alnum or _: %c", c); 1096 1.1 cgd buf[i] = c; 1097 1.1 cgd } 1098 1.1 cgd buf[i] = '\0'; 1099 1.1 cgd 1100 1.1 cgd *epp = cp; 1101 1.30 rillig return buf; 1102 1.1 cgd } 1103 1.1 cgd 1104 1.1 cgd /* 1105 1.1 cgd * Return the index of a file name. If the name cannot be found, create 1106 1.1 cgd * a new entry and return the index of the newly created entry. 1107 1.1 cgd */ 1108 1.1 cgd static int 1109 1.9 lukem getfnidx(const char *fn) 1110 1.1 cgd { 1111 1.81 rillig size_t i; 1112 1.1 cgd 1113 1.21 christos /* 0 is reserved */ 1114 1.1 cgd for (i = 1; fnames[i] != NULL; i++) { 1115 1.1 cgd if (strcmp(fnames[i], fn) == 0) 1116 1.65 rillig return (int)i; 1117 1.1 cgd } 1118 1.1 cgd 1119 1.1 cgd if (i == nfnames - 1) { 1120 1.21 christos size_t nlen = nfnames * 2; 1121 1.42 rillig fnames = xrealloc(fnames, nlen * sizeof(*fnames)); 1122 1.42 rillig (void)memset(fnames + nfnames, 0, nfnames * sizeof(*fnames)); 1123 1.42 rillig flines = xrealloc(flines, nlen * sizeof(*flines)); 1124 1.42 rillig (void)memset(flines + nfnames, 0, nfnames * sizeof(*flines)); 1125 1.21 christos nfnames = nlen; 1126 1.1 cgd } 1127 1.1 cgd 1128 1.1 cgd fnames[i] = xstrdup(fn); 1129 1.20 christos flines[i] = 0; 1130 1.65 rillig return (int)i; 1131 1.1 cgd } 1132 1.1 cgd 1133 1.1 cgd /* 1134 1.1 cgd * Separate symbols with static and external linkage. 1135 1.1 cgd */ 1136 1.1 cgd void 1137 1.9 lukem mkstatic(hte_t *hte) 1138 1.1 cgd { 1139 1.81 rillig sym_t *sym1, **symp, *sym; 1140 1.81 rillig fcall_t **callp, *call; 1141 1.81 rillig usym_t **usymp, *usym; 1142 1.81 rillig hte_t *nhte; 1143 1.81 rillig bool ofnd; 1144 1.1 cgd 1145 1.1 cgd /* Look for first static definition */ 1146 1.32 rillig for (sym1 = hte->h_syms; sym1 != NULL; sym1 = sym1->s_next) { 1147 1.1 cgd if (sym1->s_static) 1148 1.1 cgd break; 1149 1.1 cgd } 1150 1.1 cgd if (sym1 == NULL) 1151 1.1 cgd return; 1152 1.1 cgd 1153 1.1 cgd /* Do nothing if this name is used only in one translation unit. */ 1154 1.37 rillig ofnd = false; 1155 1.32 rillig for (sym = hte->h_syms; sym != NULL && !ofnd; sym = sym->s_next) { 1156 1.1 cgd if (sym->s_pos.p_src != sym1->s_pos.p_src) 1157 1.37 rillig ofnd = true; 1158 1.1 cgd } 1159 1.33 rillig for (call = hte->h_calls; call != NULL && !ofnd; call = call->f_next) { 1160 1.1 cgd if (call->f_pos.p_src != sym1->s_pos.p_src) 1161 1.37 rillig ofnd = true; 1162 1.1 cgd } 1163 1.33 rillig for (usym = hte->h_usyms; usym != NULL && !ofnd; usym = usym->u_next) { 1164 1.1 cgd if (usym->u_pos.p_src != sym1->s_pos.p_src) 1165 1.37 rillig ofnd = true; 1166 1.1 cgd } 1167 1.1 cgd if (!ofnd) { 1168 1.37 rillig hte->h_used = true; 1169 1.1 cgd /* errors about undef. static symbols are printed in lint1 */ 1170 1.37 rillig hte->h_def = true; 1171 1.37 rillig hte->h_static = true; 1172 1.1 cgd return; 1173 1.1 cgd } 1174 1.1 cgd 1175 1.1 cgd /* 1176 1.1 cgd * Create a new hash table entry 1177 1.1 cgd * 1178 1.89 rillig * XXX this entry should be put at the beginning of the list to avoid 1179 1.89 rillig * processing the same symbol twice. 1180 1.1 cgd */ 1181 1.9 lukem for (nhte = hte; nhte->h_link != NULL; nhte = nhte->h_link) 1182 1.9 lukem continue; 1183 1.42 rillig nhte->h_link = xmalloc(sizeof(*nhte->h_link)); 1184 1.1 cgd nhte = nhte->h_link; 1185 1.1 cgd nhte->h_name = hte->h_name; 1186 1.37 rillig nhte->h_used = true; 1187 1.37 rillig nhte->h_def = true; /* error in lint1 */ 1188 1.37 rillig nhte->h_static = true; 1189 1.6 mycroft nhte->h_syms = NULL; 1190 1.1 cgd nhte->h_lsym = &nhte->h_syms; 1191 1.6 mycroft nhte->h_calls = NULL; 1192 1.1 cgd nhte->h_lcall = &nhte->h_calls; 1193 1.6 mycroft nhte->h_usyms = NULL; 1194 1.1 cgd nhte->h_lusym = &nhte->h_usyms; 1195 1.6 mycroft nhte->h_link = NULL; 1196 1.6 mycroft nhte->h_hte = NULL; 1197 1.1 cgd 1198 1.1 cgd /* 1199 1.89 rillig * move all symbols used in this translation unit into the new hash 1200 1.89 rillig * table entry. 1201 1.1 cgd */ 1202 1.1 cgd for (symp = &hte->h_syms; (sym = *symp) != NULL; ) { 1203 1.1 cgd if (sym->s_pos.p_src == sym1->s_pos.p_src) { 1204 1.37 rillig sym->s_static = true; 1205 1.69 rillig *symp = sym->s_next; 1206 1.32 rillig if (hte->h_lsym == &sym->s_next) 1207 1.1 cgd hte->h_lsym = symp; 1208 1.32 rillig sym->s_next = NULL; 1209 1.1 cgd *nhte->h_lsym = sym; 1210 1.32 rillig nhte->h_lsym = &sym->s_next; 1211 1.1 cgd } else { 1212 1.32 rillig symp = &sym->s_next; 1213 1.1 cgd } 1214 1.1 cgd } 1215 1.1 cgd for (callp = &hte->h_calls; (call = *callp) != NULL; ) { 1216 1.1 cgd if (call->f_pos.p_src == sym1->s_pos.p_src) { 1217 1.69 rillig *callp = call->f_next; 1218 1.33 rillig if (hte->h_lcall == &call->f_next) 1219 1.1 cgd hte->h_lcall = callp; 1220 1.33 rillig call->f_next = NULL; 1221 1.1 cgd *nhte->h_lcall = call; 1222 1.33 rillig nhte->h_lcall = &call->f_next; 1223 1.1 cgd } else { 1224 1.33 rillig callp = &call->f_next; 1225 1.1 cgd } 1226 1.1 cgd } 1227 1.1 cgd for (usymp = &hte->h_usyms; (usym = *usymp) != NULL; ) { 1228 1.1 cgd if (usym->u_pos.p_src == sym1->s_pos.p_src) { 1229 1.69 rillig *usymp = usym->u_next; 1230 1.33 rillig if (hte->h_lusym == &usym->u_next) 1231 1.1 cgd hte->h_lusym = usymp; 1232 1.33 rillig usym->u_next = NULL; 1233 1.1 cgd *nhte->h_lusym = usym; 1234 1.33 rillig nhte->h_lusym = &usym->u_next; 1235 1.1 cgd } else { 1236 1.33 rillig usymp = &usym->u_next; 1237 1.1 cgd } 1238 1.1 cgd } 1239 1.1 cgd 1240 1.1 cgd /* h_def must be recalculated for old hte */ 1241 1.37 rillig hte->h_def = nhte->h_def = false; 1242 1.32 rillig for (sym = hte->h_syms; sym != NULL; sym = sym->s_next) { 1243 1.1 cgd if (sym->s_def == DEF || sym->s_def == TDEF) { 1244 1.37 rillig hte->h_def = true; 1245 1.1 cgd break; 1246 1.1 cgd } 1247 1.1 cgd } 1248 1.1 cgd 1249 1.1 cgd mkstatic(hte); 1250 1.1 cgd } 1251