packed attribute support

This commit is contained in:
bellard 2004-10-29 23:55:13 +00:00
parent 736b565766
commit 1e1d3ff687
2 changed files with 23 additions and 6 deletions

27
tcc.c
View File

@ -215,6 +215,7 @@ typedef struct DLLReference {
/* GNUC attribute definition */ /* GNUC attribute definition */
typedef struct AttributeDef { typedef struct AttributeDef {
int aligned; int aligned;
int packed;
Section *section; Section *section;
unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */ unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
} AttributeDef; } AttributeDef;
@ -3875,7 +3876,7 @@ static int macro_subst_tok(TokenString *tok_str,
CValue cval; CValue cval;
CString cstr; CString cstr;
char buf[32]; char buf[32];
/* if symbol is a macro, prepare substitution */ /* if symbol is a macro, prepare substitution */
/* special macros */ /* special macros */
if (tok == TOK___LINE__) { if (tok == TOK___LINE__) {
@ -4149,7 +4150,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list,
const int *ptr; const int *ptr;
int t, ret; int t, ret;
CValue cval; CValue cval;
/* first scan for '##' operator handling */ /* first scan for '##' operator handling */
ptr = macro_str; ptr = macro_str;
macro_str1 = macro_twosharps(ptr); macro_str1 = macro_twosharps(ptr);
@ -6175,8 +6176,10 @@ void inc(int post, int c)
/* Parse GNUC __attribute__ extension. Currently, the following /* Parse GNUC __attribute__ extension. Currently, the following
extensions are recognized: extensions are recognized:
- aligned(n) : set data/function alignment. - aligned(n) : set data/function alignment.
- packed : force data alignment to 1
- section(x) : generate data/code in this section. - section(x) : generate data/code in this section.
- unused : currently ignored, but may be used someday. - unused : currently ignored, but may be used someday.
- regparm(n) : pass function parameters in registers (i386 only)
*/ */
static void parse_attribute(AttributeDef *ad) static void parse_attribute(AttributeDef *ad)
{ {
@ -6214,6 +6217,10 @@ static void parse_attribute(AttributeDef *ad)
} }
ad->aligned = n; ad->aligned = n;
break; break;
case TOK_PACKED1:
case TOK_PACKED2:
ad->packed = 1;
break;
case TOK_UNUSED1: case TOK_UNUSED1:
case TOK_UNUSED2: case TOK_UNUSED2:
/* currently, no need to handle it because tcc does not /* currently, no need to handle it because tcc does not
@ -6364,8 +6371,12 @@ static void struct_decl(CType *type, int u)
get_tok_str(v, NULL)); get_tok_str(v, NULL));
} }
size = type_size(&type1, &align); size = type_size(&type1, &align);
if (align < ad.aligned) if (ad.aligned) {
align = ad.aligned; if (align < ad.aligned)
align = ad.aligned;
} else if (ad.packed) {
align = 1;
}
lbit_pos = 0; lbit_pos = 0;
if (bit_size >= 0) { if (bit_size >= 0) {
bt = type1.t & VT_BTYPE; bt = type1.t & VT_BTYPE;
@ -8480,8 +8491,12 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
error("unknown type size"); error("unknown type size");
} }
/* take into account specified alignment if bigger */ /* take into account specified alignment if bigger */
if (ad->aligned > align) if (ad->aligned) {
align = ad->aligned; if (ad->aligned > align)
align = ad->aligned;
} else if (ad->packed) {
align = 1;
}
if ((r & VT_VALMASK) == VT_LOCAL) { if ((r & VT_VALMASK) == VT_LOCAL) {
sec = NULL; sec = NULL;
if (do_bounds_check && (type->t & VT_ARRAY)) if (do_bounds_check && (type->t & VT_ARRAY))

View File

@ -90,6 +90,8 @@
DEF(TOK_SECTION2, "__section__") DEF(TOK_SECTION2, "__section__")
DEF(TOK_ALIGNED1, "aligned") DEF(TOK_ALIGNED1, "aligned")
DEF(TOK_ALIGNED2, "__aligned__") DEF(TOK_ALIGNED2, "__aligned__")
DEF(TOK_PACKED1, "packed")
DEF(TOK_PACKED2, "__packed__")
DEF(TOK_UNUSED1, "unused") DEF(TOK_UNUSED1, "unused")
DEF(TOK_UNUSED2, "__unused__") DEF(TOK_UNUSED2, "__unused__")
DEF(TOK_CDECL1, "cdecl") DEF(TOK_CDECL1, "cdecl")