2
0
Эх сурвалжийг харах

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 -
svenbarth 14 жил өмнө
parent
commit
24243f87e8

+ 8 - 0
compiler/ncal.pas

@@ -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

+ 7 - 0
compiler/nld.pas

@@ -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;
 
 

+ 14 - 9
compiler/pexpr.pas

@@ -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
-                            TypeInfo(TClassHelper) and SizeOf(TClassHelper) is }
-                          if is_objectpascal_helper(hdef) and
-                              not (current_syssym in [in_typeinfo_x,in_sizeof_x,in_bitsizeof_x]) then
-                            begin
-                              Message(parser_e_no_category_as_types);
-                              { for recovery we use the extended class }
-                              hdef:=tobjectdef(hdef).extendeddef;
-                            end;
+                          { Normally here would be the check against the usage
+                            of "TClassHelper.Something", but as that might be
+                            used inside of system symbols like sizeof and
+                            typeinfo this check is put into ttypenode.pass_1
+                            (for "TClassHelper" alone) and tcallnode.pass_1
+                            (for "TClassHelper.Something") }
                           { class reference ? }
                           { class reference ? }
                           if is_class(hdef) or
                           if is_class(hdef) or
                              is_objcclass(hdef) then
                              is_objcclass(hdef) then