forked from gbenson/binutils-gdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalops.c
3880 lines (3298 loc) · 118 KB
/
valops.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* Perform non-arithmetic operations on values, for GDB.
Copyright (C) 1986-2015 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "frame.h"
#include "inferior.h"
#include "gdbcore.h"
#include "target.h"
#include "demangle.h"
#include "language.h"
#include "gdbcmd.h"
#include "regcache.h"
#include "cp-abi.h"
#include "block.h"
#include "infcall.h"
#include "dictionary.h"
#include "cp-support.h"
#include "dfp.h"
#include "tracepoint.h"
#include "observer.h"
#include "objfiles.h"
#include "extension.h"
extern unsigned int overload_debug;
/* Local functions. */
static int typecmp (int staticp, int varargs, int nargs,
struct field t1[], struct value *t2[]);
static struct value *search_struct_field (const char *, struct value *,
struct type *, int);
static struct value *search_struct_method (const char *, struct value **,
struct value **,
int, int *, struct type *);
static int find_oload_champ_namespace (struct value **, int,
const char *, const char *,
struct symbol ***,
struct badness_vector **,
const int no_adl);
static
int find_oload_champ_namespace_loop (struct value **, int,
const char *, const char *,
int, struct symbol ***,
struct badness_vector **, int *,
const int no_adl);
static int find_oload_champ (struct value **, int, int,
struct fn_field *, VEC (xmethod_worker_ptr) *,
struct symbol **, struct badness_vector **);
static int oload_method_static_p (struct fn_field *, int);
enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE };
static enum
oload_classification classify_oload_match (struct badness_vector *,
int, int);
static struct value *value_struct_elt_for_reference (struct type *,
int, struct type *,
const char *,
struct type *,
int, enum noside);
static struct value *value_namespace_elt (const struct type *,
const char *, int , enum noside);
static struct value *value_maybe_namespace_elt (const struct type *,
const char *, int,
enum noside);
static CORE_ADDR allocate_space_in_inferior (int);
static struct value *cast_into_complex (struct type *, struct value *);
static void find_method_list (struct value **, const char *,
int, struct type *, struct fn_field **, int *,
VEC (xmethod_worker_ptr) **,
struct type **, int *);
void _initialize_valops (void);
#if 0
/* Flag for whether we want to abandon failed expression evals by
default. */
static int auto_abandon = 0;
#endif
int overload_resolution = 0;
static void
show_overload_resolution (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *value)
{
fprintf_filtered (file, _("Overload resolution in evaluating "
"C++ functions is %s.\n"),
value);
}
/* Find the address of function name NAME in the inferior. If OBJF_P
is non-NULL, *OBJF_P will be set to the OBJFILE where the function
is defined. */
struct value *
find_function_in_inferior (const char *name, struct objfile **objf_p)
{
struct block_symbol sym;
sym = lookup_symbol (name, 0, VAR_DOMAIN, 0);
if (sym.symbol != NULL)
{
if (SYMBOL_CLASS (sym.symbol) != LOC_BLOCK)
{
error (_("\"%s\" exists in this program but is not a function."),
name);
}
if (objf_p)
*objf_p = symbol_objfile (sym.symbol);
return value_of_variable (sym.symbol, sym.block);
}
else
{
struct bound_minimal_symbol msymbol =
lookup_bound_minimal_symbol (name);
if (msymbol.minsym != NULL)
{
struct objfile *objfile = msymbol.objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *type;
CORE_ADDR maddr;
type = lookup_pointer_type (builtin_type (gdbarch)->builtin_char);
type = lookup_function_type (type);
type = lookup_pointer_type (type);
maddr = BMSYMBOL_VALUE_ADDRESS (msymbol);
if (objf_p)
*objf_p = objfile;
return value_from_pointer (type, maddr);
}
else
{
if (!target_has_execution)
error (_("evaluation of this expression "
"requires the target program to be active"));
else
error (_("evaluation of this expression requires the "
"program to have a function \"%s\"."),
name);
}
}
}
/* Allocate NBYTES of space in the inferior using the inferior's
malloc and return a value that is a pointer to the allocated
space. */
struct value *
value_allocate_space_in_inferior (int len)
{
struct objfile *objf;
struct value *val = find_function_in_inferior ("malloc", &objf);
struct gdbarch *gdbarch = get_objfile_arch (objf);
struct value *blocklen;
blocklen = value_from_longest (builtin_type (gdbarch)->builtin_int, len);
val = call_function_by_hand (val, 1, &blocklen);
if (value_logical_not (val))
{
if (!target_has_execution)
error (_("No memory available to program now: "
"you need to start the target first"));
else
error (_("No memory available to program: call to malloc failed"));
}
return val;
}
static CORE_ADDR
allocate_space_in_inferior (int len)
{
return value_as_long (value_allocate_space_in_inferior (len));
}
/* Cast struct value VAL to type TYPE and return as a value.
Both type and val must be of TYPE_CODE_STRUCT or TYPE_CODE_UNION
for this to work. Typedef to one of the codes is permitted.
Returns NULL if the cast is neither an upcast nor a downcast. */
static struct value *
value_cast_structs (struct type *type, struct value *v2)
{
struct type *t1;
struct type *t2;
struct value *v;
gdb_assert (type != NULL && v2 != NULL);
t1 = check_typedef (type);
t2 = check_typedef (value_type (v2));
/* Check preconditions. */
gdb_assert ((TYPE_CODE (t1) == TYPE_CODE_STRUCT
|| TYPE_CODE (t1) == TYPE_CODE_UNION)
&& !!"Precondition is that type is of STRUCT or UNION kind.");
gdb_assert ((TYPE_CODE (t2) == TYPE_CODE_STRUCT
|| TYPE_CODE (t2) == TYPE_CODE_UNION)
&& !!"Precondition is that value is of STRUCT or UNION kind");
if (TYPE_NAME (t1) != NULL
&& TYPE_NAME (t2) != NULL
&& !strcmp (TYPE_NAME (t1), TYPE_NAME (t2)))
return NULL;
/* Upcasting: look in the type of the source to see if it contains the
type of the target as a superclass. If so, we'll need to
offset the pointer rather than just change its type. */
if (TYPE_NAME (t1) != NULL)
{
v = search_struct_field (type_name_no_tag (t1),
v2, t2, 1);
if (v)
return v;
}
/* Downcasting: look in the type of the target to see if it contains the
type of the source as a superclass. If so, we'll need to
offset the pointer rather than just change its type. */
if (TYPE_NAME (t2) != NULL)
{
/* Try downcasting using the run-time type of the value. */
int full, top, using_enc;
struct type *real_type;
real_type = value_rtti_type (v2, &full, &top, &using_enc);
if (real_type)
{
v = value_full_object (v2, real_type, full, top, using_enc);
v = value_at_lazy (real_type, value_address (v));
real_type = value_type (v);
/* We might be trying to cast to the outermost enclosing
type, in which case search_struct_field won't work. */
if (TYPE_NAME (real_type) != NULL
&& !strcmp (TYPE_NAME (real_type), TYPE_NAME (t1)))
return v;
v = search_struct_field (type_name_no_tag (t2), v, real_type, 1);
if (v)
return v;
}
/* Try downcasting using information from the destination type
T2. This wouldn't work properly for classes with virtual
bases, but those were handled above. */
v = search_struct_field (type_name_no_tag (t2),
value_zero (t1, not_lval), t1, 1);
if (v)
{
/* Downcasting is possible (t1 is superclass of v2). */
CORE_ADDR addr2 = value_address (v2);
addr2 -= value_address (v) + value_embedded_offset (v);
return value_at (type, addr2);
}
}
return NULL;
}
/* Cast one pointer or reference type to another. Both TYPE and
the type of ARG2 should be pointer types, or else both should be
reference types. If SUBCLASS_CHECK is non-zero, this will force a
check to see whether TYPE is a superclass of ARG2's type. If
SUBCLASS_CHECK is zero, then the subclass check is done only when
ARG2 is itself non-zero. Returns the new pointer or reference. */
struct value *
value_cast_pointers (struct type *type, struct value *arg2,
int subclass_check)
{
struct type *type1 = check_typedef (type);
struct type *type2 = check_typedef (value_type (arg2));
struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type1));
struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
&& TYPE_CODE (t2) == TYPE_CODE_STRUCT
&& (subclass_check || !value_logical_not (arg2)))
{
struct value *v2;
if (TYPE_CODE (type2) == TYPE_CODE_REF)
v2 = coerce_ref (arg2);
else
v2 = value_ind (arg2);
gdb_assert (TYPE_CODE (check_typedef (value_type (v2)))
== TYPE_CODE_STRUCT && !!"Why did coercion fail?");
v2 = value_cast_structs (t1, v2);
/* At this point we have what we can have, un-dereference if needed. */
if (v2)
{
struct value *v = value_addr (v2);
deprecated_set_value_type (v, type);
return v;
}
}
/* No superclass found, just change the pointer type. */
arg2 = value_copy (arg2);
deprecated_set_value_type (arg2, type);
set_value_enclosing_type (arg2, type);
set_value_pointed_to_offset (arg2, 0); /* pai: chk_val */
return arg2;
}
/* Cast value ARG2 to type TYPE and return as a value.
More general than a C cast: accepts any two types of the same length,
and if ARG2 is an lvalue it can be cast into anything at all. */
/* In C++, casts may change pointer or object representations. */
struct value *
value_cast (struct type *type, struct value *arg2)
{
enum type_code code1;
enum type_code code2;
int scalar;
struct type *type2;
int convert_to_boolean = 0;
if (value_type (arg2) == type)
return arg2;
code1 = TYPE_CODE (check_typedef (type));
/* Check if we are casting struct reference to struct reference. */
if (code1 == TYPE_CODE_REF)
{
/* We dereference type; then we recurse and finally
we generate value of the given reference. Nothing wrong with
that. */
struct type *t1 = check_typedef (type);
struct type *dereftype = check_typedef (TYPE_TARGET_TYPE (t1));
struct value *val = value_cast (dereftype, arg2);
return value_ref (val);
}
code2 = TYPE_CODE (check_typedef (value_type (arg2)));
if (code2 == TYPE_CODE_REF)
/* We deref the value and then do the cast. */
return value_cast (type, coerce_ref (arg2));
type = check_typedef (type);
code1 = TYPE_CODE (type);
arg2 = coerce_ref (arg2);
type2 = check_typedef (value_type (arg2));
/* You can't cast to a reference type. See value_cast_pointers
instead. */
gdb_assert (code1 != TYPE_CODE_REF);
/* A cast to an undetermined-length array_type, such as
(TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT,
where N is sizeof(OBJECT)/sizeof(TYPE). */
if (code1 == TYPE_CODE_ARRAY)
{
struct type *element_type = TYPE_TARGET_TYPE (type);
unsigned element_length = TYPE_LENGTH (check_typedef (element_type));
if (element_length > 0 && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type))
{
struct type *range_type = TYPE_INDEX_TYPE (type);
int val_length = TYPE_LENGTH (type2);
LONGEST low_bound, high_bound, new_length;
if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
low_bound = 0, high_bound = 0;
new_length = val_length / element_length;
if (val_length % element_length != 0)
warning (_("array element type size does not "
"divide object size in cast"));
/* FIXME-type-allocation: need a way to free this type when
we are done with it. */
range_type = create_static_range_type ((struct type *) NULL,
TYPE_TARGET_TYPE (range_type),
low_bound,
new_length + low_bound - 1);
deprecated_set_value_type (arg2,
create_array_type ((struct type *) NULL,
element_type,
range_type));
return arg2;
}
}
if (current_language->c_style_arrays
&& TYPE_CODE (type2) == TYPE_CODE_ARRAY
&& !TYPE_VECTOR (type2))
arg2 = value_coerce_array (arg2);
if (TYPE_CODE (type2) == TYPE_CODE_FUNC)
arg2 = value_coerce_function (arg2);
type2 = check_typedef (value_type (arg2));
code2 = TYPE_CODE (type2);
if (code1 == TYPE_CODE_COMPLEX)
return cast_into_complex (type, arg2);
if (code1 == TYPE_CODE_BOOL)
{
code1 = TYPE_CODE_INT;
convert_to_boolean = 1;
}
if (code1 == TYPE_CODE_CHAR)
code1 = TYPE_CODE_INT;
if (code2 == TYPE_CODE_BOOL || code2 == TYPE_CODE_CHAR)
code2 = TYPE_CODE_INT;
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|| code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
|| code2 == TYPE_CODE_RANGE);
if ((code1 == TYPE_CODE_STRUCT || code1 == TYPE_CODE_UNION)
&& (code2 == TYPE_CODE_STRUCT || code2 == TYPE_CODE_UNION)
&& TYPE_NAME (type) != 0)
{
struct value *v = value_cast_structs (type, arg2);
if (v)
return v;
}
if (code1 == TYPE_CODE_FLT && scalar)
return value_from_double (type, value_as_double (arg2));
else if (code1 == TYPE_CODE_DECFLOAT && scalar)
{
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
int dec_len = TYPE_LENGTH (type);
gdb_byte dec[16];
if (code2 == TYPE_CODE_FLT)
decimal_from_floating (arg2, dec, dec_len, byte_order);
else if (code2 == TYPE_CODE_DECFLOAT)
decimal_convert (value_contents (arg2), TYPE_LENGTH (type2),
byte_order, dec, dec_len, byte_order);
else
/* The only option left is an integral type. */
decimal_from_integral (arg2, dec, dec_len, byte_order);
return value_from_decfloat (type, dec);
}
else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
|| code1 == TYPE_CODE_RANGE)
&& (scalar || code2 == TYPE_CODE_PTR
|| code2 == TYPE_CODE_MEMBERPTR))
{
LONGEST longest;
/* When we cast pointers to integers, we mustn't use
gdbarch_pointer_to_address to find the address the pointer
represents, as value_as_long would. GDB should evaluate
expressions just as the compiler would --- and the compiler
sees a cast as a simple reinterpretation of the pointer's
bits. */
if (code2 == TYPE_CODE_PTR)
longest = extract_unsigned_integer
(value_contents (arg2), TYPE_LENGTH (type2),
gdbarch_byte_order (get_type_arch (type2)));
else
longest = value_as_long (arg2);
return value_from_longest (type, convert_to_boolean ?
(LONGEST) (longest ? 1 : 0) : longest);
}
else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT
|| code2 == TYPE_CODE_ENUM
|| code2 == TYPE_CODE_RANGE))
{
/* TYPE_LENGTH (type) is the length of a pointer, but we really
want the length of an address! -- we are really dealing with
addresses (i.e., gdb representations) not pointers (i.e.,
target representations) here.
This allows things like "print *(int *)0x01000234" to work
without printing a misleading message -- which would
otherwise occur when dealing with a target having two byte
pointers and four byte addresses. */
int addr_bit = gdbarch_addr_bit (get_type_arch (type2));
LONGEST longest = value_as_long (arg2);
if (addr_bit < sizeof (LONGEST) * HOST_CHAR_BIT)
{
if (longest >= ((LONGEST) 1 << addr_bit)
|| longest <= -((LONGEST) 1 << addr_bit))
warning (_("value truncated"));
}
return value_from_longest (type, longest);
}
else if (code1 == TYPE_CODE_METHODPTR && code2 == TYPE_CODE_INT
&& value_as_long (arg2) == 0)
{
struct value *result = allocate_value (type);
cplus_make_method_ptr (type, value_contents_writeable (result), 0, 0);
return result;
}
else if (code1 == TYPE_CODE_MEMBERPTR && code2 == TYPE_CODE_INT
&& value_as_long (arg2) == 0)
{
/* The Itanium C++ ABI represents NULL pointers to members as
minus one, instead of biasing the normal case. */
return value_from_longest (type, -1);
}
else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
&& code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
&& TYPE_LENGTH (type) != TYPE_LENGTH (type2))
error (_("Cannot convert between vector values of different sizes"));
else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar
&& TYPE_LENGTH (type) != TYPE_LENGTH (type2))
error (_("can only cast scalar to vector of same size"));
else if (code1 == TYPE_CODE_VOID)
{
return value_zero (type, not_lval);
}
else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
{
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
return value_cast_pointers (type, arg2, 0);
arg2 = value_copy (arg2);
deprecated_set_value_type (arg2, type);
set_value_enclosing_type (arg2, type);
set_value_pointed_to_offset (arg2, 0); /* pai: chk_val */
return arg2;
}
else if (VALUE_LVAL (arg2) == lval_memory)
return value_at_lazy (type, value_address (arg2));
else
{
error (_("Invalid cast."));
return 0;
}
}
/* The C++ reinterpret_cast operator. */
struct value *
value_reinterpret_cast (struct type *type, struct value *arg)
{
struct value *result;
struct type *real_type = check_typedef (type);
struct type *arg_type, *dest_type;
int is_ref = 0;
enum type_code dest_code, arg_code;
/* Do reference, function, and array conversion. */
arg = coerce_array (arg);
/* Attempt to preserve the type the user asked for. */
dest_type = type;
/* If we are casting to a reference type, transform
reinterpret_cast<T&>(V) to *reinterpret_cast<T*>(&V). */
if (TYPE_CODE (real_type) == TYPE_CODE_REF)
{
is_ref = 1;
arg = value_addr (arg);
dest_type = lookup_pointer_type (TYPE_TARGET_TYPE (dest_type));
real_type = lookup_pointer_type (real_type);
}
arg_type = value_type (arg);
dest_code = TYPE_CODE (real_type);
arg_code = TYPE_CODE (arg_type);
/* We can convert pointer types, or any pointer type to int, or int
type to pointer. */
if ((dest_code == TYPE_CODE_PTR && arg_code == TYPE_CODE_INT)
|| (dest_code == TYPE_CODE_INT && arg_code == TYPE_CODE_PTR)
|| (dest_code == TYPE_CODE_METHODPTR && arg_code == TYPE_CODE_INT)
|| (dest_code == TYPE_CODE_INT && arg_code == TYPE_CODE_METHODPTR)
|| (dest_code == TYPE_CODE_MEMBERPTR && arg_code == TYPE_CODE_INT)
|| (dest_code == TYPE_CODE_INT && arg_code == TYPE_CODE_MEMBERPTR)
|| (dest_code == arg_code
&& (dest_code == TYPE_CODE_PTR
|| dest_code == TYPE_CODE_METHODPTR
|| dest_code == TYPE_CODE_MEMBERPTR)))
result = value_cast (dest_type, arg);
else
error (_("Invalid reinterpret_cast"));
if (is_ref)
result = value_cast (type, value_ref (value_ind (result)));
return result;
}
/* A helper for value_dynamic_cast. This implements the first of two
runtime checks: we iterate over all the base classes of the value's
class which are equal to the desired class; if only one of these
holds the value, then it is the answer. */
static int
dynamic_cast_check_1 (struct type *desired_type,
const gdb_byte *valaddr,
int embedded_offset,
CORE_ADDR address,
struct value *val,
struct type *search_type,
CORE_ADDR arg_addr,
struct type *arg_type,
struct value **result)
{
int i, result_count = 0;
for (i = 0; i < TYPE_N_BASECLASSES (search_type) && result_count < 2; ++i)
{
int offset = baseclass_offset (search_type, i, valaddr, embedded_offset,
address, val);
if (class_types_same_p (desired_type, TYPE_BASECLASS (search_type, i)))
{
if (address + embedded_offset + offset >= arg_addr
&& address + embedded_offset + offset < arg_addr + TYPE_LENGTH (arg_type))
{
++result_count;
if (!*result)
*result = value_at_lazy (TYPE_BASECLASS (search_type, i),
address + embedded_offset + offset);
}
}
else
result_count += dynamic_cast_check_1 (desired_type,
valaddr,
embedded_offset + offset,
address, val,
TYPE_BASECLASS (search_type, i),
arg_addr,
arg_type,
result);
}
return result_count;
}
/* A helper for value_dynamic_cast. This implements the second of two
runtime checks: we look for a unique public sibling class of the
argument's declared class. */
static int
dynamic_cast_check_2 (struct type *desired_type,
const gdb_byte *valaddr,
int embedded_offset,
CORE_ADDR address,
struct value *val,
struct type *search_type,
struct value **result)
{
int i, result_count = 0;
for (i = 0; i < TYPE_N_BASECLASSES (search_type) && result_count < 2; ++i)
{
int offset;
if (! BASETYPE_VIA_PUBLIC (search_type, i))
continue;
offset = baseclass_offset (search_type, i, valaddr, embedded_offset,
address, val);
if (class_types_same_p (desired_type, TYPE_BASECLASS (search_type, i)))
{
++result_count;
if (*result == NULL)
*result = value_at_lazy (TYPE_BASECLASS (search_type, i),
address + embedded_offset + offset);
}
else
result_count += dynamic_cast_check_2 (desired_type,
valaddr,
embedded_offset + offset,
address, val,
TYPE_BASECLASS (search_type, i),
result);
}
return result_count;
}
/* The C++ dynamic_cast operator. */
struct value *
value_dynamic_cast (struct type *type, struct value *arg)
{
int full, top, using_enc;
struct type *resolved_type = check_typedef (type);
struct type *arg_type = check_typedef (value_type (arg));
struct type *class_type, *rtti_type;
struct value *result, *tem, *original_arg = arg;
CORE_ADDR addr;
int is_ref = TYPE_CODE (resolved_type) == TYPE_CODE_REF;
if (TYPE_CODE (resolved_type) != TYPE_CODE_PTR
&& TYPE_CODE (resolved_type) != TYPE_CODE_REF)
error (_("Argument to dynamic_cast must be a pointer or reference type"));
if (TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_VOID
&& TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) != TYPE_CODE_STRUCT)
error (_("Argument to dynamic_cast must be pointer to class or `void *'"));
class_type = check_typedef (TYPE_TARGET_TYPE (resolved_type));
if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
{
if (TYPE_CODE (arg_type) != TYPE_CODE_PTR
&& ! (TYPE_CODE (arg_type) == TYPE_CODE_INT
&& value_as_long (arg) == 0))
error (_("Argument to dynamic_cast does not have pointer type"));
if (TYPE_CODE (arg_type) == TYPE_CODE_PTR)
{
arg_type = check_typedef (TYPE_TARGET_TYPE (arg_type));
if (TYPE_CODE (arg_type) != TYPE_CODE_STRUCT)
error (_("Argument to dynamic_cast does "
"not have pointer to class type"));
}
/* Handle NULL pointers. */
if (value_as_long (arg) == 0)
return value_zero (type, not_lval);
arg = value_ind (arg);
}
else
{
if (TYPE_CODE (arg_type) != TYPE_CODE_STRUCT)
error (_("Argument to dynamic_cast does not have class type"));
}
/* If the classes are the same, just return the argument. */
if (class_types_same_p (class_type, arg_type))
return value_cast (type, arg);
/* If the target type is a unique base class of the argument's
declared type, just cast it. */
if (is_ancestor (class_type, arg_type))
{
if (is_unique_ancestor (class_type, arg))
return value_cast (type, original_arg);
error (_("Ambiguous dynamic_cast"));
}
rtti_type = value_rtti_type (arg, &full, &top, &using_enc);
if (! rtti_type)
error (_("Couldn't determine value's most derived type for dynamic_cast"));
/* Compute the most derived object's address. */
addr = value_address (arg);
if (full)
{
/* Done. */
}
else if (using_enc)
addr += top;
else
addr += top + value_embedded_offset (arg);
/* dynamic_cast<void *> means to return a pointer to the
most-derived object. */
if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR
&& TYPE_CODE (TYPE_TARGET_TYPE (resolved_type)) == TYPE_CODE_VOID)
return value_at_lazy (type, addr);
tem = value_at (type, addr);
type = value_type (tem);
/* The first dynamic check specified in 5.2.7. */
if (is_public_ancestor (arg_type, TYPE_TARGET_TYPE (resolved_type)))
{
if (class_types_same_p (rtti_type, TYPE_TARGET_TYPE (resolved_type)))
return tem;
result = NULL;
if (dynamic_cast_check_1 (TYPE_TARGET_TYPE (resolved_type),
value_contents_for_printing (tem),
value_embedded_offset (tem),
value_address (tem), tem,
rtti_type, addr,
arg_type,
&result) == 1)
return value_cast (type,
is_ref ? value_ref (result) : value_addr (result));
}
/* The second dynamic check specified in 5.2.7. */
result = NULL;
if (is_public_ancestor (arg_type, rtti_type)
&& dynamic_cast_check_2 (TYPE_TARGET_TYPE (resolved_type),
value_contents_for_printing (tem),
value_embedded_offset (tem),
value_address (tem), tem,
rtti_type, &result) == 1)
return value_cast (type,
is_ref ? value_ref (result) : value_addr (result));
if (TYPE_CODE (resolved_type) == TYPE_CODE_PTR)
return value_zero (type, not_lval);
error (_("dynamic_cast failed"));
}
/* Create a value of type TYPE that is zero, and return it. */
struct value *
value_zero (struct type *type, enum lval_type lv)
{
struct value *val = allocate_value (type);
VALUE_LVAL (val) = (lv == lval_computed ? not_lval : lv);
return val;
}
/* Create a not_lval value of numeric type TYPE that is one, and return it. */
struct value *
value_one (struct type *type)
{
struct type *type1 = check_typedef (type);
struct value *val;
if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT)
{
enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
gdb_byte v[16];
decimal_from_string (v, TYPE_LENGTH (type), byte_order, "1");
val = value_from_decfloat (type, v);
}
else if (TYPE_CODE (type1) == TYPE_CODE_FLT)
{
val = value_from_double (type, (DOUBLEST) 1);
}
else if (is_integral_type (type1))
{
val = value_from_longest (type, (LONGEST) 1);
}
else if (TYPE_CODE (type1) == TYPE_CODE_ARRAY && TYPE_VECTOR (type1))
{
struct type *eltype = check_typedef (TYPE_TARGET_TYPE (type1));
int i;
LONGEST low_bound, high_bound;
struct value *tmp;
if (!get_array_bounds (type1, &low_bound, &high_bound))
error (_("Could not determine the vector bounds"));
val = allocate_value (type);
for (i = 0; i < high_bound - low_bound + 1; i++)
{
tmp = value_one (eltype);
memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
value_contents_all (tmp), TYPE_LENGTH (eltype));
}
}
else
{
error (_("Not a numeric type."));
}
/* value_one result is never used for assignments to. */
gdb_assert (VALUE_LVAL (val) == not_lval);
return val;
}
/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.
The type of the created value may differ from the passed type TYPE.
Make sure to retrieve the returned values's new type after this call
e.g. in case the type is a variable length array. */
static struct value *
get_value_at (struct type *type, CORE_ADDR addr, int lazy)
{
struct value *val;
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
error (_("Attempt to dereference a generic pointer."));
val = value_from_contents_and_address (type, NULL, addr);
if (!lazy)
value_fetch_lazy (val);
return val;
}
/* Return a value with type TYPE located at ADDR.
Call value_at only if the data needs to be fetched immediately;
if we can be 'lazy' and defer the fetch, perhaps indefinately, call
value_at_lazy instead. value_at_lazy simply records the address of
the data and sets the lazy-evaluation-required flag. The lazy flag
is tested in the value_contents macro, which is used if and when
the contents are actually required. The type of the created value
may differ from the passed type TYPE. Make sure to retrieve the
returned values's new type after this call e.g. in case the type
is a variable length array.
Note: value_at does *NOT* handle embedded offsets; perform such
adjustments before or after calling it. */
struct value *
value_at (struct type *type, CORE_ADDR addr)
{
return get_value_at (type, addr, 0);
}
/* Return a lazy value with type TYPE located at ADDR (cf. value_at).
The type of the created value may differ from the passed type TYPE.
Make sure to retrieve the returned values's new type after this call
e.g. in case the type is a variable length array. */
struct value *
value_at_lazy (struct type *type, CORE_ADDR addr)
{
return get_value_at (type, addr, 1);
}
void
read_value_memory (struct value *val, int embedded_offset,
int stack, CORE_ADDR memaddr,
gdb_byte *buffer, size_t length)
{
ULONGEST xfered_total = 0;
struct gdbarch *arch = get_value_arch (val);
int unit_size = gdbarch_addressable_memory_unit_size (arch);
while (xfered_total < length)
{
enum target_xfer_status status;
ULONGEST xfered_partial;
status = target_xfer_partial (current_target.beneath,
TARGET_OBJECT_MEMORY, NULL,
buffer + xfered_total * unit_size, NULL,
memaddr + xfered_total,
length - xfered_total,
&xfered_partial);
if (status == TARGET_XFER_OK)
/* nothing */;
else if (status == TARGET_XFER_UNAVAILABLE)
mark_value_bytes_unavailable (val, embedded_offset + xfered_total,
xfered_partial);
else if (status == TARGET_XFER_EOF)
memory_error (TARGET_XFER_E_IO, memaddr + xfered_total);
else
memory_error (status, memaddr + xfered_total);
xfered_total += xfered_partial;
QUIT;
}
}
/* Store the contents of FROMVAL into the location of TOVAL.
Return a new value with the location of TOVAL and contents of FROMVAL. */
struct value *
value_assign (struct value *toval, struct value *fromval)
{
struct type *type;
struct value *val;
struct frame_id old_frame;