cleaning, temporarily disabling tests,e tc
[dyninst.git] / testsuite / src / symtab / test_type_info.C
1 /*
2  * Copyright (c) 1996-2008 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 #include "symtab_comp.h"
43 #include "test_lib.h"
44
45 #include "Symtab.h"
46 #include "Symbol.h"
47 #include "Type.h"
48 #include "Module.h"
49 #include <iostream>
50
51 using namespace Dyninst;
52 using namespace SymtabAPI;
53
54 class test_type_info_Mutator : public SymtabMutator {
55    std::vector<Type *> *std_types;
56    std::vector<Type *> *builtin_types;
57    test_results_t verify_basic_type_lists();
58    std::string execname;
59    bool verify_type(Type *t);
60    bool verify_type_enum(typeEnum *t, std::vector<std::pair<std::string, int> > * = NULL);
61    bool verify_type_pointer(typePointer *t, std::string * = NULL);
62    bool verify_type_function(typeFunction *t);
63    bool verify_type_subrange(typeSubrange *t);
64    bool verify_type_array(typeArray *t, int * = NULL, int * = NULL, std::string * = NULL);
65    bool verify_type_struct(typeStruct *t, 
66              std::vector<std::pair<std::string, std::string> > * = NULL, 
67              std::vector<std::pair<std::string, std::string> > * = NULL,
68              std::vector<std::pair<std::string, std::string> > * = NULL);
69    bool verify_type_union(typeUnion *t, 
70                    std::vector<std::pair<std::string, std::string> > * = NULL, 
71                    std::vector<std::pair<std::string, std::string> > * = NULL);
72    bool verify_type_scalar(typeScalar *t);
73    bool verify_type_typedef(typeTypedef *t, std::string * = NULL);
74    bool verify_field(Field *f);
75    bool verify_field_list(fieldListType *t, 
76                    std::vector<std::pair<std::string, std::string> > * = NULL, 
77          std::vector<std::pair<std::string, std::string> > * = NULL,
78                    std::vector<std::pair<std::string, std::string> > * = NULL);
79
80    bool got_type_enum;
81    bool got_type_pointer;
82    bool got_type_function;
83    bool got_type_subrange;
84    bool got_type_array;
85    bool got_type_struct;
86    bool got_type_union;
87    bool got_type_scalar;
88    bool got_type_typedef;
89
90    supportedLanguages lang;
91         public:
92    test_type_info_Mutator() : 
93            std_types(NULL), 
94            builtin_types(NULL),
95            got_type_enum(false),
96            got_type_pointer(false),
97            got_type_function(false),
98            got_type_subrange(false),
99            got_type_array(false),
100            got_type_struct(false),
101            got_type_union(false),
102            got_type_scalar(false),
103            got_type_typedef(false),
104            lang(lang_Unknown)
105    { }
106
107    bool specific_type_tests();
108
109    bool got_all_types()
110    {
111            if (!got_type_enum)
112            {
113                    logerror( "%s[%d]:  enum was missed\n", FILE__, __LINE__);
114                    return false;
115            }
116
117            if (!got_type_pointer)
118            {
119                    logerror( "%s[%d]:  pointer was missed\n", FILE__, __LINE__);
120                    return false;
121            }
122
123 #if 0
124            //  I think typeFunction is c++ only
125            if (!got_type_function)
126            {
127                    logerror( "%s[%d]:  function was missed\n", FILE__, __LINE__);
128                    return false;
129            }
130 #endif
131
132            if (!got_type_subrange)
133            {
134                    //  solaris CC does not appear to produce these
135 #if !defined(os_solaris_test) && !defined(os_aix_test) && !defined(os_windows_test)
136                    logerror( "%s[%d]:  subrange was missed\n", FILE__, __LINE__);
137                    return false;
138 #endif
139            }
140
141            if (!got_type_array)
142            {
143                    logerror( "%s[%d]:  array was missed\n", FILE__, __LINE__);
144                    return false;
145            }
146
147            if (!got_type_struct)
148            {
149                    logerror( "%s[%d]:  struct was missed\n", FILE__, __LINE__);
150                    return false;
151            }
152
153            if (!got_type_union)
154            {
155                    logerror( "%s[%d]:  union was missed\n", FILE__, __LINE__);
156                    return false;
157            }
158
159            if (!got_type_scalar)
160            {
161                    logerror( "%s[%d]:  scalar was missed\n", FILE__, __LINE__);
162                    return false;
163            }
164
165            if (!got_type_typedef)
166            {
167 #if !defined(os_windows_test)
168                    logerror( "%s[%d]:  typedef was missed\n", FILE__, __LINE__);
169                    return false;
170 #endif
171            }
172
173            return true;
174    }
175    virtual test_results_t executeTest();
176 };
177
178 extern "C" DLLEXPORT TestMutator* test_type_info_factory()
179 {
180    return new test_type_info_Mutator();
181 }
182
183 bool test_type_info_Mutator::verify_type_enum(typeEnum *t, std::vector<std::pair<std::string, int> >*vals)
184 {
185         got_type_enum = true;
186         std::string &tn = t->getName();
187         //std::cerr << "verify_type_enum for " << tn << std::endl;
188
189         std::vector<std::pair<std::string, int> > &constants = t->getConstants();
190
191         if (!constants.size())
192         {
193                 logerror( "%s[%d]: empty enum %s\n", FILE__, __LINE__, tn.c_str());
194                 return false;
195         }
196
197         for (unsigned int i = 0; i < constants.size(); ++i)
198         {
199                 if (constants[i].first.length() == 0)
200                 {
201                         logerror( "%s[%d]:  enum %s has unnamed element\n", 
202                                         FILE__, __LINE__, tn.c_str());
203                         return false;
204                 }
205         }
206
207         if (vals)
208         {
209                 std::vector<std::pair<std::string, int> > &expected_vals = *vals;
210
211                 if (expected_vals.size() != constants.size())
212                 {
213                         logerror( "%s[%d]:  differing sizes for values: %d vs %d\n", 
214                                         FILE__, __LINE__, expected_vals.size(), constants.size());
215                         return false;
216                 }
217
218                 for (unsigned int i = 0; i < expected_vals.size(); ++i)
219                 {
220                         std::string &tag1 = expected_vals[i].first;
221                         std::string &tag2 = constants[i].first;
222                         int &val1 = expected_vals[i].second;
223                         int &val2 = constants[i].second;
224
225                         if (tag1 != tag2)
226                         {
227                                 logerror( "%s[%d]:  enum elems[%d] differ: %s != %s\n", 
228                                                 FILE__, __LINE__, i, tag1.c_str(), tag2.c_str());
229                                 return false;
230                         }
231
232                         if (val1 != val2)
233                         {
234                                 logerror( "%s[%d]:  enum elems[%d] differ: %d != %d\n", 
235                                                 FILE__, __LINE__, i, val1, val2);
236                                 return false;
237                         }
238                 }
239         }
240
241         return true;
242 }
243
244 bool test_type_info_Mutator::verify_type_pointer(typePointer *t, std::string *exp_base)
245 {
246         got_type_pointer = true;
247         std::string &tn = t->getName();
248         Type *c = t->getConstituentType();
249         if (!c)
250         {
251                 logerror( "%s[%d]:  NULL constituent type for type %s!\n", 
252                                 FILE__, __LINE__, tn.c_str());
253                 return false;
254         }
255
256         if (exp_base)
257         {
258                 if (c->getName() != *exp_base)
259                 {
260                         logerror( "%s[%d]:  unexpected base type %s (not %s) for type %s\n",
261                                         FILE__, __LINE__, c->getName().c_str(), exp_base->c_str(), tn.c_str());
262                         return false;
263                 }
264         }
265         return true;
266 }
267
268 bool test_type_info_Mutator::verify_type_function(typeFunction *t)
269 {
270         got_type_function = true;
271         std::string &tn = t->getName();
272         Type *retType = t->getReturnType();
273
274         if (!retType)
275         {
276                 logerror( "%s[%d]:  func type %s has no return type\n", 
277                                 FILE__, __LINE__, tn.c_str());
278                 return false;
279         }
280
281         std::vector<Type *> &params = t->getParams();
282
283         //  It is not an error to have zero params
284
285         for (unsigned int i = 0; i < params.size(); ++i)
286         {
287                 if (params[i] == NULL)
288                 {
289                         logerror( "%s[%d]:  got NULL param type\n", FILE__, __LINE__);
290                         return false;
291                 }
292         }
293
294         return true;
295 }
296
297 bool test_type_info_Mutator::verify_type_subrange(typeSubrange *t)
298 {
299         got_type_subrange = true;
300         std::string &tn = t->getName();
301
302         //std::cerr << "verify_type_subrange for " << tn << std::endl;
303
304         if (t->getLow() > t->getHigh())
305         {
306                 logerror( "%s[%d]:  bad range [%d--%d] for type %s!\n", 
307                                 FILE__, __LINE__, t->getLow(), t->getHigh(), tn.c_str());
308                 return false;
309         }
310
311         return true;
312 }
313
314 bool test_type_info_Mutator::verify_type_array(typeArray *t, int *exp_low, int *exp_hi, 
315                 std::string *base_type_name)
316 {
317         got_type_array = true;
318         std::string &tn = t->getName();
319
320         //std::cerr << "verify_type_array for " << tn << std::endl;
321
322         if (t->getLow() > t->getHigh())
323         {
324                 //  special case (encountered w/ sun compilers -- if low bound is zero and
325                 //  highbound is -1, the array is not specified with a proper range, so
326                 //  ignore
327                 if (! (t->getLow() == 0L && t->getHigh() == -1L))
328                 {
329                         logerror( "%s[%d]:  bad ranges [%lu--%lu] for type %s!\n", 
330                                         FILE__, __LINE__, t->getLow(), t->getHigh(), tn.c_str());
331                         return false;
332                 }
333         }
334
335         Type *b = t->getBaseType();
336         if (!b)
337         {
338                 logerror( "%s[%d]:  NULL base type for type %s!\n", 
339                                 FILE__, __LINE__, tn.c_str());
340                 return false;
341         }
342
343         if (exp_low)
344         {
345                 if (*exp_low != t->getLow())
346                 {
347                         logerror( "%s[%d]:  unexpected lowbound %d (not %d) for type %s!\n", 
348                                         FILE__, __LINE__, t->getLow(), *exp_low, tn.c_str());
349                         return false;
350                 }
351         }
352
353         if (exp_hi)
354         {
355                 if (*exp_hi != t->getHigh())
356                 {
357                         logerror( "%s[%d]:  unexpected hibound %d (not %d) for type %s!\n", 
358                                         FILE__, __LINE__, t->getHigh(), *exp_hi, tn.c_str());
359                         return false;
360                 }
361         }
362
363         if (base_type_name)
364         {
365                 if (*base_type_name != b->getName())
366                 {
367                         logerror( "%s[%d]:  unexpected basetype %s (not %s) for type %s!\n", 
368                                         FILE__, __LINE__, b->getName().c_str(), base_type_name->c_str(), tn.c_str());
369                         return false;
370                 }
371         }
372
373         return true;
374 }
375
376 bool test_type_info_Mutator::verify_field(Field *f)
377 {
378         if (!f)
379         {
380                 logerror( "%s[%d]:  NULL field\n", FILE__, __LINE__);
381                 return false;
382         }
383
384         if (0 == f->getName().length())
385         {
386                 logerror( "%s[%d]:  unnamed field\n", FILE__, __LINE__);
387                 return false;
388         }
389
390         Type *ft = f->getType();
391         if (NULL == ft)
392         {
393                 logerror( "%s[%d]:  field %s has NULL type\n", FILE__, __LINE__, f->getName().c_str());
394                 return false;
395         }
396
397 #if 0
398         if (0 == f->getOffset())
399         {
400                 //  this is probably ok
401                 logerror( "%s[%d]: field %s has zero offset\n", FILE__, __LINE__, f->getName().c_str());
402                 return false;
403         }
404
405         if (visUnknown == f->getVisibility())
406         {
407                 //  this is probably ok
408                 logerror( "%s[%d]: field %s has unknown visibility\n", FILE__, __LINE__, f->getName().c_str());
409                 return false;
410         }
411 #endif
412
413         return true;
414 }
415
416 bool test_type_info_Mutator::verify_field_list(fieldListType *t, 
417                 std::vector<std::pair<std::string, std::string> > *comps, 
418       std::vector<std::pair<std::string, std::string> > *efields,
419       std::vector<std::pair<std::string, std::string> > *afields)
420 {
421         std::string &tn = t->getName();
422
423         //std::cerr << "verify_field_list for " << tn << std::endl;
424
425         std::vector<Field *> *components = t->getComponents();
426
427         if (comps && !components)
428         {
429                 logerror( "%s[%d]:  no components for type %s\n", FILE__, __LINE__, tn.c_str());
430                 return false;
431         }
432
433         if (components)
434         {
435                 for (unsigned int i = 0; i < components->size(); ++i)
436                 {
437                         Field *f = (*components)[i];
438                         if (!verify_field(f))
439                         {
440                                 logerror( "%s[%d]:  verify field failed for type %s\n", 
441                                                 FILE__, __LINE__, tn.c_str());
442                                 return false;
443                         }
444                 }
445         }
446
447         std::vector<Field *> *fields = t->getFields();
448
449         if (efields && !fields)
450         {
451                 logerror( "%s[%d]:  no fields for type %s\n", FILE__, __LINE__, tn.c_str());
452                 return false;
453         }
454
455         if (fields)
456         {
457                 for (unsigned int i = 0; i < fields->size(); ++i)
458                 {
459                         Field *f = (*fields)[i];
460                         if (!verify_field(f))
461                         {
462                                 logerror( "%s[%d]:  verify field failed for type %s\n", 
463                                                 FILE__, __LINE__, tn.c_str());
464                                 return false;
465                         }
466                 }
467
468                 if (efields)
469                 {
470                         std::vector<std::pair<std::string, std::string> > &expected_fields = *efields;
471
472                         //  We would be prudent here to use module language info to check
473                         //  whether this is c or c++, since that affects how many fields we have
474                         //  (c++ may have fields that represent functions, ctors, etc)
475                         //
476                         //  But alas, our language determination is still a bit inconsistent
477                         //  and can't really be treated as reliable
478                         //
479
480                         //if (lang = lang_CPlusPlus)
481                         //{
482                                 //  C++ field lists may contain function definitions as well
483                                 // as fields
484                         //      if (efields->size() < fields->size())
485                         //      {
486                         //              logerror( "%s[%d]:  bad sizes for expected fields\n", 
487                         //                              FILE__, __LINE__);
488                         //              logerror( "%s[%d]:  got %d, expected %d\n", FILE__, __LINE__, 
489                         //                              fields->size(), efields->size());
490                         //      }
491                         //}
492                         //else
493                         //{
494                         //      if (efields->size() != fields->size())
495                         //      {
496                         //              logerror( "%s[%d]:  WARNING:  differing sizes for expected fields\n", 
497                         //                              FILE__, __LINE__);
498                         //              logerror( "%s[%d]:  got %d, expected %d\n", FILE__, __LINE__, 
499                         //                              fields->size(), efields->size());
500                         //      }
501                         //}
502
503                         if (efields->size() > fields->size())
504                         {
505                                 logerror( "%s[%d]:  bad sizes for expected fields for type %s\n", 
506                                                 FILE__, __LINE__, tn.c_str());
507                                 logerror( "%s[%d]:  got %d, expected %d\n", FILE__, __LINE__, 
508                                                 fields->size(), efields->size());
509                                 return false;
510                         }
511
512                         bool err = false;
513                         for (unsigned int i = 0; i < expected_fields.size(); ++i)
514                         {
515                                 if (fields->size() <= i)
516                                 {
517                                         logerror( "%s[%d]:  cannot get %dth elem of %d size vec\n", 
518                                                         FILE__, __LINE__, i, fields->size());
519                                         break;
520                                 }
521
522                                 Field *f1 = (*fields)[i];
523                                 std::string fieldname = f1->getName();
524                                 std::string fieldtypename = f1->getType() ? f1->getType()->getName() : "";
525                                 Type *ft = f1->getType();
526
527                                 //if (lang == lang_CPlusPlus && ft->getFunctionType())
528                                 //{
529                                 //      logerror( "%s[%d]:  skipping field %s\n", FILE__, __LINE__, 
530                                 //                      fieldname.c_str());
531                                 //      continue;
532                                 //}
533
534                                 std::string expected_fieldname = 
535                                         (expected_fields.size() > i) ? expected_fields[i].second 
536                                         : std::string("range_error");
537                                 std::string expected_fieldtypename = 
538                                         (expected_fields.size() > i) ? expected_fields[i].first 
539                                         : std::string("range_error");
540             std::string alternate_fieldname = 
541                (afields && afields->size() > i) ? (*afields)[i].second : "range_error";
542             std::string alternate_fieldtypename = 
543                (afields && afields->size() > i) ? (*afields)[i].first : "range_error";
544
545                                 if (fieldtypename != expected_fieldtypename &&
546                 fieldtypename != alternate_fieldtypename)
547                                 {
548                                         logerror( "%s[%d]:  Field type '%s', not expected '%s'\n", FILE__,
549                                                         __LINE__, fieldtypename.c_str(), expected_fieldname.c_str());
550                                         err = true;
551                                 }
552
553                                 if (fieldname != expected_fieldname &&
554                 fieldname != alternate_fieldname)
555                                 {
556                                         logerror( "%s[%d]:  Field type '%s' not expected '%s'\n", FILE__,
557                                                         __LINE__, fieldname.c_str(), expected_fieldtypename.c_str());
558                                         err = true;
559                                 }
560                         }
561
562                         if (err) 
563                                 return false;
564                 }
565         }
566
567         return true;
568 }
569
570 bool test_type_info_Mutator::verify_type_struct(typeStruct *t, 
571                 std::vector<std::pair<std::string, std::string> > *ecomps, 
572       std::vector<std::pair<std::string, std::string> > *efields,
573       std::vector<std::pair<std::string, std::string> > *afields)
574 {
575         got_type_struct = true;
576         std::string &tn = t->getName();
577
578         //std::cerr << "verify_struct for " << tn << std::endl;
579
580         if (!verify_field_list(t, ecomps, efields, afields))
581         {
582                 logerror( "%s[%d]:  verify struct %s failing\n", FILE__, __LINE__, tn.c_str());
583                 return false;
584         }
585
586         return true;
587 }
588
589 bool test_type_info_Mutator::verify_type_union(typeUnion *t, 
590                 std::vector<std::pair<std::string, std::string> > *ecomps, 
591                 std::vector<std::pair<std::string, std::string> > *efields)
592 {
593         got_type_union = true;
594 //#if defined (os_solaris_test) || defined (os_aix_test)
595 #if 0
596         static bool did_warning = false;
597         if (!did_warning)
598         {
599                 logerror( "%s[%d]: WARNING:  union verification skipped on this platform\n", 
600                                 FILE__, __LINE__);
601                 did_warning = true;
602         }
603         return true;
604 #else
605         std::string &tn = t->getName();
606
607         //std::cerr << "verify_union for " << tn << std::endl;
608
609         if (!verify_field_list(t, ecomps, efields))
610         {
611                 logerror( "%s[%d]:  verify union %s failing\n", FILE__, __LINE__, tn.c_str());
612                 return false;
613         }
614
615         return true;
616 #endif
617 }
618
619 bool test_type_info_Mutator::verify_type_scalar(typeScalar *t)
620 {
621         got_type_scalar = true;
622         std::string &tn = t->getName();
623
624         //std::cerr << "verify_scalar for " << tn << std::endl;
625
626         //  uh... nothing to do here....  (maybe check sizes??)
627
628         return true;
629 }
630
631 bool test_type_info_Mutator::verify_type_typedef(typeTypedef *t, std::string *tn_constituent)
632 {
633         got_type_typedef = true;
634         std::string &tn = t->getName();
635
636         //std::cerr << "verify_typedef for " << tn << std::endl;
637         
638         Type *c = t->getConstituentType();
639         if (!c)
640         {
641                 logerror( "%s[%d]:  NULL constituent type for type %s!\n", 
642                                 FILE__, __LINE__, tn.c_str());
643                 return false;
644         }
645
646         if (tn_constituent)
647         {
648                 if (c->getName() != *tn_constituent)
649                 {
650                         logerror( "%s[%d]:  unexpected constituent type '%s' (not %s) for type %s!\n", 
651                                         FILE__, __LINE__, c->getName().c_str(), tn_constituent->c_str(), tn.c_str());
652                         return false;
653                 }
654         }
655
656         return true;
657 }
658
659 bool test_type_info_Mutator::verify_type(Type *t)
660 {
661         assert(t);
662         std::string & tn = t->getName();
663
664         //std::cerr << "considering type " << tn << std::endl;
665
666         if (!t->getID())
667         {
668                 logerror( "%s[%d]:  type %s with zero id\n", FILE__, __LINE__, tn.c_str());
669                 return false;
670         }
671
672         if ( 0 == tn.length())
673         {
674                 logerror( "%s[%d]:  unnamed %s type\n", FILE__, __LINE__, 
675                                 dataClass2Str(t->getDataClass()));
676                 //return false;
677         }
678
679         dataClass dc = t->getDataClass();
680
681         if (dc == dataUnknownType)
682         {
683                 logerror( "%s[%d]:  type %s has bad data class\n", FILE__, __LINE__, tn.c_str());
684                 return false;
685         }
686
687         if (dc == dataNullType)
688         {
689                 logerror( "%s[%d]:  type %s has bad data class\n", FILE__, __LINE__, tn.c_str());
690                 return false;
691         }
692
693         if (t->getEnumType())
694                 return verify_type_enum(t->getEnumType());
695         else if (t->getPointerType())
696                 return verify_type_pointer(t->getPointerType());
697         else if (t->getFunctionType())
698                 return verify_type_function(t->getFunctionType());
699         else if (t->getSubrangeType())
700                 return verify_type_subrange(t->getSubrangeType());
701         else if (t->getArrayType())
702                 return verify_type_array(t->getArrayType());
703         else if (t->getStructType())
704                 return verify_type_struct(t->getStructType());
705         else if (t->getUnionType())
706                 return verify_type_union(t->getUnionType());
707         else if (t->getScalarType())
708                 return verify_type_scalar(t->getScalarType());
709         else if (t->getTypedefType())
710                 return verify_type_typedef(t->getTypedefType());
711         else if (t->getCommonType())
712         {
713                 // common blocks are fortran only
714                 // we don't test that here yet
715                 logerror( "%s[%d]:  weird, got common type\n", FILE__, __LINE__);
716                 return true;
717                 //return verify_type_common(t->getCommonType());
718         }
719         else if (t->getRefType())
720         {
721                 //  references are c++ only
722                 // we don't test that here yet
723                 logerror( "%s[%d]:  weird, got reference type\n", FILE__, __LINE__);
724                 return true;
725                 //return verify_type_ref(t->getRefType());
726         }
727         else
728         {
729                 logerror( "%s[%d]: uknown type type for %s!\n", FILE__, __LINE__, tn.c_str());
730         }
731         return false;
732 }
733
734 bool test_type_info_Mutator::specific_type_tests()
735 {
736         Type *t = NULL;
737
738         std::string tname = "enum1";
739         if (!symtab->findType(t, tname) || (NULL == t))
740         {
741                 logerror( "%s[%d]:  could not find type %s\n", FILE__, __LINE__, tname.c_str());
742                 return false;
743         }
744
745         typeEnum *te = t->getEnumType();
746         if (!te)
747         {
748                 logerror( "%s[%d]:  %s: unexpected variety\n", FILE__, __LINE__, tname.c_str());
749                 return false;
750         }
751
752         std::vector<std::pair<std::string, int> > expected_vals;
753         expected_vals.push_back(std::pair<std::string, int>(std::string("ef1_1"), 20));
754         expected_vals.push_back(std::pair<std::string, int>(std::string("ef1_2"), 40));
755         expected_vals.push_back(std::pair<std::string, int>(std::string("ef1_3"), 60));
756         expected_vals.push_back(std::pair<std::string, int>(std::string("ef1_4"), 80));
757         if (!verify_type_enum(te, &expected_vals)) 
758                 return false;
759
760         tname = "my_union";
761         if (!symtab->findType(t, tname) || (NULL == t))
762         {
763                 logerror( "%s[%d]:  could not find type %s\n", FILE__, __LINE__, tname.c_str());
764                 return false;
765         }
766
767         typeUnion *tu = t->getUnionType();
768         if (!tu)
769         {
770                 logerror( "%s[%d]:  %s: unexpected variety\n", FILE__, __LINE__, tname.c_str());
771                 return false;
772         }
773
774         std::vector<std::pair<std::string, std::string> > expected_union_fields;
775         expected_union_fields.push_back(std::pair<std::string, std::string>("float", "my_float"));
776         expected_union_fields.push_back(std::pair<std::string, std::string>("int", "my_int"));
777
778         if (!verify_type_union(tu, NULL, &expected_union_fields)) {
779                 logerror( "%s[%d]:  could not verify union\n", FILE__, __LINE__);
780                 return false;
781    }
782
783         tname = "mystruct";
784         if (!symtab->findType(t, tname) || (NULL == t))
785         {
786                 logerror( "%s[%d]:  could not find type %s\n", FILE__, __LINE__, tname.c_str());
787                 return false;
788         }
789
790         typeStruct *ts = t->getStructType();
791         if (!ts)
792         {
793                 logerror( "%s[%d]:  %s: unexpected variety\n", FILE__, __LINE__, tname.c_str());
794                 return false;
795         }
796
797         std::vector<std::pair<std::string, std::string> > expected_struct_fields;
798         std::vector<std::pair<std::string, std::string> > alternate_struct_fields;
799         expected_struct_fields.push_back(std::pair<std::string, std::string>("int", "elem1"));
800         alternate_struct_fields.push_back(std::pair<std::string, std::string>("int", "elem1"));
801    
802         expected_struct_fields.push_back(std::pair<std::string, std::string>("double", "elem2"));
803         alternate_struct_fields.push_back(std::pair<std::string, std::string>("double", "elem2"));
804         expected_struct_fields.push_back(std::pair<std::string, std::string>("char", "elem3"));
805         alternate_struct_fields.push_back(std::pair<std::string, std::string>("signed char", "elem3"));
806         expected_struct_fields.push_back(std::pair<std::string, std::string>("float", "elem4"));
807         alternate_struct_fields.push_back(std::pair<std::string, std::string>("float", "elem4"));
808
809         if (!verify_type_struct(ts, NULL, &expected_struct_fields, &alternate_struct_fields)) {
810       logerror( "[%s:%u] - Could not verify struct\n");
811                 return false;
812    }
813 #if !defined(os_windows_test)
814         tname = "int_alias_t";
815         if (!symtab->findType(t, tname) || (NULL == t))
816         {
817                 logerror( "%s[%d]:  could not find type %s\n", FILE__, __LINE__, tname.c_str());
818                 return false;
819         }
820
821         typeTypedef *ttd = t->getTypedefType();
822         if (!ttd)
823         {
824                 logerror( "%s[%d]:  %s: unexpected variety\n", FILE__, __LINE__, tname.c_str());
825                 return false;
826         }
827
828         std::string expected_constituent_typename("int");
829         if (!verify_type_typedef(ttd, &expected_constituent_typename)) 
830                 return false;
831
832         tname = "int_array_t";
833         if (!symtab->findType(t, tname) || (NULL == t))
834         {
835                 logerror( "%s[%d]:  could not find type %s\n", FILE__, __LINE__, tname.c_str());
836                 return false;
837         }
838
839         Type *tc = NULL;
840         typeTypedef *tt = t->getTypedefType();
841         if (!tt)
842         {
843                 //  Caveat:  Solaris and gnu compilers differ here in how they emit the stab
844                 //  for the typedef array...  while it would be nice to have a consistent representation
845                 //  but it would involve creating "fake" placeholder typedefs...  or just
846                 //  modifying the test to be OK with either scenario....
847                 tc = t->getArrayType();
848                 if (NULL == tc)
849                 {
850                         logerror( "%s[%d]:  %s: unexpected variety %s\n", 
851                                         FILE__, __LINE__, tname.c_str(), t->specificType().c_str());
852                         return false;
853                 }
854         }
855         else
856         {
857                 if (!verify_type_typedef(tt, NULL)) 
858                         return false;
859
860                 tc = tt->getConstituentType();
861         }
862         if (!tc)
863         {
864                 logerror( "%s[%d]:  %s: no constituent type\n", FILE__, __LINE__, tname.c_str());
865                 return false;
866         }
867         //logerror( "%s[%d]:  typedef %s constituent typename: %s:%s/id %d, typedef id = %d\n", FILE__, __LINE__, tt->getName().c_str(), tc->specificType().c_str(), tc->getName().c_str(), tc->getID(), tt->getID());
868
869         typeArray *ta = tc->getArrayType();
870         if (!ta)
871         {
872                 logerror( "%s[%d]:  %s: unexpected variety: %s--%s\n", FILE__, __LINE__, tname.c_str(), tc->specificType().c_str(), tc->getName().c_str());
873                 typeTypedef *ttd = tc->getTypedefType();
874                 if (ttd)
875                 {
876                         Type *ttd_c = ttd->getConstituentType();
877                         logerror( "%s[%d]:  typedef constituent %s--%s\n", FILE__, __LINE__, ttd_c->getName().c_str(), ttd_c->specificType().c_str());
878                                         }
879                 return false;
880         }
881
882         std::string expected_array_base = "int";
883         int expected_low = 0;
884         int expected_hi = 255;
885         if (!verify_type_array(ta, &expected_low, &expected_hi, &expected_array_base)) 
886         {
887                 logerror( "%s[%d]: failed to verify typeArray\n", FILE__, __LINE__);
888                 return false;
889         }
890
891         if (std::string::npos == execname.find("CC")) 
892         {
893                 tname = "my_intptr_t";
894                 if (!symtab->findType(t, tname) || (NULL == t))
895                 {
896                         logerror( "%s[%d]:  could not find type %s\n", 
897                                         FILE__, __LINE__, tname.c_str());
898                         return false;
899                 }
900
901                 tt = t->getTypedefType();
902                 if (!tt)
903                 {
904                         logerror( "%s[%d]:  %s: unexpected variety\n", 
905                                         FILE__, __LINE__, tname.c_str());
906                         return false;
907                 }
908
909                 if (!verify_type_typedef(tt, NULL)) 
910                         return false;
911
912                 tc = tt->getConstituentType();
913                 if (!tc)
914                 {
915                         logerror( "%s[%d]:  %s: no constituent type\n", 
916                                         FILE__, __LINE__, tname.c_str());
917                         return false;
918                 }
919
920                 typePointer *tp = tc->getPointerType();
921                 if (!tp)
922                 {
923                         logerror( "%s[%d]:  %s: unexpected variety: %s\n", 
924                                         FILE__, __LINE__, tname.c_str(), dataClass2Str(tc->getDataClass()));
925                         return false;
926                 }
927
928                 std::string expected_pointer_base = "int";
929                 if (!verify_type_pointer(tp, &expected_pointer_base)) 
930                         return false;
931         }
932         else
933         {
934                 logerror("%s[%d]:  skipped function pointer type verifiction for sun CC compiler\n", 
935                                 FILE__, __LINE__);
936         }
937 #endif
938         return true;
939 }
940
941 test_results_t test_type_info_Mutator::verify_basic_type_lists()
942 {
943    std_types = symtab->getAllstdTypes();
944    builtin_types = symtab->getAllbuiltInTypes();
945
946    if (!std_types || !std_types->size() )
947    {
948       logerror("[%s:%u] - Unable to find std types\n", 
949                __FILE__, __LINE__);
950       return FAILED;
951    }
952
953    if (!builtin_types || !builtin_types->size() )
954    {
955       logerror("[%s:%u] - Unable to find std types\n", 
956                __FILE__, __LINE__);
957       return FAILED;
958    }
959
960    for (unsigned int i = 0; i < std_types->size(); ++i)
961    {
962            Type *t = (*std_types)[i];
963            if (!t)
964            {
965                    logerror( "%s[%d]:  NULL type returned to user\n", FILE__, __LINE__);
966                    return FAILED;
967            }
968
969            if (!verify_type(t))
970            {
971                    logerror( "%s[%d]:  failing due to bad type\n", FILE__, __LINE__);
972                    return FAILED;
973            }
974    }
975
976    for (unsigned int i = 0; i < builtin_types->size(); ++i)
977    {
978            Type *t = (*builtin_types)[i];
979            if (!t)
980            {
981                    logerror( "%s[%d]:  NULL type returned to user\n", FILE__, __LINE__);
982                    return FAILED;
983            }
984
985            if (!verify_type(t))
986            {
987                    logerror( "%s[%d]:  failing due to bad type\n", FILE__, __LINE__);
988                    return FAILED;
989            }
990    }
991
992    std::vector<SymtabAPI::Module *> mods;
993    bool result = symtab->getAllModules(mods);
994
995    if (!result || !mods.size() )
996    {
997            logerror("%s[%d]: Unable to getAllModules\n", FILE__, __LINE__);
998            return FAILED;
999    }
1000
1001    for (unsigned int i = 0; i < mods.size(); ++i)
1002    {
1003            std::vector<Type *> *modtypes = mods[i]->getAllTypes();
1004
1005            if (!modtypes)
1006            {
1007                    //  we try to look at all modules that have types
1008                    //  but not all do
1009                    //  Only fail if the module is one of ours
1010
1011                    if (  mods[i]->fileName() == std::string("mutatee_util.c")
1012                       ||(mods[i]->fileName() == std::string("solo_mutatee_boilerplate.c"))
1013                       ||(mods[i]->fileName() == std::string("mutatee_driver.c")))
1014                    {
1015                            logerror( "%s[%d]:  module %s has no types\n", FILE__, __LINE__, 
1016                                            mods[i]->fileName().c_str());
1017
1018                            return FAILED;
1019                    }
1020                    else
1021                            continue;
1022            }
1023
1024            //logerror( "%s[%d]:  examining types in module %s\n", FILE__, __LINE__,
1025            //              mods[i]->fileName().c_str());
1026
1027            for (unsigned int j = 0; j < modtypes->size(); ++j)
1028            {
1029                    Type *t = (*modtypes)[j];
1030                    if (!t)
1031                    {
1032                            logerror( "%s[%d]:  NULL type returned to user\n", FILE__, __LINE__);
1033                            return FAILED;
1034                    }
1035
1036                    if (!verify_type(t))
1037                    {
1038                            logerror( "%s[%d]:  failing due to bad type\n", FILE__, __LINE__);
1039                            return FAILED;
1040                    }
1041            }
1042    }
1043
1044
1045    if (!specific_type_tests())
1046    {
1047            logerror( "%s[%d]:  specific type test failed... \n", FILE__, __LINE__);
1048            return FAILED;
1049    }
1050
1051    if (!got_all_types())
1052    {
1053            logerror( "%s[%d]:  did not test all types...  failing\n", FILE__, __LINE__);
1054            return FAILED;
1055    }
1056
1057    return PASSED;
1058 }
1059
1060 test_results_t test_type_info_Mutator::executeTest()
1061 {
1062
1063 #if defined (os_linux_test) && defined (arch_x86_test)
1064         //  actually only fails for c++
1065         if (useAttach == DESERIALIZE)
1066                 return SKIPPED;
1067 #endif
1068 #if defined (os_aix_test) 
1069         if (useAttach == DESERIALIZE)
1070                 return SKIPPED;
1071 #endif
1072 #if defined (os_solaris_test)
1073         if (useAttach == DESERIALIZE)
1074         //      if (compiler == std::string("CC") || compiler == std::string("sun_cc"))
1075         //      {
1076                         return SKIPPED;
1077         //      }
1078 #endif
1079
1080         SymtabAPI::Module *mod = NULL;
1081         std::vector<SymtabAPI::Module *> mods;
1082
1083         execname = symtab->name();
1084         
1085         if (!symtab->getAllModules(mods))
1086         {
1087                 logerror( "%s[%d]:  failed to get all modules\n", FILE__, __LINE__);
1088                 return FAILED;
1089         }
1090
1091         for (unsigned int i = 0; i < mods.size(); ++i)
1092         {
1093                 std::string mname = mods[i]->fileName();
1094                 //logerror( "%s[%d]:  considering module %s\n", FILE__, __LINE__, mname.c_str());
1095                 if (!strncmp("solo_mutatee", mname.c_str(), strlen("solo_mutatee")) ||  
1096                     !strncmp("test_type_info_mutatee", mname.c_str(), strlen("test_type_info_mutatee")))
1097                 {
1098                    if (mod)
1099                       logerror( "%s[%d]:  FIXME\n", FILE__, __LINE__);
1100                    mod = mods[i];
1101                 }
1102         }
1103
1104         if (!mod)
1105         {
1106                 logerror( "%s[%d]:  failed to find module\n", FILE__, __LINE__);
1107                 return FAILED;
1108         }
1109
1110         lang = mod->language();
1111         //logerror( "%s[%d]:  lang = %s\n", FILE__, __LINE__, supportedLanguages2Str(lang));
1112         test_results_t ret = verify_basic_type_lists();
1113    return ret;
1114 }
1115