| @@ -846,6 +846,52 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) · 845 unmodified lines |
| 846 | 846 | return s; |
| 847 | 847 | } |
| 848 | 848 | |
| 849 | +/* Merge symbol attributes. */ |
| 850 | +static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1) |
| 851 | +{ |
| 852 | + if (sa1->aligned && !sa->aligned) |
| 853 | + sa->aligned = sa1->aligned; |
| 854 | + sa->packed |= sa1->packed; |
| 855 | + sa->weak |= sa1->weak; |
| 856 | + if (sa1->visibility != STV_DEFAULT) { |
| 857 | + int vis = sa->visibility; |
| 858 | + if (vis == STV_DEFAULT |
| 859 | + || vis > sa1->visibility) |
| 860 | + vis = sa1->visibility; |
| 861 | + sa->visibility = vis; |
| 862 | + } |
| 863 | + sa->dllexport |= sa1->dllexport; |
| 864 | + sa->nodecorate |= sa1->nodecorate; |
| 865 | + sa->dllimport |= sa1->dllimport; |
| 866 | +} |
| 867 | + |
| 868 | +/* Merge function attributes. */ |
| 869 | +static void merge_funcattr(struct FuncAttr *fa, struct FuncAttr *fa1) |
| 870 | +{ |
| 871 | + if (fa1->func_call && !fa->func_call) |
| 872 | + fa->func_call = fa1->func_call; |
| 873 | + if (fa1->func_type && !fa->func_type) |
| 874 | + fa->func_type = fa1->func_type; |
| 875 | + if (fa1->func_args && !fa->func_args) |
| 876 | + fa->func_args = fa1->func_args; |
| 877 | +} |
| 878 | + |
| 879 | +/* Merge attributes. */ |
| 880 | +static void merge_attr(AttributeDef *ad, AttributeDef *ad1) |
| 881 | +{ |
| 882 | + merge_symattr(&ad->a, &ad1->a); |
| 883 | + merge_funcattr(&ad->f, &ad1->f); |
| 884 | + |
| 885 | + if (ad1->section) |
| 886 | + ad->section = ad1->section; |
| 887 | + if (ad1->alias_target) |
| 888 | + ad->alias_target = ad1->alias_target; |
| 889 | + if (ad1->asm_label) |
| 890 | + ad->asm_label = ad1->asm_label; |
| 891 | + if (ad1->attr_mode) |
| 892 | + ad->attr_mode = ad1->attr_mode; |
| 893 | +} |
| 894 | + |
| 849 | 895 | /* Merge some type attributes. */ |
| 850 | 896 | static void patch_type(Sym *sym, CType *type) |
| 851 | 897 | { |
| @@ -905,20 +951,8 @@ static void patch_storage(Sym *sym, AttributeDef *ad, CType *type) · 53 unmodified lines |
| 905 | 951 | if (sym->a.dllimport != ad->a.dllimport) |
| 906 | 952 | tcc_error("incompatible dll linkage for redefinition of '%s'", |
| 907 | 953 | get_tok_str(sym->v, NULL)); |
| 908 | | − sym->a.dllexport |= ad->a.dllexport; |
| 909 | 954 | #endif |
| 910 | | − sym->a.weak |= ad->a.weak; |
| 911 | | − if (ad->a.visibility) { |
| 912 | | − int vis = sym->a.visibility; |
| 913 | | − int vis2 = ad->a.visibility; |
| 914 | | − if (vis == STV_DEFAULT) |
| 915 | | − vis = vis2; |
| 916 | | − else if (vis2 != STV_DEFAULT) |
| 917 | | − vis = (vis < vis2) ? vis : vis2; |
| 918 | | − sym->a.visibility = vis; |
| 919 | | − } |
| 920 | | − if (ad->a.aligned) |
| 921 | | − sym->a.aligned = ad->a.aligned; |
| 955 | + merge_symattr(&sym->a, &ad->a); |
| 922 | 956 | if (ad->asm_label) |
| 923 | 957 | sym->asm_label = ad->asm_label; |
| 924 | 958 | update_storage(sym); |
| @@ -4000,14 +4034,8 @@ do_decl: · 3075 unmodified lines |
| 4000 | 4034 | |
| 4001 | 4035 | static void sym_to_attr(AttributeDef *ad, Sym *s) |
| 4002 | 4036 | { |
| 4003 | | − if (s->a.aligned && 0 == ad->a.aligned) |
| 4004 | | − ad->a.aligned = s->a.aligned; |
| 4005 | | − if (s->f.func_call && 0 == ad->f.func_call) |
| 4006 | | − ad->f.func_call = s->f.func_call; |
| 4007 | | − if (s->f.func_type && 0 == ad->f.func_type) |
| 4008 | | − ad->f.func_type = s->f.func_type; |
| 4009 | | − if (s->a.packed) |
| 4010 | | − ad->a.packed = 1; |
| 4037 | + merge_symattr(&ad->a, &s->a); |
| 4038 | + merge_funcattr(&ad->f, &s->f); |
| 4011 | 4039 | } |
| 4012 | 4040 | |
| 4013 | 4041 | /* Add type qualifiers to a type. If the type is an array then the qualifiers |
| @@ -4294,9 +4322,10 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 280 unmodified lines |
| 4294 | 4322 | l = 0; |
| 4295 | 4323 | else if (parse_btype(&pt, &ad1)) |
| 4296 | 4324 | l = FUNC_NEW; |
| 4297 | | − else if (td) |
| 4298 | | − return 0; |
| 4299 | | − else |
| 4325 | + else if (td) { |
| 4326 | + merge_attr (ad, &ad1); |
| 4327 | + return 0; |
| 4328 | + } else |
| 4300 | 4329 | l = FUNC_OLD; |
| 4301 | 4330 | first = NULL; |
| 4302 | 4331 | plast = &first; |