summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-09-12 23:32:05 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-09-12 23:32:05 +0000
commitce29f2ef0a0bd8a46eb10227c0919da00252ef58 (patch)
tree1e1db80c9b8c7f7718ba0c75e0bff6f2abf45afa /compiler
parent3ae698866307e69253c962def7daa048d2e4ebef (diff)
downloadfpc-ce29f2ef0a0bd8a46eb10227c0919da00252ef58.tar.gz
* added decorator support to the external assembler writers so the LLVM
assembler writer can postprocess their output git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@31626 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler')
-rw-r--r--compiler/assemble.pas164
1 files changed, 135 insertions, 29 deletions
diff --git a/compiler/assemble.pas b/compiler/assemble.pas
index 5ae6e451fd..f0f4715f94 100644
--- a/compiler/assemble.pas
+++ b/compiler/assemble.pas
@@ -62,7 +62,15 @@ interface
TExternalAssembler = class;
+ IExternalAssemblerOutputFileDecorator=interface
+ function LinePrefix: AnsiString;
+ function LinePostfix: AnsiString;
+ function LineFilter(const s: AnsiString): AnsiString;
+ end;
+
TExternalAssemblerOutputFile=class
+ private
+ fdecorator: IExternalAssemblerOutputFileDecorator;
protected
owner: TExternalAssembler;
{outfile}
@@ -72,8 +80,13 @@ interface
outbuf : array[0..AsmOutSize-1] of char;
outfile : file;
fioerror : boolean;
+ linestart: boolean;
Procedure AsmClear;
+ Procedure MaybeAddLinePrefix;
+ Procedure MaybeAddLinePostfix;
+
+ Procedure AsmWriteAnsiStringUnfiltered(const s: ansistring);
public
Constructor Create(_owner: TExternalAssembler);
@@ -86,6 +99,12 @@ interface
{ clears the assembler output if nothing was added since it was marked
as empty, and returns whether it was empty }
function ClearIfEmpty: boolean;
+ { these routines will write the filtered version of their argument
+ according to the current decorator }
+ procedure AsmWriteFiltered(const c:char);
+ procedure AsmWriteFiltered(const s:string);
+ procedure AsmWriteFiltered(const s:ansistring);
+ procedure AsmWriteFiltered(p:pchar; len: longint);
{# Write a string to the assembler file }
Procedure AsmWrite(const c:char);
@@ -107,6 +126,7 @@ interface
procedure AsmClose;
property ioerror: boolean read fioerror;
+ property decorator: IExternalAssemblerOutputFileDecorator read fdecorator write fdecorator;
end;
{# This is the base class which should be overridden for each each
@@ -356,39 +376,67 @@ Implementation
end;
- Procedure TExternalAssemblerOutputFile.AsmClear;
+ procedure TExternalAssemblerOutputFile.AsmWriteFiltered(const c: char);
begin
- outcnt:=0;
+ MaybeAddLinePrefix;
+ AsmWriteAnsiStringUnfiltered(decorator.LineFilter(c));
end;
- constructor TExternalAssemblerOutputFile.Create(_owner: TExternalAssembler);
+ procedure TExternalAssemblerOutputFile.AsmWriteFiltered(const s: string);
begin
- owner:=_owner;
+ MaybeAddLinePrefix;
+ AsmWriteAnsiStringUnfiltered(decorator.LineFilter(s));
end;
- Procedure TExternalAssemblerOutputFile.AsmWrite(const c: char);
+ procedure TExternalAssemblerOutputFile.AsmWriteFiltered(const s: ansistring);
begin
- if OutCnt+1>=AsmOutSize then
- AsmFlush;
- OutBuf[OutCnt]:=c;
- inc(OutCnt);
- inc(AsmSize);
+ MaybeAddLinePrefix;
+ AsmWriteAnsiStringUnfiltered(decorator.LineFilter(s));
end;
- Procedure TExternalAssemblerOutputFile.AsmWrite(const s:string);
+ procedure TExternalAssemblerOutputFile.AsmWriteFiltered(p: pchar; len: longint);
+ var
+ s: ansistring;
begin
- if OutCnt+length(s)>=AsmOutSize then
- AsmFlush;
- Move(s[1],OutBuf[OutCnt],length(s));
- inc(OutCnt,length(s));
- inc(AsmSize,length(s));
+ MaybeAddLinePrefix;
+ setlength(s,len);
+ move(p^,s[1],len);
+ AsmWriteAnsiStringUnfiltered(decorator.LineFilter(s));
end;
- Procedure TExternalAssemblerOutputFile.AsmWrite(const s:ansistring);
+ Procedure TExternalAssemblerOutputFile.AsmClear;
+ begin
+ outcnt:=0;
+ end;
+
+
+ procedure TExternalAssemblerOutputFile.MaybeAddLinePrefix;
+ begin
+ if assigned(decorator) and
+ linestart then
+ begin
+ AsmWriteAnsiStringUnfiltered(decorator.LinePrefix);
+ linestart:=false;
+ end;
+ end;
+
+
+ procedure TExternalAssemblerOutputFile.MaybeAddLinePostfix;
+ begin
+ if assigned(decorator) and
+ not linestart then
+ begin
+ AsmWriteAnsiStringUnfiltered(decorator.LinePostfix);
+ linestart:=true;
+ end;
+ end;
+
+
+ procedure TExternalAssemblerOutputFile.AsmWriteAnsiStringUnfiltered(const s: ansistring);
var
StartIndex, ToWrite: longint;
begin
@@ -413,6 +461,56 @@ Implementation
end;
+ constructor TExternalAssemblerOutputFile.Create(_owner: TExternalAssembler);
+ begin
+ owner:=_owner;
+ linestart:=true;
+ end;
+
+
+ Procedure TExternalAssemblerOutputFile.AsmWrite(const c: char);
+ begin
+ if assigned(decorator) then
+ AsmWriteFiltered(c)
+ else
+ begin
+ if OutCnt+1>=AsmOutSize then
+ AsmFlush;
+ OutBuf[OutCnt]:=c;
+ inc(OutCnt);
+ inc(AsmSize);
+ end;
+ end;
+
+
+ Procedure TExternalAssemblerOutputFile.AsmWrite(const s:string);
+ begin
+ if s='' then
+ exit;
+ if assigned(decorator) then
+ AsmWriteFiltered(s)
+ else
+ begin
+ if OutCnt+length(s)>=AsmOutSize then
+ AsmFlush;
+ Move(s[1],OutBuf[OutCnt],length(s));
+ inc(OutCnt,length(s));
+ inc(AsmSize,length(s));
+ end;
+ end;
+
+
+ Procedure TExternalAssemblerOutputFile.AsmWrite(const s:ansistring);
+ begin
+ if s='' then
+ exit;
+ if assigned(decorator) then
+ AsmWriteFiltered(s)
+ else
+ AsmWriteAnsiStringUnfiltered(s);
+ end;
+
+
procedure TExternalAssemblerOutputFile.AsmWriteLn(const c: char);
begin
AsmWrite(c);
@@ -439,23 +537,31 @@ Implementation
i,j : longint;
begin
i:=StrLen(p);
- j:=i;
- while j>0 do
- begin
- i:=min(j,AsmOutSize);
- if OutCnt+i>=AsmOutSize then
- AsmFlush;
- Move(p[0],OutBuf[OutCnt],i);
- inc(OutCnt,i);
- inc(AsmSize,i);
- dec(j,i);
- p:=pchar(@p[i]);
- end;
+ if i=0 then
+ exit;
+ if assigned(decorator) then
+ AsmWriteFiltered(p,i)
+ else
+ begin
+ j:=i;
+ while j>0 do
+ begin
+ i:=min(j,AsmOutSize);
+ if OutCnt+i>=AsmOutSize then
+ AsmFlush;
+ Move(p[0],OutBuf[OutCnt],i);
+ inc(OutCnt,i);
+ inc(AsmSize,i);
+ dec(j,i);
+ p:=pchar(@p[i]);
+ end;
+ end;
end;
Procedure TExternalAssemblerOutputFile.AsmLn;
begin
+ MaybeAddLinePostfix;
if OutCnt>=AsmOutSize-2 then
AsmFlush;
if (cs_link_on_target in current_settings.globalswitches) then