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