Added __packed
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 23 Jun 2026 07:34:54 +0000 (08:34 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 23 Jun 2026 07:34:54 +0000 (08:34 +0100)
amd64.c
parse.c
parse.h
token.c
token.h

diff --git a/amd64.c b/amd64.c
index 3992e060ced7ddd752427c72b965419c2b7debe4..27248611e0a6d44e055ebe95f9a29da2a5d0fe2e 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -224,6 +224,13 @@ static int amd64_relayout_aggregate_members (int owner_size, const char *owner_t
             continue;
         }
         
+        if (member_infos[mi].is_packed) {
+        
+            matched = 1;
+            continue;
+        
+        }
+        
         size = member_infos[mi].size & 0x1f;
         
         if (size <= 0) {
@@ -248,6 +255,24 @@ static int amd64_relayout_aggregate_members (int owner_size, const char *owner_t
         return owner_size;
     }
     
+    if (offset == 0) {
+    
+        for (mi = 0; mi < member_info_count; mi++) {
+        
+            if (!amd64_member_owner_matches (mi, owner_size, owner_tag_name)) {
+                continue;
+            }
+            
+            if (!member_infos[mi].owner_tag_name && typedef_name && typedef_name[0]) {
+                member_infos[mi].owner_tag_name = xstrdup (typedef_name);
+            }
+        
+        }
+        
+        return owner_size;
+    
+    }
+    
     offset = amd64_align_member_offset (offset, max_align);
     
     for (mi = 0; mi < member_info_count; mi++) {
diff --git a/parse.c b/parse.c
index e05e6dda1449d015698e0349ef4952369617185f..6588ff2fd7e865de4d73b330e5087ae1b8a199b1 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -31,6 +31,7 @@ int parsed_type_is_void = 0;
 int parsed_type_is_unsigned = 0;
 int parsed_type_is_floating = 0;
 int parsed_type_only_qualifiers = 0;
+int parsed_type_is_packed = 0;
 
 int parsed_type_is_aggregate = 0;
 int parsed_type_has_tag = 0;
@@ -1734,7 +1735,7 @@ int is_type_start (enum token_kind k) {
             return 0;
         
         case TOK_AUTO:          case TOK_REGISTER:      case TOK_STATIC:
-        case TOK_DLLEXPORT:     case TOK_DLLIMPORT:
+        case TOK_DLLEXPORT:     case TOK_DLLIMPORT:     case TOK_PACKED:
         case TOK_EXTERN:        case TOK_TYPEDEF:       case TOK_INLINE:
         case TOK_CONST:         case TOK_VOLATILE:      case TOK_RESTRICT:
         case TOK_SIGNED:        case TOK_UNSIGNED:
@@ -2175,7 +2176,7 @@ static void load_typedef_name (struct typedef_entry *entry) {
 
 }
 
-static void remember_member_info_ex (const char *name, int offset, int size, int elem_size, int pointer_depth, int is_array, int is_floating) {
+static void remember_member_info_ex (const char *name, int offset, int size, int elem_size, int pointer_depth, int is_array, int is_floating, int is_packed) {
 
     if (!name) {
         return;
@@ -2193,6 +2194,7 @@ static void remember_member_info_ex (const char *name, int offset, int size, int
     member_infos[member_info_count].is_array = is_array;
     member_infos[member_info_count].is_floating = is_floating ? 1 : 0;
     member_infos[member_info_count].is_unsigned = parsed_type_is_unsigned ? 1 : 0;
+    member_infos[member_info_count].is_packed = is_packed ? 1 : 0;
     member_infos[member_info_count].calling_convention = (declarator_calling_convention != TOK_EOF) ? declarator_calling_convention : parsed_calling_convention;
     member_infos[member_info_count].tag_name = parsed_type_tag_name[0] ? xstrdup (parsed_type_tag_name) : 0;
     member_infos[member_info_count].owner_size = 0;
@@ -2365,6 +2367,7 @@ void parse_type_spec (void) {
     parsed_type_is_inline = 0;
     parsed_type_is_void = 0;
     parsed_type_only_qualifiers = 0;
+    parsed_type_is_packed = 0;
     parsed_type_size = DATA_NONE;
     
     parsed_calling_convention = TOK_EOF;
@@ -2380,7 +2383,7 @@ void parse_type_spec (void) {
     
     while (tok.kind == TOK_AUTO || tok.kind == TOK_REGISTER || tok.kind == TOK_STATIC ||
            tok.kind == TOK_EXTERN || tok.kind == TOK_TYPEDEF || tok.kind == TOK_CONST ||
-           tok.kind == TOK_VOLATILE || tok.kind == TOK_SIGNED || tok.kind == TOK_UNSIGNED ||
+           tok.kind == TOK_PACKED || tok.kind == TOK_VOLATILE || tok.kind == TOK_SIGNED || tok.kind == TOK_UNSIGNED ||
            tok.kind == TOK_SHORT || tok.kind == TOK_LONG || tok.kind == TOK_CHAR ||
            tok.kind == TOK_INT || tok.kind == TOK_VOID || tok.kind == TOK_FLOAT ||
            tok.kind == TOK_DOUBLE || tok.kind == TOK_INLINE || tok.kind == TOK_RESTRICT ||
@@ -2432,6 +2435,8 @@ void parse_type_spec (void) {
         
         } else if (tok.kind == TOK_INLINE) {
             parsed_type_is_inline = 1;
+        } else if (tok.kind == TOK_PACKED) {
+            parsed_type_is_packed = 1;
         } else if (tok.kind == TOK_CHAR) {
         
             if (parsed_type_size == DATA_CHAR) {
@@ -2643,6 +2648,7 @@ void parse_type_spec (void) {
         
         int aggregate_storage_class = parsed_storage_class;
         int aggregate_is_inline = parsed_type_is_inline;
+        int aggregate_is_packed = parsed_type_is_packed;
         
         char *tag_name = 0;
         int member_info_start = member_info_count;
@@ -2653,6 +2659,13 @@ void parse_type_spec (void) {
         clear_parsed_fields ();
         get_token ();
         
+        if (tok.kind == TOK_PACKED) {
+        
+            aggregate_is_packed = 1;
+            get_token ();
+        
+        }
+        
         if (token_is_ident ()) {
         
             tag_name = xstrdup (tok.ident);
@@ -2665,6 +2678,13 @@ void parse_type_spec (void) {
         
         }
         
+        if (tok.kind == TOK_PACKED) {
+        
+            aggregate_is_packed = 1;
+            get_token ();
+        
+        }
+        
         if (tok.kind == TOK_LBRACE) {
         
             get_token ();
@@ -2777,9 +2797,9 @@ void parse_type_spec (void) {
                         
                         }
                         
-                        member_align = declarator_is_pointer ? type_alignment (DATA_PTR) : type_alignment (member_type_size);
+                        member_align = aggregate_is_packed ? 1 : (declarator_is_pointer ? type_alignment (DATA_PTR) : type_alignment (member_type_size));
                         
-                        if (member_align > aggregate_align) {
+                        if (!aggregate_is_packed && member_align > aggregate_align) {
                             aggregate_align = member_align;
                         }
                         
@@ -2810,7 +2830,7 @@ void parse_type_spec (void) {
                         
                         if (is_union) {
                         
-                            remember_member_info_ex (member, 0, member_size, member_info_elem_size, declarator_is_pointer ? declarator_pointer_depth : 0, declarator_has_array, declarator_is_pointer ? 0 : member_type_is_floating);
+                            remember_member_info_ex (member, 0, member_size, member_info_elem_size, declarator_is_pointer ? declarator_pointer_depth : 0, declarator_has_array, declarator_is_pointer ? 0 : member_type_is_floating, aggregate_is_packed);
                             
                             if (member_size > aggregate_size) {
                                 aggregate_size = member_size;
@@ -2841,7 +2861,7 @@ void parse_type_spec (void) {
                             
                             aggregate_size = member_offset;
                             
-                            remember_member_info_ex (member, member_offset, member_size, member_info_elem_size, declarator_is_pointer ? declarator_pointer_depth : 0, declarator_has_array, declarator_is_pointer ? 0 : member_type_is_floating);
+                            remember_member_info_ex (member, member_offset, member_size, member_info_elem_size, declarator_is_pointer ? declarator_pointer_depth : 0, declarator_has_array, declarator_is_pointer ? 0 : member_type_is_floating, aggregate_is_packed);
                             aggregate_size += member_size;
                             
                             for (r = 0; r < repeat; r++) {
@@ -2880,7 +2900,9 @@ void parse_type_spec (void) {
                 aggregate_size = DATA_CHAR & 0x1f;
             }
             
-            aggregate_size = (int) align_up_long (aggregate_size, aggregate_align);
+            if (!aggregate_is_packed) {
+                aggregate_size = (int) align_up_long (aggregate_size, aggregate_align);
+            }
             
             {
             
@@ -2936,6 +2958,7 @@ void parse_type_spec (void) {
             parsed_type_is_aggregate = 1;
             parsed_type_is_void = 0;
             parsed_type_has_tag = has_tag;
+            parsed_type_is_packed = aggregate_is_packed;
             
             clear_parsed_fields ();
 
diff --git a/parse.h b/parse.h
index 0958ff02fda90e593a581b31074cd0800f068437..ab491d1e03775a3b0bcb85d6c3fde7736e61e6e3 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -28,6 +28,7 @@ extern int parsed_type_is_void;
 extern int parsed_type_is_unsigned;
 extern int parsed_type_is_floating;
 extern int parsed_type_only_qualifiers;
+extern int parsed_type_is_packed;
 
 extern int parsed_type_is_aggregate;
 extern int parsed_type_has_tag;
@@ -127,6 +128,7 @@ struct member_info_entry {
     int is_array;
     int is_floating;
     int is_unsigned;
+    int is_packed;
     
     char *tag_name;
     char *owner_tag_name;
diff --git a/token.c b/token.c
index 35a795205789836a01bd9903648739d4acfc176d..0b0f96230160b75722cff8fed491cb7a1e3aa3bd 100755 (executable)
--- a/token.c
+++ b/token.c
@@ -1071,6 +1071,7 @@ static int find_kind (const char *start, const char *caret, const char *p) {
         {   "__dllimport",              -1,     VERSION,    TOK_DLLIMPORT           },
         
         {   "__stdcall",                -1,     VERSION,    TOK_STDCALL             },
+        {   "__packed",                 -1,     VERSION,    TOK_PACKED              },
         
         {   "__asm__",                  0,      VERSION,    TOK_ASM                 },
         {   "__inline__",               0,      VERSION,    TOK_INLINE              },
diff --git a/token.h b/token.h
index da9047fff485a068304a3f3c70a1374dd9ece83a..6882c8bbb1d43a97d3736f8e0bdab9dcce9edb8e 100755 (executable)
--- a/token.h
+++ b/token.h
@@ -88,6 +88,7 @@ enum token_kind {
     TOK_INLINE,
     TOK_INT,
     TOK_LONG,
+    TOK_PACKED,
     TOK_OFFSETOF,
     TOK_REGISTER,
     TOK_RESTRICT,