gdb-2.5.2
authorgdb-2.5.2 <gdb@fsf.org>
Wed, 1 Jun 1988 00:00:00 +0000 (01:00 +0100)
committerPedro Alves <palves@redhat.com>
Sun, 3 Jun 2012 14:36:30 +0000 (15:36 +0100)
13 files changed:
gdb/dbxread.c
gdb/expread.tab.c
gdb/expread.y
gdb/expression.h
gdb/gdb+.texinfo
gdb/symseg.h
gdb/symtab.c
gdb/symtab.h
gdb/valarith.c
gdb/valops.c
gdb/valprint.c
gdb/values.c
gdb/version.c

index c1c4acc5c9c92d9949d551abcf052163835eb927..05326cf5b402a1d5323f4ee733b84dd164eb2e6f 100644 (file)
@@ -1744,8 +1744,7 @@ condense_addl_misc_bunches ()
 }
 \f
 /**************************** ADD_FILE_COMMAND() ****************************/
-/* This function allows the addition of incrementally linked object files.
-   Useful for debugging `sun_kick'. */
+/* This function allows the addition of incrementally linked object files.  */
 
 void
 add_file_command (arg_string)
@@ -1762,116 +1761,107 @@ add_file_command (arg_string)
   char* name;
   unsigned text_addr;
 
+  if (arg_string == 0)
+    error ("add-file takes a file name and an address");
+
   for( ; *arg_string == ' '; arg_string++ );
   name = arg_string;
-  for( ; *arg_string != ' ' ; arg_string++ );
+  for( ; *arg_string && *arg_string != ' ' ; arg_string++ );
   *arg_string++ = (char) 0;
-  for( ; *arg_string == ' '; arg_string++ );
-  text_addr = (unsigned) atoi(arg_string);
 
-  printf("filename \"%s\", and text_addr = 0x%x\n", name, text_addr );
+  if (name[0] == 0)
+    error ("add-file takes a file name and an address");
+
+  text_addr = parse_and_eval_address (arg_string);
 
   dont_repeat ();
 
-  if (name == 0)
+  if (query ("add symbol table from filename \"%s\" at text_addr = 0x%x\n", name, text_addr))
     {
-      if (symtab_list && !query ("Discard symbol table? ", 0))
-       error ("Not confirmed.");
-      free_all_symtabs ();
-      return;
-    }
+      desc = open (name, O_RDONLY);
+      if (desc < 0)
+       perror_with_name (name);
 
-  /*    if (symtab_list && !query ("Add new symbols from \"%s\"? ", name))
-       error ("Not confirmed.");
-       */
-  {
-    char *absolute_name;
-    desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
-    if (desc < 0)
-      perror_with_name (name);
-    else
-      name = absolute_name;
-  }
+      old_chain = make_cleanup (close, desc);
+      make_cleanup (free_current_contents, &name);
 
-  old_chain = make_cleanup (close, desc);
-  make_cleanup (free_current_contents, &name);
+      val = myread (desc, &hdr, sizeof hdr);
+      if (val < 0)
+       perror_with_name (name);
 
-  val = myread (desc, &hdr, sizeof hdr);
-  if (val < 0)
-    perror_with_name (name);
+      if (N_BADMAG (hdr))
+       error ("File \"%s\" has a bad header.", name);
 
-  if (N_BADMAG (hdr))
-    error ("File \"%s\" has a bad header.", name);
+      if (hdr.a_syms == 0)
+       {
+         printf ("%s does not have a symbol-table.\n", name);
+         fflush (stdout);
+         return;
+       }
 
-  if (hdr.a_syms == 0)
-    {
-      printf ("%s does not have a symbol-table.\n", name);
+      /* Now read the string table, all at once.  */
+      val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0);
+      if (val < 0)
+       perror_with_name (name);
+      val = myread (desc, &buffer, sizeof buffer);
+      if (val < 0)
+       perror_with_name (name);
+      stringtab = (char *) alloca (buffer);
+      bcopy (&buffer, stringtab, sizeof buffer);
+      val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer);
+      if (val < 0)
+       perror_with_name (name);
+
+      /* That puts us at the symsegs.  Read them. ########## Also need other
+        changes if they exist. */
+
+      /* Position to read the symbol table.  Do not read it all at once. */
+      val = lseek (desc, N_SYMOFF (hdr), 0);
+      if (val < 0)
+       perror_with_name (name);
+
+      printf ("Reading symbol data from %s...", name);
       fflush (stdout);
-      return;
-    }
-
-  /* Now read the string table, all at once.  */
-  val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0);
-  if (val < 0)
-    perror_with_name (name);
-  val = myread (desc, &buffer, sizeof buffer);
-  if (val < 0)
-    perror_with_name (name);
-  stringtab = (char *) alloca (buffer);
-  bcopy (&buffer, stringtab, sizeof buffer);
-  val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer);
-  if (val < 0)
-    perror_with_name (name);
 
-  /* That puts us at the symsegs.  Read them. ########## Also need other
-     changes if they exist. */
+      init_misc_functions ();
+      make_cleanup (discard_misc_bunches, 0);
+      init_header_files ();
+      make_cleanup (free_header_files, 0);
 
+      read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist),
+                     text_addr, hdr.a_text) ;
 
-  /* Position to read the symbol table.  Do not read it all at once. */
-  val = lseek (desc, N_SYMOFF (hdr), 0);
-  if (val < 0)
-    perror_with_name (name);
+      /* Sort symbols alphabetically within each block.  */
 
-  printf ("Reading symbol data from %s...", name);
-  fflush (stdout);
+      sort_syms ();
 
-  init_misc_functions ();
-  make_cleanup (discard_misc_bunches, 0);
-  init_header_files ();
-  make_cleanup (free_header_files, 0);
+      /* Go over the all misc functions and install them in vector.  */
 
-  read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist)
-                 ,text_addr, hdr.a_text) ;
+      condense_addl_misc_bunches ();
 
-  /* Sort symbols alphabetically within each block.  */
+      /* Don't allow char * to have a typename (else would get caddr_t.)  */
 
-  sort_syms ();
+      TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
 
-  /* Go over the all misc functions and install them in vector.  */
+      /* Make a default for file to list.  */
 
-  condense_addl_misc_bunches ();
+      select_source_symtab (symtab_list);
 
-  /* Don't allow char * to have a typename (else would get caddr_t.)  */
+      do_cleanups (old_chain);
 
-  TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
-
-  /* Make a default for file to list.  */
-
-  select_source_symtab (symtab_list);
-
-  do_cleanups (old_chain);
+      /* Free the symtabs made by read_symsegs, but not their contents,
+        which have been copied into symtabs on symtab_list.  */
+      while (symseg_chain)
+       {
+         register struct symtab *s = symseg_chain->next;
+         free (symseg_chain);
+         symseg_chain = s;
+       }
 
-  /* Free the symtabs made by read_symsegs, but not their contents,
-     which have been copied into symtabs on symtab_list.  */
-  while (symseg_chain)
-    {
-      register struct symtab *s = symseg_chain->next;
-      free (symseg_chain);
-      symseg_chain = s;
+      printf ("done.\n");
+      fflush (stdout);
     }
-
-  printf ("done.\n");
-  fflush (stdout);
+  else error ("Not confirmed.");
 }
 \f
 static struct symbol *
@@ -2174,15 +2164,15 @@ read_type (pp)
       {
        struct type *domain = read_type (pp);
        char c;
-       struct type *ptrtype;
+       struct type *memtype;
 
        if (*(*pp)++ != ',')
-         error ("invalid member pointer data format, at symtab pos %d.",
+         error ("invalid member type data format, at symtab pos %d.",
                 symnum);
 
-       ptrtype = read_type (pp);
+       memtype = read_type (pp);
        type = dbx_alloc_type (typenums);
-       smash_to_member_pointer_type (type, domain, ptrtype);
+       smash_to_member_type (type, domain, memtype);
       }
       break;
 
index e676cf8ef089f4dcb97c7827cfc31dbbe6183981..8974bd5ce477ac66b890fa845ea317b595d7bf84 100644 (file)
@@ -420,32 +420,40 @@ the terms of Paragraph 1 above, provided that you also do the following:
     that in whole or in part contains or is a derivative of this
     program or any part thereof, to be licensed at no charge to all
     third parties on terms identical to those contained in this
-    License Agreement (except that you may choose to grant more
-    extensive warranty protection to third parties, at your option).
+    License Agreement (except that you may choose to grant more extensive
+    warranty protection to some or all third parties, at your option).
 
     c) You may charge a distribution fee for the physical act of
     transferring a copy, and you may at your option offer warranty
     protection in exchange for a fee.
 
-  3. You may copy and distribute this program or any portion of it in
-compiled, executable or object code form under the terms of Paragraphs
-1 and 2 above provided that you do the following:
+Mere aggregation of another unrelated program with this program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other program under the scope of these terms.
 
-    a) cause each such copy to be accompanied by the
-    corresponding machine-readable source code, which must
-    be distributed under the terms of Paragraphs 1 and 2 above; or,
+  3. You may copy and distribute this program (or a portion or derivative
+of it, under Paragraph 2) in object code or executable form under the terms
+of Paragraphs 1 and 2 above provided that you also do one of the following:
 
-    b) cause each such copy to be accompanied by a
-    written offer, with no time limit, to give any third party
-    free (except for a nominal shipping charge) a machine readable
-    copy of the corresponding source code, to be distributed
-    under the terms of Paragraphs 1 and 2 above; or,
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
 
-    c) in the case of a recipient of this program in compiled, executable
-    or object code form (without the corresponding source code) you
-    shall cause copies you distribute to be accompanied by a copy
-    of the written offer of source code which you received along
-    with the copy you received.
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal
+    shipping charge) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+For an executable file, complete source code means all the source code for
+all modules it contains; but, as a special exception, it need not include
+source code for modules which are standard libraries that accompany the
+operating system on which the executable file runs.
 
   4. You may not copy, sublicense, distribute or transfer this program
 except as expressly provided under this License Agreement.  Any attempt
@@ -504,7 +512,11 @@ YYSTYPE    yylval;                 /*  the semantic value of the           */
 YYLTYPE yylloc;                        /*  location data for the lookahead     */
                                /*  symbol                              */
 
+int yynerr;                    /*  number of parse errors so far       */
+
+#ifdef YYDEBUG
 int yydebug = 0;               /*  nonzero means print parse trace     */
+#endif
 
 #endif  /* YYIMPURE */
 
@@ -523,7 +535,7 @@ int yydebug = 0;            /*  nonzero means print parse trace     */
 #endif
 
 
-#line 87 "bison.simple"
+#line 165 "bison.simple"
 int
 yyparse()
 {
@@ -551,7 +563,9 @@ yyparse()
   YYSTYPE yylval;
   YYLTYPE yylloc;
 
+#ifdef YYDEBUG
   extern int yydebug;
+#endif
 
 #endif
 
@@ -562,11 +576,14 @@ yyparse()
 
   int yylen;
 
+#ifdef YYDEBUG
   if (yydebug)
     fprintf(stderr, "Starting parse\n");
+#endif
 
   yystate = 0;
   yyerrstatus = 0;
+  yynerr = 0;
   yychar = YYEMPTY;            /* Cause a token to be read.  */
 
   /* Initialize stack pointers.
@@ -624,15 +641,19 @@ yynewstate:
       yylsp = yyls + size - 1;
       yyvsp = yyvs + size - 1;
 
+#ifdef YYDEBUG
       if (yydebug)
        fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);
+#endif
 
       if (yyssp >= yyss + yymaxdepth - 1)
        YYERROR;
     }
 
+#ifdef YYDEBUG
   if (yydebug)
     fprintf(stderr, "Entering state %d\n", yystate);
+#endif
 
 /* Do appropriate processing given the current state.  */
 /* Read a lookahead token if we need one and don't already have one.  */
@@ -651,6 +672,10 @@ yyresume:
 
   if (yychar == YYEMPTY)
     {
+#ifdef YYDEBUG
+      if (yydebug)
+       fprintf(stderr, "Reading a token: ");
+#endif
       yychar = YYLEX;
     }
 
@@ -661,15 +686,19 @@ yyresume:
       yychar1 = 0;
       yychar = YYEOF;          /* Don't call YYLEX any more */
 
+#ifdef YYDEBUG
       if (yydebug)
        fprintf(stderr, "Now at end of input.\n");
+#endif
     }
   else
     {
       yychar1 = YYTRANSLATE(yychar);
 
+#ifdef YYDEBUG
       if (yydebug)
-       fprintf(stderr, "Parsing next token; it is %d (%s)\n", yychar, yytname[yychar1]);
+       fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]);
+#endif
     }
 
   yyn += yychar1;
@@ -700,8 +729,10 @@ yyresume:
 
   /* Shift the lookahead token.  */
 
+#ifdef YYDEBUG
   if (yydebug)
     fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
 
   /* Discard the token being shifted unless it is eof.  */
   if (yychar != YYEOF)
@@ -728,6 +759,7 @@ yyreduce:
   yylen = yyr2[yyn];
   yyval = yyvsp[1-yylen]; /* implement default value of the action */
 
+#ifdef YYDEBUG
   if (yydebug)
     {
       if (yylen == 1)
@@ -737,6 +769,7 @@ yyreduce:
        fprintf (stderr, "Reducing %d values via line %d, ",
                 yylen, yyrline[yyn]);
     }
+#endif
 
 
   switch (yyn) {
@@ -1161,19 +1194,19 @@ case 67:
     break;}
 case 68:
 #line 581 "expread.y"
-{ yyval.tval = lookup_member_pointer_type (builtin_type_int, yyvsp[-2].tval); ;
+{ yyval.tval = lookup_member_type (builtin_type_int, yyvsp[-2].tval); ;
     break;}
 case 69:
 #line 583 "expread.y"
-{ yyval.tval = lookup_member_pointer_type (yyvsp[-5].tval, yyvsp[-3].tval); ;
+{ yyval.tval = lookup_member_type (yyvsp[-5].tval, yyvsp[-3].tval); ;
     break;}
 case 70:
 #line 585 "expread.y"
-{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ;
+{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ;
     break;}
 case 71:
 #line 587 "expread.y"
-{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval);
+{ yyval.tval = lookup_member_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval);
                          free (yyvsp[-1].tvec); ;
     break;}
 case 72:
@@ -1222,6 +1255,7 @@ case 78:
   yylsp -= yylen;
   yyssp -= yylen;
 
+#ifdef YYDEBUG
   if (yydebug)
     {
       short *ssp1 = yyss - 1;
@@ -1230,6 +1264,7 @@ case 78:
        fprintf (stderr, " %d", *++ssp1);
       fprintf (stderr, "\n");
     }
+#endif
 
   *++yyvsp = yyval;
 
@@ -1268,11 +1303,8 @@ yyerrlab:   /* here on detecting error */
   if (! yyerrstatus)
     /* If not already recovering from an error, report this error.  */
     {
-#ifdef ESKIT
-      db_yyerror("parse error", yyssp, yychar);
-#else
+      ++yynerr;
       yyerror("parse error");
-#endif
     }
 
   if (yyerrstatus == 3)
@@ -1283,8 +1315,10 @@ yyerrlab:   /* here on detecting error */
       if (yychar == YYEOF)
        YYERROR;
 
+#ifdef YYDEBUG
       if (yydebug)
        fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
 
       yychar = YYEMPTY;
     }
@@ -1312,6 +1346,7 @@ yyerrpop:   /* pop the current state because it cannot handle the error token */
   yylsp--;
   yystate = *--yyssp;
 
+#ifdef YYDEBUG
   if (yydebug)
     {
       short *ssp1 = yyss - 1;
@@ -1320,6 +1355,7 @@ yyerrpop:   /* pop the current state because it cannot handle the error token */
        fprintf (stderr, " %d", *++ssp1);
       fprintf (stderr, "\n");
     }
+#endif
 
 yyerrhandle:
 
@@ -1345,8 +1381,10 @@ yyerrhandle:
   if (yyn == YYFINAL)
     YYACCEPT;
 
+#ifdef YYDEBUG
   if (yydebug)
     fprintf(stderr, "Shifting error token, ");
+#endif
 
   *++yyvsp = yylval;
   *++yylsp = yylloc;
index d9a18ead9b4d12f8740c866ca846a2833f678745..996ca219fcf4b77d648fc9e1ac8258c911f6856a 100644 (file)
@@ -578,13 +578,13 @@ type      :       typebase
        |       type '&'
                        { $$ = lookup_reference_type ($1); }
        |       typebase COLONCOLON '*'
-                       { $$ = lookup_member_pointer_type (builtin_type_int, $1); }
+                       { $$ = lookup_member_type (builtin_type_int, $1); }
        |       type '(' typebase COLONCOLON '*' ')'
-                       { $$ = lookup_member_pointer_type ($1, $3); }
+                       { $$ = lookup_member_type ($1, $3); }
        |       type '(' typebase COLONCOLON '*' ')' '(' ')'
-                       { $$ = lookup_member_pointer_type (lookup_function_type ($1, 0), $3); }
+                       { $$ = lookup_member_type (lookup_function_type ($1, 0), $3); }
        |       type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')'
-                       { $$ = lookup_member_pointer_type (lookup_function_type ($1, $8), $3);
+                       { $$ = lookup_member_type (lookup_function_type ($1, $8), $3);
                          free ($8); }
        ;
 
index ee3791f253b4a2031fd15f2ba06688a19f993faa..0fac7be1d12ded3a30a3fa56606c26921fbb0391 100644 (file)
@@ -62,6 +62,8 @@ enum exp_opcode
   BINOP_EXP,           /* Exponentiation */
 
 /* C++.  */
+  BINOP_MIN,           /* <? */
+  BINOP_MAX,           /* >? */
   BINOP_SCOPE,         /* :: */
 
   /* STRUCTOP_MEMBER is used for pointer-to-member constructs.
index 627f7adf2c740814a5b4c82e826aeabe12f86abb..0591073f959869f013787d502b308ac138e65920 100644 (file)
@@ -397,6 +397,13 @@ executable file.
 @samp{core-file} with no argument specifies that no core file is
 to be used.
 
+@item add-file @var{filename} @var{address}
+When performing incremental linking, the symbol table of an incrementally
+linked file may be included in the link step, but GDB+ needs to be told
+where that symbol table is in the address space.  By issuing this command,
+it is possible to symbolically debug programs which make use of incremental
+loading in a completely natural fashion.
+
 @item kill
 @kindex kill
 Cancel running the program under GDB+.  This could be used if you wish
index f5ad8ea92ed51a774cbbd2b57295afaef3e6d355..7b16f8f4a103d56819e74799d4a58ab254be18cc 100644 (file)
@@ -120,7 +120,7 @@ enum type_code
   TYPE_CODE_PASCAL_ARRAY,      /* Array with explicit type of index */
 
   /* C++ */
-  TYPE_CODE_MPTR,              /* Member pointer type */
+  TYPE_CODE_MEMBER,            /* Member type */
   TYPE_CODE_REF,               /* C++ Reference types */
 };
 
index 5540954ff9f8e905ac859baa945614960492dddb..ec6f0d69823128e651082ce9e7f6d9b910c77b40 100644 (file)
@@ -236,63 +236,54 @@ lookup_reference_type (type)
 }
 
 
-/* Given a type TYPE, return a type of pointers to that type.
+/* Implement direct support for MEMBER_TYPE in GNU C++.
    May need to construct such a type if this is the first use.
    The TYPE is the type of the member.  The DOMAIN is the type
    of the aggregate that the member belongs to.  */
 
 struct type *
-lookup_member_pointer_type (type, domain)
+lookup_member_type (type, domain)
      struct type *type, *domain;
 {
-  register struct type *ptype = TYPE_POINTER_TYPE (type);
+  register struct type *mtype = TYPE_MAIN_VARIANT (type);
   struct type *main_type;
 
-  if (ptype)
-    {
-      ptype = TYPE_MAIN_VARIANT (ptype);
-      main_type = ptype;
-      while (ptype)
-       {
-         if (TYPE_DOMAIN_TYPE (ptype) == domain)
-           return ptype;
-         ptype = TYPE_CHAIN (ptype);
-       }
-    }
-  else
+  main_type = mtype;
+  while (mtype)
     {
-      main_type = lookup_pointer_type (type);
-      TYPE_POINTER_TYPE (type) = main_type;
+      if (TYPE_DOMAIN_TYPE (mtype) == domain)
+       return mtype;
+      mtype = TYPE_CHAIN (mtype);
     }
 
-  /* This is the first time anyone wanted a pointer to a TYPE.  */
+  /* This is the first time anyone wanted this member type.  */
   if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    ptype  = (struct type *) xmalloc (sizeof (struct type));
+    mtype  = (struct type *) xmalloc (sizeof (struct type));
   else
-    ptype  = (struct type *) obstack_alloc (symbol_obstack,
+    mtype  = (struct type *) obstack_alloc (symbol_obstack,
                                            sizeof (struct type));
 
-  bzero (ptype, sizeof (struct type));
-  TYPE_MAIN_VARIANT (ptype) = main_type;
-  TYPE_TARGET_TYPE (ptype) = type;
-  TYPE_DOMAIN_TYPE (ptype) = domain;
-  TYPE_POINTER_TYPE (type) = ptype;
+  bzero (mtype, sizeof (struct type));
+  TYPE_MAIN_VARIANT (mtype) = main_type;
+  TYPE_TARGET_TYPE (mtype) = type;
+  TYPE_DOMAIN_TYPE (mtype) = domain;
   /* New type is permanent if type pointed to is permanent.  */
   if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM;
-  /* We assume the machine has only one representation for pointers!  */
-  TYPE_LENGTH (ptype) = sizeof (char *);
-  TYPE_CODE (ptype) = TYPE_CODE_MPTR;
+    TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
+
+  /* In practice, this is never used.  */
+  TYPE_LENGTH (mtype) = 1;
+  TYPE_CODE (mtype) = TYPE_CODE_MEMBER;
 
   /* Now splice in the new member pointer type.  */
   if (main_type)
     {
       /* This type was not "smashed".  */
-      TYPE_CHAIN (ptype) = TYPE_CHAIN (main_type);
-      TYPE_CHAIN (main_type) = ptype;
+      TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
+      TYPE_CHAIN (main_type) = mtype;
     }
 
-  return ptype;
+  return mtype;
 }
 
 /* Given a type TYPE, return a type of functions that return that type.
@@ -348,31 +339,21 @@ smash_to_pointer_type (type, to_type)
     }
 }
 
-/* Smash TYPE to be a type of pointers to TO_TYPE.
-   If TO_TYPE is not permanent and has no pointer-type yet,
-   record TYPE as its pointer-type.
-
-   TYPE is the type of the member.  DOMAIN is the type of
-   the aggregate that the member belongs to.  */
+/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE.  */
 
 void
-smash_to_member_pointer_type (type, domain, to_type)
+smash_to_member_type (type, domain, to_type)
      struct type *type, *domain, *to_type;
 {
   bzero (type, sizeof (struct type));
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
-  /* We assume the machine has only one representation for pointers!  */
-  TYPE_LENGTH (type) = sizeof (char *);
-  TYPE_CODE (type) = TYPE_CODE_MPTR;
 
-  TYPE_MAIN_VARIANT (type) = lookup_pointer_type (to_type);
+  /* In practice, this is never needed.  */
+  TYPE_LENGTH (type) = 1;
+  TYPE_CODE (type) = TYPE_CODE_MEMBER;
 
-  if (TYPE_POINTER_TYPE (to_type) == 0
-      && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM))
-    {
-      TYPE_POINTER_TYPE (to_type) = type;
-    }
+  TYPE_MAIN_VARIANT (type) = lookup_member_type (domain, to_type);
 }
 
 /* Smash TYPE to be a type of reference to TO_TYPE.
index d184766356201829b6be5c356e45d140532b7716..d888dc14b001cfcba2672190cec728229ab16f29 100644 (file)
@@ -234,7 +234,7 @@ extern int find_pc_misc_function ();
 
 /* C++ stuff.  */
 extern struct type *lookup_reference_type ();
-extern struct type *lookup_member_pointer_type ();
+extern struct type *lookup_member_type ();
 extern struct type *lookup_class ();
 /* end of C++ stuff.  */
 
index 03bc1e1e923918ce46569556e3fff816a87c6beb..6ce7c6af3ee8f7838cdb6f671742e1abe97ae113 100644 (file)
@@ -27,6 +27,8 @@ anyone else from sharing it farther.  Help stamp out software hoarding!
 
 START_FILE
 \f
+value value_x_binop ();
+
 value
 value_add (arg1, arg2)
        value arg1, arg2;
@@ -63,7 +65,7 @@ value_add (arg1, arg2)
       return val;
     }
 
-  return value_binop (arg1, arg2, BINOP_ADD);
+  return value_x_binop (arg1, arg2, BINOP_ADD);
 }
 
 value
@@ -96,7 +98,7 @@ value_sub (arg1, arg2)
       return val;
     }
 
-  return value_binop (arg1, arg2, BINOP_SUB);
+  return value_x_binop (arg1, arg2, BINOP_SUB);
 }
 
 /* Return the value of ARRAY[IDX].  */
@@ -107,7 +109,70 @@ value_subscript (array, idx)
 {
   return value_ind (value_add (array, idx));
 }
+\f
+/* Check to see if either argument is a structure.  If so, then
+   create an argument vector that calls arg1.operator @ (arg1,arg2)
+   and return that value (where '@' is any binary operator which
+   is legal for GNU C++).  If both args are scalar types then just
+   return value_binop().  */
+
+value
+value_x_binop (arg1, arg2, op)
+     value arg1, arg2;
+     int op;
+{
+  value * argvec;
+  char *ptr;
+  char tstr[13];
+  
+  COERCE_ENUM (arg1);
+  COERCE_ENUM (arg2);
+
+  if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
+      || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT)
+    {
+      /* now we know that what we have to do is construct our
+        arg vector and find the right function to call it with.  */
+
+      if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
+       error ("friend functions not implemented yet");
+
+      argvec = (value *) alloca (sizeof (value) * 4);
+      argvec[1] = value_addr (arg1);
+      argvec[2] = arg2;
+      argvec[3] = 0;
 
+      /* make the right function name up */  
+      strcpy(tstr,"operator __");
+      ptr = tstr+9;
+      switch (op)
+       {
+       case BINOP_ADD: *ptr++ = '+'; *ptr = '\0'; break;
+       case BINOP_SUB: *ptr++ = '-'; *ptr = '\0'; break;
+       case BINOP_MUL: *ptr++ = '*'; *ptr = '\0'; break;
+       case BINOP_DIV: *ptr++ = '/'; *ptr = '\0'; break;
+       case BINOP_REM: *ptr++ = '%'; *ptr = '\0';break;
+       case BINOP_LSH: *ptr++ = '<'; *ptr = '<'; break;
+       case BINOP_RSH: *ptr++ = '>'; *ptr = '>'; break;
+       case BINOP_LOGAND:      *ptr++ = '&'; *ptr = '\0'; break;
+       case BINOP_LOGIOR:      *ptr++ = '|'; *ptr = '\0'; break;
+       case BINOP_LOGXOR:      *ptr++ = '^'; *ptr = '\0'; break;
+       case BINOP_AND: *ptr++ = '&'; *ptr = '&'; break;
+       case BINOP_OR:  *ptr++ = '|'; *ptr = '|'; break;
+       case BINOP_MIN: *ptr++ = '<'; *ptr = '?'; break;
+       case BINOP_MAX: *ptr++ = '>'; *ptr = '?'; break;
+       default:
+         error ("Invalid binary operation specified.");
+       }
+      argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
+      if (argvec[0])
+       return call_function (argvec[0], 2, argvec + 1);
+      else error ("member function %s not found", tstr);
+    }
+
+  return value_binop(arg1, arg2, op);
+}
+\f
 /* Perform a binary operation on two integers or two floats.
    Does not support addition and subtraction on pointers;
    use value_add or value_sub if you want to handle those possibilities.  */
@@ -219,6 +284,14 @@ value_binop (arg1, arg2, op)
          v = v1 || v2;
          break;
 
+       case BINOP_MIN:
+         v = v1 < v2 ? v1 : v2;
+         break;
+
+       case BINOP_MAX:
+         v = v1 > v2 ? v1 : v2;
+         break;
+
        default:
          error ("Invalid binary operation on numbers.");
        }
index c9629320d86248adf1772fe9f54d1133c1e83845..8992c0fa73bcbb5acbfb2ba1fd8e4e196e4f971f 100644 (file)
@@ -56,17 +56,11 @@ value_cast (type, arg2)
     return value_from_long (type, value_as_long (arg2));
   else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2)))
     {
-      if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR))
-       printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n");
-
       VALUE_TYPE (arg2) = type;
       return arg2;
     }
   else if (VALUE_LVAL (arg2) == lval_memory)
     {
-      if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR))
-       printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n");
-
       return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
     }
   else
@@ -286,8 +280,8 @@ value_ind (arg1)
 {
   COERCE_ARRAY (arg1);
 
-  if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MPTR)
-    error ("not implemented: member pointers in value_ind");
+  if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MEMBER)
+    error ("not implemented: member types in value_ind");
 
   /* Allow * on an integer so we can cast it to whatever we want.  */
   if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT)
@@ -425,8 +419,13 @@ call_function (function, nargs, args)
     register struct type *ftype = VALUE_TYPE (function);
     register enum type_code code = TYPE_CODE (ftype);
 
-    if (code == TYPE_CODE_MPTR)
-      error ("not implemented: member pointer to call_function");
+    /* If it's a member function, just look at the function
+       part of it.  */
+    if (code == TYPE_CODE_MEMBER)
+      {
+       ftype = TYPE_TARGET_TYPE (ftype);
+       code = TYPE_CODE (ftype);
+      }
 
     /* Determine address to call.  */
     if (code == TYPE_CODE_FUNC)
@@ -601,8 +600,8 @@ value_struct_elt (arg1, args, name, err)
       t = VALUE_TYPE (arg1);
     }
 
-  if (TYPE_CODE (t) == TYPE_CODE_MPTR)
-    error ("not implemented: member pointers in value_struct_elt");
+  if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
+    error ("not implemented: member type in value_struct_elt");
 
   if (TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION)
@@ -809,8 +808,8 @@ check_field (arg1, name)
       t = VALUE_TYPE (arg1);
     }
 
-  if (TYPE_CODE (t) == TYPE_CODE_MPTR)
-    error ("not implemented: member pointers in check_field");
+  if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
+    error ("not implemented: member type in check_field");
 
   if (TYPE_CODE (t) != TYPE_CODE_STRUCT
       && TYPE_CODE (t) != TYPE_CODE_UNION)
@@ -886,7 +885,7 @@ value_struct_elt_for_address (domain, intype, name)
                error ("pointers to bitfield members not allowed");
 
              v = value_from_long (builtin_type_int, TYPE_FIELD_BITPOS (t, i) >> 3);
-             VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FIELD_TYPE (t, i), baseclass);
+             VALUE_TYPE (v) = lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass);
              return v;
            }
        }
@@ -936,7 +935,7 @@ value_struct_elt_for_address (domain, intype, name)
                                                    0, VAR_NAMESPACE);
                  v = locate_var_value (s, 0);
                }
-             VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FN_FIELD_TYPE (f, j), baseclass);
+             VALUE_TYPE (v) = lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), baseclass);
              return v;
            }
        }
index 619c9704a5a90eed2051c44e4c94072f772e223c..32601a6382a7a8766bfe2b5fffe423ee35988116 100644 (file)
@@ -168,147 +168,151 @@ val_print (type, valaddr, address, stream)
       /* Array of unspecified length: treat like pointer.  */
 
     case TYPE_CODE_PTR:
-      fprintf (stream, "0x%x", * (int *) valaddr);
-      /* For a pointer to char or unsigned char,
-        also print the string pointed to, unless pointer is null.  */
-      if ((TYPE_TARGET_TYPE (type) == builtin_type_char
-          || TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char)
-         && unpack_long (type, valaddr) != 0)
+      if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
        {
-         fputc (' ', stream);
-         fputc ('"', stream);
-         for (i = 0; i < print_max; i++)
+         struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
+         struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type));
+         struct fn_field *f;
+         int j, len2;
+         char *kind = "";
+
+         val = unpack_long (builtin_type_int, valaddr);
+         if (TYPE_CODE (target) == TYPE_CODE_FUNC)
            {
-             QUIT;
-             read_memory (unpack_long (type, valaddr) + i, &c, 1);
-             if (c == 0)
-               break;
-             printchar (c, stream);
+             if (val < 128)
+               {
+                 len = TYPE_NFN_FIELDS (domain);
+                 for (i = 0; i < len; i++)
+                   {
+                     f = TYPE_FN_FIELDLIST1 (domain, i);
+                     len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+                     for (j = 0; j < len2; j++)
+                       {
+                         QUIT;
+                         if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
+                           {
+                             kind = "virtual";
+                             goto common;
+                           }
+                       }
+                   }
+               }
+             else
+               {
+                 struct symbol *sym = find_pc_function (val);
+                 if (sym == 0)
+                   error ("invalid pointer to member function");
+                 len = TYPE_NFN_FIELDS (domain);
+                 for (i = 0; i < len; i++)
+                   {
+                     f = TYPE_FN_FIELDLIST1 (domain, i);
+                     len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
+
+                     for (j = 0; j < len2; j++)
+                       {
+                         QUIT;
+                         if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
+                           goto common;
+                       }
+                   }
+               }
+           common:
+             if (i < len)
+               {
+                 fprintf (stream, "& ");
+                 type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
+                 fprintf (stream, kind);
+                 if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
+                     && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
+                   type_print_method_args
+                     (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
+                      TYPE_FN_FIELDLIST_NAME (domain, i), stream);
+                 else
+                   type_print_method_args
+                     (TYPE_FN_FIELD_ARGS (f, j), "",
+                      TYPE_FN_FIELDLIST_NAME (domain, i), stream);
+                 break;
+               }
+           }
+         else
+           {
+             /* VAL is a byte offset into the structure type DOMAIN.
+                Find the name of the field for that offset and
+                print it.  */
+             int extra = 0;
+             int bits = 0;
+             len = TYPE_NFIELDS (domain);
+             val <<= 3;        /* @@ Make VAL into bit offset */
+             for (i = 0; i < len; i++)
+               {
+                 int bitpos = TYPE_FIELD_BITPOS (domain, i);
+                 QUIT;
+                 if (val == bitpos)
+                   break;
+                 if (val < bitpos && i > 0)
+                   {
+                     int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
+                     /* Somehow pointing into a field.  */
+                     i -= 1;
+                     extra = (val - TYPE_FIELD_BITPOS (domain, i));
+                     if (extra & 0x3)
+                       bits = 1;
+                     else
+                       extra >>= 3;
+                     break;
+                   }
+               }
+             if (i < len)
+               {
+                 fprintf (stream, "& ");
+                 type_print_base (domain, stream, 0, 0);
+                 fprintf (stream, "::");
+                 fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
+                 if (extra)
+                   fprintf (stream, " + %d bytes", extra);
+                 if (bits)
+                   fprintf (stream, " (offset in bits)");
+                 break;
+               }
+           }
+         fputc ('(', stream);
+         type_print (type, "", stream, -1);
+         fprintf (stream, ") %d", val >> 3);
+       }
+      else
+       {
+         fprintf (stream, "0x%x", * (int *) valaddr);
+         /* For a pointer to char or unsigned char,
+            also print the string pointed to, unless pointer is null.  */
+         if ((TYPE_TARGET_TYPE (type) == builtin_type_char
+              || TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char)
+             && unpack_long (type, valaddr) != 0)
+           {
+             fputc (' ', stream);
+             fputc ('"', stream);
+             for (i = 0; i < print_max; i++)
+               {
+                 QUIT;
+                 read_memory (unpack_long (type, valaddr) + i, &c, 1);
+                 if (c == 0)
+                   break;
+                 printchar (c, stream);
+               }
+             fputc ('"', stream);
+             if (i == print_max)
+               fprintf (stream, "...");
+             fflush (stream);
+             /* Return number of characters printed, plus one for the
+                terminating null if we have "reached the end".  */
+             return i + (i != print_max);
            }
-         fputc ('"', stream);
-         if (i == print_max)
-           fprintf (stream, "...");
-         fflush (stream);
-         /* Return number of characters printed, plus one for the
-            terminating null if we have "reached the end".  */
-         return i + (i != print_max);
        }
       break;
 
-    case TYPE_CODE_MPTR:
-      {
-       struct type *domain = TYPE_DOMAIN_TYPE (type);
-       struct type *target = TYPE_TARGET_TYPE (type);
-       struct fn_field *f;
-       int j, len2;
-       char *kind = "";
-
-       val = unpack_long (builtin_type_int, valaddr);
-       if (TYPE_CODE (target) == TYPE_CODE_FUNC)
-         {
-           if (val < 128)
-             {
-               len = TYPE_NFN_FIELDS (domain);
-               for (i = 0; i < len; i++)
-                 {
-                   f = TYPE_FN_FIELDLIST1 (domain, i);
-                   len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
-
-                   for (j = 0; j < len2; j++)
-                     {
-                       QUIT;
-                       if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
-                         {
-                           kind = " virtual";
-                           goto common;
-                         }
-                     }
-                 }
-             }
-           else
-             {
-               struct symbol *sym = find_pc_function (val);
-               if (sym == 0)
-                 error ("invalid pointer to member function");
-               len = TYPE_NFN_FIELDS (domain);
-               for (i = 0; i < len; i++)
-                 {
-                   f = TYPE_FN_FIELDLIST1 (domain, i);
-                   len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
-
-                   for (j = 0; j < len2; j++)
-                     {
-                       QUIT;
-                       if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
-                         goto common;
-                     }
-                 }
-             }
-         common:
-           if (i < len)
-             {
-               fprintf (stream, "& ");
-               type_print_base (domain, stream, 0, 0);
-               fprintf (stream, "::%s", kind);
-               type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
-               if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
-                   && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
-                 type_print_method_args
-                   (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
-                    TYPE_FN_FIELDLIST_NAME (domain, i), stream);
-               else
-                 type_print_method_args
-                   (TYPE_FN_FIELD_ARGS (f, j), "",
-                    TYPE_FN_FIELDLIST_NAME (domain, i), stream);
-               break;
-             }
-         }
-       else
-         {
-           /* VAL is a byte offset into the structure type DOMAIN.
-              Find the name of the field for that offset and
-              print it.  */
-           int extra = 0;
-           int bits = 0;
-           len = TYPE_NFIELDS (domain);
-           val <<= 3;          /* @@ Make VAL into bit offset */
-           for (i = 0; i < len; i++)
-             {
-               int bitpos = TYPE_FIELD_BITPOS (domain, i);
-               QUIT;
-               if (val == bitpos)
-                 break;
-               if (val < bitpos && i > 0)
-                 {
-                   int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
-                   /* Somehow pointing into a field.  */
-                   i -= 1;
-                   extra = (val - TYPE_FIELD_BITPOS (domain, i));
-                   if (extra & 0x3)
-                     bits = 1;
-                   else
-                     extra >>= 3;
-                   break;
-                 }
-             }
-           if (i < len)
-             {
-               fprintf (stream, "& ");
-               type_print_base (domain, stream, 0, 0);
-               fprintf (stream, "::");
-               fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
-               if (extra)
-                 fprintf (stream, " + %d bytes", extra);
-               if (bits)
-                 fprintf (stream, " (offset in bits)");
-               break;
-             }
-         }
-       fputc ('(', stream);
-       type_print (type, "", stream, -1);
-       fprintf (stream, ") %d", val >> 3);
-       break;
-      }
+    case TYPE_CODE_MEMBER:
+      error ("not implemented: member type in val_print");
+      break;
 
     case TYPE_CODE_REF:
       fprintf (stream, "(0x%x &) = ", * (int *) valaddr);
@@ -489,7 +493,7 @@ type_print_1 (type, varstring, stream, show, level)
        &&
        (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
        || code == TYPE_CODE_ARRAY
-       || code == TYPE_CODE_MPTR
+       || code == TYPE_CODE_MEMBER
        || code == TYPE_CODE_REF)))
     fprintf (stream, " ");
   type_print_varspec_prefix (type, stream, show, 0);
@@ -550,12 +554,11 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr)
       fputc ('*', stream);
       break;
 
-    case TYPE_CODE_MPTR:
-      type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
-      if (passed_a_ptr)
-       fputc ('(', stream);
-      type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, 1);
-      fprintf (stream, "::*");
+    case TYPE_CODE_MEMBER:
+      type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+      type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0,
+                      passed_a_ptr);
+      fprintf (stream, "::");
       break;
 
     case TYPE_CODE_REF:
@@ -604,10 +607,12 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr)
       fprintf (stream, "]");
       break;
 
-    case TYPE_CODE_MPTR:
+    case TYPE_CODE_MEMBER:
       if (passed_a_ptr)
        fputc (')', stream);
-      /* Fall through.  */
+      type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+      break;
+
     case TYPE_CODE_PTR:
     case TYPE_CODE_REF:
       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1);
@@ -660,7 +665,7 @@ type_print_base (type, stream, show, level)
     {
     case TYPE_CODE_ARRAY:
     case TYPE_CODE_PTR:
-    case TYPE_CODE_MPTR:
+    case TYPE_CODE_MEMBER:
     case TYPE_CODE_REF:
     case TYPE_CODE_FUNC:
       type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
index 93d948245339b1bd0001dc440b9f6b78abd4cf1e..8fa5af9c03ad96ad656c3aefa93ca7a14b021b1d 100644 (file)
@@ -464,8 +464,7 @@ unpack_long (type, valaddr)
       if (len == sizeof (long))
        return * (unsigned long *) valaddr;
     }
-  else if (code == TYPE_CODE_INT
-          || code == TYPE_CODE_MPTR)
+  else if (code == TYPE_CODE_INT)
     {
       if (len == sizeof (char))
        return * (char *) valaddr;
@@ -485,6 +484,9 @@ unpack_long (type, valaddr)
       if (len == sizeof (char *))
        return (CORE_ADDR) * (char **) valaddr;
     }
+  else if (code == TYPE_CODE_MEMBER)
+    error ("not impelmented: member types in unpack_long");
+
   error ("Value not integer or pointer.");
 }
 
index 244d065a1f69a15faf6a9db63c5a3a455ee2fae6..5e1f9074ae1ab0fd8dd85fc107535f371cce6609 100644 (file)
@@ -1,3 +1,3 @@
 /* Define the current version number of GDB.  */
 
-char *version = "2.5.1 (GNU C++ 1.21.0 compatible)";
+char *version = "2.5.2 (GNU C++ 1.22.0 compatible)";