1 /* $NetBSD: emit2.c,v 1.12 2008/04/26 20:31:45 christos Exp $ */
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/cdefs.h>
36 #if defined(__RCSID) && !defined(lint)
37 __RCSID("$NetBSD: emit2.c,v 1.12 2008/04/26 20:31:45 christos Exp $");
42 static void outtype(type_t
*);
43 static void outdef(hte_t
*, sym_t
*);
44 static void dumpname(hte_t
*);
45 static void outfiles(void);
48 * Write type into the output buffer.
58 if ((ts
= tp
->t_tspec
) == INT
&& tp
->t_isenum
)
61 case BOOL
: t
= 'B'; s
= '\0'; break;
62 case CHAR
: t
= 'C'; s
= '\0'; break;
63 case SCHAR
: t
= 'C'; s
= 's'; break;
64 case UCHAR
: t
= 'C'; s
= 'u'; break;
65 case SHORT
: t
= 'S'; s
= '\0'; break;
66 case USHORT
: t
= 'S'; s
= 'u'; break;
67 case INT
: t
= 'I'; s
= '\0'; break;
68 case UINT
: t
= 'I'; s
= 'u'; break;
69 case LONG
: t
= 'L'; s
= '\0'; break;
70 case ULONG
: t
= 'L'; s
= 'u'; break;
71 case QUAD
: t
= 'Q'; s
= '\0'; break;
72 case UQUAD
: t
= 'Q'; s
= 'u'; break;
73 case FLOAT
: t
= 'D'; s
= 's'; break;
74 case DOUBLE
: t
= 'D'; s
= '\0'; break;
75 case LDOUBLE
: t
= 'D'; s
= 'l'; break;
76 case VOID
: t
= 'V'; s
= '\0'; break;
77 case PTR
: t
= 'P'; s
= '\0'; break;
78 case ARRAY
: t
= 'A'; s
= '\0'; break;
79 case ENUM
: t
= 'T'; s
= 'e'; break;
80 case STRUCT
: t
= 'T'; s
= 's'; break;
81 case UNION
: t
= 'T'; s
= 'u'; break;
82 case FCOMPLEX
: t
= 'X'; s
= 's'; break;
83 case DCOMPLEX
: t
= 'X'; s
= '\0'; break;
84 case LCOMPLEX
: t
= 'X'; s
= 'l'; break;
86 if (tp
->t_args
!= NULL
&& !tp
->t_proto
) {
94 errx(1, "internal error: outtype() 1");
105 } else if (ts
== ENUM
|| ts
== STRUCT
|| ts
== UNION
) {
108 outname(tp
->t_tag
->h_name
);
109 } else if (tp
->t_istynam
) {
111 outname(tp
->t_tynam
->h_name
);
112 } else if (tp
->t_isuniqpos
) {
114 outint(tp
->t_uniqpos
.p_line
);
116 outint(tp
->t_uniqpos
.p_file
);
118 outint(tp
->t_uniqpos
.p_uniq
);
120 errx(1, "internal error: outtype() 2");
121 } else if (ts
== FUNC
&& tp
->t_args
!= NULL
) {
123 for (ap
= tp
->t_args
; *ap
!= NULL
; ap
++)
128 for (ap
= tp
->t_args
; *ap
!= NULL
; ap
++)
138 * Write a definition.
141 outdef(hte_t
*hte
, sym_t
*sym
)
144 /* reset output buffer */
147 /* line number in C source file */
150 /* this is a definition */
153 /* index of file where symbol was defined and line number of def. */
160 outchar('v'); /* varargs */
164 outchar('S'); /* scanflike */
165 outint(sym
->s_nscfl
);
168 outchar('P'); /* printflike */
169 outint(sym
->s_nprfl
);
171 /* definition or tentative definition */
172 outchar(sym
->s_def
== DEF
? 'd' : 't');
173 if (TP(sym
->s_type
)->t_tspec
== FUNC
) {
175 outchar('r'); /* fkt. has return value */
177 outchar('o'); /* old style definition */
179 outchar('u'); /* used (no warning if not used) */
182 outname(hte
->h_name
);
185 outtype(TP(sym
->s_type
));
189 * Write the first definition of a name into the lint library.
196 /* static and undefined symbols are not written */
197 if (hte
->h_static
|| !hte
->h_def
)
201 * If there is a definition, write it. Otherwise write a tentative
202 * definition. This is necessary because more than one tentative
203 * definition is allowed (except with sflag).
206 for (sym
= hte
->h_syms
; sym
!= NULL
; sym
= sym
->s_nxt
) {
207 if (sym
->s_def
== DEF
) {
211 if (sym
->s_def
== TDEF
&& def
== NULL
)
215 errx(1, "internal error: dumpname() %s", hte
->h_name
);
221 * Write a new lint library.
224 outlib(const char *name
)
226 /* Open of output file and initialisation of the output buffer */
229 /* write name of lint library */
232 /* name of lint lib has index 0 */
239 * print the names of all files references by unnamed
240 * struct/union/enum declarations.
244 /* write all definitions with external linkage */
247 /* close the output */
252 * Write out the name of a file referenced by a type.
256 struct outflist
*ofl_next
;
258 static struct outflist
*outflist
;
261 addoutfile(short num
)
263 struct outflist
*ofl
, **pofl
;
268 i
= 1; /* library is 0 */
270 while (ofl
!= NULL
) {
271 if (ofl
->ofl_num
== num
)
274 pofl
= &ofl
->ofl_next
;
280 ofl
= *pofl
= xmalloc(sizeof (struct outflist
));
282 ofl
->ofl_next
= NULL
;
290 struct outflist
*ofl
;
293 for (ofl
= outflist
, i
= 1; ofl
!= NULL
; ofl
= ofl
->ofl_next
, i
++) {
294 /* reset output buffer */
299 outstrg(fnames
[ofl
->ofl_num
]);