232
231
function tloadparentfpnode.det_resulttype:tnode;
234
234
currpi : tprocinfo;
235
235
hsym : tparavarsym;
238
239
resulttype:=voidpointertype;
240
currently parentfps are never loaded in registers (FK)
241
{ currently parentfps are never loaded in registers (FK) }
242
243
if (current_procinfo.procdef.parast.symtablelevel<>parentpd.parast.symtablelevel) then
355
356
{ Handle @proc special, also @procvar in tp-mode needs
356
357
special handling }
357
358
if (left.resulttype.def.deftype=procdef) or
358
((left.resulttype.def.deftype=procvardef) and
359
(m_tp_procvar in aktmodeswitches)) then
360
(left.resulttype.def.deftype=procvardef) and
361
((m_tp_procvar in aktmodeswitches) or
362
(m_mac_procvar in aktmodeswitches))
361
365
isprocvar:=(left.resulttype.def.deftype=procvardef);
369
373
{ In tp procvar mode the result is always a voidpointer. Insert
370
374
a typeconversion to voidpointer. For methodpointers we need
371
375
to load the proc field }
372
if (m_tp_procvar in aktmodeswitches) then
376
if (m_tp_procvar in aktmodeswitches) or
377
(m_mac_procvar in aktmodeswitches) then
374
379
if tabstractprocdef(left.resulttype.def).is_addressonly then
427
432
if (nf_internal in flags) or
428
valid_for_addr(left) then
433
valid_for_addr(left,true) then
430
435
if not(nf_typedaddr in flags) then
431
436
resulttype:=voidpointertype
439
444
{ this is like the function addr }
440
445
inc(parsing_para_level);
441
set_varstate(left,vs_used,[]);
446
{ This is actually only "read", but treat it nevertheless as }
447
{ modified due to the possible use of pointers }
448
{ To avoid false positives regarding "uninitialised" }
449
{ warnings when using arrays, perform it in two steps }
450
set_varstate(left,vs_written,[]);
451
set_varstate(left,vs_read,[]);
442
452
dec(parsing_para_level);
450
460
if codegenerror then
453
{ we should allow loc_mem for @string }
454
if not(left.expectloc in [LOC_CREFERENCE,LOC_REFERENCE]) then
456
aktfilepos:=left.fileinfo;
457
CGMessage(parser_e_illegal_expression);
460
463
registersint:=left.registersint;
461
464
registersfpu:=left.registersfpu;
462
465
{$ifdef SUPPORT_MMX}
643
646
resulttypepass(left);
644
647
resulttypepass(right);
645
649
{ In p[1] p is always valid, it is not possible to
646
650
declared a shortstring or normal array that has
647
651
undefined number of elements. Dynamic array and
648
652
ansi/widestring needs to be valid }
649
653
valid:=is_dynamic_array(left.resulttype.def) or
650
654
is_ansistring(left.resulttype.def) or
651
is_widestring(left.resulttype.def);
655
is_widestring(left.resulttype.def) or
656
{ implicit pointer dereference -> pointer is read }
657
(left.resulttype.def.deftype = pointerdef);
653
set_varstate(left,vs_used,[vsf_must_be_valid])
655
set_varstate(left,vs_used,[]);
656
set_varstate(right,vs_used,[vsf_must_be_valid]);
659
set_varstate(left,vs_read,[vsf_must_be_valid]);
661
A vecn is, just like a loadn, always part of an expression with its
662
own read/write and must_be_valid semantics. Therefore we don't have
663
to do anything else here, just like for loadn's
665
set_varstate(right,vs_read,[vsf_must_be_valid]);
657
666
if codegenerror then
660
669
{ maybe type conversion for the index value, but
661
670
do not convert enums,booleans,char }
662
if (right.resulttype.def.deftype<>enumdef) and
663
not(is_char(right.resulttype.def)) and
664
not(is_boolean(right.resulttype.def)) then
671
if ((right.resulttype.def.deftype<>enumdef) and
672
not(is_char(right.resulttype.def) or is_widechar(right.resulttype.def)) and
673
not(is_boolean(right.resulttype.def))) or
674
(left.resulttype.def.deftype <> arraydef) then
666
inserttypeconv(right,s32inttype);
676
inserttypeconv(right,sinttype);
669
679
case left.resulttype.def.deftype of
894
904
resulttype:=voidtype;
896
906
resulttypepass(withrefnode);
897
set_varstate(withrefnode,vs_used,[vsf_must_be_valid]);
907
set_varstate(withrefnode,vs_read,[vsf_must_be_valid]);
898
908
if codegenerror then