Assorted spelling fixes.
[wine] / dlls / dbghelp / type.c
1 /*
2  * File types.c - management of types (hierarchical tree)
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  *               2004, Eric Pouech.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * Note: This really doesn't do much at the moment, but it forms the framework
22  * upon which full support for datatype handling will eventually be built.
23  */
24 #include "config.h"
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <assert.h>
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winreg.h"
32 #include "winnls.h"
33 #include "wine/debug.h"
34 #include "dbghelp_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
37 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symtype);
38
39 static const char* symt_get_tag_str(DWORD tag)
40 {
41     switch (tag)
42     {
43     case SymTagNull:                    return "SymTagNull";
44     case SymTagExe:                     return "SymTagExe";
45     case SymTagCompiland:               return "SymTagCompiland";
46     case SymTagCompilandDetails:        return "SymTagCompilandDetails";
47     case SymTagCompilandEnv:            return "SymTagCompilandEnv";
48     case SymTagFunction:                return "SymTagFunction";
49     case SymTagBlock:                   return "SymTagBlock";
50     case SymTagData:                    return "SymTagData";
51     case SymTagAnnotation:              return "SymTagAnnotation";
52     case SymTagLabel:                   return "SymTagLabel";
53     case SymTagPublicSymbol:            return "SymTagPublicSymbol";
54     case SymTagUDT:                     return "SymTagUDT";
55     case SymTagEnum:                    return "SymTagEnum";
56     case SymTagFunctionType:            return "SymTagFunctionType";
57     case SymTagPointerType:             return "SymTagPointerType";
58     case SymTagArrayType:               return "SymTagArrayType";
59     case SymTagBaseType:                return "SymTagBaseType";
60     case SymTagTypedef:                 return "SymTagTypedef,";
61     case SymTagBaseClass:               return "SymTagBaseClass";
62     case SymTagFriend:                  return "SymTagFriend";
63     case SymTagFunctionArgType:         return "SymTagFunctionArgType,";
64     case SymTagFuncDebugStart:          return "SymTagFuncDebugStart,";
65     case SymTagFuncDebugEnd:            return "SymTagFuncDebugEnd";
66     case SymTagUsingNamespace:          return "SymTagUsingNamespace,";
67     case SymTagVTableShape:             return "SymTagVTableShape";
68     case SymTagVTable:                  return "SymTagVTable";
69     case SymTagCustom:                  return "SymTagCustom";
70     case SymTagThunk:                   return "SymTagThunk";
71     case SymTagCustomType:              return "SymTagCustomType";
72     case SymTagManagedType:             return "SymTagManagedType";
73     case SymTagDimension:               return "SymTagDimension";
74     default:                            return "---";
75     }
76 }
77
78 const char* symt_get_name(const struct symt* sym)
79 {
80     switch (sym->tag)
81     {
82     /* lexical tree */
83     case SymTagData:            return ((struct symt_data*)sym)->hash_elt.name;
84     case SymTagFunction:        return ((struct symt_function*)sym)->hash_elt.name;
85     case SymTagPublicSymbol:    return ((struct symt_public*)sym)->hash_elt.name;
86     case SymTagBaseType:        return ((struct symt_basic*)sym)->hash_elt.name;
87     case SymTagLabel:           return ((struct symt_function_point*)sym)->name;
88     /* hierarchy tree */
89     case SymTagEnum:            return ((struct symt_enum*)sym)->name;
90     case SymTagTypedef:         return ((struct symt_typedef*)sym)->hash_elt.name;
91     case SymTagUDT:             return ((struct symt_udt*)sym)->hash_elt.name;
92     default:
93         FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag));
94         /* fall through */
95     case SymTagArrayType:
96     case SymTagPointerType:
97     case SymTagFunctionType:
98         return NULL;
99     }
100 }
101
102 static struct symt* symt_find_type_by_name(struct module* module, 
103                                            enum SymTagEnum sym_tag, 
104                                            const char* typename)
105 {
106     void*                       ptr;
107     struct symt_ht*             type;
108     struct hash_table_iter      hti;
109
110     assert(typename);
111     assert(module);
112
113     hash_table_iter_init(&module->ht_types, &hti, typename);
114     while ((ptr = hash_table_iter_up(&hti)))
115     {
116         type = GET_ENTRY(ptr, struct symt_ht, hash_elt);
117
118         if ((sym_tag == SymTagNull || type->symt.tag == sym_tag) &&
119             type->hash_elt.name && !strcmp(type->hash_elt.name, typename))
120             return &type->symt;
121     }
122     SetLastError(ERROR_INVALID_NAME); /* FIXME ?? */
123     return NULL;
124 }
125
126 struct symt_basic* symt_new_basic(struct module* module, enum BasicType bt, 
127                                   const char* typename, unsigned size)
128 {
129     struct symt_basic*          sym;
130
131     if (typename)
132     {
133         sym = (struct symt_basic*)symt_find_type_by_name(module, SymTagBaseType,
134                                                          typename);
135         if (sym && sym->bt == bt && sym->size == size)
136             return sym;
137     }
138     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
139     {
140         sym->symt.tag = SymTagBaseType;
141         if (typename)
142         {
143             sym->hash_elt.name = pool_strdup(&module->pool, typename);
144             hash_table_add(&module->ht_types, &sym->hash_elt);
145         } else sym->hash_elt.name = NULL;
146         sym->bt = bt;
147         sym->size = size;
148     }
149     return sym;
150 }
151
152 struct symt_udt* symt_new_udt(struct module* module, const char* typename, 
153                               unsigned size, enum UdtKind kind)
154 {
155     struct symt_udt*            sym;
156
157     TRACE_(dbghelp_symtype)("Adding udt %s:%s\n", module->module.ModuleName, typename);
158     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
159     {
160         sym->symt.tag = SymTagUDT;
161         sym->kind     = kind;
162         sym->size     = size;
163         if (typename)
164         {
165             sym->hash_elt.name = pool_strdup(&module->pool, typename);
166             hash_table_add(&module->ht_types, &sym->hash_elt);
167         } else sym->hash_elt.name = NULL;
168         vector_init(&sym->vchildren, sizeof(struct symt*), 8);
169     }
170     return sym;
171 }
172
173 BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned size)
174 {
175     assert(udt->symt.tag == SymTagUDT);
176     if (vector_length(&udt->vchildren) != 0)
177     {
178         if (udt->size != size)
179             FIXME_(dbghelp_symtype)("Changing size for %s from %u to %u\n", 
180                                     udt->hash_elt.name, udt->size, size);
181         return TRUE;
182     }
183     udt->size = size;
184     return TRUE;
185 }
186
187 /******************************************************************
188  *              symt_add_udt_element
189  *
190  * add an element to a udt (struct, class, union)
191  * the size & offset parameters are expressed in bits (not bytes) so that
192  * we can mix in the single call bytes aligned elements (regular fields) and
193  * the others (bit fields)
194  */
195 BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
196                           const char* name, struct symt* elt_type,
197                           unsigned offset, unsigned size)
198 {
199     struct symt_data*   m;
200     struct symt**       p;
201
202     assert(udt_type->symt.tag == SymTagUDT);
203
204     TRACE_(dbghelp_symtype)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name);
205     p = NULL;
206     while ((p = vector_iter_up(&udt_type->vchildren, p)))
207     {
208         m = (struct symt_data*)*p;
209         assert(m);
210         assert(m->symt.tag == SymTagData);
211         if (m->hash_elt.name[0] == name[0] && strcmp(m->hash_elt.name, name) == 0)
212             return TRUE;
213     }
214
215     if ((m = pool_alloc(&module->pool, sizeof(*m))) == NULL) return FALSE;
216     memset(m, 0, sizeof(*m));
217     m->symt.tag      = SymTagData;
218     m->hash_elt.name = pool_strdup(&module->pool, name);
219     m->hash_elt.next = NULL;
220
221     m->kind          = DataIsMember;
222     m->container     = &udt_type->symt;
223     m->type          = elt_type;
224     if (!(offset & 7) && !(size & 7))
225     {
226         m->location      = LocIsThisRel;
227         m->u.offset      = offset >> 3;
228         /* we could check that elt_type's size is actually size */
229     }
230     else
231     {
232         m->location            = LocIsBitField;
233         m->u.bitfield.position = offset;
234         m->u.bitfield.length   = size;
235     }
236     p = vector_add(&udt_type->vchildren, &module->pool);
237     *p = &m->symt;
238
239     return TRUE;
240 }
241
242 struct symt_enum* symt_new_enum(struct module* module, const char* typename)
243 {
244     struct symt_enum*   sym;
245
246     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
247     {
248         sym->symt.tag            = SymTagEnum;
249         sym->name = pool_strdup(&module->pool, typename);
250         vector_init(&sym->vchildren, sizeof(struct symt*), 8);
251     }
252     return sym;
253 }
254
255 BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type,
256                            const char* name, int value)
257 {
258     struct symt_data*   e;
259     struct symt**       p;
260
261     assert(enum_type->symt.tag == SymTagEnum);
262     e = pool_alloc(&module->pool, sizeof(*e));
263     if (e == NULL) return FALSE;
264
265     e->symt.tag = SymTagData;
266     e->hash_elt.name = pool_strdup(&module->pool, name);
267     e->hash_elt.next = NULL;
268     e->kind = DataIsConstant;
269     e->container = &enum_type->symt;
270     /* CV defines the underlying type for the enumeration */
271     e->type = &symt_new_basic(module, btInt, "int", 4)->symt;
272     e->location = LocIsConstant;
273     e->u.value.n1.n2.vt = VT_I4;
274     e->u.value.n1.n2.n3.lVal = value;
275
276     p = vector_add(&enum_type->vchildren, &module->pool);
277     if (!p) return FALSE; /* FIXME we leak e */
278     *p = &e->symt;
279
280     return TRUE;
281 }
282
283 struct symt_array* symt_new_array(struct module* module, int min, int max, 
284                                   struct symt* base)
285 {
286     struct symt_array*  sym;
287
288     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
289     {
290         sym->symt.tag  = SymTagArrayType;
291         sym->start     = min;
292         sym->end       = max;
293         sym->basetype  = base;
294     }
295     return sym;
296 }
297
298 struct symt_function_signature* symt_new_function_signature(struct module* module, 
299                                                             struct symt* ret_type)
300 {
301     struct symt_function_signature*     sym;
302
303     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
304     {
305         sym->symt.tag = SymTagFunctionType;
306         sym->rettype  = ret_type;
307         vector_init(&sym->vchildren, sizeof(struct symt*), 4);
308     }
309     return sym;
310 }
311
312 BOOL symt_add_function_signature_parameter(struct module* module,
313                                            struct symt_function_signature* sig_type,
314                                            struct symt* param)
315 {
316     struct symt**       p;
317
318     assert(sig_type->symt.tag == SymTagFunctionType);
319     p = vector_add(&sig_type->vchildren, &module->pool);
320     if (!p) return FALSE; /* FIXME we leak e */
321     *p = param;
322
323     return TRUE;
324 }
325
326 struct symt_pointer* symt_new_pointer(struct module* module, struct symt* ref_type)
327 {
328     struct symt_pointer*        sym;
329
330     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
331     {
332         sym->symt.tag = SymTagPointerType;
333         sym->pointsto = ref_type;
334     }
335     return sym;
336 }
337
338 struct symt_typedef* symt_new_typedef(struct module* module, struct symt* ref, 
339                                       const char* name)
340 {
341     struct symt_typedef* sym;
342
343     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
344     {
345         sym->symt.tag = SymTagTypedef;
346         sym->type     = ref;
347         sym->hash_elt.name = pool_strdup(&module->pool, name);
348         hash_table_add(&module->ht_types, &sym->hash_elt);
349     }
350     return sym;
351 }
352
353 /******************************************************************
354  *              SymEnumTypes (DBGHELP.@)
355  *
356  */
357 BOOL WINAPI SymEnumTypes(HANDLE hProcess, unsigned long BaseOfDll,
358                          PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
359                          void* UserContext)
360 {
361     struct process*             pcs;
362     struct module*              module;
363     struct symt_ht*             type;
364     void*                       ptr;
365     char                        buffer[sizeof(SYMBOL_INFO) + 256];
366     SYMBOL_INFO*                sym_info = (SYMBOL_INFO*)buffer;
367     struct hash_table_iter      hti;
368     const char*                 tmp;
369
370     TRACE("(%p %08lx %p %p)\n",
371           hProcess, BaseOfDll, EnumSymbolsCallback, UserContext);
372
373     pcs = process_find_by_handle(hProcess);
374     if (!pcs) return FALSE;
375     module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
376     if (!(module = module_get_debug(pcs, module))) return FALSE;
377
378     sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
379     sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
380
381     hash_table_iter_init(&module->ht_types, &hti, NULL);
382     while ((ptr = hash_table_iter_up(&hti)))
383     {
384         type = GET_ENTRY(ptr, struct symt_ht, hash_elt);
385         sym_info->TypeIndex = (DWORD)type;
386         sym_info->info = 0; /* FIXME */
387         symt_get_info(&type->symt, TI_GET_LENGTH, &sym_info->Size);
388         sym_info->ModBase = module->module.BaseOfImage;
389         sym_info->Flags = 0; /* FIXME */
390         sym_info->Value = 0; /* FIXME */
391         sym_info->Address = 0; /* FIXME */
392         sym_info->Register = 0; /* FIXME */
393         sym_info->Scope = 0; /* FIXME */
394         sym_info->Tag = type->symt.tag;
395         tmp = symt_get_name(&type->symt);
396         sym_info->NameLen = strlen(tmp) + 1;
397         strncpy(sym_info->Name, tmp, min(sym_info->NameLen, sym_info->MaxNameLen));
398         sym_info->Name[sym_info->MaxNameLen - 1] = '\0';
399         if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break;
400     }
401     return TRUE;
402 }
403
404 /******************************************************************
405  *              symt_get_info
406  *
407  * Retrieves inforamtion about a symt (either symbol or type)
408  */
409 BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req, 
410                    void* pInfo)
411 {
412     unsigned            len;
413
414     if (!type) return FALSE;
415
416 /* helper to typecast pInfo to its expected type (_t) */
417 #define X(_t) (*((_t*)pInfo))
418
419     switch (req)
420     {
421     case TI_FINDCHILDREN:
422         {
423             const struct vector*        v;
424             struct symt**               pt;
425             unsigned                    i;
426             TI_FINDCHILDREN_PARAMS*     tifp = pInfo;
427
428             switch (type->tag)
429             {
430             case SymTagUDT:          v = &((struct symt_udt*)type)->vchildren; break;
431             case SymTagEnum:         v = &((struct symt_enum*)type)->vchildren; break;
432             case SymTagFunctionType: v = &((struct symt_function_signature*)type)->vchildren; break;
433             case SymTagFunction:     v = &((struct symt_function*)type)->vchildren; break;
434             default:
435                 FIXME("Unsupported sym-tag %s for find-children\n", 
436                       symt_get_tag_str(type->tag));
437                 return FALSE;
438             }
439             for (i = 0; i < tifp->Count; i++)
440             {
441                 if (!(pt = vector_at(v, tifp->Start + i))) return FALSE;
442                 tifp->ChildId[i] = (DWORD)*pt;
443             }
444         }
445         break;
446
447     case TI_GET_ADDRESS:
448         switch (type->tag)
449         {
450         case SymTagData:
451             switch (((struct symt_data*)type)->kind)
452             {
453             case DataIsGlobal:
454             case DataIsFileStatic:
455                 X(DWORD) = ((struct symt_data*)type)->u.address;
456                 break;
457             default: return FALSE;
458             }
459             break;
460         case SymTagFunction:
461             X(DWORD) = ((struct symt_function*)type)->addr;
462             break;
463         case SymTagPublicSymbol:
464             X(DWORD) = ((struct symt_public*)type)->address;
465             break;
466         case SymTagFuncDebugStart:
467         case SymTagFuncDebugEnd:
468         case SymTagLabel:
469             X(DWORD) = ((struct symt_function_point*)type)->parent->addr + 
470                 ((struct symt_function_point*)type)->offset;
471             break;
472         default:
473             FIXME("Unsupported sym-tag %s for get-address\n", 
474                   symt_get_tag_str(type->tag));
475             return FALSE;
476         }
477         break;
478
479     case TI_GET_BASETYPE:
480         switch (type->tag)
481         {
482         case SymTagBaseType:
483             X(DWORD) = ((struct symt_basic*)type)->bt;
484             break;
485         case SymTagEnum:
486             X(DWORD) = btInt;
487             break;
488         default:
489             return FALSE;
490         }
491         break;
492
493     case TI_GET_BITPOSITION:
494         if (type->tag != SymTagData || ((struct symt_data*)type)->location != LocIsBitField)
495             return FALSE;
496         X(DWORD) = ((struct symt_data*)type)->u.bitfield.position;
497         break;
498
499     case TI_GET_CHILDRENCOUNT:
500         switch (type->tag)
501         {
502         case SymTagUDT:
503             X(DWORD) = vector_length(&((struct symt_udt*)type)->vchildren);
504             break;
505         case SymTagEnum:
506             X(DWORD) = vector_length(&((struct symt_enum*)type)->vchildren);
507             break;
508         case SymTagFunctionType:
509             X(DWORD) = vector_length(&((struct symt_function_signature*)type)->vchildren);
510             break;
511         case SymTagFunction:
512             X(DWORD) = vector_length(&((struct symt_function*)type)->vchildren);
513             break;
514         case SymTagPointerType: /* MS does it that way */
515         case SymTagArrayType: /* MS does it that way */
516             X(DWORD) = 0;
517             break;
518         default:
519             FIXME("Unsupported sym-tag %s for get-children-count\n", 
520                   symt_get_tag_str(type->tag));
521             /* fall through */
522         case SymTagData:
523         case SymTagPublicSymbol:
524         case SymTagBaseType:
525             return FALSE;
526         }
527         break;
528
529     case TI_GET_COUNT:
530         /* it seems that FunctionType also react to GET_COUNT (same value as
531          * GET_CHILDREN_COUNT ?, except for C++ methods, where it seems to
532          * also include 'this' (GET_CHILDREN_COUNT+1)
533          */
534         if (type->tag != SymTagArrayType) return FALSE;
535         X(DWORD) = ((struct symt_array*)type)->end - 
536             ((struct symt_array*)type)->start;
537         break;
538
539     case TI_GET_DATAKIND:
540         if (type->tag != SymTagData) return FALSE;
541         X(DWORD) = ((struct symt_data*)type)->kind;
542         break;
543
544     case TI_GET_LENGTH:
545         switch (type->tag)
546         {
547         case SymTagBaseType:
548             X(DWORD) = ((struct symt_basic*)type)->size;
549             break;
550         case SymTagFunction:
551             X(DWORD) = ((struct symt_function*)type)->size;
552             break;
553         case SymTagPointerType:
554             X(DWORD) = sizeof(void*);
555             break;
556         case SymTagUDT:
557             X(DWORD) = ((struct symt_udt*)type)->size;
558             break;
559         case SymTagEnum:
560             X(DWORD) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */
561             break;
562         case SymTagData:
563             if (((struct symt_data*)type)->location == LocIsBitField)
564                 X(DWORD) = ((struct symt_data*)type)->u.bitfield.length;
565             else
566                 return FALSE;
567             break;
568         case SymTagArrayType:   
569             if (!symt_get_info(((struct symt_array*)type)->basetype, 
570                                TI_GET_LENGTH, pInfo))
571                 return FALSE;
572             X(DWORD) *= ((struct symt_array*)type)->end - 
573                 ((struct symt_array*)type)->start;
574             break;
575         case SymTagPublicSymbol:
576             X(DWORD) = ((struct symt_public*)type)->size;
577             break;
578         case SymTagTypedef:
579             return symt_get_info(((struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
580             break;
581         default:
582             FIXME("Unsupported sym-tag %s for get-length\n", 
583                   symt_get_tag_str(type->tag));
584             return 0;
585         }
586         break;
587
588     case TI_GET_LEXICALPARENT:
589         switch (type->tag)
590         {
591         case SymTagBlock:
592             X(DWORD) = (DWORD)((struct symt_block*)type)->container;
593             break;
594         case SymTagData:
595             X(DWORD) = (DWORD)((struct symt_data*)type)->container;
596             break;
597         default:
598             FIXME("Unsupported sym-tag %s for get-lexical-parent\n", 
599                   symt_get_tag_str(type->tag));
600             return FALSE;
601         }
602         break;
603
604     case TI_GET_NESTED:
605         switch (type->tag)
606         {
607         case SymTagUDT:
608         case SymTagEnum:
609             X(DWORD) = 0;
610             break;
611         default:
612             return FALSE;
613         }
614         break;
615
616     case TI_GET_OFFSET:
617         switch (type->tag)
618         {
619         case SymTagData:
620             switch (((struct symt_data*)type)->kind)
621             {
622             case DataIsParam:
623             case DataIsLocal:
624             case DataIsMember:
625                 X(ULONG) = ((struct symt_data*)type)->u.offset; 
626                 break;
627             default:
628                 FIXME("Unknown kind (%u) for get-offset\n", 
629                       ((struct symt_data*)type)->kind);
630                 return FALSE;
631             }
632             break;
633         default:
634             FIXME("Unsupported sym-tag %s for get-offset\n", 
635                   symt_get_tag_str(type->tag));
636             return FALSE;
637         }
638         break;
639
640     case TI_GET_SYMNAME:
641         {
642             const char* name = symt_get_name(type);
643             if (!name) return FALSE;
644             len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
645             X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
646             if (!X(WCHAR*)) return FALSE;
647             MultiByteToWideChar(CP_ACP, 0, name, -1, X(WCHAR*), len);
648         }
649         break;
650
651     case TI_GET_SYMTAG:
652         X(DWORD) = type->tag;
653         break;
654
655     case TI_GET_TYPE:
656     case TI_GET_TYPEID:
657         switch (type->tag)
658         {
659             /* hierarchical => hierarchical */
660         case SymTagArrayType:
661             X(DWORD) = (DWORD)((struct symt_array*)type)->basetype;
662             break;
663         case SymTagPointerType:
664             X(DWORD) = (DWORD)((struct symt_pointer*)type)->pointsto;
665             break;
666         case SymTagFunctionType:
667             X(DWORD) = (DWORD)((struct symt_function_signature*)type)->rettype;
668             break;
669         case SymTagTypedef:
670             X(DWORD) = (DWORD)((struct symt_typedef*)type)->type;
671             break;
672             /* lexical => hierarchical */
673         case SymTagData:
674             X(DWORD) = (DWORD)((struct symt_data*)type)->type; 
675             break;
676         case SymTagFunction:
677             X(DWORD) = (DWORD)((struct symt_function*)type)->type;
678             break;
679             /* FIXME: should also work for enums and FunctionArgType */
680         default:
681             FIXME("Unsupported sym-tag %s for get-type\n", 
682                   symt_get_tag_str(type->tag));
683             return FALSE;
684         }
685         break;
686
687     case TI_GET_UDTKIND:
688         if (type->tag != SymTagUDT) return FALSE;
689         X(DWORD) = ((struct symt_udt*)type)->kind;
690         break;
691
692     case TI_GET_VALUE:
693         if (type->tag != SymTagData || ((struct symt_data*)type)->kind != DataIsConstant)
694             return FALSE;
695         X(VARIANT) = ((struct symt_data*)type)->u.value;
696         break;
697
698 #undef X
699
700     case TI_GET_ADDRESSOFFSET:
701     case TI_GET_ARRAYINDEXTYPEID:
702     case TI_GET_CALLING_CONVENTION:
703     case TI_GET_CLASSPARENTID:
704     case TI_GET_SYMINDEX:
705     case TI_GET_THISADJUST:
706     case TI_GET_VIRTUALBASECLASS:
707     case TI_GET_VIRTUALBASEPOINTEROFFSET:
708     case TI_GET_VIRTUALTABLESHAPEID:
709     case TI_IS_EQUIV_TO:
710         FIXME("Unsupported GetInfo request (%u)\n", req);
711         return FALSE;
712     }
713
714     return TRUE;
715 }
716
717 /******************************************************************
718  *              SymGetTypeInfo (DBGHELP.@)
719  *
720  */
721 BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, unsigned long ModBase,
722                            ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType,
723                            PVOID pInfo)
724 {
725     struct process*     pcs = process_find_by_handle(hProcess);
726
727     if (!pcs) return FALSE;
728 #if 0
729     struct module*      module;
730     module = module_find_by_addr(pcs, ModBase, DMT_UNKNOWN);
731     if (!(module = module_get_debug(pcs, module))) return FALSE;
732 #endif
733
734     return symt_get_info((struct symt*)TypeId, GetType, pInfo);
735 }
736
737 /******************************************************************
738  *              SymGetTypeFromName (DBGHELP.@)
739  *
740  */
741 BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, unsigned long BaseOfDll,
742                                LPSTR Name, PSYMBOL_INFO Symbol)
743 {
744     struct process*     pcs = process_find_by_handle(hProcess);
745     struct module*      module;
746     struct symt*        type;
747
748     if (!pcs) return FALSE;
749     module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
750     if (!module) return FALSE;
751     type = symt_find_type_by_name(module, SymTagNull, Name);
752     if (!type) return FALSE;
753     Symbol->TypeIndex = (DWORD)type;
754
755     return TRUE;
756 }