- Sync WIDL and ole32 with Wine-1.1.23, w/o syncing rpcrt4. Credits go to Christoph for helping out with this sync. Tested with rpcrt4_winetests and MS Office 2003 setup.

svn path=/trunk/; revision=42480
This commit is contained in:
Aleksey Bragin 2009-08-07 20:15:12 +00:00
parent 94ece7bbdb
commit e3ff5fffdc
46 changed files with 5460 additions and 4419 deletions

View file

@ -91,6 +91,7 @@
<compilerflag compiler="cxx">-Wno-non-virtual-dtor</compilerflag>
<compilerflag compiler="cc,cxx">-gstabs+</compilerflag>
<compilerflag compiler="as">-gstabs+</compilerflag>
<compilerflag compiler="midl">--win32</compilerflag>
</group>
<group compilerset="msc">

View file

@ -660,7 +660,7 @@ NTSTATUS ElfrReportEventAndSourceW(
}
void __RPC_FAR *__RPC_USER midl_user_allocate(size_t len)
void __RPC_FAR *__RPC_USER midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -368,7 +368,7 @@ void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle)
rot_entry_release(rot_entry);
}
void * __RPC_USER MIDL_user_allocate(size_t size)
void * __RPC_USER MIDL_user_allocate(SIZE_T size)
{
return HeapAlloc(GetProcessHeap(), 0, size);
}

View file

@ -135,7 +135,7 @@ RpcServerThread(LPVOID lpParameter)
}
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -525,7 +525,7 @@ DWORD _RpcGetSecuritySettings(
return ERROR_CALL_NOT_IMPLEMENTED;
}
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -5084,7 +5084,7 @@ DWORD RFunction55(
}
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -12,7 +12,7 @@
void __RPC_FAR * __RPC_USER
midl_user_allocate(size_t len)
midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -51,7 +51,7 @@ LsapInitLsa(VOID)
}
void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
{
return RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -1660,7 +1660,7 @@ HRESULT MonikerMarshal_Create(IMoniker *inner, IUnknown **outer)
return S_OK;
}
void * __RPC_USER MIDL_user_allocate(size_t size)
void * __RPC_USER MIDL_user_allocate(SIZE_T size)
{
return HeapAlloc(GetProcessHeap(), 0, size);
}

View file

@ -575,6 +575,10 @@ static HRESULT WINAPI StgStreamImpl_SetSize(
return STG_E_ACCESSDENIED;
}
/* In simple mode keep the stream size above the small block limit */
if (This->parentStorage->ancestorStorage->base.openFlags & STGM_SIMPLE)
libNewSize.u.LowPart = max(libNewSize.u.LowPart, LIMIT_TO_USE_SMALL_BLOCK);
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
@ -841,12 +845,18 @@ static HRESULT WINAPI StgStreamImpl_Stat(
if (readSuccessful)
{
StorageImpl *root = This->parentStorage->ancestorStorage;
StorageUtl_CopyPropertyToSTATSTG(pstatstg,
&curProperty,
grfStatFlag);
pstatstg->grfMode = This->grfMode;
/* In simple create mode cbSize is the current pos */
if((root->base.openFlags & STGM_SIMPLE) && root->create)
pstatstg->cbSize = This->currentPosition;
return S_OK;
}

View file

@ -979,6 +979,10 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream(
(grfMode & STGM_TRANSACTED))
return STG_E_INVALIDFUNCTION;
/* Can't create a stream on read-only storage */
if ( STGM_ACCESS_MODE( This->openFlags ) == STGM_READ )
return STG_E_ACCESSDENIED;
/*
* Check that we're compatible with the parent's storage mode
* if not in transacted mode
@ -988,6 +992,9 @@ static HRESULT WINAPI StorageBaseImpl_CreateStream(
return STG_E_ACCESSDENIED;
}
if(This->ancestorStorage->base.openFlags & STGM_SIMPLE)
if(grfMode & STGM_CREATE) return STG_E_INVALIDFLAG;
/*
* Initialize the out parameter
*/
@ -1226,8 +1233,13 @@ static HRESULT WINAPI StorageImpl_CreateStorage(
/*
* An element with this name already exists
*/
if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)
IStorage_DestroyElement(iface, pwcsName);
if (STGM_CREATE_MODE(grfMode) == STGM_CREATE &&
STGM_ACCESS_MODE(This->base.openFlags) != STGM_READ)
{
hr = IStorage_DestroyElement(iface, pwcsName);
if (FAILED(hr))
return hr;
}
else
{
WARN("file already exists\n");
@ -1792,6 +1804,9 @@ static HRESULT WINAPI StorageImpl_DestroyElement(
if (pwcsName==NULL)
return STG_E_INVALIDPOINTER;
if ( STGM_ACCESS_MODE( This->base.openFlags ) == STGM_READ )
return STG_E_ACCESSDENIED;
/*
* Create a property enumeration to search the property with the given name
*/
@ -2383,7 +2398,7 @@ static HRESULT StorageImpl_Construct(
ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased,
BOOL fileCreate)
BOOL create)
{
HRESULT hr = S_OK;
StgProperty currentProperty;
@ -2395,19 +2410,13 @@ static HRESULT StorageImpl_Construct(
memset(This, 0, sizeof(StorageImpl));
/*
* Initialize stream list
*/
list_init(&This->base.strmHead);
/*
* Initialize the virtual function table.
*/
This->base.lpVtbl = &Storage32Impl_Vtbl;
This->base.pssVtbl = &IPropertySetStorage_Vtbl;
This->base.v_destructor = StorageImpl_Destroy;
This->base.openFlags = (openFlags & ~STGM_CREATE);
This->create = create;
/*
* This is the top-level storage so initialize the ancestor pointer
@ -2415,14 +2424,8 @@ static HRESULT StorageImpl_Construct(
*/
This->base.ancestorStorage = This;
/*
* Initialize the physical support of the storage.
*/
This->hFile = hFile;
/*
* Store copy of file path.
*/
if(pwcsName) {
This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
(lstrlenW(pwcsName)+1)*sizeof(WCHAR));
@ -2445,7 +2448,7 @@ static HRESULT StorageImpl_Construct(
if (This->bigBlockFile == 0)
return E_FAIL;
if (fileCreate)
if (create)
{
ULARGE_INTEGER size;
BYTE bigBlockBuffer[BIG_BLOCK_SIZE];
@ -2526,7 +2529,7 @@ static HRESULT StorageImpl_Construct(
/*
* Write the root property (memory only)
*/
if (fileCreate)
if (create)
{
StgProperty rootProp;
/*

View file

@ -255,6 +255,8 @@ struct StorageImpl
*/
HANDLE hFile; /* Physical support for the Docfile */
LPOLESTR pwcsName; /* Full path of the document file */
BOOL create; /* Was the storage created or opened.
The behaviour of STGM_SIMPLE depends on this */
/* FIXME: should this be in Storage32BaseImpl ? */
WCHAR filename[PROPERTY_NAME_BUFFER_LEN];

View file

@ -307,7 +307,7 @@ static unsigned char * handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffe
RemotableHandle *remhandle = (RemotableHandle *)pBuffer;
if (remhandle->fContext != WDT_INPROC_CALL)
RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
*handle = (HANDLE)remhandle->u.hInproc;
*handle = (HANDLE)(LONG_PTR)remhandle->u.hInproc;
return pBuffer + sizeof(RemotableHandle);
}

View file

@ -3009,7 +3009,7 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
{
/*
* Special cases for when left variant is VT_NULL
* (NULL & 0 = NULL, NULL & value = value)
* (VT_NULL & 0 = VT_NULL, VT_NULL & value = value)
*/
if (leftvt == VT_NULL)
{

View file

@ -354,7 +354,7 @@ void WINAPI NdrInterfacePointerFree(PMIDL_STUB_MESSAGE pStubMsg,
/***********************************************************************
* NdrOleAllocate [RPCRT4.@]
*/
void * WINAPI NdrOleAllocate(size_t Size)
void * WINAPI NdrOleAllocate(SIZE_T Size)
{
if (!LoadCOM()) return NULL;
return COM_MemAlloc(Size);

View file

@ -596,7 +596,7 @@ RPC_STATUS WINAPI TowerConstruct(
return RPC_S_OK;
}
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t len)
void __RPC_FAR * __RPC_USER MIDL_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), 0, len);
}

View file

@ -111,7 +111,7 @@ PnpUnbindLocalBindingHandle(VOID)
void __RPC_FAR * __RPC_USER
midl_user_allocate(size_t len)
midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -198,7 +198,7 @@ WlanScan(IN HANDLE hClientHandle,
}
void __RPC_FAR * __RPC_USER
midl_user_allocate(size_t len)
midl_user_allocate(SIZE_T len)
{
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

View file

@ -331,6 +331,7 @@ HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree);
void WINAPI CoFreeAllLibraries(void);
void WINAPI CoFreeLibrary(HINSTANCE hLibrary);
void WINAPI CoFreeUnusedLibraries(void);
void WINAPI CoFreeUnusedLibrariesEx(DWORD dwUnloadDelay, DWORD dwReserved);
HRESULT WINAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv);
HRESULT WINAPI CoCreateInstanceEx(REFCLSID rclsid,
@ -344,13 +345,15 @@ HRESULT WINAPI CoGetInstanceFromFile(COSERVERINFO* pServerInfo, CLSID* pClsid, I
HRESULT WINAPI CoGetInstanceFromIStorage(COSERVERINFO* pServerInfo, CLSID* pClsid, IUnknown* punkOuter, DWORD dwClsCtx, IStorage* pstg, DWORD dwCount, MULTI_QI* pResults);
HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC* lpMalloc);
LPVOID WINAPI CoTaskMemAlloc(ULONG size);
LPVOID WINAPI CoTaskMemAlloc(ULONG size) __WINE_ALLOC_SIZE(1);
void WINAPI CoTaskMemFree(LPVOID ptr);
LPVOID WINAPI CoTaskMemRealloc(LPVOID ptr, ULONG size);
HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy);
HRESULT WINAPI CoRevokeMallocSpy(void);
HRESULT WINAPI CoGetContextToken( ULONG_PTR *token );
/* class registration flags; passed to CoRegisterClassObject */
typedef enum tagREGCLS
{
@ -390,9 +393,10 @@ BOOL WINAPI CoIsHandlerConnected(LPUNKNOWN pUnk);
/* security */
HRESULT WINAPI CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, SOLE_AUTHENTICATION_SERVICE* asAuthSvc, void* pReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pReserved2, DWORD dwCapabilities, void* pReserved3);
HRESULT WINAPI CoGetCallContext(REFIID riid, void** ppInterface);
HRESULT WINAPI CoSwitchCallContext(IUnknown *pContext, IUnknown **ppOldContext);
HRESULT WINAPI CoQueryAuthenticationServices(DWORD* pcAuthSvc, SOLE_AUTHENTICATION_SERVICE** asAuthSvc);
HRESULT WINAPI CoQueryProxyBlanket(IUnknown* pProxy, DWORD* pwAuthnSvc, DWORD* pAuthzSvc, OLECHAR** pServerPrincName, DWORD* pAuthnLevel, DWORD* pImpLevel, RPC_AUTH_IDENTITY_HANDLE* pAuthInfo, DWORD* pCapabilites);
HRESULT WINAPI CoQueryProxyBlanket(IUnknown* pProxy, DWORD* pwAuthnSvc, DWORD* pAuthzSvc, OLECHAR** pServerPrincName, DWORD* pAuthnLevel, DWORD* pImpLevel, RPC_AUTH_IDENTITY_HANDLE* pAuthInfo, DWORD* pCapabilities);
HRESULT WINAPI CoSetProxyBlanket(IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities);
HRESULT WINAPI CoCopyProxy(IUnknown* pProxy, IUnknown** ppCopy);

View file

@ -2442,7 +2442,7 @@ interface IContext : IUnknown
[in] CPFLAGS flags,
[in] IUnknown *pUnk);
HRESULT RemovePropert(
HRESULT RemoveProperty(
[in] REFGUID policyId);
HRESULT GetProperty(

View file

@ -122,6 +122,9 @@ HRESULT WINAPI WriteFmtUserTypeStg(LPSTORAGE pstg, CLIPFORMAT cf, LPOLESTR l
HRESULT WINAPI OleTranslateAccelerator (LPOLEINPLACEFRAME lpFrame, LPOLEINPLACEFRAMEINFO lpFrameInfo, struct tagMSG* lpmsg);
HRESULT WINAPI OleCreateFromData(LPDATAOBJECT pSrcDataObj, REFIID riid, DWORD renderopt, LPFORMATETC pFormatEtc,
LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj);
HRESULT WINAPI OleCreateFromDataEx(LPDATAOBJECT pSrcDataObj, REFIID riid, DWORD dwFlags, DWORD renderopt, ULONG num_formats,
DWORD *adv_flags, LPFORMATETC fmts, IAdviseSink *sink, DWORD *conns,
LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj);
HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid,
LPUNKNOWN pUnkOuter,
REFIID riid,

View file

@ -393,6 +393,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcMgmtSetCancelTimeout(LONG);
RPCRTAPI RPC_STATUS RPC_ENTRY
RpcMgmtWaitServerListen( void );
RPCRTAPI RPC_STATUS RPC_ENTRY
RpcMgmtInqStats( RPC_BINDING_HANDLE Binding, RPC_STATS_VECTOR **Statistics );
RPCRTAPI RPC_STATUS RPC_ENTRY
RpcMgmtStopServerListening( RPC_BINDING_HANDLE Binding );
@ -412,6 +415,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
RPCRTAPI RPC_STATUS RPC_ENTRY
RpcMgmtSetServerStackSize( ULONG ThreadStackSize );
RPCRTAPI RPC_STATUS RPC_ENTRY
RpcMgmtStatsVectorFree( RPC_STATS_VECTOR **StatsVector );
RPCRTAPI RPC_STATUS RPC_ENTRY
RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv );

View file

@ -177,7 +177,6 @@ typedef struct _NDR_PIPE_MESSAGE *PNDR_PIPE_MESSAGE;
typedef struct _NDR_ASYNC_MESSAGE *PNDR_ASYNC_MESSAGE;
typedef struct _NDR_CORRELATION_INFO *PNDR_CORRELATION_INFO;
#include <pshpack4.h>
typedef struct _MIDL_STUB_MESSAGE
{
PRPC_MESSAGE RpcMsg;
@ -202,7 +201,7 @@ typedef struct _MIDL_STUB_MESSAGE
ULONG_PTR MaxCount;
ULONG Offset;
ULONG ActualCount;
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t);
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(SIZE_T);
void (__RPC_API *pfnFree)(void *);
unsigned char *StackTop;
unsigned char *pPresentedType;
@ -254,7 +253,6 @@ typedef struct _MIDL_STUB_MESSAGE
INT_PTR Reserved51_4;
INT_PTR Reserved51_5;
} MIDL_STUB_MESSAGE, *PMIDL_STUB_MESSAGE;
#include <poppack.h>
typedef void * (__RPC_API * GENERIC_BINDING_ROUTINE)(void *);
typedef void (__RPC_API * GENERIC_UNBIND_ROUTINE)(void *, unsigned char *);
@ -329,7 +327,7 @@ typedef struct _USER_MARSHAL_CB
typedef struct _MALLOC_FREE_STRUCT
{
void * (__WINE_ALLOC_SIZE(1) __RPC_USER *pfnAllocate)(size_t);
void * (__WINE_ALLOC_SIZE(1) __RPC_USER *pfnAllocate)(SIZE_T);
void (__RPC_USER *pfnFree)(void *);
} MALLOC_FREE_STRUCT;
@ -342,7 +340,7 @@ typedef struct _COMM_FAULT_OFFSETS
typedef struct _MIDL_STUB_DESC
{
void *RpcInterfaceInformation;
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t);
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(SIZE_T);
void (__RPC_API *pfnFree)(void *);
union {
handle_t *pAutoHandle;
@ -481,7 +479,7 @@ typedef struct _NDR_USER_MARSHAL_INFO_LEVEL1
{
void *Buffer;
ULONG BufferSize;
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(size_t);
void * (__WINE_ALLOC_SIZE(1) __RPC_API *pfnAllocate)(SIZE_T);
void (__RPC_API *pfnFree)(void *);
struct IRpcChannelBuffer *pRpcChannelBuffer;
ULONG_PTR Reserved[5];
@ -685,7 +683,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
ULONG *pFaultStatus, RPC_STATUS Status_ );
RPCRTAPI void* RPC_ENTRY
NdrOleAllocate( size_t Size ) __WINE_ALLOC_SIZE(1);
NdrOleAllocate( SIZE_T Size ) __WINE_ALLOC_SIZE(1);
RPCRTAPI void RPC_ENTRY
NdrOleFree( void* NodeToFree );
@ -746,11 +744,11 @@ RPCRTAPI void RPC_ENTRY
RPCRTAPI void RPC_ENTRY
NdrRpcSmSetClientToOsf( PMIDL_STUB_MESSAGE pMessage );
RPCRTAPI void * RPC_ENTRY
NdrRpcSmClientAllocate( size_t Size ) __WINE_ALLOC_SIZE(1);
NdrRpcSmClientAllocate( SIZE_T Size ) __WINE_ALLOC_SIZE(1);
RPCRTAPI void RPC_ENTRY
NdrRpcSmClientFree( void *NodeToFree );
RPCRTAPI void * RPC_ENTRY
NdrRpcSsDefaultAllocate( size_t Size ) __WINE_ALLOC_SIZE(1);
NdrRpcSsDefaultAllocate( SIZE_T Size ) __WINE_ALLOC_SIZE(1);
RPCRTAPI void RPC_ENTRY
NdrRpcSsDefaultFree( void *NodeToFree );

View file

@ -150,14 +150,16 @@ struct statfs;
/* Macros to define assembler functions somewhat portably */
#ifdef __GNUC__
#if defined(__GNUC__) && !defined(__INTERIX) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__APPLE__)
# define __ASM_GLOBAL_FUNC(name,code) \
__asm__( ".align 4\n\t" \
__asm__( ".text\n\t" \
".align 4\n\t" \
".globl " __ASM_NAME(#name) "\n\t" \
__ASM_FUNC(#name) "\n" \
__ASM_NAME(#name) ":\n\t" \
code );
#else /* __GNUC__ */
code \
"\n\t.previous" );
#else /* defined(__GNUC__) && !defined(__MINGW32__) && !defined(__APPLE__) */
# define __ASM_GLOBAL_FUNC(name,code) \
void __asm_dummy_##name(void) { \
asm( ".align 4\n\t" \

View file

@ -41,6 +41,7 @@
static FILE* client;
static int indent = 0;
static void print_client( const char *format, ... ) __attribute__((format (printf, 1, 2)));
static void print_client( const char *format, ... )
{
va_list va;
@ -166,7 +167,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
/* declare return value '_RetVal' */
if (!is_void(type_function_get_rettype(func->type)))
{
print_client("");
print_client("%s", "");
write_type_decl_left(client, type_function_get_rettype(func->type));
fprintf(client, " _RetVal;\n");
}
@ -387,7 +388,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
static void write_clientinterfacedecl(type_t *iface)
{
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
@ -397,7 +398,7 @@ static void write_clientinterfacedecl(type_t *iface)
print_client("{\n");
indent++;
print_client("sizeof(RPC_CLIENT_INTERFACE),\n");
print_client("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n",
print_client("{{0x%08x,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n",
uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6],
uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver));
@ -468,7 +469,7 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
const statement_t *stmt;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
{
if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
int has_func = 0;
const statement_t *stmt2;

View file

@ -33,6 +33,10 @@
#include "expr.h"
#include "header.h"
#include "typetree.h"
#include "typegen.h"
static int is_integer_type(const type_t *type);
static int is_float_type(const type_t *type);
expr_t *make_expr(enum expr_type type)
{
@ -105,38 +109,17 @@ expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr)
e->ref = expr;
e->u.tref = tref;
e->is_const = FALSE;
/* check for cast of constant expression */
if (type == EXPR_SIZEOF)
{
switch (tref->type)
/* only do this for types that should be the same on all platforms */
if (is_integer_type(tref) || is_float_type(tref))
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_USMALL:
unsigned int align = 0;
e->is_const = TRUE;
e->cval = 1;
break;
case RPC_FC_WCHAR:
case RPC_FC_USHORT:
case RPC_FC_SHORT:
e->is_const = TRUE;
e->cval = 2;
break;
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_FLOAT:
case RPC_FC_ERROR_STATUS_T:
e->is_const = TRUE;
e->cval = 4;
break;
case RPC_FC_HYPER:
case RPC_FC_DOUBLE:
e->is_const = TRUE;
e->cval = 8;
break;
e->cval = type_memsize(tref, &align);
}
}
/* check for cast of constant expression */
if (type == EXPR_CAST && expr->is_const)
{
e->is_const = TRUE;
@ -302,34 +285,44 @@ struct expression_type
static int is_integer_type(const type_t *type)
{
switch (type->type)
switch (type_get_type(type))
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_USMALL:
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_INT3264:
case RPC_FC_UINT3264:
case RPC_FC_HYPER:
case RPC_FC_ENUM16:
case RPC_FC_ENUM32:
case TYPE_ENUM:
return TRUE;
case TYPE_BASIC:
switch (type_basic_get_type(type))
{
case TYPE_BASIC_INT8:
case TYPE_BASIC_INT16:
case TYPE_BASIC_INT32:
case TYPE_BASIC_INT64:
case TYPE_BASIC_INT:
case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER:
case TYPE_BASIC_BYTE:
case TYPE_BASIC_WCHAR:
case TYPE_BASIC_ERROR_STATUS_T:
return TRUE;
default:
return FALSE;
}
default:
return FALSE;
}
}
static int is_float_type(const type_t *type)
{
return (type_get_type(type) == TYPE_BASIC &&
(type_basic_get_type(type) == TYPE_BASIC_FLOAT ||
type_basic_get_type(type) == TYPE_BASIC_DOUBLE));
}
static void check_scalar_type(const struct expr_loc *expr_loc,
const type_t *cont_type, const type_t *type)
{
if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
type->type != RPC_FC_FLOAT &&
type->type != RPC_FC_DOUBLE))
!is_float_type(type)))
error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
expr_loc->attr ? " for attribute " : "",
expr_loc->attr ? expr_loc->attr : "");
@ -338,9 +331,7 @@ static void check_scalar_type(const struct expr_loc *expr_loc,
static void check_arithmetic_type(const struct expr_loc *expr_loc,
const type_t *cont_type, const type_t *type)
{
if (!cont_type || (!is_integer_type(type) &&
type->type != RPC_FC_FLOAT &&
type->type != RPC_FC_DOUBLE))
if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
expr_loc->attr ? " for attribute " : "",
expr_loc->attr ? expr_loc->attr : "");
@ -365,12 +356,33 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
if (cont_type)
{
if (cont_type->type == RPC_FC_FUNCTION)
switch (type_get_type(cont_type))
{
case TYPE_FUNCTION:
fields = type_function_get_args(cont_type);
else if (is_struct(cont_type->type))
break;
case TYPE_STRUCT:
fields = type_struct_get_fields(cont_type);
else if (is_union(cont_type->type))
break;
case TYPE_UNION:
case TYPE_ENCAPSULATED_UNION:
fields = type_union_get_cases(cont_type);
break;
case TYPE_VOID:
case TYPE_BASIC:
case TYPE_ENUM:
case TYPE_MODULE:
case TYPE_COCLASS:
case TYPE_INTERFACE:
case TYPE_POINTER:
case TYPE_ARRAY:
/* nothing to do */
break;
case TYPE_ALIAS:
/* shouldn't get here because of using type_get_type above */
assert(0);
break;
}
}
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
@ -390,6 +402,19 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
return type;
}
static int is_valid_member_operand(const type_t *type)
{
switch (type_get_type(type))
{
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ENUM:
return TRUE;
default:
return FALSE;
}
}
static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
const type_t *cont_type,
const expr_t *e)
@ -407,22 +432,22 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
case EXPR_TRUEFALSE:
result.is_variable = FALSE;
result.is_temporary = FALSE;
result.type = find_type("int", 0);
result.type = type_new_int(TYPE_BASIC_INT, 0);
break;
case EXPR_STRLIT:
result.is_variable = FALSE;
result.is_temporary = TRUE;
result.type = make_type(RPC_FC_RP, find_type("char", 0));
result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
break;
case EXPR_WSTRLIT:
result.is_variable = FALSE;
result.is_temporary = TRUE;
result.type = make_type(RPC_FC_RP, find_type("wchar_t", 0));
result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
break;
case EXPR_DOUBLE:
result.is_variable = FALSE;
result.is_temporary = FALSE;
result.type = find_type("double", 0);
result.is_temporary = TRUE;
result.type = type_new_basic(TYPE_BASIC_DOUBLE);
break;
case EXPR_IDENTIFIER:
{
@ -443,7 +468,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
check_scalar_type(expr_loc, cont_type, result.type);
result.is_variable = FALSE;
result.is_temporary = FALSE;
result.type = find_type("int", 0);
result.type = type_new_int(TYPE_BASIC_INT, 0);
break;
case EXPR_NOT:
result = resolve_expression(expr_loc, cont_type, e->ref);
@ -464,14 +489,14 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
expr_loc->attr ? expr_loc->attr : "");
result.is_variable = FALSE;
result.is_temporary = TRUE;
result.type = make_type(RPC_FC_RP, result.type);
result.type = type_new_pointer(RPC_FC_UP, result.type, NULL);
break;
case EXPR_PPTR:
result = resolve_expression(expr_loc, cont_type, e->ref);
if (result.type && is_ptr(result.type))
result.type = type_pointer_get_ref(result.type);
else if(result.type && is_array(result.type)
&& !result.type->declarray)
&& type_array_is_decl_as_ptr(result.type))
result.type = type_array_get_element(result.type);
else
error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
@ -485,7 +510,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
case EXPR_SIZEOF:
result.is_variable = FALSE;
result.is_temporary = FALSE;
result.type = find_type("int", 0);
result.type = type_new_int(TYPE_BASIC_INT, 0);
break;
case EXPR_SHL:
case EXPR_SHR:
@ -523,12 +548,12 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
check_scalar_type(expr_loc, cont_type, result_right.type);
result.is_variable = FALSE;
result.is_temporary = FALSE;
result.type = find_type("int", 0);
result.type = type_new_int(TYPE_BASIC_INT, 0);
break;
}
case EXPR_MEMBER:
result = resolve_expression(expr_loc, cont_type, e->ref);
if (result.type && (is_struct(result.type->type) || is_union(result.type->type) || result.type->type == RPC_FC_ENUM16 || result.type->type == RPC_FC_ENUM32))
if (result.type && is_valid_member_operand(result.type))
result = resolve_expression(expr_loc, result.type, e->u.ext);
else
error_loc_info(&expr_loc->v->loc_info, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",

View file

@ -23,6 +23,7 @@
#include <host/nls.h>
#include "widltypes.h"
#include "hash.h"
static const unsigned char Lookup_16[128 * 3] = {
@ -500,7 +501,7 @@ static const unsigned char Lookup_224[128 * 3] = {
* skind and lcid, while the low word is based on a repeated string
* hash of skind/str.
*/
unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
{
ULONG nOffset, nMask = skind == SYS_MAC ? 1 : 0;
ULONG nHiWord, nLoWord = 0x0deadbee;

View file

@ -22,12 +22,6 @@
#ifndef __WIDL_HASH_H
#define __WIDL_HASH_H
typedef enum tag_syskind_t {
SYS_WIN16 = 0,
SYS_WIN32,
SYS_MAC
} syskind_t;
extern unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr);
extern unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr);
#endif

View file

@ -149,7 +149,7 @@ static void write_field(FILE *h, var_t *v)
if (!v) return;
if (v->type) {
indent(h, 0);
write_type_def_or_decl(h, v->type, TRUE, "%s", v->name);
write_type_def_or_decl(h, v->type, TRUE, v->name);
fprintf(h, ";\n");
}
}
@ -183,7 +183,7 @@ static void write_enums(FILE *h, var_list_t *enums)
int needs_space_after(type_t *t)
{
return (type_is_alias(t) ||
(!is_ptr(t) && (!is_conformant_array(t) || t->declarray || (is_array(t) && t->name))));
(!is_ptr(t) && (!is_array(t) || !type_array_is_decl_as_ptr(t) || t->name)));
}
void write_type_left(FILE *h, type_t *t, int declonly)
@ -191,21 +191,13 @@ void write_type_left(FILE *h, type_t *t, int declonly)
if (!h) return;
if (is_attr(t->attrs, ATTR_CONST) &&
(type_is_alias(t) || t->declarray || !is_ptr(t)))
(type_is_alias(t) || !is_ptr(t)))
fprintf(h, "const ");
if (type_is_alias(t)) fprintf(h, "%s", t->name);
else if (t->declarray) write_type_left(h, type_array_get_element(t), declonly);
else {
if (t->sign > 0) fprintf(h, "signed ");
else if (t->sign < 0) fprintf(h, "unsigned ");
if (is_array(t) && !t->name) {
write_type_left(h, type_array_get_element(t), declonly);
fprintf(h, "%s*", needs_space_after(type_array_get_element(t)) ? " " : "");
} else switch (t->type) {
case RPC_FC_ENUM16:
case RPC_FC_ENUM32:
switch (type_get_type_detect_alias(t)) {
case TYPE_ENUM:
if (!declonly && t->defined && !t->written) {
if (t->name) fprintf(h, "enum %s {\n", t->name);
else fprintf(h, "enum {\n");
@ -217,19 +209,14 @@ void write_type_left(FILE *h, type_t *t, int declonly)
}
else fprintf(h, "enum %s", t->name ? t->name : "");
break;
case RPC_FC_STRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_BOGUS_STRUCT:
case RPC_FC_ENCAPSULATED_UNION:
case TYPE_STRUCT:
case TYPE_ENCAPSULATED_UNION:
if (!declonly && t->defined && !t->written) {
if (t->name) fprintf(h, "struct %s {\n", t->name);
else fprintf(h, "struct {\n");
t->written = TRUE;
indentation++;
if (t->type == RPC_FC_ENCAPSULATED_UNION)
if (type_get_type(t) != TYPE_STRUCT)
write_fields(h, type_encapsulated_union_get_fields(t));
else
write_fields(h, type_struct_get_fields(t));
@ -238,7 +225,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
}
else fprintf(h, "struct %s", t->name ? t->name : "");
break;
case RPC_FC_NON_ENCAPSULATED_UNION:
case TYPE_UNION:
if (!declonly && t->defined && !t->written) {
if (t->name) fprintf(h, "union %s {\n", t->name);
else fprintf(h, "union {\n");
@ -250,16 +237,68 @@ void write_type_left(FILE *h, type_t *t, int declonly)
}
else fprintf(h, "union %s", t->name ? t->name : "");
break;
case RPC_FC_RP:
case RPC_FC_UP:
case RPC_FC_FP:
case RPC_FC_OP:
case TYPE_POINTER:
write_type_left(h, type_pointer_get_ref(t), declonly);
fprintf(h, "%s*", needs_space_after(type_pointer_get_ref(t)) ? " " : "");
if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
break;
default:
case TYPE_ARRAY:
if (t->name && type_array_is_decl_as_ptr(t))
fprintf(h, "%s", t->name);
else
{
write_type_left(h, type_array_get_element(t), declonly);
if (type_array_is_decl_as_ptr(t))
fprintf(h, "%s*", needs_space_after(type_array_get_element(t)) ? " " : "");
}
break;
case TYPE_BASIC:
if (type_basic_get_type(t) != TYPE_BASIC_INT32 &&
type_basic_get_type(t) != TYPE_BASIC_HYPER)
{
if (type_basic_get_sign(t) < 0) fprintf(h, "signed ");
else if (type_basic_get_sign(t) > 0) fprintf(h, "unsigned ");
}
switch (type_basic_get_type(t))
{
case TYPE_BASIC_INT8: fprintf(h, "small"); break;
case TYPE_BASIC_INT16: fprintf(h, "short"); break;
case TYPE_BASIC_INT: fprintf(h, "int"); break;
case TYPE_BASIC_INT64: fprintf(h, "__int64"); break;
case TYPE_BASIC_BYTE: fprintf(h, "byte"); break;
case TYPE_BASIC_CHAR: fprintf(h, "char"); break;
case TYPE_BASIC_WCHAR: fprintf(h, "wchar_t"); break;
case TYPE_BASIC_FLOAT: fprintf(h, "float"); break;
case TYPE_BASIC_DOUBLE: fprintf(h, "double"); break;
case TYPE_BASIC_ERROR_STATUS_T: fprintf(h, "error_status_t"); break;
case TYPE_BASIC_HANDLE: fprintf(h, "handle_t"); break;
case TYPE_BASIC_INT32:
if (type_basic_get_sign(t) > 0)
fprintf(h, "ULONG");
else
fprintf(h, "LONG");
break;
case TYPE_BASIC_HYPER:
if (type_basic_get_sign(t) > 0)
fprintf(h, "MIDL_uhyper");
else
fprintf(h, "hyper");
break;
}
break;
case TYPE_INTERFACE:
case TYPE_MODULE:
case TYPE_COCLASS:
fprintf(h, "%s", t->name);
break;
case TYPE_VOID:
fprintf(h, "void");
break;
case TYPE_ALIAS:
case TYPE_FUNCTION:
/* handled elsewhere */
assert(0);
break;
}
}
}
@ -268,18 +307,19 @@ void write_type_right(FILE *h, type_t *t, int is_field)
{
if (!h) return;
if (t->declarray) {
if (type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t)) {
if (is_conformant_array(t)) {
fprintf(h, "[%s]", is_field ? "1" : "");
t = type_array_get_element(t);
}
for ( ; t->declarray; t = type_array_get_element(t))
fprintf(h, "[%lu]", type_array_get_dim(t));
for ( ;
type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
t = type_array_get_element(t))
fprintf(h, "[%u]", type_array_get_dim(t));
}
}
void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
const char *fmt, va_list args)
static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
{
type_t *pt;
int ptr_level = 0;
@ -289,7 +329,7 @@ void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
;
if (pt->type == RPC_FC_FUNCTION) {
if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
int i;
const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
if (!callconv) callconv = "";
@ -302,12 +342,10 @@ void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
fputc('*', h);
} else
write_type_left(h, t, declonly);
if (fmt) {
if (needs_space_after(t))
fputc(' ', h);
vfprintf(h, fmt, args);
}
if (pt->type == RPC_FC_FUNCTION) {
if (name) fprintf(h, "%s%s", needs_space_after(t) ? " " : "", name );
if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
if (ptr_level) fputc(')', h);
fputc('(', h);
write_args(h, type_function_get_args(pt), NULL, 0, FALSE);
@ -316,20 +354,14 @@ void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
write_type_right(h, t, is_field);
}
void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *fmt, ...)
void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
{
va_list args;
va_start(args, fmt);
write_type_v(f, t, field, FALSE, fmt, args);
va_end(args);
write_type_v(f, t, field, FALSE, name);
}
void write_type_decl(FILE *f, type_t *t, const char *fmt, ...)
void write_type_decl(FILE *f, type_t *t, const char *name)
{
va_list args;
va_start(args, fmt);
write_type_v(f, t, FALSE, TRUE, fmt, args);
va_end(args);
write_type_v(f, t, FALSE, TRUE, name);
}
void write_type_decl_left(FILE *f, type_t *t)
@ -389,7 +421,9 @@ void check_for_additional_prototype_types(const var_list_t *list)
/* don't carry on parsing fields within this type */
break;
}
if (type->type != RPC_FC_BIND_PRIMITIVE && is_attr(type->attrs, ATTR_HANDLE)) {
if ((type_get_type(type) != TYPE_BASIC ||
type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
is_attr(type->attrs, ATTR_HANDLE)) {
if (!generic_handle_registered(name))
{
generic_handle_t *gh = xmalloc(sizeof(*gh));
@ -412,13 +446,22 @@ void check_for_additional_prototype_types(const var_list_t *list)
}
else if (type_is_complete(type))
{
var_list_t *vars = NULL;
if (type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32)
var_list_t *vars;
switch (type_get_type_detect_alias(type))
{
case TYPE_ENUM:
vars = type_enum_get_values(type);
else if (is_struct(type->type))
break;
case TYPE_STRUCT:
vars = type_struct_get_fields(type);
else if (is_union(type->type))
break;
case TYPE_UNION:
vars = type_union_get_cases(type);
break;
default:
vars = NULL;
break;
}
check_for_additional_prototype_types(vars);
}
@ -471,7 +514,7 @@ static void write_generic_handle_routines(FILE *header)
static void write_typedef(FILE *header, type_t *type)
{
fprintf(header, "typedef ");
write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, "%s", type->name);
write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
fprintf(header, ";\n");
}
@ -515,7 +558,7 @@ static void write_declaration(FILE *header, const var_t *v)
fprintf(header, "extern ");
break;
}
write_type_def_or_decl(header, v->type, FALSE, "%s", v->name);
write_type_def_or_decl(header, v->type, FALSE, v->name);
fprintf(header, ";\n\n");
}
}
@ -537,26 +580,24 @@ const var_t* get_explicit_handle_var(const var_t *func)
return NULL;
LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
if (var->type->type == RPC_FC_BIND_PRIMITIVE)
{
const type_t *type = var->type;
if (type_get_type(type) == TYPE_BASIC && type_basic_get_type(type) == TYPE_BASIC_HANDLE)
return var;
}
return NULL;
}
const type_t* get_explicit_generic_handle_type(const var_t* var)
{
const type_t *t = var->type;
if (t->type == RPC_FC_BIND_PRIMITIVE)
return NULL;
if (!is_ptr(t) && is_attr(t->attrs, ATTR_HANDLE))
return t;
else
for (; is_ptr(t); t = t->ref)
if (t->type != RPC_FC_BIND_PRIMITIVE && is_attr(t->attrs, ATTR_HANDLE))
return t;
const type_t *t;
for (t = var->type;
is_ptr(t) || type_is_alias(t);
t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
is_attr(t->attrs, ATTR_HANDLE))
return t;
return NULL;
}
@ -685,7 +726,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
}
else fprintf(h, ",");
}
write_type_decl(h, arg->type, "%s", arg->name);
write_type_decl(h, arg->type, arg->name);
count++;
}
if (do_indent) indentation--;
@ -808,7 +849,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
fprintf(fp, " %s\n", comment);
if (rt->name && strcmp(rt->name, "HRESULT") == 0)
fprintf(fp, " return E_NOTIMPL;\n");
else if (rt->type) {
else if (type_get_type(rt) != TYPE_VOID) {
fprintf(fp, " ");
write_type_decl(fp, rt, "rv");
fprintf(fp, ";\n");
@ -841,7 +882,7 @@ static void write_local_stubs_stmts(FILE *local_stubs, const statement_list_t *s
const statement_t *stmt;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
{
if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
write_locals(local_stubs, stmt->u.type, TRUE);
else if (stmt->type == STMT_LIBRARY)
write_local_stubs_stmts(local_stubs, stmt->u.lib->stmts);
@ -998,7 +1039,7 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
if (!allocate_written)
{
allocate_written = 1;
fprintf(header, "void * __RPC_USER MIDL_user_allocate(size_t);\n");
fprintf(header, "void * __RPC_USER MIDL_user_allocate(SIZE_T);\n");
fprintf(header, "void __RPC_USER MIDL_user_free(void *);\n\n");
}
@ -1064,7 +1105,7 @@ static void write_imports(FILE *header, const statement_list_t *stmts)
switch (stmt->type)
{
case STMT_TYPE:
if (stmt->u.type->type == RPC_FC_IP)
if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
write_imports(header, type_iface_get_stmts(stmt->u.type));
break;
case STMT_TYPEREF:
@ -1095,12 +1136,12 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
switch (stmt->type)
{
case STMT_TYPE:
if (stmt->u.type->type == RPC_FC_IP)
if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
if (is_object(stmt->u.type->attrs) || is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE))
write_forward(header, stmt->u.type);
}
else if (stmt->u.type->type == RPC_FC_COCLASS)
else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
write_coclass_forward(header, stmt->u.type);
break;
case STMT_TYPEREF:
@ -1129,7 +1170,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
switch (stmt->type)
{
case STMT_TYPE:
if (stmt->u.type->type == RPC_FC_IP)
if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
type_t *iface = stmt->u.type;
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type->attrs))
@ -1145,7 +1186,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
write_rpc_interface_end(header, iface);
}
}
else if (stmt->u.type->type == RPC_FC_COCLASS)
else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
write_coclass(header, stmt->u.type);
else
{
@ -1156,7 +1197,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
case STMT_TYPEREF:
/* FIXME: shouldn't write out forward declarations for undefined
* interfaces but a number of our IDL files depend on this */
if (stmt->u.type->type == RPC_FC_IP && !stmt->u.type->written)
if (type_get_type(stmt->u.type) == TYPE_INTERFACE && !stmt->u.type->written)
write_forward(header, stmt->u.type);
break;
case STMT_IMPORTLIB:
@ -1181,7 +1222,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
fprintf(header, "%s\n", stmt->u.str);
break;
case STMT_DECLARATION:
if (iface && stmt->u.var->type->type == RPC_FC_FUNCTION)
if (iface && type_get_type(stmt->u.var->type) == TYPE_FUNCTION)
{
if (!ignore_funcs)
{

View file

@ -34,8 +34,8 @@ extern int is_declptr(const type_t *t);
extern const char* get_name(const var_t *v);
extern void write_type_left(FILE *h, type_t *t, int declonly);
extern void write_type_right(FILE *h, type_t *t, int is_field);
extern void write_type_def_or_decl(FILE *h, type_t *t, int is_field, const char *fmt, ...);
extern void write_type_decl(FILE *f, type_t *t, const char *fmt, ...);
extern void write_type_def_or_decl(FILE *h, type_t *t, int is_field, const char *name);
extern void write_type_decl(FILE *f, type_t *t, const char *name);
extern void write_type_decl_left(FILE *f, type_t *t);
extern int needs_space_after(type_t *t);
extern int is_object(const attr_list_t *list);
@ -75,7 +75,9 @@ static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
static inline int is_context_handle(const type_t *type)
{
const type_t *t;
for (t = type; is_ptr(t); t = type_pointer_get_ref(t))
for (t = type;
is_ptr(t) || type_is_alias(t);
t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
return 1;
return 0;

View file

@ -341,7 +341,6 @@ static const struct keyword attr_keywords[] =
{"requestedit", tREQUESTEDIT},
{"restricted", tRESTRICTED},
{"retval", tRETVAL},
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"source", tSOURCE},
{"strict_context_handle", tSTRICTCONTEXTHANDLE},

File diff suppressed because it is too large Load diff

View file

@ -1,27 +1,37 @@
/* A Bison parser, made by GNU Bison 2.1. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
/* A Bison parser, made by GNU Bison 2.4.1. */
This program is free software; you can redistribute it and/or modify
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
@ -147,196 +157,48 @@
tSAFEARRAY = 373,
tSHORT = 374,
tSIGNED = 375,
tSINGLE = 376,
tSIZEIS = 377,
tSIZEOF = 378,
tSMALL = 379,
tSOURCE = 380,
tSTATIC = 381,
tSTDCALL = 382,
tSTRICTCONTEXTHANDLE = 383,
tSTRING = 384,
tSTRUCT = 385,
tSWITCH = 386,
tSWITCHIS = 387,
tSWITCHTYPE = 388,
tTRANSMITAS = 389,
tTRUE = 390,
tTYPEDEF = 391,
tUNION = 392,
tUNIQUE = 393,
tUNSIGNED = 394,
tUUID = 395,
tV1ENUM = 396,
tVARARG = 397,
tVERSION = 398,
tVOID = 399,
tWCHAR = 400,
tWIREMARSHAL = 401,
ADDRESSOF = 402,
NEG = 403,
POS = 404,
PPTR = 405,
CAST = 406
tSIZEIS = 376,
tSIZEOF = 377,
tSMALL = 378,
tSOURCE = 379,
tSTATIC = 380,
tSTDCALL = 381,
tSTRICTCONTEXTHANDLE = 382,
tSTRING = 383,
tSTRUCT = 384,
tSWITCH = 385,
tSWITCHIS = 386,
tSWITCHTYPE = 387,
tTRANSMITAS = 388,
tTRUE = 389,
tTYPEDEF = 390,
tUNION = 391,
tUNIQUE = 392,
tUNSIGNED = 393,
tUUID = 394,
tV1ENUM = 395,
tVARARG = 396,
tVERSION = 397,
tVOID = 398,
tWCHAR = 399,
tWIREMARSHAL = 400,
ADDRESSOF = 401,
NEG = 402,
POS = 403,
PPTR = 404,
CAST = 405
};
#endif
/* Tokens. */
#define aIDENTIFIER 258
#define aKNOWNTYPE 259
#define aNUM 260
#define aHEXNUM 261
#define aDOUBLE 262
#define aSTRING 263
#define aWSTRING 264
#define aUUID 265
#define aEOF 266
#define SHL 267
#define SHR 268
#define MEMBERPTR 269
#define EQUALITY 270
#define INEQUALITY 271
#define GREATEREQUAL 272
#define LESSEQUAL 273
#define LOGICALOR 274
#define LOGICALAND 275
#define tAGGREGATABLE 276
#define tALLOCATE 277
#define tAPPOBJECT 278
#define tASYNC 279
#define tASYNCUUID 280
#define tAUTOHANDLE 281
#define tBINDABLE 282
#define tBOOLEAN 283
#define tBROADCAST 284
#define tBYTE 285
#define tBYTECOUNT 286
#define tCALLAS 287
#define tCALLBACK 288
#define tCASE 289
#define tCDECL 290
#define tCHAR 291
#define tCOCLASS 292
#define tCODE 293
#define tCOMMSTATUS 294
#define tCONST 295
#define tCONTEXTHANDLE 296
#define tCONTEXTHANDLENOSERIALIZE 297
#define tCONTEXTHANDLESERIALIZE 298
#define tCONTROL 299
#define tCPPQUOTE 300
#define tDEFAULT 301
#define tDEFAULTCOLLELEM 302
#define tDEFAULTVALUE 303
#define tDEFAULTVTABLE 304
#define tDISPLAYBIND 305
#define tDISPINTERFACE 306
#define tDLLNAME 307
#define tDOUBLE 308
#define tDUAL 309
#define tENDPOINT 310
#define tENTRY 311
#define tENUM 312
#define tERRORSTATUST 313
#define tEXPLICITHANDLE 314
#define tEXTERN 315
#define tFALSE 316
#define tFASTCALL 317
#define tFLOAT 318
#define tHANDLE 319
#define tHANDLET 320
#define tHELPCONTEXT 321
#define tHELPFILE 322
#define tHELPSTRING 323
#define tHELPSTRINGCONTEXT 324
#define tHELPSTRINGDLL 325
#define tHIDDEN 326
#define tHYPER 327
#define tID 328
#define tIDEMPOTENT 329
#define tIIDIS 330
#define tIMMEDIATEBIND 331
#define tIMPLICITHANDLE 332
#define tIMPORT 333
#define tIMPORTLIB 334
#define tIN 335
#define tIN_LINE 336
#define tINLINE 337
#define tINPUTSYNC 338
#define tINT 339
#define tINT64 340
#define tINTERFACE 341
#define tLCID 342
#define tLENGTHIS 343
#define tLIBRARY 344
#define tLOCAL 345
#define tLONG 346
#define tMETHODS 347
#define tMODULE 348
#define tNONBROWSABLE 349
#define tNONCREATABLE 350
#define tNONEXTENSIBLE 351
#define tNULL 352
#define tOBJECT 353
#define tODL 354
#define tOLEAUTOMATION 355
#define tOPTIONAL 356
#define tOUT 357
#define tPASCAL 358
#define tPOINTERDEFAULT 359
#define tPROPERTIES 360
#define tPROPGET 361
#define tPROPPUT 362
#define tPROPPUTREF 363
#define tPTR 364
#define tPUBLIC 365
#define tRANGE 366
#define tREADONLY 367
#define tREF 368
#define tREGISTER 369
#define tREQUESTEDIT 370
#define tRESTRICTED 371
#define tRETVAL 372
#define tSAFEARRAY 373
#define tSHORT 374
#define tSIGNED 375
#define tSINGLE 376
#define tSIZEIS 377
#define tSIZEOF 378
#define tSMALL 379
#define tSOURCE 380
#define tSTATIC 381
#define tSTDCALL 382
#define tSTRICTCONTEXTHANDLE 383
#define tSTRING 384
#define tSTRUCT 385
#define tSWITCH 386
#define tSWITCHIS 387
#define tSWITCHTYPE 388
#define tTRANSMITAS 389
#define tTRUE 390
#define tTYPEDEF 391
#define tUNION 392
#define tUNIQUE 393
#define tUNSIGNED 394
#define tUUID 395
#define tV1ENUM 396
#define tVARARG 397
#define tVERSION 398
#define tVOID 399
#define tWCHAR 400
#define tWIREMARSHAL 401
#define ADDRESSOF 402
#define NEG 403
#define POS 404
#define PPTR 405
#define CAST 406
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
{
/* Line 1676 of yacc.c */
#line 156 "parser.y"
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 176 "parser.y"
typedef union YYSTYPE {
attr_t *attr;
attr_list_t *attr_list;
str_list_t *str_list;
@ -363,15 +225,17 @@ typedef union YYSTYPE {
struct _import_t *import;
struct _decl_spec_t *declspec;
enum storage_class stgclass;
/* Line 1676 of yacc.c */
#line 233 "parser.tab.h"
} YYSTYPE;
/* Line 1447 of yacc.c. */
#line 369 "parser.tab.h"
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE parser_lval;

View file

@ -28,9 +28,6 @@
#include <assert.h>
#include <ctype.h>
#include <string.h>
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include "widl.h"
#include "utils.h"
@ -68,7 +65,7 @@
#define YYERROR_VERBOSE
unsigned char pointer_default = RPC_FC_UP;
static unsigned char pointer_default = RPC_FC_UP;
static int is_object_interface = FALSE;
typedef struct list typelist_t;
@ -92,7 +89,6 @@ typedef struct _decl_spec_t
typelist_t incomplete_types = LIST_INIT(incomplete_types);
static void add_incomplete(type_t *t);
static void fix_incomplete(void);
static void fix_incomplete_types(type_t *complete_type);
@ -109,30 +105,18 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls);
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
static ifref_t *make_ifref(type_t *iface);
static var_list_t *append_var(var_list_t *list, var_t *var);
static var_list_t *append_var_list(var_list_t *list, var_list_t *vars);
static var_t *make_var(char *name);
static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p);
static declarator_t *make_declarator(var_t *var);
static func_list_t *append_func(func_list_t *list, func_t *func);
static func_t *make_func(var_t *def);
static type_t *make_class(char *name);
static type_t *make_safearray(type_t *type);
static type_t *make_builtin(char *name);
static type_t *make_int(int sign);
static typelib_t *make_library(const char *name, const attr_list_t *attrs);
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type);
static type_t *type_new_enum(char *name, var_list_t *enums);
static type_t *type_new_struct(char *name, int defined, var_list_t *fields);
static type_t *type_new_nonencapsulated_union(char *name, var_list_t *fields);
static type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
static type_t *reg_type(type_t *type, const char *name, int t);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
static type_t *find_type_or_error(const char *name, int t);
static type_t *find_type_or_error2(char *name, int t);
static type_t *get_type(unsigned char type, char *name, int t);
static var_t *reg_const(var_t *var);
@ -168,10 +152,6 @@ static statement_t *make_statement_import(const char *str);
static statement_t *make_statement_typedef(var_list_t *names);
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
#define tsENUM 1
#define tsSTRUCT 2
#define tsUNION 3
%}
%union {
attr_t *attr;
@ -274,7 +254,6 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
%token tSAFEARRAY
%token tSHORT
%token tSIGNED
%token tSINGLE
%token tSIZEIS tSIZEOF
%token tSMALL
%token tSOURCE
@ -614,14 +593,14 @@ enum_list: enum { if (!$1->eval)
enum: ident '=' expr_int_const { $$ = reg_const($1);
$$->eval = $3;
$$->type = make_int(0);
$$->type = type_new_int(TYPE_BASIC_INT, 0);
}
| ident { $$ = reg_const($1);
$$->type = make_int(0);
$$->type = type_new_int(TYPE_BASIC_INT, 0);
}
;
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, $4); }
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, TRUE, $4); }
;
m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
@ -772,51 +751,35 @@ ident: aIDENTIFIER { $$ = make_var($1); }
| aKNOWNTYPE { $$ = make_var($<str>1); }
;
base_type: tBYTE { $$ = make_builtin($<str>1); }
| tWCHAR { $$ = make_builtin($<str>1); }
base_type: tBYTE { $$ = find_type_or_error($<str>1, 0); }
| tWCHAR { $$ = find_type_or_error($<str>1, 0); }
| int_std
| tSIGNED int_std { $$ = $2; $$->sign = 1; }
| tUNSIGNED int_std { $$ = $2; $$->sign = -1;
switch ($$->type) {
case RPC_FC_CHAR: break;
case RPC_FC_SMALL: $$->type = RPC_FC_USMALL; break;
case RPC_FC_SHORT: $$->type = RPC_FC_USHORT; break;
case RPC_FC_LONG: $$->type = RPC_FC_ULONG; break;
case RPC_FC_HYPER:
if ($$->name[0] == 'h') /* hyper, as opposed to __int64 */
{
$$ = type_new_alias($$, "MIDL_uhyper");
$$->sign = 0;
}
break;
default: break;
}
}
| tUNSIGNED { $$ = make_int(-1); }
| tFLOAT { $$ = make_builtin($<str>1); }
| tSINGLE { $$ = find_type("float", 0); }
| tDOUBLE { $$ = make_builtin($<str>1); }
| tBOOLEAN { $$ = make_builtin($<str>1); }
| tERRORSTATUST { $$ = make_builtin($<str>1); }
| tHANDLET { $$ = make_builtin($<str>1); }
| tSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), -1); }
| tUNSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), 1); }
| tUNSIGNED { $$ = type_new_int(TYPE_BASIC_INT, 1); }
| tFLOAT { $$ = find_type_or_error($<str>1, 0); }
| tDOUBLE { $$ = find_type_or_error($<str>1, 0); }
| tBOOLEAN { $$ = find_type_or_error($<str>1, 0); }
| tERRORSTATUST { $$ = find_type_or_error($<str>1, 0); }
| tHANDLET { $$ = find_type_or_error($<str>1, 0); }
;
m_int:
| tINT
;
int_std: tINT { $$ = make_builtin($<str>1); }
| tSHORT m_int { $$ = make_builtin($<str>1); }
| tSMALL { $$ = make_builtin($<str>1); }
| tLONG m_int { $$ = make_builtin($<str>1); }
| tHYPER m_int { $$ = make_builtin($<str>1); }
| tINT64 { $$ = make_builtin($<str>1); }
| tCHAR { $$ = make_builtin($<str>1); }
int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
| tSHORT m_int { $$ = type_new_int(TYPE_BASIC_INT16, 0); }
| tSMALL { $$ = type_new_int(TYPE_BASIC_INT8, 0); }
| tLONG m_int { $$ = type_new_int(TYPE_BASIC_INT32, 0); }
| tHYPER m_int { $$ = type_new_int(TYPE_BASIC_HYPER, 0); }
| tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 0); }
| tCHAR { $$ = type_new_int(TYPE_BASIC_CHAR, 0); }
;
coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); }
coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); }
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0);
if ($$->type != RPC_FC_COCLASS)
if (type_get_type_detect_alias($$) != TYPE_COCLASS)
error_loc("%s was not declared a coclass at %s:%d\n",
$2, $$->loc_info.input_name,
$$->loc_info.line_number);
@ -841,8 +804,8 @@ coclass_int:
m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; }
;
dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); }
| tDISPINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); }
dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, 0); }
| tDISPINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, 0); }
;
dispinterfacehdr: attributes dispinterface { attr_t *attrs;
@ -879,8 +842,8 @@ inherit: { $$ = NULL; }
| ':' aKNOWNTYPE { $$ = find_type_or_error2($2, 0); }
;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); }
| tINTERFACE aKNOWNTYPE { $$ = get_type(RPC_FC_IP, $2, 0); }
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, 0); }
| tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, 0); }
;
interfacehdr: attributes interface { $$.interface = $2;
@ -965,7 +928,7 @@ decl_spec_no_type:
declarator:
'*' m_type_qual_list declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(NULL, $2)); }
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
| callconv declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| direct_declarator
;
@ -999,15 +962,15 @@ pointer_type:
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, TRUE, $4); }
;
type: tVOID { $$ = find_type_or_error("void", 0); }
type: tVOID { $$ = type_new_void(); }
| aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
| base_type { $$ = $1; }
| enumdef { $$ = $1; }
| tENUM aIDENTIFIER { $$ = find_type_or_error2($2, tsENUM); }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); }
| structdef { $$ = $1; }
| tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
| uniondef { $$ = $1; }
| tUNION aIDENTIFIER { $$ = find_type_or_error2($2, tsUNION); }
| tUNION aIDENTIFIER { $$ = type_new_nonencapsulated_union($2, FALSE, NULL); }
| tSAFEARRAY '(' type ')' { $$ = make_safearray($3); }
;
@ -1018,7 +981,7 @@ typedef: tTYPEDEF m_attributes decl_spec declarator_list
;
uniondef: tUNION t_ident '{' ne_union_fields '}'
{ $$ = type_new_nonencapsulated_union($2, $4); }
{ $$ = type_new_nonencapsulated_union($2, TRUE, $4); }
| tUNION t_ident
tSWITCH '(' s_field ')'
m_ident '{' cases '}' { $$ = type_new_encapsulated_union($2, $5, $7, $9); }
@ -1031,49 +994,26 @@ version:
%%
static void decl_builtin(const char *name, unsigned char type)
static void decl_builtin_basic(const char *name, enum type_basic_type type)
{
type_t *t = make_type(type, NULL);
t->name = xstrdup(name);
type_t *t = type_new_basic(type);
reg_type(t, name, 0);
}
static type_t *make_builtin(char *name)
static void decl_builtin_alias(const char *name, type_t *t)
{
/* NAME is strdup'd in the lexer */
type_t *t = duptype(find_type_or_error(name, 0), 0);
t->name = name;
return t;
}
static type_t *make_int(int sign)
{
type_t *t = duptype(find_type_or_error("int", 0), 1);
t->sign = sign;
if (sign < 0)
t->type = t->type == RPC_FC_LONG ? RPC_FC_ULONG : RPC_FC_USHORT;
return t;
reg_type(type_new_alias(t, name), name, 0);
}
void init_types(void)
{
decl_builtin("void", 0);
decl_builtin("byte", RPC_FC_BYTE);
decl_builtin("wchar_t", RPC_FC_WCHAR);
decl_builtin("int", RPC_FC_LONG); /* win32 */
decl_builtin("short", RPC_FC_SHORT);
decl_builtin("small", RPC_FC_SMALL);
decl_builtin("long", RPC_FC_LONG);
decl_builtin("hyper", RPC_FC_HYPER);
decl_builtin("__int64", RPC_FC_HYPER);
decl_builtin("char", RPC_FC_CHAR);
decl_builtin("float", RPC_FC_FLOAT);
decl_builtin("double", RPC_FC_DOUBLE);
decl_builtin("boolean", RPC_FC_BYTE);
decl_builtin("error_status_t", RPC_FC_ERROR_STATUS_T);
decl_builtin("handle_t", RPC_FC_BIND_PRIMITIVE);
decl_builtin_basic("byte", TYPE_BASIC_BYTE);
decl_builtin_basic("wchar_t", TYPE_BASIC_WCHAR);
decl_builtin_basic("float", TYPE_BASIC_FLOAT);
decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
}
static str_list_t *append_str(str_list_t *list, char *str)
@ -1286,98 +1226,6 @@ void clear_all_offsets(void)
node->data.typestring_offset = node->data.ptrdesc = 0;
}
type_t *make_type(unsigned char type, type_t *ref)
{
type_t *t = alloc_type();
t->name = NULL;
t->type = type;
t->ref = ref;
t->attrs = NULL;
t->orig = NULL;
memset(&t->details, 0, sizeof(t->details));
t->typestring_offset = 0;
t->ptrdesc = 0;
t->declarray = FALSE;
t->ignore = (parse_only != 0);
t->sign = 0;
t->defined = FALSE;
t->written = FALSE;
t->user_types_registered = FALSE;
t->tfswrite = FALSE;
t->checked = FALSE;
t->is_alias = FALSE;
t->typelib_idx = -1;
init_loc_info(&t->loc_info);
return t;
}
static type_t *type_new_enum(char *name, var_list_t *enums)
{
type_t *t = get_type(RPC_FC_ENUM16, name, tsENUM);
if (enums)
{
t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
t->details.enumeration->enums = enums;
}
else
t->details.enumeration = NULL;
t->defined = TRUE;
return t;
}
static type_t *type_new_struct(char *name, int defined, var_list_t *fields)
{
type_t *tag_type = name ? find_type(name, tsSTRUCT) : NULL;
type_t *t = make_type(RPC_FC_STRUCT, NULL);
t->name = name;
if (defined || (tag_type && tag_type->details.structure))
{
if (tag_type && tag_type->details.structure)
{
t->details.structure = tag_type->details.structure;
t->type = tag_type->type;
}
else if (defined)
{
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
}
}
if (name)
{
if (fields)
reg_type(t, name, tsSTRUCT);
else
add_incomplete(t);
}
return t;
}
static type_t *type_new_nonencapsulated_union(char *name, var_list_t *fields)
{
type_t *t = get_type(RPC_FC_NON_ENCAPSULATED_UNION, name, tsUNION);
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
return t;
}
static type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases)
{
type_t *t = get_type(RPC_FC_ENCAPSULATED_UNION, name, tsUNION);
if (!union_field) union_field = make_var( xstrdup("tagged_union") );
union_field->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL);
union_field->type->details.structure = xmalloc(sizeof(*union_field->type->details.structure));
union_field->type->details.structure->fields = cases;
union_field->type->defined = TRUE;
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = append_var( NULL, switch_field );
t->details.structure->fields = append_var( t->details.structure->fields, union_field );
t->defined = TRUE;
return t;
}
static void type_function_add_head_arg(type_t *type, var_t *arg)
{
if (!type->details.function->args)
@ -1393,9 +1241,10 @@ static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
type_t *ptrchain_type;
if (!ptrchain)
return type;
for (ptrchain_type = ptrchain; ptrchain_type->ref; ptrchain_type = ptrchain_type->ref)
for (ptrchain_type = ptrchain; type_pointer_get_ref(ptrchain_type); ptrchain_type = type_pointer_get_ref(ptrchain_type))
;
ptrchain_type->ref = type;
assert(ptrchain_type->type_type == TYPE_POINTER);
ptrchain_type->details.pointer.ref = type;
return ptrchain;
}
@ -1429,9 +1278,8 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
v->stgclass = decl_spec->stgclass;
/* the highest level of pointer specified should default to the var's ptr attr
* or (RPC_FC_RP if not specified and it's a top level ptr), not
* pointer_default so we need to fix that up here */
/* check for pointer attribute being applied to non-pointer, non-array
* type */
if (!arr)
{
int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
@ -1447,11 +1295,21 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
else
break;
}
if (ptr && is_ptr(ptr) && (ptr_attr || top))
if (is_ptr(ptr))
{
/* duplicate type to avoid changing original type */
*pt = duptype(*pt, 1);
(*pt)->type = ptr_attr ? ptr_attr : RPC_FC_RP;
if (ptr_attr && ptr_attr != RPC_FC_UP &&
type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
warning_loc_info(&v->loc_info,
"%s: pointer attribute applied to interface "
"pointer type has no effect\n", v->name);
if (!ptr_attr && top && (*pt)->details.pointer.def_fc != RPC_FC_RP)
{
/* FIXME: this is a horrible hack to cope with the issue that we
* store an offset to the typeformat string in the type object, but
* two typeformat strings may be written depending on whether the
* pointer is a toplevel parameter or not */
*pt = duptype(*pt, 1);
}
}
else if (ptr_attr)
error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
@ -1463,9 +1321,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
if (is_attr(v->attrs, ATTR_V1ENUM))
{
if (v->type->type == RPC_FC_ENUM16)
v->type->type = RPC_FC_ENUM32;
else
if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
}
@ -1485,18 +1341,19 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
if (0)
{
unsigned int align = 0;
size_t size = type_memsize(v->type, &align);
unsigned int size = type_memsize(v->type, &align);
if (0xffffffffuL / size < (unsigned long) dim->cval)
if (0xffffffffu / size < dim->cval)
error_loc("%s: total array size is too large\n", v->name);
}
}
else
sizeless = TRUE;
*ptype = type_new_array(NULL, *ptype, TRUE,
*ptype = type_new_array(NULL, *ptype, FALSE,
dim->is_const ? dim->cval : 0,
dim->is_const ? NULL : dim, NULL);
dim->is_const ? NULL : dim, NULL,
pointer_default);
}
ptype = &v->type;
@ -1510,18 +1367,21 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
error_loc("%s: cannot specify size_is for a fixed sized array\n", v->name);
else
*ptype = type_new_array((*ptype)->name,
type_array_get_element(*ptype), TRUE,
0, dim, NULL);
type_array_get_element(*ptype), FALSE,
0, dim, NULL, 0);
}
else if (is_ptr(*ptype))
*ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), FALSE,
0, dim, NULL);
*ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
0, dim, NULL, pointer_default);
else
error_loc("%s: size_is attribute applied to illegal type\n", v->name);
}
ptype = &(*ptype)->ref;
if (*ptype == NULL)
if (is_ptr(*ptype))
ptype = &(*ptype)->details.pointer.ref;
else if (is_array(*ptype))
ptype = &(*ptype)->details.array.elem;
else
error_loc("%s: too many expressions in size_is attribute\n", v->name);
}
@ -1534,17 +1394,20 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
{
*ptype = type_new_array((*ptype)->name,
type_array_get_element(*ptype),
(*ptype)->declarray,
type_array_is_decl_as_ptr(*ptype),
type_array_get_dim(*ptype),
type_array_get_conformance(*ptype),
dim);
dim, type_array_get_ptr_default_fc(*ptype));
}
else
error_loc("%s: length_is attribute applied to illegal type\n", v->name);
}
ptype = &(*ptype)->ref;
if (*ptype == NULL)
if (is_ptr(*ptype))
ptype = &(*ptype)->details.pointer.ref;
else if (is_array(*ptype))
ptype = &(*ptype)->details.array.elem;
else
error_loc("%s: too many expressions in length_is attribute\n", v->name);
}
@ -1558,8 +1421,8 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
v->type = func_type;
for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
;
assert(ft->type == RPC_FC_FUNCTION);
ft->ref = return_type;
assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
ft->details.function->rettype = return_type;
/* move calling convention attribute, if present, from pointer nodes to
* function node */
for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
@ -1617,7 +1480,7 @@ static ifref_t *make_ifref(type_t *iface)
return l;
}
static var_list_t *append_var(var_list_t *list, var_t *var)
var_list_t *append_var(var_list_t *list, var_t *var)
{
if (!var) return list;
if (!list)
@ -1641,7 +1504,7 @@ static var_list_t *append_var_list(var_list_t *list, var_list_t *vars)
return list;
}
static var_t *make_var(char *name)
var_t *make_var(char *name)
{
var_t *v = xmalloc(sizeof(var_t));
v->name = name;
@ -1693,18 +1556,10 @@ static func_t *make_func(var_t *def)
return f;
}
static type_t *make_class(char *name)
{
type_t *c = make_type(RPC_FC_COCLASS, NULL);
c->name = name;
return c;
}
static type_t *make_safearray(type_t *type)
{
type_t *sa = find_type_or_error("SAFEARRAY", 0);
sa->ref = type;
return make_type(pointer_default, sa);
return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
NULL, NULL, RPC_FC_RP);
}
static typelib_t *make_library(const char *name, const attr_list_t *attrs)
@ -1742,7 +1597,7 @@ struct rtype {
struct rtype *type_hash[HASHMAX];
static type_t *reg_type(type_t *type, const char *name, int t)
type_t *reg_type(type_t *type, const char *name, int t)
{
struct rtype *nt;
int hash;
@ -1764,10 +1619,13 @@ static type_t *reg_type(type_t *type, const char *name, int t)
static int is_incomplete(const type_t *t)
{
return !t->defined && (is_struct(t->type) || is_union(t->type));
return !t->defined &&
(type_get_type_detect_alias(t) == TYPE_STRUCT ||
type_get_type_detect_alias(t) == TYPE_UNION ||
type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
}
static void add_incomplete(type_t *t)
void add_incomplete(type_t *t)
{
struct typenode *tn = xmalloc(sizeof *tn);
tn->type = t;
@ -1779,7 +1637,9 @@ static void fix_type(type_t *t)
if (type_is_alias(t) && is_incomplete(t)) {
type_t *ot = type_alias_get_aliasee(t);
fix_type(ot);
if (is_struct(ot->type) || is_union(ot->type))
if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
type_get_type_detect_alias(ot) == TYPE_UNION ||
type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
t->details.structure = ot->details.structure;
t->defined = ot->defined;
}
@ -1802,12 +1662,9 @@ static void fix_incomplete_types(type_t *complete_type)
LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry)
{
if (((is_struct(complete_type->type) && is_struct(tn->type->type)) ||
(is_union(complete_type->type) && is_union(tn->type->type))) &&
!strcmp(complete_type->name, tn->type->name))
if (type_is_equal(complete_type, tn->type))
{
tn->type->details.structure = complete_type->details.structure;
tn->type->type = complete_type->type;
list_remove(&tn->entry);
free(tn);
}
@ -1823,13 +1680,14 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
if (is_str)
{
type_t *t = decl_spec->type;
unsigned char c;
while (is_ptr(t))
t = type_pointer_get_ref(t);
c = t->type;
if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
if (type_get_type(t) != TYPE_BASIC &&
(get_basic_fc(t) != RPC_FC_CHAR &&
get_basic_fc(t) != RPC_FC_BYTE &&
get_basic_fc(t) != RPC_FC_WCHAR))
{
decl = LIST_ENTRY( list_head( decls ), const declarator_t, entry );
error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n",
@ -1840,8 +1698,10 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
/* We must generate names for tagless enum, struct or union.
Typedef-ing a tagless enum, struct or union means we want the typedef
to be included in a library hence the public attribute. */
if ((type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32 ||
is_struct(type->type) || is_union(type->type)) &&
if ((type_get_type_detect_alias(type) == TYPE_ENUM ||
type_get_type_detect_alias(type) == TYPE_STRUCT ||
type_get_type_detect_alias(type) == TYPE_UNION ||
type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION) &&
!type->name && !parse_only)
{
if (! is_attr(attrs, ATTR_PUBLIC))
@ -1908,7 +1768,7 @@ int is_type(const char *name)
return find_type(name, 0) != NULL;
}
static type_t *get_type(unsigned char type, char *name, int t)
type_t *get_type(enum type_type type, char *name, int t)
{
type_t *tp;
if (name) {
@ -1918,7 +1778,7 @@ static type_t *get_type(unsigned char type, char *name, int t)
return tp;
}
}
tp = make_type(type, NULL);
tp = make_type(type);
tp->name = name;
if (!name) return tp;
return reg_type(tp, name, t);
@ -2120,7 +1980,7 @@ static void check_arg(var_t *arg)
const type_t *t = arg->type;
const attr_t *attr;
if (t->type == 0 && ! is_var_ptr(arg))
if (type_get_type(t) == TYPE_VOID)
error_loc("argument '%s' has void type\n", arg->name);
if (arg->attrs)
@ -2253,23 +2113,44 @@ static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
static int is_allowed_conf_type(const type_t *type)
{
switch (type->type)
switch (type_get_type(type))
{
case RPC_FC_CHAR:
case RPC_FC_SMALL:
case RPC_FC_BYTE:
case RPC_FC_USMALL:
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_ENUM16:
case RPC_FC_USHORT:
case RPC_FC_LONG:
case RPC_FC_ENUM32:
case RPC_FC_ULONG:
case TYPE_ENUM:
return TRUE;
default:
case TYPE_BASIC:
switch (type_basic_get_type(type))
{
case TYPE_BASIC_INT8:
case TYPE_BASIC_INT16:
case TYPE_BASIC_INT32:
case TYPE_BASIC_INT64:
case TYPE_BASIC_INT:
case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER:
case TYPE_BASIC_BYTE:
case TYPE_BASIC_WCHAR:
case TYPE_BASIC_ERROR_STATUS_T:
return TRUE;
default:
return FALSE;
}
case TYPE_ALIAS:
/* shouldn't get here because of type_get_type call above */
assert(0);
/* fall through */
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ENCAPSULATED_UNION:
case TYPE_ARRAY:
case TYPE_POINTER:
case TYPE_VOID:
case TYPE_MODULE:
case TYPE_COCLASS:
case TYPE_FUNCTION:
case TYPE_INTERFACE:
return FALSE;
}
return FALSE;
}
static int is_ptr_guid_type(const type_t *type)
@ -2309,16 +2190,26 @@ static void check_field_common(const type_t *container_type,
const char *container_name, const var_t *arg)
{
type_t *type = arg->type;
int is_wire_marshal = 0;
int is_context_handle = 0;
int more_to_do;
const char *container_type_name = NULL;
if (is_struct(container_type->type))
switch (type_get_type_detect_alias(type))
{
case TYPE_STRUCT:
container_type_name = "struct";
else if (is_union(container_type->type))
break;
case TYPE_UNION:
container_type_name = "union";
else if (container_type->type == RPC_FC_FUNCTION)
break;
case TYPE_ENCAPSULATED_UNION:
container_type_name = "encapsulated union";
break;
case TYPE_FUNCTION:
container_type_name = "function";
break;
default:
break;
}
if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
(is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
@ -2366,35 +2257,56 @@ static void check_field_common(const type_t *container_type,
}
}
/* get fundamental type for the argument */
for (;;)
do
{
if (is_attr(type->attrs, ATTR_WIREMARSHAL))
{
is_wire_marshal = 1;
break;
}
if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
{
is_context_handle = 1;
break;
}
if (type_is_alias(type))
type = type_alias_get_aliasee(type);
else if (is_ptr(type))
type = type_pointer_get_ref(type);
else if (is_array(type))
type = type_array_get_element(type);
else
break;
}
more_to_do = FALSE;
if (type->type == 0 && !is_attr(arg->attrs, ATTR_IIDIS) && !is_wire_marshal && !is_context_handle)
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n", arg->name, container_type_name, container_name);
else if (type->type == RPC_FC_FUNCTION)
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n", arg->name, container_type_name, container_name);
else if (!is_wire_marshal && (is_struct(type->type) || is_union(type->type)))
check_remoting_fields(arg, type);
switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
{
case TGT_STRUCT:
case TGT_UNION:
check_remoting_fields(arg, type);
break;
case TGT_INVALID:
switch (type_get_type(type))
{
case TYPE_VOID:
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n",
arg->name, container_type_name, container_name);
break;
case TYPE_FUNCTION:
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n",
arg->name, container_type_name, container_name);
break;
case TYPE_COCLASS:
case TYPE_INTERFACE:
case TYPE_MODULE:
/* FIXME */
break;
default:
break;
}
case TGT_CTXT_HANDLE:
case TGT_CTXT_HANDLE_POINTER:
/* FIXME */
break;
case TGT_POINTER:
type = type_pointer_get_ref(type);
more_to_do = TRUE;
break;
case TGT_ARRAY:
type = type_array_get_element(type);
more_to_do = TRUE;
break;
case TGT_USER_TYPE:
case TGT_STRING:
case TGT_IFACE_POINTER:
case TGT_BASIC:
case TGT_ENUM:
/* nothing to do */
break;
}
} while (more_to_do);
}
static void check_remoting_fields(const var_t *var, type_t *type)
@ -2409,14 +2321,14 @@ static void check_remoting_fields(const var_t *var, type_t *type)
type->checked = TRUE;
if (is_struct(type->type))
if (type_get_type(type) == TYPE_STRUCT)
{
if (type_is_complete(type))
fields = type_struct_get_fields(type);
else
error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
}
else if (is_union(type->type))
else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
fields = type_union_get_cases(type);
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
@ -2431,36 +2343,37 @@ static void check_remoting_args(const var_t *func)
if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
{
int ptr_level = 0;
const type_t *type = arg->type;
/* get pointer level and fundamental type for the argument */
for (;;)
{
if (is_attr(type->attrs, ATTR_WIREMARSHAL))
break;
if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
break;
if (type_is_alias(type))
type = type_alias_get_aliasee(type);
else if (is_ptr(type))
{
ptr_level++;
type = type_pointer_get_ref(type);
}
else
break;
}
/* check that [out] parameters have enough pointer levels */
if (is_attr(arg->attrs, ATTR_OUT))
{
if (!is_array(type))
switch (typegen_detect_type(type, arg->attrs, TDT_ALL_TYPES))
{
if (!ptr_level)
error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
if (type->type == RPC_FC_IP && ptr_level == 1)
error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
case TGT_BASIC:
case TGT_ENUM:
case TGT_STRUCT:
case TGT_UNION:
case TGT_CTXT_HANDLE:
case TGT_USER_TYPE:
error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
break;
case TGT_IFACE_POINTER:
error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
break;
case TGT_STRING:
if (!is_array(type))
{
/* FIXME */
}
break;
case TGT_INVALID:
/* already error'd before we get here */
case TGT_CTXT_HANDLE_POINTER:
case TGT_POINTER:
case TGT_ARRAY:
/* OK */
break;
}
}
@ -2526,7 +2439,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
{
if (stmt->type == STMT_LIBRARY)
check_statements(stmt->u.lib->stmts, TRUE);
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
check_functions(stmt->u.type, is_inside_library);
}
}
@ -2539,7 +2452,7 @@ static void check_all_user_types(const statement_list_t *stmts)
{
if (stmt->type == STMT_LIBRARY)
check_all_user_types(stmt->u.lib->stmts);
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP &&
else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE &&
!is_local(stmt->u.type->attrs))
{
const statement_t *stmt_func;
@ -2600,8 +2513,9 @@ static statement_t *make_statement_declaration(var_t *var)
if (var->eval)
reg_const(var);
}
else if ((var->stgclass == STG_NONE || var->stgclass == STG_REGISTER) &&
var->type->type != RPC_FC_FUNCTION)
else if (type_get_type(var->type) == TYPE_FUNCTION)
check_function_attrs(var->name, var->attrs);
else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER)
error_loc("instantiation of data is illegal\n");
return stmt;
}

View file

@ -2140,7 +2140,6 @@ static const struct keyword attr_keywords[] =
{"requestedit", tREQUESTEDIT},
{"restricted", tRESTRICTED},
{"retval", tRETVAL},
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"source", tSOURCE},
{"strict_context_handle", tSTRICTCONTEXTHANDLE},

View file

@ -50,6 +50,7 @@ static int indent = 0;
/* FIXME: support generation of stubless proxies */
static void print_proxy( const char *format, ... ) __attribute__((format (printf, 1, 2)));
static void print_proxy( const char *format, ... )
{
va_list va;
@ -122,12 +123,10 @@ static void init_proxy(const statement_list_t *stmts)
print_proxy( " void *This;\n");
print_proxy( "};\n");
print_proxy( "\n");
print_proxy("#ifndef USE_COMPILER_EXCEPTIONS\n");
print_proxy("static int __proxy_filter( struct __proxy_frame *__frame )\n");
print_proxy( "{\n");
print_proxy( " return (__frame->_StubMsg.dwStubPhase != PROXY_SENDRECEIVE);\n");
print_proxy( "}\n");
print_proxy("#endif /* USE_COMPILER_EXCEPTIONS */\n");
print_proxy( "\n");
}
@ -154,44 +153,17 @@ int is_var_ptr(const var_t *v)
int cant_be_null(const var_t *v)
{
/* Search backwards for the most recent pointer attribute. */
const attr_list_t *attrs = v->attrs;
const type_t *type = v->type;
/* context handles have their own checking so they can be null for the
* purposes of null ref pointer checking */
if (is_aliaschain_attr(type, ATTR_CONTEXTHANDLE))
return 0;
if (is_user_type(type))
return 0;
if (!attrs && is_ptr(type))
{
attrs = type->attrs;
type = type_pointer_get_ref(type);
}
while (attrs)
{
int t = get_attrv(attrs, ATTR_POINTERTYPE);
if (t == RPC_FC_FP || t == RPC_FC_OP || t == RPC_FC_UP)
return 0;
if (t == RPC_FC_RP)
return 1;
if (is_ptr(type))
switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS))
{
attrs = type->attrs;
type = type_pointer_get_ref(type);
case TGT_ARRAY:
case TGT_POINTER:
return (get_pointer_fc(v->type, v->attrs, TRUE) == RPC_FC_RP);
case TGT_CTXT_HANDLE_POINTER:
return TRUE;
default:
return 0;
}
else
attrs = NULL;
}
return 1; /* Default is RPC_FC_RP. */
}
static int need_delegation(const type_t *iface)
@ -253,22 +225,18 @@ static void free_variable( const var_t *arg, const char *local_var_prefix )
return;
}
switch( type->type )
switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_WCHAR:
case RPC_FC_SHORT:
case RPC_FC_USHORT:
case RPC_FC_ENUM16:
case RPC_FC_LONG:
case RPC_FC_ULONG:
case RPC_FC_ENUM32:
case RPC_FC_STRUCT:
case TGT_ENUM:
case TGT_BASIC:
break;
case RPC_FC_FP:
case RPC_FC_IP:
case TGT_STRUCT:
if (get_struct_fc(type) != RPC_FC_STRUCT)
print_proxy("/* FIXME: %s code for %s struct type 0x%x missing */\n", __FUNCTION__, arg->name, get_struct_fc(type) );
break;
case TGT_IFACE_POINTER:
iid = get_attrp( arg->attrs, ATTR_IIDIS );
if( iid )
{
@ -276,13 +244,20 @@ static void free_variable( const var_t *arg, const char *local_var_prefix )
write_expr(proxy, iid, 1, 1, NULL, NULL, local_var_prefix);
print_proxy( ";\n\n" );
}
print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, ");
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
fprintf(proxy, "(void*)%s );\n", arg->name );
/* fall through */
case TGT_POINTER:
if (get_pointer_fc(type, arg->attrs, TRUE) == RPC_FC_FP)
{
print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, ");
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
fprintf(proxy, "(void*)%s );\n", arg->name );
}
else
print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) );
break;
default:
print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type->type );
print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) );
}
}
@ -327,9 +302,9 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
print_proxy( "struct __proxy_frame __f, * const __frame = &__f;\n" );
/* local variables */
if (has_ret) {
print_proxy( "" );
print_proxy( "%s", "" );
write_type_decl_left(proxy, type_function_get_rettype(func->type));
print_proxy(" _RetVal;\n");
print_proxy( " _RetVal;\n");
}
print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
if (has_ret) {
@ -483,8 +458,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n");
fprintf(proxy, "\n");
print_proxy("");
if (has_ret) fprintf(proxy, "__frame->_RetVal = ");
print_proxy( "%s", has_ret ? "__frame->_RetVal = " : "" );
if (cas) fprintf(proxy, "%s_%s_Stub", iface->name, cas);
else fprintf(proxy, "__frame->_This->lpVtbl->%s", get_name(func));
fprintf(proxy, "(__frame->_This");
@ -492,7 +466,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
if (type_get_function_args(func->type))
{
LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
fprintf(proxy, ", %s__frame->%s", arg->type->declarray ? "*" : "", arg->name);
fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name);
}
fprintf(proxy, ");\n");
fprintf(proxy, "\n");
@ -653,7 +627,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
print_proxy( "static const CINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n", count, iface->name);
print_proxy( "{\n");
indent++;
print_proxy( "{\n", iface->name);
print_proxy( "{\n");
indent++;
print_proxy( "&IID_%s,\n", iface->name);
indent--;
@ -688,7 +662,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
print_proxy( "%d,\n", count);
print_proxy( "&%s_table[-3],\n", iface->name);
indent--;
print_proxy( "},\n", iface->name);
print_proxy( "},\n");
print_proxy( "{\n");
indent++;
print_proxy( "CStdStubBuffer_%s\n", need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
@ -711,7 +685,7 @@ static int does_any_iface(const statement_list_t *stmts, type_pred_t pred)
if (does_any_iface(stmt->u.lib->stmts, pred))
return TRUE;
}
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
if (pred(stmt->u.type))
return TRUE;
@ -748,7 +722,7 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
{
if (stmt->type == STMT_LIBRARY)
write_proxy_stmts(stmt->u.lib->stmts, proc_offset);
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
if (need_proxy(stmt->u.type))
write_proxy(stmt->u.type, proc_offset);
@ -774,7 +748,7 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
{
if (stmt->type == STMT_LIBRARY)
build_iface_list(stmt->u.lib->stmts, ifaces, count);
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
type_t *iface = stmt->u.type;
if (type_iface_get_inherit(iface) && need_proxy(iface))

View file

@ -40,6 +40,7 @@ static FILE* server;
static int indent = 0;
static void print_server(const char *format, ...) __attribute__((format (printf, 1, 2)));
static void print_server(const char *format, ...)
{
va_list va;
@ -79,6 +80,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent++;
write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE);
if (!is_void(type_function_get_rettype(func->type)))
write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE);
if (has_full_pointer)
write_full_pointer_free(server, indent, func);
@ -155,11 +159,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
assign_stub_out_args(server, indent, func, "__frame->");
/* Call the real server function */
if (!is_void(type_function_get_rettype(func->type)))
print_server("__frame->_RetVal = ");
else
print_server("");
fprintf(server, "%s%s", prefix_server, get_name(func));
print_server("%s%s%s",
is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ",
prefix_server, get_name(func));
if (type_get_function_args(func->type))
{
@ -186,7 +188,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
}
else
{
print_server("%s__frame->%s", var->type->declarray ? "*" : "", var->name);
print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name);
}
}
fprintf(server, ");\n");
@ -248,8 +250,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
static void write_dispatchtable(type_t *iface)
{
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
unsigned long method_count = 0;
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
unsigned int method_count = 0;
const statement_t *stmt;
print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name);
@ -323,7 +325,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
static void write_serverinterfacedecl(type_t *iface)
{
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
@ -335,7 +337,7 @@ static void write_serverinterfacedecl(type_t *iface)
print_server("{\n");
indent++;
print_server("sizeof(RPC_SERVER_INTERFACE),\n");
print_server("{{0x%08lx,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n",
print_server("{{0x%08x,0x%04x,0x%04x,{0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x}},{%d,%d}},\n",
uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1],
uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6],
uuid->Data4[7], MAJORVERSION(ver), MINORVERSION(ver));
@ -390,12 +392,13 @@ static void init_server(void)
print_server(" MIDL_STUB_MESSAGE _StubMsg;\n");
print_server("};\n");
print_server("\n");
print_server("#ifndef USE_COMPILER_EXCEPTIONS\n");
print_server("static int __server_filter( struct __server_frame *__frame )\n");
print_server( "{\n");
print_server( " return RPC_BAD_STUB_DATA_EXCEPTION_FILTER;\n");
print_server( " return (__frame->code == STATUS_ACCESS_VIOLATION) ||\n");
print_server( " (__frame->code == STATUS_DATATYPE_MISALIGNMENT) ||\n");
print_server( " (__frame->code == RPC_X_BAD_STUB_DATA) ||\n");
print_server( " (__frame->code == RPC_S_INVALID_BOUND);\n");
print_server( "}\n");
print_server("#endif /* USE_COMPILER_EXCEPTIONS */\n");
print_server( "\n");
}
@ -407,7 +410,7 @@ static void write_server_stmts(const statement_list_t *stmts, int expr_eval_rout
{
if (stmt->type == STMT_LIBRARY)
write_server_stmts(stmt->u.lib->stmts, expr_eval_routines, proc_offset);
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
type_t *iface = stmt->u.type;
if (!need_stub(iface))

File diff suppressed because it is too large Load diff

View file

@ -36,6 +36,28 @@ enum remoting_phase
PHASE_FREE
};
enum typegen_detect_flags
{
TDT_ALL_TYPES = 1 << 0,
TDT_IGNORE_STRINGS = 1 << 1,
};
enum typegen_type
{
TGT_INVALID,
TGT_USER_TYPE,
TGT_CTXT_HANDLE,
TGT_CTXT_HANDLE_POINTER,
TGT_STRING,
TGT_POINTER,
TGT_ARRAY,
TGT_IFACE_POINTER,
TGT_BASIC,
TGT_ENUM,
TGT_STRUCT,
TGT_UNION,
};
typedef int (*type_pred_t)(const type_t *);
void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred);
@ -45,10 +67,10 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
enum pass pass, const var_t *var, const char *varname);
void write_remoting_arguments(FILE *file, int indent, const var_t *func, const char *local_var_prefix,
enum pass pass, enum remoting_phase phase);
size_t get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs);
size_t get_size_procformatstring_func(const var_t *func);
size_t get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred);
size_t get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred);
unsigned int get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs);
unsigned int get_size_procformatstring_func(const var_t *func);
unsigned int get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred);
unsigned int get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred);
void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char *local_var_prefix );
void declare_stub_args( FILE *file, int indent, const var_t *func );
int write_expr_eval_routines(FILE *file, const char *iface);
@ -56,7 +78,7 @@ void write_expr_eval_routine_list(FILE *file, const char *iface);
void write_user_quad_list(FILE *file);
void write_endpoints( FILE *f, const char *prefix, const str_list_t *list );
void write_exceptions( FILE *file );
size_t type_memsize(const type_t *t, unsigned int *align);
unsigned int type_memsize(const type_t *t, unsigned int *align);
int decl_indirect(const type_t *t);
void write_parameters_init(FILE *file, int indent, const var_t *func, const char *local_var_prefix);
void print(FILE *file, int indent, const char *format, va_list ap);
@ -66,3 +88,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name);
int is_full_pointer_function(const var_t *func);
void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_server);
void write_full_pointer_free(FILE *file, int indent, const var_t *func);
unsigned char get_basic_fc(const type_t *type);
unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param);
unsigned char get_struct_fc(const type_t *type);
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags);

View file

@ -108,17 +108,20 @@ static unsigned short builtin_vt(const type_t *t)
}
if (is_string_type (t->attrs, t))
{
unsigned char fc;
const type_t *elem_type;
if (is_array(t))
fc = type_array_get_element(t)->type;
elem_type = type_array_get_element(t);
else
fc = type_pointer_get_ref(t)->type;
switch (fc)
elem_type = type_pointer_get_ref(t);
if (type_get_type(elem_type) == TYPE_BASIC)
{
switch (type_basic_get_type(elem_type))
{
case RPC_FC_CHAR: return VT_LPSTR;
case RPC_FC_WCHAR: return VT_LPWSTR;
case TYPE_BASIC_CHAR: return VT_LPSTR;
case TYPE_BASIC_WCHAR: return VT_LPWSTR;
default: break;
}
}
}
return 0;
}
@ -142,74 +145,89 @@ unsigned short get_type_vt(type_t *t)
if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC))
return VT_USERDEFINED;
switch (t->type) {
case RPC_FC_BYTE:
case RPC_FC_USMALL:
return VT_UI1;
case RPC_FC_CHAR:
case RPC_FC_SMALL:
return VT_I1;
case RPC_FC_WCHAR:
return VT_I2; /* mktyplib seems to parse wchar_t as short */
case RPC_FC_SHORT:
return VT_I2;
case RPC_FC_USHORT:
return VT_UI2;
case RPC_FC_LONG:
if (match(t->name, "int")) return VT_INT;
return VT_I4;
case RPC_FC_ULONG:
if (match(t->name, "int")) return VT_UINT;
return VT_UI4;
case RPC_FC_HYPER:
if (t->sign < 0) return VT_UI8;
if (match(t->name, "MIDL_uhyper")) return VT_UI8;
return VT_I8;
case RPC_FC_FLOAT:
return VT_R4;
case RPC_FC_DOUBLE:
return VT_R8;
case RPC_FC_RP:
case RPC_FC_UP:
case RPC_FC_OP:
case RPC_FC_FP:
case RPC_FC_SMFARRAY:
case RPC_FC_LGFARRAY:
case RPC_FC_SMVARRAY:
case RPC_FC_LGVARRAY:
case RPC_FC_CARRAY:
case RPC_FC_CVARRAY:
case RPC_FC_BOGUS_ARRAY:
if(t->ref)
{
if (match(t->ref->name, "SAFEARRAY"))
return VT_SAFEARRAY;
return VT_PTR;
switch (type_get_type(t)) {
case TYPE_BASIC:
switch (type_basic_get_type(t)) {
case TYPE_BASIC_BYTE:
return VT_UI1;
case TYPE_BASIC_CHAR:
case TYPE_BASIC_INT8:
if (type_basic_get_sign(t) > 0)
return VT_UI1;
else
return VT_I1;
case TYPE_BASIC_WCHAR:
return VT_I2; /* mktyplib seems to parse wchar_t as short */
case TYPE_BASIC_INT16:
if (type_basic_get_sign(t) > 0)
return VT_UI2;
else
return VT_I2;
case TYPE_BASIC_INT:
if (type_basic_get_sign(t) > 0)
return VT_UINT;
else
return VT_INT;
case TYPE_BASIC_INT32:
case TYPE_BASIC_ERROR_STATUS_T:
if (type_basic_get_sign(t) > 0)
return VT_UI4;
else
return VT_I4;
case TYPE_BASIC_INT64:
case TYPE_BASIC_HYPER:
if (type_basic_get_sign(t) > 0)
return VT_UI8;
else
return VT_I8;
case TYPE_BASIC_FLOAT:
return VT_R4;
case TYPE_BASIC_DOUBLE:
return VT_R8;
case TYPE_BASIC_HANDLE:
error("handles can't be used in typelibs\n");
}
error("get_type_vt: unknown-deref-type: %d\n", t->ref->type);
break;
case RPC_FC_IP:
case TYPE_POINTER:
return VT_PTR;
case TYPE_ARRAY:
if (type_array_is_decl_as_ptr(t))
{
if (match(type_array_get_element(t)->name, "SAFEARRAY"))
return VT_SAFEARRAY;
}
else
error("get_type_vt: array types not supported\n");
return VT_PTR;
case TYPE_INTERFACE:
if(match(t->name, "IUnknown"))
return VT_UNKNOWN;
if(match(t->name, "IDispatch"))
return VT_DISPATCH;
return VT_USERDEFINED;
case RPC_FC_ENUM16:
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_BOGUS_STRUCT:
case RPC_FC_COCLASS:
case RPC_FC_MODULE:
case TYPE_ENUM:
case TYPE_STRUCT:
case TYPE_COCLASS:
case TYPE_MODULE:
case TYPE_UNION:
case TYPE_ENCAPSULATED_UNION:
return VT_USERDEFINED;
case 0:
case TYPE_VOID:
return VT_VOID;
default:
error("get_type_vt: unknown type: 0x%02x\n", t->type);
case TYPE_ALIAS:
/* aliases should be filtered out by the type_get_type call above */
assert(0);
break;
case TYPE_FUNCTION:
error("get_type_vt: functions not supported\n");
break;
}
return 0;
}

View file

@ -22,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "widl.h"
#include "utils.h"
@ -40,18 +41,42 @@ type_t *duptype(type_t *t, int dupname)
return d;
}
type_t *make_type(enum type_type type)
{
type_t *t = alloc_type();
t->name = NULL;
t->type_type = type;
t->attrs = NULL;
t->orig = NULL;
memset(&t->details, 0, sizeof(t->details));
t->typestring_offset = 0;
t->ptrdesc = 0;
t->ignore = (parse_only != 0);
t->defined = FALSE;
t->written = FALSE;
t->user_types_registered = FALSE;
t->tfswrite = FALSE;
t->checked = FALSE;
t->is_alias = FALSE;
t->typelib_idx = -1;
init_loc_info(&t->loc_info);
return t;
}
type_t *type_new_function(var_list_t *args)
{
type_t *t = make_type(RPC_FC_FUNCTION, NULL);
type_t *t = make_type(TYPE_FUNCTION);
t->details.function = xmalloc(sizeof(*t->details.function));
t->details.function->args = args;
t->details.function->idx = -1;
return t;
}
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs)
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
{
type_t *t = make_type(pointer_default, ref);
type_t *t = make_type(TYPE_POINTER);
t->details.pointer.def_fc = pointer_default;
t->details.pointer.ref = ref;
t->attrs = attrs;
return t;
}
@ -62,9 +87,10 @@ type_t *type_new_alias(type_t *t, const char *name)
a->name = xstrdup(name);
a->attrs = NULL;
a->declarray = FALSE;
a->orig = t;
a->is_alias = TRUE;
/* for pointer types */
a->details = t->details;
init_loc_info(&a->loc_info);
return a;
@ -72,23 +98,153 @@ type_t *type_new_alias(type_t *t, const char *name)
type_t *type_new_module(char *name)
{
type_t *type = make_type(RPC_FC_MODULE, NULL);
type_t *type = get_type(TYPE_MODULE, name, 0);
if (type->type_type != TYPE_MODULE || type->defined)
error_loc("%s: redefinition error; original definition was at %s:%d\n",
type->name, type->loc_info.input_name, type->loc_info.line_number);
type->name = name;
/* FIXME: register type to detect multiple definitions */
return type;
}
type_t *type_new_array(const char *name, type_t *element, int declarray,
unsigned long dim, expr_t *size_is, expr_t *length_is)
type_t *type_new_coclass(char *name)
{
type_t *t = make_type(RPC_FC_LGFARRAY, element);
type_t *type = get_type(TYPE_COCLASS, name, 0);
if (type->type_type != TYPE_COCLASS || type->defined)
error_loc("%s: redefinition error; original definition was at %s:%d\n",
type->name, type->loc_info.input_name, type->loc_info.line_number);
type->name = name;
return type;
}
type_t *type_new_array(const char *name, type_t *element, int declptr,
unsigned int dim, expr_t *size_is, expr_t *length_is,
unsigned char ptr_default_fc)
{
type_t *t = make_type(TYPE_ARRAY);
if (name) t->name = xstrdup(name);
t->declarray = declarray;
t->details.array.declptr = declptr;
t->details.array.length_is = length_is;
if (size_is)
t->details.array.size_is = size_is;
else
t->details.array.dim = dim;
t->details.array.elem = element;
t->details.array.ptr_def_fc = ptr_default_fc;
return t;
}
type_t *type_new_basic(enum type_basic_type basic_type)
{
type_t *t = make_type(TYPE_BASIC);
t->details.basic.type = basic_type;
t->details.basic.sign = 0;
return t;
}
type_t *type_new_int(enum type_basic_type basic_type, int sign)
{
static type_t *int_types[TYPE_BASIC_INT_MAX+1][3];
assert(basic_type <= TYPE_BASIC_INT_MAX);
/* map sign { -1, 0, 1 } -> { 0, 1, 2 } */
if (!int_types[basic_type][sign + 1])
{
int_types[basic_type][sign + 1] = type_new_basic(basic_type);
int_types[basic_type][sign + 1]->details.basic.sign = sign;
}
return int_types[basic_type][sign + 1];
}
type_t *type_new_void(void)
{
static type_t *void_type = NULL;
if (!void_type)
void_type = make_type(TYPE_VOID);
return void_type;
}
type_t *type_new_enum(const char *name, int defined, var_list_t *enums)
{
type_t *tag_type = name ? find_type(name, tsENUM) : NULL;
type_t *t = make_type(TYPE_ENUM);
t->name = name;
if (tag_type && tag_type->details.enumeration)
t->details.enumeration = tag_type->details.enumeration;
else if (defined)
{
t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
t->details.enumeration->enums = enums;
t->defined = TRUE;
}
if (name)
{
if (defined)
reg_type(t, name, tsENUM);
else
add_incomplete(t);
}
return t;
}
type_t *type_new_struct(char *name, int defined, var_list_t *fields)
{
type_t *tag_type = name ? find_type(name, tsSTRUCT) : NULL;
type_t *t = make_type(TYPE_STRUCT);
t->name = name;
if (tag_type && tag_type->details.structure)
t->details.structure = tag_type->details.structure;
else if (defined)
{
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
}
if (name)
{
if (defined)
reg_type(t, name, tsSTRUCT);
else
add_incomplete(t);
}
return t;
}
type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
{
type_t *tag_type = name ? find_type(name, tsUNION) : NULL;
type_t *t = make_type(TYPE_UNION);
t->name = name;
if (tag_type && tag_type->details.structure)
t->details.structure = tag_type->details.structure;
else if (defined)
{
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
}
if (name)
{
if (defined)
reg_type(t, name, tsUNION);
else
add_incomplete(t);
}
return t;
}
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases)
{
type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, tsUNION);
if (!union_field) union_field = make_var( xstrdup("tagged_union") );
union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases);
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = append_var( NULL, switch_field );
t->details.structure->fields = append_var( t->details.structure->fields, union_field );
t->defined = TRUE;
return t;
}
@ -117,23 +273,23 @@ static int compute_method_indexes(type_t *iface)
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
{
iface->ref = inherit;
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->details.iface->disp_props = NULL;
iface->details.iface->disp_methods = NULL;
iface->details.iface->stmts = stmts;
iface->details.iface->inherit = inherit;
iface->defined = TRUE;
compute_method_indexes(iface);
}
void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods)
{
iface->ref = find_type("IDispatch", 0);
if (!iface->ref) error_loc("IDispatch is undefined\n");
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->details.iface->disp_props = props;
iface->details.iface->disp_methods = methods;
iface->details.iface->stmts = NULL;
iface->details.iface->inherit = find_type("IDispatch", 0);
if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n");
iface->defined = TRUE;
compute_method_indexes(iface);
}
@ -158,3 +314,18 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
coclass->defined = TRUE;
return coclass;
}
int type_is_equal(const type_t *type1, const type_t *type2)
{
if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
return FALSE;
if (type1->name && type2->name)
return !strcmp(type1->name, type2->name);
else if ((!type1->name && type2->name) || (type1->name && !type2->name))
return FALSE;
/* FIXME: do deep inspection of types to determine if they are equal */
return FALSE;
}

View file

@ -25,16 +25,26 @@
#define WIDL_TYPE_TREE_H
type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs);
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
type_t *type_new_alias(type_t *t, const char *name);
type_t *type_new_module(char *name);
type_t *type_new_array(const char *name, type_t *element, int declarray,
unsigned long dim, expr_t *size_is, expr_t *length_is);
type_t *type_new_array(const char *name, type_t *element, int declptr,
unsigned int dim, expr_t *size_is, expr_t *length_is,
unsigned char ptr_default_fc);
type_t *type_new_basic(enum type_basic_type basic_type);
type_t *type_new_int(enum type_basic_type basic_type, int sign);
type_t *type_new_void(void);
type_t *type_new_coclass(char *name);
type_t *type_new_enum(const char *name, int defined, var_list_t *enums);
type_t *type_new_struct(char *name, int defined, var_list_t *fields);
type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields);
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
int type_is_equal(const type_t *type1, const type_t *type2);
/* FIXME: shouldn't need to export this */
type_t *duptype(type_t *t, int dupname);
@ -53,11 +63,18 @@ static inline enum type_type type_get_type(const type_t *type)
return type_get_type_detect_alias(type_get_real_type(type));
}
static inline unsigned char type_basic_get_fc(const type_t *type)
static inline enum type_basic_type type_basic_get_type(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_BASIC);
return type->type;
return type->details.basic.type;
}
static inline int type_basic_get_sign(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_BASIC);
return type->details.basic.sign;
}
static inline var_list_t *type_struct_get_fields(const type_t *type)
@ -78,7 +95,7 @@ static inline type_t *type_function_get_rettype(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_FUNCTION);
return type->ref;
return type->details.function->rettype;
}
static inline var_list_t *type_enum_get_values(const type_t *type)
@ -130,7 +147,7 @@ static inline type_t *type_iface_get_inherit(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_INTERFACE);
return type->ref;
return type->details.iface->inherit;
}
static inline var_list_t *type_dispiface_get_props(const type_t *type)
@ -192,7 +209,7 @@ static inline int type_array_has_variance(const type_t *type)
return (type->details.array.length_is != NULL);
}
static inline unsigned long type_array_get_dim(const type_t *type)
static inline unsigned int type_array_get_dim(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_ARRAY);
@ -217,7 +234,21 @@ static inline type_t *type_array_get_element(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_ARRAY);
return type->ref;
return type->details.array.elem;
}
static inline int type_array_is_decl_as_ptr(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_ARRAY);
return type->details.array.declptr;
}
static inline unsigned char type_array_get_ptr_default_fc(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_ARRAY);
return type->details.array.ptr_def_fc;
}
static inline int type_is_alias(const type_t *type)
@ -242,7 +273,14 @@ static inline type_t *type_pointer_get_ref(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_POINTER);
return type->ref;
return type->details.pointer.ref;
}
static inline unsigned char type_pointer_get_default_fc(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_POINTER);
return type->details.pointer.def_fc;
}
#endif /* WIDL_TYPE_TREE_H */

View file

@ -53,33 +53,35 @@
static const char usage[] =
"Usage: widl [options...] infile.idl\n"
" or: widl [options...] --dlldata-only name1 [name2...]\n"
" -c Generate client stub\n"
" -C file Name of client stub file (default is infile_c.c)\n"
" -d n Set debug level to 'n'\n"
" -D id[=val] Define preprocessor identifier id=val\n"
" --dlldata=file Name of the dlldata file (default is dlldata.c)\n"
" -E Preprocess only\n"
" -h Generate headers\n"
" -H file Name of header file (default is infile.h)\n"
" -I path Set include search dir to path (multiple -I allowed)\n"
" --local-stubs=file Write empty stubs for call_as/local methods to file\n"
" -N Do not preprocess input\n"
" --oldnames Use old naming conventions\n"
" -p Generate proxy\n"
" -P file Name of proxy file (default is infile_p.c)\n"
" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n"
" -b arch Set the target architecture\n"
" -c Generate client stub\n"
" -C file Name of client stub file (default is infile_c.c)\n"
" -d n Set debug level to 'n'\n"
" -D id[=val] Define preprocessor identifier id=val\n"
" --dlldata=file Name of the dlldata file (default is dlldata.c)\n"
" -E Preprocess only\n"
" -h Generate headers\n"
" -H file Name of header file (default is infile.h)\n"
" -I path Set include search dir to path (multiple -I allowed)\n"
" --local-stubs=file Write empty stubs for call_as/local methods to file\n"
" -m32, -m64 Set the kind of typelib to build (Win32 or Win64)\n"
" -N Do not preprocess input\n"
" --oldnames Use old naming conventions\n"
" -p Generate proxy\n"
" -P file Name of proxy file (default is infile_p.c)\n"
" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n"
" --prefix-client=p Prefix names of client stubs with 'p'\n"
" --prefix-server=p Prefix names of server functions with 'p'\n"
" -s Generate server stub\n"
" -S file Name of server stub file (default is infile_s.c)\n"
" -t Generate typelib\n"
" -T file Name of typelib file (default is infile.tlb)\n"
" -u Generate interface identifiers file\n"
" -U file Name of interface identifiers file (default is infile_i.c)\n"
" -V Print version and exit\n"
" -W Enable pedantic warnings\n"
" --win32 Only generate 32-bit code\n"
" --win64 Only generate 64-bit code\n"
" -s Generate server stub\n"
" -S file Name of server stub file (default is infile_s.c)\n"
" -t Generate typelib\n"
" -T file Name of typelib file (default is infile.tlb)\n"
" -u Generate interface identifiers file\n"
" -U file Name of interface identifiers file (default is infile_i.c)\n"
" -V Print version and exit\n"
" -W Enable pedantic warnings\n"
" --win32 Only generate 32-bit code\n"
" --win64 Only generate 64-bit code\n"
"Debug level 'n' is a bitmask with following meaning:\n"
" * 0x01 Tell which resource is parsed (verbose mode)\n"
" * 0x02 Dump internal structures\n"
@ -92,7 +94,6 @@ static const char usage[] =
static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
"Copyright 2002 Ove Kaaven\n";
int win32 = 1;
int debuglevel = DEBUGLEVEL_NONE;
int parser_debug, yy_flex_debug;
@ -135,6 +136,7 @@ FILE *header;
FILE *idfile;
size_t pointer_size = 0;
syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
time_t now;
@ -151,7 +153,7 @@ enum {
};
static const char short_options[] =
"cC:d:D:EhH:I:NpP:sS:tT:uU:VW";
"b:cC:d:D:EhH:I:m:NpP:sS:tT:uU:VW";
static const struct option long_options[] = {
{ "dlldata", 1, 0, DLLDATA_OPTION },
{ "dlldata-only", 0, 0, DLLDATA_ONLY_OPTION },
@ -196,6 +198,75 @@ static char *dup_basename_token(const char *name, const char *ext)
return ret;
}
static void add_widl_version_define(void)
{
unsigned int version;
const char *p = PACKAGE_VERSION;
/* major */
version = atoi(p) * 0x10000;
p = strchr(p, '.');
/* minor */
if (p)
{
version += atoi(p + 1) * 0x100;
p = strchr(p + 1, '.');
}
/* build */
if (p)
version += atoi(p + 1);
if (version != 0)
{
char version_str[11];
snprintf(version_str, sizeof(version_str), "0x%x", version);
wpp_add_define("__WIDL__", version_str);
}
else
wpp_add_define("__WIDL__", NULL);
}
/* set the target platform */
static void set_target( const char *target )
{
static const struct
{
const char *name;
syskind_t kind;
} cpu_names[] =
{
{ "i386", SYS_WIN32 },
{ "i486", SYS_WIN32 },
{ "i586", SYS_WIN32 },
{ "i686", SYS_WIN32 },
{ "i786", SYS_WIN32 },
{ "x86_64", SYS_WIN64 },
{ "sparc", SYS_WIN32 },
{ "alpha", SYS_WIN32 },
{ "powerpc", SYS_WIN32 }
};
unsigned int i;
char *p, *spec = xstrdup( target );
/* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */
if (!(p = strchr( spec, '-' ))) error( "Invalid target specification '%s'\n", target );
*p++ = 0;
for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++)
{
if (!strcmp( cpu_names[i].name, spec ))
{
typelib_kind = cpu_names[i].kind;
free( spec );
return;
}
}
error( "Unrecognized CPU '%s'\n", spec );
}
/* clean things up when aborting on a signal */
static void exit_on_signal( int sig )
{
@ -349,7 +420,7 @@ static void write_id_data_stmts(const statement_list_t *stmts)
if (stmt->type == STMT_TYPE)
{
const type_t *type = stmt->u.type;
if (type->type == RPC_FC_IP)
if (type_get_type(type) == TYPE_INTERFACE)
{
const UUID *uuid;
if (!is_object(type->attrs) && !is_attr(type->attrs, ATTR_DISPINTERFACE))
@ -358,7 +429,7 @@ static void write_id_data_stmts(const statement_list_t *stmts)
write_guid(idfile, is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
type->name, uuid);
}
else if (type->type == RPC_FC_COCLASS)
else if (type_get_type(type) == TYPE_COCLASS)
{
const UUID *uuid = get_attrp(type->attrs, ATTR_UUID);
write_guid(idfile, "CLSID", type->name, uuid);
@ -450,6 +521,9 @@ int main(int argc,char *argv[])
do_win32 = 0;
do_win64 = 1;
break;
case 'b':
set_target( optarg );
break;
case 'c':
do_everything = 0;
do_client = 1;
@ -477,6 +551,11 @@ int main(int argc,char *argv[])
case 'I':
wpp_add_include_path(optarg);
break;
case 'm':
if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32;
else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64;
else error( "Invalid -m argument '%s'\n", optarg );
break;
case 'N':
no_preprocess = 1;
break;
@ -596,7 +675,7 @@ int main(int argc,char *argv[])
if (do_client) client_token = dup_basename_token(client_name,"_c.c");
if (do_server) server_token = dup_basename_token(server_name,"_s.c");
wpp_add_cmdline_define("__WIDL__");
add_widl_version_define();
atexit(rm_tempfile);
if (!no_preprocess)

View file

@ -34,7 +34,6 @@ extern int debuglevel;
#define DEBUGLEVEL_PPLEX 0x0010
#define DEBUGLEVEL_PPTRACE 0x0020
extern int win32;
extern int pedantic;
extern int do_everything;
extern int do_header;

View file

@ -230,6 +230,27 @@ enum statement_type
STMT_CPPQUOTE
};
enum type_basic_type
{
TYPE_BASIC_INT8 = 1,
TYPE_BASIC_INT16,
TYPE_BASIC_INT32,
TYPE_BASIC_INT64,
TYPE_BASIC_INT,
TYPE_BASIC_CHAR,
TYPE_BASIC_HYPER,
TYPE_BASIC_BYTE,
TYPE_BASIC_WCHAR,
TYPE_BASIC_FLOAT,
TYPE_BASIC_DOUBLE,
TYPE_BASIC_ERROR_STATUS_T,
TYPE_BASIC_HANDLE,
};
#define TYPE_BASIC_MAX TYPE_BASIC_HANDLE
#define TYPE_BASIC_INT_MIN TYPE_BASIC_INT8
#define TYPE_BASIC_INT_MAX TYPE_BASIC_HYPER
struct _loc_info_t
{
const char *input_name;
@ -283,6 +304,7 @@ struct enumeration_details
struct func_details
{
var_list_t *args;
struct _type_t *rettype;
int idx;
};
@ -291,6 +313,7 @@ struct iface_details
statement_list_t *stmts;
func_list_t *disp_methods;
var_list_t *disp_props;
struct _type_t *inherit;
};
struct module_details
@ -301,8 +324,12 @@ struct module_details
struct array_details
{
unsigned long dim;
expr_t *size_is, *length_is;
expr_t *size_is;
expr_t *length_is;
struct _type_t *elem;
unsigned int dim;
unsigned char ptr_def_fc;
unsigned char declptr; /* if declared as a pointer */
};
struct coclass_details
@ -310,6 +337,18 @@ struct coclass_details
ifref_list_t *ifaces;
};
struct basic_details
{
enum type_basic_type type;
int sign;
};
struct pointer_details
{
struct _type_t *ref;
unsigned char def_fc;
};
enum type_type
{
TYPE_VOID,
@ -329,8 +368,7 @@ enum type_type
struct _type_t {
const char *name;
unsigned char type;
struct _type_t *ref;
enum type_type type_type;
attr_list_t *attrs;
union
{
@ -341,13 +379,14 @@ struct _type_t {
struct module_details *module;
struct array_details array;
struct coclass_details coclass;
struct basic_details basic;
struct pointer_details pointer;
} details;
type_t *orig; /* dup'd types */
unsigned int typestring_offset;
unsigned int ptrdesc; /* used for complex structs */
int typelib_idx;
loc_info_t loc_info;
unsigned int declarray : 1; /* if declared as an array */
unsigned int ignore : 1;
unsigned int defined : 1;
unsigned int written : 1;
@ -355,7 +394,6 @@ struct _type_t {
unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */
unsigned int checked : 1;
unsigned int is_alias : 1; /* is the type an alias? */
int sign : 2;
};
struct _var_t {
@ -458,8 +496,14 @@ struct _statement_t {
} u;
};
extern unsigned char pointer_default;
typedef enum {
SYS_WIN16,
SYS_WIN32,
SYS_MAC,
SYS_WIN64
} syskind_t;
extern syskind_t typelib_kind;
extern user_type_list_t user_type_list;
void check_for_additional_prototype_types(const var_list_t *list);
@ -475,9 +519,19 @@ int cant_be_null(const var_t *v);
int is_struct(unsigned char tc);
int is_union(unsigned char tc);
#define tsENUM 1
#define tsSTRUCT 2
#define tsUNION 3
var_t *find_const(const char *name, int f);
type_t *find_type(const char *name, int t);
type_t *make_type(unsigned char type, type_t *ref);
type_t *make_type(enum type_type type);
type_t *get_type(enum type_type type, char *name, int t);
type_t *reg_type(type_t *type, const char *name, int t);
void add_incomplete(type_t *t);
var_t *make_var(char *name);
var_list_t *append_var(var_list_t *list, var_t *var);
void init_loc_info(loc_info_t *);
@ -490,65 +544,7 @@ static inline enum type_type type_get_type_detect_alias(const type_t *type)
{
if (type->is_alias)
return TYPE_ALIAS;
switch (type->type)
{
case 0:
return TYPE_VOID;
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_USMALL:
case RPC_FC_SMALL:
case RPC_FC_WCHAR:
case RPC_FC_USHORT:
case RPC_FC_SHORT:
case RPC_FC_ULONG:
case RPC_FC_LONG:
case RPC_FC_HYPER:
case RPC_FC_IGNORE:
case RPC_FC_FLOAT:
case RPC_FC_DOUBLE:
case RPC_FC_ERROR_STATUS_T:
case RPC_FC_BIND_PRIMITIVE:
return TYPE_BASIC;
case RPC_FC_ENUM16:
case RPC_FC_ENUM32:
return TYPE_ENUM;
case RPC_FC_RP:
case RPC_FC_UP:
case RPC_FC_FP:
case RPC_FC_OP:
return TYPE_POINTER;
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_BOGUS_STRUCT:
return TYPE_STRUCT;
case RPC_FC_ENCAPSULATED_UNION:
return TYPE_ENCAPSULATED_UNION;
case RPC_FC_NON_ENCAPSULATED_UNION:
return TYPE_UNION;
case RPC_FC_SMFARRAY:
case RPC_FC_LGFARRAY:
case RPC_FC_SMVARRAY:
case RPC_FC_LGVARRAY:
case RPC_FC_CARRAY:
case RPC_FC_CVARRAY:
case RPC_FC_BOGUS_ARRAY:
return TYPE_ARRAY;
case RPC_FC_FUNCTION:
return TYPE_FUNCTION;
case RPC_FC_COCLASS:
return TYPE_COCLASS;
case RPC_FC_IP:
return TYPE_INTERFACE;
case RPC_FC_MODULE:
return TYPE_MODULE;
default:
assert(0);
return 0;
}
return type->type_type;
}
#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \

View file

@ -43,7 +43,7 @@
#include <host/typedefs.h>
#include <host/nls.h>
#include "widltypes.h"
#include "widl.h"
#include "typelib.h"
#include "typelib_struct.h"
#include "utils.h"
@ -929,18 +929,10 @@ static int encode_type(
case VT_SAFEARRAY:
{
int next_vt;
type_t *element_type = type_alias_get_aliasee(type_array_get_element(type));
int next_vt = get_type_vt(element_type);
/* skip over SAFEARRAY type straight to element type */
type = type->ref;
for(next_vt = 0; type->ref; type = type->ref) {
next_vt = get_type_vt(type->ref);
if (next_vt != 0)
break;
}
encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size);
encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)), &target_type, NULL, NULL, &child_size);
for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
@ -981,34 +973,27 @@ static int encode_type(
while (type->typelib_idx < 0 && type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
type = type_alias_get_aliasee(type);
chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type,
type->name, type->type, type->typelib_idx);
chat("encode_type: VT_USERDEFINED - type %p name = %s real type %d idx %d\n", type,
type->name, type_get_type(type), type->typelib_idx);
if(type->typelib_idx == -1) {
chat("encode_type: trying to ref not added type\n");
switch(type->type) {
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_BOGUS_STRUCT:
switch (type_get_type(type)) {
case TYPE_STRUCT:
add_structure_typeinfo(typelib, type);
break;
case RPC_FC_IP:
case TYPE_INTERFACE:
add_interface_typeinfo(typelib, type);
break;
case RPC_FC_ENUM16:
case TYPE_ENUM:
add_enum_typeinfo(typelib, type);
break;
case RPC_FC_COCLASS:
case TYPE_COCLASS:
add_coclass_typeinfo(typelib, type);
break;
case 0:
error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n");
break;
default:
error("encode_type: VT_USERDEFINED - unhandled type %d\n", type->type);
error("encode_type: VT_USERDEFINED - unhandled type %d\n",
type_get_type(type));
}
}
@ -1045,8 +1030,7 @@ static int encode_type(
static void dump_type(type_t *t)
{
chat("dump_type: %p name %s type %d ref %p attrs %p\n", t, t->name, t->type, t->ref, t->attrs);
if(t->ref) dump_type(t->ref);
chat("dump_type: %p name %s type %d attrs %p\n", t, t->name, type_get_type(t), t->attrs);
}
static int encode_var(
@ -1070,29 +1054,33 @@ static int encode_var(
if (!decoded_size) decoded_size = &scratch;
*decoded_size = 0;
chat("encode_var: var %p type %p type->name %s type->ref %p\n",
var, type, type->name ? type->name : "NULL", type->ref);
chat("encode_var: var %p type %p type->name %s\n",
var, type, type->name ? type->name : "NULL");
if (type->declarray) {
if (is_array(type) && !type_array_is_decl_as_ptr(type)) {
int num_dims, elements = 1, arrayoffset;
type_t *atype;
int *arraydata;
num_dims = 0;
for (atype = type; atype->declarray; atype = type_array_get_element(atype))
for (atype = type;
is_array(atype) && !type_array_is_decl_as_ptr(atype);
atype = type_array_get_element(atype))
++num_dims;
chat("array with %d dimensions\n", num_dims);
encode_var(typelib, atype, var, &target_type, width, alignment, NULL);
arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0);
arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
arraydata[0] = target_type;
arraydata[1] = num_dims;
arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16);
arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
arraydata += 2;
for (atype = type; atype->declarray; atype = type_array_get_element(atype))
for (atype = type;
is_array(atype) && !type_array_is_decl_as_ptr(atype);
atype = type_array_get_element(atype))
{
arraydata[0] = type_array_get_dim(atype);
arraydata[1] = 0;
@ -1480,7 +1468,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
{
int vt;
expr_t *expr = (expr_t *)attr->u.pval;
if (arg->type->type == RPC_FC_ENUM16)
if (type_get_type(arg->type) == TYPE_ENUM)
vt = VT_INT;
else
vt = get_type_vt(arg->type);
@ -1553,7 +1541,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
/* adjust size of VTBL */
if(funckind != 0x3 /* FUNC_STATIC */)
typeinfo->typeinfo->cbSizeVft += 4;
typeinfo->typeinfo->cbSizeVft += pointer_size;
/* Increment the number of function elements */
typeinfo->typeinfo->cElement += 1;
@ -2041,7 +2029,7 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
}
}
msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents;
msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4;
msft_typeinfo->typeinfo->cbSizeVft = num_funcs * pointer_size;
STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(interface) ) {
var_t *func = stmt_func->u.var;
@ -2209,42 +2197,25 @@ static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
static void add_type_typeinfo(msft_typelib_t *typelib, type_t *type)
{
switch (type->type) {
case RPC_FC_IP:
switch (type_get_type(type)) {
case TYPE_INTERFACE:
add_interface_typeinfo(typelib, type);
break;
case RPC_FC_STRUCT:
case TYPE_STRUCT:
add_structure_typeinfo(typelib, type);
break;
case RPC_FC_ENUM16:
case RPC_FC_ENUM32:
case TYPE_ENUM:
add_enum_typeinfo(typelib, type);
break;
case RPC_FC_COCLASS:
case TYPE_COCLASS:
add_coclass_typeinfo(typelib, type);
break;
case RPC_FC_BYTE:
case RPC_FC_CHAR:
case RPC_FC_USMALL:
case RPC_FC_SMALL:
case RPC_FC_WCHAR:
case RPC_FC_USHORT:
case RPC_FC_SHORT:
case RPC_FC_ULONG:
case RPC_FC_LONG:
case RPC_FC_HYPER:
case RPC_FC_IGNORE:
case RPC_FC_FLOAT:
case RPC_FC_DOUBLE:
case RPC_FC_ERROR_STATUS_T:
case RPC_FC_BIND_PRIMITIVE:
case RPC_FC_RP:
case RPC_FC_UP:
case RPC_FC_OP:
case RPC_FC_FP:
case TYPE_BASIC:
case TYPE_POINTER:
break;
default:
error("add_entry: unhandled type 0x%x for %s\n", type->type, type->name);
error("add_entry: unhandled type 0x%x for %s\n",
type_get_type(type), type->name);
break;
}
}
@ -2566,6 +2537,8 @@ int create_msft_typelib(typelib_t *typelib)
GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
msft = xmalloc(sizeof(*msft));
memset(msft, 0, sizeof(*msft));
msft->typelib = typelib;
@ -2573,7 +2546,7 @@ int create_msft_typelib(typelib_t *typelib)
ctl2_init_header(msft);
ctl2_init_segdir(msft);
msft->typelib_header.varflags |= SYS_WIN32;
msft->typelib_header.varflags |= typelib_kind;
/*
* The following two calls return an offset or -1 if out of memory. We