emit2.c revision 1.2
1/* $NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $ */ 2 3/* 4 * Copyright (c) 1994, 1995 Jochen Pohl 5 * All Rights Reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Jochen Pohl for 18 * The NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#ifndef lint 35static char rcsid[] = "$NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $"; 36#endif 37 38#include <err.h> 39 40#include "lint2.h" 41 42static void outtype __P((type_t *)); 43static void outdef __P((hte_t *, sym_t *)); 44static void dumpname __P((hte_t *)); 45 46/* 47 * Write type into the output buffer. 48 */ 49static void 50outtype(tp) 51 type_t *tp; 52{ 53 int t, s, na; 54 tspec_t ts; 55 type_t **ap; 56 57 while (tp != NULL) { 58 if ((ts = tp->t_tspec) == INT && tp->t_isenum) 59 ts = ENUM; 60 switch (ts) { 61 case CHAR: t = 'C'; s = '\0'; break; 62 case SCHAR: t = 'C'; s = 's'; break; 63 case UCHAR: t = 'C'; s = 'u'; break; 64 case SHORT: t = 'S'; s = '\0'; break; 65 case USHORT: t = 'S'; s = 'u'; break; 66 case INT: t = 'I'; s = '\0'; break; 67 case UINT: t = 'I'; s = 'u'; break; 68 case LONG: t = 'L'; s = '\0'; break; 69 case ULONG: t = 'L'; s = 'u'; break; 70 case QUAD: t = 'Q'; s = '\0'; break; 71 case UQUAD: t = 'Q'; s = 'u'; break; 72 case FLOAT: t = 'D'; s = 's'; break; 73 case DOUBLE: t = 'D'; s = '\0'; break; 74 case LDOUBLE: t = 'D'; s = 'l'; break; 75 case VOID: t = 'V'; s = '\0'; break; 76 case PTR: t = 'P'; s = '\0'; break; 77 case ARRAY: t = 'A'; s = '\0'; break; 78 case ENUM: t = 'T'; s = 'e'; break; 79 case STRUCT: t = 'T'; s = 's'; break; 80 case UNION: t = 'T'; s = 'u'; break; 81 case FUNC: 82 if (tp->t_args != NULL && !tp->t_proto) { 83 t = 'f'; 84 } else { 85 t = 'F'; 86 } 87 s = '\0'; 88 break; 89 default: 90 errx(1, "internal error: outtype() 1"); 91 } 92 if (tp->t_const) 93 outchar('c'); 94 if (tp->t_volatile) 95 outchar('v'); 96 if (s != '\0') 97 outchar(s); 98 outchar(t); 99 if (ts == ARRAY) { 100 outint(tp->t_dim); 101 } else if (ts == ENUM || ts == STRUCT || ts == UNION) { 102 if (tp->t_istag) { 103 outint(1); 104 outname(tp->t_tag->h_name); 105 } else if (tp->t_istynam) { 106 outint(2); 107 outname(tp->t_tynam->h_name); 108 } else { 109 outint(0); 110 } 111 } else if (ts == FUNC && tp->t_args != NULL) { 112 na = 0; 113 for (ap = tp->t_args; *ap != NULL; ap++) 114 na++; 115 if (tp->t_vararg) 116 na++; 117 outint(na); 118 for (ap = tp->t_args; *ap != NULL; ap++) 119 outtype(*ap); 120 if (tp->t_vararg) 121 outchar('E'); 122 } 123 tp = tp->t_subt; 124 } 125} 126 127/* 128 * Write a definition. 129 */ 130static void 131outdef(hte, sym) 132 hte_t *hte; 133 sym_t *sym; 134{ 135 /* reset output buffer */ 136 outclr(); 137 138 /* line number in C source file */ 139 outint(0); 140 141 /* this is a definition */ 142 outchar('d'); 143 144 /* index of file where symbol was defined and line number of def. */ 145 outint(0); 146 outchar('.'); 147 outint(0); 148 149 /* flags */ 150 if (sym->s_va) { 151 outchar('v'); /* varargs */ 152 outint(sym->s_nva); 153 } 154 if (sym->s_scfl) { 155 outchar('S'); /* scanflike */ 156 outint(sym->s_nscfl); 157 } 158 if (sym->s_prfl) { 159 outchar('P'); /* printflike */ 160 outint(sym->s_nprfl); 161 } 162 /* definition or tentative definition */ 163 outchar(sym->s_def == DEF ? 'd' : 't'); 164 if (TP(sym->s_type)->t_tspec == FUNC) { 165 if (sym->s_rval) 166 outchar('r'); /* fkt. has return value */ 167 if (sym->s_osdef) 168 outchar('o'); /* old style definition */ 169 } 170 outchar('u'); /* used (no warning if not used) */ 171 172 /* name */ 173 outname(hte->h_name); 174 175 /* type */ 176 outtype(TP(sym->s_type)); 177} 178 179/* 180 * Write the first definition of a name into the lint library. 181 */ 182static void 183dumpname(hte) 184 hte_t *hte; 185{ 186 sym_t *sym, *def; 187 188 /* static and undefined symbols are not written */ 189 if (hte->h_static || !hte->h_def) 190 return; 191 192 /* 193 * If there is a definition, write it. Otherwise write a tentative 194 * definition. This is neccessary because more than one tentative 195 * definition is allowed (except with sflag). 196 */ 197 def = NULL; 198 for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { 199 if (sym->s_def == DEF) { 200 def = sym; 201 break; 202 } 203 if (sym->s_def == TDEF && def == NULL) 204 def = sym; 205 } 206 if (def == NULL) 207 errx(1, "internal error: dumpname() %s", hte->h_name); 208 209 outdef(hte, def); 210} 211 212/* 213 * Write a new lint library. 214 */ 215void 216outlib(name) 217 const char *name; 218{ 219 /* Open of output file and initialisation of the output buffer */ 220 outopen(name); 221 222 /* write name of lint library */ 223 outsrc(name); 224 225 /* name of lint lib has index 0 */ 226 outclr(); 227 outint(0); 228 outchar('s'); 229 outstrg(name); 230 231 /* write all definitions with external linkage */ 232 forall(dumpname); 233 234 /* close the output */ 235 outclose(); 236} 237