Press enter to see results or esc to cancel.

Creating Pointer to Variable Reference

This procedure creates a pointer to any variable reference including procedures and functions. It is used for the @ operator and system functions Addr, Seg and Ofs. Its reverse operation is pointer dereference.

Procedure TExpression.CreatePointerToVariableReference;
Var PointerTypeDefinition: PPointerTypeDefinition;
    UnitIdentifierData: PUnitIdentifierData;
    ProcedureIdentifierData: PProcedureIdentifierData;
begin
  If Location = elProcedure then
    begin
      ProcedureIdentifierData := PProcedureIdentifierData (PChar (TypeDefPtr) - 10);
      If ((pfMethod in ProcedureIdentifierData^.Flags) and not (mcStatic in DataType)) or
         (pfInline in ProcedureIdentifierData^.Flags) then Error (InvalidProcedureOrFunctionReference);
      Location := elPointerToMemory;
      DataType := [it32Bit, it16Bit, itSigned];
      UsedRegisters := [];
      LocationData.Flags := [efTypedConstant];
      Value.Offset := 0;
      Value.BlockRecord := ProcedureIdentifierData^.ProceduresRecordOffset;
      Value.Segment := Seg (ProcedureIdentifierData^);
      TypeDefPtr := Ptr (SystemUnitSegment, Pointer_TypeOffset);
      Exit;
    end;
  If TypeDefPtr^.BaseType <> btFunctionProcedure then
    begin
      Location := elPointerToMemory;
      DataType := itLongInt;
      Exclude (LocationData.Flags, efReadOnly);
      If TypedPointers in StatementCompilerSwitches then
        begin
          PointerTypeDefinition := Ptr (DSeg, GetTempBufferOffset (SizeOf (TPointerTypeDefinition) + 2));
          UnitIdentifierData := Ptr (DSeg, Ofs (PointerTypeDefinition^) + SizeOf (TPointerTypeDefinition));
          With PointerTypeDefinition^ do
            begin
              BaseType := btPointer;
              DataType := [it32Bit, it16Bit, itSigned];
              Size := 4;
              W06_ := 0;
              PointerBaseTypeOffset.TypeOffset := Ofs (TypeDefPtr^);
              PointerBaseTypeOffset.UnitIdentifierData := Ofs (UnitIdentifierData^);
            end;
          UnitIdentifierData^.UnitSegment := Seg (TypeDefPtr^);
          TypeDefPtr := Pointer (PointerTypeDefinition);
        end else TypeDefPtr := Ptr (SystemUnitSegment, Pointer_TypeOffset);
    end else TypeDefPtr := Ptr (SystemUnitSegment, Pointer_TypeOffset);
end;