xref: /illumos-gate/usr/src/tools/smatch/src/symbol.h (revision c85f09cc92abd00c84e58ec9f0f5d942906cb713)
11f5207b7SJohn Levon #ifndef SYMBOL_H
21f5207b7SJohn Levon #define SYMBOL_H
31f5207b7SJohn Levon /*
41f5207b7SJohn Levon  * Basic symbol and namespace definitions.
51f5207b7SJohn Levon  *
61f5207b7SJohn Levon  * Copyright (C) 2003 Transmeta Corp.
71f5207b7SJohn Levon  *               2003 Linus Torvalds
81f5207b7SJohn Levon  *
91f5207b7SJohn Levon  * Permission is hereby granted, free of charge, to any person obtaining a copy
101f5207b7SJohn Levon  * of this software and associated documentation files (the "Software"), to deal
111f5207b7SJohn Levon  * in the Software without restriction, including without limitation the rights
121f5207b7SJohn Levon  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
131f5207b7SJohn Levon  * copies of the Software, and to permit persons to whom the Software is
141f5207b7SJohn Levon  * furnished to do so, subject to the following conditions:
151f5207b7SJohn Levon  *
161f5207b7SJohn Levon  * The above copyright notice and this permission notice shall be included in
171f5207b7SJohn Levon  * all copies or substantial portions of the Software.
181f5207b7SJohn Levon  *
191f5207b7SJohn Levon  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
201f5207b7SJohn Levon  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
211f5207b7SJohn Levon  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
221f5207b7SJohn Levon  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
231f5207b7SJohn Levon  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
241f5207b7SJohn Levon  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
251f5207b7SJohn Levon  * THE SOFTWARE.
261f5207b7SJohn Levon  */
271f5207b7SJohn Levon 
281f5207b7SJohn Levon #include "token.h"
291f5207b7SJohn Levon #include "target.h"
301f5207b7SJohn Levon 
311f5207b7SJohn Levon /*
321f5207b7SJohn Levon  * An identifier with semantic meaning is a "symbol".
331f5207b7SJohn Levon  *
341f5207b7SJohn Levon  * There's a 1:n relationship: each symbol is always
351f5207b7SJohn Levon  * associated with one identifier, while each identifier
361f5207b7SJohn Levon  * can have one or more semantic meanings due to C scope
371f5207b7SJohn Levon  * rules.
381f5207b7SJohn Levon  *
391f5207b7SJohn Levon  * The progression is symbol -> token -> identifier. The
401f5207b7SJohn Levon  * token contains the information on where the symbol was
411f5207b7SJohn Levon  * declared.
421f5207b7SJohn Levon  */
431f5207b7SJohn Levon enum namespace {
441f5207b7SJohn Levon 	NS_NONE = 0,
451f5207b7SJohn Levon 	NS_MACRO = 1,
461f5207b7SJohn Levon 	NS_TYPEDEF = 2,
471f5207b7SJohn Levon 	NS_STRUCT = 4,  // Also used for unions and enums.
481f5207b7SJohn Levon 	NS_LABEL = 8,
491f5207b7SJohn Levon 	NS_SYMBOL = 16,
501f5207b7SJohn Levon 	NS_ITERATOR = 32,
511f5207b7SJohn Levon 	NS_PREPROCESSOR = 64,
521f5207b7SJohn Levon 	NS_UNDEF = 128,
531f5207b7SJohn Levon 	NS_KEYWORD = 256,
541f5207b7SJohn Levon };
551f5207b7SJohn Levon 
561f5207b7SJohn Levon enum type {
571f5207b7SJohn Levon 	SYM_UNINITIALIZED,
581f5207b7SJohn Levon 	SYM_PREPROCESSOR,
591f5207b7SJohn Levon 	SYM_BASETYPE,
601f5207b7SJohn Levon 	SYM_NODE,
611f5207b7SJohn Levon 	SYM_PTR,
621f5207b7SJohn Levon 	SYM_FN,
631f5207b7SJohn Levon 	SYM_ARRAY,
641f5207b7SJohn Levon 	SYM_STRUCT,
651f5207b7SJohn Levon 	SYM_UNION,
661f5207b7SJohn Levon 	SYM_ENUM,
671f5207b7SJohn Levon 	SYM_TYPEDEF,
681f5207b7SJohn Levon 	SYM_TYPEOF,
691f5207b7SJohn Levon 	SYM_MEMBER,
701f5207b7SJohn Levon 	SYM_BITFIELD,
711f5207b7SJohn Levon 	SYM_LABEL,
721f5207b7SJohn Levon 	SYM_RESTRICT,
731f5207b7SJohn Levon 	SYM_FOULED,
741f5207b7SJohn Levon 	SYM_KEYWORD,
751f5207b7SJohn Levon 	SYM_BAD,
761f5207b7SJohn Levon };
771f5207b7SJohn Levon 
781f5207b7SJohn Levon enum keyword {
791f5207b7SJohn Levon 	KW_SPECIFIER 	= 1 << 0,
801f5207b7SJohn Levon 	KW_MODIFIER	= 1 << 1,
811f5207b7SJohn Levon 	KW_QUALIFIER	= 1 << 2,
821f5207b7SJohn Levon 	KW_ATTRIBUTE	= 1 << 3,
831f5207b7SJohn Levon 	KW_STATEMENT	= 1 << 4,
841f5207b7SJohn Levon 	KW_ASM		= 1 << 5,
851f5207b7SJohn Levon 	KW_MODE		= 1 << 6,
861f5207b7SJohn Levon 	KW_SHORT	= 1 << 7,
871f5207b7SJohn Levon 	KW_LONG		= 1 << 8,
881f5207b7SJohn Levon 	KW_EXACT	= 1 << 9,
891f5207b7SJohn Levon };
901f5207b7SJohn Levon 
911f5207b7SJohn Levon struct context {
921f5207b7SJohn Levon 	struct expression *context;
931f5207b7SJohn Levon 	unsigned int in, out;
941f5207b7SJohn Levon };
951f5207b7SJohn Levon 
961f5207b7SJohn Levon extern struct context *alloc_context(void);
971f5207b7SJohn Levon 
981f5207b7SJohn Levon DECLARE_PTR_LIST(context_list, struct context);
991f5207b7SJohn Levon 
1001f5207b7SJohn Levon struct ctype {
1011f5207b7SJohn Levon 	unsigned long modifiers;
1021f5207b7SJohn Levon 	unsigned long alignment;
1031f5207b7SJohn Levon 	struct context_list *contexts;
104*c85f09ccSJohn Levon 	struct ident *as;
1051f5207b7SJohn Levon 	struct symbol *base_type;
1061f5207b7SJohn Levon };
1071f5207b7SJohn Levon 
1081f5207b7SJohn Levon struct decl_state {
1091f5207b7SJohn Levon 	struct ctype ctype;
1101f5207b7SJohn Levon 	struct ident **ident;
1111f5207b7SJohn Levon 	struct symbol_op *mode;
1121f5207b7SJohn Levon 	unsigned char prefer_abstract, is_inline, storage_class, is_tls;
113*c85f09ccSJohn Levon 	unsigned char is_ext_visible;
1141f5207b7SJohn Levon };
1151f5207b7SJohn Levon 
1161f5207b7SJohn Levon struct symbol_op {
1171f5207b7SJohn Levon 	enum keyword type;
1181f5207b7SJohn Levon 	int (*evaluate)(struct expression *);
1191f5207b7SJohn Levon 	int (*expand)(struct expression *, int);
1201f5207b7SJohn Levon 	int (*args)(struct expression *);
1211f5207b7SJohn Levon 
1221f5207b7SJohn Levon 	/* keywords */
1231f5207b7SJohn Levon 	struct token *(*declarator)(struct token *token, struct decl_state *ctx);
1241f5207b7SJohn Levon 	struct token *(*statement)(struct token *token, struct statement *stmt);
1251f5207b7SJohn Levon 	struct token *(*toplevel)(struct token *token, struct symbol_list **list);
1261f5207b7SJohn Levon 	struct token *(*attribute)(struct token *token, struct symbol *attr, struct decl_state *ctx);
1271f5207b7SJohn Levon 	struct symbol *(*to_mode)(struct symbol *);
128*c85f09ccSJohn Levon 	void          (*asm_modifier)(struct token *token, unsigned long *mods);
1291f5207b7SJohn Levon 
1301f5207b7SJohn Levon 	int test, set, class;
1311f5207b7SJohn Levon };
1321f5207b7SJohn Levon 
1331f5207b7SJohn Levon 
1341f5207b7SJohn Levon #define SYM_ATTR_WEAK		0
1351f5207b7SJohn Levon #define SYM_ATTR_NORMAL		1
1361f5207b7SJohn Levon #define SYM_ATTR_STRONG		2
1371f5207b7SJohn Levon 
1381f5207b7SJohn Levon struct symbol {
1391f5207b7SJohn Levon 	enum type type:8;
1401f5207b7SJohn Levon 	enum namespace namespace:9;
1411f5207b7SJohn Levon 	unsigned char used:1, attr:2, enum_member:1, bound:1;
1421f5207b7SJohn Levon 	struct position pos;		/* Where this symbol was declared */
1431f5207b7SJohn Levon 	struct position endpos;		/* Where this symbol ends*/
1441f5207b7SJohn Levon 	struct ident *ident;		/* What identifier this symbol is associated with */
1451f5207b7SJohn Levon 	struct symbol *next_id;		/* Next semantic symbol that shares this identifier */
1461f5207b7SJohn Levon 	struct symbol	*replace;	/* What is this symbol shadowed by in copy-expression */
1471f5207b7SJohn Levon 	struct scope	*scope;
1481f5207b7SJohn Levon 	union {
1491f5207b7SJohn Levon 		struct symbol	*same_symbol;
1501f5207b7SJohn Levon 		struct symbol	*next_subobject;
1511f5207b7SJohn Levon 	};
1521f5207b7SJohn Levon 
1531f5207b7SJohn Levon 	struct symbol_op *op;
1541f5207b7SJohn Levon 
1551f5207b7SJohn Levon 	union {
1561f5207b7SJohn Levon 		struct /* NS_MACRO */ {
1571f5207b7SJohn Levon 			struct token *expansion;
1581f5207b7SJohn Levon 			struct token *arglist;
1591f5207b7SJohn Levon 			struct scope *used_in;
160*c85f09ccSJohn Levon 			void (*expander)(struct token *);
1611f5207b7SJohn Levon 		};
1621f5207b7SJohn Levon 		struct /* NS_PREPROCESSOR */ {
1631f5207b7SJohn Levon 			int (*handler)(struct stream *, struct token **, struct token *);
1641f5207b7SJohn Levon 			int normal;
1651f5207b7SJohn Levon 		};
1661f5207b7SJohn Levon 		struct /* NS_SYMBOL */ {
1671f5207b7SJohn Levon 			unsigned long	offset;
1681f5207b7SJohn Levon 			int		bit_size;
1691f5207b7SJohn Levon 			unsigned int	bit_offset:8,
1701f5207b7SJohn Levon 					variadic:1,
1711f5207b7SJohn Levon 					initialized:1,
1721f5207b7SJohn Levon 					examined:1,
1731f5207b7SJohn Levon 					expanding:1,
1741f5207b7SJohn Levon 					evaluated:1,
1751f5207b7SJohn Levon 					string:1,
1761f5207b7SJohn Levon 					designated_init:1,
1771f5207b7SJohn Levon 					forced_arg:1,
178*c85f09ccSJohn Levon 					accessed:1,
179*c85f09ccSJohn Levon 					builtin:1,
180*c85f09ccSJohn Levon 					torename:1,
1811f5207b7SJohn Levon 					transparent_union:1;
1821f5207b7SJohn Levon 			struct expression *array_size;
1831f5207b7SJohn Levon 			struct ctype ctype;
1841f5207b7SJohn Levon 			struct symbol_list *arguments;
1851f5207b7SJohn Levon 			struct statement *stmt;
1861f5207b7SJohn Levon 			struct symbol_list *symbol_list;
1871f5207b7SJohn Levon 			struct statement *inline_stmt;
1881f5207b7SJohn Levon 			struct symbol_list *inline_symbol_list;
1891f5207b7SJohn Levon 			struct expression *initializer;
1901f5207b7SJohn Levon 			struct entrypoint *ep;
1911f5207b7SJohn Levon 			struct symbol *definition;
1921f5207b7SJohn Levon 		};
1931f5207b7SJohn Levon 	};
1941f5207b7SJohn Levon 	union /* backend */ {
1951f5207b7SJohn Levon 		struct basic_block *bb_target;	/* label */
1961f5207b7SJohn Levon 		void *aux;			/* Auxiliary info, e.g. backend information */
1971f5207b7SJohn Levon 		struct {			/* sparse ctags */
1981f5207b7SJohn Levon 			char kind;
1991f5207b7SJohn Levon 			unsigned char visited:1;
2001f5207b7SJohn Levon 		};
2011f5207b7SJohn Levon 	};
2021f5207b7SJohn Levon 	pseudo_t pseudo;
2031f5207b7SJohn Levon };
2041f5207b7SJohn Levon 
2051f5207b7SJohn Levon /* Modifiers */
206*c85f09ccSJohn Levon #define MOD_AUTO		0x00000001
207*c85f09ccSJohn Levon #define MOD_REGISTER		0x00000002
208*c85f09ccSJohn Levon #define MOD_STATIC		0x00000004
209*c85f09ccSJohn Levon #define MOD_EXTERN		0x00000008
210*c85f09ccSJohn Levon #define MOD_TOPLEVEL		0x00000010	// scoping..
211*c85f09ccSJohn Levon #define MOD_TLS			0x00000020
212*c85f09ccSJohn Levon #define MOD_ASM_GOTO		MOD_TLS		// never used together
213*c85f09ccSJohn Levon #define MOD_INLINE		0x00000040
2141f5207b7SJohn Levon 
215*c85f09ccSJohn Levon #define MOD_ASSIGNED		0x00000080
216*c85f09ccSJohn Levon #define MOD_ADDRESSABLE		0x00000100
2171f5207b7SJohn Levon 
218*c85f09ccSJohn Levon #define MOD_CONST		0x00000200
219*c85f09ccSJohn Levon #define MOD_VOLATILE		0x00000400
220*c85f09ccSJohn Levon #define MOD_RESTRICT		0x00000800
221*c85f09ccSJohn Levon #define MOD_ATOMIC		0x00001000
2221f5207b7SJohn Levon 
223*c85f09ccSJohn Levon #define MOD_SIGNED		0x00002000
224*c85f09ccSJohn Levon #define MOD_UNSIGNED		0x00004000
225*c85f09ccSJohn Levon #define MOD_EXPLICITLY_SIGNED	0x00008000
2261f5207b7SJohn Levon 
227*c85f09ccSJohn Levon #define MOD_TYPE		0x00010000
228*c85f09ccSJohn Levon #define MOD_USERTYPE		0x00020000
229*c85f09ccSJohn Levon #define MOD_CHAR		0x00040000
230*c85f09ccSJohn Levon #define MOD_SHORT		0x00080000
231*c85f09ccSJohn Levon #define MOD_LONG		0x00100000
232*c85f09ccSJohn Levon #define MOD_LONGLONG		0x00200000
233*c85f09ccSJohn Levon #define MOD_LONGLONGLONG	0x00400000
2341f5207b7SJohn Levon 
235*c85f09ccSJohn Levon #define MOD_SAFE		0x00800000	// non-null/non-trapping pointer
236*c85f09ccSJohn Levon #define MOD_PURE		0x01000000
237*c85f09ccSJohn Levon #define MOD_BITWISE		0x02000000
238*c85f09ccSJohn Levon #define MOD_NOCAST		0x04000000
239*c85f09ccSJohn Levon #define MOD_NODEREF		0x08000000
240*c85f09ccSJohn Levon #define MOD_NORETURN		0x10000000
241*c85f09ccSJohn Levon #define MOD_EXT_VISIBLE		0x20000000
2421f5207b7SJohn Levon 
2431f5207b7SJohn Levon 
244*c85f09ccSJohn Levon #define MOD_ACCESS	(MOD_ASSIGNED | MOD_ADDRESSABLE)
2451f5207b7SJohn Levon #define MOD_NONLOCAL	(MOD_EXTERN | MOD_TOPLEVEL)
2461f5207b7SJohn Levon #define MOD_STORAGE	(MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | MOD_INLINE | MOD_TOPLEVEL)
2471f5207b7SJohn Levon #define MOD_SIGNEDNESS	(MOD_SIGNED | MOD_UNSIGNED | MOD_EXPLICITLY_SIGNED)
2481f5207b7SJohn Levon #define MOD_LONG_ALL	(MOD_LONG | MOD_LONGLONG | MOD_LONGLONGLONG)
2491f5207b7SJohn Levon #define MOD_SPECIFIER	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL | MOD_SIGNEDNESS)
2501f5207b7SJohn Levon #define MOD_SIZE	(MOD_CHAR | MOD_SHORT | MOD_LONG_ALL)
251*c85f09ccSJohn Levon #define MOD_IGNORE	(MOD_STORAGE | MOD_ACCESS | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED | MOD_EXT_VISIBLE)
252*c85f09ccSJohn Levon #define	MOD_QUALIFIER	(MOD_CONST | MOD_VOLATILE | MOD_RESTRICT | MOD_ATOMIC)
253*c85f09ccSJohn Levon #define MOD_PTRINHERIT	(MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
2541f5207b7SJohn Levon /* modifiers preserved by typeof() operator */
255*c85f09ccSJohn Levon #define MOD_TYPEOF	(MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER)
2561f5207b7SJohn Levon 
2571f5207b7SJohn Levon 
2581f5207b7SJohn Levon /* Current parsing/evaluation function */
2591f5207b7SJohn Levon extern struct symbol *current_fn;
2601f5207b7SJohn Levon 
2611f5207b7SJohn Levon /* Abstract types */
2621f5207b7SJohn Levon extern struct symbol	int_type,
2631f5207b7SJohn Levon 			fp_type;
2641f5207b7SJohn Levon 
2651f5207b7SJohn Levon /* C types */
2661f5207b7SJohn Levon extern struct symbol	bool_ctype, void_ctype, type_ctype,
2671f5207b7SJohn Levon 			char_ctype, schar_ctype, uchar_ctype,
2681f5207b7SJohn Levon 			short_ctype, sshort_ctype, ushort_ctype,
2691f5207b7SJohn Levon 			int_ctype, sint_ctype, uint_ctype,
2701f5207b7SJohn Levon 			long_ctype, slong_ctype, ulong_ctype,
2711f5207b7SJohn Levon 			llong_ctype, sllong_ctype, ullong_ctype,
2721f5207b7SJohn Levon 			lllong_ctype, slllong_ctype, ulllong_ctype,
2731f5207b7SJohn Levon 			float_ctype, double_ctype, ldouble_ctype,
2741f5207b7SJohn Levon 			string_ctype, ptr_ctype, lazy_ptr_ctype,
2751f5207b7SJohn Levon 			incomplete_ctype, label_ctype, bad_ctype,
2761f5207b7SJohn Levon 			null_ctype;
277*c85f09ccSJohn Levon extern struct symbol	int_ptr_ctype, uint_ptr_ctype;
278*c85f09ccSJohn Levon extern struct symbol	long_ptr_ctype, ulong_ptr_ctype;
279*c85f09ccSJohn Levon extern struct symbol	llong_ptr_ctype, ullong_ptr_ctype;
280*c85f09ccSJohn Levon extern struct symbol	float32_ctype, float32x_ctype;
281*c85f09ccSJohn Levon extern struct symbol	float64_ctype, float64x_ctype;
282*c85f09ccSJohn Levon extern struct symbol	float128_ctype;
283*c85f09ccSJohn Levon extern struct symbol	const_void_ctype, const_char_ctype;
284*c85f09ccSJohn Levon extern struct symbol	const_ptr_ctype, const_string_ctype;
285*c85f09ccSJohn Levon 
286*c85f09ccSJohn Levon #define	uintptr_ctype	 size_t_ctype
287*c85f09ccSJohn Levon #define	 intptr_ctype	ssize_t_ctype
2881f5207b7SJohn Levon 
2891f5207b7SJohn Levon /* Special internal symbols */
2901f5207b7SJohn Levon extern struct symbol	zero_int;
2911f5207b7SJohn Levon 
2921f5207b7SJohn Levon #define __IDENT(n,str,res) \
2931f5207b7SJohn Levon 	extern struct ident n
2941f5207b7SJohn Levon #include "ident-list.h"
2951f5207b7SJohn Levon 
2961f5207b7SJohn Levon 
2971f5207b7SJohn Levon extern struct symbol_list *translation_unit_used_list;
2981f5207b7SJohn Levon 
2991f5207b7SJohn Levon extern void access_symbol(struct symbol *);
3001f5207b7SJohn Levon 
3011f5207b7SJohn Levon extern const char * type_difference(struct ctype *c1, struct ctype *c2,
3021f5207b7SJohn Levon 	unsigned long mod1, unsigned long mod2);
3031f5207b7SJohn Levon 
3041f5207b7SJohn Levon extern struct symbol *lookup_symbol(struct ident *, enum namespace);
3051f5207b7SJohn Levon extern struct symbol *create_symbol(int stream, const char *name, int type, int namespace);
3061f5207b7SJohn Levon extern void init_symbols(void);
3071f5207b7SJohn Levon extern void init_builtins(int stream);
308*c85f09ccSJohn Levon extern void declare_builtins(void);
3091f5207b7SJohn Levon extern void init_ctype(void);
310*c85f09ccSJohn Levon extern void init_target(void);
3111f5207b7SJohn Levon extern struct symbol *alloc_symbol(struct position, int type);
3121f5207b7SJohn Levon extern void show_type(struct symbol *);
3131f5207b7SJohn Levon extern const char *modifier_string(unsigned long mod);
3141f5207b7SJohn Levon extern void show_symbol(struct symbol *);
3151f5207b7SJohn Levon extern int show_symbol_expr_init(struct symbol *sym);
3161f5207b7SJohn Levon extern void show_type_list(struct symbol *);
3171f5207b7SJohn Levon extern void show_symbol_list(struct symbol_list *, const char *);
3181f5207b7SJohn Levon extern void add_symbol(struct symbol_list **, struct symbol *);
3191f5207b7SJohn Levon extern void bind_symbol(struct symbol *, struct ident *, enum namespace);
3201f5207b7SJohn Levon 
3211f5207b7SJohn Levon extern struct symbol *examine_symbol_type(struct symbol *);
3221f5207b7SJohn Levon extern struct symbol *examine_pointer_target(struct symbol *);
323*c85f09ccSJohn Levon extern const char *show_as(struct ident *as);
3241f5207b7SJohn Levon extern const char *show_typename(struct symbol *sym);
3251f5207b7SJohn Levon extern const char *builtin_typename(struct symbol *sym);
326*c85f09ccSJohn Levon extern const char *builtin_type_suffix(struct symbol *sym);
3271f5207b7SJohn Levon extern const char *builtin_ctypename(struct ctype *ctype);
3281f5207b7SJohn Levon extern const char* get_type_name(enum type type);
3291f5207b7SJohn Levon 
3301f5207b7SJohn Levon extern void debug_symbol(struct symbol *);
3311f5207b7SJohn Levon extern void merge_type(struct symbol *sym, struct symbol *base_type);
3321f5207b7SJohn Levon extern void check_declaration(struct symbol *sym);
333*c85f09ccSJohn Levon extern void check_duplicates(struct symbol *sym);
334*c85f09ccSJohn Levon 
valid_type(const struct symbol * ctype)335*c85f09ccSJohn Levon static inline int valid_type(const struct symbol *ctype)
336*c85f09ccSJohn Levon {
337*c85f09ccSJohn Levon 	return ctype && ctype != &bad_ctype;
338*c85f09ccSJohn Levon }
3391f5207b7SJohn Levon 
get_base_type(const struct symbol * sym)3401f5207b7SJohn Levon static inline struct symbol *get_base_type(const struct symbol *sym)
3411f5207b7SJohn Levon {
3421f5207b7SJohn Levon 	return examine_symbol_type(sym->ctype.base_type);
3431f5207b7SJohn Levon }
3441f5207b7SJohn Levon 
345*c85f09ccSJohn Levon ///
346*c85f09ccSJohn Levon // test if type is an integer type
347*c85f09ccSJohn Levon //
348*c85f09ccSJohn Levon // @return: ``1`` for plain integer type, enums & bitfields
349*c85f09ccSJohn Levon //	but ``0`` for bitwise types!
is_int_type(const struct symbol * type)3501f5207b7SJohn Levon static inline int is_int_type(const struct symbol *type)
3511f5207b7SJohn Levon {
3521f5207b7SJohn Levon 	if (type->type == SYM_NODE)
3531f5207b7SJohn Levon 		type = type->ctype.base_type;
3541f5207b7SJohn Levon 	if (type->type == SYM_ENUM)
3551f5207b7SJohn Levon 		type = type->ctype.base_type;
3561f5207b7SJohn Levon 	return type->type == SYM_BITFIELD ||
3571f5207b7SJohn Levon 	       type->ctype.base_type == &int_type;
3581f5207b7SJohn Levon }
3591f5207b7SJohn Levon 
is_enum_type(const struct symbol * type)3601f5207b7SJohn Levon static inline int is_enum_type(const struct symbol *type)
3611f5207b7SJohn Levon {
3621f5207b7SJohn Levon 	if (type->type == SYM_NODE)
3631f5207b7SJohn Levon 		type = type->ctype.base_type;
3641f5207b7SJohn Levon 	return (type->type == SYM_ENUM);
3651f5207b7SJohn Levon }
3661f5207b7SJohn Levon 
is_signed_type(struct symbol * sym)367*c85f09ccSJohn Levon static inline int is_signed_type(struct symbol *sym)
368*c85f09ccSJohn Levon {
369*c85f09ccSJohn Levon 	if (sym->type == SYM_NODE)
370*c85f09ccSJohn Levon 		sym = sym->ctype.base_type;
371*c85f09ccSJohn Levon 	if (sym->type == SYM_PTR)
372*c85f09ccSJohn Levon 		return 0;
373*c85f09ccSJohn Levon 	return !(sym->ctype.modifiers & MOD_UNSIGNED);
374*c85f09ccSJohn Levon }
375*c85f09ccSJohn Levon 
is_type_type(struct symbol * type)3761f5207b7SJohn Levon static inline int is_type_type(struct symbol *type)
3771f5207b7SJohn Levon {
3781f5207b7SJohn Levon 	return (type->ctype.modifiers & MOD_TYPE) != 0;
3791f5207b7SJohn Levon }
3801f5207b7SJohn Levon 
is_ptr_type(struct symbol * type)3811f5207b7SJohn Levon static inline int is_ptr_type(struct symbol *type)
3821f5207b7SJohn Levon {
3831f5207b7SJohn Levon 	if (!type)
3841f5207b7SJohn Levon 		return 0;
3851f5207b7SJohn Levon 	if (type->type == SYM_NODE)
3861f5207b7SJohn Levon 		type = type->ctype.base_type;
3871f5207b7SJohn Levon 	return type->type == SYM_PTR || type->type == SYM_ARRAY || type->type == SYM_FN;
3881f5207b7SJohn Levon }
3891f5207b7SJohn Levon 
is_func_type(struct symbol * type)3901f5207b7SJohn Levon static inline int is_func_type(struct symbol *type)
3911f5207b7SJohn Levon {
3921f5207b7SJohn Levon 	if (type->type == SYM_NODE)
3931f5207b7SJohn Levon 		type = type->ctype.base_type;
3941f5207b7SJohn Levon 	return type->type == SYM_FN;
3951f5207b7SJohn Levon }
3961f5207b7SJohn Levon 
is_array_type(struct symbol * type)3971f5207b7SJohn Levon static inline int is_array_type(struct symbol *type)
3981f5207b7SJohn Levon {
3991f5207b7SJohn Levon 	if (type->type == SYM_NODE)
4001f5207b7SJohn Levon 		type = type->ctype.base_type;
4011f5207b7SJohn Levon 	return type->type == SYM_ARRAY;
4021f5207b7SJohn Levon }
4031f5207b7SJohn Levon 
is_float_type(struct symbol * type)4041f5207b7SJohn Levon static inline int is_float_type(struct symbol *type)
4051f5207b7SJohn Levon {
4061f5207b7SJohn Levon 	if (type->type == SYM_NODE)
4071f5207b7SJohn Levon 		type = type->ctype.base_type;
4081f5207b7SJohn Levon 	return type->ctype.base_type == &fp_type;
4091f5207b7SJohn Levon }
4101f5207b7SJohn Levon 
is_byte_type(struct symbol * type)4111f5207b7SJohn Levon static inline int is_byte_type(struct symbol *type)
4121f5207b7SJohn Levon {
4131f5207b7SJohn Levon 	return type->bit_size == bits_in_char && type->type != SYM_BITFIELD;
4141f5207b7SJohn Levon }
4151f5207b7SJohn Levon 
is_void_type(struct symbol * type)4161f5207b7SJohn Levon static inline int is_void_type(struct symbol *type)
4171f5207b7SJohn Levon {
4181f5207b7SJohn Levon 	if (type->type == SYM_NODE)
4191f5207b7SJohn Levon 		type = type->ctype.base_type;
4201f5207b7SJohn Levon 	return type == &void_ctype;
4211f5207b7SJohn Levon }
4221f5207b7SJohn Levon 
is_bool_type(struct symbol * type)4231f5207b7SJohn Levon static inline int is_bool_type(struct symbol *type)
4241f5207b7SJohn Levon {
4251f5207b7SJohn Levon 	if (type->type == SYM_NODE)
4261f5207b7SJohn Levon 		type = type->ctype.base_type;
4271f5207b7SJohn Levon 	return type == &bool_ctype;
4281f5207b7SJohn Levon }
4291f5207b7SJohn Levon 
is_scalar_type(struct symbol * type)4301f5207b7SJohn Levon static inline int is_scalar_type(struct symbol *type)
4311f5207b7SJohn Levon {
4321f5207b7SJohn Levon 	if (type->type == SYM_NODE)
4331f5207b7SJohn Levon 		type = type->ctype.base_type;
4341f5207b7SJohn Levon 	switch (type->type) {
4351f5207b7SJohn Levon 	case SYM_ENUM:
4361f5207b7SJohn Levon 	case SYM_BITFIELD:
4371f5207b7SJohn Levon 	case SYM_PTR:
4381f5207b7SJohn Levon 	case SYM_RESTRICT:	// OK, always integer types
4391f5207b7SJohn Levon 		return 1;
4401f5207b7SJohn Levon 	default:
4411f5207b7SJohn Levon 		break;
4421f5207b7SJohn Levon 	}
4431f5207b7SJohn Levon 	if (type->ctype.base_type == &int_type)
4441f5207b7SJohn Levon 		return 1;
4451f5207b7SJohn Levon 	if (type->ctype.base_type == &fp_type)
4461f5207b7SJohn Levon 		return 1;
4471f5207b7SJohn Levon 	return 0;
4481f5207b7SJohn Levon }
4491f5207b7SJohn Levon 
450*c85f09ccSJohn Levon /// return true for integer & pointer types
is_integral_type(struct symbol * type)451*c85f09ccSJohn Levon static inline bool is_integral_type(struct symbol *type)
452*c85f09ccSJohn Levon {
453*c85f09ccSJohn Levon 	if (type->type == SYM_NODE)
454*c85f09ccSJohn Levon 		type = type->ctype.base_type;
455*c85f09ccSJohn Levon 	switch (type->type) {
456*c85f09ccSJohn Levon 	case SYM_ENUM:
457*c85f09ccSJohn Levon 	case SYM_PTR:
458*c85f09ccSJohn Levon 	case SYM_RESTRICT:	// OK, always integer types
459*c85f09ccSJohn Levon 		return 1;
460*c85f09ccSJohn Levon 	default:
461*c85f09ccSJohn Levon 		break;
462*c85f09ccSJohn Levon 	}
463*c85f09ccSJohn Levon 	if (type->ctype.base_type == &int_type)
464*c85f09ccSJohn Levon 		return 1;
465*c85f09ccSJohn Levon 	return 0;
466*c85f09ccSJohn Levon }
467*c85f09ccSJohn Levon 
is_function(struct symbol * type)4681f5207b7SJohn Levon static inline int is_function(struct symbol *type)
4691f5207b7SJohn Levon {
4701f5207b7SJohn Levon 	return type && type->type == SYM_FN;
4711f5207b7SJohn Levon }
4721f5207b7SJohn Levon 
is_extern_inline(struct symbol * sym)4731f5207b7SJohn Levon static inline int is_extern_inline(struct symbol *sym)
4741f5207b7SJohn Levon {
4751f5207b7SJohn Levon 	return (sym->ctype.modifiers & MOD_EXTERN) &&
4761f5207b7SJohn Levon 		(sym->ctype.modifiers & MOD_INLINE) &&
4771f5207b7SJohn Levon 		is_function(sym->ctype.base_type);
4781f5207b7SJohn Levon }
4791f5207b7SJohn Levon 
get_sym_type(struct symbol * type)4801f5207b7SJohn Levon static inline int get_sym_type(struct symbol *type)
4811f5207b7SJohn Levon {
4821f5207b7SJohn Levon 	if (type->type == SYM_NODE)
4831f5207b7SJohn Levon 		type = type->ctype.base_type;
4841f5207b7SJohn Levon 	if (type->type == SYM_ENUM)
4851f5207b7SJohn Levon 		type = type->ctype.base_type;
4861f5207b7SJohn Levon 	return type->type;
4871f5207b7SJohn Levon }
4881f5207b7SJohn Levon 
extend_value(long long val,struct symbol * ctype)489*c85f09ccSJohn Levon static inline long long extend_value(long long val, struct symbol *ctype)
490*c85f09ccSJohn Levon {
491*c85f09ccSJohn Levon 	int is_signed = !(ctype->ctype.modifiers & MOD_UNSIGNED);
492*c85f09ccSJohn Levon 	unsigned size = ctype->bit_size;
493*c85f09ccSJohn Levon 
494*c85f09ccSJohn Levon 	return bits_extend(val, size, is_signed);
495*c85f09ccSJohn Levon }
496*c85f09ccSJohn Levon 
lookup_keyword(struct ident * ident,enum namespace ns)4971f5207b7SJohn Levon static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace ns)
4981f5207b7SJohn Levon {
4991f5207b7SJohn Levon 	if (!ident->keyword)
5001f5207b7SJohn Levon 		return NULL;
5011f5207b7SJohn Levon 	return lookup_symbol(ident, ns);
5021f5207b7SJohn Levon }
5031f5207b7SJohn Levon 
5041f5207b7SJohn Levon #define is_restricted_type(type) (get_sym_type(type) == SYM_RESTRICT)
5051f5207b7SJohn Levon #define is_fouled_type(type) (get_sym_type(type) == SYM_FOULED)
5061f5207b7SJohn Levon #define is_bitfield_type(type)   (get_sym_type(type) == SYM_BITFIELD)
5071f5207b7SJohn Levon 
5081f5207b7SJohn Levon void create_fouled(struct symbol *type);
5091f5207b7SJohn Levon struct symbol *befoul(struct symbol *type);
5101f5207b7SJohn Levon 
511*c85f09ccSJohn Levon 
512*c85f09ccSJohn Levon extern struct ident bad_address_space;
513*c85f09ccSJohn Levon 
valid_as(struct ident * as)514*c85f09ccSJohn Levon static inline bool valid_as(struct ident *as)
515*c85f09ccSJohn Levon {
516*c85f09ccSJohn Levon 	return as && as != &bad_address_space;
517*c85f09ccSJohn Levon }
518*c85f09ccSJohn Levon 
combine_address_space(struct position pos,struct ident ** tas,struct ident * sas)519*c85f09ccSJohn Levon static inline void combine_address_space(struct position pos,
520*c85f09ccSJohn Levon 	struct ident **tas, struct ident *sas)
521*c85f09ccSJohn Levon {
522*c85f09ccSJohn Levon 	struct ident *as;
523*c85f09ccSJohn Levon 	if (!sas)
524*c85f09ccSJohn Levon 		return;
525*c85f09ccSJohn Levon 	as = *tas;
526*c85f09ccSJohn Levon 	if (!as)
527*c85f09ccSJohn Levon 		*tas = sas;
528*c85f09ccSJohn Levon 	else if (as != sas) {
529*c85f09ccSJohn Levon 		*tas = &bad_address_space;
530*c85f09ccSJohn Levon 		sparse_error(pos, "multiple address spaces given");
531*c85f09ccSJohn Levon 	}
532*c85f09ccSJohn Levon }
533*c85f09ccSJohn Levon 
5341f5207b7SJohn Levon #endif /* SYMBOL_H */
535