chelper: improved function declaration parsing and extern variables pascal code generation

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1276 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2010-08-12 12:00:21 +00:00
parent 5f20a3f950
commit fc28fcccd9
3 changed files with 50 additions and 11 deletions

View File

@ -323,7 +323,6 @@ type
protected
function DoParse(AParser:TTextParser): Boolean; override;
public
Specifiers : TStringList;
RetType : TEntity;
Names : TList;
constructor Create(AOffset: Integer=-1); override;
@ -1419,6 +1418,32 @@ begin
end;
end;
function isCallConv(const s: AnsiString): AnsiString;
var
i : Integer;
c : AnsiString;
begin
Result:='';
if s='' then Exit;
c:=s;
for i:=1 to length(c) do
if c[i]<>'_' then begin
if i>1 then c:=Copy(c, i, length(c));
Break;
end;
case c[1] of
'c': if (c='cdecl') or (c='clrcall') then Result:=c;
'f': if c='fastcall' then Result:=c;
's': if c='stdcall' then Result:=c;
't': if c='thiscall' then Result:=c;
'p': if c='pascal' then Result:=c;
'r': if c='register' then Result:=c;
end;
end;
procedure ParseSepcifiers(AParser: TTextParser; st: TStrings);
begin
while isSomeSpecifier(AParser.Token) do begin
@ -1676,12 +1701,21 @@ end;
function ParseNames(Parser: TTextParser; var NameType: TEntity; Names: TList; AllowMultipleNames: Boolean): Boolean;
var
Name : TNamePart;
done : Boolean;
specs : TStringList;
done : Boolean;
specs : TStringList;
s : AnsiString;
begin
specs:=TStringList.Create;
ParseSepcifiers(Parser, specs);
NameType:=ParseCType(Parser);
s:=isCallConv(Parser.Token);
if s<>'' then begin
specs.Add(s);
Parser.NextToken;
end;
Result:=Assigned(NameType);
if Result then NameType.Specifiers.Assign(specs);
specs.Free;
@ -1761,13 +1795,11 @@ end;
constructor TVarFuncEntity.Create(AOffset: Integer);
begin
inherited Create(AOffset);
Specifiers:=TStringList.Create;
Names:=TList.Create;
end;
destructor TVarFuncEntity.Destroy;
begin
Specifiers.Free;
inherited Destroy;
end;

View File

@ -26,7 +26,6 @@ uses
// is function declared, i.e. int f()
function isFunc(name: TNamePart): Boolean;
// probably an untyped function: fn ().
// the name of the function has been consumed by TYPE parsing, so ommited!
// so TNamepart doesn't contain any children

View File

@ -129,7 +129,7 @@ type
function NextCommentBefore(AOffset: Integer): Integer;
procedure WriteLnCommentsBeforeOffset(AOffset: Integer);
procedure WriteFuncDecl(const FnName, PasRetType: Ansistring; const params : array of TFuncParam);
procedure WriteFuncDecl(const FnName, PasRetType: AnsiString; const params : array of TFuncParam);
procedure WriteFuncOrVar(cent: TVarFuncEntity; StartVar, WriteComment: Boolean); // todo: deprecate!
procedure WriteTypeDef(tp: TTypeDef);
procedure WriteEnum(en: TEnumType);
@ -725,7 +725,7 @@ begin
(params[0].name=nil);
end;
procedure TCodeConvertor.WriteFuncDecl(const FnName, PasRetType: Ansistring; const params : array of TFuncParam);
procedure TCodeConvertor.WriteFuncDecl(const FnName, PasRetType: AnsiString; const params : array of TFuncParam);
var
i : Integer;
ptypes : array of String;
@ -762,6 +762,12 @@ begin
if cfg.FuncDeclPostfix<>'' then wr.W('; '+cfg.FuncDeclPostfix);
end;
function isDeclExternal(cfg: TConvertSettings; DeclType: TEntity; isFunc: Boolean): Boolean;
begin
Result:=(isfunc and cfg.FuncsAreExternal) or
(Assigned(DeclType) and (DeclType.Specifiers.IndexOf('extern')>=0));
end;
procedure TCodeConvertor.WriteFuncOrVar(cent: TVarFuncEntity; StartVar, WriteComment: Boolean);
var
i, j : integer;
@ -770,6 +776,7 @@ var
id : AnsiString;
ref : TNamePart;
rt : AnsiString;
isfunc : Boolean;
begin
for j := 0 to cent.Names.Count - 1 do
begin
@ -778,6 +785,7 @@ begin
wr.Wln(' bad declaration synax!');
Exit;
end;
isfunc:=False;
id:=cfg.GetUniqueName(name.Id);
n:=name.owner;
if not Assigned(n) then begin
@ -790,7 +798,7 @@ begin
SetPasSection(wr, '');
rt:=GetPasTypeName(cent.RetType, n.owner);
WriteFuncDecl(id, rt, n.params);
if cfg.FuncsAreExternal then wr.W('; external');
isfunc:=True;
end else if (n.Kind=nk_Ref) then begin
if StartVar then SetPasSection(wr, 'var');
wr.W(id + ' : ');
@ -820,8 +828,8 @@ begin
wr.W(GetPasTypeName(cent.RetType, n.owner));
end;
wr.W(';');
if WriteComment then WriteLnCommentForOffset(cent.Offset)
if isDeclExternal(cfg, cent.RetType, isfunc) then wr.W(' external;');
if WriteComment then WriteLnCommentForOffset(cent.Offset);
end;
end;