Browse Source

compiler: implement record methods and class methods:
- rename tprocdef._class to tprocdef.struct and change the type from tobjectdef to tabstractrecorddef because methods can belong not to classes only now but to records too
- replace in many places use of current_objectdef to current_structdef with typcast where is needed
- add an argument to comp_expr, expr, factor, sub_expr to notify that we are searching type only symbol to solve the problem with records,objects,classes which contains fields with the same name as previosly declared type (like:
HWND = type Handle;
rec = record
hWnd: HWND;
end;)
- disable check in factor_read_id which was made for object that only static fields can be accessed as TObjectType.FieldName outside the object because it makes SizeOf(TObjectType.FieldName) imposible and since the same method was extended to handle records it also breaks a52 package compilation
- rename tcallcandidates.collect_overloads_in_class to tcallcandidates.collect_overloads_in_struct and addapt the code to handle overloads in records too
- fix searchsym_type to search also in object ancestors if we found an object symtable
- add pd_record, pd_notrecord flags to mark procedure modifies which can or can't be used with records. Disallow the next modifiers for records: abstract, dynamic, export, external, far, far16, final, forward, internconst, internproc, interrupt, message, near, override, public, reintroduce, virtual, weakexternal,
Allow the next modifiers for records: static

git-svn-id: branches/paul/extended_records@16526 -

paul 14 years ago
parent
commit
56bf42de57

+ 2 - 2
compiler/dbgdwarf.pas

@@ -2034,7 +2034,7 @@ implementation
         def.dbg_state:=dbg_state_writing;
         def.dbg_state:=dbg_state_writing;
 
 
         current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Procdef '+def.fullprocname(true))));
         current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Procdef '+def.fullprocname(true))));
-        if not is_objc_class_or_protocol(def._class) then
+        if not is_objc_class_or_protocol(def.struct) then
           append_entry(DW_TAG_subprogram,true,
           append_entry(DW_TAG_subprogram,true,
             [DW_AT_name,DW_FORM_string,symname(def.procsym)+#0
             [DW_AT_name,DW_FORM_string,symname(def.procsym)+#0
             { data continues below }
             { data continues below }
@@ -2065,7 +2065,7 @@ implementation
           append_attribute(DW_AT_external,DW_FORM_flag,[true]);
           append_attribute(DW_AT_external,DW_FORM_flag,[true]);
         { Abstract or virtual/overriding method.  }
         { Abstract or virtual/overriding method.  }
         if (([po_abstractmethod, po_virtualmethod, po_overridingmethod] * def.procoptions) <> []) and
         if (([po_abstractmethod, po_virtualmethod, po_overridingmethod] * def.procoptions) <> []) and
-           not is_objc_class_or_protocol(def._class) then
+           not is_objc_class_or_protocol(def.struct) then
           begin
           begin
             if not(po_abstractmethod in def.procoptions) then
             if not(po_abstractmethod in def.procoptions) then
               append_attribute(DW_AT_virtuality,DW_FORM_data1,[ord(DW_VIRTUALITY_virtual)])
               append_attribute(DW_AT_virtuality,DW_FORM_data1,[ord(DW_VIRTUALITY_virtual)])

+ 7 - 7
compiler/dbgstabs.pas

@@ -66,7 +66,7 @@ interface
         procedure write_sym_stabstr(list:TAsmList;sym:tsym;const ss:ansistring);
         procedure write_sym_stabstr(list:TAsmList;sym:tsym;const ss:ansistring);
         { tdef writing }
         { tdef writing }
         function  def_stab_number(def:tdef):string;
         function  def_stab_number(def:tdef):string;
-        function  def_stab_classnumber(def:tobjectdef):string;
+        function  def_stab_classnumber(def:tabstractrecorddef):string;
         function  def_var_value(const s:string;arg:pointer):string;
         function  def_var_value(const s:string;arg:pointer):string;
         function  def_stabstr_evaluate(def:tdef;const s:string;const vars:array of string):ansistring;
         function  def_stabstr_evaluate(def:tdef;const s:string;const vars:array of string):ansistring;
         procedure write_def_stabstr(list:TAsmList;def:tdef;const ss:ansistring);
         procedure write_def_stabstr(list:TAsmList;def:tdef;const ss:ansistring);
@@ -314,11 +314,11 @@ implementation
       end;
       end;
 
 
 
 
-    function TDebugInfoStabs.def_stab_classnumber(def:tobjectdef):string;
+    function TDebugInfoStabs.def_stab_classnumber(def:tabstractrecorddef):string;
       begin
       begin
         if def.stab_number=0 then
         if def.stab_number=0 then
           def_stab_number(def);
           def_stab_number(def);
-        if (def.objecttype=odt_class) then
+        if (def.typ=objectdef) and (tobjectdef(def).objecttype=odt_class) then
           result:=tostr(def.stab_number-1)
           result:=tostr(def.stab_number-1)
         else
         else
           result:=tostr(def.stab_number);
           result:=tostr(def.stab_number);
@@ -414,7 +414,7 @@ implementation
                lindex := pd.extnumber;
                lindex := pd.extnumber;
                {doesnt seem to be necessary
                {doesnt seem to be necessary
                lindex := lindex or $80000000;}
                lindex := lindex or $80000000;}
-               virtualind := '*'+tostr(lindex)+';'+def_stab_classnumber(pd._class)+';'
+               virtualind := '*'+tostr(lindex)+';'+def_stab_classnumber(pd.struct)+';'
              end
              end
             else
             else
              virtualind := '.';
              virtualind := '.';
@@ -1345,13 +1345,13 @@ implementation
                 end
                 end
             else
             else
               begin
               begin
-                if not(is_class(tprocdef(sym.owner.defowner)._class)) then
+                if not(is_class(tprocdef(sym.owner.defowner).struct)) then
                   c:='v'
                   c:='v'
                 else
                 else
                   c:='p';
                   c:='p';
                 if (sym.localloc.loc=LOC_REFERENCE) then
                 if (sym.localloc.loc=LOC_REFERENCE) then
                   ss:=sym_stabstr_evaluate(sym,'"$$t:$1",${N_TSYM},0,0,$2',
                   ss:=sym_stabstr_evaluate(sym,'"$$t:$1",${N_TSYM},0,0,$2',
-                        [c+def_stab_number(tprocdef(sym.owner.defowner)._class),tostr(sym.localloc.reference.offset)])
+                        [c+def_stab_number(tprocdef(sym.owner.defowner).struct),tostr(sym.localloc.reference.offset)])
                 else
                 else
                   begin
                   begin
                     if (c='p') then
                     if (c='p') then
@@ -1360,7 +1360,7 @@ implementation
                       c:='a';
                       c:='a';
                     regidx:=findreg_by_number(sym.localloc.register);
                     regidx:=findreg_by_number(sym.localloc.register);
                     ss:=sym_stabstr_evaluate(sym,'"$$t:$1",${N_RSYM},0,0,$2',
                     ss:=sym_stabstr_evaluate(sym,'"$$t:$1",${N_RSYM},0,0,$2',
-                        [c+def_stab_number(tprocdef(sym.owner.defowner)._class),tostr(regstabs_table[regidx])]);
+                        [c+def_stab_number(tprocdef(sym.owner.defowner).struct),tostr(regstabs_table[regidx])]);
                   end
                   end
               end;
               end;
           end
           end

+ 19 - 16
compiler/htypechk.pas

@@ -66,7 +66,7 @@ interface
         FParaNode   : tnode;
         FParaNode   : tnode;
         FParaLength : smallint;
         FParaLength : smallint;
         FAllowVariant : boolean;
         FAllowVariant : boolean;
-        procedure collect_overloads_in_class(ProcdefOverloadList:TFPObjectList);
+        procedure collect_overloads_in_struct(ProcdefOverloadList:TFPObjectList);
         procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean);
         procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean);
         procedure create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit:boolean);
         procedure create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit:boolean);
         function  proc_add(ps:tprocsym;pd:tprocdef;objcidcall: boolean):pcandidate;
         function  proc_add(ps:tprocsym;pd:tprocdef;objcidcall: boolean):pcandidate;
@@ -1714,21 +1714,21 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcallcandidates.collect_overloads_in_class(ProcdefOverloadList:TFPObjectList);
+    procedure tcallcandidates.collect_overloads_in_struct(ProcdefOverloadList:TFPObjectList);
       var
       var
         j          : integer;
         j          : integer;
         pd         : tprocdef;
         pd         : tprocdef;
         srsym      : tsym;
         srsym      : tsym;
-        objdef     : tobjectdef;
+        structdef  : tabstractrecorddef;
         hashedid   : THashedIDString;
         hashedid   : THashedIDString;
         hasoverload : boolean;
         hasoverload : boolean;
       begin
       begin
-        objdef:=tobjectdef(fprocsym.owner.defowner);
+        structdef:=tabstractrecorddef(fprocsym.owner.defowner);
         hashedid.id:=fprocsym.name;
         hashedid.id:=fprocsym.name;
         hasoverload:=false;
         hasoverload:=false;
-        while assigned(objdef) do
+        while assigned(structdef) do
          begin
          begin
-           srsym:=tprocsym(objdef.symtable.FindWithHash(hashedid));
+           srsym:=tprocsym(structdef.symtable.FindWithHash(hashedid));
            if assigned(srsym) and
            if assigned(srsym) and
               { Delphi allows hiding a property by a procedure with the same name }
               { Delphi allows hiding a property by a procedure with the same name }
               (srsym.typ=procsym) then
               (srsym.typ=procsym) then
@@ -1747,7 +1747,10 @@ implementation
                  break;
                  break;
              end;
              end;
            { next parent }
            { next parent }
-           objdef:=objdef.childof;
+           if (structdef.typ=objectdef) then
+             structdef:=tobjectdef(structdef).childof
+           else
+             structdef:=nil;
          end;
          end;
       end;
       end;
 
 
@@ -1830,7 +1833,7 @@ implementation
         hp    : pcandidate;
         hp    : pcandidate;
         pt    : tcallparanode;
         pt    : tcallparanode;
         found : boolean;
         found : boolean;
-        contextobjdef : tobjectdef;
+        contextstructdef : tabstractrecorddef;
         ProcdefOverloadList : TFPObjectList;
         ProcdefOverloadList : TFPObjectList;
       begin
       begin
         FCandidateProcs:=nil;
         FCandidateProcs:=nil;
@@ -1839,8 +1842,8 @@ implementation
         ProcdefOverloadList:=TFPObjectList.Create(false);
         ProcdefOverloadList:=TFPObjectList.Create(false);
         if not objcidcall and
         if not objcidcall and
            (FOperator=NOTOKEN) and
            (FOperator=NOTOKEN) and
-           (FProcsym.owner.symtabletype=objectsymtable) then
-          collect_overloads_in_class(ProcdefOverloadList)
+           (FProcsym.owner.symtabletype in [objectsymtable,recordsymtable]) then
+          collect_overloads_in_struct(ProcdefOverloadList)
         else
         else
           collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit);
           collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit);
 
 
@@ -1864,15 +1867,15 @@ implementation
           units. At least kylix supports it this way (PFV) }
           units. At least kylix supports it this way (PFV) }
         if assigned(FProcSymtable) and
         if assigned(FProcSymtable) and
            (
            (
-            (FProcSymtable.symtabletype=ObjectSymtable) or
+            (FProcSymtable.symtabletype in [ObjectSymtable,recordsymtable]) or
             ((FProcSymtable.symtabletype=withsymtable) and
             ((FProcSymtable.symtabletype=withsymtable) and
-             (FProcSymtable.defowner.typ=objectdef))
+             (FProcSymtable.defowner.typ in [objectdef,recorddef]))
            ) and
            ) and
            (FProcSymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
            (FProcSymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
            FProcSymtable.defowner.owner.iscurrentunit then
            FProcSymtable.defowner.owner.iscurrentunit then
-          contextobjdef:=tobjectdef(FProcSymtable.defowner)
+          contextstructdef:=tabstractrecorddef(FProcSymtable.defowner)
         else
         else
-          contextobjdef:=current_objectdef;
+          contextstructdef:=current_structdef;
 
 
         { Process all found overloads }
         { Process all found overloads }
         for j:=0 to ProcdefOverloadList.Count-1 do
         for j:=0 to ProcdefOverloadList.Count-1 do
@@ -1897,8 +1900,8 @@ implementation
                ) and
                ) and
                (
                (
                 ignorevisibility or
                 ignorevisibility or
-                (pd.owner.symtabletype<>objectsymtable) or
-                is_visible_for_object(pd,contextobjdef)
+                not (pd.owner.symtabletype in [objectsymtable,recordsymtable]) or
+                is_visible_for_object(pd,contextstructdef)
                ) then
                ) then
               begin
               begin
                 { don't add duplicates, only compare visible parameters for the user }
                 { don't add duplicates, only compare visible parameters for the user }

+ 3 - 3
compiler/i386/cgcpu.pas

@@ -617,7 +617,7 @@ unit cgcpu;
           if (procdef.extnumber=$ffff) then
           if (procdef.extnumber=$ffff) then
             Internalerror(200006139);
             Internalerror(200006139);
           { call/jmp  vmtoffs(%eax) ; method offs }
           { call/jmp  vmtoffs(%eax) ; method offs }
-          reference_reset_base(href,NR_EAX,procdef._class.vmtmethodoffset(procdef.extnumber),4);
+          reference_reset_base(href,NR_EAX,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),4);
           list.concat(taicpu.op_ref(op,S_L,href));
           list.concat(taicpu.op_ref(op,S_L,href));
         end;
         end;
 
 
@@ -629,7 +629,7 @@ unit cgcpu;
           if (procdef.extnumber=$ffff) then
           if (procdef.extnumber=$ffff) then
             Internalerror(200006139);
             Internalerror(200006139);
           { mov vmtoffs(%eax),%eax ; method offs }
           { mov vmtoffs(%eax),%eax ; method offs }
-          reference_reset_base(href,NR_EAX,procdef._class.vmtmethodoffset(procdef.extnumber),4);
+          reference_reset_base(href,NR_EAX,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),4);
           cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EAX);
           cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EAX);
         end;
         end;
 
 
@@ -641,7 +641,7 @@ unit cgcpu;
       begin
       begin
         if not(procdef.proctypeoption in [potype_function,potype_procedure]) then
         if not(procdef.proctypeoption in [potype_function,potype_procedure]) then
           Internalerror(200006137);
           Internalerror(200006137);
-        if not assigned(procdef._class) or
+        if not assigned(procdef.struct) or
            (procdef.procoptions*[po_classmethod, po_staticmethod,
            (procdef.procoptions*[po_classmethod, po_staticmethod,
              po_methodpointer, po_interrupt, po_iocheck]<>[]) then
              po_methodpointer, po_interrupt, po_iocheck]<>[]) then
           Internalerror(200006138);
           Internalerror(200006138);

+ 3 - 2
compiler/ncal.pas

@@ -1671,7 +1671,8 @@ implementation
             begin
             begin
               if (procdefinition.typ<>procdef) then
               if (procdefinition.typ<>procdef) then
                 internalerror(200305062);
                 internalerror(200305062);
-              if (oo_has_vmt in tprocdef(procdefinition)._class.objectoptions) then
+              if (tprocdef(procdefinition).struct.typ=objectdef) and
+                 (oo_has_vmt in tobjectdef(tprocdef(procdefinition).struct).objectoptions) then
                 begin
                 begin
                   { we only need the vmt, loading self is not required and there is no
                   { we only need the vmt, loading self is not required and there is no
                     need to check for typen, because that will always get the
                     need to check for typen, because that will always get the
@@ -2871,7 +2872,7 @@ implementation
               error and to prevent users from generating non-working code
               error and to prevent users from generating non-working code
               when they expect to clone the current instance, see bug 3662 (PFV) }
               when they expect to clone the current instance, see bug 3662 (PFV) }
               if (procdefinition.proctypeoption=potype_constructor) and
               if (procdefinition.proctypeoption=potype_constructor) and
-                 is_class(tprocdef(procdefinition)._class) and
+                 is_class(tprocdef(procdefinition).struct) and
                  assigned(methodpointer) and
                  assigned(methodpointer) and
                  (nf_is_self in methodpointer.flags) then
                  (nf_is_self in methodpointer.flags) then
                 resultdef:=voidtype
                 resultdef:=voidtype

+ 7 - 7
compiler/ncgcal.pas

@@ -688,12 +688,12 @@ implementation
                 (methodpointer.nodetype<>typen) and
                 (methodpointer.nodetype<>typen) and
                 (not assigned(current_procinfo) or
                 (not assigned(current_procinfo) or
                  wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
                  wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
-               tprocdef(procdefinition)._class.register_vmt_call(tprocdef(procdefinition).extnumber);
+               tobjectdef(tprocdef(procdefinition).struct).register_vmt_call(tprocdef(procdefinition).extnumber);
 {$ifdef vtentry}
 {$ifdef vtentry}
              if not is_interface(tprocdef(procdefinition)._class) then
              if not is_interface(tprocdef(procdefinition)._class) then
                begin
                begin
                  inc(current_asmdata.NextVTEntryNr);
                  inc(current_asmdata.NextVTEntryNr);
-                 current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+tprocdef(procdefinition)._class.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0));
+                 current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+tprocdef(procdefinition).struct.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0));
                end;
                end;
 {$endif vtentry}
 {$endif vtentry}
 
 
@@ -725,16 +725,16 @@ implementation
                    end;
                    end;
 
 
                  { test validity of VMT }
                  { test validity of VMT }
-                 if not(is_interface(tprocdef(procdefinition)._class)) and
-                    not(is_cppclass(tprocdef(procdefinition)._class)) then
-                   cg.g_maybe_testvmt(current_asmdata.CurrAsmList,vmtreg,tprocdef(procdefinition)._class);
+                 if not(is_interface(tprocdef(procdefinition).struct)) and
+                    not(is_cppclass(tprocdef(procdefinition).struct)) then
+                   cg.g_maybe_testvmt(current_asmdata.CurrAsmList,vmtreg,tobjectdef(tprocdef(procdefinition).struct));
 
 
                  { Call through VMT, generate a VTREF symbol to notify the linker }
                  { Call through VMT, generate a VTREF symbol to notify the linker }
-                 vmtoffset:=tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber);
+                 vmtoffset:=tobjectdef(tprocdef(procdefinition).struct).vmtmethodoffset(tprocdef(procdefinition).extnumber);
                  { register call for WPO }
                  { register call for WPO }
                  if (not assigned(current_procinfo) or
                  if (not assigned(current_procinfo) or
                      wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
                      wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
-                   tprocdef(procdefinition)._class.register_vmt_call(tprocdef(procdefinition).extnumber);
+                   tobjectdef(tprocdef(procdefinition).struct).register_vmt_call(tprocdef(procdefinition).extnumber);
 {$ifndef x86}
 {$ifndef x86}
                  pvreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
                  pvreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
 {$endif not x86}
 {$endif not x86}

+ 3 - 3
compiler/ncgld.pas

@@ -500,9 +500,9 @@ implementation
                        begin
                        begin
                          if (not assigned(current_procinfo) or
                          if (not assigned(current_procinfo) or
                              wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
                              wpoinfomanager.symbol_live(current_procinfo.procdef.mangledname)) then
-                           procdef._class.register_vmt_call(procdef.extnumber);
+                           tobjectdef(procdef.struct).register_vmt_call(procdef.extnumber);
             {$ifdef vtentry}
             {$ifdef vtentry}
-                         if not is_interface(procdef._class) then
+                         if not is_interface(procdef.struct) then
                            begin
                            begin
                              inc(current_asmdata.NextVTEntryNr);
                              inc(current_asmdata.NextVTEntryNr);
                              current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+procdef._class.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0));
                              current_asmdata.CurrAsmList.Concat(tai_symbol.CreateName('VTREF'+tostr(current_asmdata.NextVTEntryNr)+'_'+procdef._class.vmt_mangledname+'$$'+tostr(vmtoffset div sizeof(pint)),AT_FUNCTION,0));
@@ -517,7 +517,7 @@ implementation
                              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
                              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
                            end;
                            end;
                          { load method address }
                          { load method address }
-                         reference_reset_base(href,hregister,procdef._class.vmtmethodoffset(procdef.extnumber),sizeof(pint));
+                         reference_reset_base(href,hregister,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),sizeof(pint));
                          hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
                          hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
                          cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
                          cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
                          { ... and store it }
                          { ... and store it }

+ 2 - 2
compiler/ncgrtti.pas

@@ -318,9 +318,9 @@ implementation
                   begin
                   begin
                      { virtual method, write vmt offset }
                      { virtual method, write vmt offset }
                      current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,
                      current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,
-                       tprocdef(propaccesslist.procdef)._class.vmtmethodoffset(tprocdef(propaccesslist.procdef).extnumber)));
+                       tobjectdef(tprocdef(propaccesslist.procdef).struct).vmtmethodoffset(tprocdef(propaccesslist.procdef).extnumber)));
                      { register for wpo }
                      { register for wpo }
-                     tprocdef(propaccesslist.procdef)._class.register_vmt_call(tprocdef(propaccesslist.procdef).extnumber);
+                     tobjectdef(tprocdef(propaccesslist.procdef).struct).register_vmt_call(tprocdef(propaccesslist.procdef).extnumber);
                      {$ifdef vtentry}
                      {$ifdef vtentry}
                      { not sure if we can insert those vtentry symbols safely here }
                      { not sure if we can insert those vtentry symbols safely here }
                      {$error register methods used for published properties}
                      {$error register methods used for published properties}

+ 1 - 1
compiler/nflw.pas

@@ -383,7 +383,7 @@ implementation
                  ccallparanode.create(caddrnode.create(ctemprefnode.create(state)),nil)
                  ccallparanode.create(caddrnode.create(ctemprefnode.create(state)),nil)
                )
                )
              );
              );
-         sym:=search_class_member(objc_fastenumeration,'COUNTBYENUMERATINGWITHSTATE_OBJECTS_COUNT');
+         sym:=search_struct_member(objc_fastenumeration,'COUNTBYENUMERATINGWITHSTATE_OBJECTS_COUNT');
          if not assigned(sym) or
          if not assigned(sym) or
             (sym.typ<>procsym) then
             (sym.typ<>procsym) then
            internalerror(2010061901);
            internalerror(2010061901);

+ 3 - 3
compiler/nld.pas

@@ -301,17 +301,17 @@ implementation
                  definition }
                  definition }
                if vo_is_self in tabstractvarsym(symtableentry).varoptions then
                if vo_is_self in tabstractvarsym(symtableentry).varoptions then
                  begin
                  begin
-                   resultdef:=tprocdef(symtableentry.owner.defowner)._class;
+                   resultdef:=tprocdef(symtableentry.owner.defowner).struct;
                    if (po_classmethod in tprocdef(symtableentry.owner.defowner).procoptions) or
                    if (po_classmethod in tprocdef(symtableentry.owner.defowner).procoptions) or
                       (po_staticmethod in tprocdef(symtableentry.owner.defowner).procoptions) then
                       (po_staticmethod in tprocdef(symtableentry.owner.defowner).procoptions) then
                      resultdef:=tclassrefdef.create(resultdef)
                      resultdef:=tclassrefdef.create(resultdef)
-                   else if is_object(resultdef) and
+                   else if (is_object(resultdef) or is_record(resultdef)) and
                            (nf_load_self_pointer in flags) then
                            (nf_load_self_pointer in flags) then
                      resultdef:=tpointerdef.create(resultdef);
                      resultdef:=tpointerdef.create(resultdef);
                  end
                  end
                else if vo_is_vmt in tabstractvarsym(symtableentry).varoptions then
                else if vo_is_vmt in tabstractvarsym(symtableentry).varoptions then
                  begin
                  begin
-                   resultdef:=tprocdef(symtableentry.owner.defowner)._class;
+                   resultdef:=tprocdef(symtableentry.owner.defowner).struct;
                    resultdef:=tclassrefdef.create(resultdef);
                    resultdef:=tclassrefdef.create(resultdef);
                  end
                  end
                else
                else

+ 3 - 2
compiler/nmem.pas

@@ -160,7 +160,8 @@ implementation
         case left.resultdef.typ of
         case left.resultdef.typ of
           classrefdef :
           classrefdef :
             resultdef:=left.resultdef;
             resultdef:=left.resultdef;
-          objectdef :
+          objectdef,
+          recorddef:
             { access to the classtype while specializing? }
             { access to the classtype while specializing? }
             if (df_generic in left.resultdef.defoptions) then
             if (df_generic in left.resultdef.defoptions) then
               begin
               begin
@@ -202,7 +203,7 @@ implementation
              if is_objcclass(left.resultdef) and
              if is_objcclass(left.resultdef) and
                 (left.nodetype<>typen) then
                 (left.nodetype<>typen) then
                begin
                begin
-                 vs:=search_class_member(tobjectdef(left.resultdef),'ISA');
+                 vs:=search_struct_member(tobjectdef(left.resultdef),'ISA');
                  if not assigned(vs) or
                  if not assigned(vs) or
                     (tsym(vs).typ<>fieldvarsym) then
                     (tsym(vs).typ<>fieldvarsym) then
                    internalerror(2009092502);
                    internalerror(2009092502);

+ 2 - 2
compiler/nobj.pas

@@ -536,7 +536,7 @@ implementation
                 { Add procdef to the implemented interface }
                 { Add procdef to the implemented interface }
                 if assigned(implprocdef) then
                 if assigned(implprocdef) then
                   begin
                   begin
-                    if (implprocdef._class.objecttype<>odt_objcclass) then
+                    if (tobjectdef(implprocdef.struct).objecttype<>odt_objcclass) then
                       ImplIntf.AddImplProc(implprocdef)
                       ImplIntf.AddImplProc(implprocdef)
                     else
                     else
                       begin
                       begin
@@ -1345,7 +1345,7 @@ implementation
           etVirtualMethodResult, etVirtualMethodClass:
           etVirtualMethodResult, etVirtualMethodClass:
             begin
             begin
               pd := tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef);
               pd := tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef);
-              current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(pd._class.vmtmethodoffset(pd.extnumber)));
+              current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(tobjectdef(pd.struct).vmtmethodoffset(pd.extnumber)));
             end;
             end;
           else
           else
             internalerror(200802162);
             internalerror(200802162);

+ 3 - 3
compiler/nutils.pas

@@ -534,9 +534,9 @@ implementation
         result:=internalstatements(newstatement);
         result:=internalstatements(newstatement);
 
 
         { call fail helper and exit normal }
         { call fail helper and exit normal }
-        if is_class(current_objectdef) then
+        if is_class(current_structdef) then
           begin
           begin
-            srsym:=search_class_member(current_objectdef,'FREEINSTANCE');
+            srsym:=search_struct_member(current_objectdef,'FREEINSTANCE');
             if assigned(srsym) and
             if assigned(srsym) and
                (srsym.typ=procsym) then
                (srsym.typ=procsym) then
               begin
               begin
@@ -556,7 +556,7 @@ implementation
               internalerror(200305108);
               internalerror(200305108);
           end
           end
         else
         else
-          if is_object(current_objectdef) then
+          if is_object(current_structdef) then
             begin
             begin
               { parameter 3 : vmt_offset }
               { parameter 3 : vmt_offset }
               { parameter 2 : pointer to vmt }
               { parameter 2 : pointer to vmt }

+ 2 - 2
compiler/pdecl.pas

@@ -85,7 +85,7 @@ implementation
         if orgname='' then
         if orgname='' then
          internalerror(9584582);
          internalerror(9584582);
         hp:=nil;
         hp:=nil;
-        p:=comp_expr(true);
+        p:=comp_expr(true,false);
         storetokenpos:=current_tokenpos;
         storetokenpos:=current_tokenpos;
         current_tokenpos:=filepos;
         current_tokenpos:=filepos;
         case p.nodetype of
         case p.nodetype of
@@ -748,7 +748,7 @@ implementation
              _EQUAL:
              _EQUAL:
                 begin
                 begin
                    consume(_EQUAL);
                    consume(_EQUAL);
-                   p:=comp_expr(true);
+                   p:=comp_expr(true,false);
                    storetokenpos:=current_tokenpos;
                    storetokenpos:=current_tokenpos;
                    current_tokenpos:=filepos;
                    current_tokenpos:=filepos;
                    sym:=nil;
                    sym:=nil;

+ 7 - 7
compiler/pdecobj.pas

@@ -94,8 +94,8 @@ implementation
         include(current_objectdef.objectoptions,oo_has_constructor);
         include(current_objectdef.objectoptions,oo_has_constructor);
         { Set return type, class constructors return the
         { Set return type, class constructors return the
           created instance, object constructors return boolean }
           created instance, object constructors return boolean }
-        if is_class(pd._class) then
-          pd.returndef:=pd._class
+        if is_class(pd.struct) then
+          pd.returndef:=pd.struct
         else
         else
 {$ifdef CPU64bitaddr}
 {$ifdef CPU64bitaddr}
           pd.returndef:=bool64type;
           pd.returndef:=bool64type;
@@ -314,7 +314,7 @@ implementation
         p : tnode;
         p : tnode;
         valid : boolean;
         valid : boolean;
       begin
       begin
-        p:=comp_expr(true);
+        p:=comp_expr(true,false);
         if p.nodetype=stringconstn then
         if p.nodetype=stringconstn then
           begin
           begin
             stringdispose(current_objectdef.iidstr);
             stringdispose(current_objectdef.iidstr);
@@ -544,7 +544,7 @@ implementation
 
 
       procedure chkobjc(pd: tprocdef);
       procedure chkobjc(pd: tprocdef);
         begin
         begin
-          if is_objc_class_or_protocol(pd._class) then
+          if is_objc_class_or_protocol(pd.struct) then
             begin
             begin
               include(pd.procoptions,po_objc);
               include(pd.procoptions,po_objc);
             end;
             end;
@@ -790,7 +790,7 @@ implementation
 
 
                 oldparse_only:=parse_only;
                 oldparse_only:=parse_only;
                 parse_only:=true;
                 parse_only:=true;
-                pd:=parse_proc_dec(is_classdef, current_objectdef);
+                pd:=parse_proc_dec(is_classdef,current_objectdef);
 
 
                 { this is for error recovery as well as forward }
                 { this is for error recovery as well as forward }
                 { interface mappings, i.e. mapping to a method  }
                 { interface mappings, i.e. mapping to a method  }
@@ -800,9 +800,9 @@ implementation
                     parse_object_proc_directives(pd);
                     parse_object_proc_directives(pd);
 
 
                     { check if dispid is set }
                     { check if dispid is set }
-                    if is_dispinterface(pd._class) and not (po_dispid in pd.procoptions) then
+                    if is_dispinterface(pd.struct) and not (po_dispid in pd.procoptions) then
                       begin
                       begin
-                        pd.dispid:=pd._class.get_next_dispid;
+                        pd.dispid:=tobjectdef(pd.struct).get_next_dispid;
                         include(pd.procoptions, po_dispid);
                         include(pd.procoptions, po_dispid);
                       end;
                       end;
 
 

+ 150 - 128
compiler/pdecsub.pas

@@ -31,13 +31,15 @@ interface
     type
     type
       tpdflag=(
       tpdflag=(
         pd_body,         { directive needs a body }
         pd_body,         { directive needs a body }
-        pd_implemen,     { directive can be used implementation section }
-        pd_interface,    { directive can be used interface section }
-        pd_object,       { directive can be used object declaration }
-        pd_procvar,      { directive can be used procvar declaration }
-        pd_notobject,    { directive can not be used object declaration }
-        pd_notobjintf,   { directive can not be used interface declaration }
-        pd_notprocvar,   { directive can not be used procvar declaration }
+        pd_implemen,     { directive can be used in implementation section }
+        pd_interface,    { directive can be used in interface section }
+        pd_object,       { directive can be used with object declaration }
+        pd_record,       { directive can be used with record declaration }
+        pd_procvar,      { directive can be used with procvar declaration }
+        pd_notobject,    { directive can not be used with object declaration }
+        pd_notrecord,    { directive can not be used with record declaration }
+        pd_notobjintf,   { directive can not be used with interface declaration }
+        pd_notprocvar,   { directive can not be used with procvar declaration }
         pd_dispinterface,{ directive can be used with dispinterface methods }
         pd_dispinterface,{ directive can be used with dispinterface methods }
         pd_cppobject,    { directive can be used with cppclass }
         pd_cppobject,    { directive can be used with cppclass }
         pd_objcclass,    { directive can be used with objcclass }
         pd_objcclass,    { directive can be used with objcclass }
@@ -59,8 +61,9 @@ interface
     procedure parse_proc_directives(pd:tabstractprocdef;var pdflags:tpdflags);
     procedure parse_proc_directives(pd:tabstractprocdef;var pdflags:tpdflags);
     procedure parse_var_proc_directives(sym:tsym);
     procedure parse_var_proc_directives(sym:tsym);
     procedure parse_object_proc_directives(pd:tabstractprocdef);
     procedure parse_object_proc_directives(pd:tabstractprocdef);
-    function  parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean;
-    function  parse_proc_dec(isclassmethod:boolean; aclass:tobjectdef):tprocdef;
+    procedure parse_record_proc_directives(pd:tabstractprocdef);
+    function  parse_proc_head(astruct:tabstractrecorddef;potype:tproctypeoption;var pd:tprocdef):boolean;
+    function  parse_proc_dec(isclassmethod:boolean;astruct:tabstractrecorddef):tprocdef;
 
 
     { helper functions - they insert nested objects hierarcy to the symtablestack
     { helper functions - they insert nested objects hierarcy to the symtablestack
       with object hierarchy
       with object hierarchy
@@ -246,7 +249,7 @@ implementation
         sl       : tpropaccesslist;
         sl       : tpropaccesslist;
       begin
       begin
         if (pd.typ=procdef) and
         if (pd.typ=procdef) and
-           is_objc_class_or_protocol(tprocdef(pd)._class) and
+           is_objc_class_or_protocol(tprocdef(pd).struct) and
            (pd.parast.symtablelevel=normal_function_level) then
            (pd.parast.symtablelevel=normal_function_level) then
           begin
           begin
             { insert Objective-C self and selector parameters }
             { insert Objective-C self and selector parameters }
@@ -263,7 +266,7 @@ implementation
               { compatible with what gcc does }
               { compatible with what gcc does }
               hdef:=objc_idtype
               hdef:=objc_idtype
             else
             else
-              hdef:=tprocdef(pd)._class;
+              hdef:=tprocdef(pd).struct;
 
 
             vs:=tparavarsym.create('$self',paranr_objc_self,vs_value,hdef,[vo_is_self,vo_is_hidden_para]);
             vs:=tparavarsym.create('$self',paranr_objc_self,vs_value,hdef,[vo_is_self,vo_is_hidden_para]);
             pd.parast.insert(vs);
             pd.parast.insert(vs);
@@ -278,7 +281,7 @@ implementation
         else
         else
           begin
           begin
              if (pd.typ=procdef) and
              if (pd.typ=procdef) and
-                assigned(tprocdef(pd)._class) and
+                assigned(tprocdef(pd).struct) and
                 (pd.parast.symtablelevel=normal_function_level) then
                 (pd.parast.symtablelevel=normal_function_level) then
               begin
               begin
                 { static class methods have no hidden self/vmt pointer }
                 { static class methods have no hidden self/vmt pointer }
@@ -289,7 +292,7 @@ implementation
                 current_tokenpos:=tprocdef(pd).fileinfo;
                 current_tokenpos:=tprocdef(pd).fileinfo;
 
 
                 { Generate VMT variable for constructor/destructor }
                 { Generate VMT variable for constructor/destructor }
-                if (pd.proctypeoption in [potype_constructor,potype_destructor]) and not(is_cppclass(tprocdef(pd)._class)) then
+                if (pd.proctypeoption in [potype_constructor,potype_destructor]) and not(is_cppclass(tprocdef(pd).struct)) then
                  begin
                  begin
                    { can't use classrefdef as type because inheriting
                    { can't use classrefdef as type because inheriting
                      will then always file because of a type mismatch }
                      will then always file because of a type mismatch }
@@ -303,12 +306,12 @@ implementation
                 vsp:=vs_value;
                 vsp:=vs_value;
                 if (po_staticmethod in pd.procoptions) or
                 if (po_staticmethod in pd.procoptions) or
                    (po_classmethod in pd.procoptions) then
                    (po_classmethod in pd.procoptions) then
-                  hdef:=tclassrefdef.create(tprocdef(pd)._class)
+                  hdef:=tclassrefdef.create(tprocdef(pd).struct)
                 else
                 else
                   begin
                   begin
-                    if is_object(tprocdef(pd)._class) then
+                    if is_object(tprocdef(pd).struct) or is_record(tprocdef(pd).struct) then
                       vsp:=vs_var;
                       vsp:=vs_var;
-                    hdef:=tprocdef(pd)._class;
+                    hdef:=tprocdef(pd).struct;
                   end;
                   end;
                 vs:=tparavarsym.create('$self',paranr_self,vsp,hdef,[vo_is_self,vo_is_hidden_para]);
                 vs:=tparavarsym.create('$self',paranr_self,vsp,hdef,[vo_is_self,vo_is_hidden_para]);
                 pd.parast.insert(vs);
                 pd.parast.insert(vs);
@@ -409,7 +412,7 @@ implementation
                     MessagePos(fileinfo,parser_w_cdecl_no_openstring);
                     MessagePos(fileinfo,parser_w_cdecl_no_openstring);
                  if not(po_external in pd.procoptions) and
                  if not(po_external in pd.procoptions) and
                     (pd.typ<>procvardef) and
                     (pd.typ<>procvardef) and
-                    not is_objc_class_or_protocol(tprocdef(pd)._class) then
+                    not is_objc_class_or_protocol(tprocdef(pd).struct) then
                    if is_array_of_const(vardef) then
                    if is_array_of_const(vardef) then
                      MessagePos(fileinfo,parser_e_varargs_need_cdecl_and_external)
                      MessagePos(fileinfo,parser_e_varargs_need_cdecl_and_external)
                    else
                    else
@@ -732,7 +735,7 @@ implementation
             CGMessage(cg_e_file_must_call_by_reference);
             CGMessage(cg_e_file_must_call_by_reference);
 
 
           { Dispinterfaces are restricted to using only automatable types }
           { Dispinterfaces are restricted to using only automatable types }
-          if (pd.typ=procdef) and is_dispinterface(tprocdef(pd)._class) and
+          if (pd.typ=procdef) and is_dispinterface(tprocdef(pd).struct) and
              not is_automatable(hdef) then
              not is_automatable(hdef) then
             Message1(type_e_not_automatable,hdef.typename);
             Message1(type_e_not_automatable,hdef.typename);
 
 
@@ -784,7 +787,7 @@ implementation
       end;
       end;
 
 
 
 
-    function parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean;
+    function parse_proc_head(astruct:tabstractrecorddef;potype:tproctypeoption;var pd:tprocdef):boolean;
       var
       var
         hs       : string;
         hs       : string;
         orgsp,sp : TIDString;
         orgsp,sp : TIDString;
@@ -800,7 +803,7 @@ implementation
         popclass : integer;
         popclass : integer;
         ImplIntf : TImplementedInterface;
         ImplIntf : TImplementedInterface;
         old_parse_generic : boolean;
         old_parse_generic : boolean;
-        old_current_objectdef,
+        old_current_structdef: tabstractrecorddef;
         old_current_genericdef,
         old_current_genericdef,
         old_current_specializedef : tobjectdef;
         old_current_specializedef : tobjectdef;
       begin
       begin
@@ -825,9 +828,10 @@ implementation
           end;
           end;
 
 
         { examine interface map: function/procedure iname.functionname=locfuncname }
         { examine interface map: function/procedure iname.functionname=locfuncname }
-        if assigned(aclass) and
-           assigned(aclass.ImplementedInterfaces) and
-           (aclass.ImplementedInterfaces.count>0) and
+        if assigned(astruct) and
+           (astruct.typ=objectdef) and
+           assigned(tobjectdef(astruct).ImplementedInterfaces) and
+           (tobjectdef(astruct).ImplementedInterfaces.count>0) and
            try_to_consume(_POINT) then
            try_to_consume(_POINT) then
          begin
          begin
            storepos:=current_tokenpos;
            storepos:=current_tokenpos;
@@ -844,7 +848,7 @@ implementation
            ImplIntf:=nil;
            ImplIntf:=nil;
            if (srsym.typ=typesym) and
            if (srsym.typ=typesym) and
               (ttypesym(srsym).typedef.typ=objectdef) then
               (ttypesym(srsym).typedef.typ=objectdef) then
-             ImplIntf:=aclass.find_implemented_interface(tobjectdef(ttypesym(srsym).typedef));
+             ImplIntf:=tobjectdef(astruct).find_implemented_interface(tobjectdef(ttypesym(srsym).typedef));
            if ImplIntf=nil then
            if ImplIntf=nil then
              Message(parser_e_interface_id_expected);
              Message(parser_e_interface_id_expected);
            consume(_ID);
            consume(_ID);
@@ -860,14 +864,14 @@ implementation
          end;
          end;
 
 
         { method  ? }
         { method  ? }
-        if not assigned(aclass) and
+        if not assigned(astruct) and
            (potype<>potype_operator) and
            (potype<>potype_operator) and
            (symtablestack.top.symtablelevel=main_program_level) and
            (symtablestack.top.symtablelevel=main_program_level) and
            try_to_consume(_POINT) then
            try_to_consume(_POINT) then
          begin
          begin
            repeat
            repeat
              searchagain:=false;
              searchagain:=false;
-             if not assigned(aclass) then
+             if not assigned(astruct) then
                begin
                begin
                  { search for object name }
                  { search for object name }
                  storepos:=current_tokenpos;
                  storepos:=current_tokenpos;
@@ -887,19 +891,19 @@ implementation
              consume(_ID);
              consume(_ID);
              { qualifier is class name ? }
              { qualifier is class name ? }
              if (srsym.typ=typesym) and
              if (srsym.typ=typesym) and
-                (ttypesym(srsym).typedef.typ=objectdef) then
+                (ttypesym(srsym).typedef.typ in [objectdef,recorddef]) then
               begin
               begin
-                aclass:=tobjectdef(ttypesym(srsym).typedef);
+                astruct:=tabstractrecorddef(ttypesym(srsym).typedef);
                 if (token<>_POINT) and (potype in [potype_class_constructor,potype_class_destructor]) then
                 if (token<>_POINT) and (potype in [potype_class_constructor,potype_class_destructor]) then
                   sp := lower(sp);
                   sp := lower(sp);
-                srsym:=tsym(aclass.symtable.Find(sp));
+                srsym:=tsym(astruct.symtable.Find(sp));
                 if assigned(srsym) then
                 if assigned(srsym) then
                  begin
                  begin
                    if srsym.typ=procsym then
                    if srsym.typ=procsym then
                      aprocsym:=tprocsym(srsym)
                      aprocsym:=tprocsym(srsym)
                    else
                    else
                    if (srsym.typ=typesym) and
                    if (srsym.typ=typesym) and
-                      (ttypesym(srsym).typedef.typ=objectdef) then
+                      (ttypesym(srsym).typedef.typ in [objectdef,recorddef]) then
                      begin
                      begin
                        searchagain:=true;
                        searchagain:=true;
                        consume(_POINT);
                        consume(_POINT);
@@ -920,7 +924,7 @@ implementation
                  begin
                  begin
                    Message(parser_e_methode_id_expected);
                    Message(parser_e_methode_id_expected);
                    { recover by making it a normal procedure instead of method }
                    { recover by making it a normal procedure instead of method }
-                   aclass:=nil;
+                   astruct:=nil;
                  end;
                  end;
               end
               end
              else
              else
@@ -1013,27 +1017,27 @@ implementation
             checkstack:=checkstack^.next;
             checkstack:=checkstack^.next;
           end;
           end;
         pd:=tprocdef.create(st.symtablelevel+1);
         pd:=tprocdef.create(st.symtablelevel+1);
-        pd._class:=aclass;
+        pd.struct:=astruct;
         pd.procsym:=aprocsym;
         pd.procsym:=aprocsym;
         pd.proctypeoption:=potype;
         pd.proctypeoption:=potype;
 
 
         { methods inherit df_generic or df_specialization from the objectdef }
         { methods inherit df_generic or df_specialization from the objectdef }
-        if assigned(pd._class) and
+        if assigned(pd.struct) and
            (pd.parast.symtablelevel=normal_function_level) then
            (pd.parast.symtablelevel=normal_function_level) then
           begin
           begin
-            if (df_generic in pd._class.defoptions) then
+            if (df_generic in pd.struct.defoptions) then
               begin
               begin
                 include(pd.defoptions,df_generic);
                 include(pd.defoptions,df_generic);
                 parse_generic:=true;
                 parse_generic:=true;
               end;
               end;
-            if (df_specialization in pd._class.defoptions) then
+            if (df_specialization in pd.struct.defoptions) then
               begin
               begin
                 include(pd.defoptions,df_specialization);
                 include(pd.defoptions,df_specialization);
                 { Find corresponding genericdef, we need it later to
                 { Find corresponding genericdef, we need it later to
                   replay the tokens to generate the body }
                   replay the tokens to generate the body }
-                if not assigned(pd._class.genericdef) then
+                if not assigned(pd.struct.genericdef) then
                   internalerror(200512113);
                   internalerror(200512113);
-                genericst:=pd._class.genericdef.GetSymtable(gs_record);
+                genericst:=pd.struct.genericdef.GetSymtable(gs_record);
                 if not assigned(genericst) then
                 if not assigned(genericst) then
                   internalerror(200512114);
                   internalerror(200512114);
                 { We are parsing the same objectdef, the def index numbers
                 { We are parsing the same objectdef, the def index numbers
@@ -1046,9 +1050,9 @@ implementation
           end;
           end;
 
 
         { methods need to be exported }
         { methods need to be exported }
-        if assigned(aclass) and
+        if assigned(astruct) and
            (
            (
-            (symtablestack.top.symtabletype=ObjectSymtable) or
+            (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) or
             (symtablestack.top.symtablelevel=main_program_level)
             (symtablestack.top.symtablelevel=main_program_level)
            ) then
            ) then
           include(pd.procoptions,po_global);
           include(pd.procoptions,po_global);
@@ -1064,19 +1068,19 @@ implementation
           begin
           begin
             { Add ObjectSymtable to be able to find nested type definitions }
             { Add ObjectSymtable to be able to find nested type definitions }
             popclass:=0;
             popclass:=0;
-            if assigned(pd._class) and
+            if assigned(pd.struct) and
                (pd.parast.symtablelevel=normal_function_level) and
                (pd.parast.symtablelevel=normal_function_level) and
-               (symtablestack.top.symtabletype<>ObjectSymtable) then
+               not(symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then
               begin
               begin
-                popclass:=push_nested_hierarchy(pd._class);
-                old_current_objectdef:=current_objectdef;
+                popclass:=push_nested_hierarchy(pd.struct);
+                old_current_structdef:=current_structdef;
                 old_current_genericdef:=current_genericdef;
                 old_current_genericdef:=current_genericdef;
                 old_current_specializedef:=current_specializedef;
                 old_current_specializedef:=current_specializedef;
-                current_objectdef:=pd._class;
-                if assigned(current_objectdef) and (df_generic in current_objectdef.defoptions) then
-                  current_genericdef:=current_objectdef;
-                if assigned(current_objectdef) and (df_specialization in current_objectdef.defoptions) then
-                  current_specializedef:=current_objectdef;
+                current_structdef:=pd.struct;
+                if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
+                  current_genericdef:=tobjectdef(current_structdef);
+                if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
+                  current_specializedef:=tobjectdef(current_structdef);
               end;
               end;
             { Add parameter symtable }
             { Add parameter symtable }
             if pd.parast.symtabletype<>staticsymtable then
             if pd.parast.symtabletype<>staticsymtable then
@@ -1086,10 +1090,10 @@ implementation
               symtablestack.pop(pd.parast);
               symtablestack.pop(pd.parast);
             if popclass>0 then
             if popclass>0 then
               begin
               begin
-                current_objectdef:=old_current_objectdef;
+                current_structdef:=old_current_structdef;
                 current_genericdef:=old_current_genericdef;
                 current_genericdef:=old_current_genericdef;
                 current_specializedef:=old_current_specializedef;
                 current_specializedef:=old_current_specializedef;
-                dec(popclass,pop_nested_hierarchy(pd._class));
+                dec(popclass,pop_nested_hierarchy(pd.struct));
                 if popclass<>0 then
                 if popclass<>0 then
                   internalerror(201011260); // 11 nov 2010 index 0
                   internalerror(201011260); // 11 nov 2010 index 0
               end;
               end;
@@ -1100,13 +1104,13 @@ implementation
       end;
       end;
 
 
 
 
-    function parse_proc_dec(isclassmethod:boolean; aclass:tobjectdef):tprocdef;
+    function parse_proc_dec(isclassmethod:boolean;astruct:tabstractrecorddef):tprocdef;
       var
       var
         pd : tprocdef;
         pd : tprocdef;
         locationstr: string;
         locationstr: string;
         old_parse_generic: boolean;
         old_parse_generic: boolean;
         popclass: integer;
         popclass: integer;
-        old_current_objectdef,
+        old_current_structdef: tabstractrecorddef;
         old_current_genericdef,
         old_current_genericdef,
         old_current_specializedef: tobjectdef;
         old_current_specializedef: tobjectdef;
       begin
       begin
@@ -1116,7 +1120,7 @@ implementation
           _FUNCTION :
           _FUNCTION :
             begin
             begin
               consume(_FUNCTION);
               consume(_FUNCTION);
-              if parse_proc_head(aclass,potype_function,pd) then
+              if parse_proc_head(astruct,potype_function,pd) then
                 begin
                 begin
                   { pd=nil when it is a interface mapping }
                   { pd=nil when it is a interface mapping }
                   if assigned(pd) then
                   if assigned(pd) then
@@ -1127,32 +1131,32 @@ implementation
                          inc(testcurobject);
                          inc(testcurobject);
                          { Add ObjectSymtable to be able to find generic type definitions }
                          { Add ObjectSymtable to be able to find generic type definitions }
                          popclass:=0;
                          popclass:=0;
-                         if assigned(pd._class) and
+                         if assigned(pd.struct) and
                             (pd.parast.symtablelevel=normal_function_level) and
                             (pd.parast.symtablelevel=normal_function_level) and
-                            (symtablestack.top.symtabletype<>ObjectSymtable) then
+                            not (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then
                            begin
                            begin
-                             popclass:=push_nested_hierarchy(pd._class);
-                             parse_generic:=(df_generic in pd._class.defoptions);
-                             old_current_objectdef:=current_objectdef;
+                             popclass:=push_nested_hierarchy(pd.struct);
+                             parse_generic:=(df_generic in pd.struct.defoptions);
+                             old_current_structdef:=current_structdef;
                              old_current_genericdef:=current_genericdef;
                              old_current_genericdef:=current_genericdef;
                              old_current_specializedef:=current_specializedef;
                              old_current_specializedef:=current_specializedef;
-                             current_objectdef:=pd._class;
-                             if assigned(current_objectdef) and (df_generic in current_objectdef.defoptions) then
-                               current_genericdef:=current_objectdef;
-                             if assigned(current_objectdef) and (df_specialization in current_objectdef.defoptions) then
-                               current_specializedef:=current_objectdef;
+                             current_structdef:=pd.struct;
+                             if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
+                               current_genericdef:=tobjectdef(current_structdef);
+                             if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
+                               current_specializedef:=tobjectdef(current_structdef);
                            end;
                            end;
                          single_type(pd.returndef,false,false);
                          single_type(pd.returndef,false,false);
 
 
-                         if is_dispinterface(pd._class) and not is_automatable(pd.returndef) then
+                         if is_dispinterface(pd.struct) and not is_automatable(pd.returndef) then
                            Message1(type_e_not_automatable,pd.returndef.typename);
                            Message1(type_e_not_automatable,pd.returndef.typename);
 
 
                          if popclass>0 then
                          if popclass>0 then
                            begin
                            begin
-                             current_objectdef:=old_current_objectdef;
+                             current_structdef:=old_current_structdef;
                              current_genericdef:=old_current_genericdef;
                              current_genericdef:=old_current_genericdef;
                              current_specializedef:=old_current_specializedef;
                              current_specializedef:=old_current_specializedef;
-                             dec(popclass,pop_nested_hierarchy(pd._class));
+                             dec(popclass,pop_nested_hierarchy(pd.struct));
                              if popclass<>0 then
                              if popclass<>0 then
                                internalerror(201012020);
                                internalerror(201012020);
                            end;
                            end;
@@ -1187,7 +1191,7 @@ implementation
                        begin
                        begin
                           if (
                           if (
                               parse_only and
                               parse_only and
-                              not(is_interface(pd._class))
+                              not(is_interface(pd.struct))
                              ) or
                              ) or
                              (m_repeat_forward in current_settings.modeswitches) then
                              (m_repeat_forward in current_settings.modeswitches) then
                           begin
                           begin
@@ -1210,7 +1214,7 @@ implementation
           _PROCEDURE :
           _PROCEDURE :
             begin
             begin
               consume(_PROCEDURE);
               consume(_PROCEDURE);
-              if parse_proc_head(aclass,potype_procedure,pd) then
+              if parse_proc_head(astruct,potype_procedure,pd) then
                 begin
                 begin
                   { pd=nil when it is an interface mapping }
                   { pd=nil when it is an interface mapping }
                   if assigned(pd) then
                   if assigned(pd) then
@@ -1226,17 +1230,17 @@ implementation
             begin
             begin
               consume(_CONSTRUCTOR);
               consume(_CONSTRUCTOR);
               if isclassmethod then
               if isclassmethod then
-                parse_proc_head(aclass,potype_class_constructor,pd)
+                parse_proc_head(astruct,potype_class_constructor,pd)
               else
               else
-                parse_proc_head(aclass,potype_constructor,pd);
+                parse_proc_head(astruct,potype_constructor,pd);
               if not isclassmethod and
               if not isclassmethod and
                  assigned(pd) and
                  assigned(pd) and
-                 assigned(pd._class) then
+                 assigned(pd.struct) then
                 begin
                 begin
                   { Set return type, class constructors return the
                   { Set return type, class constructors return the
                     created instance, object constructors return boolean }
                     created instance, object constructors return boolean }
-                  if is_class(pd._class) then
-                    pd.returndef:=pd._class
+                  if is_class(pd.struct) then
+                    pd.returndef:=pd.struct
                   else
                   else
 {$ifdef CPU64bitaddr}
 {$ifdef CPU64bitaddr}
                     pd.returndef:=bool64type;
                     pd.returndef:=bool64type;
@@ -1252,9 +1256,9 @@ implementation
             begin
             begin
               consume(_DESTRUCTOR);
               consume(_DESTRUCTOR);
               if isclassmethod then
               if isclassmethod then
-                parse_proc_head(aclass,potype_class_destructor,pd)
+                parse_proc_head(astruct,potype_class_destructor,pd)
               else
               else
-                parse_proc_head(aclass,potype_destructor,pd);
+                parse_proc_head(astruct,potype_destructor,pd);
               if assigned(pd) then
               if assigned(pd) then
                 pd.returndef:=voidtype;
                 pd.returndef:=voidtype;
             end;
             end;
@@ -1286,7 +1290,7 @@ implementation
                  end;
                  end;
                end;
                end;
               consume(token);
               consume(token);
-              parse_proc_head(aclass,potype_operator,pd);
+              parse_proc_head(astruct,potype_operator,pd);
               if assigned(pd) then
               if assigned(pd) then
                 begin
                 begin
                   { operators always need to be searched in all units }
                   { operators always need to be searched in all units }
@@ -1375,7 +1379,7 @@ procedure pd_export(pd:tabstractprocdef);
 begin
 begin
   if pd.typ<>procdef then
   if pd.typ<>procdef then
     internalerror(200304264);
     internalerror(200304264);
-  if assigned(tprocdef(pd)._class) then
+  if assigned(tprocdef(pd).struct) then
     Message(parser_e_methods_dont_be_export);
     Message(parser_e_methods_dont_be_export);
   if pd.parast.symtablelevel>normal_function_level then
   if pd.parast.symtablelevel>normal_function_level then
     Message(parser_e_dont_nest_export);
     Message(parser_e_dont_nest_export);
@@ -1473,7 +1477,9 @@ procedure pd_abstract(pd:tabstractprocdef);
 begin
 begin
   if pd.typ<>procdef then
   if pd.typ<>procdef then
     internalerror(200304269);
     internalerror(200304269);
-  if oo_is_sealed in tprocdef(pd)._class.objectoptions then
+  if assigned(tprocdef(pd).struct) and
+    (tprocdef(pd).struct.typ=objectdef) and
+    (oo_is_sealed in tobjectdef(tprocdef(pd).struct).objectoptions) then
     Message(parser_e_sealed_class_cannot_have_abstract_methods)
     Message(parser_e_sealed_class_cannot_have_abstract_methods)
   else
   else
   if (po_virtualmethod in pd.procoptions) then
   if (po_virtualmethod in pd.procoptions) then
@@ -1502,13 +1508,13 @@ begin
   begin
   begin
     if pattern='MOVENEXT' then
     if pattern='MOVENEXT' then
     begin
     begin
-      if oo_has_enumerator_movenext in tprocdef(pd)._class.objectoptions then
+      if oo_has_enumerator_movenext in tobjectdef(tprocdef(pd).struct).objectoptions then
         message(parser_e_only_one_enumerator_movenext);
         message(parser_e_only_one_enumerator_movenext);
       pd.calcparas;
       pd.calcparas;
       if (pd.proctypeoption = potype_function) and is_boolean(pd.returndef) and
       if (pd.proctypeoption = potype_function) and is_boolean(pd.returndef) and
          (pd.minparacount = 0) then
          (pd.minparacount = 0) then
       begin
       begin
-        include(tprocdef(pd)._class.objectoptions, oo_has_enumerator_movenext);
+        include(tobjectdef(tprocdef(pd).struct).objectoptions, oo_has_enumerator_movenext);
         include(pd.procoptions,po_enumerator_movenext);
         include(pd.procoptions,po_enumerator_movenext);
       end
       end
       else
       else
@@ -1531,10 +1537,10 @@ begin
   if pd.typ<>procdef then
   if pd.typ<>procdef then
     internalerror(2003042610);
     internalerror(2003042610);
   if (pd.proctypeoption=potype_constructor) and
   if (pd.proctypeoption=potype_constructor) and
-     is_object(tprocdef(pd)._class) then
+     is_object(tprocdef(pd).struct) then
     Message(parser_e_constructor_cannot_be_not_virtual);
     Message(parser_e_constructor_cannot_be_not_virtual);
 {$ifdef WITHDMT}
 {$ifdef WITHDMT}
-  if is_object(tprocdef(pd)._class) and
+  if is_object(tprocdef(pd).struct) and
      (token<>_SEMICOLON) then
      (token<>_SEMICOLON) then
     begin
     begin
        { any type of parameter is allowed here! }
        { any type of parameter is allowed here! }
@@ -1559,7 +1565,7 @@ var pt:Tnode;
 begin
 begin
   if pd.typ<>procdef then
   if pd.typ<>procdef then
     internalerror(200604301);
     internalerror(200604301);
-  pt:=comp_expr(true);
+  pt:=comp_expr(true,false);
   if is_constintnode(pt) then
   if is_constintnode(pt) then
     if (Tordconstnode(pt).value<int64(low(longint))) or (Tordconstnode(pt).value>int64(high(longint))) then
     if (Tordconstnode(pt).value<int64(low(longint))) or (Tordconstnode(pt).value>int64(high(longint))) then
       message(parser_e_range_check_error)
       message(parser_e_range_check_error)
@@ -1582,9 +1588,9 @@ procedure pd_override(pd:tabstractprocdef);
 begin
 begin
   if pd.typ<>procdef then
   if pd.typ<>procdef then
     internalerror(2003042611);
     internalerror(2003042611);
-  if not(is_class_or_interface_or_objc(tprocdef(pd)._class)) then
+  if not(is_class_or_interface_or_objc(tprocdef(pd).struct)) then
     Message(parser_e_no_object_override)
     Message(parser_e_no_object_override)
-  else if is_objccategory(tprocdef(pd)._class) then
+  else if is_objccategory(tprocdef(pd).struct) then
     Message(parser_e_no_category_override);
     Message(parser_e_no_category_override);
 end;
 end;
 
 
@@ -1602,20 +1608,20 @@ var
 begin
 begin
   if pd.typ<>procdef then
   if pd.typ<>procdef then
     internalerror(2003042613);
     internalerror(2003042613);
-  if not is_class(tprocdef(pd)._class) and
-     not is_objc_class_or_protocol(tprocdef(pd)._class) then
+  if not is_class(tprocdef(pd).struct) and
+     not is_objc_class_or_protocol(tprocdef(pd).struct) then
     Message(parser_e_msg_only_for_classes);
     Message(parser_e_msg_only_for_classes);
   if ([po_msgstr,po_msgint]*pd.procoptions)<>[] then
   if ([po_msgstr,po_msgint]*pd.procoptions)<>[] then
     Message(parser_e_multiple_messages);
     Message(parser_e_multiple_messages);
   { check parameter type }
   { check parameter type }
-  if not is_objc_class_or_protocol(tprocdef(pd)._class) then
+  if not is_objc_class_or_protocol(tprocdef(pd).struct) then
     begin
     begin
       paracnt:=0;
       paracnt:=0;
       pd.parast.SymList.ForEachCall(@check_msg_para,@paracnt);
       pd.parast.SymList.ForEachCall(@check_msg_para,@paracnt);
       if paracnt<>1 then
       if paracnt<>1 then
         Message(parser_e_ill_msg_param);
         Message(parser_e_ill_msg_param);
     end;
     end;
-  pt:=comp_expr(true);
+  pt:=comp_expr(true,false);
   { message is 1-character long }
   { message is 1-character long }
   if is_constcharnode(pt) then
   if is_constcharnode(pt) then
     begin
     begin
@@ -1631,7 +1637,7 @@ begin
     end
     end
   else
   else
    if is_constintnode(pt) and
    if is_constintnode(pt) and
-      is_class(tprocdef(pd)._class) then
+      is_class(tprocdef(pd).struct) then
     begin
     begin
       include(pd.procoptions,po_msgint);
       include(pd.procoptions,po_msgint);
       if (Tordconstnode(pt).value<int64(low(Tprocdef(pd).messageinf.i))) or
       if (Tordconstnode(pt).value<int64(low(Tprocdef(pd).messageinf.i))) or
@@ -1644,7 +1650,7 @@ begin
     Message(parser_e_ill_msg_expr);
     Message(parser_e_ill_msg_expr);
   { check whether the selector name is valid in case of Objective-C }
   { check whether the selector name is valid in case of Objective-C }
   if (po_msgstr in pd.procoptions) and
   if (po_msgstr in pd.procoptions) and
-     is_objc_class_or_protocol(tprocdef(pd)._class) and
+     is_objc_class_or_protocol(tprocdef(pd).struct) and
      not objcvalidselectorname(@tprocdef(pd).messageinf.str^[1],length(tprocdef(pd).messageinf.str^)) then
      not objcvalidselectorname(@tprocdef(pd).messageinf.str^[1],length(tprocdef(pd).messageinf.str^)) then
     Message1(type_e_invalid_objc_selector_name,tprocdef(pd).messageinf.str^);
     Message1(type_e_invalid_objc_selector_name,tprocdef(pd).messageinf.str^);
   pt.free;
   pt.free;
@@ -1655,8 +1661,8 @@ procedure pd_reintroduce(pd:tabstractprocdef);
 begin
 begin
   if pd.typ<>procdef then
   if pd.typ<>procdef then
     internalerror(200401211);
     internalerror(200401211);
-  if not(is_class_or_interface_or_object(tprocdef(pd)._class)) and
-     not(is_objccategory(tprocdef(pd)._class)) then
+  if not(is_class_or_interface_or_object(tprocdef(pd).struct)) and
+     not(is_objccategory(tprocdef(pd).struct)) then
     Message(parser_e_no_object_reintroduce);
     Message(parser_e_no_object_reintroduce);
 end;
 end;
 
 
@@ -1937,7 +1943,7 @@ const
    (
    (
     (
     (
       idtok:_ABSTRACT;
       idtok:_ABSTRACT;
-      pd_flags : [pd_interface,pd_object,pd_notobjintf];
+      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord];
       handler  : @pd_abstract;
       handler  : @pd_abstract;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_abstractmethod];
       pooption : [po_abstractmethod];
@@ -2000,7 +2006,7 @@ const
       mutexclpo     : [po_interrupt,po_external,po_inline]
       mutexclpo     : [po_interrupt,po_external,po_inline]
     ),(
     ),(
       idtok:_DYNAMIC;
       idtok:_DYNAMIC;
-      pd_flags : [pd_interface,pd_object,pd_notobjintf];
+      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord];
       handler  : @pd_virtual;
       handler  : @pd_virtual;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_virtualmethod];
       pooption : [po_virtualmethod];
@@ -2009,7 +2015,7 @@ const
       mutexclpo     : [po_exports,po_interrupt,po_external,po_overridingmethod,po_inline]
       mutexclpo     : [po_exports,po_interrupt,po_external,po_overridingmethod,po_inline]
     ),(
     ),(
       idtok:_EXPORT;
       idtok:_EXPORT;
-      pd_flags : [pd_body,pd_interface,pd_implemen,pd_notobjintf];
+      pd_flags : [pd_body,pd_interface,pd_implemen,pd_notobjintf,pd_notrecord];
       handler  : @pd_export;
       handler  : @pd_export;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_exports,po_global];
       pooption : [po_exports,po_global];
@@ -2018,7 +2024,7 @@ const
       mutexclpo     : [po_external,po_interrupt,po_inline]
       mutexclpo     : [po_external,po_interrupt,po_inline]
     ),(
     ),(
       idtok:_EXTERNAL;
       idtok:_EXTERNAL;
-      pd_flags : [pd_implemen,pd_interface,pd_notobject,pd_notobjintf,pd_cppobject];
+      pd_flags : [pd_implemen,pd_interface,pd_notobject,pd_notobjintf,pd_cppobject,pd_notrecord];
       handler  : @pd_external;
       handler  : @pd_external;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_external];
       pooption : [po_external];
@@ -2028,7 +2034,7 @@ const
       mutexclpo     : [po_public,po_exports,po_interrupt,po_assembler,po_inline]
       mutexclpo     : [po_public,po_exports,po_interrupt,po_assembler,po_inline]
     ),(
     ),(
       idtok:_FAR;
       idtok:_FAR;
-      pd_flags : [pd_implemen,pd_body,pd_interface,pd_procvar,pd_notobject,pd_notobjintf];
+      pd_flags : [pd_implemen,pd_body,pd_interface,pd_procvar,pd_notobject,pd_notobjintf,pd_notrecord];
       handler  : @pd_far;
       handler  : @pd_far;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [];
       pooption : [];
@@ -2037,7 +2043,7 @@ const
       mutexclpo     : [po_inline]
       mutexclpo     : [po_inline]
     ),(
     ),(
       idtok:_FAR16;
       idtok:_FAR16;
-      pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar,pd_notobject];
+      pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar,pd_notobject,pd_notrecord];
       handler  : nil;
       handler  : nil;
       pocall   : pocall_far16;
       pocall   : pocall_far16;
       pooption : [];
       pooption : [];
@@ -2046,7 +2052,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_FINAL;
       idtok:_FINAL;
-      pd_flags : [pd_interface,pd_object,pd_notobjintf];
+      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord];
       handler  : @pd_final;
       handler  : @pd_final;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_finalmethod];
       pooption : [po_finalmethod];
@@ -2055,7 +2061,7 @@ const
       mutexclpo     : [po_exports,po_interrupt,po_external,po_inline]
       mutexclpo     : [po_exports,po_interrupt,po_external,po_inline]
     ),(
     ),(
       idtok:_FORWARD;
       idtok:_FORWARD;
-      pd_flags : [pd_implemen,pd_notobject,pd_notobjintf];
+      pd_flags : [pd_implemen,pd_notobject,pd_notobjintf,pd_notrecord];
       handler  : @pd_forward;
       handler  : @pd_forward;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [];
       pooption : [];
@@ -2082,7 +2088,7 @@ const
       mutexclpo     : [po_exports,po_external,po_interrupt,po_virtualmethod]
       mutexclpo     : [po_exports,po_external,po_interrupt,po_virtualmethod]
     ),(
     ),(
       idtok:_INTERNCONST;
       idtok:_INTERNCONST;
-      pd_flags : [pd_interface,pd_body,pd_notobject,pd_notobjintf];
+      pd_flags : [pd_interface,pd_body,pd_notobject,pd_notobjintf,pd_notrecord];
       handler  : @pd_internconst;
       handler  : @pd_internconst;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_internconst];
       pooption : [po_internconst];
@@ -2091,7 +2097,7 @@ const
       mutexclpo     : []
       mutexclpo     : []
     ),(
     ),(
       idtok:_INTERNPROC;
       idtok:_INTERNPROC;
-      pd_flags : [pd_interface,pd_notobject,pd_notobjintf];
+      pd_flags : [pd_interface,pd_notobject,pd_notobjintf,pd_notrecord];
       handler  : @pd_internproc;
       handler  : @pd_internproc;
       pocall   : pocall_internproc;
       pocall   : pocall_internproc;
       pooption : [];
       pooption : [];
@@ -2100,7 +2106,7 @@ const
       mutexclpo     : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_virtualmethod]
       mutexclpo     : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_virtualmethod]
     ),(
     ),(
       idtok:_INTERRUPT;
       idtok:_INTERRUPT;
-      pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf];
+      pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf,pd_notrecord];
       handler  : @pd_interrupt;
       handler  : @pd_interrupt;
       pocall   : pocall_oldfpccall;
       pocall   : pocall_oldfpccall;
       pooption : [po_interrupt];
       pooption : [po_interrupt];
@@ -2128,7 +2134,7 @@ const
       mutexclpo     : [po_external,po_exports]
       mutexclpo     : [po_external,po_exports]
     ),(
     ),(
       idtok:_MESSAGE;
       idtok:_MESSAGE;
-      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass, pd_objcprot];
+      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass,pd_objcprot,pd_notrecord];
       handler  : @pd_message;
       handler  : @pd_message;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : []; { can be po_msgstr or po_msgint }
       pooption : []; { can be po_msgstr or po_msgint }
@@ -2146,7 +2152,7 @@ const
       mutexclpo     : []
       mutexclpo     : []
     ),(
     ),(
       idtok:_NEAR;
       idtok:_NEAR;
-      pd_flags : [pd_implemen,pd_body,pd_procvar,pd_notobjintf];
+      pd_flags : [pd_implemen,pd_body,pd_procvar,pd_notobjintf,pd_notrecord];
       handler  : @pd_near;
       handler  : @pd_near;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [];
       pooption : [];
@@ -2173,7 +2179,7 @@ const
       mutexclpo     : []
       mutexclpo     : []
     ),(
     ),(
       idtok:_OVERRIDE;
       idtok:_OVERRIDE;
-      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass];
+      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass,pd_notrecord];
       handler  : @pd_override;
       handler  : @pd_override;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_overridingmethod,po_virtualmethod];
       pooption : [po_overridingmethod,po_virtualmethod];
@@ -2191,7 +2197,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_PUBLIC;
       idtok:_PUBLIC;
-      pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobject,pd_notobjintf];
+      pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobject,pd_notobjintf,pd_notrecord];
       handler  : @pd_public;
       handler  : @pd_public;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_public,po_global];
       pooption : [po_public,po_global];
@@ -2209,7 +2215,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_REINTRODUCE;
       idtok:_REINTRODUCE;
-      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass];
+      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass,pd_notrecord];
       handler  : @pd_reintroduce;
       handler  : @pd_reintroduce;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_reintroduce];
       pooption : [po_reintroduce];
@@ -2238,7 +2244,7 @@ const
       mutexclpo     : []
       mutexclpo     : []
     ),(
     ),(
       idtok:_STATIC;
       idtok:_STATIC;
-      pd_flags : [pd_interface,pd_implemen,pd_body,pd_object,pd_notobjintf];
+      pd_flags : [pd_interface,pd_implemen,pd_body,pd_object,pd_record,pd_notobjintf];
       handler  : @pd_static;
       handler  : @pd_static;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_staticmethod];
       pooption : [po_staticmethod];
@@ -2268,7 +2274,7 @@ const
       mutexclpo     : [po_external,po_assembler,po_interrupt,po_exports]
       mutexclpo     : [po_external,po_assembler,po_interrupt,po_exports]
     ),(
     ),(
       idtok:_VIRTUAL;
       idtok:_VIRTUAL;
-      pd_flags : [pd_interface,pd_object,pd_notobjintf];
+      pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord];
       handler  : @pd_virtual;
       handler  : @pd_virtual;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_virtualmethod];
       pooption : [po_virtualmethod];
@@ -2286,7 +2292,7 @@ const
       mutexclpo     : [po_assembler,po_external,po_virtualmethod]
       mutexclpo     : [po_assembler,po_external,po_virtualmethod]
     ),(
     ),(
       idtok:_VARARGS;
       idtok:_VARARGS;
-      pd_flags : [pd_interface,pd_implemen,pd_procvar,pd_objcclass, pd_objcprot];
+      pd_flags : [pd_interface,pd_implemen,pd_procvar,pd_objcclass,pd_objcprot];
       handler  : nil;
       handler  : nil;
       pocall   : pocall_none;
       pocall   : pocall_none;
       pooption : [po_varargs];
       pooption : [po_varargs];
@@ -2305,7 +2311,7 @@ const
       mutexclpo     : [po_interrupt]
       mutexclpo     : [po_interrupt]
     ),(
     ),(
       idtok:_WEAKEXTERNAL;
       idtok:_WEAKEXTERNAL;
-      pd_flags : [pd_implemen,pd_interface,pd_notobject,pd_notobjintf,pd_cppobject];
+      pd_flags : [pd_implemen,pd_interface,pd_notobject,pd_notobjintf,pd_cppobject,pd_notrecord];
       handler  : @pd_weakexternal;
       handler  : @pd_weakexternal;
       pocall   : pocall_none;
       pocall   : pocall_none;
       { mark it both external and weak external, so we don't have to
       { mark it both external and weak external, so we don't have to
@@ -2392,7 +2398,7 @@ const
          begin
          begin
             { parsing a procvar type the name can be any
             { parsing a procvar type the name can be any
               next variable !! }
               next variable !! }
-            if ((pdflags * [pd_procvar,pd_object,pd_objcclass,pd_objcprot])=[]) and
+            if ((pdflags * [pd_procvar,pd_object,pd_record,pd_objcclass,pd_objcprot])=[]) and
                not(idtoken=_PROPERTY) then
                not(idtoken=_PROPERTY) then
               Message1(parser_w_unknown_proc_directive_ignored,name);
               Message1(parser_w_unknown_proc_directive_ignored,name);
             exit;
             exit;
@@ -2406,6 +2412,10 @@ const
            not(is_cppclass(tdef(symtablestack.top.defowner)) and (pd_cppobject in proc_direcdata[p].pd_flags)) then
            not(is_cppclass(tdef(symtablestack.top.defowner)) and (pd_cppobject in proc_direcdata[p].pd_flags)) then
            exit;
            exit;
 
 
+        if (pd_notrecord in proc_direcdata[p].pd_flags) and
+           (symtablestack.top.symtabletype=recordsymtable) then
+           exit;
+
         { Conflicts between directives ? }
         { Conflicts between directives ? }
         if (pd.proctypeoption in proc_direcdata[p].mutexclpotype) or
         if (pd.proctypeoption in proc_direcdata[p].mutexclpotype) or
            (pd.proccalloption in proc_direcdata[p].mutexclpocall) or
            (pd.proccalloption in proc_direcdata[p].mutexclpocall) or
@@ -2439,26 +2449,31 @@ const
          begin
          begin
            { Check if the directive is only for objects }
            { Check if the directive is only for objects }
            if (pd_object in proc_direcdata[p].pd_flags) and
            if (pd_object in proc_direcdata[p].pd_flags) and
-              not assigned(tprocdef(pd)._class) then
+              not assigned(tprocdef(pd).struct) then
+            exit;
+
+           { Check if the directive is only for records }
+           if (pd_record in proc_direcdata[p].pd_flags) and
+              not assigned(tprocdef(pd).struct) then
             exit;
             exit;
 
 
            { check if method and directive not for interface }
            { check if method and directive not for interface }
            if (pd_notobjintf in proc_direcdata[p].pd_flags) and
            if (pd_notobjintf in proc_direcdata[p].pd_flags) and
-              is_interface(tprocdef(pd)._class) then
+              is_interface(tprocdef(pd).struct) then
             exit;
             exit;
 
 
            { check if method and directive not for interface }
            { check if method and directive not for interface }
-           if is_dispinterface(tprocdef(pd)._class) and
+           if is_dispinterface(tprocdef(pd).struct) and
              not(pd_dispinterface in proc_direcdata[p].pd_flags) then
              not(pd_dispinterface in proc_direcdata[p].pd_flags) then
             exit;
             exit;
 
 
            { check if method and directive not for objcclass }
            { check if method and directive not for objcclass }
-           if is_objcclass(tprocdef(pd)._class) and
+           if is_objcclass(tprocdef(pd).struct) and
              not(pd_objcclass in proc_direcdata[p].pd_flags) then
              not(pd_objcclass in proc_direcdata[p].pd_flags) then
             exit;
             exit;
 
 
            { check if method and directive not for objcprotocol }
            { check if method and directive not for objcprotocol }
-           if is_objcprotocol(tprocdef(pd)._class) and
+           if is_objcprotocol(tprocdef(pd).struct) and
              not(pd_objcprot in proc_direcdata[p].pd_flags) then
              not(pd_objcprot in proc_direcdata[p].pd_flags) then
             exit;
             exit;
 
 
@@ -2557,8 +2572,8 @@ const
             case pd.proccalloption of
             case pd.proccalloption of
               pocall_cdecl :
               pocall_cdecl :
                 begin
                 begin
-                  if assigned(pd._class) then
-                    result:=target_info.Cprefix+pd._class.objrealname^+'_'+pd.procsym.realname
+                  if assigned(pd.struct) then
+                    result:=target_info.Cprefix+pd.struct.objrealname^+'_'+pd.procsym.realname
                   else
                   else
                     result:=target_info.Cprefix+pd.procsym.realname;
                     result:=target_info.Cprefix+pd.procsym.realname;
                 end;
                 end;
@@ -2628,8 +2643,8 @@ const
             case pd.proccalloption of
             case pd.proccalloption of
               pocall_cdecl :
               pocall_cdecl :
                 begin
                 begin
-                  if assigned(pd._class) then
-                   pd.aliasnames.insert(target_info.Cprefix+pd._class.objrealname^+'_'+pd.procsym.realname)
+                  if assigned(pd.struct) then
+                   pd.aliasnames.insert(target_info.Cprefix+pd.struct.objrealname^+'_'+pd.procsym.realname)
                   else
                   else
                     begin
                     begin
                       { Export names are not mangled on Windows and OS/2, see also pexports.pas }
                       { Export names are not mangled on Windows and OS/2, see also pexports.pas }
@@ -2655,13 +2670,13 @@ const
       begin
       begin
         { set the default calling convention if none provided }
         { set the default calling convention if none provided }
         if (pd.typ=procdef) and
         if (pd.typ=procdef) and
-           (is_objc_class_or_protocol(tprocdef(pd)._class) or
-            is_cppclass(tprocdef(pd)._class)) then
+           (is_objc_class_or_protocol(tprocdef(pd).struct) or
+            is_cppclass(tprocdef(pd).struct)) then
           begin
           begin
             { none of the explicit calling conventions should be allowed }
             { none of the explicit calling conventions should be allowed }
             if (po_hascallingconvention in pd.procoptions) then
             if (po_hascallingconvention in pd.procoptions) then
               internalerror(2009032501);
               internalerror(2009032501);
-            if is_cppclass(tprocdef(pd)._class) then
+            if is_cppclass(tprocdef(pd).struct) then
               pd.proccalloption:=pocall_cppdecl
               pd.proccalloption:=pocall_cppdecl
             else
             else
               pd.proccalloption:=pocall_cdecl;
               pd.proccalloption:=pocall_cdecl;
@@ -2716,7 +2731,7 @@ const
                      (pd.typ=procvardef) or
                      (pd.typ=procvardef) or
                      { for objcclasses this is checked later, because the entire
                      { for objcclasses this is checked later, because the entire
                        class may be external.  }
                        class may be external.  }
-                     is_objc_class_or_protocol(tprocdef(pd)._class)) and
+                     is_objc_class_or_protocol(tprocdef(pd).struct)) and
                  not(pd.proccalloption in (cdecl_pocalls + [pocall_mwpascal])) then
                  not(pd.proccalloption in (cdecl_pocalls + [pocall_mwpascal])) then
                 Message(parser_e_varargs_need_cdecl_and_external);
                 Message(parser_e_varargs_need_cdecl_and_external);
             end
             end
@@ -2862,6 +2877,13 @@ const
         parse_proc_directives(pd,pdflags);
         parse_proc_directives(pd,pdflags);
       end;
       end;
 
 
+    procedure parse_record_proc_directives(pd:tabstractprocdef);
+      var
+        pdflags : tpdflags;
+      begin
+        pdflags:=[pd_record];
+        parse_proc_directives(pd,pdflags);
+      end;
 
 
     function proc_add_definition(var currpd:tprocdef):boolean;
     function proc_add_definition(var currpd:tprocdef):boolean;
       {
       {
@@ -3141,7 +3163,7 @@ const
                  { check if all procs have overloading, but not if the proc is a method or
                  { check if all procs have overloading, but not if the proc is a method or
                    already declared forward, then the check is already done }
                    already declared forward, then the check is already done }
                  if not(fwpd.hasforward or
                  if not(fwpd.hasforward or
-                        assigned(currpd._class) or
+                        assigned(currpd.struct) or
                         (currpd.forwarddef<>fwpd.forwarddef) or
                         (currpd.forwarddef<>fwpd.forwarddef) or
                         ((po_overload in currpd.procoptions) and
                         ((po_overload in currpd.procoptions) and
                          (po_overload in fwpd.procoptions))) then
                          (po_overload in fwpd.procoptions))) then

+ 13 - 12
compiler/pdecvar.pas

@@ -83,7 +83,7 @@ implementation
             if token=_ID then
             if token=_ID then
              begin
              begin
                if assigned(aclass) then
                if assigned(aclass) then
-                 sym:=search_class_member(aclass,pattern)
+                 sym:=search_struct_member(aclass,pattern)
                else
                else
                  searchsym(pattern,sym,srsymtable);
                  searchsym(pattern,sym,srsymtable);
                if assigned(sym) then
                if assigned(sym) then
@@ -137,7 +137,7 @@ implementation
                            begin
                            begin
                              sym:=tsym(st.Find(pattern));
                              sym:=tsym(st.Find(pattern));
                              if not(assigned(sym)) and is_object(def) then
                              if not(assigned(sym)) and is_object(def) then
-                               sym:=search_class_member(tobjectdef(def),pattern);
+                               sym:=search_struct_member(tobjectdef(def),pattern);
                              if assigned(sym) then
                              if assigned(sym) then
                               begin
                               begin
                                 pl.addsym(sl_subscript,sym);
                                 pl.addsym(sl_subscript,sym);
@@ -177,7 +177,7 @@ implementation
                          if def.typ=arraydef then
                          if def.typ=arraydef then
                           begin
                           begin
                             idx:=0;
                             idx:=0;
-                            p:=comp_expr(true);
+                            p:=comp_expr(true,false);
                             if (not codegenerror) then
                             if (not codegenerror) then
                              begin
                              begin
                                if (p.nodetype=ordconstn) then
                                if (p.nodetype=ordconstn) then
@@ -268,7 +268,7 @@ implementation
 
 
               if try_to_consume(_DISPID) then
               if try_to_consume(_DISPID) then
                 begin
                 begin
-                  pt:=comp_expr(true);
+                  pt:=comp_expr(true,false);
                   if is_constintnode(pt) then
                   if is_constintnode(pt) then
                     if (Tordconstnode(pt).value<int64(low(longint))) or (Tordconstnode(pt).value>int64(high(longint))) then
                     if (Tordconstnode(pt).value<int64(low(longint))) or (Tordconstnode(pt).value>int64(high(longint))) then
                       message(parser_e_range_check_error)
                       message(parser_e_range_check_error)
@@ -427,7 +427,7 @@ implementation
               if (idtoken=_INDEX) then
               if (idtoken=_INDEX) then
                 begin
                 begin
                    consume(_INDEX);
                    consume(_INDEX);
-                   pt:=comp_expr(true);
+                   pt:=comp_expr(true,false);
                    { Only allow enum and integer indexes. Convert all integer
                    { Only allow enum and integer indexes. Convert all integer
                      values to s32int to be compatible with delphi, because the
                      values to s32int to be compatible with delphi, because the
                      procedure matching requires equal parameters }
                      procedure matching requires equal parameters }
@@ -457,7 +457,7 @@ implementation
          else
          else
            begin
            begin
               { do an property override }
               { do an property override }
-              overridden:=search_class_member(aclass.childof,p.name);
+              overridden:=search_struct_member(aclass.childof,p.name);
               if assigned(overridden) and
               if assigned(overridden) and
                  (overridden.typ=propertysym) and
                  (overridden.typ=propertysym) and
                  not(is_dispinterface(aclass)) then
                  not(is_dispinterface(aclass)) then
@@ -618,7 +618,7 @@ implementation
                            methods
                            methods
                          }
                          }
                          if (not assigned(aclass) or
                          if (not assigned(aclass) or
-                             (search_class_member(aclass,pattern)=nil)) and
+                             (search_struct_member(aclass,pattern)=nil)) and
                             searchsym(pattern,sym,srsymtable) and
                             searchsym(pattern,sym,srsymtable) and
                             (sym.typ = constsym) then
                             (sym.typ = constsym) then
                            begin
                            begin
@@ -678,14 +678,14 @@ implementation
                 begin
                 begin
                   Message(parser_e_property_cant_have_a_default_value);
                   Message(parser_e_property_cant_have_a_default_value);
                   { Error recovery }
                   { Error recovery }
-                  pt:=comp_expr(true);
+                  pt:=comp_expr(true,false);
                   pt.free;
                   pt.free;
                 end
                 end
               else
               else
                 begin
                 begin
                   { Get the result of the default, the firstpass is
                   { Get the result of the default, the firstpass is
                     needed to support values like -1 }
                     needed to support values like -1 }
-                  pt:=comp_expr(true);
+                  pt:=comp_expr(true,false);
                   if (p.propdef.typ=setdef) and
                   if (p.propdef.typ=setdef) and
                      (pt.nodetype=arrayconstructorn) then
                      (pt.nodetype=arrayconstructorn) then
                     begin
                     begin
@@ -1428,7 +1428,8 @@ implementation
              { Don't search in the recordsymtable for types (can be nested!) }
              { Don't search in the recordsymtable for types (can be nested!) }
              recstlist.count:=0;
              recstlist.count:=0;
              if ([df_generic,df_specialization]*tdef(recst.defowner).defoptions=[]) and
              if ([df_generic,df_specialization]*tdef(recst.defowner).defoptions=[]) and
-                 not is_class_or_object(tdef(recst.defowner)) then
+                 not is_class_or_object(tdef(recst.defowner)) and
+                 not is_record(tdef(recst.defowner)) then
                begin
                begin
                  recstlist.add(recst);
                  recstlist.add(recst);
                  symtablestack.pop(recst);
                  symtablestack.pop(recst);
@@ -1619,11 +1620,11 @@ implementation
               symtablestack.push(UnionSymtable);
               symtablestack.push(UnionSymtable);
               repeat
               repeat
                 repeat
                 repeat
-                  pt:=comp_expr(true);
+                  pt:=comp_expr(true,false);
                   if not(pt.nodetype=ordconstn) then
                   if not(pt.nodetype=ordconstn) then
                     Message(parser_e_illegal_expression);
                     Message(parser_e_illegal_expression);
                   if try_to_consume(_POINTPOINT) then
                   if try_to_consume(_POINTPOINT) then
-                    pt:=crangenode.create(pt,comp_expr(true));
+                    pt:=crangenode.create(pt,comp_expr(true,false));
                   pt.free;
                   pt.free;
                   if token=_COMMA then
                   if token=_COMMA then
                     consume(_COMMA)
                     consume(_COMMA)

+ 2 - 2
compiler/pexports.pas

@@ -136,7 +136,7 @@ implementation
                      end;
                      end;
                     if try_to_consume(_INDEX) then
                     if try_to_consume(_INDEX) then
                      begin
                      begin
-                       pt:=comp_expr(true);
+                       pt:=comp_expr(true,false);
                        if pt.nodetype=ordconstn then
                        if pt.nodetype=ordconstn then
                         if (Tordconstnode(pt).value<int64(low(index))) or
                         if (Tordconstnode(pt).value<int64(low(index))) or
                            (Tordconstnode(pt).value>int64(high(index))) then
                            (Tordconstnode(pt).value>int64(high(index))) then
@@ -160,7 +160,7 @@ implementation
                      end;
                      end;
                     if try_to_consume(_NAME) then
                     if try_to_consume(_NAME) then
                      begin
                      begin
-                       pt:=comp_expr(true);
+                       pt:=comp_expr(true,false);
                        if pt.nodetype=stringconstn then
                        if pt.nodetype=stringconstn then
                          hpname:=strpas(tstringconstnode(pt).value_str)
                          hpname:=strpas(tstringconstnode(pt).value_str)
                        else
                        else

+ 119 - 119
compiler/pexpr.pas

@@ -31,13 +31,13 @@ interface
       tokens,globtype,globals,constexp;
       tokens,globtype,globals,constexp;
 
 
     { reads a whole expression }
     { reads a whole expression }
-    function expr(dotypecheck : boolean) : tnode;
+    function expr(dotypecheck:boolean) : tnode;
 
 
     { reads an expression without assignements and .. }
     { reads an expression without assignements and .. }
-    function comp_expr(accept_equal : boolean):tnode;
+    function comp_expr(accept_equal,typeonly:boolean):tnode;
 
 
     { reads a single factor }
     { reads a single factor }
-    function factor(getaddr : boolean) : tnode;
+    function factor(getaddr,typeonly:boolean) : tnode;
 
 
     procedure string_dec(var def: tdef; allowtypedef: boolean);
     procedure string_dec(var def: tdef; allowtypedef: boolean);
 
 
@@ -79,7 +79,7 @@ implementation
     const
     const
       highest_precedence = oppower;
       highest_precedence = oppower;
 
 
-    function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):tnode;forward;
+    function sub_expr(pred_level:Toperator_precedence;accept_equal,typeonly:boolean):tnode;forward;
 
 
     const
     const
        { true, if the inherited call is anonymous }
        { true, if the inherited call is anonymous }
@@ -101,7 +101,7 @@ implementation
               if not(allowtypedef) then
               if not(allowtypedef) then
                 Message(parser_e_no_local_para_def);
                 Message(parser_e_no_local_para_def);
               consume(_LECKKLAMMER);
               consume(_LECKKLAMMER);
-              p:=comp_expr(true);
+              p:=comp_expr(true,false);
               if not is_constintnode(p) then
               if not is_constintnode(p) then
                 begin
                 begin
                   Message(parser_e_illegal_expression);
                   Message(parser_e_illegal_expression);
@@ -172,12 +172,12 @@ implementation
                else
                else
                  begin
                  begin
                    named_args_allowed:=true;
                    named_args_allowed:=true;
-                   p1:=comp_expr(true);
+                   p1:=comp_expr(true,false);
                    named_args_allowed:=false;
                    named_args_allowed:=false;
                    if found_arg_name then
                    if found_arg_name then
                      begin
                      begin
                        argname:=p1;
                        argname:=p1;
-                       p1:=comp_expr(true);
+                       p1:=comp_expr(true,false);
                        p2:=ccallparanode.create(p1,p2);
                        p2:=ccallparanode.create(p1,p2);
                        tcallparanode(p2).parametername:=argname;
                        tcallparanode(p2).parametername:=argname;
                      end
                      end
@@ -188,19 +188,19 @@ implementation
              end
              end
            else
            else
              begin
              begin
-               p1:=comp_expr(true);
+               p1:=comp_expr(true,false);
                p2:=ccallparanode.create(p1,p2);
                p2:=ccallparanode.create(p1,p2);
              end;
              end;
            { it's for the str(l:5,s); }
            { it's for the str(l:5,s); }
            if __colon and (token=_COLON) then
            if __colon and (token=_COLON) then
              begin
              begin
                consume(_COLON);
                consume(_COLON);
-               p1:=comp_expr(true);
+               p1:=comp_expr(true,false);
                p2:=ccallparanode.create(p1,p2);
                p2:=ccallparanode.create(p1,p2);
                include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
                include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
                if try_to_consume(_COLON) then
                if try_to_consume(_COLON) then
                  begin
                  begin
-                   p1:=comp_expr(true);
+                   p1:=comp_expr(true,false);
                    p2:=ccallparanode.create(p1,p2);
                    p2:=ccallparanode.create(p1,p2);
                    include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
                    include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
                  end
                  end
@@ -282,7 +282,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               p1:=geninlinenode(in_ord_x,false,p1);
               p1:=geninlinenode(in_ord_x,false,p1);
               statement_syssym := p1;
               statement_syssym := p1;
@@ -296,7 +296,7 @@ implementation
                     begin
                     begin
                       if not(try_to_consume(_RKLAMMER)) then
                       if not(try_to_consume(_RKLAMMER)) then
                         begin
                         begin
-                          p1:=comp_expr(true);
+                          p1:=comp_expr(true,false);
                           consume(_RKLAMMER);
                           consume(_RKLAMMER);
                           if (not assigned(current_procinfo) or
                           if (not assigned(current_procinfo) or
                               is_void(current_procinfo.procdef.returndef)) then
                               is_void(current_procinfo.procdef.returndef)) then
@@ -360,7 +360,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               if p1.nodetype=typen then
               if p1.nodetype=typen then
                 ttypenode(p1).allowed:=true;
                 ttypenode(p1).allowed:=true;
@@ -386,7 +386,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               if (p1.nodetype<>typen) and
               if (p1.nodetype<>typen) and
                  (
                  (
@@ -431,7 +431,7 @@ implementation
                 begin
                 begin
                   consume(_LKLAMMER);
                   consume(_LKLAMMER);
                   in_args:=true;
                   in_args:=true;
-                  p1:=comp_expr(true);
+                  p1:=comp_expr(true,false);
                   { When reading a class type it is parsed as loadvmtaddrn,
                   { When reading a class type it is parsed as loadvmtaddrn,
                     typeinfo only needs the type so we remove the loadvmtaddrn }
                     typeinfo only needs the type so we remove the loadvmtaddrn }
                   if p1.nodetype=loadvmtaddrn then
                   if p1.nodetype=loadvmtaddrn then
@@ -465,7 +465,7 @@ implementation
               err:=false;
               err:=false;
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               p2:=ccallparanode.create(p1,nil);
               p2:=ccallparanode.create(p1,nil);
               p2:=geninlinenode(in_unaligned_x,false,p2);
               p2:=geninlinenode(in_unaligned_x,false,p2);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
@@ -477,7 +477,7 @@ implementation
               err:=false;
               err:=false;
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               { When reading a class type it is parsed as loadvmtaddrn,
               { When reading a class type it is parsed as loadvmtaddrn,
                 typeinfo only needs the type so we remove the loadvmtaddrn }
                 typeinfo only needs the type so we remove the loadvmtaddrn }
               if p1.nodetype=loadvmtaddrn then
               if p1.nodetype=loadvmtaddrn then
@@ -533,7 +533,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               p1:=caddrnode.create(p1);
               p1:=caddrnode.create(p1);
               if cs_typed_addresses in current_settings.localswitches then
               if cs_typed_addresses in current_settings.localswitches then
                 include(p1.flags,nf_typedaddr);
                 include(p1.flags,nf_typedaddr);
@@ -545,7 +545,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               p1:=caddrnode.create(p1);
               p1:=caddrnode.create(p1);
               do_typecheckpass(p1);
               do_typecheckpass(p1);
               { Ofs() returns a cardinal/qword, not a pointer }
               { Ofs() returns a cardinal/qword, not a pointer }
@@ -558,7 +558,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               p1:=geninlinenode(in_seg_x,false,p1);
               p1:=geninlinenode(in_seg_x,false,p1);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               statement_syssym:=p1;
               statement_syssym:=p1;
@@ -569,7 +569,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               p2:=geninlinenode(l,false,p1);
               p2:=geninlinenode(l,false,p1);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               statement_syssym:=p2;
               statement_syssym:=p2;
@@ -580,7 +580,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               p2:=geninlinenode(l,false,p1);
               p2:=geninlinenode(l,false,p1);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               statement_syssym:=p2;
               statement_syssym:=p2;
@@ -591,9 +591,9 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               if try_to_consume(_COMMA) then
               if try_to_consume(_COMMA) then
-                p2:=ccallparanode.create(comp_expr(true),nil)
+                p2:=ccallparanode.create(comp_expr(true,false),nil)
               else
               else
                 p2:=nil;
                 p2:=nil;
               p2:=ccallparanode.create(p1,p2);
               p2:=ccallparanode.create(p1,p2);
@@ -608,9 +608,9 @@ implementation
                   message(parser_e_illegal_slice);
                   message(parser_e_illegal_slice);
                   consume(_LKLAMMER);
                   consume(_LKLAMMER);
                   in_args:=true;
                   in_args:=true;
-                  comp_expr(true).free;
+                  comp_expr(true,false).free;
                   if try_to_consume(_COMMA) then
                   if try_to_consume(_COMMA) then
-                    comp_expr(true).free;
+                    comp_expr(true,false).free;
                   statement_syssym:=cerrornode.create;
                   statement_syssym:=cerrornode.create;
                   consume(_RKLAMMER);
                   consume(_RKLAMMER);
                 end
                 end
@@ -618,10 +618,10 @@ implementation
                 begin
                 begin
                   consume(_LKLAMMER);
                   consume(_LKLAMMER);
                   in_args:=true;
                   in_args:=true;
-                  p1:=comp_expr(true);
+                  p1:=comp_expr(true,false);
                   Consume(_COMMA);
                   Consume(_COMMA);
                   if not(codegenerror) then
                   if not(codegenerror) then
-                    p2:=ccallparanode.create(comp_expr(true),nil)
+                    p2:=ccallparanode.create(comp_expr(true,false),nil)
                   else
                   else
                     p2:=cerrornode.create;
                     p2:=cerrornode.create;
                   p2:=ccallparanode.create(p1,p2);
                   p2:=ccallparanode.create(p1,p2);
@@ -653,7 +653,7 @@ implementation
                 type checking }
                 type checking }
               p2:=nil;
               p2:=nil;
               repeat
               repeat
-                p1:=comp_expr(true);
+                p1:=comp_expr(true,false);
                 if p2<>nil then
                 if p2<>nil then
                   p2:=caddnode.create(addn,p2,p1)
                   p2:=caddnode.create(addn,p2,p1)
                 else
                 else
@@ -699,7 +699,7 @@ implementation
                   consume(_LKLAMMER);
                   consume(_LKLAMMER);
                   in_args:=true;
                   in_args:=true;
                   { don't turn procsyms into calls (getaddr = true) }
                   { don't turn procsyms into calls (getaddr = true) }
-                  p1:=factor(true);
+                  p1:=factor(true,false);
                   p2:=geninlinenode(l,false,p1);
                   p2:=geninlinenode(l,false,p1);
                   consume(_RKLAMMER);
                   consume(_RKLAMMER);
                   statement_syssym:=p2;
                   statement_syssym:=p2;
@@ -714,7 +714,7 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               p2:=geninlinenode(l,false,p1);
               p2:=geninlinenode(l,false,p1);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               statement_syssym:=p2;
               statement_syssym:=p2;
@@ -748,11 +748,11 @@ implementation
             Begin
             Begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args := true;
               in_args := true;
-              p1:= ccallparanode.create(comp_expr(true), nil);
+              p1:= ccallparanode.create(comp_expr(true,false), nil);
               consume(_COMMA);
               consume(_COMMA);
-              p2 := ccallparanode.create(comp_expr(true),p1);
+              p2 := ccallparanode.create(comp_expr(true,false),p1);
               if try_to_consume(_COMMA) then
               if try_to_consume(_COMMA) then
-                p2 := ccallparanode.create(comp_expr(true),p2);
+                p2 := ccallparanode.create(comp_expr(true,false),p2);
               consume(_RKLAMMER);
               consume(_RKLAMMER);
               p2 := geninlinenode(l,false,p2);
               p2 := geninlinenode(l,false,p2);
               statement_syssym := p2;
               statement_syssym := p2;
@@ -763,9 +763,9 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               consume(_COMMA);
               consume(_COMMA);
-              p2:=comp_expr(true);
+              p2:=comp_expr(true,false);
               statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,nil)));
               statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,nil)));
               consume(_RKLAMMER);
               consume(_RKLAMMER);
             end;
             end;
@@ -775,11 +775,11 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               consume(_COMMA);
               consume(_COMMA);
-              p2:=comp_expr(true);
+              p2:=comp_expr(true,false);
               consume(_COMMA);
               consume(_COMMA);
-              paras:=comp_expr(true);
+              paras:=comp_expr(true,false);
               statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,ccallparanode.create(paras,nil))));
               statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,ccallparanode.create(paras,nil))));
               consume(_RKLAMMER);
               consume(_RKLAMMER);
             end;
             end;
@@ -788,9 +788,9 @@ implementation
             begin
             begin
               consume(_LKLAMMER);
               consume(_LKLAMMER);
               in_args:=true;
               in_args:=true;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               if try_to_consume(_COMMA) then
               if try_to_consume(_COMMA) then
-                 p2:=comp_expr(true)
+                 p2:=comp_expr(true,false)
               else
               else
                begin
                begin
                  { then insert an empty string }
                  { then insert an empty string }
@@ -812,7 +812,7 @@ implementation
                    however, as a stack frame may not exist, it does more harm than
                    however, as a stack frame may not exist, it does more harm than
                    good, so ignore it.}
                    good, so ignore it.}
                   in_args:=true;
                   in_args:=true;
-                  p1:=comp_expr(true);
+                  p1:=comp_expr(true,false);
                   p1.destroy;
                   p1.destroy;
                   consume(_RKLAMMER);
                   consume(_RKLAMMER);
                 end;
                 end;
@@ -838,11 +838,12 @@ implementation
                  if (st.defowner.typ=objectdef) then
                  if (st.defowner.typ=objectdef) then
                    p1:=tnode(twithsymtable(st).withrefnode).getcopy;
                    p1:=tnode(twithsymtable(st).withrefnode).getcopy;
                end;
                end;
-             ObjectSymtable :
+             ObjectSymtable,
+             recordsymtable:
                begin
                begin
                  { We are calling from the static class method which has no self node }
                  { We are calling from the static class method which has no self node }
                  if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                  if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
-                   p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef._class))
+                   p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef.struct))
                  else
                  else
                    p1:=load_self_node;
                    p1:=load_self_node;
                  { We are calling a member }
                  { We are calling a member }
@@ -1068,7 +1069,7 @@ implementation
                          { read the expression }
                          { read the expression }
                          if propsym.propdef.typ=procvardef then
                          if propsym.propdef.typ=procvardef then
                            getprocvardef:=tprocvardef(propsym.propdef);
                            getprocvardef:=tprocvardef(propsym.propdef);
-                         p2:=comp_expr(true);
+                         p2:=comp_expr(true,false);
                          if assigned(getprocvardef) then
                          if assigned(getprocvardef) then
                            handle_procvar(getprocvardef,p2);
                            handle_procvar(getprocvardef,p2);
                          tcallnode(p1).left:=ccallparanode.create(p2,tcallnode(p1).left);
                          tcallnode(p1).left:=ccallparanode.create(p2,tcallnode(p1).left);
@@ -1095,7 +1096,7 @@ implementation
                          include(p1.flags,nf_isproperty);
                          include(p1.flags,nf_isproperty);
                          consume(_ASSIGNMENT);
                          consume(_ASSIGNMENT);
                          { read the expression }
                          { read the expression }
-                         p2:=comp_expr(true);
+                         p2:=comp_expr(true,false);
                          p1:=cassignmentnode.create(p1,p2);
                          p1:=cassignmentnode.create(p1,p2);
                       end
                       end
                     else
                     else
@@ -1109,7 +1110,7 @@ implementation
               if (ppo_dispid_write in propsym.propoptions) then
               if (ppo_dispid_write in propsym.propoptions) then
                 begin
                 begin
                   consume(_ASSIGNMENT);
                   consume(_ASSIGNMENT);
-                  p2:=comp_expr(true);
+                  p2:=comp_expr(true,false);
                   { concat value parameter too }
                   { concat value parameter too }
                   p2:=ccallparanode.create(p2,nil);
                   p2:=ccallparanode.create(p2,nil);
                   { passing p3 here is only for information purposes }
                   { passing p3 here is only for information purposes }
@@ -1255,7 +1256,7 @@ implementation
                               (
                               (
                                 is_self_node(p1) or
                                 is_self_node(p1) or
                                 (assigned(current_procinfo) and (current_procinfo.procdef.no_self_node) and
                                 (assigned(current_procinfo) and (current_procinfo.procdef.no_self_node) and
-                                 (current_procinfo.procdef._class = structh))) then
+                                (current_procinfo.procdef.struct=structh))) then
                               Message(parser_e_only_class_members)
                               Message(parser_e_only_class_members)
                             else
                             else
                               Message(parser_e_only_class_members_via_class_ref);
                               Message(parser_e_only_class_members_via_class_ref);
@@ -1273,7 +1274,7 @@ implementation
                      p1.free;
                      p1.free;
                      if try_to_consume(_LKLAMMER) then
                      if try_to_consume(_LKLAMMER) then
                       begin
                       begin
-                        p1:=comp_expr(true);
+                        p1:=comp_expr(true,false);
                         consume(_RKLAMMER);
                         consume(_RKLAMMER);
                         p1:=ctypeconvnode.create_explicit(p1,ttypesym(sym).typedef);
                         p1:=ctypeconvnode.create_explicit(p1,ttypesym(sym).typedef);
                       end
                       end
@@ -1317,7 +1318,8 @@ implementation
         memberparentdef:=nil;
         memberparentdef:=nil;
 
 
         case st.symtabletype of
         case st.symtabletype of
-          ObjectSymtable:
+          ObjectSymtable,
+          recordsymtable:
             begin
             begin
               memberparentdef:=tdef(st.defowner);
               memberparentdef:=tdef(st.defowner);
               exit;
               exit;
@@ -1344,7 +1346,7 @@ implementation
 
 
   {$maxfpuregisters 0}
   {$maxfpuregisters 0}
 
 
-    function factor(getaddr : boolean) : tnode;
+    function factor(getaddr,typeonly:boolean) : tnode;
 
 
          {---------------------------------------------
          {---------------------------------------------
                          Factor_read_id
                          Factor_read_id
@@ -1373,7 +1375,10 @@ implementation
              end
              end
            else
            else
              begin
              begin
-               searchsym(pattern,srsym,srsymtable);
+               if typeonly then
+                 searchsym_type(pattern,srsym,srsymtable)
+               else
+                 searchsym(pattern,srsym,srsymtable);
 
 
                { handle unit specification like System.Writeln }
                { handle unit specification like System.Writeln }
                unit_found:=try_consume_unitsym(srsym,srsymtable,t);
                unit_found:=try_consume_unitsym(srsym,srsymtable,t);
@@ -1462,16 +1467,16 @@ implementation
                         { objectsymtable, it means it's part of self
                         { objectsymtable, it means it's part of self
                           if only method from which it was called is
                           if only method from which it was called is
                           not class static                          }
                           not class static                          }
-                        if (srsymtable.symtabletype=ObjectSymtable) then
+                        if (srsymtable.symtabletype in [ObjectSymtable,recordsymtable]) then
                           if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                           if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
-                            p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef._class))
+                            p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef.struct))
                           else
                           else
                             p1:=load_self_node;
                             p1:=load_self_node;
                         { now, if the field itself is part of an objectsymtab }
                         { now, if the field itself is part of an objectsymtab }
                         { (it can be even if it was found in a withsymtable,  }
                         { (it can be even if it was found in a withsymtable,  }
                         {  e.g., "with classinstance do field := 5"), then    }
                         {  e.g., "with classinstance do field := 5"), then    }
                         { let do_member_read handle it                        }
                         { let do_member_read handle it                        }
-                        if (srsym.owner.symtabletype=ObjectSymtable) then
+                        if (srsym.owner.symtabletype in [ObjectSymtable,recordsymtable]) then
                           do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[])
                           do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[])
                         else
                         else
                           { otherwise it's a regular record subscript }
                           { otherwise it's a regular record subscript }
@@ -1502,20 +1507,20 @@ implementation
                          current_module.flags:=current_module.flags or uf_uses_variants;
                          current_module.flags:=current_module.flags or uf_uses_variants;
                        if try_to_consume(_LKLAMMER) then
                        if try_to_consume(_LKLAMMER) then
                         begin
                         begin
-                          p1:=comp_expr(true);
+                          p1:=comp_expr(true,false);
                           consume(_RKLAMMER);
                           consume(_RKLAMMER);
                           p1:=ctypeconvnode.create_explicit(p1,hdef);
                           p1:=ctypeconvnode.create_explicit(p1,hdef);
                         end
                         end
                        else { not LKLAMMER }
                        else { not LKLAMMER }
                         if (token=_POINT) and
                         if (token=_POINT) and
-                           is_object(hdef) then
+                           (is_object(hdef) or is_record(hdef)) then
                          begin
                          begin
                            consume(_POINT);
                            consume(_POINT);
                            { handles calling methods declared in parent objects
                            { handles calling methods declared in parent objects
                              using "parentobject.methodname()" }
                              using "parentobject.methodname()" }
-                           if assigned(current_objectdef) and
+                           if assigned(current_structdef) and
                               not(getaddr) and
                               not(getaddr) and
-                              current_objectdef.is_related(tobjectdef(hdef)) then
+                              current_structdef.is_related(hdef) then
                              begin
                              begin
                                p1:=ctypenode.create(hdef);
                                p1:=ctypenode.create(hdef);
                                { search also in inherited methods }
                                { search also in inherited methods }
@@ -1533,18 +1538,12 @@ implementation
                               p1:=ctypenode.create(hdef);
                               p1:=ctypenode.create(hdef);
                               { TP allows also @TMenu.Load if Load is only }
                               { TP allows also @TMenu.Load if Load is only }
                               { defined in an anchestor class              }
                               { defined in an anchestor class              }
-                              srsym:=search_class_member(tobjectdef(hdef),pattern);
+                              srsym:=search_struct_member(tabstractrecorddef(hdef),pattern);
                               if assigned(srsym) then
                               if assigned(srsym) then
                                 begin
                                 begin
                                   check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
                                   check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
-                                  if not(getaddr) and
-                                     not((sp_static in srsym.symoptions) or (srsym.typ in [constsym,staticvarsym])) then
-                                    Message(sym_e_only_static_in_static)
-                                  else
-                                    begin
-                                      consume(_ID);
-                                      do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[]);
-                                    end;
+                                  consume(_ID);
+                                  do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[]);
                                 end
                                 end
                               else
                               else
                                 Message1(sym_e_id_no_member,orgpattern);
                                 Message1(sym_e_id_no_member,orgpattern);
@@ -1564,7 +1563,7 @@ implementation
                                 p1:=ctypenode.create(hdef);
                                 p1:=ctypenode.create(hdef);
                                 { TP allows also @TMenu.Load if Load is only }
                                 { TP allows also @TMenu.Load if Load is only }
                                 { defined in an anchestor class              }
                                 { defined in an anchestor class              }
-                                srsym:=search_class_member(tobjectdef(hdef),pattern);
+                                srsym:=search_struct_member(tobjectdef(hdef),pattern);
                                 if assigned(srsym) then
                                 if assigned(srsym) then
                                  begin
                                  begin
                                    check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
                                    check_hints(srsym,srsym.symoptions,srsym.deprecatedmsg);
@@ -1618,7 +1617,7 @@ implementation
                       begin
                       begin
                         { not srsymtable.symtabletype since that can be }
                         { not srsymtable.symtabletype since that can be }
                         { withsymtable as well                          }
                         { withsymtable as well                          }
-                        if (srsym.owner.symtabletype=ObjectSymtable) then
+                        if (srsym.owner.symtabletype in [ObjectSymtable,recordsymtable]) then
                           do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[])
                           do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[])
                         else
                         else
                           { no procsyms in records (yet) }
                           { no procsyms in records (yet) }
@@ -1643,7 +1642,7 @@ implementation
                     { property of a class/object? }
                     { property of a class/object? }
                     if is_member_read(srsym,srsymtable,p1,hdef) then
                     if is_member_read(srsym,srsymtable,p1,hdef) then
                       begin
                       begin
-                        if (srsymtable.symtabletype=ObjectSymtable) then
+                        if (srsymtable.symtabletype in [ObjectSymtable,recordsymtable]) then
                            if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                            if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                           { no self node in static class methods }
                           { no self node in static class methods }
                             p1:=cloadvmtaddrnode.create(ctypenode.create(hdef))
                             p1:=cloadvmtaddrnode.create(ctypenode.create(hdef))
@@ -1651,7 +1650,7 @@ implementation
                             p1:=load_self_node;
                             p1:=load_self_node;
                         { not srsymtable.symtabletype since that can be }
                         { not srsymtable.symtabletype since that can be }
                         { withsymtable as well                          }
                         { withsymtable as well                          }
-                        if (srsym.owner.symtabletype=ObjectSymtable) then
+                        if (srsym.owner.symtabletype in [ObjectSymtable,recordsymtable]) then
                           do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[])
                           do_member_read(tobjectdef(hdef),getaddr,srsym,p1,again,[])
                         else
                         else
                           { no propertysyms in records (yet) }
                           { no propertysyms in records (yet) }
@@ -1733,10 +1732,10 @@ implementation
               { nested array constructors are not allowed, see also tests/webtbs/tw17213.pp }
               { nested array constructors are not allowed, see also tests/webtbs/tw17213.pp }
               old_allow_array_constructor:=allow_array_constructor;
               old_allow_array_constructor:=allow_array_constructor;
               allow_array_constructor:=false;
               allow_array_constructor:=false;
-              p1:=comp_expr(true);
+              p1:=comp_expr(true,false);
               if try_to_consume(_POINTPOINT) then
               if try_to_consume(_POINTPOINT) then
                 begin
                 begin
-                  p2:=comp_expr(true);
+                  p2:=comp_expr(true,false);
                   p1:=carrayconstructorrangenode.create(p1,p2);
                   p1:=carrayconstructorrangenode.create(p1,p2);
                 end;
                 end;
                { insert at the end of the tree, to get the correct order }
                { insert at the end of the tree, to get the correct order }
@@ -1774,14 +1773,14 @@ implementation
                 else if try_to_consume(_LECKKLAMMER) then
                 else if try_to_consume(_LECKKLAMMER) then
                   begin
                   begin
                     repeat
                     repeat
-                      comp_expr(true);
+                      comp_expr(true,false);
                     until not try_to_consume(_COMMA);
                     until not try_to_consume(_COMMA);
                     consume(_RECKKLAMMER);
                     consume(_RECKKLAMMER);
                   end
                   end
                 else if try_to_consume(_LKLAMMER) then
                 else if try_to_consume(_LKLAMMER) then
                   begin
                   begin
                     repeat
                     repeat
-                      comp_expr(true);
+                      comp_expr(true,false);
                     until not try_to_consume(_COMMA);
                     until not try_to_consume(_COMMA);
                     consume(_RKLAMMER);
                     consume(_RKLAMMER);
                   end
                   end
@@ -1812,7 +1811,7 @@ implementation
 
 
             countindices:=0;
             countindices:=0;
             repeat
             repeat
-              p4:=comp_expr(true);
+              p4:=comp_expr(true,false);
 
 
               addstatement(newstatement,cassignmentnode.create(
               addstatement(newstatement,cassignmentnode.create(
                 ctemprefnode.create_offset(temp,countindices*s32inttype.size),p4));
                 ctemprefnode.create_offset(temp,countindices*s32inttype.size),p4));
@@ -1828,7 +1827,7 @@ implementation
             if token=_ASSIGNMENT then
             if token=_ASSIGNMENT then
               begin
               begin
                 consume(_ASSIGNMENT);
                 consume(_ASSIGNMENT);
-                p4:=comp_expr(true);
+                p4:=comp_expr(true,false);
 
 
                 { create call to fpc_vararray_put }
                 { create call to fpc_vararray_put }
                 paras:=ccallparanode.create(cordconstnode.create
                 paras:=ccallparanode.create(cordconstnode.create
@@ -1958,10 +1957,10 @@ implementation
                                  if (tpointerdef(p1.resultdef).pointeddef.typ=arraydef) and
                                  if (tpointerdef(p1.resultdef).pointeddef.typ=arraydef) and
                                     (m_autoderef in current_settings.modeswitches) then
                                     (m_autoderef in current_settings.modeswitches) then
                                    p1:=cderefnode.create(p1);
                                    p1:=cderefnode.create(p1);
-                                 p2:=comp_expr(true);
+                                 p2:=comp_expr(true,false);
                                  { Support Pbytevar[0..9] which returns array [0..9].}
                                  { Support Pbytevar[0..9] which returns array [0..9].}
                                  if try_to_consume(_POINTPOINT) then
                                  if try_to_consume(_POINTPOINT) then
-                                   p2:=crangenode.create(p2,comp_expr(true));
+                                   p2:=crangenode.create(p2,comp_expr(true,false));
                                  p1:=cvecnode.create(p1,p2);
                                  p1:=cvecnode.create(p1,p2);
                               end;
                               end;
                             variantdef:
                             variantdef:
@@ -1972,15 +1971,15 @@ implementation
                               end;
                               end;
                             stringdef :
                             stringdef :
                               begin
                               begin
-                                p2:=comp_expr(true);
+                                p2:=comp_expr(true,false);
                                 { Support string[0..9] which returns array [0..9] of char.}
                                 { Support string[0..9] which returns array [0..9] of char.}
                                 if try_to_consume(_POINTPOINT) then
                                 if try_to_consume(_POINTPOINT) then
-                                  p2:=crangenode.create(p2,comp_expr(true));
+                                  p2:=crangenode.create(p2,comp_expr(true,false));
                                 p1:=cvecnode.create(p1,p2);
                                 p1:=cvecnode.create(p1,p2);
                               end;
                               end;
                             arraydef:
                             arraydef:
                               begin
                               begin
-                                p2:=comp_expr(true);
+                                p2:=comp_expr(true,false);
                                 { support SEG:OFS for go32v2 Mem[] }
                                 { support SEG:OFS for go32v2 Mem[] }
                                 if (target_info.system in [system_i386_go32v2,system_i386_watcom]) and
                                 if (target_info.system in [system_i386_go32v2,system_i386_watcom]) and
                                    (p1.nodetype=loadn) and
                                    (p1.nodetype=loadn) and
@@ -1994,11 +1993,11 @@ implementation
                                     if try_to_consume(_COLON) then
                                     if try_to_consume(_COLON) then
                                      begin
                                      begin
                                        p3:=caddnode.create(muln,cordconstnode.create($10,s32inttype,false),p2);
                                        p3:=caddnode.create(muln,cordconstnode.create($10,s32inttype,false),p2);
-                                       p2:=comp_expr(true);
+                                       p2:=comp_expr(true,false);
                                        p2:=caddnode.create(addn,p2,p3);
                                        p2:=caddnode.create(addn,p2,p3);
                                        if try_to_consume(_POINTPOINT) then
                                        if try_to_consume(_POINTPOINT) then
                                          { Support mem[$a000:$0000..$07ff] which returns array [0..$7ff] of memtype.}
                                          { Support mem[$a000:$0000..$07ff] which returns array [0..$7ff] of memtype.}
-                                         p2:=crangenode.create(p2,caddnode.create(addn,comp_expr(true),p3.getcopy));
+                                         p2:=crangenode.create(p2,caddnode.create(addn,comp_expr(true,false),p3.getcopy));
                                        p1:=cvecnode.create(p1,p2);
                                        p1:=cvecnode.create(p1,p2);
                                        include(tvecnode(p1).flags,nf_memseg);
                                        include(tvecnode(p1).flags,nf_memseg);
                                        include(tvecnode(p1).flags,nf_memindex);
                                        include(tvecnode(p1).flags,nf_memindex);
@@ -2007,7 +2006,7 @@ implementation
                                      begin
                                      begin
                                        if try_to_consume(_POINTPOINT) then
                                        if try_to_consume(_POINTPOINT) then
                                          { Support mem[$80000000..$80000002] which returns array [0..2] of memtype.}
                                          { Support mem[$80000000..$80000002] which returns array [0..2] of memtype.}
-                                         p2:=crangenode.create(p2,comp_expr(true));
+                                         p2:=crangenode.create(p2,comp_expr(true,false));
                                        p1:=cvecnode.create(p1,p2);
                                        p1:=cvecnode.create(p1,p2);
                                        include(tvecnode(p1).flags,nf_memindex);
                                        include(tvecnode(p1).flags,nf_memindex);
                                      end;
                                      end;
@@ -2016,7 +2015,7 @@ implementation
                                   begin
                                   begin
                                     if try_to_consume(_POINTPOINT) then
                                     if try_to_consume(_POINTPOINT) then
                                       { Support arrayvar[0..9] which returns array [0..9] of arraytype.}
                                       { Support arrayvar[0..9] which returns array [0..9] of arraytype.}
-                                      p2:=crangenode.create(p2,comp_expr(true));
+                                      p2:=crangenode.create(p2,comp_expr(true,false));
                                     p1:=cvecnode.create(p1,p2);
                                     p1:=cvecnode.create(p1,p2);
                                   end;
                                   end;
                               end;
                               end;
@@ -2026,7 +2025,7 @@ implementation
                                   Message(parser_e_invalid_qualifier);
                                   Message(parser_e_invalid_qualifier);
                                 p1.destroy;
                                 p1.destroy;
                                 p1:=cerrornode.create;
                                 p1:=cerrornode.create;
-                                comp_expr(true);
+                                comp_expr(true,false);
                                 again:=false;
                                 again:=false;
                               end;
                               end;
                           end;
                           end;
@@ -2117,7 +2116,7 @@ implementation
                                  begin
                                  begin
                                    consume(_ASSIGNMENT);
                                    consume(_ASSIGNMENT);
                                    { read the expression }
                                    { read the expression }
-                                   p3:=comp_expr(true);
+                                   p3:=comp_expr(true,false);
                                    { concat value parameter too }
                                    { concat value parameter too }
                                    p2:=ccallparanode.create(p3,p2);
                                    p2:=ccallparanode.create(p3,p2);
                                    { passing p3 here is only for information purposes }
                                    { passing p3 here is only for information purposes }
@@ -2238,7 +2237,7 @@ implementation
                          begin
                          begin
                            if try_to_consume(_LKLAMMER) then
                            if try_to_consume(_LKLAMMER) then
                              begin
                              begin
-                               p1:=comp_expr(true);
+                               p1:=comp_expr(true,false);
                                consume(_RKLAMMER);
                                consume(_RKLAMMER);
                                p1:=ctypeconvnode.create_explicit(p1,p1.resultdef);
                                p1:=ctypeconvnode.create_explicit(p1,p1.resultdef);
                              end
                              end
@@ -2313,7 +2312,7 @@ implementation
            { Handle references to self }
            { Handle references to self }
            if (idtoken=_SELF) and
            if (idtoken=_SELF) and
               not(block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) and
               not(block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) and
-              assigned(current_objectdef) then
+              assigned(current_structdef) then
              begin
              begin
                p1:=load_self_node;
                p1:=load_self_node;
                consume(_ID);
                consume(_ID);
@@ -2341,7 +2340,7 @@ implementation
                 begin
                 begin
                   consume(_RETURN);
                   consume(_RETURN);
                   if not(token in [_SEMICOLON,_ELSE,_END]) then
                   if not(token in [_SEMICOLON,_ELSE,_END]) then
-                    p1 := cexitnode.create(comp_expr(true))
+                    p1 := cexitnode.create(comp_expr(true,false))
                   else
                   else
                     p1 := cexitnode.create(nil);
                     p1 := cexitnode.create(nil);
                 end;
                 end;
@@ -2350,7 +2349,8 @@ implementation
                  again:=true;
                  again:=true;
                  consume(_INHERITED);
                  consume(_INHERITED);
                  if assigned(current_procinfo) and
                  if assigned(current_procinfo) and
-                    assigned(current_objectdef) then
+                    assigned(current_structdef) and
+                    (current_structdef.typ=objectdef) then
                   begin
                   begin
                     hclassdef:=current_objectdef.childof;
                     hclassdef:=current_objectdef.childof;
                     { Objective-C categories *replace* methods in the class
                     { Objective-C categories *replace* methods in the class
@@ -2527,7 +2527,7 @@ implementation
                  { STRING can be also a type cast }
                  { STRING can be also a type cast }
                  if try_to_consume(_LKLAMMER) then
                  if try_to_consume(_LKLAMMER) then
                   begin
                   begin
-                    p1:=comp_expr(true);
+                    p1:=comp_expr(true,false);
                     consume(_RKLAMMER);
                     consume(_RKLAMMER);
                     p1:=ctypeconvnode.create_explicit(p1,hdef);
                     p1:=ctypeconvnode.create_explicit(p1,hdef);
                     { handle postfix operators here e.g. string(a)[10] }
                     { handle postfix operators here e.g. string(a)[10] }
@@ -2545,7 +2545,7 @@ implementation
                  { FILE can be also a type cast }
                  { FILE can be also a type cast }
                  if try_to_consume(_LKLAMMER) then
                  if try_to_consume(_LKLAMMER) then
                   begin
                   begin
-                    p1:=comp_expr(true);
+                    p1:=comp_expr(true,false);
                     consume(_RKLAMMER);
                     consume(_RKLAMMER);
                     p1:=ctypeconvnode.create_explicit(p1,hdef);
                     p1:=ctypeconvnode.create_explicit(p1,hdef);
                     { handle postfix operators here e.g. string(a)[10] }
                     { handle postfix operators here e.g. string(a)[10] }
@@ -2589,7 +2589,7 @@ implementation
                  { support both @<x> and @(<x>) }
                  { support both @<x> and @(<x>) }
                  if try_to_consume(_LKLAMMER) then
                  if try_to_consume(_LKLAMMER) then
                   begin
                   begin
-                    p1:=factor(true);
+                    p1:=factor(true,false);
                     if token in [_CARET,_POINT,_LECKKLAMMER] then
                     if token in [_CARET,_POINT,_LECKKLAMMER] then
                      begin
                      begin
                        again:=true;
                        again:=true;
@@ -2599,7 +2599,7 @@ implementation
                     consume(_RKLAMMER);
                     consume(_RKLAMMER);
                   end
                   end
                  else
                  else
-                  p1:=factor(true);
+                  p1:=factor(true,false);
                  if token in [_CARET,_POINT,_LECKKLAMMER] then
                  if token in [_CARET,_POINT,_LECKKLAMMER] then
                   begin
                   begin
                     again:=true;
                     again:=true;
@@ -2621,7 +2621,7 @@ implementation
              _LKLAMMER :
              _LKLAMMER :
                begin
                begin
                  consume(_LKLAMMER);
                  consume(_LKLAMMER);
-                 p1:=comp_expr(true);
+                 p1:=comp_expr(true,false);
                  consume(_RKLAMMER);
                  consume(_RKLAMMER);
                  { it's not a good solution     }
                  { it's not a good solution     }
                  { but (a+b)^ makes some problems  }
                  { but (a+b)^ makes some problems  }
@@ -2642,7 +2642,7 @@ implementation
              _PLUS :
              _PLUS :
                begin
                begin
                  consume(_PLUS);
                  consume(_PLUS);
-                 p1:=factor(false);
+                 p1:=factor(false,false);
                  { we must generate a new node to do 0+<p1> otherwise the + will
                  { we must generate a new node to do 0+<p1> otherwise the + will
                    not be checked }
                    not be checked }
                  p1:=caddnode.create(addn,genintconstnode(0),p1);
                  p1:=caddnode.create(addn,genintconstnode(0),p1);
@@ -2656,7 +2656,7 @@ implementation
                       { ugly hack, but necessary to be able to parse }
                       { ugly hack, but necessary to be able to parse }
                       { -9223372036854775808 as int64 (JM)           }
                       { -9223372036854775808 as int64 (JM)           }
                       pattern := '-'+pattern;
                       pattern := '-'+pattern;
-                      p1:=sub_expr(oppower,false);
+                      p1:=sub_expr(oppower,false,false);
                       {  -1 ** 4 should be - (1 ** 4) and not
                       {  -1 ** 4 should be - (1 ** 4) and not
                          (-1) ** 4
                          (-1) ** 4
                          This was the reason of tw0869.pp test failure PM }
                          This was the reason of tw0869.pp test failure PM }
@@ -2679,7 +2679,7 @@ implementation
                     end
                     end
                  else
                  else
                    begin
                    begin
-                     p1:=sub_expr(oppower,false);
+                     p1:=sub_expr(oppower,false,false);
                      p1:=cunaryminusnode.create(p1);
                      p1:=cunaryminusnode.create(p1);
                    end;
                    end;
                end;
                end;
@@ -2687,7 +2687,7 @@ implementation
              _OP_NOT :
              _OP_NOT :
                begin
                begin
                  consume(_OP_NOT);
                  consume(_OP_NOT);
-                 p1:=factor(false);
+                 p1:=factor(false,false);
                  p1:=cnotnode.create(p1);
                  p1:=cnotnode.create(p1);
                end;
                end;
 
 
@@ -2725,7 +2725,7 @@ implementation
                }
                }
                consume(_OBJCPROTOCOL);
                consume(_OBJCPROTOCOL);
                consume(_LKLAMMER);
                consume(_LKLAMMER);
-               p1:=factor(false);
+               p1:=factor(false,false);
                consume(_RKLAMMER);
                consume(_RKLAMMER);
                p1:=cinlinenode.create(in_objc_protocol_x,false,p1);
                p1:=cinlinenode.create(in_objc_protocol_x,false,p1);
              end;
              end;
@@ -2776,7 +2776,7 @@ implementation
            _OP_AS,_OP_IS,_OP_AND,_AMPERSAND,_OP_DIV,_OP_MOD,_OP_SHL,_OP_SHR],
            _OP_AS,_OP_IS,_OP_AND,_AMPERSAND,_OP_DIV,_OP_MOD,_OP_SHL,_OP_SHR],
           [_STARSTAR] );
           [_STARSTAR] );
 
 
-    function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):tnode;
+    function sub_expr(pred_level:Toperator_precedence;accept_equal,typeonly:boolean):tnode;
     {Reads a subexpression while the operators are of the current precedence
     {Reads a subexpression while the operators are of the current precedence
      level, or any higher level. Replaces the old term, simpl_expr and
      level, or any higher level. Replaces the old term, simpl_expr and
      simpl2_expr.}
      simpl2_expr.}
@@ -2786,9 +2786,9 @@ implementation
         filepos : tfileposinfo;
         filepos : tfileposinfo;
       begin
       begin
         if pred_level=highest_precedence then
         if pred_level=highest_precedence then
-          p1:=factor(false)
+          p1:=factor(false,typeonly)
         else
         else
-          p1:=sub_expr(succ(pred_level),true);
+          p1:=sub_expr(succ(pred_level),true,typeonly);
         repeat
         repeat
           if (token in operator_levels[pred_level]) and
           if (token in operator_levels[pred_level]) and
              ((token<>_EQUAL) or accept_equal) then
              ((token<>_EQUAL) or accept_equal) then
@@ -2797,9 +2797,9 @@ implementation
              filepos:=current_tokenpos;
              filepos:=current_tokenpos;
              consume(token);
              consume(token);
              if pred_level=highest_precedence then
              if pred_level=highest_precedence then
-               p2:=factor(false)
+               p2:=factor(false,false)
              else
              else
-               p2:=sub_expr(succ(pred_level),true);
+               p2:=sub_expr(succ(pred_level),true,typeonly);
              case oldt of
              case oldt of
                _PLUS :
                _PLUS :
                  p1:=caddnode.create(addn,p1,p2);
                  p1:=caddnode.create(addn,p1,p2);
@@ -2869,14 +2869,14 @@ implementation
       end;
       end;
 
 
 
 
-    function comp_expr(accept_equal : boolean):tnode;
+    function comp_expr(accept_equal,typeonly:boolean):tnode;
       var
       var
          oldafterassignment : boolean;
          oldafterassignment : boolean;
          p1 : tnode;
          p1 : tnode;
       begin
       begin
          oldafterassignment:=afterassignment;
          oldafterassignment:=afterassignment;
          afterassignment:=true;
          afterassignment:=true;
-         p1:=sub_expr(opcompare,accept_equal);
+         p1:=sub_expr(opcompare,accept_equal,typeonly);
          { get the resultdef for this expression }
          { get the resultdef for this expression }
          if not assigned(p1.resultdef) then
          if not assigned(p1.resultdef) then
           do_typecheckpass(p1);
           do_typecheckpass(p1);
@@ -2895,7 +2895,7 @@ implementation
 
 
       begin
       begin
          oldafterassignment:=afterassignment;
          oldafterassignment:=afterassignment;
-         p1:=sub_expr(opcompare,true);
+         p1:=sub_expr(opcompare,true,false);
          { get the resultdef for this expression }
          { get the resultdef for this expression }
          if not assigned(p1.resultdef) and
          if not assigned(p1.resultdef) and
             dotypecheck then
             dotypecheck then
@@ -2908,7 +2908,7 @@ implementation
            _POINTPOINT :
            _POINTPOINT :
              begin
              begin
                 consume(_POINTPOINT);
                 consume(_POINTPOINT);
-                p2:=sub_expr(opcompare,true);
+                p2:=sub_expr(opcompare,true,false);
                 p1:=crangenode.create(p1,p2);
                 p1:=crangenode.create(p1,p2);
              end;
              end;
            _ASSIGNMENT :
            _ASSIGNMENT :
@@ -2916,7 +2916,7 @@ implementation
                 consume(_ASSIGNMENT);
                 consume(_ASSIGNMENT);
                 if (p1.resultdef.typ=procvardef) then
                 if (p1.resultdef.typ=procvardef) then
                   getprocvardef:=tprocvardef(p1.resultdef);
                   getprocvardef:=tprocvardef(p1.resultdef);
-                p2:=sub_expr(opcompare,true);
+                p2:=sub_expr(opcompare,true,false);
                 if assigned(getprocvardef) then
                 if assigned(getprocvardef) then
                   handle_procvar(getprocvardef,p2);
                   handle_procvar(getprocvardef,p2);
                 getprocvardef:=nil;
                 getprocvardef:=nil;
@@ -2925,25 +2925,25 @@ implementation
            _PLUSASN :
            _PLUSASN :
              begin
              begin
                consume(_PLUSASN);
                consume(_PLUSASN);
-               p2:=sub_expr(opcompare,true);
+               p2:=sub_expr(opcompare,true,false);
                p1:=gen_c_style_operator(addn,p1,p2);
                p1:=gen_c_style_operator(addn,p1,p2);
             end;
             end;
           _MINUSASN :
           _MINUSASN :
             begin
             begin
                consume(_MINUSASN);
                consume(_MINUSASN);
-               p2:=sub_expr(opcompare,true);
+               p2:=sub_expr(opcompare,true,false);
                p1:=gen_c_style_operator(subn,p1,p2);
                p1:=gen_c_style_operator(subn,p1,p2);
             end;
             end;
           _STARASN :
           _STARASN :
             begin
             begin
                consume(_STARASN  );
                consume(_STARASN  );
-               p2:=sub_expr(opcompare,true);
+               p2:=sub_expr(opcompare,true,false);
                p1:=gen_c_style_operator(muln,p1,p2);
                p1:=gen_c_style_operator(muln,p1,p2);
             end;
             end;
           _SLASHASN :
           _SLASHASN :
             begin
             begin
                consume(_SLASHASN  );
                consume(_SLASHASN  );
-               p2:=sub_expr(opcompare,true);
+               p2:=sub_expr(opcompare,true,false);
                p1:=gen_c_style_operator(slashn,p1,p2);
                p1:=gen_c_style_operator(slashn,p1,p2);
             end;
             end;
           else
           else
@@ -2966,7 +2966,7 @@ implementation
       p:tnode;
       p:tnode;
     begin
     begin
       result:=0;
       result:=0;
-      p:=comp_expr(true);
+      p:=comp_expr(true,false);
       if not codegenerror then
       if not codegenerror then
        begin
        begin
          if (p.nodetype<>ordconstn) or
          if (p.nodetype<>ordconstn) or
@@ -2986,7 +2986,7 @@ implementation
       p:tnode;
       p:tnode;
     begin
     begin
       get_stringconst:='';
       get_stringconst:='';
-      p:=comp_expr(true);
+      p:=comp_expr(true,false);
       if p.nodetype<>stringconstn then
       if p.nodetype<>stringconstn then
         begin
         begin
           if (p.nodetype=ordconstn) and is_char(p.resultdef) then
           if (p.nodetype=ordconstn) and is_char(p.resultdef) then

+ 8 - 8
compiler/pinline.pas

@@ -76,7 +76,7 @@ implementation
         storepos : tfileposinfo;
         storepos : tfileposinfo;
       begin
       begin
         consume(_LKLAMMER);
         consume(_LKLAMMER);
-        p:=comp_expr(true);
+        p:=comp_expr(true,false);
         { calc return type }
         { calc return type }
         if is_new then
         if is_new then
           begin
           begin
@@ -98,12 +98,12 @@ implementation
               classh := classh.childof;
               classh := classh.childof;
             if is_new then
             if is_new then
               begin
               begin
-                sym:=search_class_member(classh,'CREATE');
+                sym:=search_struct_member(classh,'CREATE');
                 p2 := cloadvmtaddrnode.create(ctypenode.create(p.resultdef));
                 p2 := cloadvmtaddrnode.create(ctypenode.create(p.resultdef));
               end
               end
             else
             else
               begin
               begin
-                sym:=search_class_member(classh,'FREE');
+                sym:=search_struct_member(classh,'FREE');
                 p2 := p;
                 p2 := p;
              end;
              end;
 
 
@@ -161,7 +161,7 @@ implementation
               begin
               begin
                  Message1(type_e_pointer_type_expected,p.resultdef.typename);
                  Message1(type_e_pointer_type_expected,p.resultdef.typename);
                  p.free;
                  p.free;
-                 p:=factor(false);
+                 p:=factor(false,false);
                  p.free;
                  p.free;
                  consume(_RKLAMMER);
                  consume(_RKLAMMER);
                  new_dispose_statement:=cerrornode.create;
                  new_dispose_statement:=cerrornode.create;
@@ -172,7 +172,7 @@ implementation
               begin
               begin
                  Message(parser_e_pointer_to_class_expected);
                  Message(parser_e_pointer_to_class_expected);
                  p.free;
                  p.free;
-                 new_dispose_statement:=factor(false);
+                 new_dispose_statement:=factor(false,false);
                  consume_all_until(_RKLAMMER);
                  consume_all_until(_RKLAMMER);
                  consume(_RKLAMMER);
                  consume(_RKLAMMER);
                  exit;
                  exit;
@@ -182,7 +182,7 @@ implementation
             if is_class(classh) then
             if is_class(classh) then
               begin
               begin
                  Message(parser_e_no_new_or_dispose_for_classes);
                  Message(parser_e_no_new_or_dispose_for_classes);
-                 new_dispose_statement:=factor(false);
+                 new_dispose_statement:=factor(false,false);
                  consume_all_until(_RKLAMMER);
                  consume_all_until(_RKLAMMER);
                  consume(_RKLAMMER);
                  consume(_RKLAMMER);
                  exit;
                  exit;
@@ -190,7 +190,7 @@ implementation
             { search cons-/destructor, also in parent classes }
             { search cons-/destructor, also in parent classes }
             storepos:=current_tokenpos;
             storepos:=current_tokenpos;
             current_tokenpos:=destructorpos;
             current_tokenpos:=destructorpos;
-            sym:=search_class_member(classh,destructorname);
+            sym:=search_struct_member(classh,destructorname);
             current_tokenpos:=storepos;
             current_tokenpos:=storepos;
 
 
             { the second parameter of new/dispose must be a call }
             { the second parameter of new/dispose must be a call }
@@ -353,7 +353,7 @@ implementation
         again  : boolean; { dummy for do_proc_call }
         again  : boolean; { dummy for do_proc_call }
       begin
       begin
         consume(_LKLAMMER);
         consume(_LKLAMMER);
-        p1:=factor(false);
+        p1:=factor(false,false);
         if p1.nodetype<>typen then
         if p1.nodetype<>typen then
          begin
          begin
            Message(type_e_type_id_expected);
            Message(type_e_type_id_expected);

+ 14 - 15
compiler/pstatmnt.pas

@@ -71,7 +71,7 @@ implementation
          ex,if_a,else_a : tnode;
          ex,if_a,else_a : tnode;
       begin
       begin
          consume(_IF);
          consume(_IF);
-         ex:=comp_expr(true);
+         ex:=comp_expr(true,false);
          consume(_THEN);
          consume(_THEN);
          if token<>_ELSE then
          if token<>_ELSE then
            if_a:=statement
            if_a:=statement
@@ -125,7 +125,7 @@ implementation
          casenode : tcasenode;
          casenode : tcasenode;
       begin
       begin
          consume(_CASE);
          consume(_CASE);
-         caseexpr:=comp_expr(true);
+         caseexpr:=comp_expr(true,false);
          { determines result type }
          { determines result type }
          do_typecheckpass(caseexpr);
          do_typecheckpass(caseexpr);
          { variants must be accepted, but first they must be converted to integer }
          { variants must be accepted, but first they must be converted to integer }
@@ -300,7 +300,7 @@ implementation
          consume(_UNTIL);
          consume(_UNTIL);
 
 
          first:=cblocknode.create(first);
          first:=cblocknode.create(first);
-         p_e:=comp_expr(true);
+         p_e:=comp_expr(true,false);
          result:=cwhilerepeatnode.create(p_e,first,false,true);
          result:=cwhilerepeatnode.create(p_e,first,false,true);
       end;
       end;
 
 
@@ -312,7 +312,7 @@ implementation
 
 
       begin
       begin
          consume(_WHILE);
          consume(_WHILE);
-         p_e:=comp_expr(true);
+         p_e:=comp_expr(true,false);
          consume(_DO);
          consume(_DO);
          p_a:=statement;
          p_a:=statement;
          result:=cwhilerepeatnode.create(p_e,p_a,true,false);
          result:=cwhilerepeatnode.create(p_e,p_a,true,false);
@@ -424,7 +424,7 @@ implementation
              else
              else
                MessagePos(hloopvar.fileinfo,type_e_illegal_count_var);
                MessagePos(hloopvar.fileinfo,type_e_illegal_count_var);
 
 
-             hfrom:=comp_expr(true);
+             hfrom:=comp_expr(true,false);
 
 
              if try_to_consume(_DOWNTO) then
              if try_to_consume(_DOWNTO) then
                backward:=true
                backward:=true
@@ -434,7 +434,7 @@ implementation
                  backward:=false;
                  backward:=false;
                end;
                end;
 
 
-             hto:=comp_expr(true);
+             hto:=comp_expr(true,false);
              consume(_DO);
              consume(_DO);
 
 
              { Check if the constants fit in the range }
              { Check if the constants fit in the range }
@@ -471,7 +471,7 @@ implementation
             var
             var
               expr: tnode;
               expr: tnode;
             begin
             begin
-              expr:=comp_expr(true);
+              expr:=comp_expr(true,false);
 
 
               consume(_DO);
               consume(_DO);
 
 
@@ -490,7 +490,7 @@ implementation
          { parse loop header }
          { parse loop header }
          consume(_FOR);
          consume(_FOR);
 
 
-         hloopvar:=factor(false);
+         hloopvar:=factor(false,false);
          valid_for_loopvar(hloopvar,true);
          valid_for_loopvar(hloopvar,true);
 
 
          if try_to_consume(_ASSIGNMENT) then
          if try_to_consume(_ASSIGNMENT) then
@@ -533,7 +533,7 @@ implementation
 
 
 
 
       begin
       begin
-         p:=comp_expr(true);
+         p:=comp_expr(true,false);
          do_typecheckpass(p);
          do_typecheckpass(p);
 
 
          if (p.nodetype=vecn) and
          if (p.nodetype=vecn) and
@@ -725,12 +725,12 @@ implementation
          if not(token in endtokens) then
          if not(token in endtokens) then
            begin
            begin
               { object }
               { object }
-              pobj:=comp_expr(true);
+              pobj:=comp_expr(true,false);
               if try_to_consume(_AT) then
               if try_to_consume(_AT) then
                 begin
                 begin
-                   paddr:=comp_expr(true);
+                   paddr:=comp_expr(true,false);
                    if try_to_consume(_COMMA) then
                    if try_to_consume(_COMMA) then
-                     pframe:=comp_expr(true);
+                     pframe:=comp_expr(true,false);
                 end;
                 end;
            end
            end
          else
          else
@@ -1204,8 +1204,7 @@ implementation
                     { can be nil in case there was an error in the expression }
                     { can be nil in case there was an error in the expression }
                     assigned(tcallnode(p).procdefinition) and
                     assigned(tcallnode(p).procdefinition) and
                     not((tcallnode(p).procdefinition.proctypeoption=potype_constructor) and
                     not((tcallnode(p).procdefinition.proctypeoption=potype_constructor) and
-                        assigned(tprocdef(tcallnode(p).procdefinition)._class) and
-                        is_object(tprocdef(tcallnode(p).procdefinition)._class)) then
+                        is_object(tprocdef(tcallnode(p).procdefinition).struct)) then
                    Message(parser_e_illegal_expression);
                    Message(parser_e_illegal_expression);
                end;
                end;
              code:=p;
              code:=p;
@@ -1314,7 +1313,7 @@ implementation
              if (current_procinfo.procdef.localst.symtabletype=localsymtable) then
              if (current_procinfo.procdef.localst.symtabletype=localsymtable) then
                inc(locals,tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals);
                inc(locals,tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals);
              if (locals=0) and
              if (locals=0) and
-                (current_procinfo.procdef.owner.symtabletype<>ObjectSymtable) and
+                not (current_procinfo.procdef.owner.symtabletype in [ObjectSymtable,recordsymtable]) and
                 (not assigned(current_procinfo.procdef.funcretsym) or
                 (not assigned(current_procinfo.procdef.funcretsym) or
                  (tabstractvarsym(current_procinfo.procdef.funcretsym).refs<=1)) and
                  (tabstractvarsym(current_procinfo.procdef.funcretsym).refs<=1)) and
                 not(paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption)) then
                 not(paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption)) then

+ 42 - 42
compiler/psub.pas

@@ -290,15 +290,15 @@ implementation
       begin
       begin
         result:=internalstatements(newstatement);
         result:=internalstatements(newstatement);
 
 
-        if assigned(current_objectdef) then
+        if assigned(current_structdef) then
           begin
           begin
             { a constructor needs a help procedure }
             { a constructor needs a help procedure }
             if (current_procinfo.procdef.proctypeoption=potype_constructor) then
             if (current_procinfo.procdef.proctypeoption=potype_constructor) then
               begin
               begin
-                if is_class(current_objectdef) then
+                if is_class(current_structdef) then
                   begin
                   begin
                     include(current_procinfo.flags,pi_needs_implicit_finally);
                     include(current_procinfo.flags,pi_needs_implicit_finally);
-                    srsym:=search_class_member(current_objectdef,'NEWINSTANCE');
+                    srsym:=search_struct_member(current_objectdef,'NEWINSTANCE');
                     if assigned(srsym) and
                     if assigned(srsym) and
                        (srsym.typ=procsym) then
                        (srsym.typ=procsym) then
                       begin
                       begin
@@ -320,7 +320,7 @@ implementation
                       internalerror(200305108);
                       internalerror(200305108);
                   end
                   end
                 else
                 else
-                  if is_object(current_objectdef) then
+                  if is_object(current_structdef) then
                     begin
                     begin
                       { parameter 3 : vmt_offset }
                       { parameter 3 : vmt_offset }
                       { parameter 2 : address of pointer to vmt,
                       { parameter 2 : address of pointer to vmt,
@@ -359,9 +359,9 @@ implementation
 
 
             { maybe call BeforeDestruction for classes }
             { maybe call BeforeDestruction for classes }
             if (current_procinfo.procdef.proctypeoption=potype_destructor) and
             if (current_procinfo.procdef.proctypeoption=potype_destructor) and
-               is_class(current_objectdef) then
+               is_class(current_structdef) then
               begin
               begin
-                srsym:=search_class_member(current_objectdef,'BEFOREDESTRUCTION');
+                srsym:=search_struct_member(current_objectdef,'BEFOREDESTRUCTION');
                 if assigned(srsym) and
                 if assigned(srsym) and
                    (srsym.typ=procsym) then
                    (srsym.typ=procsym) then
                   begin
                   begin
@@ -393,7 +393,7 @@ implementation
       begin
       begin
         result:=internalstatements(newstatement);
         result:=internalstatements(newstatement);
 
 
-        if assigned(current_objectdef) then
+        if assigned(current_structdef) then
           begin
           begin
             { Don't test self and the vmt here. The reason is that  }
             { Don't test self and the vmt here. The reason is that  }
             { a constructor already checks whether these are valid  }
             { a constructor already checks whether these are valid  }
@@ -406,9 +406,9 @@ implementation
             { a destructor needs a help procedure }
             { a destructor needs a help procedure }
             if (current_procinfo.procdef.proctypeoption=potype_destructor) then
             if (current_procinfo.procdef.proctypeoption=potype_destructor) then
               begin
               begin
-                if is_class(current_objectdef) then
+                if is_class(current_structdef) then
                   begin
                   begin
-                    srsym:=search_class_member(current_objectdef,'FREEINSTANCE');
+                    srsym:=search_struct_member(current_objectdef,'FREEINSTANCE');
                     if assigned(srsym) and
                     if assigned(srsym) and
                        (srsym.typ=procsym) then
                        (srsym.typ=procsym) then
                       begin
                       begin
@@ -430,7 +430,7 @@ implementation
                       internalerror(200305108);
                       internalerror(200305108);
                   end
                   end
                 else
                 else
-                  if is_object(current_objectdef) then
+                  if is_object(current_structdef) then
                     begin
                     begin
                       { finalize object data }
                       { finalize object data }
                       if is_managed_type(current_objectdef) then
                       if is_managed_type(current_objectdef) then
@@ -471,7 +471,7 @@ implementation
 
 
         { a constructor needs call destructor (if available) when it
         { a constructor needs call destructor (if available) when it
           is not inherited }
           is not inherited }
-        if not assigned(current_objectdef) or
+        if not assigned(current_structdef) or
            (current_procinfo.procdef.proctypeoption<>potype_constructor) then
            (current_procinfo.procdef.proctypeoption<>potype_constructor) then
           begin
           begin
             { no constructor }
             { no constructor }
@@ -495,7 +495,7 @@ implementation
                 { if safecall is used for a class method we need to call }
                 { if safecall is used for a class method we need to call }
                 { SafecallException virtual method                       }
                 { SafecallException virtual method                       }
                 { In other case we return E_UNEXPECTED error value       }
                 { In other case we return E_UNEXPECTED error value       }
-                if is_class(current_procinfo.procdef._class) then
+                if is_class(current_procinfo.procdef.struct) then
                   begin
                   begin
                     { temp variable to store exception address }
                     { temp variable to store exception address }
                     exceptaddrnode:=ctempcreatenode.create(voidpointertype,voidpointertype.size,
                     exceptaddrnode:=ctempcreatenode.create(voidpointertype,voidpointertype.size,
@@ -513,7 +513,7 @@ implementation
                       cassignmentnode.create(
                       cassignmentnode.create(
                         ctemprefnode.create(exceptobjnode),
                         ctemprefnode.create(exceptobjnode),
                         ccallnode.createintern('fpc_popobjectstack', nil)));
                         ccallnode.createintern('fpc_popobjectstack', nil)));
-                    exceptsym:=search_class_member(current_procinfo.procdef._class,'SAFECALLEXCEPTION');
+                    exceptsym:=search_struct_member(tobjectdef(current_procinfo.procdef.struct),'SAFECALLEXCEPTION');
                     addstatement(newstatement,
                     addstatement(newstatement,
                       cassignmentnode.create(
                       cassignmentnode.create(
                         cloadnode.create(sym,sym.Owner),
                         cloadnode.create(sym,sym.Owner),
@@ -595,7 +595,7 @@ implementation
         newstatement: tstatementnode;
         newstatement: tstatementnode;
         pd: tprocdef;
         pd: tprocdef;
       begin
       begin
-        if assigned(current_objectdef) and
+        if assigned(current_structdef) and
            (current_procinfo.procdef.proctypeoption=potype_constructor) then
            (current_procinfo.procdef.proctypeoption=potype_constructor) then
           begin
           begin
             { Don't test self and the vmt here. See generate_bodyexit_block }
             { Don't test self and the vmt here. See generate_bodyexit_block }
@@ -604,9 +604,9 @@ implementation
             current_settings.localswitches:=oldlocalswitches-[cs_check_object,cs_check_range];
             current_settings.localswitches:=oldlocalswitches-[cs_check_object,cs_check_range];
 
 
             { call AfterConstruction for classes }
             { call AfterConstruction for classes }
-            if is_class(current_objectdef) then
+            if is_class(current_structdef) then
               begin
               begin
-                srsym:=search_class_member(current_objectdef,'AFTERCONSTRUCTION');
+                srsym:=search_struct_member(current_objectdef,'AFTERCONSTRUCTION');
                 if assigned(srsym) and
                 if assigned(srsym) and
                    (srsym.typ=procsym) then
                    (srsym.typ=procsym) then
                   begin
                   begin
@@ -806,7 +806,7 @@ implementation
         old_current_procinfo : tprocinfo;
         old_current_procinfo : tprocinfo;
         oldmaxfpuregisters : longint;
         oldmaxfpuregisters : longint;
         oldfilepos : tfileposinfo;
         oldfilepos : tfileposinfo;
-        old_current_objectdef : tobjectdef;
+        old_current_structdef : tabstractrecorddef;
         templist : TAsmList;
         templist : TAsmList;
         headertai : tai;
         headertai : tai;
         i : integer;
         i : integer;
@@ -833,12 +833,12 @@ implementation
 
 
         old_current_procinfo:=current_procinfo;
         old_current_procinfo:=current_procinfo;
         oldfilepos:=current_filepos;
         oldfilepos:=current_filepos;
-        old_current_objectdef:=current_objectdef;
+        old_current_structdef:=current_structdef;
         oldmaxfpuregisters:=current_settings.maxfpuregisters;
         oldmaxfpuregisters:=current_settings.maxfpuregisters;
 
 
         current_procinfo:=self;
         current_procinfo:=self;
         current_filepos:=entrypos;
         current_filepos:=entrypos;
-        current_objectdef:=procdef._class;
+        current_structdef:=procdef.struct;
 
 
         templist:=TAsmList.create;
         templist:=TAsmList.create;
 
 
@@ -1265,7 +1265,7 @@ implementation
         templist.free;
         templist.free;
         current_settings.maxfpuregisters:=oldmaxfpuregisters;
         current_settings.maxfpuregisters:=oldmaxfpuregisters;
         current_filepos:=oldfilepos;
         current_filepos:=oldfilepos;
-        current_objectdef:=old_current_objectdef;
+        current_structdef:=old_current_structdef;
         current_procinfo:=old_current_procinfo;
         current_procinfo:=old_current_procinfo;
       end;
       end;
 
 
@@ -1273,11 +1273,11 @@ implementation
     procedure tcgprocinfo.add_to_symtablestack;
     procedure tcgprocinfo.add_to_symtablestack;
       begin
       begin
         { insert symtables for the class, but only if it is no nested function }
         { insert symtables for the class, but only if it is no nested function }
-        if assigned(procdef._class) and
+        if assigned(procdef.struct) and
            not(assigned(parent) and
            not(assigned(parent) and
                assigned(parent.procdef) and
                assigned(parent.procdef) and
-               assigned(parent.procdef._class)) then
-          push_nested_hierarchy(procdef._class);
+               assigned(parent.procdef.struct)) then
+          push_nested_hierarchy(procdef.struct);
 
 
         { insert parasymtable in symtablestack when parsing
         { insert parasymtable in symtablestack when parsing
           a function }
           a function }
@@ -1303,11 +1303,11 @@ implementation
           symtablestack.pop(procdef.parast);
           symtablestack.pop(procdef.parast);
 
 
         { remove symtables for the class, but only if it is no nested function }
         { remove symtables for the class, but only if it is no nested function }
-        if assigned(procdef._class) and
+        if assigned(procdef.struct) and
            not(assigned(parent) and
            not(assigned(parent) and
                assigned(parent.procdef) and
                assigned(parent.procdef) and
-               assigned(parent.procdef._class)) then
-          pop_nested_hierarchy(procdef._class);
+               assigned(parent.procdef.struct)) then
+          pop_nested_hierarchy(procdef.struct);
       end;
       end;
 
 
 
 
@@ -1379,22 +1379,22 @@ implementation
          old_current_procinfo : tprocinfo;
          old_current_procinfo : tprocinfo;
          old_block_type : tblock_type;
          old_block_type : tblock_type;
          st : TSymtable;
          st : TSymtable;
-         old_current_objectdef,
+         old_current_structdef: tabstractrecorddef;
          old_current_genericdef,
          old_current_genericdef,
          old_current_specializedef : tobjectdef;
          old_current_specializedef : tobjectdef;
       begin
       begin
          old_current_procinfo:=current_procinfo;
          old_current_procinfo:=current_procinfo;
          old_block_type:=block_type;
          old_block_type:=block_type;
-         old_current_objectdef:=current_objectdef;
+         old_current_structdef:=current_structdef;
          old_current_genericdef:=current_genericdef;
          old_current_genericdef:=current_genericdef;
          old_current_specializedef:=current_specializedef;
          old_current_specializedef:=current_specializedef;
 
 
          current_procinfo:=self;
          current_procinfo:=self;
-         current_objectdef:=procdef._class;
-         if assigned(current_objectdef) and (df_generic in current_objectdef.defoptions) then
-           current_genericdef:=current_objectdef;
-         if assigned(current_objectdef) and (df_specialization in current_objectdef.defoptions) then
-           current_specializedef:=current_objectdef;
+         current_structdef:=procdef.struct;
+         if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
+           current_genericdef:=tobjectdef(current_structdef);
+         if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
+           current_specializedef:=tobjectdef(current_structdef);
 
 
          { calculate the lexical level }
          { calculate the lexical level }
          if procdef.parast.symtablelevel>maxnesting then
          if procdef.parast.symtablelevel>maxnesting then
@@ -1500,7 +1500,7 @@ implementation
 {    aktstate.destroy;}
 {    aktstate.destroy;}
     {$endif state_tracking}
     {$endif state_tracking}
 
 
-         current_objectdef:=old_current_objectdef;
+         current_structdef:=old_current_structdef;
          current_genericdef:=old_current_genericdef;
          current_genericdef:=old_current_genericdef;
          current_specializedef:=old_current_specializedef;
          current_specializedef:=old_current_specializedef;
          current_procinfo:=old_current_procinfo;
          current_procinfo:=old_current_procinfo;
@@ -1646,7 +1646,7 @@ implementation
 
 
       var
       var
         old_current_procinfo : tprocinfo;
         old_current_procinfo : tprocinfo;
-        old_current_objectdef,
+        old_current_structdef: tabstractrecorddef;
         old_current_genericdef,
         old_current_genericdef,
         old_current_specializedef : tobjectdef;
         old_current_specializedef : tobjectdef;
         pdflags    : tpdflags;
         pdflags    : tpdflags;
@@ -1655,19 +1655,19 @@ implementation
       begin
       begin
          { save old state }
          { save old state }
          old_current_procinfo:=current_procinfo;
          old_current_procinfo:=current_procinfo;
-         old_current_objectdef:=current_objectdef;
+         old_current_structdef:=current_structdef;
          old_current_genericdef:=current_genericdef;
          old_current_genericdef:=current_genericdef;
          old_current_specializedef:=current_specializedef;
          old_current_specializedef:=current_specializedef;
 
 
          { reset current_procinfo.procdef to nil to be sure that nothing is writing
          { reset current_procinfo.procdef to nil to be sure that nothing is writing
            to another procdef }
            to another procdef }
          current_procinfo:=nil;
          current_procinfo:=nil;
-         current_objectdef:=nil;
+         current_structdef:=nil;
          current_genericdef:=nil;
          current_genericdef:=nil;
          current_specializedef:=nil;
          current_specializedef:=nil;
 
 
          { parse procedure declaration }
          { parse procedure declaration }
-         pd:=parse_proc_dec(isclassmethod, old_current_objectdef);
+         pd:=parse_proc_dec(isclassmethod,old_current_structdef);
 
 
          { set the default function options }
          { set the default function options }
          if parse_only then
          if parse_only then
@@ -1710,8 +1710,8 @@ implementation
          if not proc_add_definition(pd) then
          if not proc_add_definition(pd) then
            begin
            begin
              { A method must be forward defined (in the object declaration) }
              { A method must be forward defined (in the object declaration) }
-             if assigned(pd._class) and
-                (not assigned(old_current_objectdef)) then
+             if assigned(pd.struct) and
+                (not assigned(old_current_structdef)) then
               begin
               begin
                 MessagePos1(pd.fileinfo,parser_e_header_dont_match_any_member,pd.fullprocname(false));
                 MessagePos1(pd.fileinfo,parser_e_header_dont_match_any_member,pd.fullprocname(false));
                 tprocsym(pd.procsym).write_parameter_lists(pd);
                 tprocsym(pd.procsym).write_parameter_lists(pd);
@@ -1792,7 +1792,7 @@ implementation
                current_asmdata.DefineAsmSymbol(pd.mangledname,AB_LOCAL,AT_FUNCTION);
                current_asmdata.DefineAsmSymbol(pd.mangledname,AB_LOCAL,AT_FUNCTION);
            end;
            end;
 
 
-         current_objectdef:=old_current_objectdef;
+         current_structdef:=old_current_structdef;
          current_genericdef:=old_current_genericdef;
          current_genericdef:=old_current_genericdef;
          current_specializedef:=old_current_specializedef;
          current_specializedef:=old_current_specializedef;
          current_procinfo:=old_current_procinfo;
          current_procinfo:=old_current_procinfo;
@@ -1842,7 +1842,7 @@ implementation
                      if not(token in [_FUNCTION,_PROCEDURE,_PROPERTY,_VAR,_CONSTRUCTOR,_DESTRUCTOR]) then
                      if not(token in [_FUNCTION,_PROCEDURE,_PROPERTY,_VAR,_CONSTRUCTOR,_DESTRUCTOR]) then
                        Message(parser_e_procedure_or_function_expected);
                        Message(parser_e_procedure_or_function_expected);
 
 
-                     if is_interface(current_objectdef) then
+                     if is_interface(current_structdef) then
                        Message(parser_e_no_static_method_in_interfaces)
                        Message(parser_e_no_static_method_in_interfaces)
                      else
                      else
                        { class methods are also allowed for Objective-C protocols }
                        { class methods are also allowed for Objective-C protocols }

+ 13 - 13
compiler/ptconst.pas

@@ -191,7 +191,7 @@ implementation
           end;
           end;
 
 
         begin
         begin
-           n:=comp_expr(true);
+           n:=comp_expr(true,false);
            { for C-style booleans, true=-1 and false=0) }
            { for C-style booleans, true=-1 and false=0) }
            if is_cbool(def) then
            if is_cbool(def) then
              inserttypeconv(n,def);
              inserttypeconv(n,def);
@@ -291,7 +291,7 @@ implementation
           n : tnode;
           n : tnode;
           value : bestreal;
           value : bestreal;
         begin
         begin
-          n:=comp_expr(true);
+          n:=comp_expr(true,false);
           if is_constrealnode(n) then
           if is_constrealnode(n) then
             value:=trealconstnode(n).value_real
             value:=trealconstnode(n).value_real
           else if is_constintnode(n) then
           else if is_constintnode(n) then
@@ -332,7 +332,7 @@ implementation
         var
         var
           n : tnode;
           n : tnode;
         begin
         begin
-          n:=comp_expr(true);
+          n:=comp_expr(true,false);
           case n.nodetype of
           case n.nodetype of
             loadvmtaddrn:
             loadvmtaddrn:
               begin
               begin
@@ -369,7 +369,7 @@ implementation
           ll        : tasmlabel;
           ll        : tasmlabel;
           varalign  : shortint;
           varalign  : shortint;
         begin
         begin
-          p:=comp_expr(true);
+          p:=comp_expr(true,false);
           { remove equal typecasts for pointer/nil addresses }
           { remove equal typecasts for pointer/nil addresses }
           if (p.nodetype=typeconvn) then
           if (p.nodetype=typeconvn) then
             with Ttypeconvnode(p) do
             with Ttypeconvnode(p) do
@@ -587,7 +587,7 @@ implementation
           p : tnode;
           p : tnode;
           i : longint;
           i : longint;
         begin
         begin
-          p:=comp_expr(true);
+          p:=comp_expr(true,false);
           if p.nodetype=setconstn then
           if p.nodetype=setconstn then
             begin
             begin
               { be sure to convert to the correct result, else
               { be sure to convert to the correct result, else
@@ -622,7 +622,7 @@ implementation
         var
         var
           p : tnode;
           p : tnode;
         begin
         begin
-          p:=comp_expr(true);
+          p:=comp_expr(true,false);
           if p.nodetype=ordconstn then
           if p.nodetype=ordconstn then
             begin
             begin
               if equal_defs(p.resultdef,def) or
               if equal_defs(p.resultdef,def) or
@@ -653,7 +653,7 @@ implementation
           ca        : pchar;
           ca        : pchar;
           winlike   : boolean;
           winlike   : boolean;
         begin
         begin
-          n:=comp_expr(true);
+          n:=comp_expr(true,false);
           { load strval and strlength of the constant tree }
           { load strval and strlength of the constant tree }
           if (n.nodetype=stringconstn) or is_wide_or_unicode_string(def) or is_constwidecharnode(n) or
           if (n.nodetype=stringconstn) or is_wide_or_unicode_string(def) or is_constwidecharnode(n) or
             ((n.nodetype=typen) and is_interfacecorba(ttypenode(n).typedef)) then
             ((n.nodetype=typen) and is_interfacecorba(ttypenode(n).typedef)) then
@@ -772,7 +772,7 @@ implementation
             n : tnode;
             n : tnode;
           begin
           begin
             result:=true;
             result:=true;
-            n:=comp_expr(true);
+            n:=comp_expr(true,false);
             if (n.nodetype <> ordconstn) or
             if (n.nodetype <> ordconstn) or
                (not equal_defs(n.resultdef,def) and
                (not equal_defs(n.resultdef,def) and
                 not is_subequal(n.resultdef,def)) then
                 not is_subequal(n.resultdef,def)) then
@@ -873,7 +873,7 @@ implementation
           else if is_anychar(def.elementdef) then
           else if is_anychar(def.elementdef) then
             begin
             begin
                char_size:=def.elementdef.size;
                char_size:=def.elementdef.size;
-               n:=comp_expr(true);
+               n:=comp_expr(true,false);
                if n.nodetype=stringconstn then
                if n.nodetype=stringconstn then
                  begin
                  begin
                    len:=tstringconstnode(n).len;
                    len:=tstringconstnode(n).len;
@@ -970,7 +970,7 @@ implementation
             Message(parser_e_no_procvarobj_const);
             Message(parser_e_no_procvarobj_const);
           { parse the rest too, so we can continue with error checking }
           { parse the rest too, so we can continue with error checking }
           getprocvardef:=def;
           getprocvardef:=def;
-          n:=comp_expr(true);
+          n:=comp_expr(true,false);
           getprocvardef:=nil;
           getprocvardef:=nil;
           if codegenerror then
           if codegenerror then
             begin
             begin
@@ -1062,7 +1062,7 @@ implementation
           { GUID }
           { GUID }
           if (def=rec_tguid) and (token=_ID) then
           if (def=rec_tguid) and (token=_ID) then
             begin
             begin
-              n:=comp_expr(true);
+              n:=comp_expr(true,false);
               if n.nodetype=stringconstn then
               if n.nodetype=stringconstn then
                 handle_stringconstn
                 handle_stringconstn
               else
               else
@@ -1085,7 +1085,7 @@ implementation
             end;
             end;
           if (def=rec_tguid) and ((token=_CSTRING) or (token=_CCHAR)) then
           if (def=rec_tguid) and ((token=_CSTRING) or (token=_CCHAR)) then
             begin
             begin
-              n:=comp_expr(true);
+              n:=comp_expr(true,false);
               inserttypeconv(n,cshortstringtype);
               inserttypeconv(n,cshortstringtype);
               if n.nodetype=stringconstn then
               if n.nodetype=stringconstn then
                 handle_stringconstn
                 handle_stringconstn
@@ -1278,7 +1278,7 @@ implementation
           { only allow nil for class and interface }
           { only allow nil for class and interface }
           if is_class_or_interface_or_dispinterface_or_objc(def) then
           if is_class_or_interface_or_dispinterface_or_objc(def) then
             begin
             begin
-              n:=comp_expr(true);
+              n:=comp_expr(true,false);
               if n.nodetype<>niln then
               if n.nodetype<>niln then
                 begin
                 begin
                   Message(parser_e_type_const_not_possible);
                   Message(parser_e_type_const_not_possible);

+ 31 - 53
compiler/ptype.pas

@@ -191,7 +191,7 @@ implementation
           begin
           begin
             consume(_LSHARPBRACKET);
             consume(_LSHARPBRACKET);
             repeat
             repeat
-              pt2:=factor(false);
+              pt2:=factor(false,true);
               pt2.free;
               pt2.free;
             until not try_to_consume(_COMMA);
             until not try_to_consume(_COMMA);
             consume(_RSHARPBRACKET);
             consume(_RSHARPBRACKET);
@@ -227,7 +227,7 @@ implementation
                   consume(_COMMA)
                   consume(_COMMA)
                 else
                 else
                   first:=false;
                   first:=false;
-                pt2:=factor(false);
+                pt2:=factor(false,true);
                 if pt2.nodetype=typen then
                 if pt2.nodetype=typen then
                   begin
                   begin
                     if df_generic in pt2.resultdef.defoptions then
                     if df_generic in pt2.resultdef.defoptions then
@@ -253,9 +253,9 @@ implementation
           consume(_RSHARPBRACKET);
           consume(_RSHARPBRACKET);
 
 
         { Special case if we are referencing the current defined object }
         { Special case if we are referencing the current defined object }
-        if assigned(current_objectdef) and
-           (current_objectdef.objname^=uspecializename) then
-          tt:=current_objectdef;
+        if assigned(current_structdef) and
+           (current_structdef.objname^=uspecializename) then
+          tt:=current_structdef;
 
 
         { for units specializations can already be needed in the interface, therefor we
         { for units specializations can already be needed in the interface, therefor we
           will use the global symtable. Programs don't have a globalsymtable and there we
           will use the global symtable. Programs don't have a globalsymtable and there we
@@ -373,7 +373,7 @@ implementation
         srsymtable : TSymtable;
         srsymtable : TSymtable;
         s,sorg : TIDString;
         s,sorg : TIDString;
         t : ttoken;
         t : ttoken;
-        objdef : tobjectdef;
+        structdef : tabstractrecorddef;
       begin
       begin
          s:=pattern;
          s:=pattern;
          sorg:=orgpattern;
          sorg:=orgpattern;
@@ -381,20 +381,20 @@ implementation
          { use of current parsed object:
          { use of current parsed object:
             - classes can be used also in classes
             - classes can be used also in classes
             - objects can be parameters }
             - objects can be parameters }
-         objdef:=current_objectdef;
-         while Assigned(objdef) and (objdef.typ=objectdef) do
+         structdef:=current_structdef;
+         while Assigned(structdef) and (structdef.typ in [objectdef,recorddef]) do
            begin
            begin
-             if (tobjectdef(objdef).objname^=pattern) and
+             if (structdef.objname^=pattern) and
                 (
                 (
                   (testcurobject=2) or
                   (testcurobject=2) or
-                  is_class_or_interface_or_objc(objdef)
+                  is_class_or_interface_or_objc(structdef)
                 ) then
                 ) then
                 begin
                 begin
                   consume(_ID);
                   consume(_ID);
-                  def:=objdef;
+                  def:=structdef;
                   exit;
                   exit;
                 end;
                 end;
-             objdef:=tobjectdef(tobjectdef(objdef).owner.defowner);
+             structdef:=tabstractrecorddef(structdef.owner.defowner);
            end;
            end;
          { Use the special searchsym_type that ignores records and parameters }
          { Use the special searchsym_type that ignores records and parameters }
          searchsym_type(s,srsym,srsymtable);
          searchsym_type(s,srsym,srsymtable);
@@ -505,12 +505,12 @@ implementation
                                 consume(_POINT);
                                 consume(_POINT);
                                 consume(_ID);
                                 consume(_ID);
                              end
                              end
-                            else if is_class_or_object(def) then
+                            else if is_class_or_object(def) or is_record(def) then
                               begin
                               begin
-                                symtablestack.push(tobjectdef(def).symtable);
+                                symtablestack.push(tabstractrecorddef(def).symtable);
                                 consume(_POINT);
                                 consume(_POINT);
                                 id_type(t2,isforwarddef);
                                 id_type(t2,isforwarddef);
-                                symtablestack.pop(tobjectdef(def).symtable);
+                                symtablestack.pop(tabstractrecorddef(def).symtable);
                                 def:=t2;
                                 def:=t2;
                               end
                               end
                             else
                             else
@@ -584,6 +584,7 @@ implementation
           Exit;
           Exit;
 
 
         current_structdef.symtable.currentvisibility:=vis_public;
         current_structdef.symtable.currentvisibility:=vis_public;
+        testcurobject:=1;
         has_destructor:=false;
         has_destructor:=false;
         fields_allowed:=true;
         fields_allowed:=true;
         is_classdef:=false;
         is_classdef:=false;
@@ -716,49 +717,23 @@ implementation
                    is_classdef:=true;
                    is_classdef:=true;
                  end;
                  end;
               end;
               end;
-{ todo: record methods
             _PROCEDURE,
             _PROCEDURE,
             _FUNCTION:
             _FUNCTION:
               begin
               begin
                 oldparse_only:=parse_only;
                 oldparse_only:=parse_only;
                 parse_only:=true;
                 parse_only:=true;
-                pd:=parse_proc_dec(is_classdef, recorddef);
+                pd:=parse_proc_dec(is_classdef,current_structdef);
 
 
                 { this is for error recovery as well as forward }
                 { this is for error recovery as well as forward }
                 { interface mappings, i.e. mapping to a method  }
                 { interface mappings, i.e. mapping to a method  }
                 { which isn't declared yet                      }
                 { which isn't declared yet                      }
                 if assigned(pd) then
                 if assigned(pd) then
                   begin
                   begin
-                    parse_object_proc_directives(pd);
-
-                    { check if dispid is set }
-                    if is_dispinterface(pd._class) and not (po_dispid in pd.procoptions) then
-                      begin
-                        pd.dispid:=pd._class.get_next_dispid;
-                        include(pd.procoptions, po_dispid);
-                      end;
-
-                    { all Macintosh Object Pascal methods are virtual.  }
-                    { this can't be a class method, because macpas mode }
-                    { has no m_class                                    }
-                    if (m_mac in current_settings.modeswitches) then
-                      include(pd.procoptions,po_virtualmethod);
-
+                    parse_record_proc_directives(pd);
                     handle_calling_convention(pd);
                     handle_calling_convention(pd);
 
 
                     { add definition to procsym }
                     { add definition to procsym }
                     proc_add_definition(pd);
                     proc_add_definition(pd);
-
-                    { add procdef options to objectdef options }
-                    if (po_msgint in pd.procoptions) then
-                      include(current_objectdef.objectoptions,oo_has_msgint);
-                    if (po_msgstr in pd.procoptions) then
-                      include(current_objectdef.objectoptions,oo_has_msgstr);
-                    if (po_virtualmethod in pd.procoptions) then
-                      include(current_objectdef.objectoptions,oo_has_virtual);
-
-                    chkcpp(pd);
-                    chkobjc(pd);
                   end;
                   end;
 
 
                 maybe_parse_hint_directives(pd);
                 maybe_parse_hint_directives(pd);
@@ -767,6 +742,7 @@ implementation
                 fields_allowed:=false;
                 fields_allowed:=false;
                 is_classdef:=false;
                 is_classdef:=false;
               end;
               end;
+{ todo: constructor
             _CONSTRUCTOR :
             _CONSTRUCTOR :
               begin
               begin
                 if (current_objectdef.symtable.currentvisibility=vis_published) and
                 if (current_objectdef.symtable.currentvisibility=vis_published) and
@@ -868,6 +844,8 @@ implementation
               consume(_ID); { Give a ident expected message, like tp7 }
               consume(_ID); { Give a ident expected message, like tp7 }
           end;
           end;
         until false;
         until false;
+
+        testcurobject:=0;
       end;
       end;
 
 
     { reads a record declaration }
     { reads a record declaration }
@@ -913,7 +891,7 @@ implementation
            lv,hv   : TConstExprInt;
            lv,hv   : TConstExprInt;
            old_block_type : tblock_type;
            old_block_type : tblock_type;
            dospecialize : boolean;
            dospecialize : boolean;
-           objdef: TDef;
+           structdef: TDef;
         begin
         begin
            old_block_type:=block_type;
            old_block_type:=block_type;
            dospecialize:=false;
            dospecialize:=false;
@@ -922,32 +900,32 @@ implementation
               - objects can be parameters }
               - objects can be parameters }
            if (token=_ID) then
            if (token=_ID) then
              begin
              begin
-               objdef:=current_objectdef;
-               while Assigned(objdef) and (objdef.typ=objectdef) do
+               structdef:=current_structdef;
+               while Assigned(structdef) and (structdef.typ in [objectdef,recorddef]) do
                  begin
                  begin
-                   if (tobjectdef(objdef).objname^=pattern) and
+                   if (tabstractrecorddef(structdef).objname^=pattern) and
                       (
                       (
                         (testcurobject=2) or
                         (testcurobject=2) or
-                        is_class_or_interface_or_objc(objdef)
+                        is_class_or_interface_or_objc(structdef)
                       ) then
                       ) then
                       begin
                       begin
                         consume(_ID);
                         consume(_ID);
-                        def:=objdef;
+                        def:=structdef;
                         exit;
                         exit;
                       end;
                       end;
-                   objdef:=tobjectdef(tobjectdef(objdef).owner.defowner);
+                   structdef:=tdef(tabstractrecorddef(structdef).owner.defowner);
                  end;
                  end;
              end;
              end;
            { Generate a specialization? }
            { Generate a specialization? }
            if try_to_consume(_SPECIALIZE) then
            if try_to_consume(_SPECIALIZE) then
              dospecialize:=true;
              dospecialize:=true;
            { we can't accept a equal in type }
            { we can't accept a equal in type }
-           pt1:=comp_expr(false);
+           pt1:=comp_expr(false,true);
            if not dospecialize and
            if not dospecialize and
               try_to_consume(_POINTPOINT) then
               try_to_consume(_POINTPOINT) then
              begin
              begin
                { get high value of range }
                { get high value of range }
-               pt2:=comp_expr(false);
+               pt2:=comp_expr(false,false);
                { make both the same type or give an error. This is not
                { make both the same type or give an error. This is not
                  done when both are integer values, because typecasting
                  done when both are integer values, because typecasting
                  between -3200..3200 will result in a signed-unsigned
                  between -3200..3200 will result in a signed-unsigned
@@ -1257,7 +1235,7 @@ implementation
                     begin
                     begin
                        oldlocalswitches:=current_settings.localswitches;
                        oldlocalswitches:=current_settings.localswitches;
                        include(current_settings.localswitches,cs_allow_enum_calc);
                        include(current_settings.localswitches,cs_allow_enum_calc);
-                       p:=comp_expr(true);
+                       p:=comp_expr(true,false);
                        current_settings.localswitches:=oldlocalswitches;
                        current_settings.localswitches:=oldlocalswitches;
                        if (p.nodetype=ordconstn) then
                        if (p.nodetype=ordconstn) then
                         begin
                         begin

+ 2 - 5
compiler/rautils.pas

@@ -1334,10 +1334,7 @@ Begin
       i:=255;
       i:=255;
      base:=Copy(s,1,i-1);
      base:=Copy(s,1,i-1);
      delete(s,1,i);
      delete(s,1,i);
-     if st.symtabletype=ObjectSymtable then
-       sym:=search_class_member(tobjectdef(st.defowner),base)
-     else
-       sym:=tsym(st.Find(base));
+     sym:=search_struct_member(tabstractrecorddef(st.defowner),base);
      if not assigned(sym) then
      if not assigned(sym) then
       begin
       begin
         GetRecordOffsetSize:=false;
         GetRecordOffsetSize:=false;
@@ -1398,7 +1395,7 @@ Begin
                  begin
                  begin
                    { size = sizeof(target_system_pointer) }
                    { size = sizeof(target_system_pointer) }
                    size:=sizeof(pint);
                    size:=sizeof(pint);
-                   offset:=procdef._class.vmtmethodoffset(procdef.extnumber)
+                   offset:=tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber)
                  end;
                  end;
              end;
              end;
            { if something comes after the procsym, it's invalid assembler syntax }
            { if something comes after the procsym, it's invalid assembler syntax }

+ 21 - 13
compiler/symdef.pas

@@ -506,8 +506,8 @@ interface
           localst : TSymtable;
           localst : TSymtable;
           funcretsym : tsym;
           funcretsym : tsym;
           funcretsymderef : tderef;
           funcretsymderef : tderef;
-          _class : tobjectdef;
-          _classderef : tderef;
+          struct : tabstractrecorddef;
+          structderef : tderef;
 {$if defined(powerpc) or defined(m68k)}
 {$if defined(powerpc) or defined(m68k)}
           { library symbol for AmigaOS/MorphOS }
           { library symbol for AmigaOS/MorphOS }
           libsym : tsym;
           libsym : tsym;
@@ -782,6 +782,7 @@ interface
     function is_class_or_interface_or_dispinterface(def: tdef): boolean;
     function is_class_or_interface_or_dispinterface(def: tdef): boolean;
     function is_class_or_interface_or_dispinterface_or_objc(def: tdef): boolean;
     function is_class_or_interface_or_dispinterface_or_objc(def: tdef): boolean;
     function is_class_or_object(def: tdef): boolean;
     function is_class_or_object(def: tdef): boolean;
+    function is_record(def: tdef): boolean;
 
 
     procedure loadobjctypes;
     procedure loadobjctypes;
     procedure maybeloadcocoatypes;
     procedure maybeloadcocoatypes;
@@ -3137,7 +3138,7 @@ implementation
          forwarddef:=true;
          forwarddef:=true;
          interfacedef:=false;
          interfacedef:=false;
          hasforward:=false;
          hasforward:=false;
-         _class := nil;
+         struct := nil;
          import_dll:=nil;
          import_dll:=nil;
          import_name:=nil;
          import_name:=nil;
          import_nr:=0;
          import_nr:=0;
@@ -3161,7 +3162,7 @@ implementation
           _mangledname:=nil;
           _mangledname:=nil;
          extnumber:=ppufile.getword;
          extnumber:=ppufile.getword;
          level:=ppufile.getbyte;
          level:=ppufile.getbyte;
-         ppufile.getderef(_classderef);
+         ppufile.getderef(structderef);
          ppufile.getderef(procsymderef);
          ppufile.getderef(procsymderef);
          ppufile.getposinfo(fileinfo);
          ppufile.getposinfo(fileinfo);
          visibility:=tvisibility(ppufile.getbyte);
          visibility:=tvisibility(ppufile.getbyte);
@@ -3303,7 +3304,7 @@ implementation
 
 
          ppufile.putword(extnumber);
          ppufile.putword(extnumber);
          ppufile.putbyte(parast.symtablelevel);
          ppufile.putbyte(parast.symtablelevel);
-         ppufile.putderef(_classderef);
+         ppufile.putderef(structderef);
          ppufile.putderef(procsymderef);
          ppufile.putderef(procsymderef);
          ppufile.putposinfo(fileinfo);
          ppufile.putposinfo(fileinfo);
          ppufile.putbyte(byte(visibility));
          ppufile.putbyte(byte(visibility));
@@ -3389,9 +3390,9 @@ implementation
         showhidden:=true;
         showhidden:=true;
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
         s:='';
         s:='';
-        if assigned(_class) then
+        if assigned(struct) then
          begin
          begin
-           s:=_class.RttiName+'.';
+           s:=struct.RttiName+'.';
            if (po_classmethod in procoptions) and
            if (po_classmethod in procoptions) and
               not (proctypeoption in [potype_class_constructor,potype_class_destructor]) then
               not (proctypeoption in [potype_class_constructor,potype_class_destructor]) then
              s:='class ' + s;
              s:='class ' + s;
@@ -3466,7 +3467,7 @@ implementation
     procedure tprocdef.buildderef;
     procedure tprocdef.buildderef;
       begin
       begin
          inherited buildderef;
          inherited buildderef;
-         _classderef.build(_class);
+         structderef.build(struct);
          { procsym that originaly defined this definition, should be in the
          { procsym that originaly defined this definition, should be in the
            same symtable }
            same symtable }
          procsymderef.build(procsym);
          procsymderef.build(procsym);
@@ -3500,7 +3501,7 @@ implementation
     procedure tprocdef.deref;
     procedure tprocdef.deref;
       begin
       begin
          inherited deref;
          inherited deref;
-         _class:=tobjectdef(_classderef.resolve);
+         struct:=tabstractrecorddef(structderef.resolve);
          { procsym that originaly defined this definition, should be in the
          { procsym that originaly defined this definition, should be in the
            same symtable }
            same symtable }
          procsym:=tprocsym(procsymderef.resolve);
          procsym:=tprocsym(procsymderef.resolve);
@@ -4978,7 +4979,7 @@ implementation
             else
             else
               { all checks already done }
               { all checks already done }
               exit;
               exit;
-            if not(oo_is_external in pd._class.objectoptions) then
+            if not((pd.struct.typ=objectdef)and(oo_is_external in tobjectdef(pd.struct).objectoptions)) then
               begin
               begin
                 if (po_varargs in pd.procoptions) then
                 if (po_varargs in pd.procoptions) then
                   MessagePos(pd.fileinfo,parser_e_varargs_need_cdecl_and_external)
                   MessagePos(pd.fileinfo,parser_e_varargs_need_cdecl_and_external)
@@ -5073,11 +5074,11 @@ implementation
         if (def.typ=procdef) then
         if (def.typ=procdef) then
           begin
           begin
             pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
             pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
-            if (oo_is_external in pd._class.objectoptions) then
+            if (pd.struct.typ=objectdef) and (oo_is_external in tobjectdef(pd.struct).objectoptions) then
               begin
               begin
                 { copied from psub.read_proc }
                 { copied from psub.read_proc }
-                if assigned(pd._class.import_lib) then
-                   current_module.AddExternalImport(pd._class.import_lib^,pd.mangledname,0,false,false)
+                if assigned(tobjectdef(pd.struct).import_lib) then
+                   current_module.AddExternalImport(tobjectdef(pd.struct).import_lib^,pd.mangledname,0,false,false)
                  else
                  else
                    begin
                    begin
                      { add import name to external list for DLL scanning }
                      { add import name to external list for DLL scanning }
@@ -5491,6 +5492,13 @@ implementation
           (tobjectdef(def).objecttype in [odt_class,odt_object]);
           (tobjectdef(def).objecttype in [odt_class,odt_object]);
       end;
       end;
 
 
+    function is_record(def: tdef): boolean;
+      begin
+        result:=
+          assigned(def) and
+          (def.typ=recorddef);
+      end;
+
     procedure loadobjctypes;
     procedure loadobjctypes;
       begin
       begin
         objc_metaclasstype:=tpointerdef(search_named_unit_globaltype('OBJC','POBJC_CLASS',true).typedef);
         objc_metaclasstype:=tpointerdef(search_named_unit_globaltype('OBJC','POBJC_CLASS',true).typedef);

+ 46 - 23
compiler/symtable.pas

@@ -213,7 +213,7 @@ interface
     function  searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
     function  searchsym_in_class_by_msgstr(classh:tobjectdef;const s:string;out srsym:tsym;out srsymtable:TSymtable):boolean;
     function  search_system_type(const s: TIDString): ttypesym;
     function  search_system_type(const s: TIDString): ttypesym;
     function  search_named_unit_globaltype(const unitname, typename: TIDString; throwerror: boolean): ttypesym;
     function  search_named_unit_globaltype(const unitname, typename: TIDString; throwerror: boolean): ttypesym;
-    function  search_class_member(pd : tobjectdef;const s : string):tsym;
+    function  search_struct_member(pd : tabstractrecorddef;const s : string):tsym;
     function  search_assignment_operator(from_def,to_def:Tdef):Tprocdef;
     function  search_assignment_operator(from_def,to_def:Tdef):Tprocdef;
     function  search_enumerator_operator(from_def,to_def:Tdef):Tprocdef;
     function  search_enumerator_operator(from_def,to_def:Tdef):Tprocdef;
     function  search_class_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
     function  search_class_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
@@ -1188,7 +1188,7 @@ implementation
          if not(sym.typ in [procsym,propertysym]) then
          if not(sym.typ in [procsym,propertysym]) then
            begin
            begin
               { but private ids can be reused }
               { but private ids can be reused }
-              hsym:=search_class_member(tobjectdef(defowner),hashedid.id);
+              hsym:=search_struct_member(tobjectdef(defowner),hashedid.id);
               if assigned(hsym) and
               if assigned(hsym) and
                  (
                  (
                   (
                   (
@@ -1322,13 +1322,13 @@ implementation
           as the procsym }
           as the procsym }
         if not is_funcret_sym(sym) and
         if not is_funcret_sym(sym) and
            (defowner.typ=procdef) and
            (defowner.typ=procdef) and
-           assigned(tprocdef(defowner)._class) and
-           (tprocdef(defowner).owner.defowner=tprocdef(defowner)._class) and
+           assigned(tprocdef(defowner).struct) and
+           (tprocdef(defowner).owner.defowner=tprocdef(defowner).struct) and
            (
            (
             not(m_delphi in current_settings.modeswitches) or
             not(m_delphi in current_settings.modeswitches) or
-            is_object(tprocdef(defowner)._class)
+            is_object(tprocdef(defowner).struct)
            ) then
            ) then
-          result:=tprocdef(defowner)._class.symtable.checkduplicate(hashedid,sym);
+          result:=tprocdef(defowner).struct.symtable.checkduplicate(hashedid,sym);
       end;
       end;
 
 
 
 
@@ -1352,13 +1352,13 @@ implementation
           exit;
           exit;
         if not(m_duplicate_names in current_settings.modeswitches) and
         if not(m_duplicate_names in current_settings.modeswitches) and
            (defowner.typ=procdef) and
            (defowner.typ=procdef) and
-           assigned(tprocdef(defowner)._class) and
-           (tprocdef(defowner).owner.defowner=tprocdef(defowner)._class) and
+           assigned(tprocdef(defowner).struct) and
+           (tprocdef(defowner).owner.defowner=tprocdef(defowner).struct) and
            (
            (
             not(m_delphi in current_settings.modeswitches) or
             not(m_delphi in current_settings.modeswitches) or
-            is_object(tprocdef(defowner)._class)
+            is_object(tprocdef(defowner).struct)
            ) then
            ) then
-          result:=tprocdef(defowner)._class.symtable.checkduplicate(hashedid,sym);
+          result:=tprocdef(defowner).struct.symtable.checkduplicate(hashedid,sym);
       end;
       end;
 
 
 
 
@@ -1878,6 +1878,7 @@ implementation
       var
       var
         hashedid  : THashedIDString;
         hashedid  : THashedIDString;
         stackitem : psymtablestackitem;
         stackitem : psymtablestackitem;
+        classh : tobjectdef;
       begin
       begin
         result:=false;
         result:=false;
         hashedid.id:=s;
         hashedid.id:=s;
@@ -1886,27 +1887,46 @@ implementation
           begin
           begin
             {
             {
               It is not possible to have type symbols in:
               It is not possible to have type symbols in:
-                records
                 parameters
                 parameters
-              Exception are classes, objects, generic definitions and specializations
+              Exception are classes, objects, records, generic definitions and specializations
               that have the parameterized types inserted in the symtable.
               that have the parameterized types inserted in the symtable.
             }
             }
             srsymtable:=stackitem^.symtable;
             srsymtable:=stackitem^.symtable;
+            if (srsymtable.symtabletype=ObjectSymtable) then
+              begin
+                classh:=tobjectdef(srsymtable.defowner);
+                while assigned(classh) do
+                  begin
+                    srsymtable:=classh.symtable;
+                    srsym:=tsym(srsymtable.FindWithHash(hashedid));
+                    if assigned(srsym) and
+                       (srsym.typ=typesym) and
+                       is_visible_for_object(srsym,current_structdef) then
+                      begin
+                        addsymref(srsym);
+                        result:=true;
+                        exit;
+                      end;
+                    classh:=classh.childof;
+                  end;
+              end
+            else
             if not(srsymtable.symtabletype in [recordsymtable,ObjectSymtable,parasymtable]) or
             if not(srsymtable.symtabletype in [recordsymtable,ObjectSymtable,parasymtable]) or
                (assigned(srsymtable.defowner) and
                (assigned(srsymtable.defowner) and
                 (
                 (
                  (df_generic in tdef(srsymtable.defowner).defoptions) or
                  (df_generic in tdef(srsymtable.defowner).defoptions) or
                  (df_specialization in tdef(srsymtable.defowner).defoptions) or
                  (df_specialization in tdef(srsymtable.defowner).defoptions) or
-                 is_class_or_object(tdef(srsymtable.defowner)))
-                ) then
+                 is_class_or_object(tdef(srsymtable.defowner)) or
+                 is_record(tdef(srsymtable.defowner))
+                )
+               ) then
               begin
               begin
                 srsym:=tsym(srsymtable.FindWithHash(hashedid));
                 srsym:=tsym(srsymtable.FindWithHash(hashedid));
                 if assigned(srsym) and
                 if assigned(srsym) and
                    not(srsym.typ in [fieldvarsym,paravarsym]) and
                    not(srsym.typ in [fieldvarsym,paravarsym]) and
                    (
                    (
                     not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or
                     not (srsym.owner.symtabletype in [objectsymtable,recordsymtable]) or
-                    (is_visible_for_object(srsym,current_structdef) and
-                     (srsym.typ=typesym))
+                    ((srsym.typ=typesym)and is_visible_for_object(srsym,current_structdef))
                    ) then
                    ) then
                   begin
                   begin
                     { we need to know if a procedure references symbols
                     { we need to know if a procedure references symbols
@@ -2428,17 +2448,17 @@ implementation
       end;
       end;
 
 
 
 
-    function search_class_member(pd : tobjectdef;const s : string):tsym;
+    function search_struct_member(pd : tabstractrecorddef;const s : string):tsym;
     { searches n in symtable of pd and all anchestors }
     { searches n in symtable of pd and all anchestors }
       var
       var
         hashedid   : THashedIDString;
         hashedid   : THashedIDString;
         srsym      : tsym;
         srsym      : tsym;
-        orgpd      : tobjectdef;
+        orgpd      : tabstractrecorddef;
         srsymtable : tsymtable;
         srsymtable : tsymtable;
       begin
       begin
         { in case this is a formal objcclass, first find the real definition }
         { in case this is a formal objcclass, first find the real definition }
-        if (oo_is_formal in pd.objectoptions) then
-          pd:=find_real_objcclass_definition(pd,true);
+        if (pd.typ=objectdef) and (oo_is_formal in tobjectdef(pd).objectoptions) then
+          pd:=find_real_objcclass_definition(tobjectdef(pd),true);
         hashedid.id:=s;
         hashedid.id:=s;
         orgpd:=pd;
         orgpd:=pd;
         while assigned(pd) do
         while assigned(pd) do
@@ -2446,15 +2466,18 @@ implementation
            srsym:=tsym(pd.symtable.FindWithHash(hashedid));
            srsym:=tsym(pd.symtable.FindWithHash(hashedid));
            if assigned(srsym) then
            if assigned(srsym) then
             begin
             begin
-              search_class_member:=srsym;
+              search_struct_member:=srsym;
               exit;
               exit;
             end;
             end;
-           pd:=pd.childof;
+           if pd.typ=objectdef then
+             pd:=tobjectdef(pd).childof
+           else
+             pd:=nil;
          end;
          end;
 
 
         { not found, now look for class helpers }
         { not found, now look for class helpers }
         if is_objcclass(pd) then
         if is_objcclass(pd) then
-          search_class_helper(orgpd,s,result,srsymtable)
+          search_class_helper(tobjectdef(orgpd),s,result,srsymtable)
         else
         else
           result:=nil;
           result:=nil;
       end;
       end;

+ 4 - 0
tests/test/terecs3.pp

@@ -17,5 +17,9 @@ begin
     halt(2);
     halt(2);
   if F.C <> 1 then
   if F.C <> 1 then
     halt(3);
     halt(3);
+  if F.Test(3) <> 4 then
+    halt(4);
+  if F.Test1(4) <> 5 then
+    halt(5);
   WriteLn('ok');
   WriteLn('ok');
 end.
 end.

+ 18 - 2
tests/test/terecs_u1.pp

@@ -6,19 +6,35 @@ unit terecs_u1;
 interface
 interface
 
 
 type
 type
+  HWND = integer;
   TFoo = record
   TFoo = record
+    hWnd : HWND;
   private
   private
     F1: Integer;
     F1: Integer;
     F2: Byte;
     F2: Byte;
   public
   public
+    type
+      TBar = Integer;
     const
     const
-      C = 1;
+      C: TBar = 1;
     var
     var
-      F3: Integer;
+      F3: TBar;
       F4: Byte;
       F4: Byte;
+    function Test(n: TBar): TBar;
+    class function Test1(n: TBar): TBar;
   end;
   end;
 
 
 implementation
 implementation
 
 
+function TFoo.Test(n: TBar): TBar;
+begin
+  Result := F3 + F4 + n;
+end;
+
+class function TFoo.Test1(n: TBar): TBar;
+begin
+  Result := C + n;
+end;
+
 end.
 end.