Added a check similar to the "allowed" one to be able to remove the "current_syssym" variable again.

* nld.pas:
- added "helperallowed" boolean field to ttypenode which is set to false by default
- check that field in ttypenode.pass_1 and generate an error if it's false
* ncal.pas:
check the "helperallowed" field if the methodpointer node is a typenode and contains a helper; this is needed, because pass_1 of ttypenode is never called in case of "TSomeHelper.SomeMethod"
* pexpr.pas: 
- allow helpers in "sizeof" and "typeinfo"
- remove the check against "TSomeHelper.SomeMethod", but leave an explaining comment there

git-svn-id: branches/svenbarth/classhelpers@17308 -
This commit is contained in:
svenbarth 2011-04-12 07:10:36 +00:00
parent 798cc01ffe
commit 24243f87e8
3 changed files with 29 additions and 9 deletions

View File

@ -3238,6 +3238,14 @@ implementation
begin begin
result:=nil; result:=nil;
{ as pass_1 is never called on the methodpointer node, we must check
here that it's not a helper type }
if assigned(methodpointer) and
(methodpointer.nodetype=typen) and
is_objectpascal_helper(ttypenode(methodpointer).typedef) and
not ttypenode(methodpointer).helperallowed then
Message(parser_e_no_category_as_types);
{ convert Objective-C calls into a message call } { convert Objective-C calls into a message call }
if (procdefinition.typ=procdef) and if (procdefinition.typ=procdef) and
(po_objc in tprocdef(procdefinition).procoptions) then (po_objc in tprocdef(procdefinition).procoptions) then

View File

@ -101,6 +101,7 @@ interface
ttypenode = class(tnode) ttypenode = class(tnode)
allowed : boolean; allowed : boolean;
helperallowed : boolean;
typedef : tdef; typedef : tdef;
typedefderef : tderef; typedefderef : tderef;
constructor create(def:tdef);virtual; constructor create(def:tdef);virtual;
@ -1034,6 +1035,7 @@ implementation
inherited create(typen); inherited create(typen);
typedef:=def; typedef:=def;
allowed:=false; allowed:=false;
helperallowed:=false;
end; end;
@ -1042,6 +1044,7 @@ implementation
inherited ppuload(t,ppufile); inherited ppuload(t,ppufile);
ppufile.getderef(typedefderef); ppufile.getderef(typedefderef);
allowed:=boolean(ppufile.getbyte); allowed:=boolean(ppufile.getbyte);
helperallowed:=boolean(ppufile.getbyte);
end; end;
@ -1050,6 +1053,7 @@ implementation
inherited ppuwrite(ppufile); inherited ppuwrite(ppufile);
ppufile.putderef(typedefderef); ppufile.putderef(typedefderef);
ppufile.putbyte(byte(allowed)); ppufile.putbyte(byte(allowed));
ppufile.putbyte(byte(helperallowed));
end; end;
@ -1087,6 +1091,8 @@ implementation
an error } an error }
if not allowed then if not allowed then
Message(parser_e_no_type_not_allowed_here); Message(parser_e_no_type_not_allowed_here);
if not helperallowed then
Message(parser_e_no_category_as_types);
end; end;
@ -1097,6 +1103,7 @@ implementation
n:=ttypenode(inherited dogetcopy); n:=ttypenode(inherited dogetcopy);
n.allowed:=allowed; n.allowed:=allowed;
n.typedef:=typedef; n.typedef:=typedef;
n.helperallowed:=helperallowed;
result:=n; result:=n;
end; end;

View File

@ -407,6 +407,9 @@ implementation
end end
else else
begin begin
{ allow helpers for SizeOf and BitSizeOf }
if p1.nodetype=typen then
ttypenode(p1).helperallowed:=true;
if (p1.resultdef.typ=forwarddef) then if (p1.resultdef.typ=forwarddef) then
Message1(type_e_type_is_not_completly_defined,tforwarddef(p1.resultdef).tosymname^); Message1(type_e_type_is_not_completly_defined,tforwarddef(p1.resultdef).tosymname^);
if (l = in_sizeof_x) or if (l = in_sizeof_x) or
@ -445,7 +448,12 @@ implementation
p1:=p2; p1:=p2;
end; end;
if p1.nodetype=typen then if p1.nodetype=typen then
begin
ttypenode(p1).allowed:=true; ttypenode(p1).allowed:=true;
{ allow helpers for TypeInfo }
if l=in_typeinfo_x then
ttypenode(p1).helperallowed:=true;
end;
{ else { else
begin begin
p1.destroy; p1.destroy;
@ -1539,15 +1547,12 @@ implementation
end end
else else
begin begin
{ TClassHelper.Something is not allowed, but { Normally here would be the check against the usage
TypeInfo(TClassHelper) and SizeOf(TClassHelper) is } of "TClassHelper.Something", but as that might be
if is_objectpascal_helper(hdef) and used inside of system symbols like sizeof and
not (current_syssym in [in_typeinfo_x,in_sizeof_x,in_bitsizeof_x]) then typeinfo this check is put into ttypenode.pass_1
begin (for "TClassHelper" alone) and tcallnode.pass_1
Message(parser_e_no_category_as_types); (for "TClassHelper.Something") }
{ for recovery we use the extended class }
hdef:=tobjectdef(hdef).extendeddef;
end;
{ class reference ? } { class reference ? }
if is_class(hdef) or if is_class(hdef) or
is_objcclass(hdef) then is_objcclass(hdef) then