From 4d5105c8f1ff1ac4bae592d6c221e5737614bbad Mon Sep 17 00:00:00 2001 From: Joe Soroka Date: Tue, 1 Feb 2011 00:37:53 -0800 Subject: [PATCH] support weak attribute on variables --- libtcc.c | 2 +- tcc.h | 6 +++--- tccgen.c | 7 +++++++ tests/tcctest.c | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/libtcc.c b/libtcc.c index 483670a9..58a5ca07 100644 --- a/libtcc.c +++ b/libtcc.c @@ -429,7 +429,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, if (sym->type.t & VT_STATIC) sym_bind = STB_LOCAL; else { - if (sym_type == STT_FUNC && sym->type.ref && FUNC_WEAK(sym->type.ref->r)) + if (sym->type.t & VT_WEAK) sym_bind = STB_WEAK; else sym_bind = STB_GLOBAL; diff --git a/tcc.h b/tcc.h index 2cd2043c..b72f4e4e 100644 --- a/tcc.h +++ b/tcc.h @@ -293,7 +293,6 @@ typedef struct AttributeDef { #define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args) #define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned) #define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed) -#define FUNC_WEAK(r) (((AttributeDef*)&(r))->weak) #define ATTR_MODE(r) (((AttributeDef*)&(r))->mode) #define INT_ATTR(ad) (*(int*)(ad)) @@ -629,11 +628,12 @@ struct TCCState { #define VT_INLINE 0x00000400 /* inline definition */ #define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ #define VT_EXPORT 0x00008000 /* win32: data exported from dll */ +#define VT_WEAK 0x00010000 /* win32: data exported from dll */ -#define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ +#define VT_STRUCT_SHIFT 17 /* shift for bitfield shift values */ /* type mask (except storage) */ -#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT) +#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK) #define VT_TYPE (~(VT_STORAGE)) /* token values */ diff --git a/tccgen.c b/tccgen.c index 3c6adbc4..2d7e4aec 100644 --- a/tccgen.c +++ b/tccgen.c @@ -2922,6 +2922,9 @@ static int parse_btype(CType *type, AttributeDef *ad) case TOK_ATTRIBUTE1: case TOK_ATTRIBUTE2: parse_attribute(ad); + if (ad->weak) { + t |= VT_WEAK; + } if (ad->mode) { u = ad->mode -1; t = (t & ~VT_BTYPE) | u; @@ -3189,6 +3192,10 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) post_type(type, ad); if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) parse_attribute(ad); + + if (ad->weak) + type->t |= VT_WEAK; + if (!type1.t) return; /* append type at the end of type1 */ diff --git a/tests/tcctest.c b/tests/tcctest.c index 14ad1e64..8c2b2a25 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -82,6 +82,7 @@ void local_label_test(void); void statement_expr_test(void); void asm_test(void); void builtin_test(void); +void weak_test(void); int fib(int n); void num(int n); @@ -537,6 +538,7 @@ int main(int argc, char **argv) local_label_test(); asm_test(); builtin_test(); + weak_test(); return 0; } @@ -2227,6 +2229,22 @@ void builtin_test(void) } +extern int __attribute__((weak)) weak_f1(void); +extern int __attribute__((weak)) weak_f2(void); +extern int __attribute__((weak)) weak_v1; +extern int __attribute__((weak)) weak_v2; + +void __attribute__((weak)) weak_test(void) +{ + printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123); + printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123); + printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123); + printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123); +} + +int __attribute__((weak)) weak_f2() { return 222; } +int __attribute__((weak)) weak_v2 = 222; + void const_func(const int a) { } -- 2.11.4.GIT