mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 08:19:36 +01:00 
			
		
		
		
	* implement sizeof/typeof completely at the node level, based on
loadvmtaddr and vmt_def
   o give an error when trying to use sizeof on a class/object when
     targeting the JVM (can't get/load the data size there)
git-svn-id: trunk@32764 -
			
			
This commit is contained in:
		
							parent
							
								
									59eff35c5d
								
							
						
					
					
						commit
						8917633199
					
				@ -305,6 +305,12 @@ implementation
 | 
			
		||||
             begin
 | 
			
		||||
               result:=typecheck_new(handled);
 | 
			
		||||
             end;
 | 
			
		||||
           in_sizeof_x:
 | 
			
		||||
             begin
 | 
			
		||||
               { can't get the size of the data of a class/object }
 | 
			
		||||
               if left.resultdef.typ in [objectdef,classrefdef] then
 | 
			
		||||
                 Message(parser_e_illegal_expression);
 | 
			
		||||
             end;
 | 
			
		||||
         end;
 | 
			
		||||
        if not handled then
 | 
			
		||||
          result:=inherited pass_typecheck;
 | 
			
		||||
 | 
			
		||||
@ -208,74 +208,9 @@ implementation
 | 
			
		||||
 | 
			
		||||
    { second_handle_ the sizeof and typeof routines }
 | 
			
		||||
    procedure tcginlinenode.second_SizeOfTypeOf;
 | 
			
		||||
      var
 | 
			
		||||
         href,
 | 
			
		||||
         hrefvmt   : treference;
 | 
			
		||||
         hregister : tregister;
 | 
			
		||||
      begin
 | 
			
		||||
        location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
 | 
			
		||||
        { for both cases load vmt }
 | 
			
		||||
        if left.nodetype=typen then
 | 
			
		||||
          begin
 | 
			
		||||
            hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
 | 
			
		||||
            reference_reset_symbol(href,current_asmdata.RefAsmSymbol(tobjectdef(left.resultdef).vmt_mangledname,AT_DATA),0,voidpointertype.size);
 | 
			
		||||
            hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,href,hregister);
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          begin
 | 
			
		||||
            secondpass(left);
 | 
			
		||||
            hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
 | 
			
		||||
 | 
			
		||||
            { handle self inside a method of a class }
 | 
			
		||||
            case left.location.loc of
 | 
			
		||||
              LOC_CREGISTER,
 | 
			
		||||
              LOC_REGISTER :
 | 
			
		||||
                begin
 | 
			
		||||
                  if (left.resultdef.typ=classrefdef) or
 | 
			
		||||
                     (po_staticmethod in current_procinfo.procdef.procoptions) then
 | 
			
		||||
                    hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,left.location.register,hregister)
 | 
			
		||||
                  else
 | 
			
		||||
                   begin
 | 
			
		||||
                     { load VMT pointer }
 | 
			
		||||
                     hlcg.reference_reset_base(hrefvmt,voidpointertype,left.location.register,tobjectdef(left.resultdef).vmt_offset,voidpointertype.size);
 | 
			
		||||
                     hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,hrefvmt,hregister);
 | 
			
		||||
                   end
 | 
			
		||||
                end;
 | 
			
		||||
              LOC_REFERENCE,
 | 
			
		||||
              LOC_CREFERENCE :
 | 
			
		||||
                begin
 | 
			
		||||
                  if is_class(left.resultdef) then
 | 
			
		||||
                   begin
 | 
			
		||||
                     { deref class }
 | 
			
		||||
                     hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,left.location.reference,hregister);
 | 
			
		||||
                     hlcg.g_maybe_testself(current_asmdata.CurrAsmList,left.resultdef,hregister);
 | 
			
		||||
                     { load VMT pointer }
 | 
			
		||||
                     hlcg.reference_reset_base(hrefvmt,voidpointertype,hregister,tobjectdef(left.resultdef).vmt_offset,voidpointertype.size);
 | 
			
		||||
                     hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,hrefvmt,hregister);
 | 
			
		||||
                   end
 | 
			
		||||
                  else
 | 
			
		||||
                   begin
 | 
			
		||||
                     { load VMT pointer, but not for classrefdefs }
 | 
			
		||||
                     if (left.resultdef.typ=objectdef) then
 | 
			
		||||
                       begin
 | 
			
		||||
                         inc(left.location.reference.offset,tobjectdef(left.resultdef).vmt_offset);
 | 
			
		||||
                         left.location.reference.alignment:=newalignment(left.location.reference.alignment,tobjectdef(left.resultdef).vmt_offset);
 | 
			
		||||
                       end;
 | 
			
		||||
                     hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,voidpointertype,voidpointertype,left.location.reference,hregister);
 | 
			
		||||
                   end;
 | 
			
		||||
                end;
 | 
			
		||||
              else
 | 
			
		||||
                internalerror(200301301);
 | 
			
		||||
            end;
 | 
			
		||||
          end;
 | 
			
		||||
        { in sizeof load size }
 | 
			
		||||
        if inlinenumber=in_sizeof_x then
 | 
			
		||||
           begin
 | 
			
		||||
             hlcg.reference_reset_base(href,voidpointertype,hregister,0,voidpointertype.size);
 | 
			
		||||
             hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
 | 
			
		||||
             cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,href,hregister);
 | 
			
		||||
           end;
 | 
			
		||||
        location.register:=hregister;
 | 
			
		||||
        { handled in pass 1 }
 | 
			
		||||
        internalerror(2015122701);
 | 
			
		||||
     end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3296,6 +3296,7 @@ implementation
 | 
			
		||||
      var
 | 
			
		||||
         hp: tnode;
 | 
			
		||||
         shiftconst: longint;
 | 
			
		||||
         objdef: tobjectdef;
 | 
			
		||||
 | 
			
		||||
      begin
 | 
			
		||||
         result:=nil;
 | 
			
		||||
@ -3341,10 +3342,34 @@ implementation
 | 
			
		||||
          in_typeof_x:
 | 
			
		||||
            begin
 | 
			
		||||
              expectloc:=LOC_REGISTER;
 | 
			
		||||
              if (left.nodetype=typen) and
 | 
			
		||||
                 (cs_create_pic in current_settings.moduleswitches) and
 | 
			
		||||
                 (tf_pic_uses_got in target_info.flags) then
 | 
			
		||||
                include(current_procinfo.flags,pi_needs_got);
 | 
			
		||||
              case left.resultdef.typ of
 | 
			
		||||
                objectdef,classrefdef:
 | 
			
		||||
                  begin
 | 
			
		||||
                    if left.resultdef.typ=objectdef then
 | 
			
		||||
                      begin
 | 
			
		||||
                        result:=cloadvmtaddrnode.create(left);
 | 
			
		||||
                        objdef:=tobjectdef(left.resultdef);
 | 
			
		||||
                      end
 | 
			
		||||
                    else
 | 
			
		||||
                      begin
 | 
			
		||||
                        result:=left;
 | 
			
		||||
                        objdef:=tobjectdef(tclassrefdef(left.resultdef).pointeddef);
 | 
			
		||||
                      end;
 | 
			
		||||
                    left:=nil;
 | 
			
		||||
                    if inlinenumber=in_sizeof_x then
 | 
			
		||||
                      begin
 | 
			
		||||
                        inserttypeconv_explicit(result,cpointerdef.getreusable(objdef.vmt_def));
 | 
			
		||||
                        result:=cderefnode.create(result);
 | 
			
		||||
                        result:=genloadfield(result,'VINSTANCESIZE');
 | 
			
		||||
                      end
 | 
			
		||||
                    else
 | 
			
		||||
                      inserttypeconv_explicit(result,voidpointertype);
 | 
			
		||||
                  end;
 | 
			
		||||
                undefineddef:
 | 
			
		||||
                  ;
 | 
			
		||||
                else
 | 
			
		||||
                  internalerror(2015122702);
 | 
			
		||||
              end;
 | 
			
		||||
            end;
 | 
			
		||||
 | 
			
		||||
          in_length_x:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user