[PATCH 3/5] dlls/dbghelp: let symt_basic be trans-module and nameless
Eric Pouech
wine at gitlab.winehq.org
Tue May 10 10:41:10 CDT 2022
From: Eric Pouech <eric.pouech at gmail.com>
rationale:
- native doesn't report names for SymTagBaseType objects
=> so remove typename for sym_basic
- since symt_basic becomes pretty simple, it's possible to share the object
across all modules loaded in dbghelp (simplicity, memory usage reduction)
- removed dwarf basic types cache in dwarf.c as we now have a generic one
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
dlls/dbghelp/dbghelp_private.h | 4 +--
dlls/dbghelp/dwarf.c | 46 +++++++++++-----------------
dlls/dbghelp/msc.c | 56 +++++++++++++++++-----------------
dlls/dbghelp/stabs.c | 48 ++++++++++++++---------------
dlls/dbghelp/type.c | 37 ++++++++++------------
5 files changed, 87 insertions(+), 104 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 507724414a5..24ac003df71 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -336,7 +336,6 @@ struct symt_array
struct symt_basic
{
struct symt symt;
- struct hash_table_elt hash_elt;
enum BasicType bt;
ULONG_PTR size;
};
@@ -901,8 +900,7 @@ extern void symt_init_basic(struct module* module) DECLSPEC_HIDDEN;
extern BOOL symt_get_info(struct module* module, const struct symt* type,
IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo) DECLSPEC_HIDDEN;
extern struct symt_basic*
- symt_new_basic(struct module* module, enum BasicType,
- const char* typename, unsigned size) DECLSPEC_HIDDEN;
+ symt_get_basic(enum BasicType, unsigned size) DECLSPEC_HIDDEN;
extern struct symt_udt*
symt_new_udt(struct module* module, const char* typename,
unsigned size, enum UdtKind kind) DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index b81f83ac90b..19c0da933d3 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -162,11 +162,6 @@ typedef struct dwarf2_traverse_context_s
const unsigned char* end_data;
} dwarf2_traverse_context_t;
-/* symt_cache indexes */
-#define sc_void 0
-#define sc_unknown 1
-#define sc_num 2
-
typedef struct dwarf2_cuhead_s
{
unsigned char word_size; /* size of a word on target machine */
@@ -180,7 +175,6 @@ typedef struct dwarf2_parse_module_context_s
const dwarf2_section_t* sections;
struct module* module;
const struct elf_thunk_area*thunks;
- struct symt* symt_cache[sc_num]; /* void, unknown */
struct vector unit_contexts;
struct dwarf2_dwz_alternate_s* dwz;
DWORD cu_versions;
@@ -1138,14 +1132,14 @@ static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di)
if (!dwarf2_find_attribute(di, DW_AT_type, &attr))
/* this is only valid if current language of CU is C or C++ */
- return di->unit_ctx->module_ctx->symt_cache[sc_void];
+ return &symt_get_basic(btVoid, 0)->symt;
if (!(type = dwarf2_jump_to_debug_info(&attr)))
- return di->unit_ctx->module_ctx->symt_cache[sc_unknown];
+ return &symt_get_basic(btNoType, 0)->symt;
if (type == di)
{
FIXME("Reference to itself\n");
- return di->unit_ctx->module_ctx->symt_cache[sc_unknown];
+ return &symt_get_basic(btNoType, 0)->symt;
}
if (!type->symt)
{
@@ -1154,7 +1148,7 @@ static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di)
if (!type->symt)
{
FIXME("Unable to load forward reference for tag %Ix\n", type->abbrev->tag);
- return di->unit_ctx->module_ctx->symt_cache[sc_unknown];
+ return &symt_get_basic(btNoType, 0)->symt;
}
}
return type->symt;
@@ -1484,7 +1478,7 @@ static struct symt* dwarf2_parse_base_type(dwarf2_debug_info_t* di)
case DW_ATE_unsigned_char: bt = btChar; break;
default: bt = btNoType; break;
}
- di->symt = &symt_new_basic(di->unit_ctx->module_ctx->module, bt, name.u.string, size.u.uvalue)->symt;
+ di->symt = &symt_get_basic(bt, size.u.uvalue)->symt;
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
return di->symt;
@@ -1566,14 +1560,14 @@ static struct symt* dwarf2_parse_array_type(dwarf2_debug_info_t* di)
{
/* fake an array with unknown size */
/* FIXME: int4 even on 64bit machines??? */
- idx_type = &symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "int", 4)->symt;
+ idx_type = &symt_get_basic(btInt, 4)->symt;
min.u.uvalue = 0;
cnt.u.uvalue = 0;
}
else for (i = 0; i < vector_length(children); i++)
{
child = *(dwarf2_debug_info_t**)vector_at(children, i);
- if (child->symt == di->unit_ctx->module_ctx->symt_cache[sc_unknown]) continue;
+ if (child->symt == &symt_get_basic(btNoType, 0)->symt) continue;
switch (child->abbrev->tag)
{
case DW_TAG_subrange_type:
@@ -1665,19 +1659,18 @@ static struct symt* dwarf2_parse_restrict_type(dwarf2_debug_info_t* di)
static struct symt* dwarf2_parse_unspecified_type(dwarf2_debug_info_t* di)
{
struct attribute name;
- struct attribute size;
- struct symt_basic *basic;
+ struct symt* basic;
TRACE("%s\n", dwarf2_debug_di(di));
if (di->symt) return di->symt;
- if (!dwarf2_find_attribute(di, DW_AT_name, &name))
- name.u.string = "void";
- size.u.uvalue = di->unit_ctx->module_ctx->module->cpu->word_size;
-
- basic = symt_new_basic(di->unit_ctx->module_ctx->module, btVoid, name.u.string, size.u.uvalue);
- di->symt = &basic->symt;
+ basic = &symt_get_basic(btVoid, 0)->symt;
+ if (dwarf2_find_attribute(di, DW_AT_name, &name))
+ /* define the missing type as a typedef to void... */
+ di->symt = &symt_new_typedef(di->unit_ctx->module_ctx->module, basic, name.u.string)->symt;
+ else /* or use void if it doesn't even have a name */
+ di->symt = basic;
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
return di->symt;
@@ -1878,10 +1871,10 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_debug_info_t* di)
switch (size.u.uvalue) /* FIXME: that's wrong */
{
- case 1: basetype = symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "char", 1); break;
- case 2: basetype = symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "short", 2); break;
+ case 1: basetype = symt_get_basic(btInt, 1); break;
+ case 2: basetype = symt_get_basic(btInt, 2); break;
default:
- case 4: basetype = symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "int", 4); break;
+ case 4: basetype = symt_get_basic(btInt, 4); break;
}
type = &basetype->symt;
}
@@ -2457,7 +2450,7 @@ static void dwarf2_parse_namespace(dwarf2_debug_info_t* di)
TRACE("%s\n", dwarf2_debug_di(di));
- di->symt = di->unit_ctx->module_ctx->symt_cache[sc_void];
+ di->symt = &symt_get_basic(btVoid, 0)->symt;
children = dwarf2_get_di_children(di);
if (children) for (i = 0; i < vector_length(children); i++)
@@ -4071,9 +4064,6 @@ static BOOL dwarf2_load_CU_module(dwarf2_parse_module_context_t* module_ctx, str
module_ctx->module = module;
module_ctx->thunks = thunks;
module_ctx->load_offset = load_offset;
- memset(module_ctx->symt_cache, 0, sizeof(module_ctx->symt_cache));
- module_ctx->symt_cache[sc_void] = &symt_new_basic(module_ctx->module, btVoid, "void", 0)->symt;
- module_ctx->symt_cache[sc_unknown] = &symt_new_basic(module_ctx->module, btNoType, "# unknown", 0)->symt;
vector_init(&module_ctx->unit_contexts, sizeof(dwarf2_parse_context_t), 16);
module_ctx->cu_versions = 0;
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 22ab1ecb230..64d520c2b37 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -157,34 +157,34 @@ static void codeview_init_basic_types(struct module* module)
*/
cv_basic_types[T_NOTYPE] = NULL;
cv_basic_types[T_ABS] = NULL;
- cv_basic_types[T_VOID] = &symt_new_basic(module, btVoid, "void", 0)->symt;
- cv_basic_types[T_CHAR] = &symt_new_basic(module, btChar, "char", 1)->symt;
- cv_basic_types[T_SHORT] = &symt_new_basic(module, btInt, "short int", 2)->symt;
- cv_basic_types[T_LONG] = &symt_new_basic(module, btInt, "long int", 4)->symt;
- cv_basic_types[T_QUAD] = &symt_new_basic(module, btInt, "long long int", 8)->symt;
- cv_basic_types[T_UCHAR] = &symt_new_basic(module, btUInt, "unsigned char", 1)->symt;
- cv_basic_types[T_USHORT] = &symt_new_basic(module, btUInt, "unsigned short", 2)->symt;
- cv_basic_types[T_ULONG] = &symt_new_basic(module, btUInt, "unsigned long", 4)->symt;
- cv_basic_types[T_UQUAD] = &symt_new_basic(module, btUInt, "unsigned long long", 8)->symt;
- cv_basic_types[T_BOOL08] = &symt_new_basic(module, btBool, "BOOL08", 1)->symt;
- cv_basic_types[T_BOOL16] = &symt_new_basic(module, btBool, "BOOL16", 2)->symt;
- cv_basic_types[T_BOOL32] = &symt_new_basic(module, btBool, "BOOL32", 4)->symt;
- cv_basic_types[T_BOOL64] = &symt_new_basic(module, btBool, "BOOL64", 8)->symt;
- cv_basic_types[T_REAL32] = &symt_new_basic(module, btFloat, "float", 4)->symt;
- cv_basic_types[T_REAL64] = &symt_new_basic(module, btFloat, "double", 8)->symt;
- cv_basic_types[T_REAL80] = &symt_new_basic(module, btFloat, "long double", 10)->symt;
- cv_basic_types[T_RCHAR] = &symt_new_basic(module, btInt, "signed char", 1)->symt;
- cv_basic_types[T_WCHAR] = &symt_new_basic(module, btWChar, "wchar_t", 2)->symt;
- cv_basic_types[T_CHAR16] = &symt_new_basic(module, btChar16,"char16_t", 2)->symt;
- cv_basic_types[T_CHAR32] = &symt_new_basic(module, btChar32,"char32_t", 4)->symt;
- cv_basic_types[T_CHAR8] = &symt_new_basic(module, btChar8, "char8_t", 1)->symt;
- cv_basic_types[T_INT2] = &symt_new_basic(module, btInt, "INT2", 2)->symt;
- cv_basic_types[T_UINT2] = &symt_new_basic(module, btUInt, "UINT2", 2)->symt;
- cv_basic_types[T_INT4] = &symt_new_basic(module, btInt, "INT4", 4)->symt;
- cv_basic_types[T_UINT4] = &symt_new_basic(module, btUInt, "UINT4", 4)->symt;
- cv_basic_types[T_INT8] = &symt_new_basic(module, btInt, "INT8", 8)->symt;
- cv_basic_types[T_UINT8] = &symt_new_basic(module, btUInt, "UINT8", 8)->symt;
- cv_basic_types[T_HRESULT]= &symt_new_basic(module, btUInt, "HRESULT", 4)->symt;
+ cv_basic_types[T_VOID] = &symt_get_basic(btVoid, 0)->symt; /* void */
+ cv_basic_types[T_CHAR] = &symt_get_basic(btChar, 1)->symt; /* char */
+ cv_basic_types[T_SHORT] = &symt_get_basic(btInt, 2)->symt; /* short int */
+ cv_basic_types[T_LONG] = &symt_get_basic(btInt, 4)->symt; /* long int */
+ cv_basic_types[T_QUAD] = &symt_get_basic(btInt, 8)->symt; /* long long int */
+ cv_basic_types[T_UCHAR] = &symt_get_basic(btUInt, 1)->symt; /* unsigned char */
+ cv_basic_types[T_USHORT] = &symt_get_basic(btUInt, 2)->symt; /* unsigned short */
+ cv_basic_types[T_ULONG] = &symt_get_basic(btUInt, 4)->symt; /* unsigned long */
+ cv_basic_types[T_UQUAD] = &symt_get_basic(btUInt, 8)->symt; /* unsigned long long */
+ cv_basic_types[T_BOOL08] = &symt_get_basic(btBool, 1)->symt; /* BOOL08 */
+ cv_basic_types[T_BOOL16] = &symt_get_basic(btBool, 2)->symt; /* BOOL16 */
+ cv_basic_types[T_BOOL32] = &symt_get_basic(btBool, 4)->symt; /* BOOL32 */
+ cv_basic_types[T_BOOL64] = &symt_get_basic(btBool, 8)->symt; /* BOOL64 */
+ cv_basic_types[T_REAL32] = &symt_get_basic(btFloat, 4)->symt; /* float */
+ cv_basic_types[T_REAL64] = &symt_get_basic(btFloat, 8)->symt; /* double */
+ cv_basic_types[T_REAL80] = &symt_get_basic(btFloat, 10)->symt; /* long double */
+ cv_basic_types[T_RCHAR] = &symt_get_basic(btInt, 1)->symt; /* signed char */
+ cv_basic_types[T_WCHAR] = &symt_get_basic(btWChar, 2)->symt; /* char8_t */
+ cv_basic_types[T_CHAR16] = &symt_get_basic(btChar16, 2)->symt; /* char16_t */
+ cv_basic_types[T_CHAR32] = &symt_get_basic(btChar32, 4)->symt; /* char32_t */
+ cv_basic_types[T_CHAR8] = &symt_get_basic(btChar8, 1)->symt; /* char8_t */
+ cv_basic_types[T_INT2] = &symt_get_basic(btInt, 2)->symt; /* INT2 */
+ cv_basic_types[T_UINT2] = &symt_get_basic(btUInt, 2)->symt; /* UINT2 */
+ cv_basic_types[T_INT4] = &symt_get_basic(btInt, 4)->symt; /* INT4 */
+ cv_basic_types[T_UINT4] = &symt_get_basic(btUInt, 4)->symt; /* UINT4 */
+ cv_basic_types[T_INT8] = &symt_get_basic(btInt, 8)->symt; /* INT8 */
+ cv_basic_types[T_UINT8] = &symt_get_basic(btUInt, 8)->symt; /* UINT8 */
+ cv_basic_types[T_HRESULT]= &symt_get_basic(btUInt, 4)->symt; /* HRESULT */
cv_basic_types[T_32PVOID] = &symt_new_pointer(module, cv_basic_types[T_VOID], 4)->symt;
cv_basic_types[T_32PCHAR] = &symt_new_pointer(module, cv_basic_types[T_CHAR], 4)->symt;
diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c
index 89ae0951a6a..b22fb714973 100644
--- a/dlls/dbghelp/stabs.c
+++ b/dlls/dbghelp/stabs.c
@@ -322,31 +322,31 @@ static int stabs_get_basic(struct ParseTypedefData* ptd, unsigned basic, struct
{
switch (basic)
{
- case 1: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "int", 4); break;
- case 2: stabs_basic[basic] = symt_new_basic(ptd->module, btChar, "char", 1); break;
- case 3: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "short int", 2); break;
- case 4: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "long int", 4); break;
- case 5: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned char", 1); break;
- case 6: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "signed char", 1); break;
- case 7: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned short int", 2); break;
- case 8: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned int", 4); break;
- case 9: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned", 2); break;
- case 10: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "unsigned long int", 2); break;
- case 11: stabs_basic[basic] = symt_new_basic(ptd->module, btVoid, "void", 0); break;
- case 12: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "float", 4); break;
- case 13: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "double", 8); break;
- case 14: stabs_basic[basic] = symt_new_basic(ptd->module, btFloat, "long double", 12); break;
- case 15: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "integer", 4); break;
- case 16: stabs_basic[basic] = symt_new_basic(ptd->module, btBool, "bool", 1); break;
+ case 1: stabs_basic[basic] = symt_get_basic(btInt, 4); break; /* int */
+ case 2: stabs_basic[basic] = symt_get_basic(btChar, 1); break; /* char */
+ case 3: stabs_basic[basic] = symt_get_basic(btInt, 2); break; /* short int */
+ case 4: stabs_basic[basic] = symt_get_basic(btInt, 4); break; /* long int */
+ case 5: stabs_basic[basic] = symt_get_basic(btUInt, 1); break; /* unsigned char */
+ case 6: stabs_basic[basic] = symt_get_basic(btInt, 1); break; /* signed char */
+ case 7: stabs_basic[basic] = symt_get_basic(btUInt, 2); break; /* unsigned short int */
+ case 8: stabs_basic[basic] = symt_get_basic(btUInt, 4); break; /* unsigned int */
+ case 9: stabs_basic[basic] = symt_get_basic(btUInt, 2); break; /* unsigned */
+ case 10: stabs_basic[basic] = symt_get_basic(btUInt, 2); break; /* unsigned long int */
+ case 11: stabs_basic[basic] = symt_get_basic(btVoid, 0); break; /* void */
+ case 12: stabs_basic[basic] = symt_get_basic(btFloat, 4); break; /* float */
+ case 13: stabs_basic[basic] = symt_get_basic(btFloat, 8); break; /* double */
+ case 14: stabs_basic[basic] = symt_get_basic(btFloat, 2); break; /* long double", */
+ case 15: stabs_basic[basic] = symt_get_basic(btInt, 4); break; /* integer */
+ case 16: stabs_basic[basic] = symt_get_basic(btBool, 1); break; /* bool */
/* case 17: short real */
/* case 18: real */
- case 25: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "float complex", 8); break;
- case 26: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "double complex", 16); break;
- case 30: stabs_basic[basic] = symt_new_basic(ptd->module, btWChar, "wchar_t", 2); break;
- case 31: stabs_basic[basic] = symt_new_basic(ptd->module, btInt, "long long int", 8); break;
- case 32: stabs_basic[basic] = symt_new_basic(ptd->module, btUInt, "long long unsigned", 8); break;
+ case 25: stabs_basic[basic] = symt_get_basic(btComplex, 8); break; /* float complex */
+ case 26: stabs_basic[basic] = symt_get_basic(btComplex, 6); break; /* double complex", */
+ case 30: stabs_basic[basic] = symt_get_basic(btWChar, 2); break; /* wchar_t */
+ case 31: stabs_basic[basic] = symt_get_basic(btInt, 8); break; /* long long int */
+ case 32: stabs_basic[basic] = symt_get_basic(btUInt, 8); break; /* long long unsigned */
/* starting at 35 are wine extensions (especially for R implementation) */
- case 35: stabs_basic[basic] = symt_new_basic(ptd->module, btComplex, "long double complex", 24); break;
+ case 35: stabs_basic[basic] = symt_get_basic(btComplex, 4); break; /* long double complex", */
default: PTS_ABORTIF(ptd, 1);
}
}
@@ -541,7 +541,7 @@ static int stabs_pts_read_range(struct ParseTypedefData* ptd, const char* typena
}
else PTS_ABORTIF(ptd, 1);
- *dt = &symt_new_basic(ptd->module, bt, typename, size)->symt;
+ *dt = &symt_get_basic(bt, size)->symt;
return 0;
}
@@ -967,7 +967,7 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ
*/
if (!new_dt && typename)
{
- new_dt = &symt_new_basic(ptd->module, btVoid, typename, 0)->symt;
+ new_dt = &symt_get_basic(btVoid, 0)->symt;
PTS_ABORTIF(ptd, strcmp(typename, "void"));
}
}
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c
index 67f4265ddc9..0cbbc4e333b 100644
--- a/dlls/dbghelp/type.c
+++ b/dlls/dbghelp/type.c
@@ -97,7 +97,6 @@ const char* symt_get_name(const struct symt* sym)
case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
case SymTagInlineSite: return ((const struct symt_inlinesite*)sym)->func.hash_elt.name;
case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name;
- case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name;
case SymTagLabel: return ((const struct symt_hierarchy_point*)sym)->hash_elt.name;
case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
case SymTagCustom: return ((const struct symt_custom*)sym)->hash_elt.name;
@@ -110,6 +109,7 @@ const char* symt_get_name(const struct symt* sym)
default:
FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag));
/* fall through */
+ case SymTagBaseType:
case SymTagArrayType:
case SymTagPointerType:
case SymTagFunctionType:
@@ -224,31 +224,26 @@ static void symt_add_type(struct module* module, struct symt* symt)
*p = symt;
}
-struct symt_basic* symt_new_basic(struct module* module, enum BasicType bt,
- const char* typename, unsigned size)
+struct symt_basic* symt_get_basic(enum BasicType bt, unsigned size)
{
- struct symt_basic* sym;
+ static struct symt_basic cache[32] = { { {SymTagBaseType}, btNoType, 0 } };
+ int i;
- if (typename)
- {
- sym = (struct symt_basic*)symt_find_type_by_name(module, SymTagBaseType,
- typename);
- if (sym && sym->bt == bt && sym->size == size)
- return sym;
- }
- if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
+ if (bt == btNoType) return &cache[0];
+ for (i = 1; i < ARRAY_SIZE(cache); i++)
{
- sym->symt.tag = SymTagBaseType;
- if (typename)
+ if (cache[i].bt == btNoType) /* empty slot, create new entry */
{
- sym->hash_elt.name = pool_strdup(&module->pool, typename);
- hash_table_add(&module->ht_types, &sym->hash_elt);
- } else sym->hash_elt.name = NULL;
- sym->bt = bt;
- sym->size = size;
- symt_add_type(module, &sym->symt);
+ cache[i].symt.tag = SymTagBaseType;
+ cache[i].bt = bt;
+ cache[i].size = size;
+ return &cache[i];
+ }
+ if (cache[i].bt == bt && cache[i].size == size)
+ return &cache[i];
}
- return sym;
+ FIXME("Too few slots in basic types cache\n");
+ return &cache[0];
}
struct symt_udt* symt_new_udt(struct module* module, const char* typename,
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/51
More information about the wine-devel
mailing list