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