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;