diff mbox

[Ada] Handle WHEN used in place of WITH nicely

Message ID 20150205112249.GA20729@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Feb. 5, 2015, 11:22 a.m. UTC
This patch improves the error recovery when WHEN is used in place
of WITH for aspect specifications:

     1. package WhenWith is
     2.    X : integer when Size => 4;
                            |
        >>> "when" should be "with"

     3.    Y : integer when Rubbish;
                      |
        >>> missing ";"

     4.    procedure Q when Inline;
                       |
        >>> barrier not allowed on procedure, only on entry

     5. end WhenWith;

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

2015-02-05  Robert Dewar  <dewar@adacore.com>

	* par-ch13.adb (With_Present): New function
	(Aspect_Specifications_Present): Handle WHEN in place of WITH
	(Get_Aspect_Specifications): Comment update.
	* par.adb: Comment updates.
diff mbox

Patch

Index: par-ch13.adb
===================================================================
--- par-ch13.adb	(revision 220439)
+++ par-ch13.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2014, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -48,6 +48,10 @@ 
       function Possible_Misspelled_Aspect return Boolean;
       --  Returns True, if Token_Name is a misspelling of some aspect name
 
+      function With_Present return Boolean;
+      --  Returns True if WITH is present, indicating presence of aspect
+      --  specifications. Also allows incorrect use of WHEN in place of WITH.
+
       --------------------------------
       -- Possible_Misspelled_Aspect --
       --------------------------------
@@ -63,6 +67,43 @@ 
          return False;
       end Possible_Misspelled_Aspect;
 
+      ------------------
+      -- With_Present --
+      ------------------
+
+      function With_Present return Boolean is
+      begin
+         if Token = Tok_With then
+            return True;
+
+         --  Check for WHEN used in place of WITH
+
+         elsif Token = Tok_When then
+            declare
+               Scan_State : Saved_Scan_State;
+
+            begin
+               Save_Scan_State (Scan_State);
+               Scan; -- past WHEN
+
+               if Token = Tok_Identifier
+                 and then Get_Aspect_Id (Token_Name) /= No_Aspect
+               then
+                  Error_Msg_SC ("WHEN should be WITH");
+                  Restore_Scan_State (Scan_State);
+                  return True;
+
+               else
+                  Restore_Scan_State (Scan_State);
+                  return False;
+               end if;
+            end;
+
+         else
+            return False;
+         end if;
+      end With_Present;
+
    --  Start of processing for Aspect_Specifications_Present
 
    begin
@@ -79,14 +120,15 @@ 
       --  be too expensive. Instead we pick up the aspect specifications later
       --  as a bogus declaration, and diagnose the semicolon at that point.
 
-      if Token /= Tok_With then
+      if not With_Present then
          return False;
       end if;
 
-      --  Have a WITH, see if it looks like an aspect specification
+      --  Have a WITH or some token that we accept as a legitimate bad attempt
+      --  at writing WITH. See if it looks like an aspect specification
 
       Save_Scan_State (Scan_State);
-      Scan; -- past WITH
+      Scan; -- past WITH (or WHEN or other bad keyword)
 
       --  If no identifier, then consider that we definitely do not have an
       --  aspect specification.
@@ -193,7 +235,7 @@ 
          return Aspects;
       end if;
 
-      Scan; -- past WITH
+      Scan; -- past WITH (or possible WHEN after error)
       Aspects := Empty_List;
 
       --  Loop to scan aspects
Index: par.adb
===================================================================
--- par.adb	(revision 220439)
+++ par.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2014, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -951,6 +951,9 @@ 
       --  permitted). Note: this routine never checks the terminator token
       --  for aspects so it does not matter whether the aspect specifications
       --  are terminated by semicolon or some other character.
+      --
+      --  Note: This function also handles the case of WHEN used where WITH
+      --  was intended, and in that case posts an error and returns True.
 
       procedure P_Aspect_Specifications
         (Decl      : Node_Id;
@@ -960,15 +963,17 @@ 
       --  argument is False, the scan pointer is left pointing past the aspects
       --  and the caller must check for a proper terminator.
       --
-      --  P_Aspect_Specifications is called with the current token pointing to
-      --  either a WITH keyword starting an aspect specification, or an
-      --  instance of the terminator token. In the former case, the aspect
-      --  specifications are scanned out including the terminator token if it
-      --  it is a semicolon, and the Has_Aspect_Specifications flag is set in
-      --  the given declaration node. A list of aspects is built and stored for
-      --  this declaration node using a call to Set_Aspect_Specifications. If
-      --  no WITH keyword is present, then this call has no effect other than
-      --  scanning out the terminator if it is a semicolon.
+      --  P_Aspect_Specifications is called with the current token pointing
+      --  to either a WITH keyword starting an aspect specification, or an
+      --  instance of what shpould be a terminator token. In the former case,
+      --  the aspect specifications are scanned out including the terminator
+      --  token if it it is a semicolon, and the Has_Aspect_Specifications
+      --  flag is set in the given declaration node. A list of aspects
+      --  is built and stored for this declaration node using a call to
+      --  Set_Aspect_Specifications. If no WITH keyword is present, then this
+      --  call has no effect other than scanning out the terminator if it is a
+      --  semicolon (with the exception that it detects WHEN used in place of
+      --  WITH).
 
       --  If Decl is Error on entry, any scanned aspect specifications are
       --  ignored and a message is output saying aspect specifications not