diff options
Diffstat (limited to 'usr/src/tools/smatch/src/symbol.h')
| -rw-r--r-- | usr/src/tools/smatch/src/symbol.h | 182 |
1 files changed, 134 insertions, 48 deletions
diff --git a/usr/src/tools/smatch/src/symbol.h b/usr/src/tools/smatch/src/symbol.h index 88959603c8..5c84516ecb 100644 --- a/usr/src/tools/smatch/src/symbol.h +++ b/usr/src/tools/smatch/src/symbol.h @@ -101,7 +101,7 @@ struct ctype { unsigned long modifiers; unsigned long alignment; struct context_list *contexts; - unsigned int as; + struct ident *as; struct symbol *base_type; }; @@ -110,6 +110,7 @@ struct decl_state { struct ident **ident; struct symbol_op *mode; unsigned char prefer_abstract, is_inline, storage_class, is_tls; + unsigned char is_ext_visible; }; struct symbol_op { @@ -124,6 +125,7 @@ struct symbol_op { struct token *(*toplevel)(struct token *token, struct symbol_list **list); struct token *(*attribute)(struct token *token, struct symbol *attr, struct decl_state *ctx); struct symbol *(*to_mode)(struct symbol *); + void (*asm_modifier)(struct token *token, unsigned long *mods); int test, set, class; }; @@ -155,6 +157,7 @@ struct symbol { struct token *expansion; struct token *arglist; struct scope *used_in; + void (*expander)(struct token *); }; struct /* NS_PREPROCESSOR */ { int (*handler)(struct stream *, struct token **, struct token *); @@ -164,7 +167,6 @@ struct symbol { unsigned long offset; int bit_size; unsigned int bit_offset:8, - arg_count:10, variadic:1, initialized:1, examined:1, @@ -173,6 +175,9 @@ struct symbol { string:1, designated_init:1, forced_arg:1, + accessed:1, + builtin:1, + torename:1, transparent_union:1; struct expression *array_size; struct ctype ctype; @@ -183,7 +188,6 @@ struct symbol { struct symbol_list *inline_symbol_list; struct expression *initializer; struct entrypoint *ep; - long long value; /* Initial value */ struct symbol *definition; }; }; @@ -199,55 +203,56 @@ struct symbol { }; /* Modifiers */ -#define MOD_AUTO 0x0001 -#define MOD_REGISTER 0x0002 -#define MOD_STATIC 0x0004 -#define MOD_EXTERN 0x0008 - -#define MOD_CONST 0x0010 -#define MOD_VOLATILE 0x0020 -#define MOD_SIGNED 0x0040 -#define MOD_UNSIGNED 0x0080 - -#define MOD_CHAR 0x0100 -#define MOD_SHORT 0x0200 -#define MOD_LONG 0x0400 -#define MOD_LONGLONG 0x0800 -#define MOD_LONGLONGLONG 0x1000 -#define MOD_PURE 0x2000 - -#define MOD_TYPEDEF 0x10000 - -#define MOD_TLS 0x20000 -#define MOD_INLINE 0x40000 -#define MOD_ADDRESSABLE 0x80000 - -#define MOD_NOCAST 0x100000 -#define MOD_NODEREF 0x200000 -#define MOD_ACCESSED 0x400000 -#define MOD_TOPLEVEL 0x800000 // scoping.. - -#define MOD_ASSIGNED 0x2000000 -#define MOD_TYPE 0x4000000 -#define MOD_SAFE 0x8000000 // non-null/non-trapping pointer - -#define MOD_USERTYPE 0x10000000 -#define MOD_NORETURN 0x20000000 -#define MOD_EXPLICITLY_SIGNED 0x40000000 -#define MOD_BITWISE 0x80000000 - - +#define MOD_AUTO 0x00000001 +#define MOD_REGISTER 0x00000002 +#define MOD_STATIC 0x00000004 +#define MOD_EXTERN 0x00000008 +#define MOD_TOPLEVEL 0x00000010 // scoping.. +#define MOD_TLS 0x00000020 +#define MOD_ASM_GOTO MOD_TLS // never used together +#define MOD_INLINE 0x00000040 + +#define MOD_ASSIGNED 0x00000080 +#define MOD_ADDRESSABLE 0x00000100 + +#define MOD_CONST 0x00000200 +#define MOD_VOLATILE 0x00000400 +#define MOD_RESTRICT 0x00000800 +#define MOD_ATOMIC 0x00001000 + +#define MOD_SIGNED 0x00002000 +#define MOD_UNSIGNED 0x00004000 +#define MOD_EXPLICITLY_SIGNED 0x00008000 + +#define MOD_TYPE 0x00010000 +#define MOD_USERTYPE 0x00020000 +#define MOD_CHAR 0x00040000 +#define MOD_SHORT 0x00080000 +#define MOD_LONG 0x00100000 +#define MOD_LONGLONG 0x00200000 +#define MOD_LONGLONGLONG 0x00400000 + +#define MOD_SAFE 0x00800000 // non-null/non-trapping pointer +#define MOD_PURE 0x01000000 +#define MOD_BITWISE 0x02000000 +#define MOD_NOCAST 0x04000000 +#define MOD_NODEREF 0x08000000 +#define MOD_NORETURN 0x10000000 +#define MOD_EXT_VISIBLE 0x20000000 + + +#define MOD_ACCESS (MOD_ASSIGNED | MOD_ADDRESSABLE) #define MOD_NONLOCAL (MOD_EXTERN | MOD_TOPLEVEL) #define MOD_STORAGE (MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | MOD_INLINE | MOD_TOPLEVEL) #define MOD_SIGNEDNESS (MOD_SIGNED | MOD_UNSIGNED | MOD_EXPLICITLY_SIGNED) #define MOD_LONG_ALL (MOD_LONG | MOD_LONGLONG | MOD_LONGLONGLONG) #define MOD_SPECIFIER (MOD_CHAR | MOD_SHORT | MOD_LONG_ALL | MOD_SIGNEDNESS) #define MOD_SIZE (MOD_CHAR | MOD_SHORT | MOD_LONG_ALL) -#define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE | \ - MOD_ASSIGNED | MOD_USERTYPE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED) -#define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST) +#define MOD_IGNORE (MOD_STORAGE | MOD_ACCESS | MOD_USERTYPE | MOD_EXPLICITLY_SIGNED | MOD_EXT_VISIBLE) +#define MOD_QUALIFIER (MOD_CONST | MOD_VOLATILE | MOD_RESTRICT | MOD_ATOMIC) +#define MOD_PTRINHERIT (MOD_QUALIFIER | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST) /* modifiers preserved by typeof() operator */ -#define MOD_TYPEOF (MOD_VOLATILE | MOD_CONST | MOD_NOCAST | MOD_SPECIFIER) +#define MOD_TYPEOF (MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER) /* Current parsing/evaluation function */ @@ -269,6 +274,17 @@ extern struct symbol bool_ctype, void_ctype, type_ctype, string_ctype, ptr_ctype, lazy_ptr_ctype, incomplete_ctype, label_ctype, bad_ctype, null_ctype; +extern struct symbol int_ptr_ctype, uint_ptr_ctype; +extern struct symbol long_ptr_ctype, ulong_ptr_ctype; +extern struct symbol llong_ptr_ctype, ullong_ptr_ctype; +extern struct symbol float32_ctype, float32x_ctype; +extern struct symbol float64_ctype, float64x_ctype; +extern struct symbol float128_ctype; +extern struct symbol const_void_ctype, const_char_ctype; +extern struct symbol const_ptr_ctype, const_string_ctype; + +#define uintptr_ctype size_t_ctype +#define intptr_ctype ssize_t_ctype /* Special internal symbols */ extern struct symbol zero_int; @@ -277,7 +293,6 @@ extern struct symbol zero_int; extern struct ident n #include "ident-list.h" -#define symbol_is_typename(sym) ((sym)->type == SYM_TYPE) extern struct symbol_list *translation_unit_used_list; @@ -290,7 +305,9 @@ extern struct symbol *lookup_symbol(struct ident *, enum namespace); extern struct symbol *create_symbol(int stream, const char *name, int type, int namespace); extern void init_symbols(void); extern void init_builtins(int stream); +extern void declare_builtins(void); extern void init_ctype(void); +extern void init_target(void); extern struct symbol *alloc_symbol(struct position, int type); extern void show_type(struct symbol *); extern const char *modifier_string(unsigned long mod); @@ -303,21 +320,33 @@ extern void bind_symbol(struct symbol *, struct ident *, enum namespace); extern struct symbol *examine_symbol_type(struct symbol *); extern struct symbol *examine_pointer_target(struct symbol *); -extern void examine_simple_symbol_type(struct symbol *); +extern const char *show_as(struct ident *as); extern const char *show_typename(struct symbol *sym); extern const char *builtin_typename(struct symbol *sym); +extern const char *builtin_type_suffix(struct symbol *sym); extern const char *builtin_ctypename(struct ctype *ctype); extern const char* get_type_name(enum type type); extern void debug_symbol(struct symbol *); extern void merge_type(struct symbol *sym, struct symbol *base_type); extern void check_declaration(struct symbol *sym); +extern void check_duplicates(struct symbol *sym); + +static inline int valid_type(const struct symbol *ctype) +{ + return ctype && ctype != &bad_ctype; +} static inline struct symbol *get_base_type(const struct symbol *sym) { return examine_symbol_type(sym->ctype.base_type); } +/// +// test if type is an integer type +// +// @return: ``1`` for plain integer type, enums & bitfields +// but ``0`` for bitwise types! static inline int is_int_type(const struct symbol *type) { if (type->type == SYM_NODE) @@ -335,6 +364,15 @@ static inline int is_enum_type(const struct symbol *type) return (type->type == SYM_ENUM); } +static inline int is_signed_type(struct symbol *sym) +{ + if (sym->type == SYM_NODE) + sym = sym->ctype.base_type; + if (sym->type == SYM_PTR) + return 0; + return !(sym->ctype.modifiers & MOD_UNSIGNED); +} + static inline int is_type_type(struct symbol *type) { return (type->ctype.modifiers & MOD_TYPE) != 0; @@ -409,6 +447,24 @@ static inline int is_scalar_type(struct symbol *type) return 0; } +/// return true for integer & pointer types +static inline bool is_integral_type(struct symbol *type) +{ + if (type->type == SYM_NODE) + type = type->ctype.base_type; + switch (type->type) { + case SYM_ENUM: + case SYM_PTR: + case SYM_RESTRICT: // OK, always integer types + return 1; + default: + break; + } + if (type->ctype.base_type == &int_type) + return 1; + return 0; +} + static inline int is_function(struct symbol *type) { return type && type->type == SYM_FN; @@ -430,6 +486,14 @@ static inline int get_sym_type(struct symbol *type) return type->type; } +static inline long long extend_value(long long val, struct symbol *ctype) +{ + int is_signed = !(ctype->ctype.modifiers & MOD_UNSIGNED); + unsigned size = ctype->bit_size; + + return bits_extend(val, size, is_signed); +} + static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace ns) { if (!ident->keyword) @@ -440,9 +504,31 @@ static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace #define is_restricted_type(type) (get_sym_type(type) == SYM_RESTRICT) #define is_fouled_type(type) (get_sym_type(type) == SYM_FOULED) #define is_bitfield_type(type) (get_sym_type(type) == SYM_BITFIELD) -extern int is_ptr_type(struct symbol *); void create_fouled(struct symbol *type); struct symbol *befoul(struct symbol *type); + +extern struct ident bad_address_space; + +static inline bool valid_as(struct ident *as) +{ + return as && as != &bad_address_space; +} + +static inline void combine_address_space(struct position pos, + struct ident **tas, struct ident *sas) +{ + struct ident *as; + if (!sas) + return; + as = *tas; + if (!as) + *tas = sas; + else if (as != sas) { + *tas = &bad_address_space; + sparse_error(pos, "multiple address spaces given"); + } +} + #endif /* SYMBOL_H */ |
