mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-29 20:01:55 +01:00
compiler: write extended RTTI for tkProcVar (tkProcedure in Delphi)
rtl: add appropriate types for tkProcVar RTTI (based on Delphi help) + test git-svn-id: trunk@24468 -
This commit is contained in:
parent
2d67a3169d
commit
bc973e538d
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -11692,6 +11692,7 @@ tests/test/trtti5.pp svneol=native#text/plain
|
|||||||
tests/test/trtti6.pp svneol=native#text/pascal
|
tests/test/trtti6.pp svneol=native#text/pascal
|
||||||
tests/test/trtti7.pp svneol=native#text/pascal
|
tests/test/trtti7.pp svneol=native#text/pascal
|
||||||
tests/test/trtti8.pp svneol=native#text/pascal
|
tests/test/trtti8.pp svneol=native#text/pascal
|
||||||
|
tests/test/trtti9.pp svneol=native#text/pascal
|
||||||
tests/test/tsafecall1.pp svneol=native#text/plain
|
tests/test/tsafecall1.pp svneol=native#text/plain
|
||||||
tests/test/tsafecall2.pp svneol=native#text/pascal
|
tests/test/tsafecall2.pp svneol=native#text/pascal
|
||||||
tests/test/tsafecall3.pp svneol=native#text/pascal
|
tests/test/tsafecall3.pp svneol=native#text/pascal
|
||||||
|
|||||||
@ -693,12 +693,9 @@ implementation
|
|||||||
{ pocall_interrupt } 12
|
{ pocall_interrupt } 12
|
||||||
);
|
);
|
||||||
|
|
||||||
procedure write_para(parasym:tparavarsym);
|
procedure write_param_flag(parasym:tparavarsym);
|
||||||
var
|
var
|
||||||
paraspec : byte;
|
paraspec : byte;
|
||||||
begin
|
|
||||||
{ only store user visible parameters }
|
|
||||||
if not(vo_is_hidden_para in parasym.varoptions) then
|
|
||||||
begin
|
begin
|
||||||
case parasym.varspez of
|
case parasym.varspez of
|
||||||
vs_value : paraspec := 0;
|
vs_value : paraspec := 0;
|
||||||
@ -724,6 +721,15 @@ implementation
|
|||||||
paraspec:=reverse_byte(paraspec);
|
paraspec:=reverse_byte(paraspec);
|
||||||
{ write flags for current parameter }
|
{ write flags for current parameter }
|
||||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(paraspec));
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(paraspec));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure write_para(parasym:tparavarsym);
|
||||||
|
begin
|
||||||
|
{ only store user visible parameters }
|
||||||
|
if not(vo_is_hidden_para in parasym.varoptions) then
|
||||||
|
begin
|
||||||
|
{ write flags for current parameter }
|
||||||
|
write_param_flag(parasym);
|
||||||
{ write name of current parameter }
|
{ write name of current parameter }
|
||||||
write_string(parasym.realname);
|
write_string(parasym.realname);
|
||||||
{ write name of type of current parameter }
|
{ write name of type of current parameter }
|
||||||
@ -731,6 +737,20 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure write_procedure_param(parasym:tparavarsym);
|
||||||
|
begin
|
||||||
|
{ only store user visible parameters }
|
||||||
|
if not(vo_is_hidden_para in parasym.varoptions) then
|
||||||
|
begin
|
||||||
|
{ write flags for current parameter }
|
||||||
|
write_param_flag(parasym);
|
||||||
|
{ write param type }
|
||||||
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(parasym.vardef,fullrtti)));
|
||||||
|
{ write name of current parameter }
|
||||||
|
write_string(parasym.realname);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
methodkind : byte;
|
methodkind : byte;
|
||||||
i : integer;
|
i : integer;
|
||||||
@ -795,7 +815,27 @@ implementation
|
|||||||
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(tparavarsym(def.paras[i]).vardef,fullrtti)));
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(tparavarsym(def.paras[i]).vardef,fullrtti)));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
begin
|
||||||
write_header(def,tkProcvar);
|
write_header(def,tkProcvar);
|
||||||
|
maybe_write_align;
|
||||||
|
|
||||||
|
{ flags }
|
||||||
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
|
||||||
|
maybe_write_align;
|
||||||
|
{ write calling convention }
|
||||||
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ProcCallOptionToCallConv[def.proccalloption]));
|
||||||
|
maybe_write_align;
|
||||||
|
{ write result typeinfo }
|
||||||
|
if is_void(def.returndef) then
|
||||||
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(nil))
|
||||||
|
else
|
||||||
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.returndef,fullrtti)));
|
||||||
|
{ write parameter count }
|
||||||
|
current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount));
|
||||||
|
maybe_write_align;
|
||||||
|
for i:=0 to def.paras.count-1 do
|
||||||
|
write_procedure_param(tparavarsym(def.paras[i]));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -125,6 +125,7 @@ unit typinfo;
|
|||||||
Dims: array[0..255] of PTypeInfo;
|
Dims: array[0..255] of PTypeInfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
PManagedField = ^TManagedField;
|
||||||
TManagedField =
|
TManagedField =
|
||||||
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
packed
|
packed
|
||||||
@ -134,6 +135,29 @@ unit typinfo;
|
|||||||
FldOffset: SizeInt;
|
FldOffset: SizeInt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
PProcedureParam = ^TProcedureParam;
|
||||||
|
TProcedureParam =
|
||||||
|
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
|
packed
|
||||||
|
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
|
record
|
||||||
|
Flags: Byte;
|
||||||
|
ParamType: PPTypeInfo;
|
||||||
|
Name: ShortString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TProcedureSignature =
|
||||||
|
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
|
packed
|
||||||
|
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
|
||||||
|
record
|
||||||
|
Flags: Byte;
|
||||||
|
CC: TCallConv;
|
||||||
|
ResultType: PTypeInfo;
|
||||||
|
ParamCount: Byte;
|
||||||
|
{Params: array[1..ParamCount] of TProcedureParam;}
|
||||||
|
end;
|
||||||
|
|
||||||
{$PACKRECORDS C}
|
{$PACKRECORDS C}
|
||||||
PTypeData = ^TTypeData;
|
PTypeData = ^TTypeData;
|
||||||
TTypeData =
|
TTypeData =
|
||||||
@ -203,6 +227,8 @@ unit typinfo;
|
|||||||
CC : TCallConv;
|
CC : TCallConv;
|
||||||
ParamTypeRefs : array[1..ParamCount] of PTypeInfo;}
|
ParamTypeRefs : array[1..ParamCount] of PTypeInfo;}
|
||||||
);
|
);
|
||||||
|
tkProcVar:
|
||||||
|
(ProcSig: TProcedureSignature);
|
||||||
tkInt64:
|
tkInt64:
|
||||||
(MinInt64Value, MaxInt64Value: Int64);
|
(MinInt64Value, MaxInt64Value: Int64);
|
||||||
tkQWord:
|
tkQWord:
|
||||||
@ -223,9 +249,7 @@ unit typinfo;
|
|||||||
IIDStr: ShortString;
|
IIDStr: ShortString;
|
||||||
);
|
);
|
||||||
tkArray:
|
tkArray:
|
||||||
(
|
(ArrayData: TArrayTypeData);
|
||||||
ArrayData: TArrayTypeData;
|
|
||||||
);
|
|
||||||
tkDynArray:
|
tkDynArray:
|
||||||
(
|
(
|
||||||
elSize : PtrUInt;
|
elSize : PtrUInt;
|
||||||
@ -235,13 +259,9 @@ unit typinfo;
|
|||||||
DynUnitName: ShortStringBase
|
DynUnitName: ShortStringBase
|
||||||
);
|
);
|
||||||
tkClassRef:
|
tkClassRef:
|
||||||
(
|
(InstanceType: PTypeInfo);
|
||||||
InstanceType: PTypeInfo;
|
|
||||||
);
|
|
||||||
tkPointer:
|
tkPointer:
|
||||||
(
|
(RefType: PTypeInfo);
|
||||||
RefType: PTypeInfo;
|
|
||||||
);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TPropData =
|
TPropData =
|
||||||
|
|||||||
38
tests/test/trtti9.pp
Normal file
38
tests/test/trtti9.pp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
program trtti9;
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
|
||||||
|
uses
|
||||||
|
typinfo;
|
||||||
|
|
||||||
|
type
|
||||||
|
PProcedureParam = ^TProcedureParam;
|
||||||
|
TProc = procedure(var A: Integer; S: String); stdcall;
|
||||||
|
|
||||||
|
function TestParam(Param: PProcedureParam; Flags: Byte; ParamType: Pointer; Name: ShortString): Boolean;
|
||||||
|
begin
|
||||||
|
Result := (Param^.Flags = Flags) and (Param^.ParamType = ParamType) and (Param^.Name = Name);
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
Info: PTypeInfo;
|
||||||
|
Data: PTypeData;
|
||||||
|
Param: PProcedureParam;
|
||||||
|
begin
|
||||||
|
Info := TypeInfo(TProc);
|
||||||
|
if Info^.Kind <> tkProcedure then
|
||||||
|
halt(1);
|
||||||
|
Data := GetTypeData(Info);
|
||||||
|
if Data^.ProcSig.CC <> ccStdCall then
|
||||||
|
halt(2);
|
||||||
|
if Data^.ProcSig.ResultType <> nil then
|
||||||
|
halt(3);
|
||||||
|
if Data^.ProcSig.ParamCount <> 2 then
|
||||||
|
halt(4);
|
||||||
|
Param := PProcedureParam(PAnsiChar(@Data^.ProcSig.Flags) + SizeOf(TProcedureSignature));
|
||||||
|
if not TestParam(Param, 1, TypeInfo(Integer), 'A') then
|
||||||
|
halt(5);
|
||||||
|
Param := PProcedureParam(PAnsiChar(@Param^.Name) + (Length(Param^.Name) + 1) * SizeOf(AnsiChar));
|
||||||
|
if not TestParam(Param, 0, TypeInfo(String), 'S') then
|
||||||
|
halt(6);
|
||||||
|
end.
|
||||||
Loading…
Reference in New Issue
Block a user