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