From b25d569376cbe58bed4e413458cf7005ba068dda Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Fri, 7 Mar 2008 14:50:27 +0000 Subject: [PATCH] more on MS __declspec [r18921] --- ast.c | 53 ++++++++++++++++++++++++++++++++++++++--- ast_t.h | 22 ++++++++++------- parser.c | 23 +++++++++++------- parsetest/MS/declspec.c | 5 ++++ 4 files changed, 84 insertions(+), 19 deletions(-) diff --git a/ast.c b/ast.c index d2de04e..af5ae48 100644 --- a/ast.c +++ b/ast.c @@ -1206,6 +1206,48 @@ void print_initializer(const initializer_t *initializer) panic("invalid initializer kind found"); } +/** + * Print microsoft extended declaration modifiers. + */ +static void print_ms_modifiers(const declaration_t *declaration) { + decl_modifiers_t modifiers = declaration->modifiers; + + /* DM_FORCEINLINE handled outside. */ + if((modifiers & ~DM_FORCEINLINE) != 0) { + char next = '('; + + fputs("__declspec", out); + if(modifiers & DM_DLLIMPORT) { + fputc(next, out); next = ' '; fputs("dllimport", out); + } + if(modifiers & DM_DLLEXPORT) { + fputc(next, out); next = ' '; fputs("dllexport", out); + } + if(modifiers & DM_THREAD) { + fputc(next, out); next = ' '; fputs("thread", out); + } + if(modifiers & DM_NAKED) { + fputc(next, out); next = ' '; fputs("naked", out); + } + if(modifiers & DM_THREAD) { + fputc(next, out); next = ' '; fputs("thread", out); + } + if(modifiers & DM_SELECTANY) { + fputc(next, out); next = ' '; fputs("selectany", out); + } + if(modifiers & DM_NOTHROW) { + fputc(next, out); next = ' '; fputs("nothrow", out); + } + if(modifiers & DM_NORETURN) { + fputc(next, out); next = ' '; fputs("noreturn", out); + } + if(modifiers & DM_NOINLINE) { + fputc(next, out); next = ' '; fputs("noinline", out); + } + fputs(") ", out); + } +} + /** * Print a declaration in the NORMAL namespace. * @@ -1215,11 +1257,16 @@ static void print_normal_declaration(const declaration_t *declaration) { print_storage_class((storage_class_tag_t) declaration->declared_storage_class); if(declaration->is_inline) { - if (declaration->modifiers & DM_FORCEINLINE) + if(declaration->modifiers & DM_FORCEINLINE) fputs("__forceinline ", out); - else - fputs("inline ", out); + else { + if(declaration->modifiers & DM_MICROSOFT_INLINE) + fputs("__inline ", out); + else + fputs("inline ", out); + } } + print_ms_modifiers(declaration); print_type_ext(declaration->type, declaration->symbol, &declaration->scope); diff --git a/ast_t.h b/ast_t.h index e6b71e6..cbe83ce 100644 --- a/ast_t.h +++ b/ast_t.h @@ -415,15 +415,21 @@ union initializer_t { initializer_designator_t designator; }; +/** + * Extended microsoft modifier. + */ typedef enum { - DM_DLLIMPORT = (1 << 0), - DM_DLLEXPORT = (1 << 1), - DM_THREAD = (1 << 2), - DM_NAKED = (1 << 3), - DM_FORCEINLINE = (1 << 4), - DM_NOTHROW = (1 << 5), - DM_NORETURN = (1 << 6), - DM_NOINLINE = (1 << 7) + DM_DLLIMPORT = (1 << 0), + DM_DLLEXPORT = (1 << 1), + DM_THREAD = (1 << 2), + DM_NAKED = (1 << 3), + DM_MICROSOFT_INLINE = (1 << 4), + DM_FORCEINLINE = (1 << 5), + DM_SELECTANY = (1 << 6), + DM_NOTHROW = (1 << 7), + DM_NOVTABLE = (1 << 8), + DM_NORETURN = (1 << 9), + DM_NOINLINE = (1 << 10) } decl_modifier_t; typedef unsigned short decl_modifiers_t; diff --git a/parser.c b/parser.c index e85b10d..02bc78a 100644 --- a/parser.c +++ b/parser.c @@ -1949,9 +1949,9 @@ static type_t *get_typedef_type(symbol_t *symbol) return type; } -static void parse_microsoft_extended_decl_modifier(void) +static void parse_microsoft_extended_decl_modifier(decl_modifiers_t *modifiers) { - symbol_t *symbol; + symbol_t *symbol; while(true) { switch(token.type) { @@ -1974,20 +1974,28 @@ static void parse_microsoft_extended_decl_modifier(void) expect(')'); } else if(symbol == sym_dllimport) { next_token(); - } else if(symbol == sym_dllimport) { - next_token(); + *modifiers |= DM_DLLIMPORT; } else if(symbol == sym_dllexport) { next_token(); + *modifiers |= DM_DLLEXPORT; + } else if(symbol == sym_thread) { + next_token(); + *modifiers |= DM_THREAD; } else if(symbol == sym_naked) { next_token(); + *modifiers |= DM_NAKED; } else if(symbol == sym_noinline) { next_token(); + *modifiers |= DM_NOINLINE; } else if(symbol == sym_noreturn) { next_token(); + *modifiers |= DM_NORETURN; } else if(symbol == sym_nothrow) { next_token(); + *modifiers |= DM_NOTHROW; } else if(symbol == sym_novtable) { next_token(); + *modifiers |= DM_NOVTABLE; } else if(symbol == sym_property) { next_token(); expect('('); @@ -2006,8 +2014,6 @@ static void parse_microsoft_extended_decl_modifier(void) expect(')'); } else if(symbol == sym_selectany) { next_token(); - } else if(symbol == sym_thread) { - next_token(); } else if(symbol == sym_uuid) { next_token(); expect('('); @@ -2022,7 +2028,7 @@ static void parse_microsoft_extended_decl_modifier(void) } } end_error: - ; + return; } static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) @@ -2056,7 +2062,7 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) case T_declspec: next_token(); expect('('); - parse_microsoft_extended_decl_modifier(); + parse_microsoft_extended_decl_modifier(&specifiers->decl_modifiers); expect(')'); break; @@ -3126,6 +3132,7 @@ static void parse_anonymous_declaration_rest( declaration->type = specifiers->type; declaration->declared_storage_class = specifiers->declared_storage_class; declaration->source_position = specifiers->source_position; + declaration->modifiers = specifiers->decl_modifiers; if (declaration->declared_storage_class != STORAGE_CLASS_NONE) { warningf(declaration->source_position, "useless storage class in empty declaration"); diff --git a/parsetest/MS/declspec.c b/parsetest/MS/declspec.c index 7af4da1..cdf21cc 100644 --- a/parsetest/MS/declspec.c +++ b/parsetest/MS/declspec.c @@ -1 +1,6 @@ int __declspec(align(4)) x; + +int __declspec(dllimport) y; +int __declspec(dllexport) z; + +int __declspec(noinline naked)func(void); -- 2.20.1