Make the "noderef" attribute work right.
[smatch.git] / lib.h
blob40555a483296f96bdb04aebe209114e562826f0b
1 #ifndef LIB_H
2 #define LIB_H
3 /*
4 * Basic helper routine descriptions for 'sparse'.
6 * Copyright (C) 2003 Transmeta Corp.
7 * 2003 Linus Torvalds
9 * Licensed under the Open Software License version 1.1
12 extern unsigned int hexval(unsigned int c);
14 struct position {
15 unsigned int type:6,
16 stream:10,
17 pos:14,
18 newline:1,
19 whitespace:1;
20 unsigned int line;
23 struct ident;
24 struct token;
25 struct symbol;
26 struct symbol_list;
27 struct statement;
28 struct statement_list;
29 struct expression;
30 struct expression_list;
31 struct basic_block;
32 struct basic_block_list;
33 struct entrypoint;
34 struct instruction;
35 struct instruction_list;
36 struct multijmp;
38 struct token *skip_to(struct token *, int);
39 struct token *expect(struct token *, int, const char *);
40 extern void warn(struct position, const char *, ...);
41 extern void error(struct position, const char *, ...);
43 #define __DECLARE_ALLOCATOR(type, x) \
44 extern type *__alloc_##x(int); \
45 extern void show_##x##_alloc(void); \
46 extern void clear_##x##_alloc(void);
47 #define DECLARE_ALLOCATOR(x) __DECLARE_ALLOCATOR(struct x, x)
49 DECLARE_ALLOCATOR(ident);
50 DECLARE_ALLOCATOR(token);
51 DECLARE_ALLOCATOR(symbol);
52 DECLARE_ALLOCATOR(expression);
53 DECLARE_ALLOCATOR(statement);
54 DECLARE_ALLOCATOR(string);
55 DECLARE_ALLOCATOR(scope);
56 __DECLARE_ALLOCATOR(void, bytes);
57 DECLARE_ALLOCATOR(basic_block);
58 DECLARE_ALLOCATOR(entrypoint);
59 DECLARE_ALLOCATOR(instruction);
60 DECLARE_ALLOCATOR(multijmp);
61 DECLARE_ALLOCATOR(phi);
64 #define LIST_NODE_NR (29)
66 struct ptr_list {
67 int nr;
68 struct ptr_list *prev;
69 struct ptr_list *next;
70 void *list[LIST_NODE_NR];
73 struct list_iterator {
74 struct ptr_list **head;
75 struct ptr_list *active;
76 int index;
77 unsigned int flags;
80 enum iterator_br_state {
81 BR_INIT,
82 BR_TRUE,
83 BR_FALSE,
84 BR_END,
87 struct terminator_iterator {
88 struct instruction *terminator;
89 union {
90 struct list_iterator multijmp;
91 int branch;
95 #define ITERATOR_BACKWARDS 1
96 #define ITERATOR_CURRENT 2
98 #define ITERATE_FIRST 1
99 #define ITERATE_LAST 2
101 #define ptr_list_empty(x) ((x) == NULL)
103 void iterate(struct ptr_list *,void (*callback)(void *, void *, int), void*);
104 void init_iterator(struct ptr_list **head, struct list_iterator *iterator, int flags);
105 void * next_iterator(struct list_iterator *iterator);
106 void delete_iterator(struct list_iterator *iterator);
107 void init_terminator_iterator(struct instruction* terminator, struct terminator_iterator *iterator);
108 struct basic_block* next_terminator_bb(struct terminator_iterator *iterator);
109 void replace_terminator_bb(struct terminator_iterator *iterator, struct basic_block* bb);
110 void * delete_ptr_list_last(struct ptr_list **head);
111 int replace_ptr_list(struct ptr_list **head, void *old_ptr, void *new_ptr);
113 extern void add_ptr_list(struct ptr_list **, void *);
114 extern void concat_ptr_list(struct ptr_list *a, struct ptr_list **b);
115 extern void free_ptr_list(struct ptr_list **);
116 extern int ptr_list_size(struct ptr_list *);
117 extern char **handle_switch(char *arg, char **next);
118 extern void add_pre_buffer(const char *fmt, ...);
120 extern unsigned int pre_buffer_size;
121 extern unsigned char pre_buffer[8192];
122 extern int include_fd;
123 extern char *include;
124 extern int preprocess_only;
126 extern void create_builtin_stream(void);
128 #define symbol_list_size(list) ptr_list_size((struct ptr_list *)(list))
129 #define statement_list_size(list) ptr_list_size((struct ptr_list *)(list))
130 #define expression_list_size(list) ptr_list_size((struct ptr_list *)(list))
131 #define instruction_list_size(list) ptr_list_size((struct ptr_list *)(list))
132 #define bb_list_size(list) ptr_list_size((struct ptr_list *)(list))
135 #define init_multijmp_iterator(list, iterator, flags) init_iterator((struct ptr_list **)(list), (iterator), (flags))
137 #define next_basic_block(iterator) (struct basic_block*) next_iterator(iterator)
138 #define next_multijmp(iterator) (struct multijmp*) next_iterator(iterator)
140 void * next_iterator(struct list_iterator *iterator);
142 static inline void init_bb_iterator(struct basic_block_list **head, struct list_iterator *iterator, int flags)
144 init_iterator((struct ptr_list **)head, iterator, flags);
147 static inline struct instruction * delete_last_instruction(struct instruction_list **head)
149 return delete_ptr_list_last((struct ptr_list **)head);
152 static inline struct basic_block * delete_last_basic_block(struct basic_block_list **head)
154 return delete_ptr_list_last((struct ptr_list **)head);
158 static inline void *first_ptr_list(struct ptr_list *list)
160 if (!list)
161 return NULL;
162 return list->list[0];
165 static inline void *last_ptr_list(struct ptr_list *list)
168 if (!list)
169 return NULL;
170 list = list->prev;
171 return list->list[list->nr-1];
174 static inline void * current_iterator(struct list_iterator *iterator)
176 struct ptr_list *list = iterator->active;
177 return list ? list->list[iterator->index] : NULL;
180 static inline struct basic_block *first_basic_block(struct basic_block_list *head)
182 return last_ptr_list((struct ptr_list *)head);
184 static inline struct instruction *last_instruction(struct instruction_list *head)
186 return last_ptr_list((struct ptr_list *)head);
189 static inline struct instruction *first_instruction(struct instruction_list *head)
191 return first_ptr_list((struct ptr_list *)head);
194 static inline int replace_basic_block_list(struct basic_block_list **head, struct basic_block *from, struct basic_block *to)
196 return replace_ptr_list((struct ptr_list **)head, (void*)from, (void*)to);
199 static inline void concat_symbol_list(struct symbol_list *from, struct symbol_list **to)
201 concat_ptr_list((struct ptr_list *)from, (struct ptr_list **)to);
204 static inline void concat_basic_block_list(struct basic_block_list *from, struct basic_block_list **to)
206 concat_ptr_list((struct ptr_list *)from, (struct ptr_list **)to);
209 static inline void concat_instruction_list(struct instruction_list *from, struct instruction_list **to)
211 concat_ptr_list((struct ptr_list *)from, (struct ptr_list **)to);
214 static inline void add_symbol(struct symbol_list **list, struct symbol *sym)
216 add_ptr_list((struct ptr_list **)list, sym);
219 static inline void add_statement(struct statement_list **list, struct statement *stmt)
221 add_ptr_list((struct ptr_list **)list, stmt);
224 static inline void add_expression(struct expression_list **list, struct expression *expr)
226 add_ptr_list((struct ptr_list **)list, expr);
229 static inline void symbol_iterate(struct symbol_list *list, void (*callback)(struct symbol *, void *, int), void *data)
231 iterate((struct ptr_list *)list, (void (*)(void *, void *, int))callback, data);
234 static inline void statement_iterate(struct statement_list *list, void (*callback)(struct statement *, void *, int), void *data)
236 iterate((struct ptr_list *)list, (void (*)(void *, void *, int))callback, data);
239 static inline void expression_iterate(struct expression_list *list, void (*callback)(struct expression *, void *, int), void *data)
241 iterate((struct ptr_list *)list, (void (*)(void *, void *, int))callback, data);
244 #define PREPARE_PTR_LIST(head, ptr) \
245 do { \
246 struct ptr_list *__head##ptr = (struct ptr_list *) (head); \
247 struct ptr_list *__list##ptr = __head##ptr; \
248 int __nr##ptr = 0; \
249 if (__head##ptr) ptr = (__typeof__(ptr)) __head##ptr->list[0]; \
250 else ptr = NULL
252 #define NEXT_PTR_LIST(ptr) \
253 if (ptr) { \
254 if (++__nr##ptr < __list##ptr->nr) { \
255 ptr = (__typeof__(ptr)) __list##ptr->list[__nr##ptr]; \
256 } else { \
257 __list##ptr = __list##ptr->next; \
258 ptr = NULL; \
259 if (__list##ptr != __head##ptr) { \
260 __nr##ptr = 0; \
261 ptr = (__typeof__(ptr)) __list##ptr->list[0]; \
266 #define RESET_PTR_LIST(ptr) do { \
267 __nr##ptr = 0; \
268 __list##ptr = __head##ptr; \
269 if (__head##ptr) ptr = (__typeof__(ptr)) __head##ptr->list[0]; \
270 } while (0)
273 #define FINISH_PTR_LIST(ptr) \
274 (void)(__nr##ptr); /* Sanity-check nesting */ \
275 } while (0)
277 #define FOR_EACH_PTR(head, ptr) do { \
278 struct ptr_list *__head = (struct ptr_list *) (head); \
279 struct ptr_list *__list = __head; \
280 int __flag = ITERATE_FIRST; \
281 if (__head) { \
282 do { int __i; \
283 for (__i = 0; __i < __list->nr; __i++) { \
284 if (__i == __list->nr-1 && __list->next == __head) \
285 __flag |= ITERATE_LAST; \
286 do { \
287 ptr = (__typeof__(ptr)) (__list->list[__i]); \
288 do {
290 #define END_FOR_EACH_PTR } while (0); \
291 } while (0); \
292 __flag = 0; \
294 } while ((__list = __list->next) != __head); \
296 } while (0)
298 #define FOR_EACH_PTR_REVERSE(head, ptr) do { \
299 struct ptr_list *__head = (struct ptr_list *) (head); \
300 struct ptr_list *__list = __head; \
301 int __flag = ITERATE_FIRST; \
302 if (__head) { \
303 do { int __i; \
304 __list = __list->prev; \
305 __i = __list->nr; \
306 while (--__i >= 0) { \
307 if (__i == 0 && __list == __head) \
308 __flag |= ITERATE_LAST; \
309 do { \
310 ptr = (__typeof__(ptr)) (__list->list[__i]); \
311 do {
313 #define END_FOR_EACH_PTR_REVERSE } while (0); \
314 } while (0); \
315 __flag = 0; \
317 } while (__list != __head); \
319 } while (0)
321 #define THIS_ADDRESS(x) \
322 ((__typeof__(&(x))) (__list->list + __i))
324 #endif