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