win32: handle __declspec(dllimport)

This commit is contained in:
grischka 2009-11-13 17:14:05 +01:00
parent dd70d19267
commit 5b113f3ee3
4 changed files with 50 additions and 4 deletions

View File

@ -184,6 +184,32 @@ static void gen_modrm(int op_reg, int r, Sym *sym, int c)
} }
} }
#ifdef TCC_TARGET_PE
static void mk_pointer(CType *type);
static void indir(void);
int handle_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv))
{
if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST))
return 0;
if (0 == (sv->sym->type.t & VT_IMPORT))
return 0;
printf("import %d %04x %s\n", r, ind, get_tok_str(sv->sym->v, NULL));
sv->sym->type.t &= ~VT_IMPORT;
++vtop;
*vtop = *sv;
mk_pointer(&vtop->type);
indir();
fn(r, vtop);
--vtop;
sv->sym->type.t |= VT_IMPORT;
return 1;
}
#endif
/* load 'r' from value 'sv' */ /* load 'r' from value 'sv' */
void load(int r, SValue *sv) void load(int r, SValue *sv)
@ -191,6 +217,10 @@ void load(int r, SValue *sv)
int v, t, ft, fc, fr; int v, t, ft, fc, fr;
SValue v1; SValue v1;
#ifdef TCC_TARGET_PE
if (handle_dllimport(r, sv, load))
return;
#endif
fr = sv->r; fr = sv->r;
ft = sv->type.t; ft = sv->type.t;
fc = sv->c.ul; fc = sv->c.ul;
@ -255,6 +285,10 @@ void store(int r, SValue *v)
{ {
int fr, bt, ft, fc; int fr, bt, ft, fc;
#ifdef TCC_TARGET_PE
if (handle_dllimport(r, v, store))
return;
#endif
ft = v->type.t; ft = v->type.t;
fc = v->c.ul; fc = v->c.ul;
fr = v->r & VT_VALMASK; fr = v->r & VT_VALMASK;

7
tcc.h
View File

@ -276,11 +276,13 @@ typedef struct {
unsigned unsigned
func_call : 8, func_call : 8,
func_args : 8, func_args : 8,
func_export : 1; func_export : 1,
func_import : 1;
} func_attr_t; } func_attr_t;
#define FUNC_CALL(r) (((func_attr_t*)&(r))->func_call) #define FUNC_CALL(r) (((func_attr_t*)&(r))->func_call)
#define FUNC_EXPORT(r) (((func_attr_t*)&(r))->func_export) #define FUNC_EXPORT(r) (((func_attr_t*)&(r))->func_export)
#define FUNC_IMPORT(r) (((func_attr_t*)&(r))->func_import)
#define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args) #define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args)
/* -------------------------------------------------- */ /* -------------------------------------------------- */
@ -570,11 +572,12 @@ struct TCCState {
#define VT_STATIC 0x00000100 /* static variable */ #define VT_STATIC 0x00000100 /* static variable */
#define VT_TYPEDEF 0x00000200 /* typedef definition */ #define VT_TYPEDEF 0x00000200 /* typedef definition */
#define VT_INLINE 0x00000400 /* inline definition */ #define VT_INLINE 0x00000400 /* inline definition */
#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */
#define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
/* type mask (except storage) */ /* type mask (except storage) */
#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE) #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT)
#define VT_TYPE (~(VT_STORAGE)) #define VT_TYPE (~(VT_STORAGE))
/* token values */ /* token values */

View File

@ -1100,8 +1100,9 @@ void gen_opic(int op)
} }
goto general_case; goto general_case;
} else if (c2 && (op == '+' || op == '-') && } else if (c2 && (op == '+' || op == '-') &&
((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM)
(VT_CONST | VT_SYM) || && !(vtop[-1].sym->type.t & VT_IMPORT))
||
(vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) { (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
/* symbol + constant case */ /* symbol + constant case */
if (op == '-') if (op == '-')
@ -2257,6 +2258,9 @@ static void parse_attribute(AttributeDef *ad)
case TOK_DLLEXPORT: case TOK_DLLEXPORT:
FUNC_EXPORT(ad->func_attr) = 1; FUNC_EXPORT(ad->func_attr) = 1;
break; break;
case TOK_DLLIMPORT:
FUNC_IMPORT(ad->func_attr) = 1;
break;
default: default:
if (tcc_state->warn_unsupported) if (tcc_state->warn_unsupported)
warning("'%s' attribute ignored", get_tok_str(t, NULL)); warning("'%s' attribute ignored", get_tok_str(t, NULL));
@ -5131,6 +5135,10 @@ static void decl(int l)
/* NOTE: as GCC, uninitialized global static /* NOTE: as GCC, uninitialized global static
arrays of null size are considered as arrays of null size are considered as
extern */ extern */
#ifdef TCC_TARGET_PE
if (FUNC_IMPORT(ad.func_attr))
type.t |= VT_IMPORT;
#endif
external_sym(v, &type, r); external_sym(v, &type, r);
} else { } else {
type.t |= (btype.t & VT_STATIC); /* Retain "static". */ type.t |= (btype.t & VT_STATIC); /* Retain "static". */

View File

@ -105,6 +105,7 @@
DEF(TOK_FASTCALL2, "__fastcall") DEF(TOK_FASTCALL2, "__fastcall")
DEF(TOK_FASTCALL3, "__fastcall__") DEF(TOK_FASTCALL3, "__fastcall__")
DEF(TOK_DLLEXPORT, "dllexport") DEF(TOK_DLLEXPORT, "dllexport")
DEF(TOK_DLLIMPORT, "dllimport")
DEF(TOK_NORETURN1, "noreturn") DEF(TOK_NORETURN1, "noreturn")
DEF(TOK_NORETURN2, "__noreturn__") DEF(TOK_NORETURN2, "__noreturn__")
DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")