Il 27/12/2017 15:05, Sven Barth via fpc-devel ha scritto:
No matter the syntax that might be chosen for this it will likely be
sufficient to handle that feature by an absolutevarsym with a boolean
flag or something like that. The difference to an ordinary absolute
variable appears to be too small to warrant a new sym type.
After struggling sometime to find out the best way to implement the
based feature without adding a new keyword, I found that the syntax:
aVar: anyType ABSOLUTE somePTR^;
can be implemented with minimal changes.
Attached the patch which does the trick, and which works like the old
proven one.
It doesn't support *implicit* dereferencing, because I've left untouched
the code which filters it out.
One could remove the filtering for consistency, but I don't like very
much the idea: the aim of such a feature is to provide a more readable
and understandable code, not the opposite.
Giuliano
diff --git a/compiler/pdecvar.pas b/compiler/pdecvar.pas
index 1c828f5..5d67d28 100644
--- a/compiler/pdecvar.pas
+++ b/compiler/pdecvar.pas
@@ -61,7 +61,7 @@ implementation
fmodule,htypechk,
{ pass 1 }
node,pass_1,aasmbase,aasmdata,
- ncon,nset,ncnv,nld,nutils,
+ ncon,nset,ncnv,nld,nutils,nmem,
{ codegen }
ngenutil,
{ parser }
@@ -1133,11 +1133,13 @@ implementation
abssym : tabsolutevarsym;
pt,hp : tnode;
st : tsymtable;
+ isBased: boolean;
{$if defined(i386) or defined(i8086)}
tmpaddr : int64;
{$endif defined(i386) or defined(i8086)}
begin
abssym:=nil;
+ isBased:= false;
{ only allowed for one var }
vs:=tabstractvarsym(sc[0]);
if sc.count>1 then
@@ -1146,6 +1148,15 @@ implementation
Message(parser_e_initialized_not_for_external);
{ parse the rest }
pt:=expr(true);
+ { Support for absolute deref -
+ syntax:
+ sym: type ABSOLUTE ptr^;
+ }
+ if pt.nodetype=derefn then begin
+ pt := tderefnode(pt).left; // let's find the actual pointer
+ if pt.nodetype=loadn then // and check that it's valid
+ isBased:= true;
+ end;
{ check allowed absolute types }
if (pt.nodetype=stringconstn) or
(is_constcharnode(pt)) then
@@ -1257,6 +1268,7 @@ implementation
abssym:=cabsolutevarsym.create(vs.realname,vs.vardef);
abssym.fileinfo:=vs.fileinfo;
abssym.abstyp:=tovar;
+ abssym.isBased:= isBased;
abssym.ref:=node_to_propaccesslist(pt);
{ if the sizes are different, can't be a regvar since you }
diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas
index 6d972de..ecc0533 100644
--- a/compiler/pexpr.pas
+++ b/compiler/pexpr.pas
@@ -3016,11 +3016,17 @@ implementation
begin
p1:=nil;
propaccesslist_to_node(p1,nil,tabsolutevarsym(srsym).ref);
+ if tabsolutevarsym(srsym).isBased then
+ p1 := cderefnode.create(p1);
p1:=ctypeconvnode.create(p1,tabsolutevarsym(srsym).vardef);
include(p1.flags,nf_absolute);
end
else
+ begin
+ if tabsolutevarsym(srsym).isBased then
+ p1 := cderefnode.create(p1);
p1:=cloadnode.create(srsym,srsymtable);
+ end;
end;
staticvarsym,
diff --git a/compiler/symsym.pas b/compiler/symsym.pas
index d522314..86bc007 100644
--- a/compiler/symsym.pas
+++ b/compiler/symsym.pas
@@ -316,6 +316,7 @@ interface
tabsolutevarsym = class(tabstractvarsym)
public
abstyp : absolutetyp;
+ isBased : boolean;
asmname : pshortstring;
addroffset : PUint;
ref : tpropaccesslist;
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel