1 /* $NetBSD: lint2.h,v 1.28 2025/02/27 06:48:29 rillig Exp $ */
2 
3 /*
4  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
5  * Copyright (c) 1994, 1995 Jochen Pohl
6  * All Rights Reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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
19  *        The NetBSD Project.
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.
22  *
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.
33  */
34 
35 #include "lint.h"
36 
37 /*
38  * Types are described by structures of type type_t.
39  */
40 struct lint2_type {
41           tspec_t   t_tspec;  /* type specifier */
42           bool      t_const:1;          /* constant */
43           bool      t_volatile:1;       /* volatile */
44           bool      t_vararg:1;         /* function has variable number of arguments */
45           bool      t_is_enum:1;
46           bool      t_proto:1;          /* this is a prototype */
47           bool      t_istag:1;          /* tag with _t_tag valid */
48           bool      t_istynam:1;        /* tag with _t_tynam valid */
49           bool      t_isuniqpos:1;      /* tag with _t_uniqpos valid */
50           union {
51                     int       _t_dim;             /* if the type is an ARRAY than this
52                                                    * is the dimension of the array. */
53                     struct hte *_t_tag; /* hash table entry of tag if
54                                                    * t_is_enum, STRUCT or UNION */
55                     struct hte *_t_tynam;         /* hash table entry of typename if
56                                                    * t_is_enum, STRUCT or UNION */
57                     struct {
58                               int p_line;
59                               short p_file;
60                               int p_uniq;
61                     } _t_uniqpos;                 /* unique position, for untagged
62                                                    * untyped STRUCTs, UNIONS, and ENUMs,
63                                                    * if t_isuniqpos */
64                     struct lint2_type **_t_args; /* list of argument types if
65                                                    * this is a prototype */
66           } t_u;
67           struct lint2_type *t_subt;    /*- element type (if ARRAY),
68                                                    * return type (if FUNC),
69                                                    * target type (if PTR) */
70 };
71 
72 #define   t_dim               t_u._t_dim
73 #define   t_tag               t_u._t_tag
74 #define   t_tynam             t_u._t_tynam
75 #define   t_uniqpos t_u._t_uniqpos
76 #define   t_args              t_u._t_args
77 
78 /*
79  * argument information
80  *
81  * Such a structure is created for each argument of a function call
82  * which is an integer constant or a constant string.
83  */
84 typedef struct arginf {
85           int       a_num;              /* # of argument (1..) */
86           bool      a_zero:1; /* argument is 0 */
87           bool      a_pcon:1; /* msb of argument is not set */
88           bool      a_ncon:1; /* msb of argument is set */
89           bool      a_fmt:1;  /* a_fstrg points to format string */
90           char      *a_fstrg; /* format string */
91           struct arginf *a_next;        /* information for next const. argument */
92 } arginf_t;
93 
94 /*
95  * Keeps information about position in source file.
96  */
97 typedef struct {
98           unsigned short p_src;         /* index of name of translation unit (the name
99                                          * which was specified at the command line) */
100           unsigned short p_line;        /* line number in p_src */
101           unsigned short p_isrc;        /* index of (included) file */
102           unsigned short p_iline;       /* line number in p_iline */
103 } pos_t;
104 
105 /* Used for definitions and declarations. */
106 typedef struct sym {
107           struct {
108                     pos_t     s_pos;              /* pos of def./decl. */
109 #if !defined(lint) && !defined(DEBUG)
110                     unsigned char s_def;          /* DECL, TDEF or DEF */
111 #else
112                     def_t     s_def;
113 #endif
114                     bool      s_function_has_return_value:1;
115                     bool      s_inline:1;
116                     bool      s_old_style_function:1;
117                     bool      s_static:1;
118                     bool      s_check_only_first_args:1;
119                     bool      s_printflike:1;
120                     bool      s_scanflike:1;
121                     unsigned short s_type;
122                     struct sym *s_next; /* next symbol with same name */
123           } s_s;
124           /*
125            * To save memory, the remaining members are only allocated if one of
126            * s_check_only_first_args, s_printflike and s_scanflike is set.
127            */
128           short     s_check_num_args;   /* if s_check_only_first_args */
129           short     s_printflike_arg;   /* if s_printflike */
130           short     s_scanflike_arg;    /* if s_scanflike */
131 } sym_t;
132 
133 #define s_pos                 s_s.s_pos
134 #define s_function_has_return_value s_s.s_function_has_return_value
135 #define s_old_style_function s_s.s_old_style_function
136 #define s_inline    s_s.s_inline
137 #define s_static    s_s.s_static
138 #define s_def                 s_s.s_def
139 #define s_check_only_first_args         s_s.s_check_only_first_args
140 #define s_printflike          s_s.s_printflike
141 #define s_scanflike s_s.s_scanflike
142 #define s_type                s_s.s_type
143 #define s_next                s_s.s_next
144 
145 /*
146  * Used to store information about function calls.
147  */
148 typedef struct fcall {
149           pos_t     f_pos;              /* position of call */
150           bool      f_rused:1;          /* return value used */
151           bool      f_rdisc:1;          /* return value discarded (casted to void) */
152           unsigned short f_type;        /* types of expected return value and args */
153           arginf_t *f_args;   /* information about constant arguments */
154           struct fcall *f_next;         /* next call of same function */
155 } fcall_t;
156 
157 /*
158  * Used to store information about usage of symbols other
159  * than for function calls.
160  */
161 typedef struct usym {
162           pos_t     u_pos;              /* position */
163           struct usym *u_next;          /* next usage */
164 } usym_t;
165 
166 /*
167  * hash table entry
168  */
169 typedef struct hte {
170           const char *h_name; /* name */
171           bool      h_used:1; /* symbol is used */
172           bool      h_def:1;  /* symbol is defined */
173           bool      h_static:1;         /* static symbol */
174           sym_t     *h_syms;  /* declarations and definitions */
175           sym_t     **h_lsym; /* points to s_next of last decl./def. */
176           fcall_t   *h_calls; /* function calls */
177           fcall_t   **h_lcall;          /* points to f_next of last call */
178           usym_t    *h_usyms; /* usage info */
179           usym_t    **h_lusym;          /* points to u_next of last usage info */
180           struct hte *h_link; /* next hte with same hash function */
181           struct hte *h_hte;  /* pointer to other htes (for renames) */
182 } hte_t;
183 
184 #include "externs2.h"
185 
186 /* maps type indices into pointers to type structs */
187 static inline type_t *
TP(unsigned short type_id)188 TP(unsigned short type_id)
189 {
190           /* force sequence point for newly parsed type_id */
191           return tlst[type_id];
192 }
193