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