Browse Source

* removed typed const, it is now handled by staticvarsym
* globalvarsym renamed to staticvarsym
* fixed invalid regvar use in init when the finalize also uses the var

git-svn-id: trunk@5290 -

peter 19 years ago
parent
commit
0557ddc342

+ 3 - 4
compiler/browcol.pas

@@ -767,7 +767,7 @@ begin
   case Typ of
     abstractsym  : S:='abst';
     fieldvarsym  : S:='member';
-    globalvarsym,
+    staticvarsym,
     localvarsym,
     paravarsym   : S:='var';
     typesym      : S:='type';
@@ -778,7 +778,6 @@ begin
     unitsym      : S:='unit';
     constsym     : S:='const';
     enumsym      : S:='enum';
-    typedconstsym: S:='const';
     errorsym     : S:='error';
     syssym       : S:='sys';
     labelsym     : S:='label';
@@ -1430,7 +1429,7 @@ end;
         sym:=tsym(Table.SymList[symidx]);
         New(Symbol, Init(Sym.Name,Sym.Typ,'',nil));
         case Sym.Typ of
-          globalvarsym,
+          staticvarsym,
           localvarsym,
           paravarsym :
              with tabstractvarsym(sym) do
@@ -1707,7 +1706,7 @@ begin
         C^.Insert(P);
       if (P^.typ=typesym) then
         D^.Insert(P);
-      if (P^.typ in [globalvarsym,localvarsym,paravarsym]) and ((P^.flags and sfPointer)<>0) then
+      if (P^.typ in [staticvarsym,localvarsym,paravarsym]) and ((P^.flags and sfPointer)<>0) then
         E^.Insert(P);
       if P^.Items<>nil then
         InsertSymbolCollection(P^.Items);

+ 14 - 14
compiler/cgobj.pas

@@ -919,7 +919,7 @@ implementation
 
    procedure tcg.a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister);
      var
-       bitmask: aint;
+       bitmask: aword;
        tmpreg: tregister;
        stopbit: byte;
      begin
@@ -928,11 +928,11 @@ implementation
        stopbit := sreg.startbit + sreg.bitlen;
        // on x86(64), 1 shl 32(64) = 1 instead of 0
        // use aword to prevent overflow with 1 shl 31
-       if (stopbit - sreg.startbit < AIntBits) then
+       if (stopbit - sreg.startbit <> AIntBits) then
          bitmask := (aword(1) shl (stopbit - sreg.startbit)) - 1
        else
-         bitmask := -1;
-       a_op_const_reg(list,OP_AND,sreg.subsetregsize,bitmask,tmpreg);
+         bitmask := high(aword);
+       a_op_const_reg(list,OP_AND,sreg.subsetregsize,aint(bitmask),tmpreg);
        tmpreg := makeregsize(list,tmpreg,subsetsize);
        a_load_reg_reg(list,tcgsize2unsigned[subsetsize],subsetsize,tmpreg,tmpreg);
        a_load_reg_reg(list,subsetsize,tosize,tmpreg,destreg);
@@ -947,7 +947,7 @@ implementation
 
    procedure tcg.a_load_regconst_subsetreg_intern(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt);
      var
-       bitmask: aint;
+       bitmask: aword;
        tmpreg: tregister;
        stopbit: byte;
      begin
@@ -956,17 +956,17 @@ implementation
        if (stopbit <> AIntBits) then
          bitmask := not(((aword(1) shl stopbit)-1) xor ((aword(1) shl sreg.startbit)-1))
        else
-         bitmask := not(-1 xor ((aword(1) shl sreg.startbit)-1));
+         bitmask := not(high(aword) xor ((aword(1) shl sreg.startbit)-1));
        if not(slopt in [SL_SETZERO,SL_SETMAX]) then
          begin
            tmpreg:=getintregister(list,sreg.subsetregsize);
            a_load_reg_reg(list,fromsize,sreg.subsetregsize,fromreg,tmpreg);
            a_op_const_reg(list,OP_SHL,sreg.subsetregsize,sreg.startbit,tmpreg);
             if (slopt <> SL_REGNOSRCMASK) then
-             a_op_const_reg(list,OP_AND,sreg.subsetregsize,not(bitmask),tmpreg);
+             a_op_const_reg(list,OP_AND,sreg.subsetregsize,aint(not(bitmask)),tmpreg);
          end;
        if (slopt <> SL_SETMAX) then
-         a_op_const_reg(list,OP_AND,sreg.subsetregsize,bitmask,sreg.subsetreg);
+         a_op_const_reg(list,OP_AND,sreg.subsetregsize,aint(bitmask),sreg.subsetreg);
 
        case slopt of
          SL_SETZERO : ;
@@ -986,7 +986,7 @@ implementation
     procedure tcg.a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize : tcgsize; const fromsreg, tosreg: tsubsetregister);
       var
         tmpreg: tregister;
-        bitmask: aint;
+        bitmask: aword;
         stopbit: byte;
       begin
         if (fromsreg.bitlen >= tosreg.bitlen) then
@@ -1003,8 +1003,8 @@ implementation
               bitmask := not(((aword(1) shl stopbit)-1) xor ((aword(1) shl tosreg.startbit)-1))
              else
                bitmask := (aword(1) shl tosreg.startbit) - 1;
-            a_op_const_reg(list,OP_AND,tosreg.subsetregsize,bitmask,tosreg.subsetreg);
-            a_op_const_reg(list,OP_AND,tosreg.subsetregsize,not(bitmask),tmpreg);
+            a_op_const_reg(list,OP_AND,tosreg.subsetregsize,aint(bitmask),tosreg.subsetreg);
+            a_op_const_reg(list,OP_AND,tosreg.subsetregsize,aint(not(bitmask)),tmpreg);
             a_op_reg_reg(list,OP_OR,tosreg.subsetregsize,tmpreg,tosreg.subsetreg);
           end
         else
@@ -1038,7 +1038,7 @@ implementation
 
   procedure tcg.a_load_const_subsetreg(list: TAsmlist; subsetsize: tcgsize; a: aint; const sreg: tsubsetregister);
     var
-      bitmask: aint;
+      bitmask: aword;
       stopbit: byte;
     begin
        stopbit := sreg.startbit + sreg.bitlen;
@@ -1048,8 +1048,8 @@ implementation
        else
          bitmask := (aword(1) shl sreg.startbit) - 1;
        if (((a shl sreg.startbit) and not bitmask) <> not bitmask) then
-         a_op_const_reg(list,OP_AND,sreg.subsetregsize,bitmask,sreg.subsetreg);
-       a_op_const_reg(list,OP_OR,sreg.subsetregsize,(a shl sreg.startbit) and not(bitmask),sreg.subsetreg);
+         a_op_const_reg(list,OP_AND,sreg.subsetregsize,aint(bitmask),sreg.subsetreg);
+       a_op_const_reg(list,OP_OR,sreg.subsetregsize,aint((aword(a) shl sreg.startbit) and not(bitmask)),sreg.subsetreg);
     end;
 
 

+ 3 - 26
compiler/dbgdwarf.pas

@@ -251,7 +251,6 @@ interface
         procedure appendsym_unit(sym:tunitsym); virtual;
         procedure appendsym_const(sym:tconstsym); virtual;
         procedure appendsym_type(sym:ttypesym); virtual;
-        procedure appendsym_typedconst(sym:ttypedconstsym); virtual;
         procedure appendsym_label(sym:tlabelsym); virtual;
         procedure appendsym_absolute(sym:tabsolutevarsym); virtual;
         procedure appendsym_property(sym:tpropertysym); virtual;
@@ -1591,7 +1590,7 @@ implementation
             else
               begin
                 case sym.typ of
-                  globalvarsym:
+                  staticvarsym:
                     begin
                       if (vo_is_thread_var in sym.varoptions) then
                         begin
@@ -1747,26 +1746,6 @@ implementation
           finish_entry;
         end;
 
-      procedure TDebugInfoDwarf.appendsym_typedconst(sym: ttypedconstsym);
-        begin
-          append_entry(DW_TAG_variable,false,[
-            DW_AT_name,DW_FORM_string,symname(sym)+#0,
-            {
-            DW_AT_decl_file,DW_FORM_data1,0,
-            DW_AT_decl_line,DW_FORM_data1,
-            }
-            DW_AT_external,DW_FORM_flag,true,
-            { data continues below }
-            DW_AT_location,DW_FORM_block1,1+sizeof(aword)
-          ]);
-          { append block data }
-          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(3));
-          current_asmdata.asmlists[al_dwarf_info].concat(tai_const.createname(sym.mangledname,0));
-          append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.typedconstdef));
-
-          finish_entry;
-        end;
-
       procedure TDebugInfoDwarf.appendsym_label(sym: tlabelsym);
         begin
           { ignore label syms for now, the problem is that a label sym
@@ -1874,8 +1853,8 @@ implementation
 
         current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Symbol '+symname(sym))));
         case sym.typ of
-          globalvarsym :
-            appendsym_var(tglobalvarsym(sym));
+          staticvarsym :
+            appendsym_var(tstaticvarsym(sym));
           unitsym:
             appendsym_unit(tunitsym(sym));
           procsym :
@@ -1886,8 +1865,6 @@ implementation
             appendsym_var(tlocalvarsym(sym));
           paravarsym :
             appendsym_var(tparavarsym(sym));
-          typedconstsym :
-            appendsym_typedconst(ttypedconstsym(sym));
           constsym :
             appendsym_const(tconstsym(sym));
           typesym :

+ 9 - 7
compiler/dbgstabs.pas

@@ -1089,11 +1089,12 @@ implementation
                   [def_stab_number(sym.vardef)]);
           end;
 
-        function globalvarsym_stabstr(sym:tglobalvarsym):Pchar;
+        function staticvarsym_stabstr(sym:tstaticvarsym):Pchar;
           var
             st : string;
             threadvaroffset : string;
             regidx : Tregisterindex;
+            nsym : string[7];
           begin
             result:=nil;
             { external symbols can't be resolved at link time, so we
@@ -1121,12 +1122,16 @@ implementation
                     threadvaroffset:='+'+tostr(sizeof(aint))
                   else
                     threadvaroffset:='';
+                  if (vo_is_typed_const in sym.varoptions) then
+                    nsym:='N_STSYM'
+                  else
+                    nsym:='N_LCSYM';
                   { Here we used S instead of
                     because with G GDB doesn't look at the address field
                     but searches the same name or with a leading underscore
                     but these names don't exist in pascal !}
                   st:='S'+st;
-                  result:=sym_stabstr_evaluate(sym,'"${name}:$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
+                  result:=sym_stabstr_evaluate(sym,'"${name}:$1",${'+nsym+'},0,${line},${mangledname}$2',[st,threadvaroffset]);
                 end;
             end;
           end;
@@ -1311,15 +1316,12 @@ implementation
             stabstr:=sym_stabstr_evaluate(sym,'"${name}",${N_LSYM},0,${line},0',[]);
           fieldvarsym :
             stabstr:=fieldvarsym_stabstr(tfieldvarsym(sym));
-          globalvarsym :
-            stabstr:=globalvarsym_stabstr(tglobalvarsym(sym));
+          staticvarsym :
+            stabstr:=staticvarsym_stabstr(tstaticvarsym(sym));
           localvarsym :
             stabstr:=localvarsym_stabstr(tlocalvarsym(sym));
           paravarsym :
             stabstr:=paravarsym_stabstr(tparavarsym(sym));
-          typedconstsym :
-            stabstr:=sym_stabstr_evaluate(sym,'"${name}:S$1",${N_STSYM},0,${line},${mangledname}',
-                [def_stab_number(ttypedconstsym(sym).typedconstdef)]);
           constsym :
             stabstr:=constsym_stabstr(tconstsym(sym));
           typesym :

+ 2 - 2
compiler/defutil.pas

@@ -774,8 +774,8 @@ implementation
               l:=tarraydef(def).lowrange;
               h:=tarraydef(def).highrange;
             end;
-        else
-          internalerror(987);
+          else
+            internalerror(200611054);
         end;
       end;
 

+ 0 - 2
compiler/globals.pas

@@ -251,7 +251,6 @@ interface
        parsing_para_level : integer;     { parameter level, used to convert
                                            proc calls to proc loads in firstcalln }
        compile_level : word;
-       make_ref : boolean;
        resolving_forward : boolean;      { used to add forward reference as second ref }
        inlining_procedure : boolean;     { are we inlining a procedure }
        exceptblockcounter    : integer;  { each except block gets a unique number check gotos      }
@@ -1308,7 +1307,6 @@ implementation
         DLLsource:=false;
         inlining_procedure:=false;
         resolving_forward:=false;
-        make_ref:=false;
         LinkTypeSetExplicitly:=false;
         paratarget:=system_none;
         paratargetasm:=as_none;

+ 4 - 15
compiler/htypechk.pas

@@ -655,7 +655,7 @@ implementation
                else
                  make_not_regable_intern(ttypeconvnode(p).left,how,records_only);
             loadn :
-              if (tloadnode(p).symtableentry.typ in [globalvarsym,localvarsym,paravarsym]) and
+              if (tloadnode(p).symtableentry.typ in [staticvarsym,localvarsym,paravarsym]) and
                  (tabstractvarsym(tloadnode(p).symtableentry).varregable <> vr_none) and
                  ((not records_only) or
                   (tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then
@@ -818,7 +818,7 @@ implementation
                break;
              loadn :
                begin
-                 if (tloadnode(p).symtableentry.typ in [localvarsym,paravarsym,globalvarsym]) then
+                 if (tloadnode(p).symtableentry.typ in [localvarsym,paravarsym,staticvarsym]) then
                   begin
                     hsym:=tabstractvarsym(tloadnode(p).symtableentry);
                     if (vsf_must_be_valid in varstateflags) and
@@ -1245,7 +1245,7 @@ implementation
                begin
                  case tloadnode(hp).symtableentry.typ of
                    absolutevarsym,
-                   globalvarsym,
+                   staticvarsym,
                    localvarsym,
                    paravarsym :
                      begin
@@ -1257,7 +1257,7 @@ implementation
                           CGMessage1(parser_e_illegal_assignment_to_count_var,tloadnode(hp).symtableentry.realname)
                          else
                           exit;
-                       { derefed pointer }
+                       { read-only variable? }
                        if (tabstractvarsym(tloadnode(hp).symtableentry).varspez=vs_const) then
                         begin
                           { allow p^:= constructions with p is const parameter }
@@ -1272,17 +1272,6 @@ implementation
                        result:=true;
                        exit;
                      end;
-                   typedconstsym :
-                     begin
-                       if ttypedconstsym(tloadnode(hp).symtableentry).is_writable or
-                          (valid_addr in opts) or
-                          (valid_const in opts) then
-                        result:=true
-                       else
-                        if report_errors then
-                         CGMessagePos(hp.fileinfo,type_e_no_assign_to_const);
-                       exit;
-                     end;
                    procsym :
                      begin
                        if (Valid_Const in opts) then

+ 2 - 2
compiler/m68k/ra68kmot.pas

@@ -693,8 +693,8 @@ const
                                  Message(asmr_e_no_local_or_para_allowed);
                                  hs:=tabstractvarsym(sym).mangledname;
                                end;
-                             typedconstsym :
-                                   hs:=ttypedconstsym(sym).mangledname;
+                             staticvarsym :
+                                   hs:=tstaticvarsym(sym).mangledname;
                              procsym :
                                begin
                                  if tprocsym(sym).procdeflist.count>1 then

+ 1 - 3
compiler/nadd.pas

@@ -672,7 +672,6 @@ implementation
         hp      : tnode;
         lt,rt   : tnodetype;
         rd,ld   : tdef;
-        hdef    : tdef;
         ot      : tnodetype;
         hsym    : tfieldvarsym;
         i       : longint;
@@ -1102,8 +1101,7 @@ implementation
              begin
                { generate a temporary normset def, it'll be destroyed
                  when the symtable is unloaded }
-               hdef:=tsetdef.create(tsetdef(ld).elementdef,255);
-               inserttypeconv(left,hdef);
+               inserttypeconv(left,tsetdef.create(tsetdef(ld).elementdef,255));
              end;
 
             { if the right side is also a setdef then the settype must

+ 1 - 1
compiler/ncal.pas

@@ -2090,7 +2090,7 @@ implementation
 
                { The object is already used if it is called once }
                if (hpt.nodetype=loadn) and
-                  (tloadnode(hpt).symtableentry.typ in [localvarsym,paravarsym,globalvarsym]) then
+                  (tloadnode(hpt).symtableentry.typ in [localvarsym,paravarsym,staticvarsym]) then
                  set_varstate(hpt,vs_read,[]);
 //                 tabstractvarsym(tloadnode(hpt).symtableentry).varstate:=vs_readwritten;
              end;

+ 8 - 10
compiler/ncgld.pas

@@ -72,7 +72,7 @@ implementation
       begin
 {$ifndef sparc}
         location.reference.base:=current_procinfo.got;
-        location.reference.symbol:=current_asmdata.RefAsmSymbol(tglobalvarsym(symtableentry).mangledname+'@GOT');
+        location.reference.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(symtableentry).mangledname+'@GOT');
 {$endif sparc}
       end;
 
@@ -81,7 +81,7 @@ implementation
       var
         hregister : tregister;
         vs   : tabstractnormalvarsym;
-        gvs  : tglobalvarsym;
+        gvs  : tstaticvarsym;
         pd   : tprocdef;
         href : treference;
         newsize : tcgsize;
@@ -131,12 +131,12 @@ implementation
                  else
                    internalerror(22798);
               end;
-            globalvarsym :
+            staticvarsym :
               begin
-                gvs:=tglobalvarsym(symtableentry);
+                gvs:=tstaticvarsym(symtableentry);
                 if ([vo_is_dll_var,vo_is_external] * gvs.varoptions <> []) then
                   begin
-                    location.reference.base := cg.g_indirect_sym_load(current_asmdata.CurrAsmList,tglobalvarsym(symtableentry).mangledname);
+                    location.reference.base := cg.g_indirect_sym_load(current_asmdata.CurrAsmList,tstaticvarsym(symtableentry).mangledname);
                     if (location.reference.base <> NR_NO) then
                       exit;
                   end;
@@ -145,7 +145,7 @@ implementation
                 { DLL variable }
                   begin
                     hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
-                    location.reference.symbol:=current_asmdata.RefAsmSymbol(tglobalvarsym(symtableentry).mangledname);
+                    location.reference.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(symtableentry).mangledname);
                     cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,location.reference,hregister);
                     reference_reset_base(location.reference,hregister,0);
                   end
@@ -190,7 +190,7 @@ implementation
                          cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
                          cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_ADDR,OC_EQ,0,hregister,norelocatelab);
                          { don't save the allocated register else the result will be destroyed later }
-                         reference_reset_symbol(href,current_asmdata.RefAsmSymbol(tglobalvarsym(symtableentry).mangledname),0);
+                         reference_reset_symbol(href,current_asmdata.RefAsmSymbol(tstaticvarsym(symtableentry).mangledname),0);
                          paramanager.allocparaloc(current_asmdata.CurrAsmList,paraloc1);
                          cg.a_param_ref(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
                          paramanager.freeparaloc(current_asmdata.CurrAsmList,paraloc1);
@@ -208,7 +208,7 @@ implementation
                            layout of a threadvar is (4 bytes pointer):
                              0 - Threadvar index
                              4 - Threadvar value in single threading }
-                         reference_reset_symbol(href,current_asmdata.RefAsmSymbol(tglobalvarsym(symtableentry).mangledname),sizeof(aint));
+                         reference_reset_symbol(href,current_asmdata.RefAsmSymbol(tstaticvarsym(symtableentry).mangledname),sizeof(aint));
                          cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister);
                          cg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
                          location.reference.base:=hregister;
@@ -348,8 +348,6 @@ implementation
                          location.reference.symbol:=current_asmdata.RefAsmSymbol(procdef.mangledname);
                     end;
                end;
-           typedconstsym :
-              location.reference.symbol:=current_asmdata.RefAsmSymbol(ttypedconstsym(symtableentry).mangledname);
             labelsym :
               location.reference.symbol:=tcglabelnode((tlabelsym(symtableentry).code)).getasmlabel;
             else internalerror(200510032);

+ 37 - 40
compiler/ncgutil.pas

@@ -138,7 +138,7 @@ interface
     procedure new_exception(list:TAsmList;const t:texceptiontemps;exceptlabel:tasmlabel);
     procedure free_exception(list:TAsmList;const t:texceptiontemps;a:aint;endexceptlabel:tasmlabel;onlyfree:boolean);
 
-    procedure insertbssdata(sym : tglobalvarsym);
+    procedure insertbssdata(sym : tstaticvarsym);
 
     procedure gen_alloc_symtable(list:TAsmList;st:TSymtable);
     procedure gen_free_symtable(list:TAsmList;st:TSymtable);
@@ -974,7 +974,7 @@ implementation
 {$q-}
 {$endif}
                cg.a_load_const_reg(list,reg_cgsize(tabstractnormalvarsym(p).initialloc.register),
-                 trashintval and (aint(1) shl (tcgsize2size[reg_cgsize(tabstractnormalvarsym(p).initialloc.register)] * 8) - 1),
+                 trashintval and (aword(1) shl (tcgsize2size[reg_cgsize(tabstractnormalvarsym(p).initialloc.register)] * 8) - 1),
                    tabstractnormalvarsym(p).initialloc.register);
 {$ifdef overflowon}
 {$undef overflowon}
@@ -1008,28 +1008,31 @@ implementation
     { initializes the regvars from staticsymtable with 0 }
     procedure initialize_regvars(p:TObject;arg:pointer);
       begin
-        if (tsym(p).typ=globalvarsym) then
+        if (tsym(p).typ=staticvarsym) then
          begin
-           case tglobalvarsym(p).initialloc.loc of
+           { Static variables can have the initialloc only set to LOC_CxREGISTER
+             or LOC_INVALID, for explaination see gen_alloc_symtable (PFV) }
+           case tstaticvarsym(p).initialloc.loc of
              LOC_CREGISTER :
                begin
 {$ifndef cpu64bit}
-                 if (tglobalvarsym(p).initialloc.size in [OS_64,OS_S64]) then
-                   cg64.a_load64_const_reg(TAsmList(arg),0,tglobalvarsym(p).initialloc.register64)
+                 if (tstaticvarsym(p).initialloc.size in [OS_64,OS_S64]) then
+                   cg64.a_load64_const_reg(TAsmList(arg),0,tstaticvarsym(p).initialloc.register64)
                  else
 {$endif not cpu64bit}
-                   cg.a_load_const_reg(TAsmList(arg),reg_cgsize(tglobalvarsym(p).initialloc.register),0,
-                       tglobalvarsym(p).initialloc.register);
+                   cg.a_load_const_reg(TAsmList(arg),reg_cgsize(tstaticvarsym(p).initialloc.register),0,
+                       tstaticvarsym(p).initialloc.register);
                end;
-             LOC_REFERENCE : ;
              LOC_CMMREGISTER :
                { clear the whole register }
-               cg.a_opmm_reg_reg(TAsmList(arg),OP_XOR,reg_cgsize(tglobalvarsym(p).initialloc.register),
-                 tglobalvarsym(p).initialloc.register,
-                 tglobalvarsym(p).initialloc.register,
+               cg.a_opmm_reg_reg(TAsmList(arg),OP_XOR,reg_cgsize(tstaticvarsym(p).initialloc.register),
+                 tstaticvarsym(p).initialloc.register,
+                 tstaticvarsym(p).initialloc.register,
                  nil);
              LOC_CFPUREGISTER :
                ;
+             LOC_INVALID :
+               ;
              else
                internalerror(200410124);
            end;
@@ -1043,8 +1046,9 @@ implementation
         OldAsmList : TAsmList;
         hp : tnode;
       begin
-        if (tsym(p).typ in [globalvarsym,localvarsym]) and
+        if (tsym(p).typ in [staticvarsym,localvarsym]) and
            (tabstractvarsym(p).refs>0) and
+           not(vo_is_typed_const in tabstractvarsym(p).varoptions) and
            not(vo_is_external in tabstractvarsym(p).varoptions) and
            not(is_class(tabstractvarsym(p).vardef)) and
            tabstractvarsym(p).vardef.needs_inittable then
@@ -1097,14 +1101,14 @@ implementation
         pd : tprocdef;
       begin
         case tsym(p).typ of
-          globalvarsym :
+          staticvarsym :
             begin
-              if (tglobalvarsym(p).refs>0) and
-                 (tglobalvarsym(p).varspez<>vs_const) and
-                 not(vo_is_funcret in tglobalvarsym(p).varoptions) and
-                 not(vo_is_external in tglobalvarsym(p).varoptions) and
-                 not(is_class(tglobalvarsym(p).vardef)) and
-                 tglobalvarsym(p).vardef.needs_inittable then
+              if (tstaticvarsym(p).refs>0) and
+                 (tstaticvarsym(p).varspez<>vs_const) and
+                 not(vo_is_funcret in tstaticvarsym(p).varoptions) and
+                 not(vo_is_external in tstaticvarsym(p).varoptions) and
+                 not(is_class(tstaticvarsym(p).vardef)) and
+                 tstaticvarsym(p).vardef.needs_inittable then
                 finalize_sym(TAsmList(arg),tsym(p));
             end;
           procsym :
@@ -2128,7 +2132,7 @@ implementation
                                Const Data
 ****************************************************************************}
 
-    procedure insertbssdata(sym : tglobalvarsym);
+    procedure insertbssdata(sym : tstaticvarsym);
       var
         l : aint;
         varalign : shortint;
@@ -2167,7 +2171,7 @@ implementation
            DLLSource or
            (assigned(current_procinfo) and
             (po_inline in current_procinfo.procdef.procoptions)) or
-           (vo_is_exported in sym.varoptions) then
+           (vo_is_public in sym.varoptions) then
           list.concat(Tai_datablock.create_global(sym.mangledname,l))
         else
           list.concat(Tai_datablock.create(sym.mangledname,l));
@@ -2198,33 +2202,26 @@ implementation
         sym     : tsym;
         vs      : tabstractnormalvarsym;
         isaddr  : boolean;
-        cgsize  : tcgsize;
       begin
         for i:=0 to st.SymList.Count-1 do
           begin
             sym:=tsym(st.SymList[i]);
             case sym.typ of
-              globalvarsym :
+              staticvarsym :
                 begin
                   vs:=tabstractnormalvarsym(sym);
-                  vs.initialloc.size:=def_cgsize(vs.vardef);
+                  { The code in laodnode.pass_generatecode will create the
+                    LOC_REFERENCE instead for all none register variables. This is
+                    required because we can't store an asmsymbol in the localloc because
+                    the asmsymbol is invalid after an unit is compiled. This gives
+                    problems when this procedure is inlined in an other unit (PFV) }
                   if vs.is_regvar(false) then
                     begin
                       vs.initialloc.loc:=tvarregable2tcgloc[vs.varregable];
+                      vs.initialloc.size:=def_cgsize(vs.vardef);
                       gen_alloc_regvar(list,vs);
-                    end
-                  else
-                    begin
-                      vs.initialloc.loc:=LOC_REFERENCE;
-                      { PIC, DLL and Threadvar need extra code and are handled in ncgld }
-                      if not(vo_is_dll_var in vs.varoptions) and
-                         (
-                          (tf_section_threadvars in target_info.flags) or
-                          not(vo_is_thread_var in vs.varoptions)
-                         ) then
-                        reference_reset_symbol(vs.initialloc.reference,current_asmdata.RefAsmSymbol(vs.mangledname),0);
+                      setlocalloc(vs);
                     end;
-                  setlocalloc(vs);
                 end;
               paravarsym :
                 begin
@@ -2325,7 +2322,7 @@ implementation
             if (ttemprefnode(n).tempinfo^.valid) then
               add_regvars(rv^,ttemprefnode(n).tempinfo^.location);
           loadn:
-            if (tloadnode(n).symtableentry.typ in [globalvarsym,localvarsym,paravarsym]) then
+            if (tloadnode(n).symtableentry.typ in [staticvarsym,localvarsym,paravarsym]) then
               add_regvars(rv^,tabstractnormalvarsym(tloadnode(n).symtableentry).localloc);
           vecn:
             { range checks sometimes need the high parameter }
@@ -2353,7 +2350,7 @@ implementation
         rv: pusedregvarscommon absolute arg;
       begin
         if (n.nodetype = loadn) and
-           (tloadnode(n).symtableentry.typ in [globalvarsym,localvarsym,paravarsym]) then
+           (tloadnode(n).symtableentry.typ in [staticvarsym,localvarsym,paravarsym]) then
           with tabstractnormalvarsym(tloadnode(n).symtableentry).localloc do
             case loc of
               LOC_CREGISTER:
@@ -2568,7 +2565,7 @@ implementation
         for i:=0 to st.SymList.Count-1 do
           begin
             sym:=tsym(st.SymList[i]);
-            if (sym.typ in [globalvarsym,localvarsym,paravarsym]) then
+            if (sym.typ in [staticvarsym,localvarsym,paravarsym]) then
               begin
                 with tabstractnormalvarsym(sym) do
                   begin

+ 27 - 28
compiler/nld.pas

@@ -256,36 +256,39 @@ implementation
                else
                  internalerror(22799);
              end;
-           globalvarsym,
+           staticvarsym :
+             begin
+               inc(tabstractvarsym(symtableentry).refs);
+               { static variables referenced in procedures or from finalization,
+                 variable needs to be in memory.
+                 It is too hard and the benefit is too small to detect whether a
+                 variable is only used in the finalization to add support for it (PFV) }
+               if assigned(current_procinfo) and
+                  (symtable.symtabletype=staticsymtable) and
+                  (
+                    (symtable.symtablelevel<>current_procinfo.procdef.localst.symtablelevel) or
+                    (current_procinfo.procdef.proctypeoption=potype_unitfinalize)
+                  ) then
+                 make_not_regable(self,vr_none);
+               resultdef:=tabstractvarsym(symtableentry).vardef;
+             end;
            paravarsym,
            localvarsym :
              begin
                inc(tabstractvarsym(symtableentry).refs);
                { Nested variable? The we need to load the framepointer of
                  the parent procedure }
-               if assigned(current_procinfo) then
+               if assigned(current_procinfo) and
+                  (symtable.symtabletype in [localsymtable,parasymtable]) and
+                  (symtable.symtablelevel<>current_procinfo.procdef.parast.symtablelevel) then
                  begin
-                   if (symtable.symtabletype in [localsymtable,parasymtable]) and
-                      (symtable.symtablelevel<>current_procinfo.procdef.parast.symtablelevel) then
-                     begin
-                       if assigned(left) then
-                         internalerror(200309289);
-                       left:=cloadparentfpnode.create(tprocdef(symtable.defowner));
-                       { we can't inline the referenced parent procedure }
-                       exclude(tprocdef(symtable.defowner).procoptions,po_inline);
-                       { reference in nested procedures, variable needs to be in memory }
-                       make_not_regable(self,vr_none);
-                     end;
-                   { static variables referenced in procedures or from finalization,
-                     variable needs to be in memory.
-                     It is too hard and the benefit is too small to detect whether a
-                     variable is only used in the finalization to add support for it (PFV) }
-                   if (symtable.symtabletype=staticsymtable) and
-                      (
-                       (symtable.symtablelevel<>current_procinfo.procdef.localst.symtablelevel) or
-                       (current_procinfo.procdef.proctypeoption=potype_unitfinalize)
-                      ) then
-                     make_not_regable(self,vr_none);
+                   if assigned(left) then
+                     internalerror(200309289);
+                   left:=cloadparentfpnode.create(tprocdef(symtable.defowner));
+                   { we can't inline the referenced parent procedure }
+                   exclude(tprocdef(symtable.defowner).procoptions,po_inline);
+                   { reference in nested procedures, variable needs to be in memory }
+                   make_not_regable(self,vr_none);
                  end;
                { fix self type which is declared as voidpointer in the
                  definition }
@@ -307,8 +310,6 @@ implementation
                else
                  resultdef:=tabstractvarsym(symtableentry).vardef;
              end;
-           typedconstsym :
-             resultdef:=ttypedconstsym(symtableentry).typedconstdef;
            procsym :
              begin
                { Return the first procdef. In case of overlaoded
@@ -363,7 +364,7 @@ implementation
                  if tconstsym(symtableentry).consttyp=constresourcestring then
                    expectloc:=LOC_CREFERENCE;
               end;
-            globalvarsym,
+            staticvarsym,
             localvarsym,
             paravarsym :
               begin
@@ -394,8 +395,6 @@ implementation
                 if cg.t_times>1 then
                   inc(tabstractvarsym(symtableentry).refs,cg.t_times-1);
               end;
-            typedconstsym :
-                ;
             procsym :
                 begin
                    { method pointer ? }

+ 0 - 16
compiler/nmem.pas

@@ -787,10 +787,6 @@ implementation
     end;
 
     function tvecnode.pass_1 : tnode;
-{$ifdef consteval}
-      var
-         tcsym : ttypedconstsym;
-{$endif}
       begin
          result:=nil;
          firstpass(left);
@@ -817,18 +813,6 @@ implementation
          { the register calculation is easy if a const index is used }
          if right.nodetype=ordconstn then
            begin
-{$ifdef consteval}
-              { constant evaluation }
-              if (left.nodetype=loadn) and
-                 (left.symtableentry.typ=typedconstsym) then
-               begin
-                 tcsym:=ttypedconstsym(left.symtableentry);
-                 if tcsym.defintion^.typ=stringdef then
-                  begin
-
-                  end;
-               end;
-{$endif}
               registersint:=left.registersint;
 
               { for ansi/wide strings, we need at least one register }

+ 2 - 2
compiler/nutils.pas

@@ -574,8 +574,8 @@ implementation
               loadn:
                 begin
                   { threadvars need a helper call }
-                  if (tloadnode(p).symtableentry.typ=globalvarsym) and
-                     (vo_is_thread_var in tglobalvarsym(tloadnode(p).symtableentry).varoptions) then
+                  if (tloadnode(p).symtableentry.typ=staticvarsym) and
+                     (vo_is_thread_var in tstaticvarsym(tloadnode(p).symtableentry).varoptions) then
                     inc(result,5)
                   else
                     inc(result);

+ 7 - 4
compiler/pdecl.pas

@@ -164,6 +164,7 @@ implementation
          old_block_type : tblock_type;
          skipequal : boolean;
          tclist : tasmlist;
+         varspez : tvarspez;
       begin
          consume(_CONST);
          old_block_type:=block_type;
@@ -203,7 +204,11 @@ implementation
                    { create symbol }
                    storetokenpos:=current_tokenpos;
                    current_tokenpos:=filepos;
-                   sym:=ttypedconstsym.create(orgname,hdef,(cs_typed_const_writable in current_settings.localswitches));
+                   if not (cs_typed_const_writable in current_settings.localswitches) then
+                     varspez:=vs_const
+                   else
+                     varspez:=vs_value;
+                   sym:=tstaticvarsym.create(orgname,varspez,hdef,[]);
                    current_tokenpos:=storetokenpos;
                    symtablestack.top.insert(sym);
                    { procvar can have proc directives, but not type references }
@@ -240,7 +245,7 @@ implementation
                         tclist:=current_asmdata.asmlists[al_rotypedconsts]
                       else
                         tclist:=current_asmdata.asmlists[al_typedconsts];
-                      readtypedconst(tclist,hdef,ttypedconstsym(sym),(cs_typed_const_writable in current_settings.localswitches));
+                      read_typed_const(tclist,tstaticvarsym(sym));
                       consume(_SEMICOLON);
                     end;
                 end;
@@ -317,11 +322,9 @@ implementation
                     stpos:=current_tokenpos;
                     current_tokenpos:=tforwarddef(hpd).forwardpos;
                     resolving_forward:=true;
-                    make_ref:=false;
                     if not assigned(tforwarddef(hpd).tosymname) then
                       internalerror(20021120);
                     searchsym(tforwarddef(hpd).tosymname^,srsym,srsymtable);
-                    make_ref:=true;
                     resolving_forward:=false;
                     current_tokenpos:=stpos;
                     { we don't need the forwarddef anymore, dispose it }

+ 4 - 6
compiler/pdecsub.pas

@@ -1337,7 +1337,7 @@ begin
 
       if consume_sym(sym,symtable) then
         begin
-          if (sym.typ=globalvarsym) and
+          if (sym.typ=staticvarsym) and
              (
               (tabstractvarsym(sym).vardef.typ=pointerdef) or
               is_32bitint(tabstractvarsym(sym).vardef)
@@ -1367,7 +1367,7 @@ begin
 
       if consume_sym(sym,symtable) then
         begin
-          if (sym.typ=globalvarsym) and
+          if (sym.typ=staticvarsym) and
              (
               (tabstractvarsym(sym).vardef.typ=pointerdef) or
               is_32bitint(tabstractvarsym(sym).vardef)
@@ -1430,7 +1430,7 @@ begin
 
       if consume_sym(sym,symtable) then
         begin
-          if (sym.typ=globalvarsym) and
+          if (sym.typ=staticvarsym) and
              (
               (tabstractvarsym(sym).vardef.typ=pointerdef) or
               is_32bitint(tabstractvarsym(sym).vardef)
@@ -2366,12 +2366,10 @@ const
         pd:=nil;
         case sym.typ of
           fieldvarsym,
-          globalvarsym,
+          staticvarsym,
           localvarsym,
           paravarsym :
             pd:=tabstractprocdef(tabstractvarsym(sym).vardef);
-          typedconstsym :
-            pd:=tabstractprocdef(ttypedconstsym(sym).typedconstdef);
           typesym :
             pd:=tabstractprocdef(ttypesym(sym).typedef);
           else

+ 312 - 329
compiler/pdecvar.pas

@@ -671,64 +671,273 @@ implementation
 
     procedure read_var_decls(options:Tvar_dec_options);
 
-      procedure read_default_value(sc : TFPObjectList;def:tdef;is_threadvar : boolean);
+        procedure read_default_value(sc : TFPObjectList);
         var
           vs : tabstractnormalvarsym;
-          tcsym : ttypedconstsym;
+          tcsym : tstaticvarsym;
         begin
           vs:=tabstractnormalvarsym(sc[0]);
           if sc.count>1 then
-             Message(parser_e_initialized_only_one_var);
-          if is_threadvar then
-             Message(parser_e_initialized_not_for_threadvar);
-          if symtablestack.top.symtabletype=localsymtable then
+            Message(parser_e_initialized_only_one_var);
+          if vo_is_thread_var in vs.varoptions then
+            Message(parser_e_initialized_not_for_threadvar);
+          consume(_EQUAL);
+          case vs.typ of
+            localvarsym :
+              begin
+                tcsym:=tstaticvarsym.create('$default'+vs.realname,vs_const,vs.vardef,[]);
+                include(tcsym.symoptions,sp_internal);
+                vs.defaultconstsym:=tcsym;
+                symtablestack.top.insert(tcsym);
+                read_typed_const(current_asmdata.asmlists[al_typedconsts],tcsym);
+                { The variable has a value assigned }
+                vs.varstate:=vs_initialised;
+              end;
+            staticvarsym :
+              begin
+                read_typed_const(current_asmdata.asmlists[al_typedconsts],tstaticvarsym(vs));
+              end;
+            else
+              internalerror(200611051);
+          end;
+        end;
+
+        procedure read_gpc_name(sc : TFPObjectList);
+        var
+          vs : tabstractnormalvarsym;
+          C_Name : string;
+        begin
+          consume(_ID);
+          C_Name:=get_stringconst;
+          vs:=tabstractnormalvarsym(sc[0]);
+          if sc.count>1 then
+            Message(parser_e_absolute_only_one_var);
+          if vs.typ=staticvarsym then
             begin
-              consume(_EQUAL);
-              tcsym:=ttypedconstsym.create('$default'+vs.realname,def,false);
-              include(tcsym.symoptions,sp_internal);
-              vs.defaultconstsym:=tcsym;
-              symtablestack.top.insert(tcsym);
-              readtypedconst(current_asmdata.asmlists[al_typedconsts],def,tcsym,false);
-              { The variable has a value assigned }
-              vs.varstate:=vs_initialised;
+              tstaticvarsym(vs).set_mangledname(target_info.Cprefix+vs.realname);
+              include(vs.varoptions,vo_is_external);
             end
           else
+            Message(parser_e_no_local_var_external);
+        end;
+
+        procedure read_absolute(sc : TFPObjectList);
+        var
+          vs     : tabstractvarsym;
+          abssym : tabsolutevarsym;
+          pt,hp  : tnode;
+        begin
+          abssym:=nil;
+          { only allowed for one var }
+          vs:=tabstractvarsym(sc[0]);
+          if sc.count>1 then
+            Message(parser_e_absolute_only_one_var);
+          { parse the rest }
+          pt:=expr;
+          { check allowed absolute types }
+          if (pt.nodetype=stringconstn) or
+            (is_constcharnode(pt)) then
+            begin
+              abssym:=tabsolutevarsym.create(vs.realname,vs.vardef);
+              abssym.fileinfo:=vs.fileinfo;
+              if pt.nodetype=stringconstn then
+                abssym.asmname:=stringdup(strpas(tstringconstnode(pt).value_str))
+              else
+                abssym.asmname:=stringdup(chr(tordconstnode(pt).value));
+              consume(token);
+              abssym.abstyp:=toasm;
+            end
+          { address }
+          else if is_constintnode(pt) then
+            begin
+              abssym:=tabsolutevarsym.create(vs.realname,vs.vardef);
+              abssym.fileinfo:=vs.fileinfo;
+              abssym.abstyp:=toaddr;
+              abssym.addroffset:=tordconstnode(pt).value;
+{$ifdef i386}
+              abssym.absseg:=false;
+              if (target_info.system in [system_i386_go32v2,system_i386_watcom]) and
+                  try_to_consume(_COLON) then
+                begin
+                  pt.free;
+                  pt:=expr;
+                  if is_constintnode(pt) then
+                    begin
+                      abssym.addroffset:=abssym.addroffset shl 4+tordconstnode(pt).value;
+                      abssym.absseg:=true;
+                    end
+                  else
+                    Message(type_e_ordinal_expr_expected);
+                end;
+{$endif i386}
+            end
+          { variable }
+          else
+            begin
+              { remove subscriptn before checking for loadn }
+              hp:=pt;
+              while (hp.nodetype in [subscriptn,typeconvn,vecn]) do
+                hp:=tunarynode(hp).left;
+              if (hp.nodetype=loadn) then
+                begin
+                  { we should check the result type of loadn }
+                  if not (tloadnode(hp).symtableentry.typ in [fieldvarsym,staticvarsym,localvarsym,paravarsym]) then
+                    Message(parser_e_absolute_only_to_var_or_const);
+                  abssym:=tabsolutevarsym.create(vs.realname,vs.vardef);
+                  abssym.fileinfo:=vs.fileinfo;
+                  abssym.abstyp:=tovar;
+                  abssym.ref:=node_to_propaccesslist(pt);
+                end
+              else
+                Message(parser_e_absolute_only_to_var_or_const);
+            end;
+          pt.free;
+          { replace old varsym with the new absolutevarsym }
+          if assigned(abssym) then
             begin
-              tcsym:=ttypedconstsym.create(vs.realname,def,true);
-              tcsym.fileinfo:=vs.fileinfo;
               Hidesym(vs);
-              vs.owner.Insert(tcsym);
-              consume(_EQUAL);
-              readtypedconst(current_asmdata.asmlists[al_typedconsts],def,tcsym,true);
+              vs.owner.insert(abssym);
+              sc[0]:=abssym;
+            end;
+        end;
+
+        procedure read_public_and_external(sc:TFPObjectList);
+        var
+          vs          : tabstractvarsym;
+          semicolonatend,
+          is_dll,
+          is_cdecl,
+          is_external_var,
+          is_public_var  : boolean;
+          dll_name,
+          C_name      : string;
+        begin
+          { only allowed for one var }
+          vs:=tabstractvarsym(sc[0]);
+          if sc.count>1 then
+            Message(parser_e_absolute_only_one_var);
+          { only allow external and public on global symbols }
+          if vs.typ<>staticvarsym then
+            begin
+              Message(parser_e_no_local_var_external);
+              exit;
+            end;
+            
+          { defaults }
+          is_dll:=false;
+          is_cdecl:=false;
+          is_external_var:=false;
+          is_public_var:=false;
+          semicolonatend:= false;
+          C_name:=vs.realname;
+
+          { macpas specific handling due to some switches}
+          if (m_mac in current_settings.modeswitches) then
+            begin
+              if (cs_external_var in current_settings.localswitches) then
+                begin {The effect of this is the same as if cvar; external; has been given as directives.}
+                  is_cdecl:=true;
+                  is_external_var:=true;
+                end
+              else if (cs_externally_visible in current_settings.localswitches) then
+                begin {The effect of this is the same as if cvar has been given as directives.}
+                  is_cdecl:=true;
+                end;
+            end;
+
+          { cdecl }
+          if try_to_consume(_CVAR) then
+            begin
+              consume(_SEMICOLON);
+              is_cdecl:=true;
+            end;
+
+          { external }
+          if try_to_consume(_EXTERNAL) then
+            begin
+              is_external_var:=true;
+              if not is_cdecl then
+                begin
+                  if idtoken<>_NAME then
+                    begin
+                      is_dll:=true;
+                      dll_name:=get_stringconst;
+                      if ExtractFileExt(dll_name)='' then
+                        dll_name:=ChangeFileExt(dll_name,target_info.sharedlibext);
+                    end;
+                  if try_to_consume(_NAME) then
+                    C_name:=get_stringconst;
+                end;
+              consume(_SEMICOLON);
+            end;
+
+          { export or public }
+          if idtoken in [_EXPORT,_PUBLIC] then
+            begin
+              consume(_ID);
+              if is_external_var then
+                Message(parser_e_not_external_and_export)
+              else
+                is_public_var:=true;
+              if try_to_consume(_NAME) then
+                C_name:=get_stringconst;
+              consume(_SEMICOLON);
             end;
+
+          { Windows uses an indirect reference using import tables }
+          if is_dll and
+             (target_info.system in system_all_windows) then
+            include(vs.varoptions,vo_is_dll_var);
+
+          { Add C _ prefix }
+          if is_cdecl or
+             (
+              is_dll and
+              (target_info.system in [system_powerpc_darwin,system_i386_darwin])
+             ) then
+            C_Name := target_info.Cprefix+C_Name;
+
+          if is_public_var then
+            begin
+              include(vs.varoptions,vo_is_public);
+              vs.varregable := vr_none;
+              { mark as referenced }
+              inc(vs.refs);
+            end;
+
+          { now we can insert it in the import lib if its a dll, or
+            add it to the externals }
+          if is_external_var then
+            begin
+              include(vs.varoptions,vo_is_external);
+              vs.varregable := vr_none;
+              if is_dll then
+                current_module.AddExternalImport(dll_name,C_Name,0,true)
+              else
+                if tf_has_dllscanner in target_info.flags then
+                  current_module.dllscannerinputlist.Add(vs.mangledname,vs);
+            end;
+
+          { Set the assembler name }
+          tstaticvarsym(vs).set_mangledname(C_Name);
         end;
 
       var
-         sc : TFPObjectList;
-         i  : longint;
-         old_block_type : tblock_type;
-         symdone : boolean;
-         { to handle absolute }
-         abssym : tabsolutevarsym;
-         { c var }
-         is_dll,
-         hasdefaultvalue,
-         is_gpc_name,is_cdecl,
-         extern_var,export_var : boolean;
-         old_current_object_option : tsymoptions;
-         hs,sorg,C_name,dll_name : string;
+         sc   : TFPObjectList;
+         vs   : tabstractvarsym;
          hdef : tdef;
-         hp,pt : tnode;
-         vs    : tabstractvarsym;
-         hintsymoptions : tsymoptions;
-         semicolonatend,semicoloneaten: boolean;
+         i    : longint;
+         semicoloneaten,
+         hasdefaultvalue : boolean;
+         old_current_object_option : tsymoptions;
+         hintsymoptions  : tsymoptions;
+         old_block_type  : tblock_type;
       begin
          old_current_object_option:=current_object_option;
          { all variables are public if not in a object declaration }
          current_object_option:=[sp_public];
          old_block_type:=block_type;
          block_type:=bt_type;
-         is_gpc_name:=false;
          { Force an expected ID error message }
          if not (token in [_ID,_CASE,_END]) then
            consume(_ID);
@@ -736,10 +945,8 @@ implementation
          sc:=TFPObjectList.create(false);
          while (token=_ID) do
            begin
-             sorg:=orgpattern;
              semicoloneaten:=false;
              hasdefaultvalue:=false;
-             symdone:=false;
              sc.clear;
              repeat
                if (token = _ID) then
@@ -749,7 +956,11 @@ implementation
                        vs:=tlocalvarsym.create(orgpattern,vs_value,generrordef,[]);
                      staticsymtable,
                      globalsymtable :
-                       vs:=tglobalvarsym.create(orgpattern,vs_value,generrordef,[]);
+                       begin
+                         vs:=tstaticvarsym.create(orgpattern,vs_value,generrordef,[]);
+                         if vd_threadvar in options then
+                           include(vs.varoptions,vo_is_thread_var);
+                       end;
                      else
                        internalerror(200411064);
                    end;
@@ -763,136 +974,34 @@ implementation
              if (m_gpc in current_settings.modeswitches) and
                 (token=_ID) and
                 (orgpattern='__asmname__') then
-               begin
-                 consume(_ID);
-                 C_name:=get_stringconst;
-                 Is_gpc_name:=true;
-               end;
+               read_gpc_name(sc);
 
-             { this is needed for Delphi mode at least
-               but should be OK for all modes !! (PM) }
+             { read variable type def }
              ignore_equal:=true;
              read_anon_type(hdef,false);
              ignore_equal:=false;
+             for i:=0 to sc.count-1 do
+               begin
+                 vs:=tabstractvarsym(sc[i]);
+                 vs.vardef:=hdef;
+               end;
 
              { Process procvar directives }
              if maybe_parse_proc_directives(hdef) then
                semicoloneaten:=true;
 
-             if is_gpc_name then
-               begin
-                  vs:=tabstractvarsym(sc[0]);
-                  if sc.count>1 then
-                    Message(parser_e_absolute_only_one_var);
-                  vs.vardef:=hdef;
-                  if vs.typ=globalvarsym then
-                    begin
-                      tglobalvarsym(vs).set_mangledname(target_info.Cprefix+sorg);
-                      include(vs.varoptions,vo_is_C_var);
-                      include(vs.varoptions,vo_is_external);
-                    end
-                  else
-                    Message(parser_e_no_local_var_external);
-                  symdone:=true;
-               end;
-
              { check for absolute }
-             if not symdone and
-                try_to_consume(_ABSOLUTE) then
-              begin
-                abssym:=nil;
-                { only allowed for one var }
-                vs:=tabstractvarsym(sc[0]);
-                if sc.count>1 then
-                  Message(parser_e_absolute_only_one_var);
-                { parse the rest }
-                pt:=expr;
-                { check allowed absolute types }
-                if (pt.nodetype=stringconstn) or
-                   (is_constcharnode(pt)) then
-                 begin
-                   abssym:=tabsolutevarsym.create(vs.realname,hdef);
-                   abssym.fileinfo:=vs.fileinfo;
-                   if pt.nodetype=stringconstn then
-                     hs:=strpas(tstringconstnode(pt).value_str)
-                   else
-                     hs:=chr(tordconstnode(pt).value);
-                   consume(token);
-                   abssym.abstyp:=toasm;
-                   abssym.asmname:=stringdup(hs);
-                   { replace the varsym }
-                   Hidesym(vs);
-                   vs.owner.insert(abssym);
-                 end
-                { address }
-                else if is_constintnode(pt) and
-                        ((target_info.system in [system_i386_go32v2,system_i386_watcom,
-                                                 system_i386_wdosx,system_i386_win32,
-                                                 system_arm_wince,system_i386_wince,
-                                                 system_arm_gba]) or
-                         (m_objfpc in current_settings.modeswitches) or
-                         (m_delphi in current_settings.modeswitches)) then
-                 begin
-                   abssym:=tabsolutevarsym.create(vs.realname,hdef);
-                   abssym.fileinfo:=vs.fileinfo;
-                   abssym.abstyp:=toaddr;
-                   abssym.addroffset:=tordconstnode(pt).value;
-{$ifdef i386}
-                   abssym.absseg:=false;
-                   if (target_info.system in [system_i386_go32v2,system_i386_watcom]) and
-                      try_to_consume(_COLON) then
-                    begin
-                      pt.free;
-                      pt:=expr;
-                      if is_constintnode(pt) then
-                        begin
-                          abssym.addroffset:=abssym.addroffset shl 4+tordconstnode(pt).value;
-                          abssym.absseg:=true;
-                        end
-                      else
-                         Message(type_e_ordinal_expr_expected);
-                    end;
-{$endif i386}
-                   HideSym(vs);
-                   vs.owner.Insert(abssym);
-                 end
-                { variable }
-                else
-                  begin
-                    { remove subscriptn before checking for loadn }
-                    hp:=pt;
-                    while (hp.nodetype in [subscriptn,typeconvn,vecn]) do
-                      hp:=tunarynode(hp).left;
-                    if (hp.nodetype=loadn) then
-                     begin
-                       { we should check the result type of loadn }
-                       if not (tloadnode(hp).symtableentry.typ in [fieldvarsym,globalvarsym,localvarsym,
-                                                                   paravarsym,typedconstsym]) then
-                         Message(parser_e_absolute_only_to_var_or_const);
-                       abssym:=tabsolutevarsym.create(vs.realname,hdef);
-                       abssym.fileinfo:=vs.fileinfo;
-                       abssym.abstyp:=tovar;
-                       abssym.ref:=node_to_propaccesslist(pt);
-                       Hidesym(vs);
-                       vs.owner.insert(abssym);
-                     end
-                    else
-                     Message(parser_e_absolute_only_to_var_or_const);
-                  end;
-                if assigned(abssym) then
-                 begin
-                   { try to consume the hint directives with absolute symbols }
-                   hintsymoptions:=[];
-                   try_consume_hintdirective(hintsymoptions);
-                   abssym.symoptions := abssym.symoptions + hintsymoptions;
-                 end;
-                pt.free;
-                symdone:=true;
-              end;
+             if try_to_consume(_ABSOLUTE) then
+               read_absolute(sc);
 
              { try to parse the hint directives }
              hintsymoptions:=[];
              try_consume_hintdirective(hintsymoptions);
+             for i:=0 to sc.count-1 do
+               begin
+                 vs:=tabstractvarsym(sc[i]);
+                 vs.symoptions := vs.symoptions + hintsymoptions;
+               end;
 
              { Handling of Delphi typed const = initialized vars }
              if (token=_EQUAL) and
@@ -903,11 +1012,8 @@ implementation
                  if (hdef.typ=procvardef) and
                     (hdef.typesym=nil) then
                    handle_calling_convention(tprocvardef(hdef));
-                 read_default_value(sc,hdef,vd_threadvar in options);
+                 read_default_value(sc);
                  consume(_SEMICOLON);
-                 { for locals we've created typedconstsym with a different name }
-                 if symtablestack.top.symtabletype<>localsymtable then
-                   symdone:=true;
                  hasdefaultvalue:=true;
                end
              else
@@ -930,163 +1036,37 @@ implementation
                     not(m_tp7 in current_settings.modeswitches) and
                     (symtablestack.top.symtabletype<>parasymtable) then
                    begin
-                     read_default_value(sc,hdef,vd_threadvar in options);
+                     read_default_value(sc);
                      consume(_SEMICOLON);
-                     symdone:=true;
                      hasdefaultvalue:=true;
                    end;
                end;
 
              { Check for EXTERNAL etc directives or, in macpas, if cs_external_var is set}
-             if not symdone then
-              begin
-                if (
-                     (token=_ID) and
-                     (m_cvar_support in current_settings.modeswitches) and
-                     (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR])
-                   ) or
-                   (
-                     (m_mac in current_settings.modeswitches) and
-                     ((cs_external_var in current_settings.localswitches) or (cs_externally_visible in current_settings.localswitches))
-                   ) then
-                 begin
-                   { only allowed for one var }
-                   vs:=tabstractvarsym(sc[0]);
-                   if sc.count>1 then
-                     Message(parser_e_absolute_only_one_var);
-                   { set type of the var }
-                   vs.vardef:=hdef;
-                   vs.symoptions := vs.symoptions + hintsymoptions;
-                   { defaults }
-                   is_dll:=false;
-                   is_cdecl:=false;
-                   extern_var:=false;
-                   export_var:=false;
-                   C_name:=sorg;
-                   semicolonatend:= false;
-                   { cdecl }
-                   if try_to_consume(_CVAR) then
-                    begin
-                      consume(_SEMICOLON);
-                      is_cdecl:=true;
-                      C_name:=target_info.Cprefix+sorg;
-                    end;
-                   { external }
-                   if try_to_consume(_EXTERNAL) then
-                    begin
-                      extern_var:=true;
-                      semicolonatend:= true;
-                    end;
-                   { macpas specific handling due to some switches}
-                   if (m_mac in current_settings.modeswitches) then
-                     begin
-                       if (cs_external_var in current_settings.localswitches) then
-                         begin {The effect of this is the same as if cvar; external; has been given as directives.}
-                           is_cdecl:=true;
-                           C_name:=target_info.Cprefix+sorg;
-                           extern_var:=true;
-                         end
-                       else if (cs_externally_visible in current_settings.localswitches) then
-                         begin {The effect of this is the same as if cvar has been given as directives.}
-                           is_cdecl:=true;
-                           C_name:=target_info.Cprefix+sorg;
-                         end;
-                       vs.varregable := vr_none;
-                     end;
-                   { export }
-                   if idtoken in [_EXPORT,_PUBLIC] then
-                    begin
-                      consume(_ID);
-                      if extern_var then
-                       Message(parser_e_not_external_and_export)
-                      else
-                       begin
-                         export_var:=true;
-                         semicolonatend:= true;
-                       end;
-                    end;
-                   { external and export need a name after when no cdecl is used }
-                   if not is_cdecl then
-                    begin
-                      { dll name ? }
-                      if (extern_var) and (idtoken<>_NAME) then
-                       begin
-                         is_dll:=true;
-                         dll_name:=get_stringconst;
-                         if ExtractFileExt(dll_name)='' then
-                           dll_name:=ChangeFileExt(dll_name,target_info.sharedlibext);
-                       end;
-                      if try_to_consume(_NAME) then
-                        C_name:=get_stringconst
-                      else
-                        C_name:=sorg;
-                    end;
-                   { consume the ; when export or external is used }
-                   if semicolonatend then
-                    consume(_SEMICOLON);
-
-                   { set some vars options }
-                   if is_dll then
-                     begin
-                       { Windows uses an indirect reference using import tables }
-                       if target_info.system in system_all_windows then
-                         include(vs.varoptions,vo_is_dll_var);
-                     end
-                   else
-                     include(vs.varoptions,vo_is_C_var);
-
-                   if (is_dll) and
-                      (target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
-                     C_Name := target_info.Cprefix+C_Name;
-
-                   if export_var then
-                    begin
-                      inc(vs.refs);
-                      include(vs.varoptions,vo_is_exported);
-                    end;
-
-                   if extern_var then
-                    include(vs.varoptions,vo_is_external);
-
-                   if vs.typ=globalvarsym then
-                     begin
-                       tglobalvarsym(vs).set_mangledname(C_Name);
-                       { insert in the al_globals when it is not external }
-                       if (not extern_var) then
-                         insertbssdata(tglobalvarsym(vs));
-                       { now we can insert it in the import lib if its a dll, or
-                         add it to the externals }
-                       if extern_var then
-                        begin
-                          vs.varregable := vr_none;
-                          if is_dll then
-                            current_module.AddExternalImport(dll_name,C_Name,0,true)
-                          else
-                            if tf_has_dllscanner in target_info.flags then
-                              current_module.dllscannerinputlist.Add(vs.mangledname,vs);
-                        end;
-                     end
-                   else
-                     Message(parser_e_no_local_var_external);
-                   symdone:=true;
-                 end;
-              end;
-
-             { insert it in the symtable, if not done yet }
-             if not symdone then
+             if (not hasdefaultvalue) and
+                (
+                 (
+                  (idtoken in [_EXPORT,_EXTERNAL,_PUBLIC,_CVAR]) and
+                  (m_cvar_support in current_settings.modeswitches)
+                 ) or
+                 (
+                  (m_mac in current_settings.modeswitches) and
+                  (
+                   (cs_external_var in current_settings.localswitches) or
+                   (cs_externally_visible in current_settings.localswitches)
+                  )
+                 )
+                ) then
+               read_public_and_external(sc);
+
+             { allocate normal variable (non-external and non-typed-const) staticvarsyms }
+             for i:=0 to sc.count-1 do
                begin
-                 for i:=0 to sc.count-1 do
-                   begin
-                     vs:=tabstractvarsym(sc[i]);
-                     vs.vardef:=hdef;
-                     { insert any additional hint directives }
-                     vs.symoptions := vs.symoptions + hintsymoptions;
-                     if vd_threadvar in options then
-                       include(vs.varoptions,vo_is_thread_var);
-                     { static data fields are inserted in the globalsymtable }
-                     if vs.typ=globalvarsym then
-                       insertbssdata(tglobalvarsym(vs));
-                   end;
+                 vs:=tabstractvarsym(sc[i]);
+                 if (vs.typ=staticvarsym) and
+                    not(vo_is_typed_const in vs.varoptions) and
+                    not(vo_is_external in vs.varoptions) then
+                   insertbssdata(tstaticvarsym(vs));
                end;
            end;
          block_type:=old_block_type;
@@ -1112,7 +1092,7 @@ implementation
          maxpadalign, startpadalign: shortint;
          pt : tnode;
          fieldvs   : tfieldvarsym;
-         hstaticvs : tglobalvarsym;
+         hstaticvs : tstaticvarsym;
          vs    : tabstractvarsym;
          srsym : tsym;
          srsymtable : TSymtable;
@@ -1120,7 +1100,6 @@ implementation
          unionsymtable : trecordsymtable;
          offset : longint;
          uniondef : trecorddef;
-//         unionsym : tfieldvarsym;
          hintsymoptions : tsymoptions;
          semicoloneaten: boolean;
 {$ifdef powerpc}
@@ -1214,6 +1193,15 @@ implementation
              hintsymoptions:=[];
              try_consume_hintdirective(hintsymoptions);
 
+             { update variable type and hints }
+             for i:=0 to sc.count-1 do
+               begin
+                 fieldvs:=tfieldvarsym(sc[i]);
+                 fieldvs.vardef:=hdef;
+                 { insert any additional hint directives }
+                 fieldvs.symoptions := fieldvs.symoptions + hintsymoptions;
+               end;
+
              { Records and objects can't have default values }
              { for a record there doesn't need to be a ; before the END or )    }
              if not(token in [_END,_RKLAMMER]) and
@@ -1233,7 +1221,15 @@ implementation
                 (cs_static_keyword in current_settings.moduleswitches) and
                 (try_to_consume(_STATIC)) then
                begin
-                 include(current_object_option,sp_static);
+                 { add static flag and staticvarsyms }
+                 for i:=0 to sc.count-1 do
+                   begin
+                     fieldvs:=tfieldvarsym(sc[i]);
+                     include(fieldvs.symoptions,sp_static);
+                     hstaticvs:=tstaticvarsym.create('$'+lower(symtablestack.top.name^)+'_'+fieldvs.name,vs_value,hdef,[]);
+                     recst.defowner.owner.insert(hstaticvs);
+                     insertbssdata(hstaticvs);
+                   end;
                  consume(_SEMICOLON);
                end;
 
@@ -1258,23 +1254,12 @@ implementation
                  exclude(current_object_option,sp_published);
                end;
 
-             { update variable options }
+             { Generate field in the recordsymtable }
              for i:=0 to sc.count-1 do
                begin
                  fieldvs:=tfieldvarsym(sc[i]);
-                 fieldvs.vardef:=hdef;
-                 { insert any additional hint directives }
-                 fieldvs.symoptions := fieldvs.symoptions + hintsymoptions;
-                 if (sp_static in current_object_option) then
-                   include(fieldvs.symoptions,sp_static);
-                 { static data fields are inserted in the globalsymtable }
-                 if (sp_static in current_object_option) then
-                   begin
-                      hstaticvs:=tglobalvarsym.create('$'+lower(symtablestack.top.name^)+'_'+fieldvs.name,vs_value,hdef,[]);
-                      recst.defowner.owner.insert(hstaticvs);
-                      insertbssdata(hstaticvs);
-                   end
-                 else
+                 { static data fields are already inserted in the globalsymtable }
+                 if not(sp_static in current_object_option) then
                    recst.addfield(fieldvs);
                end;
 
@@ -1361,7 +1346,6 @@ implementation
               { at last set the record size to that of the biggest variant }
               unionsymtable.datasize:=maxsize;
               unionsymtable.fieldalignment:=maxalignment;
-//              UnionSym:=tfieldvarsym.create('$case',vs_value,uniondef,[]);
               unionsymtable.addalignmentpadding;
 {$ifdef powerpc}
               { parent inherits the alignment padding if the variant is the first "field" of the parent record/variant }
@@ -1384,7 +1368,6 @@ implementation
                 recst.fieldalignment:=unionsymtable.recordalignment;
 
               trecordsymtable(recst).insertunionst(Unionsymtable,offset);
-//              unionsym.free;
               uniondef.free;
            end;
          block_type:=old_block_type;

+ 2 - 4
compiler/pexports.pas

@@ -91,10 +91,8 @@ implementation
                 hp.sym:=srsym;
                 InternalProcName:='';
                 case srsym.typ of
-                  globalvarsym :
-                    InternalProcName:=tglobalvarsym(srsym).mangledname;
-                  typedconstsym :
-                    InternalProcName:=ttypedconstsym(srsym).mangledname;
+                  staticvarsym :
+                    InternalProcName:=tstaticvarsym(srsym).mangledname;
                   procsym :
                     begin
                       pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);

+ 1 - 6
compiler/pexpr.pas

@@ -1429,7 +1429,7 @@ implementation
                       p1:=cloadnode.create(srsym,srsymtable);
                   end;
 
-                globalvarsym,
+                staticvarsym,
                 localvarsym,
                 paravarsym,
                 fieldvarsym :
@@ -1469,11 +1469,6 @@ implementation
                     end;
                   end;
 
-                typedconstsym :
-                  begin
-                    p1:=cloadnode.create(srsym,srsymtable);
-                  end;
-
                 syssym :
                   begin
                     p1:=statement_syssym(tsyssym(srsym).number);

+ 103 - 83
compiler/pmodules.pas

@@ -184,13 +184,13 @@ implementation
         ltvTable : TAsmList;
       begin
         ltvTable:=TAsmList(arg);
-        if (tsym(p).typ=globalvarsym) and
-           (vo_is_thread_var in tglobalvarsym(p).varoptions) then
+        if (tsym(p).typ=staticvarsym) and
+           (vo_is_thread_var in tstaticvarsym(p).varoptions) then
          begin
            { address of threadvar }
-           ltvTable.concat(tai_const.Createname(tglobalvarsym(p).mangledname,0));
+           ltvTable.concat(tai_const.Createname(tstaticvarsym(p).mangledname,0));
            { size of threadvar }
-           ltvTable.concat(tai_const.create_32bit(tglobalvarsym(p).getsize));
+           ltvTable.concat(tai_const.create_32bit(tstaticvarsym(p).getsize));
          end;
       end;
 
@@ -712,7 +712,7 @@ implementation
       end;
 
 
-    function create_main_proc(const name:string;potype:tproctypeoption;st:TSymtable):tprocdef;
+    function create_main_proc(const name:string;potype:tproctypeoption;st:TSymtable):tcgprocinfo;
       var
         ps  : tprocsym;
         pd  : tprocdef;
@@ -741,35 +741,25 @@ implementation
         pd.localst.free;
         pd.localst:=st;
         { set procinfo and current_procinfo.procdef }
-        current_procinfo:=cprocinfo.create(nil);
-        current_module.procinfo:=current_procinfo;
-        current_procinfo.procdef:=pd;
-        { return procdef }
-        create_main_proc:=pd;
+        result:=tcgprocinfo(cprocinfo.create(nil));
+        result.procdef:=pd;
         { main proc does always a call e.g. to init system unit }
-        include(current_procinfo.flags,pi_do_call);
+        include(result.flags,pi_do_call);
       end;
 
 
-    procedure release_main_proc(pd:tprocdef);
+    procedure release_main_proc(pi:tcgprocinfo);
       begin
-        { this is a main proc, so there should be no parent }
-        if not(assigned(current_procinfo)) or
-           assigned(current_procinfo.parent) or
-           not(current_procinfo.procdef=pd) then
-         internalerror(200304276);
+        { remove localst as it was replaced by staticsymtable }
+        pi.procdef.localst:=nil;
         { remove procinfo }
         current_module.procinfo:=nil;
-        current_procinfo.free;
-        current_procinfo:=nil;
-        { remove localst as it was replaced by staticsymtable }
-        pd.localst:=nil;
+        pi.free;
+        pi:=nil;
       end;
 
 
-    procedure gen_implicit_initfinal(flag:word;st:TSymtable);
-      var
-        pd : tprocdef;
+    function gen_implicit_initfinal(flag:word;st:TSymtable):tcgprocinfo;
       begin
         { update module flags }
         current_module.flags:=current_module.flags or flag;
@@ -777,20 +767,18 @@ implementation
         case flag of
           uf_init :
             begin
-              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'init_implicit'),potype_unitinit,st);
-              pd.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
+              result:=create_main_proc(make_mangledname('',current_module.localsymtable,'init_implicit'),potype_unitinit,st);
+              result.procdef.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
             end;
           uf_finalize :
             begin
-              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize_implicit'),potype_unitfinalize,st);
-              pd.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
+              result:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize_implicit'),potype_unitfinalize,st);
+              result.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
             end;
           else
             internalerror(200304253);
         end;
-        tcgprocinfo(current_procinfo).code:=cnothingnode.create;
-        tcgprocinfo(current_procinfo).generate_code;
-        release_main_proc(pd);
+        result.code:=cnothingnode.create;
       end;
 
 
@@ -826,13 +814,17 @@ implementation
          store_interface_crc : cardinal;
          s1,s2  : ^string; {Saves stack space}
          force_init_final : boolean;
-         pd : tprocdef;
+         init_procinfo,
+         finalize_procinfo : tcgprocinfo;
          unitname8 : string[8];
          has_impl,ag: boolean;
 {$ifdef i386}
-         globalvarsym : tglobalvarsym;
+         gotvarsym : tstaticvarsym;
 {$endif i386}
       begin
+         init_procinfo:=nil;
+         finalize_procinfo:=nil;
+
          if m_mac in current_settings.modeswitches then
            current_module.mode_switch_allowed:= false;
 
@@ -916,9 +908,6 @@ implementation
          { load default units, like the system unit }
          loaddefaultunits;
 
-         { reset }
-         make_ref:=true;
-
          { insert qualifier for the system unit (allows system.writeln) }
          if not(cs_compilesystem in current_settings.moduleswitches) and
             (token=_USES) then
@@ -988,12 +977,12 @@ implementation
          if cs_create_pic in current_settings.moduleswitches then
            begin
              { insert symbol for got access in assembler code}
-             globalvarsym:=tglobalvarsym.create('_GLOBAL_OFFSET_TABLE_',vs_value,voidpointertype,[vo_is_external,vo_is_C_var]);
-             globalvarsym.set_mangledname('_GLOBAL_OFFSET_TABLE_');
-             current_module.localsymtable.insert(globalvarsym);
+             gotvarsym:=tstaticvarsym.create('_GLOBAL_OFFSET_TABLE_',vs_value,voidpointertype,[vo_is_external]);
+             gotvarsym.set_mangledname('_GLOBAL_OFFSET_TABLE_');
+             current_module.localsymtable.insert(gotvarsym);
              { avoid unnecessary warnings }
-             globalvarsym.varstate:=vs_read;
-             globalvarsym.refs:=1;
+             gotvarsym.varstate:=vs_read;
+             gotvarsym.refs:=1;
            end;
 {$endif i386}
 
@@ -1024,14 +1013,11 @@ implementation
                internalerror(200212285);
 
              { Compile the unit }
-             pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'init'),potype_unitinit,current_module.localsymtable);
-             pd.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
-             tcgprocinfo(current_procinfo).parse_body;
-             tcgprocinfo(current_procinfo).generate_code;
-             tcgprocinfo(current_procinfo).resetprocdef;
+             init_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'init'),potype_unitinit,current_module.localsymtable);
+             init_procinfo.procdef.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
+             init_procinfo.parse_body;
              { save file pos for debuginfo }
-             current_module.mainfilepos:=current_procinfo.entrypos;
-             release_main_proc(pd);
+             current_module.mainfilepos:=init_procinfo.entrypos;
            end;
 
          { Generate specializations of objectdefs methods }
@@ -1045,7 +1031,12 @@ implementation
          { should we force unit initialization? }
          { this is a hack, but how can it be done better ? }
          if force_init_final and ((current_module.flags and uf_init)=0) then
-           gen_implicit_initfinal(uf_init,current_module.localsymtable);
+           begin
+             { first release the not used init procinfo }
+             if assigned(init_procinfo) then
+               release_main_proc(init_procinfo);
+             init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable);
+           end;
          { finalize? }
          if has_impl and (token=_FINALIZATION) then
            begin
@@ -1053,15 +1044,29 @@ implementation
               current_module.flags:=current_module.flags or uf_finalize;
 
               { Compile the finalize }
-              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
-              pd.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
-              tcgprocinfo(current_procinfo).parse_body;
-              tcgprocinfo(current_procinfo).generate_code;
-              tcgprocinfo(current_procinfo).resetprocdef;
-              release_main_proc(pd);
+              finalize_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
+              finalize_procinfo.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
+              finalize_procinfo.parse_body;
            end
          else if force_init_final then
-           gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
+           finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
+
+         { Now both init and finalize bodies are read and it is known
+           which variables are used in both init and finalize we can now
+           generate the code. This is required to prevent putting a variable in
+           a register that is also used in the finalize body (PFV) }
+         if assigned(init_procinfo) then
+           begin
+             init_procinfo.generate_code;
+             init_procinfo.resetprocdef;
+             release_main_proc(init_procinfo);
+           end;
+         if assigned(finalize_procinfo) then
+           begin
+             finalize_procinfo.generate_code;
+             finalize_procinfo.resetprocdef;
+             release_main_proc(finalize_procinfo);
+           end;
 
          symtablestack.pop(current_module.localsymtable);
          symtablestack.pop(current_module.globalsymtable);
@@ -1180,12 +1185,18 @@ implementation
       var
          main_file : tinputfile;
          hp,hp2    : tmodule;
-         pd        : tprocdef;
+         finalize_procinfo,
+         init_procinfo,
+         main_procinfo : tcgprocinfo;
+         force_init_final : boolean;
       begin
          DLLsource:=islibrary;
          Status.IsLibrary:=IsLibrary;
          Status.IsExe:=true;
          parse_only:=false;
+         main_procinfo:=nil;
+         init_procinfo:=nil;
+         finalize_procinfo:=nil;
 
          { DLL defaults to create reloc info }
          if islibrary then
@@ -1301,40 +1312,33 @@ implementation
            from the bootstrap code.}
          if islibrary then
           begin
-            pd:=create_main_proc(make_mangledname('',current_module.localsymtable,mainaliasname),potype_proginit,current_module.localsymtable);
+            main_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,mainaliasname),potype_proginit,current_module.localsymtable);
             { Win32 startup code needs a single name }
             if not(target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
-              pd.aliasnames.insert('PASCALMAIN')
+              main_procinfo.procdef.aliasnames.insert('PASCALMAIN')
             else
-              pd.aliasnames.insert(target_info.Cprefix+'PASCALMAIN')
+              main_procinfo.procdef.aliasnames.insert(target_info.Cprefix+'PASCALMAIN')
           end
          else if (target_info.system in [system_i386_netware,system_i386_netwlibc,system_powerpc_macos,system_powerpc_darwin,system_i386_darwin]) then
            begin
-             pd:=create_main_proc('PASCALMAIN',potype_proginit,current_module.localsymtable);
+             main_procinfo:=create_main_proc('PASCALMAIN',potype_proginit,current_module.localsymtable);
            end
          else
            begin
-             pd:=create_main_proc(mainaliasname,potype_proginit,current_module.localsymtable);
-             pd.aliasnames.insert('PASCALMAIN');
+             main_procinfo:=create_main_proc(mainaliasname,potype_proginit,current_module.localsymtable);
+             main_procinfo.procdef.aliasnames.insert('PASCALMAIN');
            end;
-         tcgprocinfo(current_procinfo).parse_body;
-         tcgprocinfo(current_procinfo).generate_code;
-         tcgprocinfo(current_procinfo).resetprocdef;
+         main_procinfo.parse_body;
          { save file pos for debuginfo }
-         current_module.mainfilepos:=current_procinfo.entrypos;
-         release_main_proc(pd);
+         current_module.mainfilepos:=main_procinfo.entrypos;
 
          { Generate specializations of objectdefs methods }
          generate_specialization_procs;
 
          { should we force unit initialization? }
-         if tstaticsymtable(current_module.localsymtable).needs_init_final then
-           begin
-              { initialize section }
-              gen_implicit_initfinal(uf_init,current_module.localsymtable);
-              { finalize section }
-              gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
-           end;
+         force_init_final:=tstaticsymtable(current_module.localsymtable).needs_init_final;
+         if force_init_final then
+           init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable);
 
          { Add symbol to the exports section for win32 so smartlinking a
            DLL will include the edata section }
@@ -1348,14 +1352,30 @@ implementation
            begin
               { set module options }
               current_module.flags:=current_module.flags or uf_finalize;
-
-              { Compile the finalize }
-              pd:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
-              pd.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
-              tcgprocinfo(current_procinfo).parse_body;
-              tcgprocinfo(current_procinfo).generate_code;
-              tcgprocinfo(current_procinfo).resetprocdef;
-              release_main_proc(pd);
+              { Parse the finalize }
+              finalize_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
+              finalize_procinfo.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
+              finalize_procinfo.parse_body;
+           end
+         else
+           if force_init_final then
+             finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
+
+         { See remark in unit init/final }
+         main_procinfo.generate_code;
+         main_procinfo.resetprocdef;
+         release_main_proc(main_procinfo);
+         if assigned(init_procinfo) then
+           begin
+             init_procinfo.generate_code;
+             init_procinfo.resetprocdef;
+             release_main_proc(init_procinfo);
+           end;
+         if assigned(finalize_procinfo) then
+           begin
+             finalize_procinfo.generate_code;
+             finalize_procinfo.resetprocdef;
+             release_main_proc(finalize_procinfo);
            end;
 
          symtablestack.pop(current_module.localsymtable);

+ 2 - 1
compiler/powerpc/cpupi.pas

@@ -89,7 +89,8 @@ unit cpupi;
           end
         else
           begin
-            if tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals <> 0 then
+            if (current_procinfo.procdef.localst.symtabletype=localsymtable) and
+               (tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals <> 0) then
               begin
                 { at 0(r1), the previous value of r1 will be stored }
                 tg.setfirsttemp(4);

+ 1 - 1
compiler/powerpc/nppccal.pas

@@ -88,7 +88,7 @@ implementation
                   cg.getcpuregister(current_asmdata.CurrAsmList,NR_R12);
 
                   reference_reset(tmpref);
-                  tmpref.symbol:=current_asmdata.RefAsmSymbol(tglobalvarsym(tprocdef(procdefinition).libsym).mangledname);
+                  tmpref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(tprocdef(procdefinition).libsym).mangledname);
                   tmpref.refaddr:=addr_hi;
                   current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref(A_LIS,NR_R12,tmpref));
                   tmpref.base:=NR_R12;

+ 2 - 1
compiler/powerpc64/cpupi.pas

@@ -77,7 +77,8 @@ begin
     end;
     tg.setfirsttemp(ofs);
   end else begin
-    if tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals <> 0 then
+    if (current_procinfo.procdef.localst.symtabletype=localsymtable) and
+       (tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals <> 0) then
       { at 0(r1), the previous value of r1 will be stored }
       tg.setfirsttemp(8);
   end;

+ 2 - 2
compiler/ppu.pas

@@ -87,10 +87,10 @@ const
   {syms}
   ibtypesym        = 20;
   ibprocsym        = 21;
-  ibglobalvarsym   = 22;
+  ibstaticvarsym   = 22;
   ibconstsym       = 23;
   ibenumsym        = 24;
-  ibtypedconstsym  = 25;
+//  ibtypedconstsym  = 25;
   ibabsolutevarsym = 26;
   ibpropertysym    = 27;
   ibfieldvarsym    = 28;

+ 18 - 16
compiler/pstatmnt.pas

@@ -355,20 +355,22 @@ implementation
             (hp.nodetype=loadn) then
            begin
              case tloadnode(hp).symtableentry.typ of
-               globalvarsym,
+               staticvarsym,
                localvarsym,
                paravarsym :
                  begin
-                   { we need a simple loadn and the load must be in a global symtable or
-                     in the same level as the para of the current proc }
+                   { we need a simple loadn:
+                       1. The load must be in a global symtable or
+                           in the same level as the para of the current proc.
+                       2. value variables (no const,out or var)
+                       3. No threadvar, readonly or typedconst
+                   }
                    if (
                        (tloadnode(hp).symtable.symtablelevel=main_program_level) or
                        (tloadnode(hp).symtable.symtablelevel=current_procinfo.procdef.parast.symtablelevel)
                       ) and
-                      not(
-                          ((tabstractvarsym(tloadnode(hp).symtableentry).varspez in [vs_var,vs_out]) or
-                           (vo_is_thread_var in tabstractvarsym(tloadnode(hp).symtableentry).varoptions))
-                         ) then
+                      (tabstractvarsym(tloadnode(hp).symtableentry).varspez=vs_value) and
+                      ([vo_is_thread_var,vo_is_typed_const] * tabstractvarsym(tloadnode(hp).symtableentry).varoptions=[]) then
                      begin
                        { Assigning for-loop variable is only allowed in tp7 and macpas }
                        if ([m_tp7,m_mac] * current_settings.modeswitches = []) then
@@ -379,13 +381,12 @@ implementation
                          end;
                      end
                    else
-                     MessagePos(hp.fileinfo,type_e_illegal_count_var);
-                 end;
-               typedconstsym :
-                 begin
-                   { Bad programming, only allowed in tp7 mode }
-                   if not(m_tp7 in current_settings.modeswitches) then
-                     MessagePos(hp.fileinfo,type_e_illegal_count_var);
+                     begin
+                       { Typed const is allowed in tp7 }
+                       if not(m_tp7 in current_settings.modeswitches) or
+                          not(vo_is_typed_const in tabstractvarsym(tloadnode(hp).symtableentry).varoptions) then
+                         MessagePos(hp.fileinfo,type_e_illegal_count_var);
+                     end;
                  end;
                else
                  MessagePos(hp.fileinfo,type_e_illegal_count_var);
@@ -1168,8 +1169,9 @@ implementation
                - target processor has optional frame pointer save
                  (vm, i386, vm only currently)
              }
-             locals:=tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals+
-                     tabstractlocalsymtable(current_procinfo.procdef.parast).count_locals;
+             locals:=tabstractlocalsymtable(current_procinfo.procdef.parast).count_locals;
+             if (current_procinfo.procdef.localst.symtabletype=localsymtable) then
+               inc(locals,tabstractlocalsymtable(current_procinfo.procdef.localst).count_locals);
              if (locals=0) and
                 (current_procinfo.procdef.owner.symtabletype<>ObjectSymtable) and
                 (not assigned(current_procinfo.procdef.funcretsym) or

+ 3 - 3
compiler/psub.pas

@@ -122,7 +122,7 @@ implementation
       var
         b : tblocknode;
       begin
-        if not (tsym(p).typ in [localvarsym,globalvarsym]) then
+        if not (tsym(p).typ in [localvarsym,staticvarsym]) then
          exit;
         with tabstractnormalvarsym(p) do
          begin
@@ -602,7 +602,7 @@ implementation
 
     procedure clearrefs(p:TObject;arg:pointer);
       begin
-         if (tsym(p).typ in [localvarsym,paravarsym,globalvarsym]) then
+         if (tsym(p).typ in [localvarsym,paravarsym,staticvarsym]) then
            if tabstractvarsym(p).refs>1 then
              tabstractvarsym(p).refs:=1;
       end;
@@ -610,7 +610,7 @@ implementation
 
     procedure translate_registers(p:TObject;list:pointer);
       begin
-         if (tsym(p).typ in [localvarsym,paravarsym,globalvarsym]) and
+         if (tsym(p).typ in [localvarsym,paravarsym,staticvarsym]) and
             (tabstractnormalvarsym(p).localloc.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_MMREGISTER,
               LOC_CMMREGISTER,LOC_FPUREGISTER,LOC_CFPUREGISTER]) then
            begin

+ 977 - 950
compiler/ptconst.pas

@@ -27,10 +27,8 @@ interface
 
    uses symtype,symsym,aasmdata;
 
-    { this procedure reads typed constants }
-    { sym is only needed for ansi strings  }
-    { the assembler label is in the middle (PM) }
-    procedure readtypedconst(list:tasmlist;def:tdef;sym : ttypedconstsym;writable : boolean);
+    procedure read_typed_const(list:tasmlist;sym:tstaticvarsym);
+
 
 implementation
 
@@ -52,1031 +50,1060 @@ implementation
 {$maxfpuregisters 0}
 
     { this procedure reads typed constants }
-    procedure readtypedconst(list:tasmlist;def:tdef;sym : ttypedconstsym;writable : boolean);
-      label
-         myexit;
-      type
-         setbytes = array[0..31] of byte;
-         Psetbytes = ^setbytes;
-      var
-         len,base  : longint;
-         p,hp      : tnode;
-         i,j,l     : longint;
-         varalign  : shortint;
-         offset,
-         strlength : aint;
-         ll        : tasmlabel;
-         c_name,
-         s,sorg    : string;
-         c         : char;
-         ca        : pchar;
-         tmpguid   : tguid;
-         symidx,
-         aktpos    : longint;
-         pd        : tprocdef;
-         obj       : tobjectdef;
-         recsym,
-         srsym     : tsym;
-         symt      : TSymtable;
-         value     : bestreal;
-         intvalue  : tconstexprint;
-         strval    : pchar;
-         pw        : pcompilerwidestring;
-         error     : boolean;
-         old_block_type : tblock_type;
-         storefilepos : tfileposinfo;
-         cursectype : TAsmSectiontype;
-         datalist : tasmlist;
+    procedure read_typed_const_data(list:tasmlist;def:tdef);
 
-         procedure check_range(def:torddef);
-           begin
-              if ((tordconstnode(p).value>def.high) or
-                  (tordconstnode(p).value<def.low)) then
+        procedure parse_orddef(list:tasmlist;def:torddef);
+        var
+          n : tnode;
+          intvalue : tconstexprint;
+        begin
+           n:=comp_expr(true);
+           case def.ordtype of
+              bool8bit :
                 begin
-                   if (cs_check_range in current_settings.localswitches) then
-                     Message(parser_e_range_check_error)
+                   if is_constboolnode(n) then
+                     list.concat(Tai_const.Create_8bit(byte(tordconstnode(n).value)))
                    else
-                     Message(parser_w_range_check_error);
+                     Message(parser_e_illegal_expression);
                 end;
-           end;
-
-      begin
-         old_block_type:=block_type;
-         block_type:=bt_const;
-         datalist:=tasmlist.create;
-
-         case def.typ of
-            orddef:
-              begin
-                 p:=comp_expr(true);
-                 case torddef(def).ordtype of
-                    bool8bit :
-                      begin
-                         if is_constboolnode(p) then
-                           datalist.concat(Tai_const.Create_8bit(byte(tordconstnode(p).value)))
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    bool16bit :
-                      begin
-                         if is_constboolnode(p) then
-                           datalist.concat(Tai_const.Create_16bit(word(tordconstnode(p).value)))
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    bool32bit :
-                      begin
-                         if is_constboolnode(p) then
-                           datalist.concat(Tai_const.Create_32bit(longint(tordconstnode(p).value)))
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    bool64bit :
-                      begin
-                         if is_constboolnode(p) then
-                           datalist.concat(Tai_const.Create_64bit(int64(tordconstnode(p).value)))
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    uchar :
-                      begin
-                         if is_constcharnode(p) then
-                           datalist.concat(Tai_const.Create_8bit(byte(tordconstnode(p).value)))
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    uwidechar :
-                      begin
-                         if is_constcharnode(p) then
-                           inserttypeconv(p,cwidechartype);
-                         if is_constwidecharnode(p) then
-                           datalist.concat(Tai_const.Create_16bit(word(tordconstnode(p).value)))
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    s8bit,
-                    u8bit :
-                      begin
-                         if is_constintnode(p) then
-                           begin
-                              datalist.concat(Tai_const.Create_8bit(byte(tordconstnode(p).value)));
-                              check_range(torddef(def));
-                           end
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    u16bit,
-                    s16bit :
-                      begin
-                         if is_constintnode(p) then
-                           begin
-                             datalist.concat(Tai_const.Create_16bit(word(tordconstnode(p).value)));
-                             check_range(torddef(def));
-                           end
-                         else
-                           Message(parser_e_illegal_expression);
+              bool16bit :
+                begin
+                   if is_constboolnode(n) then
+                     list.concat(Tai_const.Create_16bit(word(tordconstnode(n).value)))
+                   else
+                     Message(parser_e_illegal_expression);
+                end;
+              bool32bit :
+                begin
+                   if is_constboolnode(n) then
+                     list.concat(Tai_const.Create_32bit(longint(tordconstnode(n).value)))
+                   else
+                     Message(parser_e_illegal_expression);
+                end;
+              bool64bit :
+                begin
+                   if is_constboolnode(n) then
+                     list.concat(Tai_const.Create_64bit(int64(tordconstnode(n).value)))
+                   else
+                     Message(parser_e_illegal_expression);
+                end;
+              uchar :
+                begin
+                   if is_constcharnode(n) then
+                     list.concat(Tai_const.Create_8bit(byte(tordconstnode(n).value)))
+                   else
+                     Message(parser_e_illegal_expression);
+                end;
+              uwidechar :
+                begin
+                   if is_constcharnode(n) then
+                     inserttypeconv(n,cwidechartype);
+                   if is_constwidecharnode(n) then
+                     list.concat(Tai_const.Create_16bit(word(tordconstnode(n).value)))
+                   else
+                     Message(parser_e_illegal_expression);
+                end;
+              s8bit,u8bit,
+              u16bit,s16bit,
+              s32bit,u32bit,
+              s64bit,u64bit :
+                begin
+                   if is_constintnode(n) then
+                     begin
+                       testrange(def,tordconstnode(n).value,false);
+                       case def.size of
+                         1 :
+                           list.concat(Tai_const.Create_8bit(byte(tordconstnode(n).value)));
+                         2 :
+                           list.concat(Tai_const.Create_16bit(word(tordconstnode(n).value)));
+                         4 :
+                           list.concat(Tai_const.Create_32bit(longint(tordconstnode(n).value)));
+                         8 :
+                           list.concat(Tai_const.Create_64bit(tordconstnode(n).value));
+                       end;
+                     end
+                   else
+                     Message(parser_e_illegal_expression);
+                end;
+              scurrency:
+                begin
+                   if is_constintnode(n) then
+                     intvalue := tordconstnode(n).value
+                   { allow bootstrapping }
+                   else if is_constrealnode(n) then
+                     intvalue:=round(trealconstnode(n).value_real*10000)
+                   else
+                     begin
+                       intvalue:=0;
+                       Message(parser_e_illegal_expression);
                      end;
-                    s32bit,
-                    u32bit :
-                      begin
-                         if is_constintnode(p) then
-                           begin
-                              datalist.concat(Tai_const.Create_32bit(longint(tordconstnode(p).value)));
-                              if torddef(def).ordtype<>u32bit then
-                               check_range(torddef(def));
-                           end
-                         else
-                           Message(parser_e_illegal_expression);
-                      end;
-                    s64bit,
-                    u64bit,
-                    scurrency:
-                      begin
-                         if is_constintnode(p) then
-                           intvalue := tordconstnode(p).value
-                         else if is_constrealnode(p) and
-                                 (torddef(def).ordtype=scurrency)
-                           { allow bootstrapping }
-                           then
-                             begin
-                               intvalue:=round(trealconstnode(p).value_real*10000);
-                             end
-                         else
-                           begin
-                             intvalue:=0;
-                             Message(parser_e_illegal_expression);
-                           end;
-                        datalist.concat(Tai_const.Create_64bit(intvalue));
-                      end;
-                    else
-                      internalerror(3799);
-                 end;
-                 p.free;
-              end;
-         floatdef:
-           begin
-              p:=comp_expr(true);
-              if is_constrealnode(p) then
-                value:=trealconstnode(p).value_real
-              else if is_constintnode(p) then
-                value:=tordconstnode(p).value
+                  list.concat(Tai_const.Create_64bit(intvalue));
+                end;
               else
-                Message(parser_e_illegal_expression);
+                internalerror(200611052);
+           end;
+           n.free;
+        end;
+
+        procedure parse_floatdef(list:tasmlist;def:tfloatdef);
+        var
+          n : tnode;
+          value : bestreal;
+        begin
+          n:=comp_expr(true);
+          if is_constrealnode(n) then
+            value:=trealconstnode(n).value_real
+          else if is_constintnode(n) then
+            value:=tordconstnode(n).value
+          else
+            Message(parser_e_illegal_expression);
 
-              case tfloatdef(def).floattype of
-                 s32real :
-                   datalist.concat(Tai_real_32bit.Create(ts32real(value)));
-                 s64real :
+          case def.floattype of
+             s32real :
+               list.concat(Tai_real_32bit.Create(ts32real(value)));
+             s64real :
 {$ifdef ARM}
-                   if current_settings.fputype in [fpu_fpa,fpu_fpa10,fpu_fpa11] then
-                     datalist.concat(Tai_real_64bit.Create_hiloswapped(ts64real(value)))
-                   else
+               if current_settings.fputype in [fpu_fpa,fpu_fpa10,fpu_fpa11] then
+                 list.concat(Tai_real_64bit.Create_hiloswapped(ts64real(value)))
+               else
 {$endif ARM}
-                     datalist.concat(Tai_real_64bit.Create(ts64real(value)));
-                 s80real :
-                   datalist.concat(Tai_real_80bit.Create(value));
+                 list.concat(Tai_real_64bit.Create(ts64real(value)));
+             s80real :
+               list.concat(Tai_real_80bit.Create(value));
+             s64comp :
+               { the round is necessary for native compilers where comp isn't a float }
+               list.concat(Tai_comp_64bit.Create(round(value)));
+             s64currency:
+               list.concat(Tai_comp_64bit.Create(round(value*10000)));
+             s128real:
+               list.concat(Tai_real_128bit.Create(value));
+             else
+               internalerror(200611053);
+          end;
+          n.free;
+        end;
 
-                 { the round is necessary for native compilers where comp isn't a float }
-                 s64comp :
-                   datalist.concat(Tai_comp_64bit.Create(round(value)));
-                 s64currency:
-                   datalist.concat(Tai_comp_64bit.Create(round(value*10000)));
-                 s128real:
-                   datalist.concat(Tai_real_128bit.Create(value));
-                 else
-                   internalerror(18);
-              end;
-              p.free;
-           end;
-         classrefdef:
-           begin
-              p:=comp_expr(true);
-              case p.nodetype of
-                 loadvmtaddrn:
-                   with Tclassrefdef(p.resultdef) do
-                     begin
-                        if not Tobjectdef(pointeddef).is_related(Tobjectdef(tclassrefdef(def).pointeddef)) then
-                          message(parser_e_illegal_expression);
-                        datalist.concat(Tai_const.Create_sym(current_asmdata.RefAsmSymbol(
-                          Tobjectdef(pointeddef).vmt_mangledname)));
-                     end;
-                 niln:
-                   datalist.concat(Tai_const.Create_sym(nil));
-                 else Message(parser_e_illegal_expression);
+        procedure parse_classrefdef(list:tasmlist;def:tclassrefdef);
+        var
+          n : tnode;
+        begin
+          n:=comp_expr(true);
+          case n.nodetype of
+            loadvmtaddrn:
+              begin
+                if not Tobjectdef(tclassrefdef(n.resultdef).pointeddef).is_related(tobjectdef(def.pointeddef)) then
+                  message(parser_e_illegal_expression);
+                list.concat(Tai_const.Create_sym(current_asmdata.RefAsmSymbol(Tobjectdef(tclassrefdef(n.resultdef).pointeddef).vmt_mangledname)));
               end;
-              p.free;
-           end;
-         pointerdef:
-           begin
-              p:=comp_expr(true);
-              if (p.nodetype=typeconvn) then
-                with Ttypeconvnode(p) do
-                  if (left.nodetype in [addrn,niln]) and equal_defs(def,p.resultdef) then
-                    begin
-                      hp:=left;
-                      left:=nil;
-                      p.free;
-                      p:=hp;
-                    end;
-              { allows horrible ofs(typeof(TButton)^) code !! }
-              if (p.nodetype=addrn) then
-                with Taddrnode(p) do
-                  if left.nodetype=derefn then
-                    begin
-                      hp:=tderefnode(left).left;
-                      tderefnode(left).left:=nil;
-                      p.free;
-                      p:=hp;
-                   end;
-              { const pointer ? }
-              if (p.nodetype = pointerconstn) then
+             niln:
+               list.concat(Tai_const.Create_sym(nil));
+             else
+               Message(parser_e_illegal_expression);
+          end;
+          n.free;
+        end;
+
+        procedure parse_pointerdef(list:tasmlist;def:tpointerdef);
+        var
+          hp,p      : tnode;
+          srsym     : tsym;
+          pd        : tprocdef;
+          ca        : pchar;
+          pw        : pcompilerwidestring;
+          i,len     : longint;
+          base,
+          offset    : aint;
+          ll        : tasmlabel;
+          varalign  : shortint;
+        begin
+          p:=comp_expr(true);
+          { remove equal typecasts for pointer/nil addresses }
+          if (p.nodetype=typeconvn) then
+            with Ttypeconvnode(p) do
+              if (left.nodetype in [addrn,niln]) and equal_defs(def,p.resultdef) then
                 begin
-                  if sizeof(TConstPtrUInt)=8 then
-                    datalist.concat(Tai_const.Create_64bit(TConstPtrUInt(tpointerconstnode(p).value)))
-                  else
-                    if sizeof(TConstPtrUInt)=4 then
-                      datalist.concat(Tai_const.Create_32bit(TConstPtrUInt(tpointerconstnode(p).value)))
-                  else
-                    internalerror(200404122);
-                end
-              { nil pointer ? }
-              else if p.nodetype=niln then
-                datalist.concat(Tai_const.Create_sym(nil))
-              { maybe pchar ? }
+                  hp:=left;
+                  left:=nil;
+                  p.free;
+                  p:=hp;
+                end;
+          { allows horrible ofs(typeof(TButton)^) code !! }
+          if (p.nodetype=addrn) then
+            with Taddrnode(p) do
+              if left.nodetype=derefn then
+                begin
+                  hp:=tderefnode(left).left;
+                  tderefnode(left).left:=nil;
+                  p.free;
+                  p:=hp;
+               end;
+          { const pointer ? }
+          if (p.nodetype = pointerconstn) then
+            begin
+              if sizeof(TConstPtrUInt)=8 then
+                list.concat(Tai_const.Create_64bit(TConstPtrUInt(tpointerconstnode(p).value)))
               else
-                if is_char(tpointerdef(def).pointeddef) and
-                   (p.nodetype<>addrn) then
-                  begin
-                    current_asmdata.getdatalabel(ll);
-                    datalist.concat(Tai_const.Create_sym(ll));
-                    if p.nodetype=stringconstn then
-                     varalign:=size_2_align(tstringconstnode(p).len)
-                    else
-                     varalign:=0;
-                    varalign:=const_align(varalign);
-                    current_asmdata.asmlists[al_const].concat(Tai_align.Create(varalign));
-                    current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
-                    if p.nodetype=stringconstn then
-                      begin
-                        len:=tstringconstnode(p).len;
-                        { For tp7 the maximum lentgh can be 255 }
-                        if (m_tp7 in current_settings.modeswitches) and
-                           (len>255) then
-                         len:=255;
-                        getmem(ca,len+2);
-                        move(tstringconstnode(p).value_str^,ca^,len+1);
-                        current_asmdata.asmlists[al_const].concat(Tai_string.Create_pchar(ca,len+1));
-                      end
-                    else
-                      if is_constcharnode(p) then
-                        current_asmdata.asmlists[al_const].concat(Tai_string.Create(char(byte(tordconstnode(p).value))+#0))
-                    else
-                      message(parser_e_illegal_expression);
-                end
-              { maybe pwidechar ? }
+                if sizeof(TConstPtrUInt)=4 then
+                  list.concat(Tai_const.Create_32bit(TConstPtrUInt(tpointerconstnode(p).value)))
               else
-                if is_widechar(tpointerdef(def).pointeddef) and
-                   (p.nodetype<>addrn) then
+                internalerror(200404122);
+            end
+          { nil pointer ? }
+          else if p.nodetype=niln then
+            list.concat(Tai_const.Create_sym(nil))
+          { maybe pchar ? }
+          else
+            if is_char(def.pointeddef) and
+               (p.nodetype<>addrn) then
+              begin
+                current_asmdata.getdatalabel(ll);
+                list.concat(Tai_const.Create_sym(ll));
+                if p.nodetype=stringconstn then
+                 varalign:=size_2_align(tstringconstnode(p).len)
+                else
+                 varalign:=0;
+                varalign:=const_align(varalign);
+                current_asmdata.asmlists[al_const].concat(Tai_align.Create(varalign));
+                current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
+                if p.nodetype=stringconstn then
                   begin
-                    current_asmdata.getdatalabel(ll);
-                    datalist.concat(Tai_const.Create_sym(ll));
-                    current_asmdata.asmlists[al_typedconsts].concat(tai_align.create(const_align(sizeof(aint))));
-                    current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(ll));
-                    if (p.nodetype in [stringconstn,ordconstn]) then
-                      begin
-                        { convert to widestring stringconstn }
-                        inserttypeconv(p,cwidestringtype);
-                        if (p.nodetype=stringconstn) and
-                           (tstringconstnode(p).cst_type=cst_widestring) then
-                         begin
-                           pw:=pcompilerwidestring(tstringconstnode(p).value_str);
-                           for i:=0 to tstringconstnode(p).len-1 do
-                             current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(pw^.data[i]));
-                           { ending #0 }
-                           current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(0))
-                         end;
-                      end
-                    else
-                      Message(parser_e_illegal_expression);
-                end
-              else
-                if (p.nodetype=addrn) or
-                   is_procvar_load(p) then
+                    len:=tstringconstnode(p).len;
+                    { For tp7 the maximum lentgh can be 255 }
+                    if (m_tp7 in current_settings.modeswitches) and
+                       (len>255) then
+                     len:=255;
+                    getmem(ca,len+2);
+                    move(tstringconstnode(p).value_str^,ca^,len+1);
+                    current_asmdata.asmlists[al_const].concat(Tai_string.Create_pchar(ca,len+1));
+                  end
+                else
+                  if is_constcharnode(p) then
+                    current_asmdata.asmlists[al_const].concat(Tai_string.Create(char(byte(tordconstnode(p).value))+#0))
+                else
+                  message(parser_e_illegal_expression);
+            end
+          { maybe pwidechar ? }
+          else
+            if is_widechar(def.pointeddef) and
+               (p.nodetype<>addrn) then
+              begin
+                current_asmdata.getdatalabel(ll);
+                list.concat(Tai_const.Create_sym(ll));
+                current_asmdata.asmlists[al_typedconsts].concat(tai_align.create(const_align(sizeof(aint))));
+                current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(ll));
+                if (p.nodetype in [stringconstn,ordconstn]) then
+                  begin
+                    { convert to widestring stringconstn }
+                    inserttypeconv(p,cwidestringtype);
+                    if (p.nodetype=stringconstn) and
+                       (tstringconstnode(p).cst_type=cst_widestring) then
+                     begin
+                       pw:=pcompilerwidestring(tstringconstnode(p).value_str);
+                       for i:=0 to tstringconstnode(p).len-1 do
+                         current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(pw^.data[i]));
+                       { ending #0 }
+                       current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(0))
+                     end;
+                  end
+                else
+                  Message(parser_e_illegal_expression);
+            end
+          else
+            if (p.nodetype=addrn) or
+               is_procvar_load(p) then
+              begin
+                { insert typeconv }
+                inserttypeconv(p,def);
+                hp:=p;
+                while assigned(hp) and (hp.nodetype in [addrn,typeconvn,subscriptn,vecn]) do
+                  hp:=tunarynode(hp).left;
+                if (hp.nodetype=loadn) then
                   begin
-                    { insert typeconv }
-                    inserttypeconv(p,def);
                     hp:=p;
-                    while assigned(hp) and (hp.nodetype in [addrn,typeconvn,subscriptn,vecn]) do
-                      hp:=tunarynode(hp).left;
-                    if (hp.nodetype=loadn) then
+                    offset:=0;
+                    while assigned(hp) and (hp.nodetype<>loadn) do
                       begin
-                        hp:=p;
-                        offset:=0;
-                        while assigned(hp) and (hp.nodetype<>loadn) do
-                          begin
-                             case hp.nodetype of
-                               vecn :
-                                 begin
-                                   case tvecnode(hp).left.resultdef.typ of
-                                     stringdef :
-                                       begin
-                                          { this seems OK for shortstring and ansistrings PM }
-                                          { it is wrong for widestrings !! }
+                         case hp.nodetype of
+                           vecn :
+                             begin
+                               case tvecnode(hp).left.resultdef.typ of
+                                 stringdef :
+                                   begin
+                                      { this seems OK for shortstring and ansistrings PM }
+                                      { it is wrong for widestrings !! }
+                                      len:=1;
+                                      base:=0;
+                                   end;
+                                 arraydef :
+                                   begin
+                                      if not is_packed_array(tvecnode(hp).left.resultdef) then
+                                        begin
+                                          len:=tarraydef(tvecnode(hp).left.resultdef).elesize;
+                                          base:=tarraydef(tvecnode(hp).left.resultdef).lowrange;
+                                        end
+                                      else
+                                        begin
+                                          Message(parser_e_packed_dynamic_open_array);
                                           len:=1;
                                           base:=0;
-                                       end;
-                                     arraydef :
-                                       begin
-                                          if not is_packed_array(tvecnode(hp).left.resultdef) then
-                                            begin
-                                              len:=tarraydef(tvecnode(hp).left.resultdef).elesize;
-                                              base:=tarraydef(tvecnode(hp).left.resultdef).lowrange;
-                                            end
-                                          else
-                                            begin
-                                              Message(parser_e_packed_dynamic_open_array);
-                                              len:=1;
-                                              base:=0;
-                                            end;
-                                       end
-                                     else
-                                       Message(parser_e_illegal_expression);
-                                   end;
-                                   if is_constintnode(tvecnode(hp).right) then
-                                     inc(offset,len*(get_ordinal_value(tvecnode(hp).right)-base))
-                                   else
-                                     Message(parser_e_illegal_expression);
-                                 end;
-                               subscriptn :
-                                 inc(offset,tsubscriptnode(hp).vs.fieldoffset);
-                               typeconvn :
-                                 begin
-                                   if not(ttypeconvnode(hp).convtype in [tc_equal,tc_proc_2_procvar]) then
-                                     Message(parser_e_illegal_expression);
-                                 end;
-                               addrn :
-                                 ;
+                                        end;
+                                   end
+                                 else
+                                   Message(parser_e_illegal_expression);
+                               end;
+                               if is_constintnode(tvecnode(hp).right) then
+                                 inc(offset,len*(get_ordinal_value(tvecnode(hp).right)-base))
                                else
                                  Message(parser_e_illegal_expression);
                              end;
-                             hp:=tunarynode(hp).left;
-                          end;
-                        srsym:=tloadnode(hp).symtableentry;
-                        case srsym.typ of
-                          procsym :
-                            begin
-                              pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
-                              if Tprocsym(srsym).ProcdefList.Count>1 then
-                                Message(parser_e_no_overloaded_procvars);
-                              if po_abstractmethod in pd.procoptions then
-                                Message(type_e_cant_take_address_of_abstract_method)
-                              else
-                                datalist.concat(Tai_const.Createname(pd.mangledname,offset));
-                            end;
-                          globalvarsym :
-                            datalist.concat(Tai_const.Createname(tglobalvarsym(srsym).mangledname,offset));
-                          typedconstsym :
-                            datalist.concat(Tai_const.Createname(ttypedconstsym(srsym).mangledname,offset));
-                          labelsym :
-                            datalist.concat(Tai_const.Createname(tlabelsym(srsym).mangledname,offset));
-                          constsym :
-                            if tconstsym(srsym).consttyp=constresourcestring then
-                              datalist.concat(Tai_const.Createname(make_mangledname('RESOURCESTRINGLIST',tconstsym(srsym).owner,''),tconstsym(srsym).resstrindex*(4+sizeof(aint)*3)+4+sizeof(aint)))
-                            else
-                              Message(type_e_variable_id_expected);
+                           subscriptn :
+                             inc(offset,tsubscriptnode(hp).vs.fieldoffset);
+                           typeconvn :
+                             begin
+                               if not(ttypeconvnode(hp).convtype in [tc_equal,tc_proc_2_procvar]) then
+                                 Message(parser_e_illegal_expression);
+                             end;
+                           addrn :
+                             ;
+                           else
+                             Message(parser_e_illegal_expression);
+                         end;
+                         hp:=tunarynode(hp).left;
+                      end;
+                    srsym:=tloadnode(hp).symtableentry;
+                    case srsym.typ of
+                      procsym :
+                        begin
+                          pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
+                          if Tprocsym(srsym).ProcdefList.Count>1 then
+                            Message(parser_e_no_overloaded_procvars);
+                          if po_abstractmethod in pd.procoptions then
+                            Message(type_e_cant_take_address_of_abstract_method)
                           else
-                            Message(type_e_variable_id_expected);
+                            list.concat(Tai_const.Createname(pd.mangledname,offset));
                         end;
-                      end
-                    else
-                      Message(parser_e_illegal_expression);
+                      staticvarsym :
+                        list.concat(Tai_const.Createname(tstaticvarsym(srsym).mangledname,offset));
+                      labelsym :
+                        list.concat(Tai_const.Createname(tlabelsym(srsym).mangledname,offset));
+                      constsym :
+                        if tconstsym(srsym).consttyp=constresourcestring then
+                          list.concat(Tai_const.Createname(make_mangledname('RESOURCESTRINGLIST',tconstsym(srsym).owner,''),tconstsym(srsym).resstrindex*(4+sizeof(aint)*3)+4+sizeof(aint)))
+                        else
+                          Message(type_e_variable_id_expected);
+                      else
+                        Message(type_e_variable_id_expected);
+                    end;
                   end
-              else
-              { allow typeof(Object type)}
-                if (p.nodetype=inlinen) and
-                   (tinlinenode(p).inlinenumber=in_typeof_x) then
+                else
+                  Message(parser_e_illegal_expression);
+              end
+          else
+          { allow typeof(Object type)}
+            if (p.nodetype=inlinen) and
+               (tinlinenode(p).inlinenumber=in_typeof_x) then
+              begin
+                if (tinlinenode(p).left.nodetype=typen) then
                   begin
-                    if (tinlinenode(p).left.nodetype=typen) then
-                      begin
-                        datalist.concat(Tai_const.createname(
-                          tobjectdef(tinlinenode(p).left.resultdef).vmt_mangledname,0));
-                      end
-                    else
-                      Message(parser_e_illegal_expression);
+                    list.concat(Tai_const.createname(
+                      tobjectdef(tinlinenode(p).left.resultdef).vmt_mangledname,0));
                   end
-              else
-                Message(parser_e_illegal_expression);
-              p.free;
-           end;
-         setdef:
-           begin
-              p:=comp_expr(true);
-              if p.nodetype=setconstn then
-                begin
-                   { be sure to convert to the correct result, else
-                     it can generate smallset data instead of normalset (PFV) }
-                   inserttypeconv(p,def);
-                   { we only allow const sets }
-                   if assigned(tsetconstnode(p).left) then
-                     Message(parser_e_illegal_expression)
-                   else
-                     begin
-                        { this writing is endian independant   }
-                        { untrue - because they are considered }
-                        { arrays of 32-bit values CEC          }
+                else
+                  Message(parser_e_illegal_expression);
+              end
+          else
+            Message(parser_e_illegal_expression);
+          p.free;
+        end;
 
-                        if source_info.endian = target_info.endian then
-                          begin
-                            for l:=0 to p.resultdef.size-1 do
-                              datalist.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[l]));
-                          end
-                        else
-                          begin
-                            { store as longint values in swaped format }
-                            j:=0;
-                            for l:=0 to ((p.resultdef.size-1) div 4) do
-                              begin
-                                datalist.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+3]));
-                                datalist.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+2]));
-                                datalist.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+1]));
-                                datalist.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j]));
-                                Inc(j,4);
-                              end;
-                          end;
-                     end;
-                end
+        procedure parse_setdef(list:tasmlist;def:tsetdef);
+        type
+           setbytes = array[0..31] of byte;
+           Psetbytes = ^setbytes;
+        var
+          p : tnode;
+          i,j : longint;
+        begin
+          p:=comp_expr(true);
+          if p.nodetype=setconstn then
+            begin
+              { be sure to convert to the correct result, else
+                it can generate smallset data instead of normalset (PFV) }
+              inserttypeconv(p,def);
+              { we only allow const sets }
+              if assigned(tsetconstnode(p).left) then
+                Message(parser_e_illegal_expression)
               else
-                Message(parser_e_illegal_expression);
-              p.free;
-           end;
-         enumdef:
-           begin
-              p:=comp_expr(true);
-              if p.nodetype=ordconstn then
                 begin
-                  if equal_defs(p.resultdef,def) or
-                     is_subequal(p.resultdef,def) then
-                   begin
-                     case longint(p.resultdef.size) of
-                       1 : datalist.concat(Tai_const.Create_8bit(Byte(tordconstnode(p).value)));
-                       2 : datalist.concat(Tai_const.Create_16bit(Word(tordconstnode(p).value)));
-                       4 : datalist.concat(Tai_const.Create_32bit(Longint(tordconstnode(p).value)));
-                     end;
-                   end
+                  { this writing is endian independant   }
+                  { untrue - because they are considered }
+                  { arrays of 32-bit values CEC          }
+                  if source_info.endian = target_info.endian then
+                    begin
+                      for i:=0 to p.resultdef.size-1 do
+                        list.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[i]));
+                    end
                   else
-                   IncompatibleTypes(p.resultdef,def);
-                end
-              else
-                Message(parser_e_illegal_expression);
-              p.free;
-           end;
-         stringdef:
-           begin
-              p:=comp_expr(true);
-              { load strval and strlength of the constant tree }
-              if (p.nodetype=stringconstn) or is_widestring(def) then
-                begin
-                  { convert to the expected string type so that
-                    for widestrings strval is a pcompilerwidestring }
-                  inserttypeconv(p,def);
-                  strlength:=tstringconstnode(p).len;
-                  strval:=tstringconstnode(p).value_str;
-                end
-              else if is_constcharnode(p) then
-                begin
-                  { strval:=pchar(@tordconstnode(p).value);
-                    THIS FAIL on BIG_ENDIAN MACHINES PM }
-                  c:=chr(tordconstnode(p).value and $ff);
-                  strval:=@c;
-                  strlength:=1
-                end
-              else if is_constresourcestringnode(p) then
+                    begin
+                      { store as longint values in swaped format }
+                      j:=0;
+                      for i:=0 to ((p.resultdef.size-1) div 4) do
+                        begin
+                          list.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+3]));
+                          list.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+2]));
+                          list.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j+1]));
+                          list.concat(tai_const.create_8bit(Psetbytes(tsetconstnode(p).value_set)^[j]));
+                          Inc(j,4);
+                        end;
+                    end;
+                end;
+            end
+          else
+            Message(parser_e_illegal_expression);
+          p.free;
+        end;
+
+        procedure parse_enumdef(list:tasmlist;def:tenumdef);
+        var
+          p : tnode;
+        begin
+          p:=comp_expr(true);
+          if p.nodetype=ordconstn then
+            begin
+              if equal_defs(p.resultdef,def) or
+                 is_subequal(p.resultdef,def) then
                 begin
-                  strval:=pchar(tconstsym(tloadnode(p).symtableentry).value.valueptr);
-                  strlength:=tconstsym(tloadnode(p).symtableentry).value.len;
+                  case longint(p.resultdef.size) of
+                    1 : list.concat(Tai_const.Create_8bit(Byte(tordconstnode(p).value)));
+                    2 : list.concat(Tai_const.Create_16bit(Word(tordconstnode(p).value)));
+                    4 : list.concat(Tai_const.Create_32bit(Longint(tordconstnode(p).value)));
+                  end;
                 end
               else
-                begin
-                  Message(parser_e_illegal_expression);
-                  strlength:=-1;
-                end;
-              if strlength>=0 then
-               begin
-                 case tstringdef(def).stringtype of
-                   st_shortstring:
-                     begin
-                       if strlength>=def.size then
-                        begin
-                          message2(parser_w_string_too_long,strpas(strval),tostr(def.size-1));
-                          strlength:=def.size-1;
-                        end;
-                       datalist.concat(Tai_const.Create_8bit(strlength));
-                       { this can also handle longer strings }
-                       getmem(ca,strlength+1);
-                       move(strval^,ca^,strlength);
-                       ca[strlength]:=#0;
-                       datalist.concat(Tai_string.Create_pchar(ca,strlength));
-                       { fillup with spaces if size is shorter }
-                       if def.size>strlength then
-                        begin
-                          getmem(ca,def.size-strlength);
-                          { def.size contains also the leading length, so we }
-                          { we have to subtract one                       }
-                          fillchar(ca[0],def.size-strlength-1,' ');
-                          ca[def.size-strlength-1]:=#0;
-                          { this can also handle longer strings }
-                          datalist.concat(Tai_string.Create_pchar(ca,def.size-strlength-1));
-                        end;
-                     end;
-                   st_ansistring:
-                     begin
-                        { an empty ansi string is nil! }
-                        if (strlength=0) then
-                          datalist.concat(Tai_const.Create_sym(nil))
-                        else
-                          begin
-                            current_asmdata.getdatalabel(ll);
-                            datalist.concat(Tai_const.Create_sym(ll));
-                            current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
-                            current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
-                            current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength));
-                            current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
-                            getmem(ca,strlength+1);
-                            move(strval^,ca^,strlength);
-                            { The terminating #0 to be stored in the .data section (JM) }
-                            ca[strlength]:=#0;
-                            current_asmdata.asmlists[al_const].concat(Tai_string.Create_pchar(ca,strlength+1));
-                          end;
-                     end;
-                   st_widestring:
+                IncompatibleTypes(p.resultdef,def);
+            end
+          else
+            Message(parser_e_illegal_expression);
+          p.free;
+        end;
+
+        procedure parse_stringdef(list:tasmlist;def:tstringdef);
+        var
+          n : tnode;
+          i : longint;
+          strlength : aint;
+          strval    : pchar;
+          strch     : char;
+          ll        : tasmlabel;
+          ca        : pchar;
+        begin
+          n:=comp_expr(true);
+          { load strval and strlength of the constant tree }
+          if (n.nodetype=stringconstn) or is_widestring(def) then
+            begin
+              { convert to the expected string type so that
+                for widestrings strval is a pcompilerwidestring }
+              inserttypeconv(n,def);
+              strlength:=tstringconstnode(n).len;
+              strval:=tstringconstnode(n).value_str;
+            end
+          else if is_constcharnode(n) then
+            begin
+              { strval:=pchar(@tordconstnode(n).value);
+                THIS FAIL on BIG_ENDIAN MACHINES PM }
+              strch:=chr(tordconstnode(n).value and $ff);
+              strval:=@strch;
+              strlength:=1
+            end
+          else if is_constresourcestringnode(n) then
+            begin
+              strval:=pchar(tconstsym(tloadnode(n).symtableentry).value.valueptr);
+              strlength:=tconstsym(tloadnode(n).symtableentry).value.len;
+            end
+          else
+            begin
+              Message(parser_e_illegal_expression);
+              strlength:=-1;
+            end;
+          if strlength>=0 then
+            begin
+              case def.stringtype of
+                st_shortstring:
+                  begin
+                    if strlength>=def.size then
                      begin
-                        { an empty ansi string is nil! }
-                        if (strlength=0) then
-                          datalist.concat(Tai_const.Create_sym(nil))
-                        else
-                          begin
-                            current_asmdata.getdatalabel(ll);
-                            datalist.concat(Tai_const.Create_sym(ll));
-                            current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
-                            if tf_winlikewidestring in target_info.flags then
-                              current_asmdata.asmlists[al_const].concat(Tai_const.Create_32bit(strlength*cwidechartype.size))
-                            else
-                              begin
-                                current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
-                                current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength*cwidechartype.size));
-                              end;
-                            current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
-                            for i:=0 to strlength-1 do
-                              current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(pcompilerwidestring(strval)^.data[i]));
-                            { ending #0 }
-                            current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(0))
-                          end;
+                       message2(parser_w_string_too_long,strpas(strval),tostr(def.size-1));
+                       strlength:=def.size-1;
                      end;
-                   st_longstring:
+                    list.concat(Tai_const.Create_8bit(strlength));
+                    { this can also handle longer strings }
+                    getmem(ca,strlength+1);
+                    move(strval^,ca^,strlength);
+                    ca[strlength]:=#0;
+                    list.concat(Tai_string.Create_pchar(ca,strlength));
+                    { fillup with spaces if size is shorter }
+                    if def.size>strlength then
                      begin
-                       internalerror(200107081);
+                       getmem(ca,def.size-strlength);
+                       { def.size contains also the leading length, so we }
+                       { we have to subtract one                       }
+                       fillchar(ca[0],def.size-strlength-1,' ');
+                       ca[def.size-strlength-1]:=#0;
+                       { this can also handle longer strings }
+                       list.concat(Tai_string.Create_pchar(ca,def.size-strlength-1));
                      end;
-                 end;
-               end;
-              p.free;
-           end;
-         arraydef:
-           begin
-              { dynamic array nil }
-               if is_dynamic_array(def) then
+                  end;
+                st_ansistring:
+                  begin
+                     { an empty ansi string is nil! }
+                     if (strlength=0) then
+                       list.concat(Tai_const.Create_sym(nil))
+                     else
+                       begin
+                         current_asmdata.getdatalabel(ll);
+                         list.concat(Tai_const.Create_sym(ll));
+                         current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
+                         current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
+                         current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength));
+                         current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
+                         getmem(ca,strlength+1);
+                         move(strval^,ca^,strlength);
+                         { The terminating #0 to be stored in the .data section (JM) }
+                         ca[strlength]:=#0;
+                         current_asmdata.asmlists[al_const].concat(Tai_string.Create_pchar(ca,strlength+1));
+                       end;
+                  end;
+                st_widestring:
+                  begin
+                     { an empty ansi string is nil! }
+                     if (strlength=0) then
+                       list.concat(Tai_const.Create_sym(nil))
+                     else
+                       begin
+                         current_asmdata.getdatalabel(ll);
+                         list.concat(Tai_const.Create_sym(ll));
+                         current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
+                         if tf_winlikewidestring in target_info.flags then
+                           current_asmdata.asmlists[al_const].concat(Tai_const.Create_32bit(strlength*cwidechartype.size))
+                         else
+                           begin
+                             current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(-1));
+                             current_asmdata.asmlists[al_const].concat(Tai_const.Create_aint(strlength*cwidechartype.size));
+                           end;
+                         current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
+                         for i:=0 to strlength-1 do
+                           current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(pcompilerwidestring(strval)^.data[i]));
+                         { ending #0 }
+                         current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(0))
+                       end;
+                  end;
+                else
+                  internalerror(200107081);
+              end;
+            end;
+          n.free;
+        end;
+
+        procedure parse_arraydef(list:tasmlist;def:tarraydef);
+        var
+          n : tnode;
+          i : longint;
+          len : aint;
+          ch  : char;
+          ca  : pchar;
+        begin
+          { dynamic array nil }
+          if is_dynamic_array(def) then
+            begin
+              { Only allow nil initialization }
+              consume(_NIL);
+              list.concat(Tai_const.Create_sym(nil));
+            end
+          { no packed array constants supported }
+          else if is_packed_array(def) then
+            begin
+              Message(type_e_no_const_packed_array);
+              consume_all_until(_RKLAMMER);
+            end
+          { normal array const between brackets }
+          else if try_to_consume(_LKLAMMER) then
+            begin
+              for i:=def.lowrange to def.highrange-1 do
                 begin
-                  { Only allow nil initialization }
-                  consume(_NIL);
-                  datalist.concat(Tai_const.Create_sym(nil));
-                end
-               { no packed array constants supported }
-               else if is_packed_array(def) then
+                  read_typed_const_data(list,def.elementdef);
+                  consume(_COMMA);
+                end;
+              read_typed_const_data(list,def.elementdef);
+              consume(_RKLAMMER);
+            end
+          { if array of char then we allow also a string }
+          else if is_char(def.elementdef) then
+            begin
+               n:=comp_expr(true);
+               if n.nodetype=stringconstn then
                  begin
-                   Message(type_e_no_const_packed_array);
-                   consume_all_until(_RKLAMMER);
+                   len:=tstringconstnode(n).len;
+                   { For tp7 the maximum lentgh can be 255 }
+                   if (m_tp7 in current_settings.modeswitches) and
+                      (len>255) then
+                    len:=255;
+                   ca:=tstringconstnode(n).value_str;
                  end
-              else
-              if try_to_consume(_LKLAMMER) then
-                begin
-                  for l:=tarraydef(def).lowrange to tarraydef(def).highrange-1 do
-                    begin
-                      readtypedconst(datalist,tarraydef(def).elementdef,nil,writable);
-                      consume(_COMMA);
-                    end;
-                  readtypedconst(datalist,tarraydef(def).elementdef,nil,writable);
-                  consume(_RKLAMMER);
-                end
-              else
-              { if array of char then we allow also a string }
-               if is_char(tarraydef(def).elementdef) then
+               else
+                 if is_constcharnode(n) then
+                  begin
+                    ch:=chr(tordconstnode(n).value and $ff);
+                    ca:=@ch;
+                    len:=1;
+                  end
+               else
+                 begin
+                   Message(parser_e_illegal_expression);
+                   len:=0;
+                 end;
+               if len>(def.highrange-def.lowrange+1) then
+                 Message(parser_e_string_larger_array);
+               for i:=def.lowrange to def.highrange do
+                 begin
+                    if i+1-def.lowrange<=len then
+                      begin
+                         list.concat(Tai_const.Create_8bit(byte(ca^)));
+                         inc(ca);
+                      end
+                    else
+                      {Fill the remaining positions with #0.}
+                      list.concat(Tai_const.Create_8bit(0));
+                 end;
+               n.free;
+            end
+          else
+            begin
+              { we want the ( }
+              consume(_LKLAMMER);
+            end;
+        end;
+
+        procedure parse_procvardef(list:tasmlist;def:tprocvardef);
+        var
+          tmpn,n : tnode;
+          pd   : tprocdef;
+        begin
+          { Procvars and pointers are no longer compatible.  }
+          { under tp:  =nil or =var under fpc: =nil or =@var }
+          if try_to_consume(_NIL) then
+            begin
+               list.concat(Tai_const.Create_sym(nil));
+               if (po_methodpointer in def.procoptions) then
+                 list.concat(Tai_const.Create_sym(nil));
+               exit;
+            end;
+          { you can't assign a value other than NIL to a typed constant  }
+          { which is a "procedure of object", because this also requires }
+          { address of an object/class instance, which is not known at   }
+          { compile time (JM)                                            }
+          if (po_methodpointer in def.procoptions) then
+            Message(parser_e_no_procvarobj_const);
+          { parse the rest too, so we can continue with error checking }
+          getprocvardef:=def;
+          n:=comp_expr(true);
+          getprocvardef:=nil;
+          if codegenerror then
+            begin
+              n.free;
+              exit;
+            end;
+          { let type conversion check everything needed }
+          inserttypeconv(n,def);
+          if codegenerror then
+            begin
+              n.free;
+              exit;
+            end;
+          { remove typeconvs, that will normally insert a lea
+            instruction which is not necessary for us }
+          while n.nodetype=typeconvn do
+            begin
+              tmpn:=ttypeconvnode(n).left;
+              ttypeconvnode(n).left:=nil;
+              n.free;
+              n:=tmpn;
+            end;
+          { remove addrn which we also don't need here }
+          if n.nodetype=addrn then
+            begin
+              tmpn:=taddrnode(n).left;
+              taddrnode(n).left:=nil;
+              n.free;
+              n:=tmpn;
+            end;
+          { we now need to have a loadn with a procsym }
+          if (n.nodetype=loadn) and
+             (tloadnode(n).symtableentry.typ=procsym) then
+            begin
+              pd:=tprocdef(tprocsym(tloadnode(n).symtableentry).ProcdefList[0]);
+              list.concat(Tai_const.createname(pd.mangledname,0));
+            end
+          else
+            Message(parser_e_illegal_expression);
+          n.free;
+        end;
+
+        procedure parse_recorddef(list:tasmlist;def:trecorddef);
+        var
+          n       : tnode;
+          i,
+          symidx  : longint;
+          recsym,
+          srsym   : tsym;
+          hs      : string;
+          sorg,s  : TIDString;
+          tmpguid : tguid;
+          curroffset  : aint;
+          error   : boolean;
+        begin
+          { no packed record support }
+          if is_packed_record_or_object(def) then
+            begin
+              Message(type_e_no_const_packed_record);
+              exit;
+            end;
+          { GUID }
+          if (def=rec_tguid) and
+             ((token=_CSTRING) or (token=_CCHAR) or (token=_ID)) then
+            begin
+              n:=comp_expr(true);
+              inserttypeconv(n,cshortstringtype);
+              if n.nodetype=stringconstn then
                 begin
-                   p:=comp_expr(true);
-                   if p.nodetype=stringconstn then
+                  hs:=strpas(tstringconstnode(n).value_str);
+                  if string2guid(hs,tmpguid) then
                     begin
-                      len:=tstringconstnode(p).len;
-                      { For tp7 the maximum lentgh can be 255 }
-                      if (m_tp7 in current_settings.modeswitches) and
-                         (len>255) then
-                       len:=255;
-                      ca:=tstringconstnode(p).value_str;
+                      list.concat(Tai_const.Create_32bit(longint(tmpguid.D1)));
+                      list.concat(Tai_const.Create_16bit(tmpguid.D2));
+                      list.concat(Tai_const.Create_16bit(tmpguid.D3));
+                      for i:=Low(tmpguid.D4) to High(tmpguid.D4) do
+                        list.concat(Tai_const.Create_8bit(tmpguid.D4[i]));
                     end
-                   else
-                     if is_constcharnode(p) then
-                      begin
-                        c:=chr(tordconstnode(p).value and $ff);
-                        ca:=@c;
-                        len:=1;
-                      end
-                   else
-                     begin
-                       Message(parser_e_illegal_expression);
-                       len:=0;
-                     end;
-                   if len>(tarraydef(def).highrange-tarraydef(def).lowrange+1) then
-                     Message(parser_e_string_larger_array);
-                   for i:=tarraydef(def).lowrange to tarraydef(def).highrange do
-                     begin
-                        if i+1-tarraydef(def).lowrange<=len then
-                          begin
-                             datalist.concat(Tai_const.Create_8bit(byte(ca^)));
-                             inc(ca);
-                          end
-                        else
-                          {Fill the remaining positions with #0.}
-                          datalist.concat(Tai_const.Create_8bit(0));
-                     end;
-                   p.free;
+                  else
+                    Message(parser_e_improper_guid_syntax);
                 end
               else
+                Message(parser_e_illegal_expression);
+              n.free;
+              exit;
+            end;
+          { normal record }
+          consume(_LKLAMMER);
+          curroffset:=0;
+          symidx:=0;
+          srsym:=tsym(def.symtable.SymList[symidx]);
+          recsym := nil;
+          while token<>_RKLAMMER do
+            begin
+              s:=pattern;
+              sorg:=orgpattern;
+              consume(_ID);
+              consume(_COLON);
+              error := false;
+              recsym := tsym(def.symtable.Find(s));
+              if not assigned(recsym) then
                 begin
-                  { we want the ( }
-                  consume(_LKLAMMER);
+                  Message1(sym_e_illegal_field,sorg);
+                  error := true;
                 end;
-           end;
-         procvardef:
-           begin
-              { Procvars and pointers are no longer compatible.  }
-              { under tp:  =nil or =var under fpc: =nil or =@var }
-              if token=_NIL then
+              if (not error) and
+                 (not assigned(srsym) or
+                  (s <> srsym.name)) then
+                { possible variant record (JM) }
                 begin
-                   datalist.concat(Tai_const.Create_sym(nil));
-                   if (po_methodpointer in tprocvardef(def).procoptions) then
-                     datalist.concat(Tai_const.Create_sym(nil));
-                   consume(_NIL);
-                   goto myexit;
-                end;
-              { you can't assign a value other than NIL to a typed constant  }
-              { which is a "procedure of object", because this also requires }
-              { address of an object/class instance, which is not known at   }
-              { compile time (JM)                                            }
-              if (po_methodpointer in tprocvardef(def).procoptions) then
-                Message(parser_e_no_procvarobj_const);
-                { parse the rest too, so we can continue with error checking }
-              getprocvardef:=tprocvardef(def);
-              p:=comp_expr(true);
-              getprocvardef:=nil;
-              if codegenerror then
-               begin
-                 p.free;
-                 goto myexit;
-               end;
-              { let type conversion check everything needed }
-              inserttypeconv(p,def);
-              if codegenerror then
-               begin
-                 p.free;
-                 goto myexit;
-               end;
-              { remove typeconvs, that will normally insert a lea
-                instruction which is not necessary for us }
-              while p.nodetype=typeconvn do
-               begin
-                 hp:=ttypeconvnode(p).left;
-                 ttypeconvnode(p).left:=nil;
-                 p.free;
-                 p:=hp;
-               end;
-              { remove addrn which we also don't need here }
-              if p.nodetype=addrn then
-               begin
-                 hp:=taddrnode(p).left;
-                 taddrnode(p).left:=nil;
-                 p.free;
-                 p:=hp;
-               end;
-              { we now need to have a loadn with a procsym }
-              if (p.nodetype=loadn) and
-                 (tloadnode(p).symtableentry.typ=procsym) then
-               begin
-                 pd:=tprocdef(tprocsym(tloadnode(p).symtableentry).ProcdefList[0]);
-                 datalist.concat(Tai_const.createname(pd.mangledname,0));
-               end
-              else
-               Message(parser_e_illegal_expression);
-              p.free;
-           end;
-         { reads a typed constant record }
-         recorddef:
-           begin
-              { packed record }
-              if is_packed_record_or_object(def) then
-                Message(type_e_no_const_packed_record)
-              { KAZ }
-              else if (trecorddef(def)=rec_tguid) and
-                 ((token=_CSTRING) or (token=_CCHAR) or (token=_ID)) then
-                begin
-                  p:=comp_expr(true);
-                  inserttypeconv(p,cshortstringtype);
-                  if p.nodetype=stringconstn then
+                  { All parts of a variant start at the same offset      }
+                  { Also allow jumping from one variant part to another, }
+                  { as long as the offsets match                         }
+                  if (assigned(srsym) and
+                      (tfieldvarsym(recsym).fieldoffset = tfieldvarsym(srsym).fieldoffset)) or
+                     { srsym is not assigned after parsing w2 in the      }
+                     { typed const in the next example:                   }
+                     {   type tr = record case byte of                    }
+                     {          1: (l1,l2: dword);                        }
+                     {          2: (w1,w2: word);                         }
+                     {        end;                                        }
+                     {   const r: tr = (w1:1;w2:1;l2:5);                  }
+                     (tfieldvarsym(recsym).fieldoffset = curroffset) then
+                    srsym := recsym
+                  { going backwards isn't allowed in any mode }
+                  else if (tfieldvarsym(recsym).fieldoffset<curroffset) then
                     begin
-                      s:=strpas(tstringconstnode(p).value_str);
-                      p.free;
-                      if string2guid(s,tmpguid) then
-                        begin
-                          datalist.concat(Tai_const.Create_32bit(longint(tmpguid.D1)));
-                          datalist.concat(Tai_const.Create_16bit(tmpguid.D2));
-                          datalist.concat(Tai_const.Create_16bit(tmpguid.D3));
-                          for i:=Low(tmpguid.D4) to High(tmpguid.D4) do
-                            datalist.concat(Tai_const.Create_8bit(tmpguid.D4[i]));
-                        end
-                      else
-                        Message(parser_e_improper_guid_syntax);
+                      Message(parser_e_invalid_record_const);
+                      error := true;
+                    end
+                  { Delphi allows you to skip fields }
+                  else if (m_delphi in current_settings.modeswitches) then
+                    begin
+                      Message1(parser_w_skipped_fields_before,sorg);
+                      srsym := recsym;
                     end
+                  { FPC and TP don't }
                   else
                     begin
-                      p.free;
-                      Message(parser_e_illegal_expression);
-                      goto myexit;
+                      Message1(parser_e_skipped_fields_before,sorg);
+                      error := true;
                     end;
-                end
+                end;
+              if error then
+                consume_all_until(_SEMICOLON)
               else
                 begin
-                   consume(_LKLAMMER);
-                   sorg:='';
-                   aktpos:=0;
-                   symidx:=0;
-                   srsym:=tsym(trecorddef(def).symtable.SymList[symidx]);
-                   recsym := nil;
-                   while token<>_RKLAMMER do
-                     begin
-                        s:=pattern;
-                        sorg:=orgpattern;
-                        consume(_ID);
-                        consume(_COLON);
-                        error := false;
-                        recsym := tsym(trecorddef(def).symtable.Find(s));
-                        if not assigned(recsym) then
-                          begin
-                            Message1(sym_e_illegal_field,sorg);
-                            error := true;
-                          end;
-                        if (not error) and
-                           (not assigned(srsym) or
-                            (s <> srsym.name)) then
-                          { possible variant record (JM) }
-                          begin
-                            { All parts of a variant start at the same offset      }
-                            { Also allow jumping from one variant part to another, }
-                            { as long as the offsets match                         }
-                            if (assigned(srsym) and
-                                (tfieldvarsym(recsym).fieldoffset = tfieldvarsym(srsym).fieldoffset)) or
-                               { srsym is not assigned after parsing w2 in the      }
-                               { typed const in the next example:                   }
-                               {   type tr = record case byte of                    }
-                               {          1: (l1,l2: dword);                        }
-                               {          2: (w1,w2: word);                         }
-                               {        end;                                        }
-                               {   const r: tr = (w1:1;w2:1;l2:5);                  }
-                               (tfieldvarsym(recsym).fieldoffset = aktpos) then
-                              srsym := recsym
-                            { going backwards isn't allowed in any mode }
-                            else if (tfieldvarsym(recsym).fieldoffset<aktpos) then
-                              begin
-                                Message(parser_e_invalid_record_const);
-                                error := true;
-                              end
-                            { Delphi allows you to skip fields }
-                            else if (m_delphi in current_settings.modeswitches) then
-                              begin
-                                Message1(parser_w_skipped_fields_before,sorg);
-                                srsym := recsym;
-                              end
-                            { FPC and TP don't }
-                            else
-                              begin
-                                Message1(parser_e_skipped_fields_before,sorg);
-                                error := true;
-                              end;
-                          end;
-                        if error then
-                          consume_all_until(_SEMICOLON)
-                        else
-                          begin
 
-                            { if needed fill (alignment) }
-                            if tfieldvarsym(srsym).fieldoffset>aktpos then
-                               for i:=1 to tfieldvarsym(srsym).fieldoffset-aktpos do
-                                 datalist.concat(Tai_const.Create_8bit(0));
+                  { if needed fill (alignment) }
+                  if tfieldvarsym(srsym).fieldoffset>curroffset then
+                     for i:=1 to tfieldvarsym(srsym).fieldoffset-curroffset do
+                       list.concat(Tai_const.Create_8bit(0));
+
+                   { new position }
+                   curroffset:=tfieldvarsym(srsym).fieldoffset+tfieldvarsym(srsym).vardef.size;
+
+                   { read the data }
+                   read_typed_const_data(list,tfieldvarsym(srsym).vardef);
 
-                             { new position }
-                             aktpos:=tfieldvarsym(srsym).fieldoffset+tfieldvarsym(srsym).vardef.size;
+                   { keep previous field for checking whether whole }
+                   { record was initialized (JM)                    }
+                   recsym := srsym;
+                   { goto next field }
+                   inc(symidx);
+                   if symidx<def.symtable.SymList.Count then
+                     srsym:=tsym(def.symtable.SymList[symidx])
+                   else
+                     srsym:=nil;
 
-                             { read the data }
-                             readtypedconst(datalist,tfieldvarsym(srsym).vardef,nil,writable);
+                   if token=_SEMICOLON then
+                     consume(_SEMICOLON)
+                   else break;
+                end;
+            end;
 
-                             { keep previous field for checking whether whole }
-                             { record was initialized (JM)                    }
-                             recsym := srsym;
-                             { goto next field }
-                             inc(symidx);
-                             if symidx<trecorddef(def).symtable.SymList.Count then
-                               srsym:=tsym(trecorddef(def).symtable.SymList[symidx])
-                             else
-                               srsym:=nil;
+          { are there any fields left, but don't complain if there only
+            come other variant partsa fter the last initialized field }
+          if assigned(srsym) and
+             (
+              (recsym=nil) or
+              (tfieldvarsym(srsym).fieldoffset > tfieldvarsym(recsym).fieldoffset)
+             ) then
+            Message1(parser_w_skipped_fields_after,sorg);
 
-                             if token=_SEMICOLON then
-                               consume(_SEMICOLON)
-                             else break;
-                          end;
-                   end;
+          for i:=1 to def.size-curroffset do
+            list.concat(Tai_const.Create_8bit(0));
 
-                 { are there any fields left?                            }
-                 if assigned(srsym) and
-                    { don't complain if there only come other variant parts }
-                    { after the last initialized field                      }
-                    ((recsym=nil) or
-                     (tfieldvarsym(srsym).fieldoffset > tfieldvarsym(recsym).fieldoffset)) then
-                   Message1(parser_w_skipped_fields_after,sorg);
+          consume(_RKLAMMER);
+        end;
 
-                 for i:=1 to def.size-aktpos do
-                   datalist.concat(Tai_const.Create_8bit(0));
 
-                 consume(_RKLAMMER);
-              end;
-           end;
-         { reads a typed object }
-         objectdef:
-           begin
-              if is_class_or_interface(def) then
+        procedure parse_objectdef(list:tasmlist;def:tobjectdef);
+        var
+          n      : tnode;
+          i      : longint;
+          obj    : tobjectdef;
+          srsym  : tsym;
+          st     : tsymtable;
+          curroffset : aint;
+          s,sorg : TIDString;
+        begin
+          { no support for packed object }
+          if is_packed_record_or_object(def) then
+            begin
+              Message(type_e_no_const_packed_record);
+              exit;
+            end;
+
+          { only allow nil for class and interface }
+          if is_class_or_interface(def) then
+            begin
+              n:=comp_expr(true);
+              if n.nodetype<>niln then
                 begin
-                  p:=comp_expr(true);
-                  if p.nodetype<>niln then
-                    begin
-                      Message(type_e_no_const_packed_array);
-                      consume_all_until(_SEMICOLON);
-                    end
-                  else
-                    begin
-                      datalist.concat(Tai_const.Create_sym(nil));
-                    end;
-                  p.free;
+                  Message(type_e_no_const_packed_array);
+                  consume_all_until(_SEMICOLON);
                 end
-              { for objects we allow it only if it doesn't contain a vmt }
-              else if (oo_has_vmt in tobjectdef(def).objectoptions) and
-                      (m_fpc in current_settings.modeswitches) then
-                 Message(parser_e_type_const_not_possible)
-              { packed object }
-              else if is_packed_record_or_object(def) then
-                Message(type_e_no_const_packed_record)
               else
-                begin
-                   consume(_LKLAMMER);
-                   aktpos:=0;
-                   while token<>_RKLAMMER do
-                     begin
-                        s:=pattern;
-                        sorg:=orgpattern;
-                        consume(_ID);
-                        consume(_COLON);
-                        srsym:=nil;
-                        obj:=tobjectdef(def);
-                        symt:=obj.symtable;
-                        while (srsym=nil) and assigned(symt) do
-                          begin
-                             srsym:=tsym(symt.Find(s));
-                             if assigned(obj) then
-                               obj:=obj.childof;
-                             if assigned(obj) then
-                               symt:=obj.symtable
-                             else
-                               symt:=nil;
-                          end;
+                list.concat(Tai_const.Create_sym(nil));
+              n.free;
+              exit;
+            end;
 
-                        if srsym=nil then
-                          begin
-                             Message1(sym_e_id_not_found,sorg);
-                             consume_all_until(_SEMICOLON);
-                          end
-                        else
-                          with tfieldvarsym(srsym) do
-                            begin
-                               { check position }
-                               if fieldoffset<aktpos then
-                                 message(parser_e_invalid_record_const);
+          { for objects we allow it only if it doesn't contain a vmt }
+          if (oo_has_vmt in def.objectoptions) and
+             (m_fpc in current_settings.modeswitches) then
+            begin
+              Message(parser_e_type_const_not_possible);
+              exit;
+            end;
 
-                               { check in VMT needs to be added for TP mode }
-                               with Tobjectdef(def) do
-                                 if not(m_fpc in current_settings.modeswitches) and
-                                    (oo_has_vmt in objectoptions) and
-                                    (vmt_offset<fieldoffset) then
-                                   begin
-                                     for i:=1 to vmt_offset-aktpos do
-                                       datalist.concat(tai_const.create_8bit(0));
-                                     datalist.concat(tai_const.createname(vmt_mangledname,0));
-                                     { this is more general }
-                                     aktpos:=vmt_offset + sizeof(aint);
-                                   end;
+          consume(_LKLAMMER);
+          curroffset:=0;
+          while token<>_RKLAMMER do
+            begin
+              s:=pattern;
+              sorg:=orgpattern;
+              consume(_ID);
+              consume(_COLON);
+              srsym:=nil;
+              obj:=tobjectdef(def);
+              st:=obj.symtable;
+              while (srsym=nil) and assigned(st) do
+                begin
+                  srsym:=tsym(st.Find(s));
+                  if assigned(obj) then
+                    obj:=obj.childof;
+                  if assigned(obj) then
+                    st:=obj.symtable
+                  else
+                    st:=nil;
+                end;
 
-                               { if needed fill }
-                               if fieldoffset>aktpos then
-                                 for i:=1 to fieldoffset-aktpos do
-                                   datalist.concat(Tai_const.Create_8bit(0));
+              if srsym=nil then
+                begin
+                  Message1(sym_e_id_not_found,sorg);
+                  consume_all_until(_SEMICOLON);
+                end
+              else
+                with tfieldvarsym(srsym) do
+                  begin
+                    { check position }
+                    if fieldoffset<curroffset then
+                      message(parser_e_invalid_record_const);
 
-                               { new position }
-                               aktpos:=fieldoffset+vardef.size;
+                    { check in VMT needs to be added for TP mode }
+                    if not(m_fpc in current_settings.modeswitches) and
+                       (oo_has_vmt in def.objectoptions) and
+                       (def.vmt_offset<fieldoffset) then
+                      begin
+                        for i:=1 to def.vmt_offset-curroffset do
+                          list.concat(tai_const.create_8bit(0));
+                        list.concat(tai_const.createname(def.vmt_mangledname,0));
+                        { this is more general }
+                        curroffset:=def.vmt_offset + sizeof(aint);
+                      end;
 
-                               { read the data }
-                               readtypedconst(datalist,vardef,nil,writable);
+                    { if needed fill }
+                    if fieldoffset>curroffset then
+                      for i:=1 to fieldoffset-curroffset do
+                        list.concat(Tai_const.Create_8bit(0));
 
-                               if not try_to_consume(_SEMICOLON) then
-                                 break;
-                          end;
-                     end;
-                   if not(m_fpc in current_settings.modeswitches) and
-                      (oo_has_vmt in tobjectdef(def).objectoptions) and
-                      (tobjectdef(def).vmt_offset>=aktpos) then
-                     begin
-                       for i:=1 to tobjectdef(def).vmt_offset-aktpos do
-                         datalist.concat(tai_const.create_8bit(0));
-                       datalist.concat(tai_const.createname(tobjectdef(def).vmt_mangledname,0));
-                       { this is more general }
-                       aktpos:=tobjectdef(def).vmt_offset + sizeof(aint);
-                     end;
-                   for i:=1 to def.size-aktpos do
-                     datalist.concat(Tai_const.Create_8bit(0));
-                   consume(_RKLAMMER);
-                end;
-           end;
-         errordef:
-           begin
-              { try to consume something useful }
-              if token=_LKLAMMER then
-                consume_all_until(_RKLAMMER)
-              else
-                consume_all_until(_SEMICOLON);
-           end;
-         else Message(parser_e_type_const_not_possible);
-         end;
+                    { new position }
+                    curroffset:=fieldoffset+vardef.size;
 
-         { Parse hints and public directive }
-         if assigned(sym) then
-           begin
-             try_consume_hintdirective(sym.symoptions);
+                    { read the data }
+                    read_typed_const_data(list,vardef);
 
-             { Support public name directive }
-             if try_to_consume(_PUBLIC) then
-               begin
-                 if try_to_consume(_NAME) then
-                   C_name:=get_stringconst
-                 else
-                   C_name:=sorg;
-                 sym.set_mangledname(C_Name);
-               end;
-           end;
-
-      myexit:
-         block_type:=old_block_type;
+                    if not try_to_consume(_SEMICOLON) then
+                      break;
+                  end;
+            end;
+          if not(m_fpc in current_settings.modeswitches) and
+             (oo_has_vmt in def.objectoptions) and
+             (def.vmt_offset>=curroffset) then
+            begin
+              for i:=1 to def.vmt_offset-curroffset do
+                list.concat(tai_const.create_8bit(0));
+              list.concat(tai_const.createname(def.vmt_mangledname,0));
+              { this is more general }
+              curroffset:=def.vmt_offset + sizeof(aint);
+            end;
+          for i:=1 to def.size-curroffset do
+            list.concat(Tai_const.Create_8bit(0));
+          consume(_RKLAMMER);
+        end;
 
-         { Add symbol name if this is specified. For array
-           elements sym=nil and we should skip this }
-         if assigned(sym) then
-           begin
-             storefilepos:=current_filepos;
-             current_filepos:=sym.fileinfo;
-             { insert cut for smartlinking or alignment }
-             if writable then
-               cursectype:=sec_data
-             else
-               cursectype:=sec_rodata;
-             maybe_new_object_file(list);
-             new_section(list,cursectype,lower(sym.mangledname),const_align(def.alignment));
-             if (sym.owner.symtabletype=globalsymtable) or
-                maybe_smartlink_symbol or
-                (assigned(current_procinfo) and
-                 (po_inline in current_procinfo.procdef.procoptions)) or
-                DLLSource then
-               list.concat(Tai_symbol.Createname_global(sym.mangledname,AT_DATA,0))
-             else
-               list.concat(Tai_symbol.Createname(sym.mangledname,AT_DATA,0));
-             list.concatlist(datalist);
-             list.concat(tai_symbol_end.Createname(sym.mangledname));
-             current_filepos:=storefilepos;
-           end
-         else
-           list.concatlist(datalist);
-         datalist.free;
+      var
+        old_block_type : tblock_type;
+      begin
+        old_block_type:=block_type;
+        block_type:=bt_const;
+        case def.typ of
+          orddef :
+            parse_orddef(list,torddef(def));
+          floatdef :
+            parse_floatdef(list,tfloatdef(def));
+          classrefdef :
+            parse_classrefdef(list,tclassrefdef(def));
+          pointerdef :
+            parse_pointerdef(list,tpointerdef(def));
+          setdef :
+            parse_setdef(list,tsetdef(def));
+          enumdef :
+            parse_enumdef(list,tenumdef(def));
+          stringdef :
+            parse_stringdef(list,tstringdef(def));
+          arraydef :
+            parse_arraydef(list,tarraydef(def));
+          procvardef:
+            parse_procvardef(list,tprocvardef(def));
+          recorddef:
+            parse_recorddef(list,trecorddef(def));
+          objectdef:
+            parse_objectdef(list,tobjectdef(def));
+          errordef:
+            begin
+               { try to consume something useful }
+               if token=_LKLAMMER then
+                 consume_all_until(_RKLAMMER)
+               else
+                 consume_all_until(_SEMICOLON);
+            end;
+          else
+            Message(parser_e_type_const_not_possible);
+        end;
+        block_type:=old_block_type;
       end;
 
 {$maxfpuregisters default}
 
+    procedure read_typed_const(list:tasmlist;sym:tstaticvarsym);
+      var
+        storefilepos : tfileposinfo;
+        cursectype   : TAsmSectionType;
+        C_name       : string;
+      begin
+        { mark the staticvarsym as typedconst }
+        include(sym.varoptions,vo_is_typed_const);
+        { the variable is declared }
+        sym.varstate:=vs_declared;
+        { the variable can't be placed in a register }
+        sym.varregable:=vr_none;
+
+        { generate data for typed const }
+        storefilepos:=current_filepos;
+        current_filepos:=sym.fileinfo;
+        if sym.varspez=vs_const then
+          cursectype:=sec_rodata
+        else
+          cursectype:=sec_data;
+        maybe_new_object_file(list);
+        new_section(list,cursectype,lower(sym.mangledname),const_align(sym.vardef.alignment));
+        if (sym.owner.symtabletype=globalsymtable) or
+           maybe_smartlink_symbol or
+           (assigned(current_procinfo) and
+            (po_inline in current_procinfo.procdef.procoptions)) or
+           DLLSource then
+          list.concat(Tai_symbol.Createname_global(sym.mangledname,AT_DATA,0))
+        else
+          list.concat(Tai_symbol.Createname(sym.mangledname,AT_DATA,0));
+        read_typed_const_data(list,sym.vardef);
+        list.concat(tai_symbol_end.Createname(sym.mangledname));
+        current_filepos:=storefilepos;
+
+        { Parse hints }
+        try_consume_hintdirective(sym.symoptions);
+
+        { Support public name directive }
+        if try_to_consume(_PUBLIC) then
+          begin
+            include(sym.varoptions,vo_is_public);
+            if try_to_consume(_NAME) then
+              C_name:=get_stringconst
+            else
+              C_name:=sym.realname;
+            sym.set_mangledname(C_Name);
+          end;
+      end;
+
 end.

+ 3 - 7
compiler/raatt.pas

@@ -1350,12 +1350,10 @@ unit raatt;
                       if assigned(sym) then
                        begin
                          case sym.typ of
-                           globalvarsym,
+                           staticvarsym,
                            localvarsym,
                            paravarsym :
                              l:=tabstractvarsym(sym).getsize;
-                           typedconstsym :
-                             l:=ttypedconstsym(sym).getsize;
                            typesym :
                              l:=ttypesym(sym).typedef.size;
                            else
@@ -1401,13 +1399,11 @@ unit raatt;
                       if assigned(sym) then
                        begin
                          case sym.typ of
-                           globalvarsym :
-                             hs:=tglobalvarsym(sym).mangledname;
+                           staticvarsym :
+                             hs:=tstaticvarsym(sym).mangledname;
                            localvarsym,
                            paravarsym :
                              Message(asmr_e_no_local_or_para_allowed);
-                           typedconstsym :
-                             hs:=ttypedconstsym(sym).mangledname;
                            procsym :
                              begin
                                if Tprocsym(sym).ProcdefList.Count>1 then

+ 7 - 38
compiler/rautils.pas

@@ -791,7 +791,7 @@ Begin
         hasvar:=true;
         SetupVar:=true;
       end;
-    globalvarsym,
+    staticvarsym,
     localvarsym,
     paravarsym :
       begin
@@ -801,15 +801,14 @@ Begin
         inc(tabstractvarsym(sym).refs);
         { variable can't be placed in a register }
         tabstractvarsym(sym).varregable:=vr_none;
-        case sym.owner.symtabletype of
-          globalsymtable,
-          staticsymtable :
+        case sym.typ of
+          staticvarsym :
             begin
               initref;
-              opr.ref.symbol:=current_asmdata.RefAsmSymbol(tglobalvarsym(sym).mangledname);
+              opr.ref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(sym).mangledname);
             end;
-          parasymtable,
-          localsymtable :
+          paravarsym,
+          localvarsym :
             begin
               if opr.typ=OPR_REFERENCE then
                 begin
@@ -845,41 +844,13 @@ Begin
           orddef,
           enumdef,
           pointerdef,
-          arraydef,
           floatdef :
             SetSize(tabstractvarsym(sym).getsize,false);
-          (* makes no sense when using sse instructions (FK)
           arraydef :
             begin
               { for arrays try to get the element size, take care of
                 multiple indexes }
               harrdef:=tarraydef(tabstractvarsym(sym).vardef);
-              while assigned(harrdef.elementdef) and
-                    (harrdef.elementdef.typ=arraydef) do
-               harrdef:=tarraydef(harrdef.elementdef);
-              SetSize(harrdef.elesize,false);
-            end;
-          *)
-        end;
-        hasvar:=true;
-        SetupVar:=true;
-        Exit;
-      end;
-    typedconstsym :
-      begin
-        initref;
-        opr.ref.symbol:=current_asmdata.RefAsmSymbol(ttypedconstsym(sym).mangledname);
-        case ttypedconstsym(sym).typedconstdef.typ of
-          orddef,
-          enumdef,
-          pointerdef,
-          floatdef :
-            SetSize(ttypedconstsym(sym).getsize,false);
-          arraydef :
-            begin
-              { for arrays try to get the element size, take care of
-                multiple indexes }
-              harrdef:=tarraydef(ttypedconstsym(sym).typedconstdef);
               while assigned(harrdef.elementdef) and
                     (harrdef.elementdef.typ=arraydef) do
                harrdef:=tarraydef(harrdef.elementdef);
@@ -1306,14 +1277,12 @@ Begin
      { we can start with a var,type,typedconst }
      if assigned(sym) then
        case sym.typ of
-         globalvarsym,
+         staticvarsym,
          localvarsym,
          paravarsym :
            st:=Tabstractvarsym(sym).vardef.GetSymtable(gs_record);
          typesym :
            st:=Ttypesym(sym).typedef.GetSymtable(gs_record);
-         typedconstsym :
-           st:=Ttypedconstsym(sym).typedconstdef.GetSymtable(gs_record);
        end
      else
        s:='';

+ 1 - 3
compiler/scanner.pas

@@ -837,12 +837,10 @@ In case not, the value returned can be arbitrary.
                         begin
                           l:=0;
                           case srsym.typ of
-                            globalvarsym,
+                            staticvarsym,
                             localvarsym,
                             paravarsym :
                               l:=tabstractvarsym(srsym).getsize;
-                            typedconstsym :
-                              l:=ttypedconstsym(srsym).getsize;
                             typesym:
                               l:=ttypesym(srsym).typedef.size;
                             else

+ 6 - 6
compiler/symconst.pas

@@ -333,13 +333,12 @@ type
 
   { options for variables }
   tvaroption=(vo_none,
-    vo_is_C_var,
     vo_is_external,
     vo_is_dll_var,
     vo_is_thread_var,
     vo_has_local_copy,
     vo_is_const,  { variable is declared as const (parameter) and can't be written to }
-    vo_is_exported,
+    vo_is_public,
     vo_is_high_para,
     vo_is_funcret,
     vo_is_self,
@@ -350,7 +349,8 @@ type
     vo_is_hidden_para,
     vo_has_explicit_paraloc,
     vo_is_syscall_lib,
-    vo_has_mangledname
+    vo_has_mangledname,
+    vo_is_typed_const
   );
   tvaroptions=set of tvaroption;
 
@@ -384,8 +384,8 @@ type
 
   { possible types for symtable entries }
   tsymtyp = (abstractsym,
-    globalvarsym,localvarsym,paravarsym,fieldvarsym,
-    typesym,procsym,unitsym,constsym,enumsym,typedconstsym,
+    staticvarsym,localvarsym,paravarsym,fieldvarsym,
+    typesym,procsym,unitsym,constsym,enumsym,
     errorsym,syssym,labelsym,absolutevarsym,propertysym,
     macrosym
   );
@@ -441,7 +441,7 @@ const
 
      SymTypeName : array[tsymtyp] of string[12] = (
        'abstractsym','globalvar','localvar','paravar','fieldvar',
-       'type','proc','unit','const','enum','typed const',
+       'type','proc','unit','const','enum',
        'errorsym','system sym','label','absolutevar','property',
        'macrosym'
      );

+ 23 - 131
compiler/symsym.pas

@@ -182,7 +182,7 @@ interface
           procedure ppuwrite(ppufile:tcompilerppufile);override;
       end;
 
-      tglobalvarsym = class(tabstractnormalvarsym)
+      tstaticvarsym = class(tabstractnormalvarsym)
       private
           _mangledname : pshortstring;
       public
@@ -237,24 +237,6 @@ interface
           procedure deref;override;
        end;
 
-       ttypedconstsym = class(tstoredsym)
-       private
-          _mangledname : pshortstring;
-       public
-          typedconstdef  : tdef;
-          typedconstdefderef : tderef;
-          is_writable     : boolean;
-          constructor create(const n : string;def : tdef;writable : boolean);
-          constructor ppuload(ppufile:tcompilerppufile);
-          destructor destroy;override;
-          function  mangledname : string;override;
-          procedure ppuwrite(ppufile:tcompilerppufile);override;
-          procedure buildderef;override;
-          procedure deref;override;
-          function  getsize:longint;
-          procedure set_mangledname(const s:string);
-       end;
-
        tconstvalue = record
          case integer of
          0: (valueord : tconstexprint);
@@ -444,13 +426,8 @@ implementation
 ****************************************************************************}
 
     constructor tunitsym.create(const n : string;amodule : tobject);
-      var
-        old_make_ref : boolean;
       begin
-         old_make_ref:=make_ref;
-         make_ref:=false;
          inherited create(unitsym,n);
-         make_ref:=old_make_ref;
          module:=amodule;
       end;
 
@@ -1204,32 +1181,32 @@ implementation
 
 
 {****************************************************************************
-                             TGLOBALVARSYM
+                             Tstaticvarsym
 ****************************************************************************}
 
-    constructor tglobalvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
+    constructor tstaticvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
       begin
-         inherited create(globalvarsym,n,vsp,def,vopts);
+         inherited create(staticvarsym,n,vsp,def,vopts);
          _mangledname:=nil;
       end;
 
 
-    constructor tglobalvarsym.create_dll(const n : string;vsp:tvarspez;def:tdef);
+    constructor tstaticvarsym.create_dll(const n : string;vsp:tvarspez;def:tdef);
       begin
-         tglobalvarsym(self).create(n,vsp,def,[vo_is_dll_var]);
+         tstaticvarsym(self).create(n,vsp,def,[vo_is_dll_var]);
       end;
 
 
-    constructor tglobalvarsym.create_C(const n,mangled : string;vsp:tvarspez;def:tdef);
+    constructor tstaticvarsym.create_C(const n,mangled : string;vsp:tvarspez;def:tdef);
       begin
-         tglobalvarsym(self).create(n,vsp,def,[]);
+         tstaticvarsym(self).create(n,vsp,def,[]);
          set_mangledname(mangled);
       end;
 
 
-    constructor tglobalvarsym.ppuload(ppufile:tcompilerppufile);
+    constructor tstaticvarsym.ppuload(ppufile:tcompilerppufile);
       begin
-         inherited ppuload(globalvarsym,ppufile);
+         inherited ppuload(staticvarsym,ppufile);
          if vo_has_mangledname in varoptions then
            _mangledname:=stringdup(ppufile.getstring)
          else
@@ -1237,7 +1214,7 @@ implementation
       end;
 
 
-    destructor tglobalvarsym.destroy;
+    destructor tstaticvarsym.destroy;
       begin
         if assigned(_mangledname) then
           begin
@@ -1253,30 +1230,36 @@ implementation
       end;
 
 
-    procedure tglobalvarsym.ppuwrite(ppufile:tcompilerppufile);
+    procedure tstaticvarsym.ppuwrite(ppufile:tcompilerppufile);
       begin
          inherited ppuwrite(ppufile);
          if vo_has_mangledname in varoptions then
            ppufile.putstring(_mangledname^);
-         ppufile.writeentry(ibglobalvarsym);
+         ppufile.writeentry(ibstaticvarsym);
       end;
 
 
-    function tglobalvarsym.mangledname:string;
+    function tstaticvarsym.mangledname:string;
+      var
+        prefix : string[2];
       begin
         if not assigned(_mangledname) then
           begin
+            if (vo_is_typed_const in varoptions) then
+              prefix:='TC'
+            else
+              prefix:='U';
       {$ifdef compress}
-            _mangledname:=stringdup(minilzw_encode(make_mangledname('U',owner,name)));
+            _mangledname:=stringdup(minilzw_encode(make_mangledname(prefix,owner,name)));
       {$else}
-           _mangledname:=stringdup(make_mangledname('U',owner,name));
+           _mangledname:=stringdup(make_mangledname(prefix,owner,name));
       {$endif}
           end;
         result:=_mangledname^;
       end;
 
 
-    procedure tglobalvarsym.set_mangledname(const s:string);
+    procedure tstaticvarsym.set_mangledname(const s:string);
       begin
         stringdispose(_mangledname);
       {$ifdef compress}
@@ -1489,97 +1472,6 @@ implementation
       end;
 
 
-{****************************************************************************
-                             TTYPEDCONSTSYM
-*****************************************************************************}
-
-    constructor ttypedconstsym.create(const n : string;def : tdef;writable : boolean);
-      begin
-         inherited create(typedconstsym,n);
-         typedconstdef:=def;
-         is_writable:=writable;
-      end;
-
-
-    constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
-      begin
-         inherited ppuload(typedconstsym,ppufile);
-         ppufile.getderef(typedconstdefderef);
-         is_writable:=boolean(ppufile.getbyte);
-      end;
-
-
-    destructor ttypedconstsym.destroy;
-      begin
-        if assigned(_mangledname) then
-          begin
-{$ifdef MEMDEBUG}
-            memmanglednames.start;
-{$endif MEMDEBUG}
-            stringdispose(_mangledname);
-{$ifdef MEMDEBUG}
-            memmanglednames.stop;
-{$endif MEMDEBUG}
-          end;
-         inherited destroy;
-      end;
-
-
-    function ttypedconstsym.mangledname:string;
-      begin
-        if not assigned(_mangledname) then
-          begin
-      {$ifdef compress}
-            _mangledname:=stringdup(make_mangledname('TC',owner,name));
-      {$else}
-            _mangledname:=stringdup(make_mangledname('TC',owner,name));
-      {$endif}
-          end;
-        result:=_mangledname^;
-      end;
-
-
-    procedure ttypedconstsym.set_mangledname(const s:string);
-      begin
-        stringdispose(_mangledname);
-      {$ifdef compress}
-        _mangledname:=stringdup(minilzw_encode(s));
-      {$else}
-        _mangledname:=stringdup(s);
-      {$endif}
-      end;
-
-
-    function ttypedconstsym.getsize : longint;
-      begin
-        if assigned(typedconstdef) then
-         getsize:=typedconstdef.size
-        else
-         getsize:=0;
-      end;
-
-
-    procedure ttypedconstsym.buildderef;
-      begin
-        typedconstdefderef.build(typedconstdef);
-      end;
-
-
-    procedure ttypedconstsym.deref;
-      begin
-        typedconstdef:=tdef(typedconstdefderef.resolve);
-      end;
-
-
-    procedure ttypedconstsym.ppuwrite(ppufile:tcompilerppufile);
-      begin
-         inherited ppuwrite(ppufile);
-         ppufile.putderef(typedconstdefderef);
-         ppufile.putbyte(byte(is_writable));
-         ppufile.writeentry(ibtypedconstsym);
-      end;
-
-
 {****************************************************************************
                                   TCONSTSYM
 ****************************************************************************}

+ 5 - 12
compiler/symtable.pas

@@ -354,13 +354,12 @@ implementation
                 ibtypesym : sym:=ttypesym.ppuload(ppufile);
                 ibprocsym : sym:=tprocsym.ppuload(ppufile);
                ibconstsym : sym:=tconstsym.ppuload(ppufile);
-           ibglobalvarsym : sym:=tglobalvarsym.ppuload(ppufile);
+           ibstaticvarsym : sym:=tstaticvarsym.ppuload(ppufile);
             iblocalvarsym : sym:=tlocalvarsym.ppuload(ppufile);
              ibparavarsym : sym:=tparavarsym.ppuload(ppufile);
             ibfieldvarsym : sym:=tfieldvarsym.ppuload(ppufile);
          ibabsolutevarsym : sym:=tabsolutevarsym.ppuload(ppufile);
                 ibenumsym : sym:=tenumsym.ppuload(ppufile);
-          ibtypedconstsym : sym:=ttypedconstsym.ppuload(ppufile);
             ibpropertysym : sym:=tpropertysym.ppuload(ppufile);
                 ibunitsym : sym:=tunitsym.ppuload(ppufile);
                iblabelsym : sym:=tlabelsym.ppuload(ppufile);
@@ -549,7 +548,7 @@ implementation
 
     procedure TStoredSymtable.varsymbolused(sym:TObject;arg:pointer);
       begin
-         if (tsym(sym).typ in [globalvarsym,localvarsym,paravarsym,fieldvarsym]) and
+         if (tsym(sym).typ in [staticvarsym,localvarsym,paravarsym,fieldvarsym]) and
             ((tsym(sym).owner.symtabletype in
              [parasymtable,localsymtable,ObjectSymtable,staticsymtable])) then
           begin
@@ -587,12 +586,12 @@ implementation
                   end
                 else if (tsym(sym).owner.symtabletype=ObjectSymtable) then
                   MessagePos2(tsym(sym).fileinfo,sym_n_private_identifier_only_set,tsym(sym).owner.realname^,tsym(sym).realname)
-                else if not(vo_is_exported in tabstractvarsym(sym).varoptions) and
+                else if not(vo_is_public in tabstractvarsym(sym).varoptions) and
                         not(vo_is_funcret in tabstractvarsym(sym).varoptions) then
                   MessagePos1(tsym(sym).fileinfo,sym_n_local_identifier_only_set,tsym(sym).realname);
              end
            else if (tabstractvarsym(sym).varstate = vs_read_not_warned) and
-                   ([vo_is_exported,vo_is_external] * tabstractvarsym(sym).varoptions = []) then
+                   ([vo_is_public,vo_is_external] * tabstractvarsym(sym).varoptions = []) then
              MessagePos1(tsym(sym).fileinfo,sym_w_identifier_only_read,tsym(sym).realname)
          end
       else if ((tsym(sym).owner.symtabletype in
@@ -702,7 +701,7 @@ implementation
           exit;
          case tsym(sym).typ of
            fieldvarsym,
-           globalvarsym,
+           staticvarsym,
            localvarsym,
            paravarsym :
              begin
@@ -710,12 +709,6 @@ implementation
                   tstoreddef(tabstractvarsym(sym).vardef).needs_inittable then
                  b_needs_init_final:=true;
              end;
-           typedconstsym :
-             begin
-               if ttypedconstsym(sym).is_writable and
-                  tstoreddef(ttypedconstsym(sym).typedconstdef).needs_inittable then
-                 b_needs_init_final:=true;
-             end;
          end;
       end;
 

+ 4 - 8
compiler/systems/t_win.pas

@@ -826,10 +826,8 @@ implementation
                    inc(current_index);
                 end;
               case hp.sym.typ of
-                globalvarsym :
-                  address_table.concat(Tai_const.Createname_rva(tglobalvarsym(hp.sym).mangledname));
-                typedconstsym :
-                  address_table.concat(Tai_const.Createname_rva(ttypedconstsym(hp.sym).mangledname));
+                staticvarsym :
+                  address_table.concat(Tai_const.Createname_rva(tstaticvarsym(hp.sym).mangledname));
                 procsym :
                   address_table.concat(Tai_const.Createname_rva(tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname));
               end;
@@ -860,10 +858,8 @@ implementation
          while assigned(hp) do
            begin
              case hp.sym.typ of
-               globalvarsym :
-                 s:=tglobalvarsym(hp.sym).mangledname;
-               typedconstsym :
-                 s:=ttypedconstsym(hp.sym).mangledname;
+               staticvarsym :
+                 s:=tstaticvarsym(hp.sym).mangledname;
                procsym :
                  s:=tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname;
                else

+ 14 - 19
compiler/utils/ppudump.pp

@@ -1139,13 +1139,12 @@ end;
 type
   { options for variables }
   tvaroption=(vo_none,
-    vo_is_C_var,
     vo_is_external,
     vo_is_dll_var,
     vo_is_thread_var,
     vo_has_local_copy,
     vo_is_const,  { variable is declared as const (parameter) and can't be written to }
-    vo_is_exported,
+    vo_is_public,
     vo_is_high_para,
     vo_is_funcret,
     vo_is_self,
@@ -1156,14 +1155,16 @@ type
     vo_is_hidden_para,
     vo_has_explicit_paraloc,
     vo_is_syscall_lib,
-    vo_has_mangledname
+    vo_has_mangledname,
+    vo_is_typed_const
   );
   tvaroptions=set of tvaroption;
   { register variable }
   tvarregable=(vr_none,
     vr_intreg,
     vr_fpureg,
-    vr_mmreg
+    vr_mmreg,
+    vr_addr
   );
 procedure readabstractvarsym(const s:string;var varoptions:tvaroptions);
 type
@@ -1174,13 +1175,12 @@ type
 const
   varopts=18;
   varopt : array[1..varopts] of tvaropt=(
-     (mask:vo_is_C_var;        str:'CVar'),
      (mask:vo_is_external;     str:'External'),
      (mask:vo_is_dll_var;      str:'DLLVar'),
      (mask:vo_is_thread_var;   str:'ThreadVar'),
      (mask:vo_has_local_copy;  str:'HasLocalCopy'),
      (mask:vo_is_const;        str:'Constant'),
-     (mask:vo_is_exported;     str:'Exported'),
+     (mask:vo_is_public;       str:'Public'),
      (mask:vo_is_high_para;    str:'HighValue'),
      (mask:vo_is_funcret;      str:'Funcret'),
      (mask:vo_is_self;         str:'Self'),
@@ -1191,7 +1191,8 @@ const
      (mask:vo_is_hidden_para;  str:'Hidden'),
      (mask:vo_has_explicit_paraloc;str:'ExplicitParaloc'),
      (mask:vo_is_syscall_lib;  str:'SysCallLib'),
-     (mask:vo_has_mangledname; str:'HasMangledName')
+     (mask:vo_has_mangledname; str:'HasMangledName'),
+     (mask:vo_is_typed_const;  str:'TypedConst')
   );
 var
   i : longint;
@@ -1236,7 +1237,8 @@ type
     oo_has_msgstr,
     oo_has_msgint,
     oo_can_have_published,{ the class has rtti, i.e. you can publish properties }
-    oo_has_default_property
+    oo_has_default_property,
+    oo_vmt_written
   );
   tobjectoptions=set of tobjectoption;
   tsymopt=record
@@ -1244,7 +1246,7 @@ type
     str  : string[30];
   end;
 const
-  symopts=13;
+  symopts=14;
   symopt : array[1..symopts] of tsymopt=(
      (mask:oo_has_virtual;        str:'IsForward'),
      (mask:oo_has_virtual;        str:'HasVirtual'),
@@ -1258,7 +1260,8 @@ const
      (mask:oo_has_msgstr;         str:'HasMsgStr'),
      (mask:oo_has_msgint;         str:'HasMsgInt'),
      (mask:oo_can_have_published; str:'CanHavePublished'),
-     (mask:oo_has_default_property;str:'HasDefaultProperty')
+     (mask:oo_has_default_property;str:'HasDefaultProperty'),
+     (mask:oo_vmt_written;        str:'VMTWritten')
   );
 var
   symoptions : tobjectoptions;
@@ -1518,7 +1521,7 @@ begin
              writeln(space,'      Address : ',getaint);
            end;
 
-         ibglobalvarsym :
+         ibstaticvarsym :
            begin
              readabstractvarsym('Global Variable symbol ',varoptions);
              write  (space,' DefaultConst : ');
@@ -1580,14 +1583,6 @@ begin
                end;
            end;
 
-         ibtypedconstsym :
-           begin
-             readcommonsym('Typed constant ');
-             write  (space,'  Constant Type : ');
-             readderef;
-             writeln(space,'    ReallyConst : ',(getbyte<>0));
-           end;
-
          ibpropertysym :
            begin
              readcommonsym('Property ');

+ 4 - 11
compiler/x86/rax86int.pas

@@ -872,12 +872,10 @@ Unit Rax86int;
                       if assigned(sym) then
                        begin
                          case sym.typ of
-                           globalvarsym,
+                           staticvarsym,
                            localvarsym,
                            paravarsym :
                              l:=tabstractvarsym(sym).getsize;
-                           typedconstsym :
-                             l:=ttypedconstsym(sym).getsize;
                            typesym :
                              l:=ttypesym(sym).typedef.size;
                            else
@@ -957,21 +955,16 @@ Unit Rax86int;
                       if assigned(sym) then
                        begin
                          case sym.typ of
-                           globalvarsym :
+                           staticvarsym :
                              begin
-                               hs:=tglobalvarsym(sym).mangledname;
-                               def:=tglobalvarsym(sym).vardef;
+                               hs:=tstaticvarsym(sym).mangledname;
+                               def:=tstaticvarsym(sym).vardef;
                              end;
                            localvarsym,
                            paravarsym :
                              begin
                                Message(asmr_e_no_local_or_para_allowed);
                              end;
-                           typedconstsym :
-                             begin
-                               hs:=ttypedconstsym(sym).mangledname;
-                               def:=ttypedconstsym(sym).typedconstdef;
-                             end;
                            procsym :
                              begin
                                if Tprocsym(sym).ProcdefList.Count>1 then

+ 2 - 2
ide/fpsymbol.pas

@@ -499,7 +499,7 @@ begin
     exit;
   if not Debugger^.IsRunning then
     exit;
-  if (S^.typ in [fieldvarsym,globalvarsym,localvarsym,paravarsym]) or (GDBI=Debugger^.RunCount) then
+  if (S^.typ in [fieldvarsym,staticvarsym,localvarsym,paravarsym]) or (GDBI=Debugger^.RunCount) then
     exit;
   If Assigned(St) then
     DisposeStr(St);
@@ -1829,7 +1829,7 @@ begin
   PB:=New(PBrowserWindow, Init(R,
     st2,SearchFreeWindowNo,S,Line,st,
     Symbols,References,Inheritance,MemInfo));
-  if (assigned(S) and (S^.typ in [fieldvarsym,globalvarsym,localvarsym,paravarsym])) or
+  if (assigned(S) and (S^.typ in [fieldvarsym,staticvarsym,localvarsym,paravarsym])) or
      (assigned(ParentBrowser) and ParentBrowser^.IsValid) then
     PB^.IsValid:=true;