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