/src/libreoffice/bridges/source/cpp_uno/shared/vtables.cxx
Line | Count | Source |
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 <vtables.hxx> |
22 | | |
23 | | #include <sal/types.h> |
24 | | #include <typelib/typedescription.h> |
25 | | |
26 | | #include <algorithm> |
27 | | #include <cassert> |
28 | | |
29 | | namespace |
30 | | { |
31 | | |
32 | | /** |
33 | | * Calculates the number of vtables associated with an interface type. |
34 | | * |
35 | | * <p>Multiple-inheritance C++ classes have more than one vtable.</p> |
36 | | * |
37 | | * @param type a non-null pointer to an interface type description |
38 | | * @return the number of vtables associated with the given interface type |
39 | | */ |
40 | 0 | sal_Int32 getVtableCount(typelib_InterfaceTypeDescription const * type) { |
41 | 0 | sal_Int32 n = 0; |
42 | 0 | for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) { |
43 | 0 | n += getVtableCount(type->ppBaseTypes[i]); |
44 | 0 | } |
45 | 0 | return std::max< sal_Int32 >(n, 1); |
46 | 0 | } |
47 | | |
48 | | /** |
49 | | * Maps a local member index to a local function index. |
50 | | * |
51 | | * <p><em>Local</em> members/functions are those not inherited from any base |
52 | | * types. The number of <em>functions</em> is potentially larger than the |
53 | | * number of <em>members</em>, as each read–write attribute member counts |
54 | | * as two functions.</p> |
55 | | * |
56 | | * @param type a non-null pointer to an interface type description |
57 | | * @param localMember a local member index, relative to the given interface type |
58 | | * @return the local function index corresponding to the given local member |
59 | | * index, relative to the given interface type |
60 | | */ |
61 | | sal_Int32 mapLocalMemberToLocalFunction( |
62 | | typelib_InterfaceTypeDescription * type, sal_Int32 localMember) |
63 | 94.4k | { |
64 | 94.4k | typelib_typedescription_complete( |
65 | 94.4k | reinterpret_cast< typelib_TypeDescription ** >(&type)); |
66 | 94.4k | sal_Int32 localMemberOffset = type->nAllMembers - type->nMembers; |
67 | 94.4k | sal_Int32 localFunctionOffset = type->nMapFunctionIndexToMemberIndex |
68 | 94.4k | - bridges::cpp_uno::shared::getLocalFunctions(type); |
69 | 94.4k | return type->pMapMemberIndexToFunctionIndex[localMemberOffset + localMember] |
70 | 94.4k | - localFunctionOffset; |
71 | 94.4k | } |
72 | | |
73 | | // Since on Solaris we compile with --instances=static, getVtableSlot cannot be |
74 | | // a template function, with explicit instantiates for |
75 | | // T = typelib_InterfaceAttributeTypeDescription and |
76 | | // T = typelib_InterfaceMethodTypeDescription in this file; hence, there are two |
77 | | // overloaded versions of getVtableSlot that both delegate to this template |
78 | | // function: |
79 | | template< typename T > bridges::cpp_uno::shared::VtableSlot doGetVtableSlot( |
80 | | T const * ifcMember) |
81 | 94.4k | { |
82 | 94.4k | bridges::cpp_uno::shared::VtableSlot slot; |
83 | 94.4k | slot.offset = 0; |
84 | 94.4k | T * member = const_cast< T * >(ifcMember); |
85 | 94.4k | while (member->pBaseRef != nullptr) { |
86 | 0 | assert(member->nIndex < member->pInterface->nBaseTypes); |
87 | 0 | for (sal_Int32 i = 0; i < member->nIndex; ++i) { |
88 | 0 | slot.offset += getVtableCount(member->pInterface->ppBaseTypes[i]); |
89 | 0 | } |
90 | 0 | typelib_TypeDescription * desc = nullptr; |
91 | 0 | typelib_typedescriptionreference_getDescription( |
92 | 0 | &desc, member->pBaseRef); |
93 | 0 | assert( |
94 | 0 | desc != nullptr && desc->eTypeClass == member->aBase.aBase.eTypeClass); |
95 | 0 | if (member != ifcMember) { |
96 | 0 | typelib_typedescription_release(&member->aBase.aBase); |
97 | 0 | } |
98 | 0 | member = reinterpret_cast< T * >(desc); |
99 | 0 | } |
100 | 94.4k | slot.index |
101 | 94.4k | = bridges::cpp_uno::shared::getPrimaryFunctions( |
102 | 94.4k | member->pInterface->pBaseTypeDescription) |
103 | 94.4k | + mapLocalMemberToLocalFunction(member->pInterface, member->nIndex); |
104 | 94.4k | if (member != ifcMember) { |
105 | 0 | typelib_typedescription_release(&member->aBase.aBase); |
106 | 0 | } |
107 | 94.4k | return slot; |
108 | 94.4k | } Unexecuted instantiation: vtables.cxx:bridges::cpp_uno::shared::VtableSlot (anonymous namespace)::doGetVtableSlot<_typelib_InterfaceAttributeTypeDescription>(_typelib_InterfaceAttributeTypeDescription const*) vtables.cxx:bridges::cpp_uno::shared::VtableSlot (anonymous namespace)::doGetVtableSlot<_typelib_InterfaceMethodTypeDescription>(_typelib_InterfaceMethodTypeDescription const*) Line | Count | Source | 81 | 94.4k | { | 82 | 94.4k | bridges::cpp_uno::shared::VtableSlot slot; | 83 | 94.4k | slot.offset = 0; | 84 | 94.4k | T * member = const_cast< T * >(ifcMember); | 85 | 94.4k | while (member->pBaseRef != nullptr) { | 86 | 0 | assert(member->nIndex < member->pInterface->nBaseTypes); | 87 | 0 | for (sal_Int32 i = 0; i < member->nIndex; ++i) { | 88 | 0 | slot.offset += getVtableCount(member->pInterface->ppBaseTypes[i]); | 89 | 0 | } | 90 | 0 | typelib_TypeDescription * desc = nullptr; | 91 | 0 | typelib_typedescriptionreference_getDescription( | 92 | 0 | &desc, member->pBaseRef); | 93 | 0 | assert( | 94 | 0 | desc != nullptr && desc->eTypeClass == member->aBase.aBase.eTypeClass); | 95 | 0 | if (member != ifcMember) { | 96 | 0 | typelib_typedescription_release(&member->aBase.aBase); | 97 | 0 | } | 98 | 0 | member = reinterpret_cast< T * >(desc); | 99 | 0 | } | 100 | 94.4k | slot.index | 101 | 94.4k | = bridges::cpp_uno::shared::getPrimaryFunctions( | 102 | 94.4k | member->pInterface->pBaseTypeDescription) | 103 | 94.4k | + mapLocalMemberToLocalFunction(member->pInterface, member->nIndex); | 104 | 94.4k | if (member != ifcMember) { | 105 | 0 | typelib_typedescription_release(&member->aBase.aBase); | 106 | 0 | } | 107 | 94.4k | return slot; | 108 | 94.4k | } |
|
109 | | |
110 | | } |
111 | | |
112 | | namespace bridges::cpp_uno::shared { |
113 | | |
114 | 188k | sal_Int32 getLocalFunctions(typelib_InterfaceTypeDescription const * type) { |
115 | 188k | return type->nMembers == 0 |
116 | 188k | ? 0 |
117 | 188k | : (type->nMapFunctionIndexToMemberIndex |
118 | 188k | - type->pMapMemberIndexToFunctionIndex[ |
119 | 188k | type->nAllMembers - type->nMembers]); |
120 | 188k | } |
121 | | |
122 | 94.4k | sal_Int32 getPrimaryFunctions(typelib_InterfaceTypeDescription * type) { |
123 | 94.4k | sal_Int32 n = 0; |
124 | 188k | for (; type != nullptr; type = type->pBaseTypeDescription) { |
125 | 94.4k | typelib_typedescription_complete( |
126 | 94.4k | reinterpret_cast< typelib_TypeDescription ** >(&type)); |
127 | 94.4k | n += getLocalFunctions(type); |
128 | 94.4k | } |
129 | 94.4k | return n; |
130 | 94.4k | } |
131 | | |
132 | | VtableSlot getVtableSlot( |
133 | | typelib_InterfaceAttributeTypeDescription const * ifcMember) |
134 | 0 | { |
135 | 0 | return doGetVtableSlot(ifcMember); |
136 | 0 | } |
137 | | |
138 | | VtableSlot getVtableSlot( |
139 | | typelib_InterfaceMethodTypeDescription const * ifcMember) |
140 | 94.4k | { |
141 | 94.4k | return doGetVtableSlot(ifcMember); |
142 | 94.4k | } |
143 | | |
144 | | } |
145 | | |
146 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |