From 11db59ea8e96fc4e7163a54c5564cb76a6bacd63 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 4 Jul 2020 18:10:32 +0200 Subject: predefine: add testcase for multi-token predefines The function predefine() and its variants are only valid if they define a single-token value. Add a testcase for this. Signed-off-by: Luc Van Oostenryck --- validation/preprocessor/predef-token.c | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 validation/preprocessor/predef-token.c diff --git a/validation/preprocessor/predef-token.c b/validation/preprocessor/predef-token.c new file mode 100644 index 00000000..6df8ea40 --- /dev/null +++ b/validation/preprocessor/predef-token.c @@ -0,0 +1,5 @@ +static __UINT8_TYPE__ u8; + +/* + * check-name: predef-token + */ -- cgit 1.2.3-korg From c6dff56f6c017cf909ddf03631d513a3fcd15888 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 4 Jul 2020 18:28:56 +0200 Subject: predefine: fix multi-token predefine The function predefine() and its variants are only valid if they define a single-token value. However, when a type is signed, predefine_min() will produce a multi-token value. Fix this by using add_pre_buffer() instead of predefine(). Signed-off-by: Luc Van Oostenryck --- predefine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/predefine.c b/predefine.c index ff457b38..d05b1018 100644 --- a/predefine.c +++ b/predefine.c @@ -52,7 +52,7 @@ static void predefined_min(const char *name, struct symbol *type) snprintf(buf, sizeof(buf), "__%s_MIN__", name); if (is_signed_type(type)) - predefine(buf, 1, "(-__%s_MAX__ - 1)", name); + add_pre_buffer("#weak_define %s (-__%s_MAX__ - 1)\n", buf, name); else predefine(buf, 1, "0%s", suffix); } -- cgit 1.2.3-korg From 20b4c3c4ca21106acc4065b7c22b6cd98b4de0e9 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Fri, 3 Jul 2020 00:25:20 +0200 Subject: predefine: add helper predefine_{strong,weak}() A lot of predefined macros are just set to the value '1' and of them have a name that is not statically known. OTOH, the function predefine() is designed for a statically known name but a variable value. Add a set of helpers to cover the first case: predefine_strong() and predefine_weak(). Signed-off-by: Luc Van Oostenryck --- lib.h | 2 ++ pre-process.c | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib.h b/lib.h index 682e54f5..5458fa71 100644 --- a/lib.h +++ b/lib.h @@ -123,6 +123,8 @@ enum phase { extern void add_pre_buffer(const char *fmt, ...) FORMAT_ATTR(1); extern void predefine(const char *name, int weak, const char *fmt, ...) FORMAT_ATTR(3); +extern void predefine_strong(const char *name, ...) FORMAT_ATTR(1); +extern void predefine_weak(const char *name, ...) FORMAT_ATTR(1); extern void predefine_nostd(const char *name); extern void predefined_macros(void); diff --git a/pre-process.c b/pre-process.c index 38167802..403e3507 100644 --- a/pre-process.c +++ b/pre-process.c @@ -1439,6 +1439,32 @@ void predefine_nostd(const char *name) predefine(name, 1, "1"); } +static void predefine_fmt(const char *fmt, int weak, va_list ap) +{ + static char buf[256]; + + vsnprintf(buf, sizeof(buf), fmt, ap); + predefine(buf, weak, "1"); +} + +void predefine_strong(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + predefine_fmt(fmt, 0, ap); + va_end(ap); +} + +void predefine_weak(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + predefine_fmt(fmt, 1, ap); + va_end(ap); +} + static int do_handle_define(struct stream *stream, struct token **line, struct token *token, int attr) { struct token *arglist, *expansion; -- cgit 1.2.3-korg From f99c666c493c2f31642bed44e97df34c4e71dbc8 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Thu, 2 Jul 2020 23:39:28 +0200 Subject: predefine: avoid add_pre_buffer() for targets Avoid add_pre_buffer() and use one of the predefine...() variant instead. Signed-off-by: Luc Van Oostenryck --- target-arm64.c | 2 +- target-riscv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target-arm64.c b/target-arm64.c index d491b65e..8619bd84 100644 --- a/target-arm64.c +++ b/target-arm64.c @@ -21,7 +21,7 @@ static void predefine_arm64(const struct target *self) predefine("__aarch64__", 1, "1"); if (cmodel) - add_pre_buffer("#define __AARCH64_CMODEL_%s__ 1\n", cmodel); + predefine_strong("__AARCH64_CMODEL_%s__", cmodel); } const struct target target_arm64 = { diff --git a/target-riscv.c b/target-riscv.c index 08d036ca..d68fb585 100644 --- a/target-riscv.c +++ b/target-riscv.c @@ -24,7 +24,7 @@ static void predefine_riscv(const struct target *self) predefine("__riscv_xlen", 1, "%d", ptr_ctype.bit_size); if (cmodel) - add_pre_buffer("#define __riscv_cmodel_%s 1\n", cmodel); + predefine_strong("__riscv_cmodel_%s", cmodel); } const struct target target_riscv32 = { -- cgit 1.2.3-korg From 0a45df1135e7244b4bc40c1d1c09ca80b920b35e Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sun, 5 Jul 2020 04:09:05 +0200 Subject: predef: simplify add_pre_buffer() pre_buffer_begin & pre_buffer_end are the head and the tail of a singly chained list. As such, it's slightly easier to not keep a pointer on the last element but a pointer where the next element should be written. Signed-off-by: Luc Van Oostenryck --- lib.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib.c b/lib.c index 57c89a16..d4f4dd30 100644 --- a/lib.c +++ b/lib.c @@ -173,7 +173,7 @@ void die(const char *fmt, ...) //////////////////////////////////////////////////////////////////////////////// static struct token *pre_buffer_begin = NULL; -static struct token *pre_buffer_end = NULL; +static struct token **pre_buffer_next = &pre_buffer_begin; void add_pre_buffer(const char *fmt, ...) { @@ -186,11 +186,8 @@ void add_pre_buffer(const char *fmt, ...) size = vsnprintf(buffer, sizeof(buffer), fmt, args); va_end(args); begin = tokenize_buffer(buffer, size, &end); - if (!pre_buffer_begin) - pre_buffer_begin = begin; - if (pre_buffer_end) - pre_buffer_end->next = begin; - pre_buffer_end = end; + *pre_buffer_next = begin; + pre_buffer_next = &end->next; } static void create_builtin_stream(void) -- cgit 1.2.3-korg