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