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