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.
*
{
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);
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;
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) {
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('(');
expect(')');
} else if(symbol == sym_selectany) {
next_token();
- } else if(symbol == sym_thread) {
- next_token();
} else if(symbol == sym_uuid) {
next_token();
expect('(');
}
}
end_error:
- ;
+ return;
}
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;
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");
int __declspec(align(4)) x;
+
+int __declspec(dllimport) y;
+int __declspec(dllexport) z;
+
+int __declspec(noinline naked)func(void);