瀏覽代碼

* 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 年之前
父節點
當前提交
bbfbab7e0c
共有 4 個文件被更改,包括 106 次插入94 次删除
  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;
    forcelabel: boolean;
   begin
+    c:=scanner.c;
     forcelabel := FALSE;
     actasmpattern :='';
     {* INIT TOKEN TO NOTHING *}
@@ -246,11 +247,11 @@ const
     while c in [' ',#9] do
      c:=current_scanner.asmgetchar;
 
-    if not (c in [#10,#13,'{',';']) then
+    if not (c in [#10,#13,'{',';','(','/']) then
      current_scanner.gettokenpos;
     { Possiblities for first token in a statement:                }
     {   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
 
       firsttoken := FALSE;
@@ -414,8 +415,15 @@ const
                    exit;
                  end;
            '(' : begin
-                   actasmtoken := AS_LPAREN;
                    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;
                  end;
            ')' : begin
@@ -449,8 +457,14 @@ const
                    exit;
                  end;
            '/' : begin
-                   actasmtoken := AS_SLASH;
                    c:=current_scanner.asmgetchar;
+                   if c='/' then
+                     begin
+                       current_scanner.skipdelphicomment;
+                       GetToken;
+                     end
+                   else
+                     actasmtoken := AS_SLASH;
                    exit;
                  end;
            '<' : begin
@@ -518,7 +532,13 @@ const
                   actasmtoken:=AS_SEPARATOR;
                end;
 
-         '{',#13,#10 : begin
+         '{' : begin
+                 current_scanner.skipcomment;
+                 GetToken;
+               end;
+
+         #13,#10 : begin
+                            current_scanner.linebreak;
                             c:=current_scanner.asmgetchar;
                             firsttoken := TRUE;
                             actasmtoken:=AS_SEPARATOR;
@@ -1749,7 +1769,6 @@ const
             _asmsorted := TRUE;
           end;
         curlist:=TAsmList.Create;
-        c:=current_scanner.asmgetchar;
         gettoken;
         while actasmtoken<>AS_END do
           begin

+ 45 - 13
compiler/raatt.pas

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

+ 1 - 69
compiler/scanner.pas

@@ -136,7 +136,6 @@ interface
 
           comment_level,
           yylexcount     : longint;
-          lastasmgetchar : char;
           ignoredirectives : TFPHashList; { ignore directives, used to give warnings only once }
           preprocstack   : tpreprocstack;
           replaystack    : treplaystack;
@@ -221,7 +220,6 @@ interface
           procedure skipoldtpcomment;
           procedure readtoken(allowrecordtoken:boolean);
           function  readpreproc:ttoken;
-          function  asmgetcharstart : char;
           function  asmgetchar:char;
        end;
 
@@ -2650,7 +2648,6 @@ type
         nexttokenpos:=0;
         lasttoken:=NOTOKEN;
         nexttoken:=NOTOKEN;
-        lastasmgetchar:=#0;
         ignoredirectives:=TFPHashList.Create;
         in_asm_string:=false;
       end;
@@ -5498,24 +5495,9 @@ exit_label:
       end;
 
 
-    function tscannerfile.asmgetcharstart : char;
-      begin
-        { return first the character already
-          available in c }
-        lastasmgetchar:=c;
-        result:=asmgetchar;
-      end;
-
-
     function tscannerfile.asmgetchar : char;
       begin
-         if lastasmgetchar<>#0 then
-          begin
-            c:=lastasmgetchar;
-            lastasmgetchar:=#0;
-          end
-         else
-          readchar;
+         readchar;
          if in_asm_string then
            begin
              asmgetchar:=c;
@@ -5523,29 +5505,6 @@ exit_label:
            end;
          repeat
            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 :
                begin
                  reload;
@@ -5553,33 +5512,6 @@ exit_label:
                    end_of_file;
                  continue;
                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
                begin
                  asmgetchar:=c;

+ 35 - 6
compiler/x86/rax86int.pas

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