fixed on usage msgSend function for parametered functions; fix for returning structures as a result

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@446 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2008-04-30 13:51:19 +00:00
parent ece0e03c29
commit 81763fac6a
4 changed files with 178 additions and 70 deletions

View File

@@ -294,6 +294,17 @@ type
{ TClassDef } { TClassDef }
{ TClassesForward }
TClassesForward = class(TEntity)
protected
function DoParse(AParser: TTextParser): Boolean; override;
public
_Classes : TStringList;
constructor Create(AOwner: TEntity);
destructor Destroy; override;
end;
TClassDef = class(TEntity) TClassDef = class(TEntity)
protected protected
function DoParse(AParser: TTextParser): Boolean; override; function DoParse(AParser: TTextParser): Boolean; override;
@@ -1040,10 +1051,20 @@ begin
ent := TEnumTypeDef.Create(Self); ent := TEnumTypeDef.Create(Self);
if not ent.Parse(AParser) then Exit; if not ent.Parse(AParser) then Exit;
AParser.FindNextToken(s, tt); // skipping last ';' AParser.FindNextToken(s, tt); // skipping last ';'
end else if s = 'struct' then begin
APArser.index := APArser.TokenPos;
ent := TStructTypeDef.Create(SElf);
if not ent.Parse(AParser) then Exit;
AParser.FindNextToken(s, tt); //? skipping last ';'?
if s <> ';' then AParser.Index := AParser.TokenPos;
end else if s = '@interface' then begin end else if s = '@interface' then begin
AParser.Index := AParser.TokenPos; AParser.Index := AParser.TokenPos;
ent := TClassDef.Create(Self); ent := TClassDef.Create(Self);
if not ent.Parse(AParser) then Exit; if not ent.Parse(AParser) then Exit;
end else if s = '@class' then begin
AParser.Index := AParser.TokenPos;
ent := TClassesForward.create(Self);
if not ent.Parse(AParser) then Exit;
end else begin end else begin
// anything else is skipped, though should not! // anything else is skipped, though should not!
ent := TSkip.Create(Self); ent := TSkip.Create(Self);
@@ -1924,4 +1945,37 @@ begin
end; end;
end; end;
{ TClassesForward }
function TClassesForward.DoParse(AParser: TTextParser): Boolean;
var
s : AnsiString;
tt : TTokenType;
begin
AParser.FindNextToken(s, tt);
if s <> '@class' then begin
AParser.SetError( ErrExpectStr('@class', s));
Exit;
end;
while s <> ';' do begin
AParser.FindNextToken(s, tt);
if tt = tt_Ident then
_Classes.Add(s);
end;
Result := true;
end;
constructor TClassesForward.Create(AOwner: TEntity);
begin
inherited Create(AOwner);
_Classes:=TStringList.Create;
end;
destructor TClassesForward.Destroy;
begin
_Classes.Free;
inherited Destroy;
end;
end. end.

View File

@@ -219,7 +219,7 @@ begin
tp := TTypeDef(TObjCParameterDef(p)._Type._Type); tp := TTypeDef(TObjCParameterDef(p)._Type._Type);
vtype := ObjCToDelphiType(tp._Name, tp._IsPointer); vtype := ObjCToDelphiType(tp._Name, tp._IsPointer);
end else begin end else begin
prc := 'TProc' + TObjCParameterDef(p)._Name + IntToStr(ConvertSettings.CustomTypes.Count); prc := 'TProc' + TClassDef(m.Owner)._ClassName + TObjCParameterDef(p)._Name + IntToStr(ConvertSettings.CustomTypes.Count);
ConvertSettings.AssignNewTypeName(prc, CToDelphiFuncType(TFunctionTypeDef(TObjCParameterDef(p)._Type._Type)), vtype); ConvertSettings.AssignNewTypeName(prc, CToDelphiFuncType(TFunctionTypeDef(TObjCParameterDef(p)._Type._Type)), vtype);
tp := TTypeDef.Create(TObjCParameterDef(p)._Type); tp := TTypeDef.Create(TObjCParameterDef(p)._Type);
tp._Name := vtype; tp._Name := vtype;
@@ -361,9 +361,9 @@ begin
for i := 0 to mtd.Items.Count - 1 do begin for i := 0 to mtd.Items.Count - 1 do begin
obj := mtd.Items[i]; obj := mtd.Items[i];
if not Assigned(obj) then Continue; if not Assigned(obj) then Continue;
if obj is TParamDescr then if obj is TParamDescr then begin
Result := Result + TParamDescr(obj)._Descr Result := Result + TParamDescr(obj)._Descr;
else if obj is TObjCParameterDef then end else if obj is TObjCParameterDef then
Result := Result + '_'; Result := Result + '_';
end; end;
i := length(Result); i := length(Result);
@@ -1295,19 +1295,27 @@ const
MtdPrefix = 'TMtd_'; MtdPrefix = 'TMtd_';
MtdPostfix = ''; MtdPostfix = '';
procedure ObjCMethodToProcType(mtd: TClassMethodDef; var typeName: AnsiString; subs: TStrings); procedure ObjCMethodToProcType(mtd: TClassMethodDef; var typeName: AnsiString; subs: TStrings; isResultStruct: Boolean);
var var
s : AnsiString; s : AnsiString;
ms : AnsiString; ms : AnsiString;
restype : AnsiString; restype : AnsiString;
begin begin
typeName := MtdPrefix + mtd._Name + MtdPostFix; //typeName := MtdPrefix + mtd._Name + MtdPostFix;
typeName := 'TmsgSendWrapper';
subs.Add('type'); subs.Add('type');
ms := GetMethodParams(mtd, false); ms := GetMethodParams(mtd, false);
if ms = '' then ms := 'param1: objc.id; param2: SEL' if ms = '' then ms := 'param1: objc.id; param2: SEL'
else ms := 'param1: objc.id; param2: SEL' + ';' + ms; else ms := 'param1: objc.id; param2: SEL' + ';' + ms;
if isResultStruct then begin
restype := '';
ms := 'result_param: Pointer; ' + ms;
end else begin
restype := GetMethodResultType(mtd); restype := GetMethodResultType(mtd);
if IsMethodConstructor(mtd.Owner as TClassDef, mtd) then restype := 'objc.id'; if IsMethodConstructor(mtd.Owner as TClassDef, mtd) then restype := 'objc.id';
end;
s := Format(' %s = %s cdecl;',[typeName, GetProcFuncHead('', '', ms, restype, '' )]); s := Format(' %s = %s cdecl;',[typeName, GetProcFuncHead('', '', ms, restype, '' )]);
subs.Add(s); subs.Add(s);
@@ -1356,7 +1364,7 @@ var
prms : AnsiString; prms : AnsiString;
begin begin
cl := TClassDef(mtd.Owner); cl := TClassDef(mtd.Owner);
ObjCMethodToProcType(mtd, typeName, subs); ObjCMethodToProcType(mtd, typeName, subs, false);
prms := GetMethodParams(mtd, true); prms := GetMethodParams(mtd, true);
if prms <> '' then prms := ', ' + prms; if prms <> '' then prms := ', ' + prms;
@@ -1402,6 +1410,7 @@ var
res : AnsiString; res : AnsiString;
callobj : AnsiString; callobj : AnsiString;
mnm : AnsiString; mnm : AnsiString;
prms : AnsiString;
begin begin
cl := TClassDef(mtd.Owner); cl := TClassDef(mtd.Owner);
callobj := ClassMethodCaller[mtd._IsClassMethod]; callobj := ClassMethodCaller[mtd._IsClassMethod];
@@ -1410,10 +1419,11 @@ begin
mnm := RefixName(mtd._Name); mnm := RefixName(mtd._Name);
//s := Format('vmethod(%s, sel_registerName(PChar(Str%s_%s)), %s)', [callobj, cl._ClassName, RefixName(mtd._Name), GetParamsNames(mtd)]); //s := Format('vmethod(%s, sel_registerName(PChar(Str%s_%s)), %s)', [callobj, cl._ClassName, RefixName(mtd._Name), GetParamsNames(mtd)]);
tp := GetObjCVarType(res); tp := GetObjCVarType(res);
prms := GetMethodParams(mtd, true);
case tp of case tp of
vt_Int, vt_Object: s := Format('objc_msgSend(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]); vt_Int, vt_Object: s := Format('vmethod(%s, sel_registerName(PChar(Str%s_%s)), %s)', [callobj, cl._ClassName, mnm, prms]);
vt_FloatPoint: s := Format('objc_msgSend_fpret(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]); vt_FloatPoint: s := Format('vmethod(%s, sel_registerName(PChar(Str%s_%s)), %s)', [callobj, cl._ClassName, mnm, prms]);
vt_Struct: s := Format('objc_msgSend_stret(@Result, %s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]); vt_Struct: s := Format('vmethod(@Result, %s, sel_registerName(PChar(Str%s_%s)), %s)', [callobj, cl._ClassName, mnm, prms]);
end; end;
if (tp <> vt_Struct) and (ObjCResultToDelphiType(mtd.GetResultType) <> '') then begin if (tp <> vt_Struct) and (ObjCResultToDelphiType(mtd.GetResultType) <> '') then begin
@@ -1425,13 +1435,17 @@ begin
end; end;
ObjCMethodToProcType(mtd, typeName, subs); ObjCMethodToProcType(mtd, typeName, subs, tp=vt_Struct);
subs.Add('var'); subs.Add('var');
subs.Add( subs.Add(
Format(' vmethod: %s;', [typeName])); Format(' vmethod: %s;', [typeName]));
subs.Add('begin'); subs.Add('begin');
subs.Add( case tp of
Format(' vmethod := %s(@objc_msgSend);', [typeName])); vt_Struct: subs.Add(Format(' vmethod := %s(@objc_msgSend_fpret);', [typeName]));
vt_FloatPoint: subs.Add(Format(' vmethod := %s(@objc_msgSend_stret);', [typeName]));
else
subs.Add( Format(' vmethod := %s(@objc_msgSend);', [typeName]));
end;
subs.Add( subs.Add(
Format(' %s;', [s])); Format(' %s;', [s]));
subs.Add('end;'); subs.Add('end;');
@@ -1452,24 +1466,14 @@ begin
res := GetMethodResultType(mtd); res := GetMethodResultType(mtd);
tp := GetObjCVarType(res); tp := GetObjCVarType(res);
{ if tp = vt_Object then begin
subs.Add('var');
subs.Add(' hnd: objc.id;');
subs.Add('begin');
subs.Add(' hnd := ' + Format('objc_msgSend(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, RefixName(mtd._Name) ]));
subs.Add(' if Assigned(hnd) then begin ');
subs.Add(' Result := ' + Format('%s.Create; ', [res]) );
subs.Add(' Result.Handle := hnd;');
subs.Add(' end else');
subs.Add(' Result := nil;');
subs.Add('end;');
end else begin}
mnm := RefixName(mtd._Name); mnm := RefixName(mtd._Name);
case tp of case tp of
vt_Int, vt_Object: s := Format('objc_msgSend(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]); vt_Int, vt_Object:
vt_FloatPoint: s := Format('objc_msgSend_fpret(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]); s := Format('objc_msgSend(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]);
vt_Struct: s := Format('objc_msgSend_stret(@Result, %s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]); vt_FloatPoint:
s := Format('objc_msgSend_fpret(%s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]);
vt_Struct:
s := Format('objc_msgSend_stret(@Result, %s, sel_registerName(PChar(Str%s_%s)), [])', [callobj, cl._ClassName, mnm ]);
end; end;
if (tp <> vt_Struct) and (res <> '') then begin if (tp <> vt_Struct) and (res <> '') then begin
@@ -1477,16 +1481,13 @@ begin
s := Format('Result := %s(%s)', [res, s]) s := Format('Result := %s(%s)', [res, s])
else else
s := Format('Result := %s', [s]); s := Format('Result := %s', [s]);
//s := 'Result := '+res+'('+s+')';
//if res = 'objc.id' then s := 'Result := ' +s
//else
end; end;
s := s + ';'; s := s + ';';
subs.Add('begin'); subs.Add('begin');
subs.Add(' ' + s); subs.Add(' ' + s);
subs.Add('end;'); subs.Add('end;');
// end;
end; end;
procedure WriteOutMethodToImplementation(mtd: TClassMethodDef; subs: TStrings); procedure WriteOutMethodToImplementation(mtd: TClassMethodDef; subs: TStrings);
@@ -1683,6 +1684,7 @@ end;
procedure AppleHeaderFix(ent : TEntity); procedure AppleHeaderFix(ent : TEntity);
var var
i : Integer; i : Integer;
j : Integer;
obj : TEntity; obj : TEntity;
prm : TObjCParameterDef; prm : TObjCParameterDef;
res : TObjCResultTypeDef; res : TObjCResultTypeDef;
@@ -1701,9 +1703,9 @@ begin
end else if (obj is TClassDef) and ((TClassDef(obj)._Category = '') and (TClassDef(obj)._ClassName = 'NSObject')) then begin end else if (obj is TClassDef) and ((TClassDef(obj)._Category = '') and (TClassDef(obj)._ClassName = 'NSObject')) then begin
if TClassDef(obj)._SuperClass = '' then if TClassDef(obj)._SuperClass = '' then
TClassDef(obj)._SuperClass := 'TObject' TClassDef(obj)._SuperClass := 'TObject'
end else if (obj is TParamDescr) then begin {end else if (obj is TParamDescr) then begin
if IsPascalReserved(TParamDescr(obj)._Descr) then if IsPascalReserved(TParamDescr(obj)._Descr) then
TParamDescr(obj)._Descr := '_'+TParamDescr(obj)._Descr TParamDescr(obj)._Descr := '_'+TParamDescr(obj)._Descr}
end else if (obj is TClassMethodDef) and not IsMethodConstructor(TClassDef(obj.Owner ), TClassMethodDef(obj)) then begin end else if (obj is TClassMethodDef) and not IsMethodConstructor(TClassDef(obj.Owner ), TClassMethodDef(obj)) then begin
res := TClassMethodDef(obj).GetResultType; res := TClassMethodDef(obj).GetResultType;
if ConvertSettings.ObjCClassTypes.IndexOf( ObjCResultToDelphiType(res))>= 0 then if ConvertSettings.ObjCClassTypes.IndexOf( ObjCResultToDelphiType(res))>= 0 then
@@ -1729,6 +1731,9 @@ begin
if ConvertSettings.ObjCClassTypes.IndexOf(TStructField(obj)._TypeName) >= 0 then begin if ConvertSettings.ObjCClassTypes.IndexOf(TStructField(obj)._TypeName) >= 0 then begin
TStructField(obj)._TypeName := 'objc.id' TStructField(obj)._TypeName := 'objc.id'
end; end;
end else if (obj is TClassesForward) then begin
for j := 0 to TClassesForward(obj)._Classes.Count - 1 do
ConvertSettings.ObjCClassTypes.Add( TClassesForward(obj)._Classes[j]);
end; end;
@@ -1774,12 +1779,31 @@ var
cl : TClassDef; cl : TClassDef;
subs : TStringList; subs : TStringList;
consts : TStringList; consts : TStringList;
used : TStringList;
begin begin
subs := TStringList.Create; subs := TStringList.Create;
consts := TStringList.Create; consts := TStringList.Create;
try try
st.AddStrings(ConvertSettings.ConvertPrefix); st.AddStrings(ConvertSettings.ConvertPrefix);
used := TStringList.Create;
try
for i := 0 to hdr.Items.Count - 1 do begin
if (TObject(hdr.Items[i]) is TClassDef) then begin
cl := TClassDef(hdr.Items[i]);
if (cl._Category = '') then begin
WriteOutClassToConsts(cl, subs, consts);
used.Add(cl._ClassName);
end else if used.IndexOf(cl._Classname) >= 0 then begin
WriteOutClassToConsts(cl, subs, consts);
end;
end;
end;
finally
used.Free;
used := nil;
end;
if hdr.Items.Count <= 0 then Exit; if hdr.Items.Count <= 0 then Exit;
AppleHeaderFix(hdr); AppleHeaderFix(hdr);
@@ -1793,17 +1817,10 @@ begin
hdr.Items.Delete(0); hdr.Items.Delete(0);
end; end;
for i := 0 to hdr.Items.Count - 1 do begin
if (TObject(hdr.Items[i]) is TClassDef) then begin
cl := TClassDef(hdr.Items[i]);
WriteOutClassToConsts(cl, subs, consts);
end;
end;
WriteOutHeaderSection(hdr, st); WriteOutHeaderSection(hdr, st);
WriteOutForwardSection(hdr, st); WriteOutForwardSection(hdr, st);
for i := 0 to hdr.Items.Count - 1 do for i := 0 to hdr.Items.Count - 1 do
if TObject(hdr.Items[i]) is TClassDef then if TObject(hdr.Items[i]) is TClassDef then
FixAppleClassDef(TClassDef(hdr.Items[i])); FixAppleClassDef(TClassDef(hdr.Items[i]));

View File

@@ -1,5 +1,5 @@
[common] [common]
ignoreincludes0=CoreFoundation/ Foundation/ ignoreincludes0=CoreFoundation/
ignoreincludes1=setjmp.h stdarg.h stdbool.h limits.h stdarg.h ignoreincludes1=setjmp.h stdarg.h stdbool.h limits.h stdarg.h
ignoreincludes2=AvailabilityMacros.h ignoreincludes2=AvailabilityMacros.h
ignoreincludes3=ApplicationServices/ ignoreincludes3=ApplicationServices/
@@ -7,6 +7,7 @@ ignoreincludes4=ApplicationServices/../FrameWorks/CoreGraphics.framework/Headers
ignoreincludes5=AvailabilityMacros.h ignoreincludes5=AvailabilityMacros.h
[TypeReplace] [TypeReplace]
NSRect=CGRect
NSStringRef=CFStringRef NSStringRef=CFStringRef
NSStringRef*=CFStringRef NSStringRef*=CFStringRef
NSArray=CFArrayRef NSArray=CFArrayRef
@@ -65,7 +66,7 @@ CGSize=struct
CGPoint=struct CGPoint=struct
CFTimeInterval=float CFTimeInterval=float
CGAffineTransform=struct CGAffineTransform=struct
NSRect=struct
NSPoint=struct NSPoint=struct
NSSize=struct NSSize=struct
NSRange=struct NSRange=struct

View File

@@ -36,7 +36,7 @@
<Filename Value="objcparser.pas"/> <Filename Value="objcparser.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="objcparser"/> <UnitName Value="objcparser"/>
<CursorPos X="69" Y="3"/> <CursorPos X="45" Y="11"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="26"/> <UsageCount Value="26"/>
@@ -45,8 +45,8 @@
<Unit1> <Unit1>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<UnitName Value="ObjCParserUtils"/> <UnitName Value="ObjCParserUtils"/>
<CursorPos X="44" Y="1705"/> <CursorPos X="13" Y="1305"/>
<TopLine Value="1703"/> <TopLine Value="1293"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<UsageCount Value="13"/> <UsageCount Value="13"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@@ -54,22 +54,58 @@
<Unit2> <Unit2>
<Filename Value="ObjCParserTypes.pas"/> <Filename Value="ObjCParserTypes.pas"/>
<UnitName Value="ObjCParserTypes"/> <UnitName Value="ObjCParserTypes"/>
<CursorPos X="30" Y="85"/> <CursorPos X="18" Y="1966"/>
<TopLine Value="64"/> <TopLine Value="1950"/>
<EditorIndex Value="2"/> <EditorIndex Value="2"/>
<UsageCount Value="13"/> <UsageCount Value="13"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit2> </Unit2>
</Units> </Units>
<JumpHistory Count="2" HistoryIndex="1"> <JumpHistory Count="11" HistoryIndex="10">
<Position1> <Position1>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1708" Column="49" TopLine="1699"/> <Caret Line="1772" Column="46" TopLine="1769"/>
</Position1> </Position1>
<Position2> <Position2>
<Filename Value="ObjCParserUtils.pas"/> <Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1707" Column="93" TopLine="1694"/> <Caret Line="1" Column="1" TopLine="1"/>
</Position2> </Position2>
<Position3>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="64" Column="85" TopLine="52"/>
</Position3>
<Position4>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="89" Column="42" TopLine="77"/>
</Position4>
<Position5>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="91" Column="39" TopLine="79"/>
</Position5>
<Position6>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="98" Column="39" TopLine="86"/>
</Position6>
<Position7>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="101" Column="32" TopLine="89"/>
</Position7>
<Position8>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="106" Column="49" TopLine="94"/>
</Position8>
<Position9>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position9>
<Position10>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1365" Column="15" TopLine="1361"/>
</Position10>
<Position11>
<Filename Value="ObjCParserUtils.pas"/>
<Caret Line="1306" Column="3" TopLine="1295"/>
</Position11>
</JumpHistory> </JumpHistory>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>