Sfoglia il codice sorgente

+ support for anonymous record types for the JVM targets: automatically
generate a name and typesym for them

git-svn-id: branches/jvmbackend@18491 -

Jonas Maebe 14 anni fa
parent
commit
df7100ff80
3 ha cambiato i file con 41 aggiunte e 6 eliminazioni
  1. 3 1
      compiler/pdecvar.pas
  2. 23 3
      compiler/pjvm.pas
  3. 15 2
      compiler/ptype.pas

+ 3 - 1
compiler/pdecvar.pas

@@ -65,7 +65,7 @@ implementation
        ncgutil,ngenutil,
        { parser }
        scanner,
-       pbase,pexpr,ptype,ptconst,pdecsub,
+       pbase,pexpr,ptype,ptconst,pdecsub,pjvm,
        { link }
        import
        ;
@@ -1372,6 +1372,7 @@ implementation
 {$endif}
 
              read_anon_type(hdef,false);
+             jvm_guarantee_record_typesym(hdef);
              for i:=0 to sc.count-1 do
                begin
                  vs:=tabstractvarsym(sc[i]);
@@ -1586,6 +1587,7 @@ implementation
                  symtablestack.pop(recst);
                end;
              read_anon_type(hdef,false);
+             jvm_guarantee_record_typesym(hdef);
              block_type:=bt_var;
              { allow only static fields reference to struct where they are declared }
              if not (vd_class in options) and

+ 23 - 3
compiler/pjvm.pas

@@ -27,7 +27,7 @@ unit pjvm;
 interface
 
     uses
-     symdef;
+     symtype,symdef;
 
     { the JVM specs require that you add a default parameterless
       constructor in case the programmer hasn't specified any }
@@ -38,6 +38,9 @@ interface
       to initialse dynamic arrays }
     procedure add_java_default_record_methods_intf(def: trecorddef);
 
+    procedure jvm_guarantee_record_typesym(var def: tdef);
+
+
 implementation
 
   uses
@@ -47,7 +50,7 @@ implementation
     fmodule,
     parabase,
     pdecsub,
-    symbase,symtype,symtable,symconst,symsym,symcreat,defcmp,jvmdef,
+    symbase,symtable,symconst,symsym,symcreat,defcmp,jvmdef,
     defutil,paramgr;
 
 
@@ -182,7 +185,7 @@ implementation
         else
           internalerror(2011032806);
         { can't use def.typesym, not yet set at this point }
-        if def.symtable.realname^='' then
+        if not assigned(def.symtable.realname) then
           internalerror(2011032803);
         if str_parse_method_dec('procedure fpcDeepCopy(out result:'+def.symtable.realname^+');',potype_procedure,false,def,pd) then
           pd.synthetickind:=tsk_record_deepcopy
@@ -192,6 +195,23 @@ implementation
       end;
 
 
+    procedure jvm_guarantee_record_typesym(var def: tdef);
+      var
+        ts: ttypesym;
+      begin
+        { create a dummy typesym for the JVM target, because the record
+          has to be wrapped by a class }
+        if (target_info.system=system_jvm_java32) and
+           (def.typ=recorddef) and
+           not assigned(def.typesym) then
+          begin
+            ts:=ttypesym.create(trecorddef(def).symtable.realname^,def);
+            symtablestack.top.insert(ts);
+            ts.visibility:=vis_strictprivate;
+            def.typesym:=ts;
+          end;
+      end;
+
 {******************************************************************
                     jvm type validity checking
 *******************************************************************}

+ 15 - 2
compiler/ptype.pas

@@ -969,8 +969,21 @@ implementation
          current_genericdef:=nil;
          current_specializedef:=nil;
          { create recdef }
-         recst:=trecordsymtable.create(n,current_settings.packrecords);
-         current_structdef:=trecorddef.create(n,recst);
+         if (n<>'') or
+            (target_info.system<>system_jvm_java32) then
+           begin
+             recst:=trecordsymtable.create(n,current_settings.packrecords);
+             { can't use recst.realname^ instead of n, because recst.realname is
+               nil in case of an empty name }
+             current_structdef:=trecorddef.create(n,recst);
+           end
+         else
+           begin
+             { for the JVM target records always need a name, because they are
+               represented by a class }
+             recst:=trecordsymtable.create('fpc_intern_recname_'+tostr(symtablestack.top.deflist.count),current_settings.packrecords);
+             current_structdef:=trecorddef.create(recst.name^,recst);
+           end;
          result:=current_structdef;
          { insert in symtablestack }
          symtablestack.push(recst);