Print this page
11972 resync smatch
@@ -99,19 +99,20 @@
struct ctype {
unsigned long modifiers;
unsigned long alignment;
struct context_list *contexts;
- unsigned int as;
+ struct ident *as;
struct symbol *base_type;
};
struct decl_state {
struct ctype ctype;
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 {
enum keyword type;
int (*evaluate)(struct expression *);
@@ -122,10 +123,11 @@
struct token *(*declarator)(struct token *token, struct decl_state *ctx);
struct token *(*statement)(struct token *token, struct statement *stmt);
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;
};
@@ -153,28 +155,31 @@
union {
struct /* NS_MACRO */ {
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 *);
int normal;
};
struct /* NS_SYMBOL */ {
unsigned long offset;
int bit_size;
unsigned int bit_offset:8,
- arg_count:10,
variadic:1,
initialized:1,
examined:1,
expanding:1,
evaluated:1,
string:1,
designated_init:1,
forced_arg:1,
+ accessed:1,
+ builtin:1,
+ torename:1,
transparent_union:1;
struct expression *array_size;
struct ctype ctype;
struct symbol_list *arguments;
struct statement *stmt;
@@ -181,11 +186,10 @@
struct symbol_list *symbol_list;
struct statement *inline_stmt;
struct symbol_list *inline_symbol_list;
struct expression *initializer;
struct entrypoint *ep;
- long long value; /* Initial value */
struct symbol *definition;
};
};
union /* backend */ {
struct basic_block *bb_target; /* label */
@@ -197,59 +201,60 @@
};
pseudo_t pseudo;
};
/* Modifiers */
-#define MOD_AUTO 0x0001
-#define MOD_REGISTER 0x0002
-#define MOD_STATIC 0x0004
-#define MOD_EXTERN 0x0008
+#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_CONST 0x0010
-#define MOD_VOLATILE 0x0020
-#define MOD_SIGNED 0x0040
-#define MOD_UNSIGNED 0x0080
+#define MOD_ASSIGNED 0x00000080
+#define MOD_ADDRESSABLE 0x00000100
-#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_CONST 0x00000200
+#define MOD_VOLATILE 0x00000400
+#define MOD_RESTRICT 0x00000800
+#define MOD_ATOMIC 0x00001000
-#define MOD_TYPEDEF 0x10000
+#define MOD_SIGNED 0x00002000
+#define MOD_UNSIGNED 0x00004000
+#define MOD_EXPLICITLY_SIGNED 0x00008000
-#define MOD_TLS 0x20000
-#define MOD_INLINE 0x40000
-#define MOD_ADDRESSABLE 0x80000
+#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_NOCAST 0x100000
-#define MOD_NODEREF 0x200000
-#define MOD_ACCESSED 0x400000
-#define MOD_TOPLEVEL 0x800000 // scoping..
+#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_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_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 */
extern struct symbol *current_fn;
@@ -267,19 +272,29 @@
lllong_ctype, slllong_ctype, ulllong_ctype,
float_ctype, double_ctype, ldouble_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;
#define __IDENT(n,str,res) \
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;
extern void access_symbol(struct symbol *);
@@ -288,11 +303,13 @@
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);
extern void show_symbol(struct symbol *);
extern int show_symbol_expr_init(struct symbol *sym);
@@ -301,25 +318,37 @@
extern void add_symbol(struct symbol_list **, struct symbol *);
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)
type = type->ctype.base_type;
if (type->type == SYM_ENUM)
@@ -333,10 +362,19 @@
if (type->type == SYM_NODE)
type = type->ctype.base_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;
}
@@ -407,10 +445,28 @@
if (type->ctype.base_type == &fp_type)
return 1;
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;
}
@@ -428,10 +484,18 @@
if (type->type == SYM_ENUM)
type = type->ctype.base_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)
return NULL;
return lookup_symbol(ident, ns);
@@ -438,11 +502,33 @@
}
#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 */