From: pfieland@cyclonic.sw.stratus.com (Peggy Fieland)
Subject: (none)
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 12 Aug 1992 19:32:13 GMT

For gdb-4.6 (on a Sun sparc or Stratus FTX), even when demangle-style
is set to cfront, the name of the virtual table is not demangled.

Here is a sample debugging session:

cyclonic-tests% gdb46 zoo
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.6, Copyright 1992 Free Software Foundation, Inc...
(gdb) set demangle-style cfront
(gdb) info var
All defined variables:

File zoo.c:
struct __mptr *__ptbl_vec__zoo_c_insert_[4];
struct __mptr Bear::__vtbl[5];
struct __mptr Lion::__vtbl[5];
struct __mptr Buffalo::__vtbl[5];
struct __mptr __vtbl__9ZooAnimal__zoo_c[5];
static struct Lion *__0__F13;
static struct Bear *__0__F14;
static struct Buffalo *__0__F15;
static struct ZooList alist;

Non-debugging symbols:
        00004000  _DYNAMIC
        000040b8  environ
        000040c0  _ctors
        000043b0  _dtors
        000043b8  _new_handler
        000043c0  edata
        000049e8  end

Here is the test program (unfortunately, somewhat long)

extern "C" printf(...);


// Example of virtual functions, class inheritance and overloading!
// By Farooq Butt


 extern "C" {                   // Get the C "strcpy" function
strcpy(char *,char *);
 }


enum fruit { apple, orange, banana };              // Herbivore foods 
enum meat  { rawsteak, bones, groundbeef };        // Carnivore foods


class ZooAnimal {
   public: 
   
   ZooAnimal(){ printf( "creating a ZooAnimal \n"); strcpy (mytype,"ZooAnimal");}

   virtual void draw()     { printf( "Generic Zoo Animal\n"); }
   virtual void feed(fruit){ printf( "Can't feed a generic Zoo Animal\n");}
   virtual void feed(meat) { printf( "Can't feed a generic Zoo Animal\n");}

   private:
   char mytype[255]; 
   }; 


class Bear : public ZooAnimal {

   public:

   Bear (char *whoami = "bear"){strcpy(mytype,whoami);}

   void draw();
   void feed(fruit);
   void feed(meat);

   private:
   char mytype[255]; 
      
}; 


class Lion : public ZooAnimal{

   public:

   Lion (char *whoami = "lion"){strcpy(mytype,whoami);}

   void draw();
   void feed(fruit);
   void feed(meat);

   private:
   char mytype[255]; 
}; 

class Buffalo : public  ZooAnimal {

   public:

   Buffalo (char *whoami = "buffalo"){strcpy(mytype,whoami);}

   void draw();
   void feed(fruit);
   void feed(meat);

   private:
   char mytype[255]; 
}; 



// The ZooList is the list object while the ZooItem is the list item 
// object.  It is VERY important to differentiate between the two because
// a list is a functionally different thing from its components.


class ZooList;         // Forward declaration


class ListItem{

   friend class ZooList;     // i.e. Let the ZooList object get at privates
 
   public:
   ListItem(ZooAnimal *v){val = v; next =0;}

   private:
   ZooAnimal *val;
   ListItem *next; 
}; 

class ZooList{

   public: 
   ZooList(){thelist=0;}         // constructor 

   void insert(ZooAnimal*);       // interface 
   void traverse(); 

   private:
   ListItem *thelist;
}; 


void ZooList::insert(ZooAnimal* v)
      {
         ListItem *pt = new ListItem(v);

         pt->next = thelist;
         thelist = pt;

      }

void ZooList::traverse()
{
   if (thelist == 0)
      printf( "empty list\n");

   ListItem *pt = thelist;

   while (pt){
      pt->val->draw();

      pt->val->feed(apple);
      pt->val->feed(rawsteak);

      pt=pt->next;
   }
}



   
void Bear::draw()
{
   printf( "Grrrrrrraaawr I am a bear\n"); 
}

void Bear::feed(meat)
{
   printf( "YUM YUM, bears love meat!\n"); 
}

void Bear::feed(fruit)
{
   printf( "ECCCCHHH Bears can't eat fruit!\n"); 
}



void Lion::draw()
{
   printf( "Roooooaaaaar I am the king of the forest\n"); 
}

void Lion::feed(meat)
{
   printf( "YUM YUM, lions love meat!\n"); 
}

void Lion::feed(fruit)
{
   printf( "ECCCCHHH Lions can't eat fruit!\n"); 
}

void Buffalo::draw()
{
   printf( "Mooooooo I am the woolly plains-buffalo\n"); 
}

void Buffalo::feed(meat)
{
   printf( "YUK! How could you feed meat to a buffalo!\n");
}

void Buffalo::feed(fruit)
{
   printf( "YUM, got any more fruit there ? We buffalos love it!\n"); 
}

static ZooList alist;


main()
{

   static Lion a1; 
   static Bear a2; 
   static Buffalo a3; 

   a1.draw(); 
   a2.draw();
   a3.draw();

   printf( "\n"); 

   alist.insert(&a1);
   alist.insert(&a2);
   alist.insert(&a3);

   alist.traverse(); 
}
   
Here is a fix:

*** /home/tools/gnu/gdb-4.6/gdb/cplus-dem.c	Tue Jul 14 03:34:20 1992
--- cplus-dem.c	Mon Aug 10 09:58:32 1992
*** 191,196 ****
--- 196,204 ----
  static int
  gnu_special PARAMS ((string *, const char **, struct work_stuff *));
  
+ static int
+ cfront_special PARAMS ((string *, const char **, struct work_stuff *));
+ 
  static void
  string_need PARAMS ((string *, int));
  
***************
*** 926,945 ****
        /* Mangled name starts with "__".  Skip over any leading '_' characters,
  	 then find the next "__" that separates the prefix from the signature.
  	 */
!       while (*scan == '_')
! 	{
! 	  scan++;
! 	}
!       if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
! 	{
! 	  /* No separator (I.E. "__not_mangled"), or empty signature
! 	     (I.E. "__not_mangled_either__") */
! 	  success = 0;
! 	}
!       else
! 	{
! 	  demangle_function_name (declp, mangled, work, scan);
! 	}
      }
    else if (*(scan + 2) != '\0')
      {
--- 946,970 ----
        /* Mangled name starts with "__".  Skip over any leading '_' characters,
  	 then find the next "__" that separates the prefix from the signature.
  	 */
!        if ((current_demangling_style != cfront_demangling) ||
!            (cfront_special (declp, mangled, work) == 0))
!           {
!             
!              while (*scan == '_')
!                 {
!                    scan++;
!                 }
!              if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
!                 {
!                    /* No separator (I.E. "__not_mangled"), or empty signature
!                       (I.E. "__not_mangled_either__") */
!                    success = 0;
!                 }
!              else
!                 {
!                    demangle_function_name (declp, mangled, work, scan);
!                 }
!           }
      }
    else if (*(scan + 2) != '\0')
      {
***************
*** 1033,1038 ****
--- 1058,1124 ----
    return (success);
  }
  
+ /*
+ 
+ LOCAL FUNCTION
+ 
+ 	cfront_special -- special handling of gnu mangled strings
+ 
+ SYNOPSIS
+ 
+ 	static int
+ 	cfront_special (string *declp, const char **mangled,
+ 		     struct work_stuff *work)
+ 
+ 
+ DESCRIPTION
+ 
+ 	Process some special cfront style mangling forms that don't fit
+ 	the normal pattern.  For example:
+ 
+ 		__vtbl_
+ 
+  */
+ 
+ static int
+ cfront_special (declp, mangled, work)
+      string *declp;
+      const char **mangled;
+      struct work_stuff *work;
+ {
+   int n, i;
+   int success = 1;
+   const char *p;
+ 
+ /* account for __vtbl__  -- see above for differences in naming conventions */
+ #define MIN_VTABLE_STRLEN 8
+ #define MIN_OPERATOR_NAME_LEN   6
+    n = strlen(*mangled);
+    if ((n > MIN_VTABLE_STRLEN) && (! memcmp(*mangled,"__vtbl__",8)))
+     {
+       /* Found a cfront style virtual table, get past "__vtbl__
+          and create the decl.  Note that we consume the entire mangled
+ 	 input string, which means that demangle_signature has no work
+ 	 to do. */
+       (*mangled) += MIN_VTABLE_STRLEN;
+       get_count(mangled, &i);
+       if (i == 0)
+          success = 0;
+       else
+ 	{
+ 	  string_appendn (declp, *mangled, i);
+ 	  string_append (declp, " virtual table");
+        n = strlen (*mangled);
+       (*mangled) += n;
+ 	}
+     }
+   else
+     {
+       success = 0;
+     }
+   return (success);
+ }
+ 
  /* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
  
  static int

      

Newsgroups: gnu.gdb.bug