Przeglądaj źródła

* Moved handling of comments and line breaks in assembler blocks from scanner to tokenizer level. Handling them at character level was causing compiler to accept comments in the middle of any assembler token, which should never happen. It was also causing Mantis #27459: a newline immediately after closing 'end' token was first handled in asmgetchar and then by normal parser, causing all subsequent line numbering to be off by one.

git-svn-id: trunk@32828 -
sergei 9 lat temu
rodzic
commit
bbfbab7e0c
4 zmienionych plików z 106 dodań i 94 usunięć
  1. 25 6
      compiler/m68k/ra68kmot.pas
  2. 45 13
      compiler/raatt.pas
  3. 1 69
      compiler/scanner.pas
  4. 35 6
      compiler/x86/rax86int.pas

+ 25 - 6
compiler/m68k/ra68kmot.pas

@@ -238,6 +238,7 @@ const
    token: tasmtoken;
    token: tasmtoken;
    forcelabel: boolean;
    forcelabel: boolean;
   begin
   begin
+    c:=scanner.c;
     forcelabel := FALSE;
     forcelabel := FALSE;
     actasmpattern :='';
     actasmpattern :='';
     {* INIT TOKEN TO NOTHING *}
     {* INIT TOKEN TO NOTHING *}
@@ -246,11 +247,11 @@ const
     while c in [' ',#9] do
     while c in [' ',#9] do
      c:=current_scanner.asmgetchar;
      c:=current_scanner.asmgetchar;
 
 
-    if not (c in [#10,#13,'{',';']) then
+    if not (c in [#10,#13,'{',';','(','/']) then
      current_scanner.gettokenpos;
      current_scanner.gettokenpos;
     { Possiblities for first token in a statement:                }
     { Possiblities for first token in a statement:                }
     {   Local Label, Label, Directive, Prefix or Opcode....       }
     {   Local Label, Label, Directive, Prefix or Opcode....       }
-    if firsttoken and not (c in [#10,#13,'{',';']) then
+    if firsttoken and not (c in [#10,#13,'{',';','(','/']) then
     begin
     begin
 
 
       firsttoken := FALSE;
       firsttoken := FALSE;
@@ -414,8 +415,15 @@ const
                    exit;
                    exit;
                  end;
                  end;
            '(' : begin
            '(' : begin
-                   actasmtoken := AS_LPAREN;
                    c:=current_scanner.asmgetchar;
                    c:=current_scanner.asmgetchar;
+                   if c='*' then
+                     begin
+                       scanner.c:=#0;{Signal skipoldtpcomment to reload a char }
+                       current_scanner.skipoldtpcomment;
+                       GetToken;
+                     end
+                   else
+                     actasmtoken:=AS_LPAREN;
                    exit;
                    exit;
                  end;
                  end;
            ')' : begin
            ')' : begin
@@ -449,8 +457,14 @@ const
                    exit;
                    exit;
                  end;
                  end;
            '/' : begin
            '/' : begin
-                   actasmtoken := AS_SLASH;
                    c:=current_scanner.asmgetchar;
                    c:=current_scanner.asmgetchar;
+                   if c='/' then
+                     begin
+                       current_scanner.skipdelphicomment;
+                       GetToken;
+                     end
+                   else
+                     actasmtoken := AS_SLASH;
                    exit;
                    exit;
                  end;
                  end;
            '<' : begin
            '<' : begin
@@ -518,7 +532,13 @@ const
                   actasmtoken:=AS_SEPARATOR;
                   actasmtoken:=AS_SEPARATOR;
                end;
                end;
 
 
-         '{',#13,#10 : begin
+         '{' : begin
+                 current_scanner.skipcomment;
+                 GetToken;
+               end;
+
+         #13,#10 : begin
+                            current_scanner.linebreak;
                             c:=current_scanner.asmgetchar;
                             c:=current_scanner.asmgetchar;
                             firsttoken := TRUE;
                             firsttoken := TRUE;
                             actasmtoken:=AS_SEPARATOR;
                             actasmtoken:=AS_SEPARATOR;
@@ -1749,7 +1769,6 @@ const
             _asmsorted := TRUE;
             _asmsorted := TRUE;
           end;
           end;
         curlist:=TAsmList.Create;
         curlist:=TAsmList.Create;
-        c:=current_scanner.asmgetchar;
         gettoken;
         gettoken;
         while actasmtoken<>AS_END do
         while actasmtoken<>AS_END do
           begin
           begin

+ 45 - 13
compiler/raatt.pas

@@ -203,6 +203,7 @@ unit raatt;
         srsym : tsym;
         srsym : tsym;
         srsymtable : TSymtable;
         srsymtable : TSymtable;
       begin
       begin
+        c:=scanner.c;
         { save old token and reset new token }
         { save old token and reset new token }
         prevasmtoken:=actasmtoken;
         prevasmtoken:=actasmtoken;
         actasmtoken:=AS_NONE;
         actasmtoken:=AS_NONE;
@@ -212,10 +213,10 @@ unit raatt;
         while c in [' ',#9] do
         while c in [' ',#9] do
          c:=current_scanner.asmgetchar;
          c:=current_scanner.asmgetchar;
         { get token pos }
         { get token pos }
-        if not (c in [#10,#13,'{',';']) then
+        if not (c in [#10,#13,'{',';','/','(']) then
           current_scanner.gettokenpos;
           current_scanner.gettokenpos;
         { Local Label, Label, Directive, Prefix or Opcode }
         { Local Label, Label, Directive, Prefix or Opcode }
-        if firsttoken and not(c in [#10,#13,'{',';']) then
+        if firsttoken and not(c in [#10,#13,'{',';','/','(']) then
          begin
          begin
            firsttoken:=FALSE;
            firsttoken:=FALSE;
            len:=0;
            len:=0;
@@ -659,15 +660,29 @@ unit raatt;
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
                  exit;
                  exit;
                end;
                end;
-{$ifdef arm}
-             // the arm assembler uses { ... } for register sets
+
              '{' :
              '{' :
                begin
                begin
-                 actasmtoken:=AS_LSBRACKET;
+{$ifdef arm}
+                 // the arm assembler uses { ... } for register sets
+                 // but compiler directives {$... } are still allowed
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
+                 if c<>'$' then
+                   actasmtoken:=AS_LSBRACKET
+                 else
+                   begin
+                     dec(current_scanner.inputpointer);
+                     current_scanner.skipcomment;
+                     GetToken;
+                   end;
+{$else arm}
+                 current_scanner.skipcomment;
+                 GetToken;
+{$endif arm}
                  exit;
                  exit;
                end;
                end;
 
 
+{$ifdef arm}
              '}' :
              '}' :
                begin
                begin
                  actasmtoken:=AS_RSBRACKET;
                  actasmtoken:=AS_RSBRACKET;
@@ -725,8 +740,15 @@ unit raatt;
 
 
              '(' :
              '(' :
                begin
                begin
-                 actasmtoken:=AS_LPAREN;
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
+                 if c='*' then
+                   begin
+                     scanner.c:=#0;{Signal skipoldtpcomment to reload a char }
+                     current_scanner.skipoldtpcomment;
+                     GetToken;
+                   end
+                 else
+                   actasmtoken:=AS_LPAREN;
                  exit;
                  exit;
                end;
                end;
 
 
@@ -767,8 +789,14 @@ unit raatt;
 
 
              '/' :
              '/' :
                begin
                begin
-                 actasmtoken:=AS_SLASH;
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
+                 if c='/' then
+                   begin
+                     current_scanner.skipdelphicomment;
+                     GetToken;
+                   end
+                 else
+                   actasmtoken:=AS_SLASH;
                  exit;
                  exit;
                end;
                end;
 
 
@@ -786,12 +814,17 @@ unit raatt;
                  exit;
                  exit;
                end;
                end;
 
 
-{$ifndef arm}
-             '{',
-{$endif arm}
-             #13,#10,';' :
+             #13,#10:
+               begin
+                 current_scanner.linebreak;
+                 c:=current_scanner.asmgetchar;
+                 firsttoken:=TRUE;
+                 actasmtoken:=AS_SEPARATOR;
+                 exit;
+               end;
+
+             ';' :
                begin
                begin
-                 { the comment is read by asmgetchar }
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
                  firsttoken:=TRUE;
                  firsttoken:=TRUE;
                  actasmtoken:=AS_SEPARATOR;
                  actasmtoken:=AS_SEPARATOR;
@@ -1024,7 +1057,6 @@ unit raatt;
        curlist:=TAsmList.Create;
        curlist:=TAsmList.Create;
        lasTSec:=sec_code;
        lasTSec:=sec_code;
        { start tokenizer }
        { start tokenizer }
-       c:=current_scanner.asmgetcharstart;
        gettoken;
        gettoken;
        { main loop }
        { main loop }
        repeat
        repeat

+ 1 - 69
compiler/scanner.pas

@@ -136,7 +136,6 @@ interface
 
 
           comment_level,
           comment_level,
           yylexcount     : longint;
           yylexcount     : longint;
-          lastasmgetchar : char;
           ignoredirectives : TFPHashList; { ignore directives, used to give warnings only once }
           ignoredirectives : TFPHashList; { ignore directives, used to give warnings only once }
           preprocstack   : tpreprocstack;
           preprocstack   : tpreprocstack;
           replaystack    : treplaystack;
           replaystack    : treplaystack;
@@ -221,7 +220,6 @@ interface
           procedure skipoldtpcomment;
           procedure skipoldtpcomment;
           procedure readtoken(allowrecordtoken:boolean);
           procedure readtoken(allowrecordtoken:boolean);
           function  readpreproc:ttoken;
           function  readpreproc:ttoken;
-          function  asmgetcharstart : char;
           function  asmgetchar:char;
           function  asmgetchar:char;
        end;
        end;
 
 
@@ -2650,7 +2648,6 @@ type
         nexttokenpos:=0;
         nexttokenpos:=0;
         lasttoken:=NOTOKEN;
         lasttoken:=NOTOKEN;
         nexttoken:=NOTOKEN;
         nexttoken:=NOTOKEN;
-        lastasmgetchar:=#0;
         ignoredirectives:=TFPHashList.Create;
         ignoredirectives:=TFPHashList.Create;
         in_asm_string:=false;
         in_asm_string:=false;
       end;
       end;
@@ -5498,24 +5495,9 @@ exit_label:
       end;
       end;
 
 
 
 
-    function tscannerfile.asmgetcharstart : char;
-      begin
-        { return first the character already
-          available in c }
-        lastasmgetchar:=c;
-        result:=asmgetchar;
-      end;
-
-
     function tscannerfile.asmgetchar : char;
     function tscannerfile.asmgetchar : char;
       begin
       begin
-         if lastasmgetchar<>#0 then
-          begin
-            c:=lastasmgetchar;
-            lastasmgetchar:=#0;
-          end
-         else
-          readchar;
+         readchar;
          if in_asm_string then
          if in_asm_string then
            begin
            begin
              asmgetchar:=c;
              asmgetchar:=c;
@@ -5523,29 +5505,6 @@ exit_label:
            end;
            end;
          repeat
          repeat
            case c of
            case c of
-             // the { ... } is used in ARM assembler to define register sets,  so we can't used
-             // it as comment, either (* ... *), /* ... */ or // ... should be used instead.
-             // But compiler directives {$...} are allowed in ARM assembler.
-             '{' :
-               begin
-{$ifdef arm}
-                 readchar;
-                 dec(inputpointer);
-                 if c<>'$' then
-                   begin
-                     asmgetchar:='{';
-                     exit;
-                   end
-                 else
-{$endif arm}
-                   skipcomment;
-               end;
-             #10,#13 :
-               begin
-                 linebreak;
-                 asmgetchar:=c;
-                 exit;
-               end;
              #26 :
              #26 :
                begin
                begin
                  reload;
                  reload;
@@ -5553,33 +5512,6 @@ exit_label:
                    end_of_file;
                    end_of_file;
                  continue;
                  continue;
                end;
                end;
-             '/' :
-               begin
-                  readchar;
-                  if c='/' then
-                   skipdelphicomment
-                  else
-                   begin
-                     asmgetchar:='/';
-                     lastasmgetchar:=c;
-                     exit;
-                   end;
-               end;
-             '(' :
-               begin
-                  readchar;
-                  if c='*' then
-                   begin
-                     c:=#0;{Signal skipoldtpcomment to reload a char }
-                     skipoldtpcomment;
-                   end
-                  else
-                   begin
-                     asmgetchar:='(';
-                     lastasmgetchar:=c;
-                     exit;
-                   end;
-               end;
              else
              else
                begin
                begin
                  asmgetchar:=c;
                  asmgetchar:=c;

+ 35 - 6
compiler/x86/rax86int.pas

@@ -263,6 +263,7 @@ Unit Rax86int;
         srsym : tsym;
         srsym : tsym;
         srsymtable : TSymtable;
         srsymtable : TSymtable;
       begin
       begin
+        c:=scanner.c;
         { save old token and reset new token }
         { save old token and reset new token }
         prevasmtoken:=actasmtoken;
         prevasmtoken:=actasmtoken;
         actasmtoken:=AS_NONE;
         actasmtoken:=AS_NONE;
@@ -273,10 +274,10 @@ Unit Rax86int;
         while (c in [' ',#9]) do
         while (c in [' ',#9]) do
           c:=current_scanner.asmgetchar;
           c:=current_scanner.asmgetchar;
         { get token pos }
         { get token pos }
-        if not (c in [#10,#13,'{',';']) then
+        if not (c in [#10,#13,'{',';','(','/']) then
           current_scanner.gettokenpos;
           current_scanner.gettokenpos;
       { Local Label, Label, Directive, Prefix or Opcode }
       { Local Label, Label, Directive, Prefix or Opcode }
-        if firsttoken and not (c in [#10,#13,'{',';']) then
+        if firsttoken and not (c in [#10,#13,'{',';','(','/']) then
          begin
          begin
            firsttoken:=FALSE;
            firsttoken:=FALSE;
            len:=0;
            len:=0;
@@ -571,8 +572,15 @@ Unit Rax86int;
 
 
              '(' :
              '(' :
                begin
                begin
-                 actasmtoken:=AS_LPAREN;
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
+                 if c='*' then
+                   begin
+                     scanner.c:=#0;{Signal skipoldtpcomment to reload a char }
+                     current_scanner.skipoldtpcomment;
+                     GetToken;
+                   end
+                 else
+                   actasmtoken:=AS_LPAREN;
                  exit;
                  exit;
                end;
                end;
 
 
@@ -638,8 +646,14 @@ Unit Rax86int;
 
 
              '/' :
              '/' :
                begin
                begin
-                 actasmtoken:=AS_SLASH;
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
+                 if c='/' then
+                   begin
+                     current_scanner.skipdelphicomment;
+                     GetToken;
+                   end
+                 else
+                   actasmtoken:=AS_SLASH;
                  exit;
                  exit;
                end;
                end;
 
 
@@ -691,14 +705,30 @@ Unit Rax86int;
                     end;
                     end;
                   end;
                   end;
                end;
                end;
-             ';','{',#13,#10 :
+
+             #13,#10:
                begin
                begin
+                 current_scanner.linebreak;
                  c:=current_scanner.asmgetchar;
                  c:=current_scanner.asmgetchar;
                  firsttoken:=TRUE;
                  firsttoken:=TRUE;
                  actasmtoken:=AS_SEPARATOR;
                  actasmtoken:=AS_SEPARATOR;
                  exit;
                  exit;
                end;
                end;
 
 
+             ';':
+               begin
+                 c:=current_scanner.asmgetchar;
+                 firsttoken:=TRUE;
+                 actasmtoken:=AS_SEPARATOR;
+                 exit;
+               end;
+
+             '{':
+               begin
+                 current_scanner.skipcomment;
+                 GetToken;
+               end;
+
               else
               else
                  current_scanner.illegal_char(c);
                  current_scanner.illegal_char(c);
            end;
            end;
@@ -2439,7 +2469,6 @@ Unit Rax86int;
       if not parse_generic then
       if not parse_generic then
         current_procinfo.generate_parameter_info;
         current_procinfo.generate_parameter_info;
       { start tokenizer }
       { start tokenizer }
-      c:=current_scanner.asmgetcharstart;
       gettoken;
       gettoken;
       { main loop }
       { main loop }
       repeat
       repeat