LibreOffice Module bridges (master) 1
gcc3_linux_x86-64/cpp2uno.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <typeinfo>
22
23#include <rtl/alloc.h>
24#include <sal/log.hxx>
25
26#include <com/sun/star/uno/genfunc.hxx>
27#include <com/sun/star/uno/RuntimeException.hpp>
28#include <config_options.h>
29#include <uno/data.h>
30#include <typelib/typedescription.hxx>
31
32#include <bridge.hxx>
33#include <cppinterfaceproxy.hxx>
34#include <types.hxx>
35#include <vtablefactory.hxx>
36
37#include "abi.hxx"
38#include "call.hxx"
39#include "rtti.hxx"
40#include "share.hxx"
41
42using namespace ::com::sun::star::uno;
43
44// Perform the UNO call
45//
46// We must convert the parameters stored in gpreg, fpreg and ovrflw to UNO
47// arguments and call pThis->getUnoI()->pDispatcher.
48//
49// gpreg: [ret *], this, [gpr params]
50// fpreg: [fpr params]
51// ovrflw: [gpr or fpr params (properly aligned)]
52//
53// [ret *] is present when we are returning a structure bigger than 16 bytes
54// Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
55// Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
56//
57// The return value is the same as for cpp_vtable_call.
58static int cpp2uno_call(
60 const typelib_TypeDescription * pMemberTypeDescr,
61 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
62 sal_Int32 nParams, typelib_MethodParameter * pParams,
63 void ** gpreg, void ** fpreg, void ** ovrflw,
64 sal_uInt64 * pRegisterReturn /* space for register return */ )
65{
66 unsigned int nr_gpr = 0; //number of gpr registers used
67 unsigned int nr_fpr = 0; //number of fpr registers used
68
69 // return
70 typelib_TypeDescription * pReturnTypeDescr = nullptr;
71 if (pReturnTypeRef)
72 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
73 x86_64::ReturnKind returnKind
74 = (pReturnTypeRef == nullptr || pReturnTypeRef->eTypeClass == typelib_TypeClass_VOID)
76
77 void * pUnoReturn = nullptr;
78 void * pCppReturn = nullptr; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
79
80 if ( pReturnTypeDescr )
81 {
82 if ( returnKind == x86_64::ReturnKind::Memory )
83 {
84 pCppReturn = *gpreg++;
85 nr_gpr++;
86
87 pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
88 ? alloca( pReturnTypeDescr->nSize )
89 : pCppReturn ); // direct way
90 }
91 else
92 pUnoReturn = pRegisterReturn; // direct way for simple types
93 }
94
95 // pop this
96 gpreg++;
97 nr_gpr++;
98
99 // stack space
100 // parameters
101 void ** pUnoArgs = static_cast<void **>(alloca( 4 * sizeof(void *) * nParams ));
102 void ** pCppArgs = pUnoArgs + nParams;
103 // indices of values this have to be converted (interface conversion cpp<=>uno)
104 sal_Int32 * pTempIndices = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 * nParams));
105 // type descriptions for reconversions
106 typelib_TypeDescription ** ppTempParamTypeDescr = reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams));
107
108 sal_Int32 nTempIndices = 0;
109
110 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
111 {
112 const typelib_MethodParameter & rParam = pParams[nPos];
113
114 if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value
115 {
116 int nUsedGPR = 0;
117 int nUsedSSE = 0;
118 bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, nUsedGPR, nUsedSSE );
119
120 // Simple types must fit exactly one register on x86_64
121 assert( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) ); (void)bFitsRegisters;
122
123 if ( nUsedSSE == 1 )
124 {
125 if ( nr_fpr < x86_64::MAX_SSE_REGS )
126 {
127 pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
128 nr_fpr++;
129 }
130 else
131 pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
132 }
133 else if ( nUsedGPR == 1 )
134 {
135 if ( nr_gpr < x86_64::MAX_GPR_REGS )
136 {
137 pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
138 nr_gpr++;
139 }
140 else
141 pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
142 }
143 }
144 else // ref
145 {
146 typelib_TypeDescription * pParamTypeDescr = nullptr;
147 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
148
149 void *pCppStack;
150 if ( nr_gpr < x86_64::MAX_GPR_REGS )
151 {
152 pCppArgs[nPos] = pCppStack = *gpreg++;
153 nr_gpr++;
154 }
155 else
156 pCppArgs[nPos] = pCppStack = *ovrflw++;
157
158 if (! rParam.bIn) // is pure out
159 {
160 // uno out is unconstructed mem!
161 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
162 pTempIndices[nTempIndices] = nPos;
163 // will be released at reconversion
164 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
165 }
166 else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
167 {
168 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
169 uno_copyAndConvertData( pUnoArgs[nPos],
170 pCppStack, pParamTypeDescr,
171 pThis->getBridge()->getCpp2Uno() );
172 pTempIndices[nTempIndices] = nPos; // has to be reconverted
173 // will be released at reconversion
174 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
175 }
176 else // direct way
177 {
178 pUnoArgs[nPos] = pCppStack;
179 // no longer needed
180 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
181 }
182 }
183 }
184
185 // ExceptionHolder
186 uno_Any aUnoExc; // Any will be constructed by callee
187 uno_Any * pUnoExc = &aUnoExc;
188
189 // invoke uno dispatch call
190 (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
191
192 // in case an exception occurred...
193 if ( pUnoExc )
194 {
195 // destruct temporary in/inout params
196 for ( ; nTempIndices--; )
197 {
198 sal_Int32 nIndex = pTempIndices[nTempIndices];
199
200 if (pParams[nIndex].bIn) // is in/inout => was constructed
201 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], nullptr );
202 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
203 }
204 if (pReturnTypeDescr)
205 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
206
207 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
208 // is here for dummy
209 return 0;
210 }
211 else // else no exception occurred...
212 {
213 // temporary params
214 for ( ; nTempIndices--; )
215 {
216 sal_Int32 nIndex = pTempIndices[nTempIndices];
217 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
218
219 if ( pParams[nIndex].bOut ) // inout/out
220 {
221 // convert and assign
222 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
223 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
224 pThis->getBridge()->getUno2Cpp() );
225 }
226 // destroy temp uno param
227 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, nullptr );
228
229 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
230 }
231 // return
232 if ( pCppReturn ) // has complex return
233 {
234 if ( pUnoReturn != pCppReturn ) // needs reconversion
235 {
236 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
237 pThis->getBridge()->getUno2Cpp() );
238 // destroy temp uno return
239 uno_destructData( pUnoReturn, pReturnTypeDescr, nullptr );
240 }
241 // complex return ptr is set to return reg
242 *reinterpret_cast<void **>(pRegisterReturn) = pCppReturn;
243 }
244 if ( pReturnTypeDescr )
245 {
246 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
247 }
248 switch (returnKind) {
250 return 0;
252 return 1;
253 default:
254 return -1;
255 }
256 }
257}
258
259// Returns -1 for the general case where potential return values from privateSnippetExecutor can be
260// copied from pRegisterReturn to both %rax and %rdx (in that order) and to %xmm0 and %xmm1 (in that
261// order)---each specific return type will only require a subset of that copy operations, but the
262// other copies to those non--callee-saved registers will be redundant and harmless. Returns 0 for
263// the special case where return values from privateSnippetExecutor must be copied from
264// pRegisterReturn to %xmm0 and %rax (in that order). Returns 1 for the special case where return
265// privateSnippetExecutor must be copied from pRegisterReturn to %rax and %xmm0 (in that order).
267 sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
268 void ** gpreg, void ** fpreg, void ** ovrflw,
269 sal_uInt64 * pRegisterReturn /* space for register return */ )
270{
271 // gpreg: [ret *], this, [other gpr params]
272 // fpreg: [fpr params]
273 // ovrflw: [gpr or fpr params (properly aligned)]
274 void * pThis;
275 if ( nFunctionIndex & 0x80000000 )
276 {
277 nFunctionIndex &= 0x7fffffff;
278 pThis = gpreg[1];
279 }
280 else
281 {
282 pThis = gpreg[0];
283 }
284 pThis = static_cast<char *>( pThis ) - nVtableOffset;
285
288
289 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
290
291 if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
292 {
293 SAL_WARN(
294 "bridges",
295 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
296 << " vtable index " << nFunctionIndex << "/"
297 << pTypeDescr->nMapFunctionIndexToMemberIndex);
298 throw RuntimeException(
299 ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
300 + " vtable index " + OUString::number(nFunctionIndex) + "/"
301 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
302 reinterpret_cast<XInterface *>( pCppI ) );
303 }
304
305 // determine called method
306 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
307 assert(nMemberPos < pTypeDescr->nAllMembers);
308
309 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
310
311 int eRet;
312 switch ( aMemberDescr.get()->eTypeClass )
313 {
314 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
315 {
316 typelib_TypeDescriptionReference *pAttrTypeRef =
317 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
318
319 if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
320 {
321 // is GET method
322 eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
323 0, nullptr, // no params
324 gpreg, fpreg, ovrflw, pRegisterReturn );
325 }
326 else
327 {
328 // is SET method
329 typelib_MethodParameter aParam;
330 aParam.pTypeRef = pAttrTypeRef;
331 aParam.bIn = true;
332 aParam.bOut = false;
333
334 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
335 nullptr, // indicates void return
336 1, &aParam,
337 gpreg, fpreg, ovrflw, pRegisterReturn );
338 }
339 break;
340 }
341 case typelib_TypeClass_INTERFACE_METHOD:
342 {
343 // is METHOD
344 switch ( nFunctionIndex )
345 {
346 case 1: // acquire()
347 pCppI->acquireProxy(); // non virtual call!
348 eRet = 0;
349 break;
350 case 2: // release()
351 pCppI->releaseProxy(); // non virtual call!
352 eRet = 0;
353 break;
354 case 0: // queryInterface() opt
355 {
356 typelib_TypeDescription * pTD = nullptr;
357 TYPELIB_DANGER_GET( &pTD, static_cast<Type *>( gpreg[2] )->getTypeLibType() );
358 if ( pTD )
359 {
360 XInterface * pInterface = nullptr;
361 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
362 ( pCppI->getBridge()->getCppEnv(),
363 reinterpret_cast<void **>(&pInterface),
364 pCppI->getOid().pData,
365 reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
366
367 if ( pInterface )
368 {
369 ::uno_any_construct( static_cast<uno_Any *>( gpreg[0] ),
370 &pInterface, pTD, cpp_acquire );
371
372 pInterface->release();
373 TYPELIB_DANGER_RELEASE( pTD );
374
375 reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
376 eRet = 0;
377 break;
378 }
379 TYPELIB_DANGER_RELEASE( pTD );
380 }
381 [[fallthrough]]; // else perform queryInterface()
382 }
383 default:
384 {
385 typelib_InterfaceMethodTypeDescription *pMethodTD =
386 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
387
388 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
389 pMethodTD->pReturnTypeRef,
390 pMethodTD->nParams,
391 pMethodTD->pParams,
392 gpreg, fpreg, ovrflw, pRegisterReturn );
393 }
394 }
395 break;
396 }
397 default:
398 {
399 throw RuntimeException("no member description found!",
400 reinterpret_cast<XInterface *>( pCppI ) );
401 }
402 }
403
404 return eRet;
405}
406
407const int codeSnippetSize = 24;
408
409// Generate a trampoline that redirects method calls to
410// privateSnippetExecutor().
411//
412// privateSnippetExecutor() saves all the registers that are used for
413// parameter passing on x86_64, and calls the cpp_vtable_call().
414// When it returns, privateSnippetExecutor() sets the return value.
415//
416// Note: The code snippet we build here must not create a stack frame,
417// otherwise the UNO exceptions stop working thanks to non-existing
418// unwinding info.
419static unsigned char * codeSnippet( unsigned char * code,
420 sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
421 bool bHasHiddenParam )
422{
423 sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>(nVtableOffset) << 32 ) | static_cast<sal_uInt64>(nFunctionIndex);
424
425 if ( bHasHiddenParam )
426 nOffsetAndIndex |= 0x80000000;
427
428 // movq $<nOffsetAndIndex>, %r10
429 *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
430 *reinterpret_cast<sal_uInt16 *>( code + 2 ) = nOffsetAndIndex & 0xFFFF;
431 *reinterpret_cast<sal_uInt32 *>( code + 4 ) = nOffsetAndIndex >> 16;
432 *reinterpret_cast<sal_uInt16 *>( code + 8 ) = nOffsetAndIndex >> 48;
433
434 // movq $<address of the privateSnippetExecutor>, %r11
435 *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
436 *reinterpret_cast<sal_uInt32 *>( code + 12 )
437 = reinterpret_cast<sal_uInt64>(privateSnippetExecutor);
438 *reinterpret_cast<sal_uInt32 *>( code + 16 )
439 = reinterpret_cast<sal_uInt64>(privateSnippetExecutor) >> 32;
440
441 // jmpq *%r11
442 *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
443
444 return code + codeSnippetSize;
445}
446
448
451{
452 return static_cast< Slot * >(block) + 2;
453}
454
456 sal_Int32 slotCount)
457{
458 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
459}
460
461#if ENABLE_RUNTIME_OPTIMIZATIONS
462namespace {
463// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
464// on such proxy objects not crash:
465struct ProxyRtti {};
466}
467#endif
468
471 void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
472 typelib_InterfaceTypeDescription * type)
473{
474 Slot * slots = mapBlockToVtable(block);
475#if ENABLE_RUNTIME_OPTIMIZATIONS
476 slots[-2].fn = nullptr;
477 slots[-1].fn = &typeid(ProxyRtti);
478 (void)vtableNumber;
479 (void)type;
480#else
481 slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
482 slots[-1].fn = x86_64::getRtti(type->aBase);
483#endif
484 return slots + slotCount;
485}
486
487
489 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
490 typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
491 sal_Int32 functionCount, sal_Int32 nVtableOffset )
492{
493 (*slots) -= functionCount;
494 Slot * s = *slots;
495 for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
496 {
497 typelib_TypeDescription * pTD = nullptr;
498
499 TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
500 assert(pTD);
501
502 if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE )
503 {
504 typelib_InterfaceAttributeTypeDescription *pAttrTD =
505 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
506
507 // get method
508 (s++)->fn = code + writetoexecdiff;
509 code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
510 x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
511
512 if ( ! pAttrTD->bReadOnly )
513 {
514 // set method
515 (s++)->fn = code + writetoexecdiff;
516 code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
517 }
518 }
519 else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD )
520 {
521 typelib_InterfaceMethodTypeDescription *pMethodTD =
522 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
523
524 (s++)->fn = code + writetoexecdiff;
525 code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
526 x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
527 }
528 else
529 assert(false);
530
531 TYPELIB_DANGER_RELEASE( pTD );
532 }
533 return code;
534}
535
537 SAL_UNUSED_PARAMETER unsigned char const *,
538 SAL_UNUSED_PARAMETER unsigned char const * )
539{}
540
541/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
uno_Mapping * getUno2Cpp()
Definition: bridge.hxx:73
uno_ExtEnvironment * getCppEnv()
Definition: bridge.hxx:69
uno_Mapping * getCpp2Uno()
Definition: bridge.hxx:72
A cpp proxy wrapping a uno interface.
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
typelib_InterfaceTypeDescription * getTypeDescr()
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
static void flushCode(unsigned char const *begin, unsigned char const *end)
Flush all the generated code snippets of a vtable, on platforms that require it.
static unsigned char * addLocalFunctions(Slot **slots, unsigned char *code, sal_PtrDiff writetoexecdiff, typelib_InterfaceTypeDescription const *type, sal_Int32 functionOffset, sal_Int32 functionCount, sal_Int32 vtableOffset)
Fill the vtable slots corresponding to all local (i.e., not inherited) functions of a given interface...
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
void(* privateSnippetExecutor)()
const int codeSnippetSize
int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
static int cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy *pThis, const typelib_TypeDescription *pMemberTypeDescr, typelib_TypeDescriptionReference *pReturnTypeRef, sal_Int32 nParams, typelib_MethodParameter *pParams, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
sal_Int32 nIndex
sal_uInt16 nPos
#define SAL_WARN(area, stream)
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:53
struct _uno_Any uno_Any
Definition: msvc/except.hxx:32
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT,...
Definition: types.cxx:28
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type,...
Definition: types.cxx:41
Type
std::type_info * getRtti(typelib_TypeDescription const &type)
Definition: rtti.cxx:265
bool examine_argument(typelib_TypeDescriptionReference *pTypeRef, int &nUsedGPR, int &nUsedSSE) noexcept
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef) noexcept
Does function that returns this type use a hidden parameter, or registers?
const sal_uInt32 MAX_SSE_REGS
ReturnKind getReturnKind(typelib_TypeDescriptionReference *type) noexcept
const sal_uInt32 MAX_GPR_REGS
sal_Unicode code
ResultType type