[PATCH 5/7] programs/winedbg: do type / id discrimintation when parsing

Eric Pouech wine at gitlab.winehq.org
Fri May 20 10:08:55 CDT 2022


From: Eric Pouech <eric.pouech at gmail.com>

typically what a C compiler does...
- get rid of struct type_expr_t
- enabling back typecasts (and rewriting the typecast to fit the type
  parsing scheme)

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
 programs/winedbg/dbg.y      |  14 ++--
 programs/winedbg/debug.l    |   9 ++-
 programs/winedbg/debugger.h |  34 +++-------
 programs/winedbg/expr.c     | 125 +++++++++++++++---------------------
 programs/winedbg/stack.c    |   8 +--
 programs/winedbg/types.c    |  85 +++++++++++++-----------
 6 files changed, 130 insertions(+), 145 deletions(-)

diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y
index 748d16e96c5..6faa196e052 100644
--- a/programs/winedbg/dbg.y
+++ b/programs/winedbg/dbg.y
@@ -44,7 +44,7 @@ static void parser(const char*);
     dbg_lgint_t         integer;
     IMAGEHLP_LINE64     listing;
     struct expr*        expression;
-    struct type_expr_t  type;
+    struct dbg_type     type;
     struct list_string* strings;
 }
 
@@ -57,6 +57,7 @@ static void parser(const char*);
 %token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE
 %token <string> tPATH tIDENTIFIER tSTRING tINTVAR
 %token <integer> tNUM tFORMAT
+%token <type> tTYPEDEF
 %token tSYMBOLFILE tRUN tATTACH tDETACH tKILL tMAINTENANCE tTYPE tMINIDUMP
 %token tNOPROCESS
 
@@ -346,11 +347,12 @@ type_expr:
     | tFLOAT                    { if (!types_find_basic(L"float",                  $1, &$$)) YYERROR; }
     | tDOUBLE                   { if (!types_find_basic(L"double",                 $1, &$$)) YYERROR; }
     | tLONG tDOUBLE             { if (!types_find_basic(L"long double",            $1, &$$)) YYERROR; }
-    | type_expr '*'		{ $$ = $1; $$.deref_count++; }
-    | tCLASS identifier         { $$.type = type_expr_udt_class; $$.deref_count = 0; $$.u.name = $2; }
-    | tSTRUCT identifier        { $$.type = type_expr_udt_struct; $$.deref_count = 0; $$.u.name = $2; }
-    | tUNION identifier         { $$.type = type_expr_udt_union; $$.deref_count = 0; $$.u.name = $2; }
-    | tENUM identifier          { $$.type = type_expr_enumeration; $$.deref_count = 0; $$.u.name = $2; }
+    | tTYPEDEF                  { $$ = $1; }
+    | type_expr '*'             { if (!types_find_pointer(&$1, &$$)) {yyerror("Cannot find pointer type\n"); YYERROR; } }
+    | tCLASS identifier         { if (!types_find_type($2, SymTagUDT, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
+    | tSTRUCT identifier        { if (!types_find_type($2, SymTagUDT, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
+    | tUNION identifier         { if (!types_find_type($2, SymTagUDT, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
+    | tENUM identifier          { if (!types_find_type($2, SymTagEnum, &$$)) {yyerror("Unknown type\n"); YYERROR; } }
     ;
 
 expr_lvalue:
diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l
index 90dd4dfac11..1f8040ff976 100644
--- a/programs/winedbg/debug.l
+++ b/programs/winedbg/debug.l
@@ -100,6 +100,13 @@ static char* unescape_string(const char* str)
     return ret;
 }
 
+static int resolve_identifier(const char* id, DBG_STYPE* lval)
+{
+    if (types_find_type(id, SymTagTypedef, &lval->type)) return tTYPEDEF;
+    lval->string = lexeme_alloc(id);
+    return tIDENTIFIER;
+}
+
 #define YY_INPUT(buf,result,max_size) \
         (result = input_lex_read_buffer(buf, max_size))
 
@@ -258,7 +265,7 @@ union					{ return tUNION; }
 enum					{ return tENUM; }
 all                                     { return tALL; }
 
-{MODULE_IDENTIFIER}?{SCOPED_IDENTIFIER}*{IDENTIFIER}	{ dbg_lval.string = lexeme_alloc(yytext); return tIDENTIFIER; }
+{MODULE_IDENTIFIER}?{SCOPED_IDENTIFIER}*{IDENTIFIER} { return resolve_identifier(yytext, &dbg_lval); }
 "$"{IDENTIFIER}				{ dbg_lval.string = lexeme_alloc(yytext+1); return tINTVAR; }
 
 <PATH_EXPECTED,PATH_ACCEPTED>{PATHNAME}	{ dbg_lval.string = lexeme_alloc(yytext); return tPATH; }
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index bde912eaee5..d5c5934cceb 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -150,14 +150,15 @@ static inline void init_lvalue(struct dbg_lvalue* lv, BOOL in_debuggee, void* ad
     lv->type.id = dbg_itype_none;
 }
 
-static inline void init_lvalue_in_debugger(struct dbg_lvalue* lv, enum dbg_internal_types it, void* addr)
+static inline void init_lvalue_in_debugger(struct dbg_lvalue* lv, DWORD_PTR module,
+                                           enum dbg_internal_types it, void* addr)
 {
     lv->in_debuggee = 0;
     lv->bitstart = 0;
     lv->bitlen = 0;
     lv->addr.Mode = AddrModeFlat;
     lv->addr.Offset = (DWORD_PTR)addr;
-    lv->type.module = 0;
+    lv->type.module = module;
     lv->type.id = it;
 }
 
@@ -310,26 +311,6 @@ struct dbg_internal_var
 
 enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};
 
-enum type_expr_e
-{
-    type_expr_type_id,
-    type_expr_udt_class,
-    type_expr_udt_struct,
-    type_expr_udt_union,
-    type_expr_enumeration
-};
-
-struct type_expr_t
-{ 
-    enum type_expr_e    type;
-    unsigned            deref_count;
-    union
-    {
-        struct dbg_type type;
-        const char*     name;
-    } u;
-};
-
 enum dbg_start {start_ok, start_error_parse, start_error_init};
 
   /* break.c */
@@ -385,7 +366,7 @@ extern struct expr*     expr_alloc_unary_op(int oper, struct expr*);
 extern struct expr*     expr_alloc_pstruct(struct expr*, const char* element);
 extern struct expr*     expr_alloc_struct(struct expr*, const char* element);
 extern struct expr*     WINAPIV expr_alloc_func_call(const char*, int nargs, ...);
-extern struct expr*     expr_alloc_typecast(struct type_expr_t*, struct expr*);
+extern struct expr*     expr_alloc_typecast(struct dbg_type*, struct expr*);
 extern struct dbg_lvalue expr_eval(struct expr*);
 extern struct expr*     expr_clone(const struct expr* exp, BOOL *local_binding);
 extern BOOL             expr_free(struct expr* exp);
@@ -510,12 +491,13 @@ extern BOOL             types_udt_find_element(struct dbg_lvalue* value, const c
 extern BOOL             types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result);
 extern BOOL             types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
 extern BOOL             types_get_real_type(struct dbg_type* type, DWORD* tag);
-extern struct dbg_type  types_find_pointer(const struct dbg_type* type);
-extern struct dbg_type  types_find_type(DWORD64 linear, const char* name, enum SymTagEnum tag);
+extern BOOL             types_find_pointer(const struct dbg_type* type, struct dbg_type* outtype);
+extern BOOL             types_find_type(const char* name, enum SymTagEnum tag, struct dbg_type* outtype);
 extern BOOL             types_compare(const struct dbg_type, const struct dbg_type, BOOL* equal);
 extern BOOL             types_is_integral_type(const struct dbg_lvalue*);
 extern BOOL             types_is_float_type(const struct dbg_lvalue*);
-extern BOOL             types_find_basic(const WCHAR*, const char*, struct type_expr_t* type);
+extern BOOL             types_is_pointer_type(const struct dbg_lvalue*);
+extern BOOL             types_find_basic(const WCHAR*, const char*, struct dbg_type* type);
 
   /* winedbg.c */
 #ifdef __GNUC__
diff --git a/programs/winedbg/expr.c b/programs/winedbg/expr.c
index 5d9ef30ad13..9a927338ba8 100644
--- a/programs/winedbg/expr.c
+++ b/programs/winedbg/expr.c
@@ -75,8 +75,9 @@ struct expr
 
         struct
         {
-            struct type_expr_t  cast_to;
+            struct dbg_type     cast_to;
             struct expr*        expr;
+            dbg_lgint_t         result;
         } cast;
 
         struct
@@ -128,14 +129,14 @@ void expr_free_all(void)
     next_expr_free = 0;
 }
 
-struct expr* expr_alloc_typecast(struct type_expr_t* tet, struct expr* exp)
+struct expr* expr_alloc_typecast(struct dbg_type* type, struct expr* exp)
 {
     struct expr*        ex;
 
     ex = expr_alloc();
 
     ex->type            = EXPR_TYPE_CAST;
-    ex->un.cast.cast_to = *tet;
+    ex->un.cast.cast_to = *type;
     ex->un.cast.expr    = exp;
     return ex;
 }
@@ -272,75 +273,74 @@ struct expr* WINAPIV expr_alloc_func_call(const char* funcname, int nargs, ...)
 struct dbg_lvalue expr_eval(struct expr* exp)
 {
     struct dbg_lvalue                   rtn;
-    int		                        i;
     struct dbg_lvalue                   exp1;
     struct dbg_lvalue                   exp2;
     DWORD64	                        scale1, scale2, scale3;
     struct dbg_type                     type1, type2;
     DWORD                               tag;
     const struct dbg_internal_var*      div;
+    BOOL                                ret;
 
-    init_lvalue_in_debugger(&rtn, dbg_itype_none, NULL);
+    init_lvalue_in_debugger(&rtn, 0, dbg_itype_none, NULL);
 
     switch (exp->type)
     {
     case EXPR_TYPE_CAST:
-        /* this is really brute force, we simply change the type... without 
-         * checking if this is right or not
-         */
-        rtn = expr_eval(exp->un.cast.expr);
-        switch (exp->un.cast.cast_to.type)
+        exp1 = expr_eval(exp->un.cast.expr);
+        if (exp1.type.id == dbg_itype_none)
+            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
+        rtn = exp1;
+        rtn.type = exp->un.cast.cast_to;
+        init_lvalue_in_debugger(&rtn, exp->un.cast.cast_to.module, exp->un.cast.cast_to.id, &exp->un.cast.result);
+        if (types_is_float_type(&exp1))
         {
-        case type_expr_type_id:
-            if (exp->un.cast.cast_to.u.type.id == dbg_itype_none)
+            double dbl;
+            ret = memory_fetch_float(&exp1, &dbl);
+            if (ret)
             {
-                dbg_printf("Can't cast to unknown type\n");
-                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
+                if (types_is_float_type(&rtn))
+                    ret = memory_store_float(&rtn, &dbl);
+                else if (types_is_integral_type(&rtn))
+                    ret = memory_store_integer(&rtn, (dbg_lgint_t)dbl);
+                else
+                    ret = FALSE;
             }
-            rtn.type = exp->un.cast.cast_to.u.type;
-            break;
-        case type_expr_udt_class:
-        case type_expr_udt_struct:
-        case type_expr_udt_union:
-            rtn.type = types_find_type(rtn.type.module, exp->un.cast.cast_to.u.name,
-                                       SymTagUDT);
-            if (rtn.type.id == dbg_itype_none)
-            {
-                dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name);
-                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
-            }
-            break;
-        case type_expr_enumeration:
-            rtn.type = types_find_type(rtn.type.module, exp->un.cast.cast_to.u.name,
-                                       SymTagEnum);
-            if (rtn.type.id == dbg_itype_none)
-            {
-                dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name);
-                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
-            }
-            break;
-        default:
-            dbg_printf("Unsupported cast type %u\n", exp->un.cast.cast_to.type);
-            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
         }
-        for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
+        else if (types_is_integral_type(&exp1))
         {
-            rtn.type = types_find_pointer(&rtn.type);
-            if (rtn.type.id == dbg_itype_none)
+            dbg_lgint_t val = types_extract_as_integer(&exp1);
+            if (types_is_float_type(&rtn))
             {
-                dbg_printf("Cannot find pointer type\n");
-                RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
+                double dbl = val;
+                ret = memory_store_float(&rtn, &dbl);
             }
+            else if (types_is_integral_type(&rtn) || types_is_pointer_type(&rtn))
+                ret = memory_store_integer(&rtn, val);
+            else
+                ret = FALSE;
+        }
+        else if (types_is_pointer_type(&exp1))
+        {
+            dbg_lgint_t val = types_extract_as_integer(&exp1);
+
+            if (types_is_integral_type(&rtn) || types_is_pointer_type(&rtn))
+                ret = memory_store_integer(&rtn, val);
+            else
+                ret = FALSE;
         }
+        else
+            ret = FALSE;
+        if (!ret)
+            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
         break;
     case EXPR_TYPE_STRING:
-        init_lvalue_in_debugger(&rtn, dbg_itype_astring, &exp->un.string.str);
+        init_lvalue_in_debugger(&rtn, 0, dbg_itype_astring, &exp->un.string.str);
         break;
     case EXPR_TYPE_U_CONST:
-        init_lvalue_in_debugger(&rtn, dbg_itype_lguint, &exp->un.u_const.value);
+        init_lvalue_in_debugger(&rtn, 0, dbg_itype_lguint, &exp->un.u_const.value);
         break;
     case EXPR_TYPE_S_CONST:
-        init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.s_const.value);
+        init_lvalue_in_debugger(&rtn, 0, dbg_itype_lgint, &exp->un.s_const.value);
         break;
     case EXPR_TYPE_SYMBOL:
         switch (symbol_get_lvalue(exp->un.symbol.name, -1, &rtn, FALSE))
@@ -440,7 +440,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
          */
         exp->un.call.result = 0;
 #endif
-        init_lvalue_in_debugger(&rtn, dbg_itype_none, &exp->un.call.result);
+        init_lvalue_in_debugger(&rtn, 0, dbg_itype_none, &exp->un.call.result);
         /* get return type from function signature type */
         /* FIXME rtn.type.module should be set to function's module... */
         types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type.id);
@@ -448,14 +448,14 @@ struct dbg_lvalue expr_eval(struct expr* exp)
     case EXPR_TYPE_INTVAR:
         if (!(div = dbg_get_internal_var(exp->un.intvar.name)))
             RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
-        init_lvalue_in_debugger(&rtn, div->typeid, div->pval);
+        init_lvalue_in_debugger(&rtn, 0, div->typeid, div->pval);
         break;
     case EXPR_TYPE_BINOP:
         exp1 = expr_eval(exp->un.binop.exp1);
         exp2 = expr_eval(exp->un.binop.exp2);
         if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none)
             RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
-        init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.binop.result);
+        init_lvalue_in_debugger(&rtn, 0, dbg_itype_lgint, &exp->un.binop.result);
         type1 = exp1.type;
         type2 = exp2.type;
         switch (exp->un.binop.binop_type)
@@ -584,7 +584,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
     case EXPR_TYPE_UNOP:
         exp1 = expr_eval(exp->un.unop.exp1);
         if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
-        init_lvalue_in_debugger(&rtn, dbg_itype_lgint, &exp->un.unop.result);
+        init_lvalue_in_debugger(&rtn, 0, dbg_itype_lgint, &exp->un.unop.result);
         switch (exp->un.unop.unop_type)
 	{
 	case EXP_OP_NEG:
@@ -610,8 +610,7 @@ struct dbg_lvalue expr_eval(struct expr* exp)
             if (exp1.addr.Mode != AddrModeFlat)
                 RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
             exp->un.unop.result = (ULONG_PTR)memory_to_linear_addr(&exp1.addr);
-            rtn.type = types_find_pointer(&exp1.type);
-            if (rtn.type.id == dbg_itype_none)
+            if (!types_find_pointer(&exp1.type, &rtn.type))
                 RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL);
             break;
 	default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
@@ -629,30 +628,12 @@ struct dbg_lvalue expr_eval(struct expr* exp)
 BOOL expr_print(const struct expr* exp)
 {
     int		        i;
-    struct dbg_type     type;
 
     switch (exp->type)
     {
     case EXPR_TYPE_CAST:
-        WINE_FIXME("No longer supported (missing module base)\n");
         dbg_printf("((");
-        switch (exp->un.cast.cast_to.type)
-        {
-        case type_expr_type_id:
-            type.module = 0;
-            type.id = exp->un.cast.cast_to.type;
-            types_print_type(&type, FALSE); break;
-        case type_expr_udt_class:
-            dbg_printf("class %s", exp->un.cast.cast_to.u.name); break;
-        case type_expr_udt_struct:
-            dbg_printf("struct %s", exp->un.cast.cast_to.u.name); break;
-        case type_expr_udt_union:
-            dbg_printf("union %s", exp->un.cast.cast_to.u.name); break;
-        case type_expr_enumeration:
-            dbg_printf("enum %s", exp->un.cast.cast_to.u.name); break;
-        }
-        for (i = 0; i < exp->un.cast.cast_to.deref_count; i++)
-            dbg_printf("*");
+        types_print_type(&exp->un.cast.cast_to, FALSE);
         dbg_printf(")");
         expr_print(exp->un.cast.expr);
         dbg_printf(")");
diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index 50932e14ddd..01a86108d6e 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -103,7 +103,7 @@ BOOL stack_get_register_frame(const struct dbg_internal_var* div, struct dbg_lva
     struct dbg_frame* currfrm = stack_get_curr_frame();
     if (currfrm == NULL) return FALSE;
     if (currfrm->is_ctx_valid)
-        init_lvalue_in_debugger(lvalue, div->typeid,
+        init_lvalue_in_debugger(lvalue, 0, div->typeid,
                                 (char*)&currfrm->context + (DWORD_PTR)div->pval);
     else
     {
@@ -116,13 +116,13 @@ BOOL stack_get_register_frame(const struct dbg_internal_var* div, struct dbg_lva
         switch (kind)
         {
         case be_cpu_addr_pc:
-            init_lvalue_in_debugger(lvalue, itype, &currfrm->linear_pc);
+            init_lvalue_in_debugger(lvalue, 0, itype, &currfrm->linear_pc);
             break;
         case be_cpu_addr_stack:
-            init_lvalue_in_debugger(lvalue, itype, &currfrm->linear_stack);
+            init_lvalue_in_debugger(lvalue, 0, itype, &currfrm->linear_stack);
             break;
         case be_cpu_addr_frame:
-            init_lvalue_in_debugger(lvalue, itype, &currfrm->linear_frame);
+            init_lvalue_in_debugger(lvalue, 0, itype, &currfrm->linear_frame);
             break;
         }
     }
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index f9860bd12c1..b8f29058162 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -300,7 +300,8 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lv
         }
         break;
     default:
-        assert(FALSE);
+        FIXME("unexpected tag %lx\n", tag);
+        return FALSE;
     }
     /*
      * Get the base type, so we know how much to index by.
@@ -332,13 +333,9 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lv
 
 struct type_find_t
 {
-    ULONG               result; /* out: the found type */
     enum SymTagEnum     tag;    /* in: the tag to look for */
-    union
-    {
-        ULONG                   typeid; /* when tag is SymTagUDT */
-        const char*             name;   /* when tag is SymTagPointerType */
-    } u;
+    struct dbg_type     type;   /* out: the type found */
+    ULONG               ptr_typeid; /* in: when tag is SymTagPointerType */
 };
 
 static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
@@ -353,18 +350,18 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
         switch (user->tag)
         {
         case SymTagUDT:
-            if (!strcmp(user->u.name, sym->Name))
-            {
-                user->result = sym->TypeIndex;
-                ret = FALSE;
-            }
+        case SymTagEnum:
+        case SymTagTypedef:
+            user->type.module = sym->ModBase;
+            user->type.id = sym->TypeIndex;
+            ret = FALSE;
             break;
         case SymTagPointerType:
             type.module = sym->ModBase;
             type.id = sym->TypeIndex;
-            if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->u.typeid)
+            if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->ptr_typeid)
             {
-                user->result = sym->TypeIndex;
+                user->type = type;
                 ret = FALSE;
             }
             break;
@@ -380,18 +377,17 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
  * Should look up in module based at linear whether (typeid*) exists
  * Otherwise, we could create it locally
  */
-struct dbg_type types_find_pointer(const struct dbg_type* type)
+BOOL types_find_pointer(const struct dbg_type* type, struct dbg_type* outtype)
 {
     struct type_find_t  f;
-    struct dbg_type     ret;
 
-    f.result = dbg_itype_none;
+    f.type.id = dbg_itype_none;
     f.tag = SymTagPointerType;
-    f.u.typeid = type->id;
-    SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
-    ret.module = type->module;
-    ret.id = f.result;
-    return ret;
+    f.ptr_typeid = type->id;
+    if (!SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f) || f.type.id == dbg_itype_none)
+        return FALSE;
+    *outtype = f.type;
+    return TRUE;
 }
 
 /******************************************************************
@@ -400,19 +396,29 @@ struct dbg_type types_find_pointer(const struct dbg_type* type)
  * Should look up in the module based at linear address whether a type
  * named 'name' and with the correct tag exists
  */
-struct dbg_type types_find_type(DWORD64 linear, const char* name, enum SymTagEnum tag)
-
+BOOL types_find_type(const char* name, enum SymTagEnum tag, struct dbg_type* outtype)
 {
     struct type_find_t  f;
-    struct dbg_type     ret;
+    char* str = NULL;
+    BOOL ret;
 
-    f.result = dbg_itype_none;
+    if (!strchr(name, '!')) /* no module, lookup across all modules */
+    {
+        str = malloc(strlen(name) + 3);
+        if (!str) return FALSE;
+        str[0] = '*';
+        str[1] = '!';
+        strcpy(str + 2, name);
+        name = str;
+    }
+    f.type.id = dbg_itype_none;
     f.tag = tag;
-    f.u.name = name;
-    SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
-    ret.module = linear;
-    ret.id = f.result;
-    return ret;
+    ret = SymEnumTypesByName(dbg_curr_process->handle, 0, name, types_cb, &f);
+    free(str);
+    if (!ret || f.type.id == dbg_itype_none)
+        return FALSE;
+    *outtype = f.type;
+    return TRUE;
 }
 
 /***********************************************************************
@@ -916,7 +922,7 @@ static BOOL CALLBACK enum_mod_cb(const char* module, DWORD64 base, void* user)
     return TRUE;
 }
 
-BOOL             types_find_basic(const WCHAR* name, const char* mod, struct type_expr_t* type)
+BOOL             types_find_basic(const WCHAR* name, const char* mod, struct dbg_type* type)
 {
     const struct data_model* model;
     struct mod_by_name mbn = {mod, 0};
@@ -928,15 +934,13 @@ BOOL             types_find_basic(const WCHAR* name, const char* mod, struct typ
     SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
     if (!ret || mbn.base == 0)
         return FALSE;
-    type->type = type_expr_type_id;
-    type->deref_count = 0;
     model = get_data_model(mbn.base);
     for (; model->name; model++)
     {
         if (!wcscmp(name, model->name))
         {
-            type->u.type.module = 0;
-            type->u.type.id = model->itype;
+            type->module = 0;
+            type->id = model->itype;
             return TRUE;
         }
     }
@@ -1238,3 +1242,12 @@ BOOL types_is_float_type(const struct dbg_lvalue* lv)
         !types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
     return bt == btFloat;
 }
+
+BOOL types_is_pointer_type(const struct dbg_lvalue* lv)
+{
+    struct dbg_type type = lv->type;
+    DWORD tag;
+    if (lv->bitlen) return FALSE;
+    return types_get_real_type(&type, &tag) &&
+        (tag == SymTagPointerType || tag == SymTagArrayType || tag == SymTagFunctionType);
+}
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/104



More information about the wine-devel mailing list