00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026
00027 #include "real.h"
00028 #include "rtl.h"
00029 #include "tree.h"
00030 #include "input.h"
00031 #include "output.h"
00032 #include "c-tree.h"
00033 #include "c-common.h"
00034 #include "flags.h"
00035 #include "timevar.h"
00036 #include "cpplib.h"
00037 #include "c-pragma.h"
00038 #include "toplev.h"
00039 #include "intl.h"
00040 #include "tm_p.h"
00041 #include "splay-tree.h"
00042 #include "debug.h"
00043
00044
00045 static int header_time, body_time;
00046 static splay_tree file_info_tree;
00047
00048 #undef WCHAR_TYPE_SIZE
00049 #define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node)
00050
00051
00052 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
00053
00054 int pending_lang_change;
00055 int c_header_level;
00056
00057
00058
00059
00060
00061 int c_lex_string_translate = 1;
00062
00063
00064
00065 bool c_lex_return_raw_strings = false;
00066
00067 static tree interpret_integer (const cpp_token *, unsigned int);
00068 static tree interpret_float (const cpp_token *, unsigned int);
00069 static enum integer_type_kind narrowest_unsigned_type
00070 (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
00071 static enum integer_type_kind narrowest_signed_type
00072 (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
00073 static enum cpp_ttype lex_string (const cpp_token *, tree *, bool);
00074 static tree lex_charconst (const cpp_token *);
00075 static void update_header_times (const char *);
00076 static int dump_one_header (splay_tree_node, void *);
00077 static void cb_line_change (cpp_reader *, const cpp_token *, int);
00078 static void cb_ident (cpp_reader *, unsigned int, const cpp_string *);
00079 static void cb_def_pragma (cpp_reader *, unsigned int);
00080 static void cb_define (cpp_reader *, unsigned int, cpp_hashnode *);
00081 static void cb_undef (cpp_reader *, unsigned int, cpp_hashnode *);
00082
00083 void
00084 init_c_lex (void)
00085 {
00086 struct cpp_callbacks *cb;
00087 struct c_fileinfo *toplevel;
00088
00089
00090
00091 toplevel = get_fileinfo ("<top level>");
00092 if (flag_detailed_statistics)
00093 {
00094 header_time = 0;
00095 body_time = get_run_time ();
00096 toplevel->time = body_time;
00097 }
00098
00099 cb = cpp_get_callbacks (parse_in);
00100
00101 cb->line_change = cb_line_change;
00102 cb->ident = cb_ident;
00103 cb->def_pragma = cb_def_pragma;
00104 cb->valid_pch = c_common_valid_pch;
00105 cb->read_pch = c_common_read_pch;
00106
00107
00108 if (debug_info_level == DINFO_LEVEL_VERBOSE
00109 && (write_symbols == DWARF2_DEBUG
00110 || write_symbols == VMS_AND_DWARF2_DEBUG))
00111 {
00112 cb->define = cb_define;
00113 cb->undef = cb_undef;
00114 }
00115 }
00116
00117 struct c_fileinfo *
00118 get_fileinfo (const char *name)
00119 {
00120 splay_tree_node n;
00121 struct c_fileinfo *fi;
00122
00123 if (!file_info_tree)
00124 file_info_tree = splay_tree_new ((splay_tree_compare_fn) strcmp,
00125 0,
00126 (splay_tree_delete_value_fn) free);
00127
00128 n = splay_tree_lookup (file_info_tree, (splay_tree_key) name);
00129 if (n)
00130 return (struct c_fileinfo *) n->value;
00131
00132 fi = XNEW (struct c_fileinfo);
00133 fi->time = 0;
00134 fi->interface_only = 0;
00135 fi->interface_unknown = 1;
00136 splay_tree_insert (file_info_tree, (splay_tree_key) name,
00137 (splay_tree_value) fi);
00138 return fi;
00139 }
00140
00141 static void
00142 update_header_times (const char *name)
00143 {
00144
00145
00146 if (flag_detailed_statistics)
00147 {
00148 int this_time = get_run_time ();
00149 struct c_fileinfo *file = get_fileinfo (name);
00150 header_time += this_time - body_time;
00151 file->time += this_time - body_time;
00152 body_time = this_time;
00153 }
00154 }
00155
00156 static int
00157 dump_one_header (splay_tree_node n, void * ARG_UNUSED (dummy))
00158 {
00159 print_time ((const char *) n->key,
00160 ((struct c_fileinfo *) n->value)->time);
00161 return 0;
00162 }
00163
00164 void
00165 dump_time_statistics (void)
00166 {
00167 struct c_fileinfo *file = get_fileinfo (input_filename);
00168 int this_time = get_run_time ();
00169 file->time += this_time - body_time;
00170
00171 fprintf (stderr, "\n******\n");
00172 print_time ("header files (total)", header_time);
00173 print_time ("main file (total)", this_time - body_time);
00174 fprintf (stderr, "ratio = %g : 1\n",
00175 (double) header_time / (double) (this_time - body_time));
00176 fprintf (stderr, "\n******\n");
00177
00178 splay_tree_foreach (file_info_tree, dump_one_header, 0);
00179 }
00180
00181 static void
00182 cb_ident (cpp_reader * ARG_UNUSED (pfile),
00183 unsigned int ARG_UNUSED (line),
00184 const cpp_string * ARG_UNUSED (str))
00185 {
00186 #ifdef ASM_OUTPUT_IDENT
00187 if (!flag_no_ident)
00188 {
00189
00190 cpp_string cstr = { 0, 0 };
00191 if (cpp_interpret_string (pfile, str, 1, &cstr, false))
00192 {
00193 ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text);
00194 free ((void *) cstr.text);
00195 }
00196 }
00197 #endif
00198 }
00199
00200
00201
00202 static void
00203 cb_line_change (cpp_reader * ARG_UNUSED (pfile), const cpp_token *token,
00204 int parsing_args)
00205 {
00206 if (token->type != CPP_EOF && !parsing_args)
00207 #ifdef USE_MAPPED_LOCATION
00208 input_location = token->src_loc;
00209 #else
00210 {
00211 source_location loc = token->src_loc;
00212 const struct line_map *map = linemap_lookup (&line_table, loc);
00213 input_line = SOURCE_LINE (map, loc);
00214 }
00215 #endif
00216 }
00217
00218 void
00219 fe_file_change (const struct line_map *new_map)
00220 {
00221 if (new_map == NULL)
00222 return;
00223
00224 if (new_map->reason == LC_ENTER)
00225 {
00226
00227
00228 if (!MAIN_FILE_P (new_map))
00229 {
00230 #ifdef USE_MAPPED_LOCATION
00231 int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
00232
00233 input_location = included_at;
00234 push_srcloc (new_map->start_location);
00235 #else
00236 int included_at = LAST_SOURCE_LINE (new_map - 1);
00237
00238 input_line = included_at;
00239 push_srcloc (new_map->to_file, 1);
00240 #endif
00241 (*debug_hooks->start_source_file) (included_at, new_map->to_file);
00242 #ifndef NO_IMPLICIT_EXTERN_C
00243 if (c_header_level)
00244 ++c_header_level;
00245 else if (new_map->sysp == 2)
00246 {
00247 c_header_level = 1;
00248 ++pending_lang_change;
00249 }
00250 #endif
00251 }
00252 }
00253 else if (new_map->reason == LC_LEAVE)
00254 {
00255 #ifndef NO_IMPLICIT_EXTERN_C
00256 if (c_header_level && --c_header_level == 0)
00257 {
00258 if (new_map->sysp == 2)
00259 warning ("badly nested C headers from preprocessor");
00260 --pending_lang_change;
00261 }
00262 #endif
00263 pop_srcloc ();
00264
00265 (*debug_hooks->end_source_file) (new_map->to_line);
00266 }
00267
00268 update_header_times (new_map->to_file);
00269 in_system_header = new_map->sysp != 0;
00270 #ifdef USE_MAPPED_LOCATION
00271 input_location = new_map->start_location;
00272 #else
00273 input_filename = new_map->to_file;
00274 input_line = new_map->to_line;
00275 #endif
00276 }
00277
00278 static void
00279 cb_def_pragma (cpp_reader *pfile, source_location loc)
00280 {
00281
00282
00283
00284 if (warn_unknown_pragmas > in_system_header)
00285 {
00286 const unsigned char *space, *name;
00287 const cpp_token *s;
00288 #ifndef USE_MAPPED_LOCATION
00289 location_t fe_loc;
00290 const struct line_map *map = linemap_lookup (&line_table, loc);
00291 fe_loc.file = map->to_file;
00292 fe_loc.line = SOURCE_LINE (map, loc);
00293 #else
00294 location_t fe_loc = loc;
00295 #endif
00296
00297 space = name = (const unsigned char *) "";
00298 s = cpp_get_token (pfile);
00299 if (s->type != CPP_EOF)
00300 {
00301 space = cpp_token_as_text (pfile, s);
00302 s = cpp_get_token (pfile);
00303 if (s->type == CPP_NAME)
00304 name = cpp_token_as_text (pfile, s);
00305 }
00306
00307 warning ("%Hignoring #pragma %s %s", &fe_loc, space, name);
00308 }
00309 }
00310
00311
00312 static void
00313 cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
00314 {
00315 const struct line_map *map = linemap_lookup (&line_table, loc);
00316 (*debug_hooks->define) (SOURCE_LINE (map, loc),
00317 (const char *) cpp_macro_definition (pfile, node));
00318 }
00319
00320
00321 static void
00322 cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
00323 cpp_hashnode *node)
00324 {
00325 const struct line_map *map = linemap_lookup (&line_table, loc);
00326 (*debug_hooks->undef) (SOURCE_LINE (map, loc),
00327 (const char *) NODE_NAME (node));
00328 }
00329
00330
00331
00332
00333
00334 enum cpp_ttype
00335 c_lex_with_flags (tree *value, unsigned char *cpp_flags)
00336 {
00337 static bool no_more_pch;
00338 const cpp_token *tok;
00339 enum cpp_ttype type;
00340
00341 timevar_push (TV_CPP);
00342 retry:
00343 tok = cpp_get_token (parse_in);
00344 type = tok->type;
00345
00346 retry_after_at:
00347 switch (type)
00348 {
00349 case CPP_PADDING:
00350 goto retry;
00351
00352 case CPP_NAME:
00353 *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
00354 break;
00355
00356 case CPP_NUMBER:
00357 {
00358 unsigned int flags = cpp_classify_number (parse_in, tok);
00359
00360 switch (flags & CPP_N_CATEGORY)
00361 {
00362 case CPP_N_INVALID:
00363
00364 *value = error_mark_node;
00365 break;
00366
00367 case CPP_N_INTEGER:
00368 *value = interpret_integer (tok, flags);
00369 break;
00370
00371 case CPP_N_FLOATING:
00372 *value = interpret_float (tok, flags);
00373 break;
00374
00375 default:
00376 gcc_unreachable ();
00377 }
00378 }
00379 break;
00380
00381 case CPP_ATSIGN:
00382
00383 if (c_dialect_objc ())
00384 {
00385 location_t atloc = input_location;
00386
00387 retry_at:
00388 tok = cpp_get_token (parse_in);
00389 type = tok->type;
00390 switch (type)
00391 {
00392 case CPP_PADDING:
00393 goto retry_at;
00394
00395 case CPP_STRING:
00396 case CPP_WSTRING:
00397 type = lex_string (tok, value, true);
00398 break;
00399
00400 case CPP_NAME:
00401 *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
00402 if (objc_is_reserved_word (*value))
00403 {
00404 type = CPP_AT_NAME;
00405 break;
00406 }
00407
00408
00409 default:
00410
00411 error ("%Hstray %<@%> in program", &atloc);
00412 goto retry_after_at;
00413 }
00414 break;
00415 }
00416
00417
00418 case CPP_HASH:
00419 case CPP_PASTE:
00420 {
00421 unsigned char name[4];
00422
00423 *cpp_spell_token (parse_in, tok, name) = 0;
00424
00425 error ("stray %qs in program", name);
00426 }
00427
00428 goto retry;
00429
00430 case CPP_OTHER:
00431 {
00432 cppchar_t c = tok->val.str.text[0];
00433
00434 if (c == '"' || c == '\'')
00435 error ("missing terminating %c character", (int) c);
00436 else if (ISGRAPH (c))
00437 error ("stray %qc in program", (int) c);
00438 else
00439 error ("stray %<\\%o%> in program", (int) c);
00440 }
00441 goto retry;
00442
00443 case CPP_CHAR:
00444 case CPP_WCHAR:
00445 *value = lex_charconst (tok);
00446 break;
00447
00448 case CPP_STRING:
00449 case CPP_WSTRING:
00450 if (!c_lex_return_raw_strings)
00451 {
00452 type = lex_string (tok, value, false);
00453 break;
00454 }
00455
00456
00457
00458 case CPP_PRAGMA:
00459 *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
00460 break;
00461
00462
00463 case CPP_HEADER_NAME:
00464 case CPP_COMMENT:
00465 case CPP_MACRO_ARG:
00466 gcc_unreachable ();
00467
00468 default:
00469 *value = NULL_TREE;
00470 break;
00471 }
00472
00473 if (cpp_flags)
00474 *cpp_flags = tok->flags;
00475
00476 if (!no_more_pch)
00477 {
00478 no_more_pch = true;
00479 c_common_no_more_pch ();
00480 }
00481
00482 timevar_pop (TV_CPP);
00483
00484 return type;
00485 }
00486
00487 enum cpp_ttype
00488 c_lex (tree *value)
00489 {
00490 return c_lex_with_flags (value, NULL);
00491 }
00492
00493
00494
00495
00496
00497 static enum integer_type_kind
00498 narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
00499 unsigned HOST_WIDE_INT high,
00500 unsigned int flags)
00501 {
00502 enum integer_type_kind itk;
00503
00504 if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
00505 itk = itk_unsigned_int;
00506 else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
00507 itk = itk_unsigned_long;
00508 else
00509 itk = itk_unsigned_long_long;
00510
00511 for (; itk < itk_none; itk += 2 )
00512 {
00513 tree upper = TYPE_MAX_VALUE (integer_types[itk]);
00514
00515 if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
00516 || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
00517 && TREE_INT_CST_LOW (upper) >= low))
00518 return itk;
00519 }
00520
00521 return itk_none;
00522 }
00523
00524
00525 static enum integer_type_kind
00526 narrowest_signed_type (unsigned HOST_WIDE_INT low,
00527 unsigned HOST_WIDE_INT high, unsigned int flags)
00528 {
00529 enum integer_type_kind itk;
00530
00531 if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
00532 itk = itk_int;
00533 else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
00534 itk = itk_long;
00535 else
00536 itk = itk_long_long;
00537
00538
00539 for (; itk < itk_none; itk += 2 )
00540 {
00541 tree upper = TYPE_MAX_VALUE (integer_types[itk]);
00542
00543 if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
00544 || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
00545 && TREE_INT_CST_LOW (upper) >= low))
00546 return itk;
00547 }
00548
00549 return itk_none;
00550 }
00551
00552
00553 static tree
00554 interpret_integer (const cpp_token *token, unsigned int flags)
00555 {
00556 tree value, type;
00557 enum integer_type_kind itk;
00558 cpp_num integer;
00559 cpp_options *options = cpp_get_options (parse_in);
00560
00561 integer = cpp_interpret_integer (parse_in, token, flags);
00562 integer = cpp_num_sign_extend (integer, options->precision);
00563
00564
00565 if (flags & CPP_N_UNSIGNED)
00566 itk = narrowest_unsigned_type (integer.low, integer.high, flags);
00567 else
00568 {
00569
00570
00571
00572 enum integer_type_kind itk_u
00573 = narrowest_unsigned_type (integer.low, integer.high, flags);
00574 enum integer_type_kind itk_s
00575 = narrowest_signed_type (integer.low, integer.high, flags);
00576
00577
00578
00579
00580
00581 if ((flags & CPP_N_RADIX) != CPP_N_DECIMAL)
00582 itk = MIN (itk_u, itk_s);
00583 else
00584 {
00585
00586
00587
00588
00589
00590
00591 itk = itk_s;
00592 if (itk_s > itk_u && itk_s > itk_long)
00593 {
00594 if (!flag_isoc99)
00595 {
00596 if (itk_u < itk_unsigned_long)
00597 itk_u = itk_unsigned_long;
00598 itk = itk_u;
00599 warning ("this decimal constant is unsigned only in ISO C90");
00600 }
00601 else if (warn_traditional)
00602 warning ("this decimal constant would be unsigned in ISO C90");
00603 }
00604 }
00605 }
00606
00607 if (itk == itk_none)
00608
00609 type = ((flags & CPP_N_UNSIGNED)
00610 ? widest_unsigned_literal_type_node
00611 : widest_integer_literal_type_node);
00612 else
00613 type = integer_types[itk];
00614
00615 if (itk > itk_unsigned_long
00616 && (flags & CPP_N_WIDTH) != CPP_N_LARGE
00617 && !in_system_header && !flag_isoc99)
00618 pedwarn ("integer constant is too large for %qs type",
00619 (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
00620
00621 value = build_int_cst_wide (type, integer.low, integer.high);
00622
00623
00624 if (flags & CPP_N_IMAGINARY)
00625 value = build_complex (NULL_TREE, build_int_cst (type, 0), value);
00626
00627 return value;
00628 }
00629
00630
00631
00632 static tree
00633 interpret_float (const cpp_token *token, unsigned int flags)
00634 {
00635 tree type;
00636 tree value;
00637 REAL_VALUE_TYPE real;
00638 char *copy;
00639 size_t copylen;
00640 const char *type_name;
00641
00642
00643 if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
00644 {
00645 type = long_double_type_node;
00646 type_name = "long double";
00647 }
00648 else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
00649 || flag_single_precision_constant)
00650 {
00651 type = float_type_node;
00652 type_name = "float";
00653 }
00654 else
00655 {
00656 type = double_type_node;
00657 type_name = "double";
00658 }
00659
00660
00661
00662
00663 copylen = token->val.str.len;
00664 if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
00665
00666 copylen--;
00667 if (flags & CPP_N_IMAGINARY)
00668
00669 copylen--;
00670
00671 copy = (char *) alloca (copylen + 1);
00672 memcpy (copy, token->val.str.text, copylen);
00673 copy[copylen] = '\0';
00674
00675 real_from_string (&real, copy);
00676 real_convert (&real, TYPE_MODE (type), &real);
00677
00678
00679
00680
00681
00682
00683 if (REAL_VALUE_ISINF (real) && pedantic)
00684 pedwarn ("floating constant exceeds range of %<%s%>", type_name);
00685
00686
00687 value = build_real (type, real);
00688 if (flags & CPP_N_IMAGINARY)
00689 value = build_complex (NULL_TREE, convert (type, integer_zero_node), value);
00690
00691 return value;
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 static enum cpp_ttype
00711 lex_string (const cpp_token *tok, tree *valp, bool objc_string)
00712 {
00713 tree value;
00714 bool wide = false;
00715 size_t concats = 0;
00716 struct obstack str_ob;
00717 cpp_string istr;
00718
00719
00720
00721 cpp_string str = tok->val.str;
00722 cpp_string *strs = &str;
00723
00724 if (tok->type == CPP_WSTRING)
00725 wide = true;
00726
00727 retry:
00728 tok = cpp_get_token (parse_in);
00729 switch (tok->type)
00730 {
00731 case CPP_PADDING:
00732 goto retry;
00733 case CPP_ATSIGN:
00734 if (c_dialect_objc ())
00735 {
00736 objc_string = true;
00737 goto retry;
00738 }
00739
00740
00741 default:
00742 break;
00743
00744 case CPP_WSTRING:
00745 wide = true;
00746
00747
00748 case CPP_STRING:
00749 if (!concats)
00750 {
00751 gcc_obstack_init (&str_ob);
00752 obstack_grow (&str_ob, &str, sizeof (cpp_string));
00753 }
00754
00755 concats++;
00756 obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
00757 goto retry;
00758 }
00759
00760
00761 _cpp_backup_tokens (parse_in, 1);
00762 if (concats)
00763 strs = (cpp_string *) obstack_finish (&str_ob);
00764
00765 if (concats && !objc_string && warn_traditional && !in_system_header)
00766 warning ("traditional C rejects string constant concatenation");
00767
00768 if ((c_lex_string_translate
00769 ? cpp_interpret_string : cpp_interpret_string_notranslate)
00770 (parse_in, strs, concats + 1, &istr, wide))
00771 {
00772 value = build_string (istr.len, (char *) istr.text);
00773 free ((void *) istr.text);
00774
00775 if (c_lex_string_translate == -1)
00776 {
00777 int xlated = cpp_interpret_string_notranslate (parse_in, strs,
00778 concats + 1,
00779 &istr, wide);
00780
00781
00782 gcc_assert (xlated);
00783
00784 if (TREE_STRING_LENGTH (value) != (int) istr.len
00785 || 0 != strncmp (TREE_STRING_POINTER (value), (char *) istr.text,
00786 istr.len))
00787 {
00788
00789
00790
00791 *valp = build_string (istr.len, (char *) istr.text);
00792 valp = &TREE_CHAIN (*valp);
00793 }
00794 free ((void *) istr.text);
00795 }
00796 }
00797 else
00798 {
00799
00800
00801
00802 if (wide)
00803 value = build_string (TYPE_PRECISION (wchar_type_node)
00804 / TYPE_PRECISION (char_type_node),
00805 "\0\0\0");
00806
00807 else
00808 value = build_string (1, "");
00809 }
00810
00811 TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
00812 *valp = fix_string_type (value);
00813
00814 if (concats)
00815 obstack_free (&str_ob, 0);
00816
00817 return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
00818 }
00819
00820
00821 static tree
00822 lex_charconst (const cpp_token *token)
00823 {
00824 cppchar_t result;
00825 tree type, value;
00826 unsigned int chars_seen;
00827 int unsignedp;
00828
00829 result = cpp_interpret_charconst (parse_in, token,
00830 &chars_seen, &unsignedp);
00831
00832 if (token->type == CPP_WCHAR)
00833 type = wchar_type_node;
00834
00835
00836 else if (!c_dialect_cxx () || chars_seen > 1)
00837 type = integer_type_node;
00838 else
00839 type = char_type_node;
00840
00841
00842
00843 if (unsignedp || (cppchar_signed_t) result >= 0)
00844 value = build_int_cst_wide (type, result, 0);
00845 else
00846 value = build_int_cst_wide (type, (cppchar_signed_t) result, -1);
00847
00848 return value;
00849 }