Compile fix after removing deprecated SymtabAPI methods.
[dyninst.git] / symtabAPI / src / parseStab.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include <ctype.h>
32 #include <iostream>
33 // from libiberty's demangle.h
34 #define DMGL_PARAMS   (1 << 0) 
35 #define DMGL_ANSI     (1 << 1) 
36 #define DMGL_VERBOSE  (1 << 3) 
37
38 #include "symutil.h"
39 #include "Symtab.h" // For looking up compiler type
40 #include "Symbol.h" 
41 #include "Function.h"
42 #include "Variable.h"
43 #include "Module.h" 
44 #include "Collections.h"
45 #include "annotations.h"
46 #include "common/h/headers.h"
47 #include "Type-mem.h"
48
49 #include "debug.h"
50
51 using namespace Dyninst;
52 using namespace Dyninst::SymtabAPI;
53
54 /*
55 #include "BPatch.h"
56 #include "debug.h"
57 */
58
59 extern std::string symt_current_func_name;
60 extern std::string symt_current_mangled_func_name;
61 extern Function *symt_current_func;
62 namespace Dyninst{
63 namespace SymtabAPI{
64     std::string parseStabString(Module *mod, int linenum, char *stabstr, 
65                       int framePtr, typeCommon *commonBlock = NULL);
66 }
67 }
68
69 // Forward references for parsing routines
70 static int parseSymDesc(char *stabstr, int &cnt);
71 static Type *parseConstantUse(Module *, char *stabstr, int &cnt);
72 static char *parseTypeDef(Module *, char *stabstr, 
73                           const char *name, int ID, unsigned int sizeHint = 0);
74 static int parseTypeUse(Module*, char *&stabstr, int &cnt,
75                         const char *name);
76 static inline bool isSymId(char ch);
77 static std::string getIdentifier(char *stabstr, int &cnt, bool stopOnSpace=false);
78
79 static std::string currentRawSymbolName;
80
81 std::string convertCharToString(const char *ptr){
82     if(ptr)
83         return ptr;
84     else
85         return "";
86 }
87
88 //
89 // Start of code to parse Stab information.
90 //    The structure of this code is a recursive decent parser that parses
91 //    information in stab records and builds up the corresponding BPatch_types.
92 //    
93 //    Each non-terminal in the grammer has a function of the form parse<NT>.
94 //      
95 //    The grammar for a non-terminal appears in the comments just before
96 //    the non-terminal parsing function
97 //      
98
99 void vectorNameMatchKLUDGE(Module *mod, char *demangled_sym, std::vector<Function *> &bpfv, std::vector<int> &matches)
100 {
101   // iterate through all matches and demangle names with extra parameters, compare
102   for (unsigned int i = 0; i < bpfv.size(); ++i) {
103     std::string l_mangled;
104     std::vector<Symbol *> syms;
105     bpfv[i]->getSymbols(syms);
106     if (syms.size()) {
107         l_mangled = syms[0]->getMangledName();
108         
109         char * l_demangled_raw = P_cplus_demangle(l_mangled.c_str(), mod->exec()->isNativeCompiler());
110         if( l_demangled_raw == NULL ) {
111             l_demangled_raw = strdup(l_mangled.c_str());
112         }
113         
114         if (!strcmp(l_demangled_raw, demangled_sym)) {
115            matches.push_back(i);
116         }
117         free(l_demangled_raw);
118     }
119   } /* end iteration over function vector */
120 }
121
122 Function *mangledNameMatchKLUDGE(const char *pretty, const char *mangled, 
123                                         Module *mod)
124 {
125
126   std::vector<Function *> bpfv;
127   if (!mod->exec()->findFunctionsByName(bpfv, pretty)) {
128      //cerr << __FILE__ << __LINE__ << ":  KLUDGE Cannot find " << pretty << endl;
129      return NULL;  // no pretty name hits, expecting multiple
130   }
131
132   //cerr << __FILE__ << __LINE__ << ":  mangledNameMatchKLUDGE: language = " 
133   //<< mod->getLanguageStr() << endl;
134
135   if (lang_Fortran_with_pretty_debug == mod->language()) {
136       // debug function symbols are presented in "demangled" style.
137       if (bpfv.size() == 1)
138         return bpfv[0];
139       else {
140         cerr << __FILE__ << __LINE__ << ":  FIXME!" << endl;
141         return NULL;
142       }
143     }
144
145   // demangle name with extra parameters
146   char * demangled_sym = P_cplus_demangle( mangled, mod->exec()->isNativeCompiler(), true );
147   if( demangled_sym == NULL ) {
148         demangled_sym = strdup( mangled );
149         assert( demangled_sym != NULL );
150   }
151
152   std::vector<int> matches;
153
154   vectorNameMatchKLUDGE(mod, demangled_sym, bpfv, matches);
155
156   Function *ret = NULL;
157
158   if (matches.size() == 1) {ret = bpfv[matches[0]]; goto clean_up;}
159   if (matches.size() > 1) goto clean_up;
160   
161   // check in the uninstrumentable pile
162   bpfv.clear();
163   matches.clear();
164
165   vectorNameMatchKLUDGE(mod, demangled_sym, bpfv, matches);
166   if (matches.size() == 1) {ret = bpfv[matches[0]]; goto clean_up;}
167   if (matches.size() > 1) goto clean_up;
168
169  clean_up:
170   free( demangled_sym );
171   return ret;
172 }
173
174 // This function takes the stab stabstring and parses it to create a new 
175 // type or variable object.  This function only defines the type/variable 
176 // name and ID.
177 //
178 // <stabString> = <ident>:<symDesc>                     |
179 //                <ident>:c<constantUse>                |
180 //                <ident>:f<symDesc>                    |
181 //                <ident>:f<syymDesc>,<ident>,<ident>   |
182 //                <ident>:F<typeUse><paramList>         |
183 //                <ident>:G<typeUse>                    |
184 //                <ident>:r<int>                        |
185 //                <ident>:S<typeUse>                    |
186 //                <ident>:[pPr]<typeUse>                |
187 //                <ident>::T<typeUse>                   |
188 //                <ident>:t<typeUse>                    |
189 //                <ident>:T<typeUse>                    |
190 //                <ident>:v<typeUse>                    |
191 //                <ident>:V<symDesc>                    |
192 //                <indet>:Y[Tc|Ts]
193 //
194 // <paramList> = | <typeUse>;<paramList> 
195 //
196
197 std::string Dyninst::SymtabAPI::parseStabString(Module *mod, int linenum, char *stabstr, 
198       int framePtr, typeCommon *commonBlock)
199 {
200         typeCollection *tc = typeCollection::getModTypeCollection(mod);
201    int cnt;
202    int ID = 0;
203    int symdescID = 0;
204    int funcReturnID = 0;
205    Function  *fp = NULL;
206    Type * ptrType = NULL;
207    Type * newType = NULL; // For new types to add to the collection
208    localVar *locVar = NULL;
209    cnt= 0;
210
211    types_printf("parseStabString, mod %p/%s, linenum %d, stabstr %s\n",
212                 mod,
213                 (mod != NULL) ? mod->fileName().c_str() : "NULL",
214                 linenum, 
215                 stabstr);
216
217    std::string fName = mod->fileName();
218
219    /* get type or variable name */
220    std::string mangledname = getIdentifier( stabstr, cnt );
221
222    currentRawSymbolName = mangledname;
223    char * demangled = P_cplus_demangle( mangledname.c_str(), mod->exec()->isNativeCompiler() );
224    std::string name;
225
226    if ( demangled == NULL ) 
227    {
228       name = mangledname;
229    } 
230    else 
231    {
232       name = demangled;
233    }
234
235    if ( name[0] != '\0' && stabstr[cnt] != ':' ) 
236    {
237      types_printf("\t returning name %s\n", name.c_str());
238       return name;
239    }
240
241    if (stabstr[cnt] == ':') 
242    {
243       // skip to type part
244       cnt++;
245    }
246
247    if (isSymId(stabstr[cnt])) 
248    {
249       /* instance of a predefined type */
250
251       ID = parseSymDesc(stabstr, cnt);
252
253       if (stabstr[cnt] == '=') 
254       {
255          /* More Stuff to parse, call parseTypeDef */
256
257                   stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name.c_str(), ID);
258          cnt = 0;
259          ptrType = tc->findOrCreateType(ID);
260          if (!symt_current_func) 
261          {
262             // XXX-may want to use N_LBRAC and N_RBRAC to set function scope 
263             // -- jdd 5/13/99
264             // Still need to add to local variable list if in a function
265
266             std::string modName = mod->fileName();
267             //bperr("%s[%d] Can't find function %s in module %s\n", __FILE__, __LINE__,
268             //     symt_current_mangled_func_name.c_str(), modName);
269             //bperr("Unable to add %s to local variable list in %s\n",
270             //     name.c_str(), symt_current_func_name.c_str());
271          } 
272          else 
273          {
274             locVar = new localVar(name, ptrType, fName, linenum, symt_current_func);
275             VariableLocation loc;
276             loc.stClass = storageRegOffset;
277             loc.refClass = storageNoRef;
278             loc.frameOffset = framePtr;
279             locVar->addLocation(loc);
280             if (!ptrType) {
281                //bperr("adding local var with missing type %s, type = %d\n",
282                //      name, ID);
283             }
284
285             localVarCollection *lvs = NULL;
286
287             if (!symt_current_func->getAnnotation(lvs, FunctionLocalVariablesAnno)) 
288             {
289                lvs = new localVarCollection();
290                if (!symt_current_func->addAnnotation(lvs, FunctionLocalVariablesAnno)) 
291                {
292                   fprintf(stderr, "%s[%d]: failed to add annotation here\n", FILE__, __LINE__);
293                }
294             }
295
296             if (!lvs)
297             {
298                fprintf(stderr, "%s[%d]: failed to get annotation here\n", FILE__, __LINE__);
299             }
300
301             lvs->addLocalVar(locVar);
302          }
303       } 
304       else if (symt_current_func) 
305       {
306          // Try to find the BPatch_Function
307          ptrType = tc->findOrCreateType( ID);
308
309          locVar = new localVar(name, ptrType, fName, linenum, symt_current_func);
310          VariableLocation loc;
311          loc.stClass = storageRegOffset;
312          loc.refClass = storageNoRef;
313          loc.frameOffset = framePtr;
314          locVar->addLocation(loc);
315
316          if (!ptrType) 
317          {
318             ////bperr("adding local var with missing type %s, type = %d\n",
319             //       name, ID);
320          }
321
322          if (!symt_current_func->addLocalVar(locVar)) 
323          {
324             fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
325          }
326
327       }
328    } 
329    else if (stabstr[cnt]) 
330    {
331       std::vector<Function *> bpfv;
332
333       switch (stabstr[cnt]) {
334          case 'f': /*Local Function*/ 
335             {
336                std::string scopeName;
337                std::string lfuncName;
338                cnt++;
339
340                symt_current_func_name = name;
341                symt_current_mangled_func_name = mangledname;
342
343                funcReturnID = parseTypeUse(mod, stabstr, cnt, name.c_str());
344
345                if (stabstr[cnt]==',') 
346                {
347                   cnt++;        /*skip the comma*/
348
349                   /* Local Function Name */
350                   lfuncName = getIdentifier(stabstr, cnt);
351
352                   assert(stabstr[cnt] == ',');
353                   cnt++;        /*skip the comma*/
354
355                   /* Scope Name of Local Function */
356                   scopeName = getIdentifier(stabstr, cnt);
357
358                   if (stabstr[cnt]) 
359                   {
360                      //bperr("Extra: %s\n", &stabstr[cnt]);
361                   }
362                }
363
364                if (!scopeName.length()) 
365                { 
366                   // Not an embeded function
367
368                   ptrType = tc->findOrCreateType(funcReturnID);
369                   /*
370                     The shared_ptr type_Untyped is static, so this
371                     otherwise unsafe operation is safe.
372                   */
373                   if ( !ptrType) ptrType = Symtab::type_Untyped().get();
374
375                   if (!(mod->exec()->findFunctionsByName(bpfv, name)))
376                   {
377                       //showInfoCallback(string("missing local function ") +
378                       //                                             name + "\n");
379                       // It's very possible that we might not find a function
380                       // that's a weak reference, and defined in multiple places
381                       // as we only store an object from the last definition
382                       //
383                       // 12/08 - not sure this is necessary anymore
384                       // due to the Function abstraction
385                       fp = NULL;
386                   } 
387                   else 
388                   {
389                      if (bpfv.size() > 1) 
390                      {
391                         // warn if we find more than one function with current_func_name
392                         char msg[1024];
393                         sprintf(msg, "%s[%d]:  found %d functions with name %s, using the first",
394                               __FILE__, __LINE__, (int)bpfv.size(), name.c_str());
395                         // BPatch::bpatch->reportError(BPatchWarning, 0, msg);
396
397                      }
398                      else if (!bpfv.size()) 
399                      {
400                         //bperr("%s[%d]:  SERIOUS: found 0 functions with name %s",
401                         //       __FILE__, __LINE__, name.c_str());
402                         break;
403                      }
404
405                      fp = bpfv[0];
406                      // set return type.
407                      fp->setReturnType(ptrType);
408                   }
409                } 
410                else 
411                {
412                   //bperr("%s is an embedded function in %s\n",name.c_str(), scopeName.c_str());
413                }
414
415                symt_current_func = fp;
416                // skip to end - SunPro Compilers output extra info here - jkh 6/9/3
417                cnt = strlen(stabstr);
418
419                break;
420             }  
421
422          case 'F':/* Global Function */
423             {
424                cnt++; /*skipping 'F' */
425
426                funcReturnID = parseTypeUse(mod, stabstr, cnt, name.c_str());
427
428                symt_current_func_name = name;
429                symt_current_mangled_func_name = mangledname;
430
431                //
432                // For SunPro compilers there may be a parameter list after 
433                //   the return
434                //
435
436                while (stabstr[cnt] == ';') 
437                {
438                   cnt++;        // skip ';'
439                   (void) parseTypeUse(mod, stabstr, cnt, "");
440                }
441
442                // skip to end - SunPro Compilers output extra info here - jkh 6/9/3
443                cnt = strlen(stabstr);
444
445                ptrType = tc->findOrCreateType(funcReturnID);
446                if (!ptrType) ptrType = Symtab::type_Untyped().get();
447
448                std::vector<Function *>fpv;
449                if (!mod->exec()->findFunctionsByName(fpv, symt_current_mangled_func_name))
450                //if (!mod->findSymbol(fpv, symt_current_mangled_func_name, Symbol::ST_FUNCTION, true)) 
451                {
452                   std::string modName = mod->fileName();
453
454                   if (NULL == (fp = mangledNameMatchKLUDGE(symt_current_func_name.c_str(), 
455                               symt_current_mangled_func_name.c_str(), mod)))
456                   {
457                      //bpwarn("%s L%d - Cannot find global function with mangled name '%s' or pretty name '%s' with return type '%s' in module '%s', possibly extern\n",
458                      //       __FILE__, __LINE__,
459                      //       symt_current_mangled_func_name.c_str(), current_func_name.c_str(),
460                      //       ((ptrType->getMangledName() == NULL) ? "" : ptrType->getMangledName()), 
461                      //       modName);
462                      //char prefix[5];
463                      //strncpy(prefix, current_mangled_func_name, 4);
464                      //prefix[4] = '\0';
465                      // mod->dumpMangled(prefix);
466                      break;
467                   }
468                }
469                fp = fpv[0];
470
471                fp->setReturnType(ptrType);
472                symt_current_func = fp;
473                fpv.clear();
474             }    
475             break;
476
477          case 'U':/* Class Declaration - for Sun Compilers - jkh 6/6/03 */
478          case 'E':/* Extern'd Global ??? - undocumented type for Sun Compilers - jkh 6/6/03 */
479          case 'G':/* Global Varaible */
480             cnt++; /* skip the 'G' */
481
482             /* Get variable type number */
483             symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
484             Type *BPtype;
485
486             BPtype = tc->findOrCreateType(symdescID);
487             if (BPtype) 
488             {
489               Module *toUse = mod;
490                std::vector<Variable *> ret;
491                bool result = mod->findVariablesByName(ret, name);
492                if (!result) {
493                  // Might be in a different module...
494                  if (mod->exec()->getDefaultModule()->findVariablesByName(ret, name))
495                    toUse = mod->exec()->getDefaultModule();
496                }
497                for (unsigned i=0; i<ret.size(); i++) {
498                  ret[i]->setType(BPtype);
499                }
500
501                    typeCollection *tc_to_use = typeCollection::getModTypeCollection(toUse);
502                tc_to_use->addGlobalVariable(name, BPtype);
503             }
504             else 
505             break;
506
507          case 'P':      // function parameter passed in a register (GNU/Solaris)
508          case 'R':      // function parameter passed in a register (AIX style)
509          case 'v':      // Fortran Local Variable
510          case 'X':      // Fortran function return Variable (e.g. function name)
511          case 'p': 
512             {   
513                // Function Parameter
514                cnt++; /* skip the 'p' */
515
516                /* Get variable type number */
517                symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
518
519                if (stabstr[cnt] == ';') 
520                {
521                   // parameter type information, not used for now
522                   cnt = strlen(stabstr);
523                } 
524               // else if (stabstr[cnt]) 
525               // {
526                   //bperr( "\tMore to parse func param %s\n", &stabstr[cnt]);
527                   //bperr( "\tFull String: %s\n", stabstr);
528                //}
529
530                ptrType = tc->findOrCreateType(symdescID);
531                if (!ptrType) ptrType = Symtab::type_Untyped().get();
532
533                localVar *param;
534
535                param = new localVar(name, ptrType, fName, linenum, symt_current_func);
536                VariableLocation loc;
537                loc.stClass = storageRegOffset;
538                loc.refClass = storageNoRef;
539                loc.frameOffset = framePtr;
540                param->addLocation(loc);
541
542                if (symt_current_func) 
543                {
544                   if (!symt_current_func->addParam(param)) 
545                   {
546                      fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
547                   }
548                } 
549
550                break;
551             }
552
553          case 'c': /* constant */
554             {
555                cnt++; /*move past the 'c' */
556                if (symt_current_mangled_func_name.length()) 
557                {
558                   std::vector<Function *>fpv;
559                   if (mod->exec()->findFunctionsByName(fpv, symt_current_mangled_func_name))
560                   { 
561                      // found function, add parameter
562                      fp = fpv[0];       
563                      symt_current_func = fp;
564                   }
565                   fpv.clear();
566                } 
567
568                ptrType = parseConstantUse(mod, stabstr, cnt);
569
570                if (!ptrType) ptrType = Symtab::type_Untyped().get();
571
572                localVar *var;
573                var = new localVar(name, ptrType, fName, linenum, symt_current_func);
574                VariableLocation loc;
575                loc.stClass = storageRegOffset;
576                loc.refClass = storageNoRef;
577                loc.frameOffset = 0;
578                var->addLocation(loc);
579                if (symt_current_func) {
580                      if (!symt_current_func->addParam(var)) 
581                      {
582                         fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
583                      }
584                   }
585             }
586             break;
587
588          case 'r':/* Register Variable */
589             cnt++; /*move past the 'r'*/
590             /* get type reference */
591
592             symdescID = parseSymDesc(stabstr, cnt);
593             break;
594
595          case 'S':/* Global Static Variable */ 
596             {
597                cnt++; /*move past the 'S'*/
598
599                /* get type reference */
600                symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
601
602                // lookup symbol and set type
603                Type *BPtype;
604
605                std::string nameTrailer;
606                if (name.find(".") < name.length()) 
607                {
608                   std::string defaultNameSpace;
609                   defaultNameSpace = name.substr(0,name.find("."));
610                   nameTrailer = name.substr(name.find(".")+1,name.length()-name.find(".")-1);
611                   mod->setDefaultNamespacePrefix(defaultNameSpace);
612                } 
613                else
614                {
615                   nameTrailer = name;
616                }
617
618                BPtype = tc->findOrCreateType(symdescID);
619
620                if (BPtype) 
621                {
622                   Symtab *img = mod->exec();
623                   std::vector<Symbol *>syms;
624                   if (img->findSymbol(syms, 
625                                             nameTrailer,
626                                             Symbol::ST_OBJECT,
627                                             mangledName) ||
628                       img->findSymbol(syms, 
629                                             nameTrailer,
630                                             Symbol::ST_OBJECT, 
631                                             mangledName,
632                                             true)) 
633                   {
634                      
635                      tc->addGlobalVariable(nameTrailer, BPtype);
636                   }
637                }
638
639                //else 
640                //{
641                   //bperr("ERROR: unable to find type #%d for variable %s\n", 
642                   // symdescID, nameTrailer.c_str());
643                //} 
644
645                break;
646             }
647
648          case 't':      // Type Name 
649             cnt++; /*move past the 't'*/
650
651             /* get type reference */
652             symdescID = parseSymDesc(stabstr, cnt);
653
654             //Create Type.
655             if (stabstr[cnt] == '=') 
656             {
657                /* More Stuff to parse, call parseTypeDef */
658                //char *oldstabstr = stabstr;
659                                 stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name.c_str(), symdescID);
660                cnt = 0;
661
662
663                // AIX seems to append an semi at the end of these
664                if (stabstr[0] && strcmp(stabstr, ";")) 
665                {
666                   //bperr("\tMore to parse creating type %s\n", stabstr);
667                   //bperr( "\tFull String: %s\n", oldStr);
668                }
669             } 
670             else 
671             {
672                //Create Type defined as a pre-exisitng type.
673
674                ptrType = tc->findOrCreateType(symdescID);
675                if (!ptrType)
676                {
677                   ptrType = Symtab::type_Untyped().get();
678                }
679
680                // We assume that IDs are unique per type. Instead of reusing the 
681                // underlying base ID, use a SymtabAPI-generated ID.
682
683                typeTypedef *newType = new typeTypedef(ptrType, name);
684
685                if (newType) 
686                {
687                                    tc->addOrUpdateType(newType);
688                            }
689                         }
690             break;
691
692          case ':':      // :T... - skip ":" and parse 'T'
693             if ((stabstr[cnt+1] == 't') || (stabstr[cnt+1] == 'T')) 
694             {
695                // parse as a normal typedef
696                parseStabString(mod, linenum, &stabstr[cnt+1], framePtr);
697             } 
698
699             // else 
700             //{
701             //bperr("Unknown type seen %s\n", stabstr);
702             //}
703
704             break;
705
706          case 'T':/* Aggregate type tag -struct, union, enum */
707             cnt++; /*move past the 'T'*/
708
709             if (stabstr[cnt] == 't') 
710             {
711                //C++ struct  tag "T" and type def "t"
712                ////bperr("SKipping C++ Identifier t of Tt\n");
713                cnt++;  //skip it
714             }
715
716             /* get type reference */
717             symdescID = parseSymDesc(stabstr, cnt);
718
719             //Create Type.
720             if (stabstr[cnt] == '=') 
721             {
722                /* More Stuff to parse, call parseTypeDef */
723                stabstr = parseTypeDef(mod,(&stabstr[cnt+1]),name.c_str(),symdescID);
724                cnt = 0;
725
726                //if (stabstr[0]) 
727                //{
728                   //bperr( "\tMore to parse aggregate type %s\n", (&stabstr[cnt]));
729                   //bperr("\tFull String: %s\n", stabstr);
730                //}
731
732             } 
733             else 
734             {
735                //Create Type defined as a pre-exisitng type.
736
737                newType = Type::createPlaceholder(symdescID, name);
738             }
739
740             break;
741
742          case 'V':/* Local Static Variable (common block vars too) */
743             cnt++; /*move past the 'V'*/
744
745             // //bperr("parsing 'v' type of %s\n", stabstr);
746             /* Get variable type number */
747
748             symdescID = parseTypeUse(mod, stabstr, cnt, name.c_str());
749
750             // lookup symbol and set type
751             BPtype = tc->findOrCreateType(symdescID);
752
753             if (!BPtype) 
754             {
755                //bperr("ERROR: unable to find type #%d for variable %s\n", 
756                // symdescID, name.c_str());
757                break;
758             }
759
760             if (commonBlock) 
761             {
762                /* This variable is in a common block */
763                /* add it only if not already there, common block
764                   are re-defined for each subroutine but subroutines
765                   define only the member they care about
766                 */
767
768                bool found = false;
769                const std::vector<Field *> *fields;
770                fields = commonBlock->getFields();
771                if (fields) 
772                {
773                   for (unsigned int i=0; i < fields->size(); i++) 
774                   {
775                      if (name == (*fields)[i]->getName()) 
776                      {
777                         found = true;
778                         break;
779                      }
780
781                      int start1, start2, end1, end2;
782                      start1 = (*fields)[i]->getOffset();
783                      end1 = start1 + (*fields)[i]->getSize();
784                      start2 = framePtr;
785                      end2 = framePtr + BPtype->getSize();
786                      if ( ((start2 >= start1) && (start2 < end1)) 
787                          || ((start1 >= start2) && (start1 < end2)) ) 
788                      {
789                         /* common block aliasing detected */
790                         //bpwarn("WARN: EQUIVALENCE used in %s: %s and %s\n",
791                         //  current_func_name.c_str(), name.c_str(), (*fields)[i]->getName());
792
793                         found = true;
794                         break;
795                      }
796                   }
797                }
798
799                if (!found) 
800                {
801                   commonBlock->addField(name, BPtype, framePtr);
802                }
803             } 
804             else 
805             {
806                // put it into the local variable scope
807                if (symt_current_func) 
808                {
809                   locVar = new localVar(name, BPtype, fName, linenum, symt_current_func);
810                   VariableLocation loc;
811                   loc.stClass = storageAddr;
812                   loc.refClass = storageNoRef;
813                   loc.frameOffset = framePtr;
814                   locVar->addLocation(loc);
815
816                   if (!symt_current_func->addLocalVar(locVar)) 
817                   {
818                      fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
819                   }
820                }
821
822                //else 
823                //{
824                   //bperr("Unable to add %s to local variable list in %s\n",
825                   //     name.c_str(),current_func_name.c_str());
826                //} 
827             }
828             break;
829          case 'l':
830             // These are string literals, of the form 
831             // name:l(type);value
832             // where type must be predefined, and value of of type type.
833             // It should be safe to ignore these. 
834
835             cnt = strlen(stabstr);
836             break;
837
838          case 'Y':      // C++ specific stuff
839             cnt++; // Skip past the 'Y'
840             if (stabstr[cnt] == 'I') 
841             {
842                /* Template instantiation */
843                cnt++; // skip past the I;
844                if (stabstr[cnt] == 'f') /* Template function */ 
845                {
846                   while (stabstr[cnt] != '@') cnt++;
847                   cnt++; // Skip past '@'
848                   cnt++; // Skip past ';'
849                   cnt++; // Skip past ';'
850                   while (stabstr[cnt] != ':') cnt++;
851                   // Create fake stab string that cuts out template garbage
852                   char *dupstring = strdup(stabstr);
853                   strcpy(dupstring, mangledname.c_str());
854                   strcat(dupstring, stabstr+cnt);
855                   parseStabString(mod, linenum, dupstring, framePtr, commonBlock);
856                   free(dupstring);
857               }
858           } 
859           cnt = strlen(stabstr);
860           break;
861
862           default:
863           //bperr( "Unknown symbol descriptor: %c\n", stabstr[cnt]);
864           //bperr( " : %s\n", stabstr);
865           break;
866       }   
867     }
868
869     return(&stabstr[cnt]);
870 } /* end of parseStabString */
871
872
873 //
874 // Is the current character a valid prefix for a symDesc non-terminal?
875 //
876 inline bool isSymId(char ch)
877 {
878     return ((ch == '(') || isdigit(ch) || (ch == '-'));
879 }
880
881 //
882 // parse a Symbol Descriptor ID
883 //      symDesc = <int> | (<int>,<int>)
884 //
885 int parseSymDesc(char *stabstr, int &cnt)
886 {
887     int id;
888     int lid;
889     int hid;
890     int sign = 1;
891     bool newForm = false;
892
893     hid = 0; //file-number
894     // parse both an int and (int,int) format (file-number, type ID)
895     if (stabstr[cnt] == '(') {
896         cnt++;
897         while (isdigit(stabstr[cnt])) {
898             hid = hid * 10 + stabstr[cnt] - '0';
899             cnt++;
900         }
901
902         // skip ","
903         if (stabstr[cnt] == ',') cnt++;
904         newForm = true;
905     }
906        
907     if (stabstr[cnt] == '-') {
908         sign = -1;
909         cnt++;
910     }
911
912     lid = 0; //type ID
913     while (isdigit(stabstr[cnt])) {
914         lid = lid * 10 + stabstr[cnt] - '0';
915         cnt++;
916     }
917     if( hid != 0 )
918       assert(lid < 65536);
919     
920     // skip closing ')'
921     if (newForm) cnt++;
922
923     id = hid * 65536 + lid;
924     id = id * sign;
925     
926     return id;
927 }
928
929 //
930 // parse an identifier up to a ":" or "," or ";"
931 //
932 std::string getIdentifier( char *stabstr, int &cnt, bool stopOnSpace ) {
933         int i = 0;
934         int brCnt = 0;
935         bool idChar = true;
936
937         while( idChar ) {
938                 switch( stabstr[ cnt + i ] ) {
939                         case '<':
940                         case '(':
941                                 brCnt++;
942                                 i++;
943                                 break;
944
945                         case '>':
946                         case ')':
947                                 brCnt--;
948                                 i++;
949                                 break;
950
951                 case ' ':
952                                 if ( !stopOnSpace ) {
953                                     i++;
954                                     break;
955                                         } // else fall through
956                         case '\0':
957                         case ':':
958                         case ',':
959                         case ';':
960                                 /* Handle case of '::' */
961                                 if ( stabstr[ cnt + i ] == ':' && stabstr[ cnt + i + 1 ] == ':' &&
962                                      (stabstr[ cnt + i + 2 ] == '_' || isalpha(stabstr[ cnt + i + 2 ])) ) {
963                                    i+=3;
964                                    break;
965                                 }
966                                 /* If we're inside a bracket and we haven't reached
967                                    the end of the string, continue. */
968                                 if( brCnt != 0 && stabstr[ cnt + i ] != '\0' ) {
969                                         i++;
970                                         }
971                                 else if( brCnt ) {
972                                         //bperr( "Failed to find identifier in stabstring '%s;\n", stabstr );
973                                         idChar = false;
974                                         }
975                                 else {
976                                         idChar = false;
977                                         }
978                                 break;
979                                 
980                         default:
981                                 i++;
982                                 break;
983                         } /* end switch */
984     } /* end while */
985
986         char * identifier = (char *)malloc( i + 1 );
987         assert( identifier );
988         
989         strncpy( identifier, & stabstr[cnt], i );
990         identifier[i] = '\0';
991         cnt += i;
992         
993         std::string pd_identifier = identifier;
994         free(identifier);
995         return pd_identifier;
996         } /* end getIdentifier() */
997
998 //
999 // getFieldName
1000 //
1001 // A simplified version of getIdentifier, it only cares about finding a ':'
1002 //
1003
1004 char * getFieldName( char *stabstr, int &cnt) {
1005    int i = 0;
1006    bool idChar = true;
1007
1008    while ( idChar ) {
1009       switch( stabstr[ cnt + i ] ) {
1010       case ':':
1011          idChar = false;
1012          break;
1013       default:
1014          i++;
1015       }
1016    }
1017
1018    char * identifier = (char *) malloc(i + 1);
1019    assert(identifier);
1020
1021    strncpy(identifier, &stabstr[cnt], i);
1022    identifier[i] = '\0';
1023    cnt += i;
1024
1025    return identifier;
1026 }
1027
1028 //
1029 // Parse a use of a type.  
1030 //
1031 //      <typeUse> = <symDesc> | <symDesc>=<typeDef>
1032 //
1033 static int parseTypeUse(Module *mod,char *&stabstr, int &cnt, 
1034                         const char *name)
1035 {
1036     int ret = parseSymDesc(stabstr, cnt);
1037
1038     if (stabstr[cnt] == '=') {
1039         /* More Stuff to parse, call parseTypeDef */
1040         stabstr = parseTypeDef(mod, (&stabstr[cnt+1]), name, ret);
1041         cnt = 0;
1042     }
1043     return ret;
1044 }
1045
1046 //
1047 // parseCrossRef - internal struct/union pointer
1048 //
1049 //      <crossRef>      = [s|u|e]<ident>
1050 //
1051 static char *parseCrossRef(typeCollection *moduleTypes,const char * /*name*/,
1052                            int ID, char *stabstr, int &cnt)
1053 {
1054     std::string temp;
1055     Type *newType = NULL;
1056     char xreftype;
1057     cnt++; /* skip 'x'*/
1058
1059     if ((stabstr[cnt] == 's') ||        // struct 
1060             (stabstr[cnt] == 'u') ||    // union
1061             (stabstr[cnt] == 'e')) {    // enum
1062         xreftype = stabstr[cnt++];
1063
1064         temp = getIdentifier(stabstr, cnt);
1065         cnt++; /*skip ':' */
1066
1067         // Find type that this one points to.
1068         Type *ptrType = moduleTypes->findType(temp.c_str());
1069         if (!ptrType) {
1070             // This type name hasn't been seen before.  Create the
1071             // skeleton for it, and we'll update it later when we actually see
1072             // it
1073             if (xreftype == 'e') {
1074                 newType = new typeEnum(ID, temp);
1075                 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
1076             } else if (xreftype == 'u') {
1077                 newType = new typeUnion(ID, temp);
1078                 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
1079             } else {
1080                 newType = new typeStruct(ID, temp);
1081                 newType = moduleTypes->addOrUpdateType((typeEnum *) newType);
1082             }
1083             assert(newType);
1084         }         
1085     } else {
1086         /* don't know what it is?? */
1087
1088         temp = getIdentifier(stabstr, cnt);
1089         cnt++; /*skip ':' */
1090     }
1091
1092     return( &(stabstr[cnt]));
1093 }
1094             
1095 //
1096 // parse the definition of an array.
1097 //      arrayDef = ar<symDesc>;<symDesc>;<symDesc>;<symDesc> |
1098 //                 ar<symDesc>;<symDesc>;<symDesc>;<arrayDef> |
1099 //                 A<arrayDef>
1100 //
1101 static Type *parseArrayDef(Module *mod, const char *name,
1102                      int ID, char *&stabstr, int &cnt, unsigned int sizeHint)
1103 {
1104         typeCollection *tc = typeCollection::getModTypeCollection(mod);
1105     char *symdesc;
1106     int symdescID;
1107     int elementType;
1108     Type *newType = NULL;
1109     Type *ptrType = NULL;
1110     int lowbound, hibound;
1111
1112     // format is ar<indexType>;<lowBound>;<highBound>;<elementType>
1113
1114     assert(stabstr[cnt] == 'a' || stabstr[cnt] == 'A');
1115
1116     if (stabstr[cnt ++] == 'A') {
1117        // Open array
1118        lowbound = 1;
1119        hibound = 0;
1120        elementType = parseSymDesc(stabstr, cnt);
1121        ptrType = tc->findOrCreateType(elementType);
1122     } else {
1123        // Regular (maybe) array
1124
1125        if (stabstr[cnt] != 'r') {
1126           //bperr("unknown array definition seen %s\n", &stabstr[cnt]);
1127           return(NULL);
1128        }
1129        
1130        /* array with range */
1131        symdesc = &(stabstr[cnt]);
1132        
1133        cnt++;   /* skip 'r' */
1134        
1135        symdescID = parseTypeUse(mod, stabstr, cnt, name);
1136        
1137        cnt++; /* skip semicolon */
1138        lowbound = parseSymDesc(stabstr, cnt);
1139        
1140        cnt++; /* skip semicolon */
1141        if (stabstr[cnt] == 'J') {
1142           /* Fortran unbounded array */
1143           hibound = 0;
1144           cnt++;
1145        } else if (stabstr[cnt] == 'T') {
1146           /* Fortran runtime bound array - Txx is the form (xx=digits)*/
1147           hibound = 0;
1148           cnt++;
1149           while (isdigit(stabstr[cnt])) cnt++;
1150        } else {
1151           hibound = parseSymDesc(stabstr, cnt);
1152        }
1153        
1154        cnt++; /* skip semicolon */
1155        elementType = parseSymDesc(stabstr, cnt);
1156        
1157            if (stabstr[cnt] == 'a') 
1158            {
1159                    /* multi dimensional array - Fortran style */
1160                    /* it has no valid id, so we give it a known duplicate */
1161                    //fprintf(stderr, "%s[%d]:  parseArrayDef(...'%s'...)\n", FILE__, __LINE__, stabstr);
1162                    ptrType = parseArrayDef(mod, name, 0, stabstr, cnt, sizeHint);
1163            } 
1164            else 
1165            { 
1166                    if (stabstr[cnt] == '=') 
1167                    {
1168                            /* multi dimensional array */
1169                            char *temp;
1170                            temp = parseTypeDef(mod, &(stabstr[cnt+1]), NULL, elementType);
1171                            /* parseTypeDef uses old style of returning updated stabstr,
1172                                   but parseArrayDef function needs to return an updated cnt.  
1173                                   This simple hack updates cnt based on how far parseTypDef 
1174                                   advances it.  jkh 12/4/00 */
1175                            cnt = temp-stabstr;
1176                            if (stabstr[cnt] == ':') {
1177                                    //C++ stuff
1178                                    ////bperr("Skipping C++ rest of array def:  %s\n",name );
1179                                    while (stabstr[cnt] != ';') cnt++;
1180                            }
1181                    }
1182                    ptrType = tc->findOrCreateType(elementType);
1183            }
1184         }
1185
1186         //  //bperr("Symbol Desriptor: %s Descriptor ID: %d Type: %d, Low Bound: %d, Hi Bound: %d,\n", symdesc, symdescID, elementType, lowbound, hibound);
1187
1188
1189         if (ptrType) {
1190                 // Create new type - field in a struct or union
1191                 std::string tName = convertCharToString(name);
1192
1193                 typeArray *newAType = new typeArray(ID, ptrType, lowbound, hibound, tName, sizeHint);
1194                 // Add to Collection
1195                 newType = tc->addOrUpdateType((typeArray *) newAType);
1196
1197                 return newAType;
1198     }
1199             
1200     // //bperr( "parsed array def to %d, remaining %s\n", cnt, &stabstr[cnt]);
1201     return newType;
1202 }
1203
1204 int guessSize(const char *low, const char *hi) 
1205 {
1206    long long l, h;
1207
1208    if (low[0] == '0')
1209       sscanf(low, "%llo", &l);
1210    else
1211       sscanf(low, "%lld", &l);
1212    if (hi[0] == '0')
1213       sscanf(hi, "%llo", &h);
1214    else
1215       sscanf(hi, "%lld", &h);
1216
1217    /*   
1218    if (( low[0]=='-' && l < -2147483648LL )
1219        || ( l > || ( h > 2147483647LL))
1220       return 8;
1221    else if (( l < -32768 ) || ( h > 32767 ))
1222       return 4;
1223    else if (( l < -128 ) || ( h > 127 ))
1224       return 2;
1225    else
1226       return 1;
1227    */
1228    if (l < 0) { // Must be signed
1229       if (l < -2147483648LL || h > 0x7fffffffLL)
1230          return 8;
1231       else if (l < 0xffff8000 || h > 0x7fff)
1232          return 4;
1233       else if (l < 0xffffff80 || h > 0x7f)
1234          return 2;
1235       else
1236          return 1;
1237    } else {
1238       if (h > 0xffffffffLL)
1239          return 8;
1240       else if (h > 0xffff)
1241          return 4;
1242       else if (h > 0xff)
1243          return 2;
1244       else
1245          return 1;
1246    }
1247 }
1248
1249 #if defined(i386_unknown_linux2_0) \
1250  || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ 
1251 //
1252 // parse range type of the form:        
1253 //
1254 //      <rangeType> = r<typeNum>;<low>;<high>;
1255 //
1256 static char *parseRangeType(Module *mod, const char *name, int ID, 
1257                             char *stabstr, unsigned int sizeHint = 0)
1258 {
1259    int cnt, i, symdescID;
1260    //int sign = 1;
1261    Type *baseType;
1262
1263    cnt = i = 0;
1264
1265    assert(stabstr[0] == 'r');
1266    cnt++;
1267
1268    // range index type - not used
1269    symdescID = parseSymDesc(stabstr, cnt);
1270
1271    typeCollection *tc = typeCollection::getModTypeCollection(mod);
1272    if (!mod || !tc) 
1273    {
1274       fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
1275       return NULL;
1276    }
1277    else 
1278    {
1279       baseType = tc->findType(symdescID);
1280    }
1281
1282    // //bperr("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
1283
1284    cnt++; /* Discarding the ';' */
1285    i=0;
1286    if (stabstr[cnt] == '-' ) {
1287       i++;
1288    }
1289
1290    /* Getting type range or size */
1291
1292    while (isdigit(stabstr[cnt+i])) i++;
1293
1294    char *low = (char *)malloc(sizeof(char)*(i+1));
1295    if(!strncpy(low, &(stabstr[cnt]), i))
1296       /* Error copying size/range*/
1297       exit(1);
1298    low[i] = '\0';
1299
1300    cnt = cnt + i + 1; /* Discard other Semicolon */
1301    i = 0;
1302    if((stabstr[cnt]) == '-') {
1303       i++; /* discard '-' for (long) unsigned int */
1304    }
1305    //Find high bound
1306    while (isdigit(stabstr[cnt+i])) i++;
1307    char *hi = (char *)malloc(sizeof(char)*(i+1));
1308    if(!strncpy(hi, &(stabstr[cnt]), i))
1309       /* Error copying upper range */
1310       exit(1);
1311    hi[i] = '\0';
1312
1313    int j = atol(hi);
1314     
1315    if (j == 0) {
1316        //Size
1317        int size = atol(low);
1318
1319        //Create new type
1320        Type *newType = new typeScalar(ID, size, name);
1321        //Add to Collection
1322        newType = tc->addOrUpdateType((typeScalar *) newType);
1323    }
1324    else {
1325        //Range
1326        //Create new type
1327        Type *newType;
1328        std::string tName = convertCharToString(name);
1329
1330            errno = 0;
1331            long low_conv = strtol(low, NULL, 10);
1332            if (errno)
1333            {
1334                    low_conv = LONG_MIN;
1335            }
1336
1337            errno = 0;
1338            long hi_conv = strtol(hi, NULL, 10);
1339            if (errno)
1340            {
1341                    hi_conv = LONG_MAX;
1342            }
1343
1344        if (baseType == NULL)
1345            newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : guessSize(low,hi), 
1346                                    low_conv, hi_conv, tName);
1347        else
1348            newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(), 
1349                                    low_conv, hi_conv, tName);
1350        //Add to Collection
1351        tc->addOrUpdateType((typeSubrange *) newType);
1352    }
1353    free(low);
1354    free(hi);
1355    hi=low=NULL;
1356
1357    cnt = cnt + i;
1358    if( stabstr[cnt] == ';')
1359       cnt++;
1360
1361    return(&(stabstr[cnt]));
1362 }
1363
1364 #else
1365 //
1366 // parse range type of the form:        
1367 //
1368 //      <rangeType> = r<typeNum>;<low>;<high>;
1369 //
1370 static char *parseRangeType(Module *mod, const char *name, int ID,
1371                             char *stabstr, unsigned int sizeHint = 0)
1372 {
1373     int cnt, i, symdescID;
1374     Type *baseType;
1375     Type *newType;
1376
1377     cnt = i = 0;
1378
1379     assert(stabstr[0] == 'r');
1380     cnt++;
1381
1382     // range index type
1383     symdescID = parseSymDesc(stabstr, cnt);
1384
1385         typeCollection *tc = typeCollection::getModTypeCollection(mod);
1386     baseType = tc->findType(symdescID);
1387
1388     // //bperr("\tSymbol Descriptor: %c and Value: %d\n",tmpchar, symdescID);
1389
1390     cnt++; /* Discarding the ';' */
1391     i=0;
1392     if (stabstr[cnt] == '-' ) {
1393        i++;
1394     }
1395
1396     /* Getting type range or size */
1397     while (isdigit(stabstr[cnt+i])) i++;
1398
1399     char *temp = (char *)malloc(sizeof(char)*(i+1));
1400     if(!strncpy(temp, &(stabstr[cnt]), i))
1401       /* Error copying size/range*/
1402       exit(1);
1403     temp[i] = '\0';
1404     int j = atol(temp);
1405     
1406     char *low = temp;
1407     cnt = cnt + i + 1; /* Discard other Semicolon */
1408     i = 0;
1409     if((stabstr[cnt]) == '-') {
1410        i++; /* discard '-' for (long) unsigned int */
1411     }
1412     
1413     while(isdigit(stabstr[cnt+i]))
1414        i++;
1415     
1416     char *hi = (char *)malloc(sizeof(char)*(i+1));
1417     if(!strncpy(hi, &(stabstr[cnt]), i))
1418        /* Error copying upper range */
1419        exit(1);
1420     hi[i] = '\0';
1421
1422     std::string tname = convertCharToString(name);
1423         if ( j <= 0 )
1424         {
1425                 /* range */
1426
1427                 // //bperr("\tLower limit: %s and Upper limit: %s\n", low, hi);
1428                 //Create new type
1429                 errno = 0;
1430                 long low_conv = strtol(low, NULL, 10);
1431                 if (errno)
1432                 {
1433                 //      fprintf(stderr, "%s[%d]:  error converting range limit '%s' to long: %s\n", 
1434                 //                      FILE__, __LINE__, low, strerror(errno));
1435                         low_conv = LONG_MIN;
1436                 }
1437
1438                 if (low_conv < LONG_MIN)
1439                 {
1440                         fprintf(stderr, "%s[%d]:  signed variable saturation...\n", FILE__, __LINE__);
1441                         low_conv = LONG_MIN;
1442                 }
1443
1444                 errno = 0;
1445                 long hi_conv = strtol(hi, NULL, 10);
1446                 if (errno)
1447                 {
1448                         //fprintf(stderr, "%s[%d]:  error converting range limit '%s' to long: %s\n", 
1449                 //                      FILE__, __LINE__, hi, strerror(errno));
1450                         hi_conv = LONG_MAX;
1451                 }
1452
1453                 if (hi_conv > LONG_MAX)
1454                 {
1455                         fprintf(stderr, "%s[%d]:  signed variable saturation...\n", FILE__, __LINE__);
1456                         hi_conv = LONG_MAX;
1457                 }
1458
1459                 if (baseType == NULL) 
1460                 {
1461                         newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : guessSize(low,hi), 
1462                                         low_conv, hi_conv, tname);
1463                 }
1464                 else 
1465                 {
1466                         newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(), 
1467                                         low_conv, hi_conv, tname);
1468                 }
1469                 newType = tc->addOrUpdateType((typeSubrange *) newType);
1470         } 
1471         else if( j > 0)
1472         {
1473                 j = atol(hi);
1474                 if (j == 0)
1475                 {
1476                         /*size */
1477                         int size = (int)j;
1478
1479                         // //bperr("\tSize of Type : %d bytes\n",size);
1480                         //Create new type
1481
1482                         newType = new typeScalar(ID, size, convertCharToString(name));
1483                         //Add to Collection
1484                         newType = tc->addOrUpdateType((typeScalar *) newType);
1485                 } 
1486                 else 
1487                 {
1488                         /* range */
1489                         // //bperr("Type RANGE: ERROR!!\n");
1490                         errno = 0;
1491                         long low_conv = strtol(low, NULL, 10);
1492                         if (errno)
1493                         {
1494                                 fprintf(stderr, "%s[%d]:  error converting range limit '%s' to long: %s\n", 
1495                                                 FILE__, __LINE__, low, strerror(errno));
1496                                 low_conv = LONG_MIN;
1497                         }
1498
1499                         errno = 0;
1500                         long hi_conv = strtol(hi, NULL, 10);
1501                         if (errno)
1502                         {
1503                                 fprintf(stderr, "%s[%d]:  error converting range limit '%s' to long: %s\n", 
1504                                                 FILE__, __LINE__, hi, strerror(errno));
1505                                 hi_conv = LONG_MAX;
1506                         }
1507
1508                         if (baseType == NULL)
1509                                 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : sizeof(long), 
1510                                                 low_conv, hi_conv, tname);
1511                         else
1512                                 newType = new typeSubrange(ID, sizeHint ? sizeHint / 8 : baseType->getSize(), 
1513                                                 low_conv, hi_conv, tname);
1514                         newType = tc->addOrUpdateType((typeSubrange *) newType);
1515         }       
1516     }
1517     free(low);
1518     free(hi);
1519
1520     cnt = cnt + i;
1521     if( stabstr[cnt] == ';')
1522       cnt++;
1523     
1524     return(&(stabstr[cnt]));
1525 }
1526
1527 #endif
1528
1529 //
1530 //  <attrType> = @s<int>;<int>
1531 //  <attrType> = @s<int>;(<int>,<int>)
1532 //  <attrType> = @s<int>;r(<int>,<int>);<int>;<int>;
1533 //
1534
1535 //
1536 //   This may in fact be much simpler than first anticipated
1537 //   AIX stabs use attributes only as hints, and dbx only
1538 //   understands @s (size) and @P (packed) types.  We only 
1539 //   parse the size attribute, and should be able to get away
1540 //   with simply passing the remainder to the rest of our parser
1541 //
1542 static char *parseAttrType(Module *mod, const char *name,
1543                          int ID, char *stabstr, int &cnt)
1544 {
1545     assert(stabstr[cnt] == '@');
1546     cnt++; // skip the @
1547    
1548     if (stabstr[cnt] == 's') {
1549       cnt++;
1550       
1551       int size = parseSymDesc(stabstr, cnt);
1552       cnt++;  // skip ';'
1553
1554       char *newstr =  parseTypeDef(mod, stabstr+cnt, name, ID, size);
1555       if (newstr[0] == ';')
1556          return newstr+1;
1557       else
1558          return newstr;
1559     } else {
1560         ////bperr(" Unable to parse Type Attribute: %s ID %d : %s\n", 
1561         // name,ID, &(stabstr[cnt]));
1562        while (stabstr[cnt] != ';') cnt++;
1563        cnt++;
1564        return parseTypeDef(mod, stabstr+cnt, name, ID);
1565     }
1566 }
1567 /*
1568 static void parseAttrType(Module *mod, const char *name,
1569                          int ID, char *stabstr, int &cnt)
1570 {
1571     bool includesRange = false;
1572     char *low = NULL, *high = NULL;
1573
1574     // format @s(size in bits); negative type number;
1575     dataClass typdescr = dataTypeAttrib;
1576
1577     assert(stabstr[cnt] == '@');
1578     cnt++; // skip the @
1579
1580     if (stabstr[cnt] == 's') {
1581       cnt++;
1582       
1583       int size = parseSymDesc(stabstr, cnt);
1584       cnt++;  // skip ';'
1585
1586       if (stabstr[cnt] == 'r') {
1587           // include range at end
1588           cnt++;
1589           includesRange = true;
1590       }
1591
1592       int type = parseSymDesc(stabstr, cnt);
1593       // skip ';' end of stab record ??? (at least for bool)
1594       cnt++;
1595
1596       if (includesRange) {
1597           int len;
1598
1599           // Parse out low range string.
1600           len = 0;
1601           if (stabstr[cnt] == '-' ) cnt++, len++;
1602           while (isdigit(stabstr[cnt])) cnt++, len++;
1603           cnt++;    // skip ';'
1604
1605           // Store the low range string.
1606           low = (char *)malloc(sizeof(char) * (len + 1));
1607           assert(low);
1608           strncpy(low, &stabstr[cnt - (len + 1)], len);
1609           low[len] = '\0';
1610
1611           // Parse out high range string.
1612           len = 0;
1613           if (stabstr[cnt] == '-' ) cnt++, len++;
1614           while (isdigit(stabstr[cnt])) cnt++, len++;
1615           cnt++;    // skip ';'
1616
1617           // Store the high range string.
1618           high = (char *)malloc(sizeof(char) * (len + 1));
1619           assert(high);
1620           strncpy(high, &stabstr[cnt - (len + 1)], len);
1621           high[len] = '\0';
1622       }
1623
1624       // Create a new B_type that points to a builtInTypes
1625       Type *ptrType =BPatch::bpatch->builtInTypes->findBuiltInType(type);
1626       
1627       if (!ptrType) ptrType = BPatch::bpatch->type_Untyped;
1628       
1629       Type *newType = new Type(name, ID, typdescr, size/8, ptrType);
1630       if(!newType) {
1631             //bperr(" Can't Allocate new type ");
1632             exit(-1);
1633       }
1634
1635       if (includesRange) {
1636           newType->setLow(low);
1637           newType->setHigh(high);
1638           free(low);
1639           free(high);
1640       }
1641
1642       // Add type to collection
1643       newType2 = tc->addOrUpdateType(newType);
1644
1645       if (stabstr[cnt]) {
1646           //bperr("More Type Attribute to Parse: %s ID %d : %s\n", name,
1647                ID, &(stabstr[cnt]));
1648           //bperr("got type = %d\n", type);
1649           //bperr("full string = %s\n", stabstr);
1650       }
1651     } else {
1652         ////bperr(" Unable to parse Type Attribute: %s ID %d : %s\n", 
1653         // name,ID, &(stabstr[cnt]));
1654     }
1655 }
1656 */
1657 //
1658 //  <refType> = &<typeUse>
1659 //
1660 static char *parseRefType(Module *mod, const char *name,
1661                    int ID, char *stabstr, int &cnt)
1662 {
1663     /* reference to another type */
1664     assert(stabstr[cnt] == '&');
1665     cnt++;
1666     
1667     int refID = parseTypeUse(mod, stabstr, cnt, name);
1668     
1669     // Create a new B_type that points to a structure
1670         typeCollection *tc = typeCollection::getModTypeCollection(mod);
1671     Type *ptrType = tc->findOrCreateType(refID);
1672     if (!ptrType) ptrType = Symtab::type_Untyped().get();
1673     std::string tName = convertCharToString(name); 
1674     typeRef *newType = new typeRef(ID, ptrType, tName);
1675
1676     // Add to typeCollection
1677     newType = tc->addOrUpdateType(newType);
1678     
1679     return(&(stabstr[cnt]));
1680 }
1681
1682 //
1683 // Given a base class and a new type, add all visible fields to the new class
1684 //
1685 void addBaseClassToClass(Module *mod, int baseID, 
1686                          fieldListType *newType, int /*offset*/)
1687 {
1688
1689         typeCollection *tc = typeCollection::getModTypeCollection(mod);
1690
1691     //Find base class
1692     fieldListType *baseCl = dynamic_cast<fieldListType *>(tc->findType(baseID));
1693     if( ! baseCl ) {
1694         std::string modName = mod->fileName();
1695         //bpwarn( "can't find base class id %d in module %s\n", baseID, modName);
1696         baseCl = new typeStruct(baseID);
1697         fieldListType *baseCl2 = dynamic_cast<typeStruct *>(tc->addOrUpdateType( (typeStruct *)baseCl ));
1698         std::string fName = "{superclass}";
1699         newType->addField( fName, baseCl2, -1, visUnknown );
1700         baseCl->decrRefCount();
1701         return;
1702     }
1703     std::string fName = "{superclass}";
1704     newType->addField( fName, baseCl, -1, visUnknown );
1705
1706     //Get field descriptions of the base type
1707     /*
1708     const std::vector<Field *> *baseClFields = baseCl->getComponents();
1709     for (unsigned int fieldNum=0; fieldNum < baseClFields->size(); fieldNum++) {
1710         Field *field = (*baseClFields)[fieldNum];
1711
1712         if (field->getVisibility() == visPrivate)
1713             continue; //Can not add this member
1714
1715         newType->addField(field->getName(), field->getTypeDesc(), field->getType(), field->getOffset()+offset, field->getVisibility());
1716     }
1717     */
1718 }
1719
1720 //
1721 // parse a list of fields.
1722 //    Format is [A|B|C-M|N|O][c][G]<fieldName>:<type-desc>;offset;size;
1723 //
1724 static char *parseFieldList(Module *mod, fieldListType *newType, 
1725                 char *stabstr, bool sunCPlusPlus)
1726 {
1727         int cnt = 0;
1728         int size = 0;
1729         char *compname;
1730         int comptype= 0;
1731         int beg_offset=0;
1732         visibility_t _vis = visUnknown;
1733         dataClass typedescr;
1734         bool hasVirtuals = false;
1735         typeCollection *tc = typeCollection::getModTypeCollection(mod);
1736         assert(tc);
1737
1738         if (stabstr[cnt] == '!') 
1739         {
1740                 //Inheritance definition, Add base class field list to the current one
1741                 //according to visibility rules.
1742
1743                 cnt++; //Skip '!'
1744
1745                 //Get # of base classes
1746                 int baseClNum = atoi(getIdentifier(stabstr, cnt).c_str());
1747                 cnt++; //Skip ','
1748
1749                 typeStruct *newStructType = dynamic_cast<typeStruct *>(newType);
1750                 //Skip information for each base class
1751                 for (int i=0; i<baseClNum; ++i) 
1752                 {
1753                         //Skip virtual inheritance flag, base visibility flag and base offset
1754                         getIdentifier(stabstr, cnt);
1755                         cnt++; //Skip ','
1756
1757                         //Find base class type identifier
1758                         int baseID = parseSymDesc(stabstr, cnt);
1759
1760                         cnt++; //Skip ';'
1761
1762                         addBaseClassToClass(mod, baseID, newStructType, 0);
1763                 }
1764         }
1765
1766         while (stabstr[cnt] && (stabstr[cnt] != ';')) 
1767         {
1768                 typedescr = dataScalar;
1769
1770                 if (stabstr[cnt] == '~') 
1771                 {
1772                         //End of virtual class
1773                         while (stabstr[cnt] != ';') cnt++;
1774                         break; //End of class is reached
1775                 }
1776
1777                 // skip <letter>cG
1778                 if (sunCPlusPlus) cnt += 3;
1779
1780                 if ((stabstr[cnt] == 'u') && (stabstr[cnt+1] == ':') && (!isdigit(stabstr[cnt+2]))) 
1781                 {
1782                         cnt += 2;
1783                 }
1784
1785                 compname = getFieldName(stabstr, cnt);
1786
1787                 /*
1788                    if (strlen(compname) == 0) {
1789                 //Something wrong! Most probably unhandled C++ type
1790                 //Skip the rest of the structure
1791                 while(stabstr[cnt]) cnt++;
1792                 return(&stabstr[cnt]);
1793                 }
1794                  */
1795                 cnt++;  // Skip ":"
1796
1797                 if ((stabstr[cnt]) == ':') 
1798                 {
1799                         //Method definition
1800                         typedescr = dataFunction;
1801                         cnt++;
1802                 }
1803
1804                 if ((stabstr[cnt]) == '/') 
1805                 { // visibility C++
1806                         cnt++; /* get '/' */
1807                         switch (stabstr[cnt]) {
1808                                 case '0':
1809                                         _vis = visPrivate;
1810                                         break;
1811                                 case '1':
1812                                         _vis = visProtected;
1813                                         break;
1814                                 case '2':
1815                                         _vis = visPublic;
1816                                         break;
1817                                 default:
1818                                         _vis = visUnknown;
1819                         }
1820                         cnt++; // get visibility value
1821                 }
1822
1823                 // should be a typeDescriptor
1824                 comptype = parseTypeUse(mod, stabstr, cnt, "");
1825
1826                 if (stabstr[cnt] == ':') 
1827                 {
1828                         while (stabstr[cnt] == ':') 
1829                         {
1830                                 cnt++; //Discard ':'
1831                                 beg_offset = 0;
1832                                 size = 0;
1833                                 std::string varName = getIdentifier(stabstr, cnt);
1834
1835                                 if (typedescr == dataFunction) 
1836                                 {
1837                                         // Additional qualifiers for methods
1838                                         cnt++; //Skip ';'
1839                                         cnt++; //Skip visibility
1840                                         cnt++; //Skip method modifier
1841                                         if (stabstr[cnt] == '*') 
1842                                         {
1843                                                 //Virtual fcn definition
1844                                                 hasVirtuals = true;
1845                                                 cnt++; //Skip '*'
1846                                                 while(stabstr[cnt] != ';') cnt++; //Skip vtable index
1847                                                 cnt++; //Skip ';'
1848                                                 if (stabstr[cnt] != ';') 
1849                                                 {
1850                                                         parseTypeUse(mod, stabstr, cnt, ""); //Skip type number to the base class
1851                                                 }
1852                                                 cnt++; //Skip ';'
1853                                                 if (isSymId(stabstr[cnt])) 
1854                                                 {
1855                                                         parseTypeUse(mod, stabstr, cnt, "");
1856                                                 }
1857                                         } else if (   (stabstr[cnt] == '.') 
1858                                                            || (stabstr[cnt] == '?') ) 
1859                                         {
1860                                                 cnt++; //Skip '.' or '?'
1861                                                 if (isSymId(stabstr[cnt])) 
1862                                                 {
1863                                                         parseTypeUse(mod, stabstr, cnt, "");
1864                                                 }
1865                                         }
1866                                 }
1867
1868                                 if (stabstr[cnt] == ';')
1869                                         cnt++; //Skip ';'
1870                         }
1871                 } 
1872                 else if (stabstr[cnt] == ',') 
1873                 {
1874                         cnt++;  // skip ','
1875                         beg_offset = parseSymDesc(stabstr, cnt);
1876
1877                         if (stabstr[cnt] == ',') 
1878                         {
1879                                 cnt++;  // skip ','
1880                                 size = parseSymDesc(stabstr, cnt);
1881                         }
1882                         else
1883                                 size = 0;
1884                 }
1885
1886                 if (stabstr[cnt] == ';') // jaw 03/15/02-- major kludge here for DPCL compat
1887                         cnt++;  // needs further examination
1888
1889                 // //bperr("\tType: %d, Starting Offset: %d (bits), Size: %d (bits)\n", comptype, beg_offset, size);
1890                 // Add struct field to type
1891
1892                 Type *fieldType = tc->findOrCreateType( comptype );
1893                 if (fieldType == NULL) 
1894                 {
1895                         //C++ compilers may add extra fields whose types might not available.
1896                         //Assign void type to these kind of fields. --Mehmet
1897                         fieldType = tc->findType("void");
1898                 }
1899                 std::string fName = convertCharToString(compname);
1900                 if (_vis == visUnknown) 
1901                 {
1902                         newType->addField(fName, fieldType, beg_offset);
1903                 } 
1904                 else 
1905                 {
1906                         // //bperr( "Adding field '%s' to type '%s' @ 0x%x\n", compname, newType->getName(), newType );
1907                         newType->addField(fName, fieldType, beg_offset, _vis);
1908                         ////bperr("Adding Component with VISIBILITY STRUCT\n");
1909                 }
1910                 free(compname);
1911         }
1912
1913         if (hasVirtuals && 
1914                         stabstr[cnt] == ';' &&
1915                         stabstr[cnt+1] == '~' &&
1916                         stabstr[cnt+2] == '%') 
1917         {
1918                 cnt+=3;
1919                 while (stabstr[cnt] != ';') cnt++;
1920         }         
1921
1922         // should end with a ';'
1923         if (stabstr[cnt] == ';') 
1924         {
1925                 return &stabstr[cnt+1];
1926         } 
1927         else if (stabstr[cnt] == '\0') 
1928         {
1929                 return &stabstr[cnt];
1930         } 
1931         else 
1932         {
1933                 //bperr("invalid stab record: %s\n", &stabstr[cnt]);
1934                 abort();
1935                 return NULL; // should not get here
1936         }
1937 }
1938
1939
1940 //
1941 //      Y<type><size><className>;<Bases>;<DataMembers>;<MemberFunctions>;<StaticDataMembers>;
1942 //              <Friends>;<VirtualFunctionInfo>;<NestedClassList>;<AccessAdjustments>;
1943 //              <VirtualBaseClassOffsets>;<TemplatmentMembers>;<PassMethod>;
1944 //
1945 static char *parseCPlusPlusInfo(Module *mod,
1946                 char *stabstr, const char *mangledName, int ID)
1947 {
1948         typeCollection *tc = typeCollection::getModTypeCollection(mod);
1949         int cnt;
1950         char *name;
1951         int structsize;
1952     bool sunStyle = true;
1953     bool nestedType = false;
1954     dataClass typdescr;
1955     fieldListType * newType = NULL, *newType2 = NULL;
1956
1957     assert(stabstr[0] == 'Y');
1958     cnt = 1;
1959
1960     // size on AIX 
1961     if (isdigit(stabstr[cnt])) {
1962         structsize = parseSymDesc(stabstr, cnt);
1963         sunStyle = false;
1964     }
1965
1966     switch(stabstr[cnt]) {
1967         case 'C':
1968         case 'c':
1969             typdescr = dataTypeClass;
1970             break;
1971
1972         case 'S':
1973             nestedType = true;
1974         case 's':
1975             typdescr = dataStructure;
1976             break;
1977
1978         case 'U':
1979             nestedType = true;
1980         case 'u':
1981             typdescr = dataUnion;
1982             break;
1983
1984         case 'n':       // namespace - ignored
1985             cnt = strlen(stabstr);
1986             return(&(stabstr[cnt]));
1987             break;
1988
1989         default:
1990             //bperr( "ERROR: Unrecognized C++ str = %s\n", stabstr);
1991             cnt = strlen(stabstr);
1992             return(&(stabstr[cnt]));
1993             break;
1994     }
1995
1996     cnt++;              // skip to size
1997     if (isdigit(stabstr[cnt])) {
1998         structsize = parseSymDesc(stabstr, cnt);
1999     }
2000     
2001     if (stabstr[cnt] == 'V') cnt++;
2002     if (stabstr[cnt] == '(') cnt++;
2003
2004     if (sunStyle && (stabstr[cnt] != ';')) {
2005         int len;
2006         char *n;
2007
2008         // Class or Type Name
2009         n = &stabstr[cnt];
2010         while (stabstr[cnt] != ';') cnt++;
2011         len = &stabstr[cnt] - n;
2012         name = (char *) calloc(len + 1, sizeof(char));
2013         strncpy(name, n, len);
2014     } else {
2015         name = const_cast< char * >( mangledName );
2016     }
2017
2018     std::string tName = convertCharToString(name);
2019     //Create new type
2020     switch (typdescr) {
2021     case dataTypeClass:
2022     case dataStructure:
2023        newType = new typeStruct(ID, tName);
2024        newType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeStruct *) newType));
2025        break;
2026     case dataUnion:
2027        newType = new typeUnion(ID, tName);
2028        newType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeUnion *) newType));
2029        break;
2030     default:
2031        assert(0);
2032     }
2033     //add to type collection
2034
2035     if(newType2 != newType)
2036         newType->decrRefCount();
2037
2038     if (sunStyle) {
2039         cnt++;
2040         // base class(es) 
2041         while (stabstr[cnt] != ';') {
2042             // skip visibility flag
2043             cnt++;
2044
2045             int offset = parseSymDesc(stabstr, cnt);
2046
2047             // Find base class type identifier
2048             int baseID = parseSymDesc(stabstr, cnt);
2049             addBaseClassToClass(mod, baseID, newType2, offset);
2050         }
2051
2052         cnt++;  // skip ;
2053     }
2054
2055     // parse dataMembers
2056     stabstr = parseFieldList(mod, newType2, &stabstr[cnt], sunStyle);
2057     cnt = 0;
2058
2059     if (stabstr[0]) {
2060         // parse member functions
2061         cnt++;
2062         while (stabstr[cnt] && (stabstr[cnt] != ';')) {
2063             std::string pd_funcName = getIdentifier(stabstr, cnt, true);
2064             const char *funcName = pd_funcName.c_str();
2065
2066             funcName++; // skip ppp-code
2067
2068             if (*funcName == '-') funcName++; // it's a pure vitual
2069
2070             while (isdigit(*funcName)) funcName++; // skip virtual function index
2071             funcName++;
2072
2073             char *className = strdup(currentRawSymbolName.c_str());
2074             className[3] = 'c';
2075             className[strlen(className)-1] = '\0';      // remove tailing "_"
2076             std::string methodName = std::string(className) + std::string(funcName) + std::string("_");
2077                 char * name = P_cplus_demangle( methodName.c_str(), mod->exec()->isNativeCompiler() );
2078                 if( name != NULL ) {
2079                         funcName = strrchr( name, ':' );
2080                         if( funcName ) { funcName++; }
2081                         else { funcName = name; }
2082                         }
2083
2084             // should include position for virtual methods
2085             Type *fieldType = tc->findType("void");
2086
2087             std::string fName = convertCharToString(funcName);
2088
2089             typeFunction *funcType = new typeFunction( ID, fieldType, fName);
2090             newType2->addField( fName, funcType);
2091                                             
2092             free(name);
2093             free(className);
2094             if (stabstr[cnt] == ' ') cnt++;
2095         }
2096     }
2097
2098     cnt = strlen(stabstr);
2099     return(&(stabstr[cnt]));
2100 }
2101
2102 //
2103 // This function takes a <typeDef> and parses it 
2104 //
2105 //      <typeDef> = <symDesc>   |
2106 //              <crossRef>      |       
2107 //              *<typeUse>      |       Pointer to a type
2108 //              <arrayDef>      |
2109 //              f<typeUse>      |       function type
2110 //              R<int>,<int>    |       Real type 
2111 //              b[u|s][c|]<int>;<int>;<int>     |       Builtin
2112 //              <rangeType>     |
2113 //              e<enumType>     |
2114 //              <attrType>      |
2115 //              <refType>       |
2116 //              k<typeDef>      |       SunPro constant
2117 //              B<typeDef>      |       SunPro volatile
2118 //              M<symDesc>;<int>|       Fortran CHARACTER array
2119 //              s<int><fields>  |       Structure <int> is size
2120 //              u<int><fields>  |       Union <int> is size
2121 //              V<typeUse>
2122 //
2123 //      <enumType> = <ident>:<int> | <ident>:<int>,<enumType>
2124 //
2125 // It adds the typeDef to the type definition with the name name, and id ID.
2126 //
2127 static char *parseTypeDef(Module *mod, char *stabstr, 
2128                           const char *name, int ID, unsigned int sizeHint)
2129 {
2130         typeCollection *tc = typeCollection::getModTypeCollection(mod);
2131     Type * newType = NULL;
2132     fieldListType * newFieldType = NULL, *newFieldType2 = NULL;
2133     Type * ptrType = NULL;
2134   
2135     std::string compsymdesc;
2136   
2137     dataClass typdescr;
2138     int ptrID=0;
2139     
2140     int value;
2141     int cnt,i,j,k;
2142     int structsize;
2143     int type;
2144     cnt = i = j = k = 0;
2145
2146     assert (stabstr[0] != '=');
2147
2148     // //bperr( "parsing %s\n", stabstr);
2149     if (isSymId(stabstr[0])) 
2150         {
2151         typdescr = dataScalar;
2152         type = parseSymDesc(stabstr, cnt);
2153                     
2154     if (ID == type) 
2155         {
2156         // Type:tFOO = FOO
2157         // as far as I can tell, this only happens when defining an empty
2158         // type (i.e. void)
2159
2160         std::string tName = convertCharToString(name);
2161         newType = new typeScalar(ID, 0, tName);
2162                 newType = tc->addOrUpdateType((typeScalar *) newType); 
2163     } 
2164         else if (stabstr[cnt] == '=') 
2165         {
2166         // XXX - in the new type t(0,1)=(0,2)=s... is possible
2167         //           skip the second id for now -- jkh 3/21/99
2168         stabstr = parseTypeDef(mod, &(stabstr[cnt+i+1]), name, type);
2169         cnt = 0;
2170         Type *oldType;
2171
2172         oldType = tc->findOrCreateType(type);
2173         if (!oldType) oldType = Symtab::type_Untyped().get();
2174         std::string tName = convertCharToString(name);
2175         newType = new typeTypedef(ID, oldType, tName, sizeHint);
2176                 tc->addOrUpdateType((typeTypedef *) newType);
2177
2178         } 
2179         else 
2180         {
2181                 Type *oldType;
2182         std::string tName = convertCharToString(name);
2183         oldType = tc->findOrCreateType(type);
2184         newType = new typeTypedef(ID, oldType, tName, sizeHint);
2185         newType = tc->addOrUpdateType((typeTypedef *) newType);
2186     }
2187     } else {
2188       switch (stabstr[0]) {
2189           case 'x':  //cross reference 
2190           {
2191             parseCrossRef(tc, name, ID, stabstr, cnt);
2192             break;
2193           }   
2194           case '*':
2195           {
2196             /* pointer to another type */
2197             cnt++;
2198             ptrID = parseTypeUse(mod, stabstr, cnt, NULL);
2199
2200             // Create a new B_type that points to a structure
2201             ptrType = tc->findOrCreateType(ptrID);
2202             if (!ptrType) ptrType = Symtab::type_Untyped().get();
2203
2204             newType = new typePointer(ID, ptrType);
2205             // Add to typeCollection
2206             newType = tc->addOrUpdateType((typePointer *) newType);
2207             return(&(stabstr[cnt]));
2208             break;
2209           }
2210           case 'a':
2211       case 'A':
2212           {
2213               (void) parseArrayDef(mod, name, ID, stabstr, cnt, sizeHint);
2214               return (&stabstr[cnt]);
2215               break;
2216       }
2217       case 'g':  
2218           {
2219                 /* function with return type and prototype */
2220
2221                 // g<typeUse>[<typeUse>]*#
2222                 typdescr = dataFunction;
2223
2224                 cnt++; /* skip the g */
2225                 type = parseTypeUse(mod, stabstr, cnt, name);
2226                 ptrType = tc->findOrCreateType(type);
2227
2228                 {
2229                    std::string tName = convertCharToString(name);
2230                    typeFunction *newFunction = 
2231                       new typeFunction(ID, ptrType, tName);
2232                    typeFunction *newFunction2 = NULL;
2233                    
2234                    if (newFunction) { 
2235                       newFunction2 = dynamic_cast<typeFunction*>(tc->addOrUpdateType(newFunction)); 
2236                       if(newFunction2 != newFunction)
2237                               newFunction->decrRefCount();
2238                    }
2239                    if (!newFunction2) {
2240                       //bpfatal(" Can't Allocate new type ");
2241                             types_printf("%s[%d]: parseTypeDef: unable to allocate newType\n", FILE__, __LINE__);
2242                             //exit(-1);
2243                    }
2244                    
2245                    while ((stabstr[cnt] != '#') &&  (stabstr[cnt])) {
2246                       int paramType;
2247                       paramType = parseTypeUse(mod, stabstr, cnt, name);
2248                       newType = tc->findOrCreateType(paramType);
2249                       newFunction2->addParam(newType);
2250                       //newFunction2->addField(buffer, newType->getDataClass(), newType, curOffset, newType->getSize());
2251                    }
2252                 }
2253
2254                 // skip #
2255                 if (stabstr[cnt] == '#') cnt++;
2256                 break;
2257           }
2258           case 'f':
2259           {
2260                 /* function type */
2261                 typdescr = dataFunction;
2262
2263                 cnt++; /* skip the f */
2264                 type = parseTypeUse(mod, stabstr, cnt, name);
2265                 ptrType = tc->findOrCreateType(type);
2266
2267                 
2268                 std::string tName = convertCharToString(name);
2269                 newType = new typeFunction(ID, ptrType, tName);
2270                 newType = tc->addOrUpdateType((typeFunction *) newType);
2271
2272                 // skip to end - SunPro Compilers output extra info here - jkh 6/9/3
2273                 // cnt = strlen(stabstr);
2274                 break;
2275          }
2276
2277          case 'M': 
2278          {
2279                 /* CHARACTER ??? */
2280                 cnt++; // skip  'M'
2281
2282                 int baseType = parseSymDesc(stabstr, cnt);
2283                 if (baseType != -2 || (stabstr[cnt] != ';')) {
2284                     //bperr("unexpected non character array %s\n", stabstr);
2285                 } else {
2286                     cnt++; // skip ';'
2287                     int size;
2288                     if (stabstr[cnt] == 'T') {
2289                       /* Fortran stack-based array bounds */
2290                       size = 0;
2291                       cnt++; // skip 'T'
2292                       (void) parseSymDesc(stabstr, cnt);
2293                     } else if (stabstr[cnt] == 'J') {
2294                       /* Unbounded range */
2295                       size = 0;
2296                       cnt++; // skip 'J';
2297                       (void) parseSymDesc(stabstr, cnt);
2298                     } else
2299                       size = parseSymDesc(stabstr, cnt);
2300
2301                     ptrType = tc->findOrCreateType(baseType);
2302                     std::string tName = convertCharToString(name);
2303
2304                     Type *newAType = new typeArray(ID, ptrType, 1, size, tName);
2305                     newType = tc->addOrUpdateType((typeArray* ) newAType);
2306                 }
2307                 break;
2308
2309          }
2310          case 'R': 
2311          {
2312                 // Define a floating point type - R fp-type; bytes;
2313                 cnt++;
2314                 (void) parseSymDesc(stabstr, cnt);
2315                 cnt ++;
2316
2317                 int bytes = parseSymDesc(stabstr, cnt);
2318
2319                 newType = new typeScalar(ID, bytes, name);
2320                 newType = tc->addOrUpdateType((typeScalar *) newType);
2321
2322                 if (stabstr[cnt] == ';') cnt++; // skip the final ';'
2323
2324                 // gcc 3.0 adds an extra field that is always 0 (no indication in the code why)
2325                 if (stabstr[cnt] == '0') cnt += 2;      // skip the final '0;'
2326
2327                 break;
2328           }
2329
2330           case 'b': 
2331           {
2332                 // builtin type b  - signed char-flag width; offset; nbits
2333                 int limit = strlen(&stabstr[cnt]);
2334
2335                 // skip to width
2336                 while (!isdigit(stabstr[cnt+i]) && (i < limit)) i++;    
2337                 if (i >= limit) return(&(stabstr[cnt]));
2338
2339                 cnt += i;
2340                 int size = parseSymDesc(stabstr,cnt);
2341                 cnt -= i;
2342                 i++;    // skip the ';'
2343
2344                 // skip to bits
2345                 while (stabstr[cnt+i] != ';' && (i < limit)) i++;       
2346                 if (i >= limit) return(&(stabstr[cnt]));
2347                 i++;
2348
2349                 cnt += i;
2350                 parseSymDesc(stabstr, cnt);
2351                 
2352                 if (stabstr[cnt]) cnt++;        // skip the final ';'
2353
2354                 newType = new typeScalar(ID, size, name);
2355                 //Add to Collection
2356                 newType = tc->addOrUpdateType((typeScalar *) newType);
2357
2358                 return &stabstr[cnt];
2359                 break;
2360         }
2361         case 'r':               // range type
2362         {    
2363             return parseRangeType(mod, name, ID, stabstr, sizeHint);
2364             break;
2365         }
2366         case 'e':               // Enumerated type
2367         {
2368             cnt++;      /* skip the 'e' */
2369
2370             // Create new Enum type
2371             std::string tName = convertCharToString(name);
2372             typeEnum *newEnumType = new typeEnum(ID, tName);
2373             // Add type to collection
2374             newEnumType = dynamic_cast<typeEnum *>(tc->addOrUpdateType(newEnumType));
2375                 
2376             while (stabstr[cnt]) {
2377                 /* Get enum component value */
2378                 compsymdesc = getIdentifier(stabstr, cnt);
2379                 cnt++; /* skip colon */
2380
2381 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
2382                 //bperr( "%s[%d]:  before parseSymDesc -- enumerated type \n", 
2383             //          __FILE__, __LINE__);
2384 #endif            
2385                 value = parseSymDesc(stabstr, cnt);
2386
2387                 // add enum field to type
2388                 newEnumType->addConstant(compsymdesc, value);
2389                   
2390                 cnt++; /* skip trailing comma */
2391                 if ((stabstr[cnt]) == ';') cnt++; /* End of enum stab record */
2392             }
2393             break;
2394         }    
2395         case '@':  // type attribute, defines size and type (negative num)
2396         {
2397             return parseAttrType(mod, name, ID, stabstr, cnt);
2398             break;
2399         }
2400         case '&': //XXX- Need to complete, may be more to parse jdd 4/22/99
2401         {    
2402             return parseRefType(mod, name, ID, stabstr, cnt);
2403             break;
2404         }
2405         case 'k':       // Sun constant type s<typeDef> - parse as <typeDef>
2406         {
2407             return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
2408             break;
2409         }
2410         case 'V':       // AIX colatile ? type V<typeDef> - parse as <typeDef>
2411         case 'B':       // Sun volatile type B<typeDef> - parse as <typeDef>
2412             return parseTypeDef(mod, &stabstr[cnt+1], name, ID);
2413             break;
2414
2415         case 's':       // struct
2416         case 'u':       // union
2417     case 'T':   // Fortran TYPE
2418         {    
2419             /* Type descriptor */
2420             if (stabstr[cnt] == 's' || stabstr[cnt] == 'T') {
2421                 typdescr = dataStructure;
2422             } else {
2423                 typdescr = dataUnion;
2424             }
2425
2426             cnt++;              // skip to size
2427             structsize = parseSymDesc(stabstr, cnt);
2428            
2429             std::string tName = convertCharToString(name);
2430             //Create new type
2431             if (typdescr == dataStructure) {
2432                newFieldType = new typeStruct(ID, tName);
2433                newFieldType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeStruct *) newFieldType));
2434             }
2435             else {
2436                newFieldType = new typeUnion(ID, tName);
2437                newFieldType2 = dynamic_cast<fieldListType *>(tc->addOrUpdateType((typeUnion *) newFieldType));
2438             }
2439             //add to type collection
2440
2441         //TODO What if two different files have the same structure?? // on AIX
2442         if(!newFieldType2)
2443                 newFieldType2 = dynamic_cast<fieldListType *>(newFieldType);
2444         if(newFieldType2 != newFieldType)
2445             newFieldType->decrRefCount();
2446             char *ret = parseFieldList(mod, newFieldType2, &stabstr[cnt], false);
2447         return ret;
2448
2449             break;
2450         }
2451         case 'Y':
2452         {
2453             // C++ specific stabs (Sun compiler)
2454             return parseCPlusPlusInfo(mod, stabstr, name, ID);
2455             break;
2456         }
2457         case 'Z':  // What is this ??? - jkh 10/14/99 (xlc compiler uses it)
2458         {    
2459             return (&stabstr[1]);
2460             break;
2461         }
2462         case '#':
2463         {
2464             //Class method definition
2465             cnt++; //Skip '#'
2466             if (stabstr[cnt] == '#') {
2467                 //Get return type
2468                 cnt++; //Skip '#'
2469                 parseTypeUse(mod, stabstr, cnt, name);
2470             }
2471             else {
2472                 while(1) {
2473                         //Skip class type, return typ and arg types
2474                         parseTypeUse(mod, stabstr, cnt, name);
2475                         if (stabstr[cnt] == ',')
2476                                 cnt++;
2477                         else if (stabstr[cnt] == ';')
2478                                 break;
2479                 }
2480             }
2481
2482             cnt++; //Skip ';'
2483             return(&(stabstr[cnt]));
2484             break;
2485         }
2486         default:
2487             //bperr( "ERROR: Unrecognized str = %s\n", &stabstr[cnt]);
2488             //      return NULL;
2489             // Null probably isn't the right choice here.
2490             cnt = strlen(stabstr);
2491             break;
2492       }
2493     }
2494
2495     return(&(stabstr[cnt]));
2496 } /* end of parseTypeDef*/
2497
2498 //
2499 // parseConstantUse - parse a constant (used by Fortran PARAMETERS)
2500 //
2501 // <constantUse> = =i<int> |
2502 //                 =r <float>
2503 //
2504 //
2505 static Type *parseConstantUse(Module *mod, char *stabstr, int &cnt)
2506 {
2507         typeCollection *tc = typeCollection::getModTypeCollection(mod);
2508     // skip =
2509     cnt++;
2510
2511     Type *ret;
2512
2513     if (stabstr[cnt] == 'i') {
2514         ret = tc->findType("integer*4");
2515     } else if (stabstr[cnt] == 'r') {
2516         ret = tc->findType("double");
2517     } else if (stabstr[cnt] == 's') {
2518         ret = tc->findType("char *");
2519     } else {
2520         //bperr("unknown constant type %s\n", &stabstr[cnt]);
2521         ret = NULL;
2522     }
2523
2524     cnt = strlen(stabstr);
2525
2526     return ret;
2527 }
2528