Changed to __declspec to hopefully make adding things easier
authorRobert Pengelly <robertapengelly@hotmail.com>
Thu, 20 Aug 2026 13:08:59 +0000 (14:08 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Thu, 20 Aug 2026 13:08:59 +0000 (14:08 +0100)
amd64.c
i386.c
parse.c
token.c
token.h

diff --git a/amd64.c b/amd64.c
index bc25c09762ad6f344a9129fab4b3cad30d754b8b..ef55b2b58719a2e011bbbaa91a7fb8e0060f5133 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -6222,90 +6222,6 @@ static void switch_section (int sec) {
 
 }
 
-static int current_token_spells_identifier_now (const char *name) {
-
-    const char *p;
-    size_t len;
-    
-    if (!name || !*name) {
-        return 0;
-    }
-    
-    if (tok.ident && strcmp (tok.ident, name) == 0) {
-        return 1;
-    }
-    
-    /*
-     * Some declaration modifiers are real tokens rather than TOK_IDENT.
-     * Use the original source spelling as a generic fallback so the
-     * declaration parser can accept them in either specifier position:
-     *
-     *     __dllexport void f(void);
-     *     void __dllexport f(void);
-     */
-    p = tok.caret ? tok.caret : tok.start;
-    
-    if (!p) {
-       return 0;
-    }
-    
-    while (*p == ' ' || *p == '\t') {
-        p++;
-    }
-    
-    len = strlen (name);
-    
-    if (strncmp (p, name, len) != 0) {
-        return 0;
-    }
-    
-    if ((p[len] >= 'A' && p[len] <= 'Z') ||
-        (p[len] >= 'a' && p[len] <= 'z') ||
-        (p[len] >= '0' && p[len] <= '9') ||
-        p[len] == '_') {
-        return 0;
-    }
-    
-    return 1;
-
-}
-
-static void consume_post_type_declaration_modifiers_now (int *out_dllimport, int *out_dllexport) {
-
-    for (;;) {
-    
-        if (current_token_spells_identifier_now ("__dllimport")) {
-        
-            if (out_dllimport) {
-                *out_dllimport = 1;
-            }
-            
-            parsed_dllimport = 1;
-            get_token ();
-            
-            continue;
-        
-        }
-        
-        if (current_token_spells_identifier_now ("__dllexport")) {
-        
-            if (out_dllexport) {
-                *out_dllexport = 1;
-            }
-            
-            parsed_dllexport = 1;
-            get_token ();
-            
-            continue;
-        
-        }
-        
-        break;
-    
-    }
-
-}
-
 static int last_deref_cast_type_is_floating = 0;
 
 static int parse_deref_cast_type_name (int *out_size) {
@@ -37617,7 +37533,7 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
     if (emit_body) {
     
         if (parsed_dllimport) {
-            report_line_at (get_filename (), last_declarator_name_line, REPORT_ERROR, last_declarator_name_start, last_declarator_name_caret, "function '%s' cannot be defined with '__dllimport'", name);
+            report_line_at (get_filename (), last_declarator_name_line, REPORT_ERROR, last_declarator_name_start, last_declarator_name_caret, "function '%s' cannot be defined with '__declspec(dllimport)'", name);
         }
         
         should_emit = add_global_symbol (name, GLOBAL_SYMBOL_FUNCTION, 0, last_declarator_name_start, last_declarator_name_caret, last_declarator_name_line);
@@ -39278,7 +39194,6 @@ static void parse_external_after_type (void) {
         declaration_dllimport = parsed_dllimport;
         declaration_dllexport = parsed_dllexport;
         
-        consume_post_type_declaration_modifiers_now (&declaration_dllimport, &declaration_dllexport);
         parse_declarator (&name);
         
         declaration_dllimport = declaration_dllimport || parsed_dllimport || declarator_dllimport;
diff --git a/i386.c b/i386.c
index dd41fe8d5fdc9ca2446d426be9832789c3c69824..98f1ba53126ffc229f777864003e2dfc2e989549 100644 (file)
--- a/i386.c
+++ b/i386.c
@@ -34980,7 +34980,7 @@ static void parse_function_body (const char *name, int storage_class, int is_inl
     if (emit_body) {
     
         if (parsed_dllimport) {
-            report_line_at (get_filename (), last_declarator_name_line, REPORT_ERROR, last_declarator_name_start, last_declarator_name_caret, "function '%s' cannot be defined with '__dllimport'", name);
+            report_line_at (get_filename (), last_declarator_name_line, REPORT_ERROR, last_declarator_name_start, last_declarator_name_caret, "function '%s' cannot be defined with '__declspec(dllimport)'", name);
         }
         
         should_emit = add_global_symbol (name, GLOBAL_SYMBOL_FUNCTION, 0, last_declarator_name_start, last_declarator_name_caret, last_declarator_name_line);
diff --git a/parse.c b/parse.c
index 6bdf3097187885f9118d8648e7488c71d0487a9e..11160d539a03cee261a95fa5e4deab3ad1f7d99f 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -14,6 +14,7 @@
 #include    "vector.h"
 
 struct typedef_entry typedef_names[MAX_TYPEDEF_NAMES];
+
 int typedef_name_count = 0;
 int anonymous_aggregate_owner_id = 1;
 
@@ -404,42 +405,85 @@ static void parse_decl_modifier (void) {
         if (parsed_calling_convention == TOK_EOF && declarator_calling_convention == TOK_EOF) {
             parsed_calling_convention = TOK_STDCALL;
         }
+        
+        get_token ();
+        return;
     
-    } else if (tok.kind == TOK_DLLEXPORT) {
+    }
     
-        if (parsed_dllexport) {
-            report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate '__dllexport'");
-        } else if (parsed_dllimport) {
-            report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "'__dllexport' and '__dllimport' cannot both be specified");
-        } else {
+    if (tok.kind == TOK_DECLSPEC) {
+    
+        const char *declspec_start = tok.report_start;
+        const char *declspec_caret = tok.report_caret;
         
-            declarator_dllexport = 1;
-            parsed_dllexport = 1;
+        get_token ();
+        
+        if (!_accept (TOK_LPAREN)) {
+        
+            report_line_at (get_filename (), get_line_number (), REPORT_ERROR, declspec_start, declspec_caret, "expected '(' after '__declspec'");
+            return;
         
         }
-    
-    } else if (tok.kind == TOK_DLLIMPORT) {
-    
-        if (parsed_dllimport) {
-            report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate '__dllimport'");
-        } else if (parsed_dllexport) {
-            report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "'__dllexport' and '__dllimport' cannot both be specified");
+        
+        if (tok.kind != TOK_IDENT || !tok.ident) {
+            report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "expected attribute in '__declspec'");
+        } else if (strcmp (tok.ident, "dllexport") == 0) {
+        
+            if (parsed_dllexport) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate '__declspec(dllexport)'");
+            } else if (parsed_dllimport) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "'__declspec(dllexport)' and '__declspec(dllimport)' cannot both be specified");
+            } else {
+            
+                declarator_dllexport = 1;
+                parsed_dllexport = 1;
+            
+            }
+            
+            get_token ();
+        
+        } else if (strcmp (tok.ident, "dllimport") == 0) {
+        
+            if (parsed_dllimport) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate '__declspec(dllimport)'");
+            } else if (parsed_dllexport) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "'__declspec(dllexport)' and '__declspec(dllimport)' cannot both be specified");
+            } else {
+            
+                declarator_dllimport = 1;
+                parsed_dllimport = 1;
+            
+            }
+            
+            get_token ();
+         
+        } else if (strcmp (tok.ident, "packed") == 0) {
+        
+            if (parsed_type_is_packed) {
+                report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate '__declspec(packed)'");
+            } else {
+                parsed_type_is_packed = 1;
+            }
+            
+            get_token ();
+        
         } else {
         
-            declarator_dllimport = 1;
-            parsed_dllimport = 1;
+            report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "unsupported '__declspec' attribute '%s'", tok.ident);
+            get_token ();
         
         }
+        
+        expect (TOK_RPAREN, ")");
+        return;
     
     }
-    
-    get_token ();
 
 }
 
 void parse_declarator_inner (char **out_name) {
 
-    while (tok.kind == TOK_STDCALL || tok.kind == TOK_DLLEXPORT || tok.kind == TOK_DLLIMPORT) {
+    while (tok.kind == TOK_STDCALL || tok.kind == TOK_DECLSPEC) {
     
         if (tok.kind == TOK_STDCALL) {
         
@@ -462,7 +506,7 @@ void parse_declarator_inner (char **out_name) {
         
         get_token ();
         
-        while (tok.kind == TOK_CONST || tok.kind == TOK_VOLATILE || tok.kind == TOK_RESTRICT || tok.kind == TOK_STDCALL || tok.kind == TOK_DLLEXPORT || tok.kind == TOK_DLLIMPORT) {
+        while (tok.kind == TOK_CONST || tok.kind == TOK_VOLATILE || tok.kind == TOK_RESTRICT || tok.kind == TOK_STDCALL || tok.kind == TOK_DECLSPEC) {
         
             if (tok.kind == TOK_STDCALL) {
             
@@ -472,7 +516,7 @@ void parse_declarator_inner (char **out_name) {
                 
                 get_token ();
             
-            } else if (tok.kind == TOK_DLLEXPORT || tok.kind == TOK_DLLIMPORT) {
+            } else if (tok.kind == TOK_DECLSPEC) {
                 parse_decl_modifier ();
             } else {
                 get_token ();
@@ -1781,7 +1825,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_PACKED:
+        case TOK_DECLSPEC:      case TOK_STDCALL:
         case TOK_EXTERN:        case TOK_TYPEDEF:       case TOK_INLINE:
         case TOK_CONST:         case TOK_VOLATILE:      case TOK_RESTRICT:
         case TOK_SIGNED:        case TOK_UNSIGNED:
@@ -2447,11 +2491,11 @@ 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_PACKED || tok.kind == TOK_VOLATILE || tok.kind == TOK_SIGNED || tok.kind == TOK_UNSIGNED ||
+           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 ||
-           tok.kind == TOK_DLLEXPORT || tok.kind == TOK_DLLIMPORT || tok.kind == TOK_STDCALL || token_is_ms_int_type_name ()) {
+           tok.kind == TOK_DECLSPEC || tok.kind == TOK_STDCALL || token_is_ms_int_type_name ()) {
         
         saw = 1;
         
@@ -2462,7 +2506,7 @@ void parse_type_spec (void) {
             saw_real_type = 1;
         }
         
-        if (tok.kind == TOK_STDCALL || tok.kind == TOK_DLLEXPORT || tok.kind == TOK_DLLIMPORT) {
+        if (tok.kind == TOK_STDCALL || tok.kind == TOK_DECLSPEC) {
         
             parse_decl_modifier ();
             continue;
@@ -2499,8 +2543,6 @@ 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) {
@@ -2722,10 +2764,13 @@ void parse_type_spec (void) {
         clear_parsed_fields ();
         get_token ();
         
-        if (tok.kind == TOK_PACKED) {
+        while (tok.kind == TOK_DECLSPEC) {
         
-            aggregate_is_packed = 1;
-            get_token ();
+            parse_decl_modifier ();
+            
+            if (parsed_type_is_packed) {
+                aggregate_is_packed = 1;
+            }
         
         }
         
@@ -2741,10 +2786,13 @@ void parse_type_spec (void) {
         
         }
         
-        if (tok.kind == TOK_PACKED) {
+        while (tok.kind == TOK_DECLSPEC) {
         
-            aggregate_is_packed = 1;
-            get_token ();
+            parse_decl_modifier ();
+            
+            if (parsed_type_is_packed) {
+                aggregate_is_packed = 1;
+            }
         
         }
         
diff --git a/token.c b/token.c
index dc242981fecfc81ac39e44f5a51369c9ec3178a8..beafe20de7572ec7fcb89a3de33dccdefa36f9a5 100755 (executable)
--- a/token.c
+++ b/token.c
@@ -1067,11 +1067,8 @@ static int find_kind (const char *start, const char *caret, const char *p) {
         /* Compiler Specific keywords */
         {   "__scc_builtin_va_arg",     -1,     VERSION,    TOK_SCC_BUILTIN_VA_ARG  },
         
-        {   "__dllexport",              -1,     VERSION,    TOK_DLLEXPORT           },
-        {   "__dllimport",              -1,     VERSION,    TOK_DLLIMPORT           },
-        
+        {   "__declspec",               -1,     VERSION,    TOK_DECLSPEC            },
         {   "__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 4e277d9f3ab20fe914cab07c836fcbc666767004..5812b036609fd1d5e4d4251a0e5d593887966293 100755 (executable)
--- a/token.h
+++ b/token.h
@@ -73,9 +73,8 @@ enum token_kind {
     TOK_CHAR,
     TOK_CONST,
     TOK_CONTINUE,
+    TOK_DECLSPEC,
     TOK_DEFAULT,
-    TOK_DLLEXPORT,
-    TOK_DLLIMPORT,
     TOK_DO,
     TOK_DOUBLE,
     TOK_ELSE,
@@ -88,7 +87,6 @@ enum token_kind {
     TOK_INLINE,
     TOK_INT,
     TOK_LONG,
-    TOK_PACKED,
     TOK_OFFSETOF,
     TOK_REGISTER,
     TOK_RESTRICT,