Browse Source

* Labels that are defined or referenced in a different lexical level
than their declaration need to be code generated as global asmlabels.

git-svn-id: trunk@9791 -

daniel 17 years ago
parent
commit
4ca3a590e8
5 changed files with 28 additions and 6 deletions
  1. 6 0
      compiler/aasmdata.pas
  2. 4 1
      compiler/ncgflw.pas
  3. 2 0
      compiler/pexpr.pas
  4. 8 3
      compiler/rautils.pas
  5. 8 2
      compiler/symsym.pas

+ 6 - 0
compiler/aasmdata.pas

@@ -135,6 +135,7 @@ interface
         { create new assembler label }
         { create new assembler label }
         procedure getlabel(out l : TAsmLabel;alt:TAsmLabeltype);
         procedure getlabel(out l : TAsmLabel;alt:TAsmLabeltype);
         procedure getjumplabel(out l : TAsmLabel);
         procedure getjumplabel(out l : TAsmLabel);
+        procedure getglobaljumplabel(out l : TAsmLabel);
         procedure getaddrlabel(out l : TAsmLabel);
         procedure getaddrlabel(out l : TAsmLabel);
         procedure getdatalabel(out l : TAsmLabel);
         procedure getdatalabel(out l : TAsmLabel);
         { generate an alternative (duplicate) symbol }
         { generate an alternative (duplicate) symbol }
@@ -397,6 +398,11 @@ implementation
         inc(FNextLabelNr[alt_jump]);
         inc(FNextLabelNr[alt_jump]);
       end;
       end;
 
 
+    procedure TAsmData.getglobaljumplabel(out l : TAsmLabel);
+      begin
+        l:=TAsmLabel.createglobal(AsmSymbolDict,name,FNextLabelNr[alt_jump],alt_jump);
+        inc(FNextLabelNr[alt_jump]);
+      end;
 
 
     procedure TAsmData.getdatalabel(out l : TAsmLabel);
     procedure TAsmData.getdatalabel(out l : TAsmLabel);
       begin
       begin

+ 4 - 1
compiler/ncgflw.pas

@@ -877,7 +877,10 @@ implementation
     function tcglabelnode.getasmlabel : tasmlabel;
     function tcglabelnode.getasmlabel : tasmlabel;
       begin
       begin
         if not(assigned(asmlabel)) then
         if not(assigned(asmlabel)) then
-          current_asmdata.getjumplabel(asmlabel);
+          if labsym.nonlocal then
+            current_asmdata.getglobaljumplabel(asmlabel)
+          else
+            current_asmdata.getjumplabel(asmlabel);
         result:=asmlabel
         result:=asmlabel
       end;
       end;
 
 

+ 2 - 0
compiler/pexpr.pas

@@ -1700,6 +1700,8 @@ implementation
                         consume(_COLON);
                         consume(_COLON);
                         if tlabelsym(srsym).defined then
                         if tlabelsym(srsym).defined then
                           Message(sym_e_label_already_defined);
                           Message(sym_e_label_already_defined);
+                        if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
+                          tlabelsym(srsym).nonlocal:=true;
                         tlabelsym(srsym).defined:=true;
                         tlabelsym(srsym).defined:=true;
                         p1:=clabelnode.create(nil,tlabelsym(srsym));
                         p1:=clabelnode.create(nil,tlabelsym(srsym));
                         tlabelsym(srsym).code:=p1;
                         tlabelsym(srsym).code:=p1;

+ 8 - 3
compiler/rautils.pas

@@ -1419,13 +1419,18 @@ Begin
   case sym.typ of
   case sym.typ of
     labelsym :
     labelsym :
       begin
       begin
+        if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
+          Tlabelsym(sym).nonlocal:=true;
         if not(assigned(tlabelsym(sym).asmblocklabel)) then
         if not(assigned(tlabelsym(sym).asmblocklabel)) then
-          current_asmdata.getjumplabel(tlabelsym(sym).asmblocklabel);
+          if Tlabelsym(sym).nonlocal then
+            current_asmdata.getglobaljumplabel(tlabelsym(sym).asmblocklabel)
+          else
+            current_asmdata.getjumplabel(tlabelsym(sym).asmblocklabel);
         hl:=tlabelsym(sym).asmblocklabel;
         hl:=tlabelsym(sym).asmblocklabel;
         if emit then
         if emit then
-         tlabelsym(sym).defined:=true
+          tlabelsym(sym).defined:=true
         else
         else
-         tlabelsym(sym).used:=true;
+          tlabelsym(sym).used:=true;
         SearchLabel:=true;
         SearchLabel:=true;
       end;
       end;
   end;
   end;

+ 8 - 2
compiler/symsym.pas

@@ -51,7 +51,8 @@ interface
 
 
        tlabelsym = class(tstoredsym)
        tlabelsym = class(tstoredsym)
           used,
           used,
-          defined : boolean;
+          defined,
+          nonlocal : boolean;
           { points to the matching node, only valid resultdef pass is run and
           { points to the matching node, only valid resultdef pass is run and
             the goto<->label relation in the node tree is created, should
             the goto<->label relation in the node tree is created, should
             be a tnode }
             be a tnode }
@@ -390,6 +391,7 @@ implementation
          inherited create(labelsym,n);
          inherited create(labelsym,n);
          used:=false;
          used:=false;
          defined:=false;
          defined:=false;
+         nonlocal:=false;
          code:=nil;
          code:=nil;
       end;
       end;
 
 
@@ -399,6 +401,7 @@ implementation
          inherited ppuload(labelsym,ppufile);
          inherited ppuload(labelsym,ppufile);
          code:=nil;
          code:=nil;
          used:=false;
          used:=false;
+         nonlocal:=false;
          defined:=true;
          defined:=true;
       end;
       end;
 
 
@@ -420,7 +423,10 @@ implementation
        if not(defined) then
        if not(defined) then
          begin
          begin
            defined:=true;
            defined:=true;
-           current_asmdata.getjumplabel(asmblocklabel);
+           if nonlocal then
+             current_asmdata.getglobaljumplabel(asmblocklabel)
+           else
+             current_asmdata.getjumplabel(asmblocklabel);
          end;
          end;
        result:=asmblocklabel.name;
        result:=asmblocklabel.name;
      end;
      end;