This patch improves the performance of the parser for declarations
ended by a semicolon. Previously an error check for aspect specs
following the semicolon was done inefficiently.

There should be no external effect from this improvement. But the
following test is useful:

     1. pragma Ada_2012;
     2. package AspectSem is
     3.    type R is new Integer;
                                |
        >>> extra ";" ignored

     4.      with Size => 64;
     5. end;

This gives the same output befor and after the patch, but the internal
mechanism for giving that message is entirely different.

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-08-02  Robert Dewar  <de...@adacore.com>

        * par-ch13.adb (Aspect_Specifications_Present): Always return false on
        semicolon, do not try to see if there are aspects following it.
        * par-ch3.adb (P_Declarative_Items): Better message for unexpected
        aspect spec.

Index: par-ch13.adb
===================================================================
--- par-ch13.adb        (revision 177086)
+++ par-ch13.adb        (working copy)
@@ -46,31 +46,19 @@
       Result     : Boolean;
 
    begin
-      Save_Scan_State (Scan_State);
+      --  Definitely must have WITH to consider aspect specs to be present
 
-      --  If we have a semicolon, test for semicolon followed by Aspect
-      --  Specifications, in which case we decide the semicolon is accidental.
+      --  Note that this means that if we have a semicolon, we immediately
+      --  return False. There is a case in which this is not optimal, namely
+      --  something like
 
-      if Token = Tok_Semicolon then
-         Scan; -- past semicolon
+      --    type R is new Integer;
+      --      with bla bla;
 
-         --  The recursive test is set Strict, since we already have one
-         --  error (the unexpected semicolon), so we will ignore that semicolon
-         --  only if we absolutely definitely have an aspect specification
-         --  following it.
+      --  where the semicolon is redundant, but scanning forward for it would
+      --  be too expensive. Instead we pick up the aspect specifications later
+      --  as a bogus declaration, and diagnose the semicolon at that point.
 
-         if Aspect_Specifications_Present (Strict => True) then
-            Error_Msg_SP ("|extra "";"" ignored");
-            return True;
-
-         else
-            Restore_Scan_State (Scan_State);
-            return False;
-         end if;
-      end if;
-
-      --  Definitely must have WITH to consider aspect specs to be present
-
       if Token /= Tok_With then
          return False;
       end if;
Index: par-ch3.adb
===================================================================
--- par-ch3.adb (revision 177029)
+++ par-ch3.adb (working copy)
@@ -4274,9 +4274,43 @@
 
          when Tok_With =>
             Check_Bad_Layout;
-            Error_Msg_SC ("WITH can only appear in context clause");
-            raise Error_Resync;
 
+            if Aspect_Specifications_Present then
+
+               --  If we are after a semicolon, complain that it was ignored.
+               --  But we don't really ignore it, since we dump the aspects,
+               --  so we make the error message a normal fatal message which
+               --  will inhibit semantic analysis anyway).
+
+               if Prev_Token = Tok_Semicolon then
+                  Error_Msg_SP -- CODEFIX
+                    ("extra "";"" ignored");
+
+               --  If not just past semicolon, just complain that aspects are
+               --  not allowed at this point.
+
+               else
+                  Error_Msg_SC ("aspect specifications not allowed here");
+               end if;
+
+               declare
+                  Dummy_Node : constant Node_Id :=
+                                 New_Node (N_Package_Specification, Token_Ptr);
+                  pragma Warnings (Off, Dummy_Node);
+                  --  Dummy node to attach aspect specifications to. We will
+                  --  then throw them away.
+
+               begin
+                  P_Aspect_Specifications (Dummy_Node, Semicolon => True);
+               end;
+
+            --  Here if not aspect specifications case
+
+            else
+               Error_Msg_SC ("WITH can only appear in context clause");
+               raise Error_Resync;
+            end if;
+
          --  BEGIN terminates the scan of a sequence of declarations unless
          --  there is a missing subprogram body, see section on handling
          --  semicolon in place of IS. We only treat the begin as satisfying

Reply via email to