aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-03-18 15:40:40 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-03-20 00:52:39 +0100
commitc88f0098ff20f8f64cd4f57c4b63363da88b8ee0 (patch)
treeb4f8685fee65af4310f193d7628c3281e7d350b2
parente737cc332ccb8f48fb0f1ddefd4a4fba20140c9d (diff)
downloadsparse-c88f0098ff20f8f64cd4f57c4b63363da88b8ee0.tar.gz
add support for linearization of builtins
Sparse ignores most builtins. A few of them are directly interpreted at parsing time (types_compatible_p, offsetof). Some others are expanded if their argument(s) are constant but that's all. However, some of the builtins are significant at the IR level and shouldn't thus be ignored. This patch add the support needed for the linearization of these builtins. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--builtin.c2
-rw-r--r--linearize.c32
-rw-r--r--symbol.h7
3 files changed, 40 insertions, 1 deletions
diff --git a/builtin.c b/builtin.c
index 52285a91..debc22c0 100644
--- a/builtin.c
+++ b/builtin.c
@@ -418,6 +418,8 @@ void init_builtins(int stream)
sym->op = ptr->op;
sym->builtin = 1;
}
+
+ init_linearized_builtins(stream);
}
static void declare_builtin(const char *name, struct symbol *rtype, int variadic, ...)
diff --git a/linearize.c b/linearize.c
index a8395bff..bda831ce 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1509,6 +1509,11 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
fn = expr->fn;
fntype = fn->ctype;
+
+ // handle builtins
+ if (fntype->op && fntype->op->linearize)
+ return fntype->op->linearize(ep, expr);
+
ctype = &fntype->ctype;
if (fntype->type == SYM_NODE)
fntype = fntype->ctype.base_type;
@@ -2526,3 +2531,30 @@ struct entrypoint *linearize_symbol(struct symbol *sym)
return linearize_fn(sym, base_type);
return NULL;
}
+
+/*
+ * Builtin functions
+ */
+
+static struct sym_init {
+ const char *name;
+ pseudo_t (*linearize)(struct entrypoint *, struct expression*);
+ struct symbol_op op;
+} builtins_table[] = {
+ // must be declared in builtin.c:declare_builtins[]
+ { }
+};
+
+void init_linearized_builtins(int stream)
+{
+ struct sym_init *ptr;
+
+ for (ptr = builtins_table; ptr->name; ptr++) {
+ struct symbol *sym;
+ sym = create_symbol(stream, ptr->name, SYM_NODE, NS_SYMBOL);
+ if (!sym->op)
+ sym->op = &ptr->op;
+ sym->op->type |= KW_BUILTIN;
+ ptr->op.linearize = ptr->linearize;
+ }
+}
diff --git a/symbol.h b/symbol.h
index 9ef5a886..270ae098 100644
--- a/symbol.h
+++ b/symbol.h
@@ -78,7 +78,7 @@ enum keyword {
KW_MODIFIER = 1 << 1,
KW_QUALIFIER = 1 << 2,
KW_ATTRIBUTE = 1 << 3,
- // KW UNUSED = 1 << 4,
+ KW_BUILTIN = 1 << 4,
KW_ASM = 1 << 5,
KW_MODE = 1 << 6,
// KW UNUSED = 1 << 7,
@@ -112,11 +112,15 @@ struct decl_state {
unsigned char is_ext_visible;
};
+struct pseudo;
+struct entrypoint;
+
struct symbol_op {
enum keyword type;
int (*evaluate)(struct expression *);
int (*expand)(struct expression *, int);
int (*args)(struct expression *);
+ struct pseudo *(*linearize)(struct entrypoint *, struct expression *);
/* keywords */
struct token *(*declarator)(struct token *token, struct decl_state *ctx);
@@ -308,6 +312,7 @@ 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 init_linearized_builtins(int stream);
extern void declare_builtins(void);
extern void init_ctype(void);
extern struct symbol *alloc_symbol(struct position, int type);