aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/par-ch2.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/par-ch2.adb')
-rw-r--r--gcc/ada/par-ch2.adb90
1 files changed, 81 insertions, 9 deletions
diff --git a/gcc/ada/par-ch2.adb b/gcc/ada/par-ch2.adb
index 62c6735..37fe454 100644
--- a/gcc/ada/par-ch2.adb
+++ b/gcc/ada/par-ch2.adb
@@ -40,6 +40,12 @@ package body Ch2 is
-- the scanned association has an identifier (this is used to check the
-- rule that no associations without identifiers can follow an association
-- which has an identifier). The result is returned in Association.
+ --
+ -- Note: We allow attribute forms Pre'Class, Post'Class, Invariant'Class,
+ -- Type_Invariant'Class in place of a pragma argument identifier. Rather
+ -- than handle this case specially, we replace such references with
+ -- one of the special internal identifiers _Pre, _Post, _Invariant, or
+ -- _Type_Invariant, and this procedure is where this replacement occurs.
---------------------
-- 2.3 Identifier --
@@ -448,6 +454,24 @@ package body Ch2 is
-- [pragma_argument_IDENTIFIER =>] NAME
-- | [pragma_argument_IDENTIFIER =>] EXPRESSION
+ -- In Ada 2012, there are two more possibilities:
+
+ -- PRAGMA_ARGUMENT_ASSOCIATION ::=
+ -- [pragma_argument_ASPECT_MARK =>] NAME
+ -- | [pragma_argument_ASPECT_MARK =>] EXPRESSION
+
+ -- where the interesting allowed cases (which do not fit the syntax of the
+ -- first alternative above are
+
+ -- ASPECT_MARK ::=
+ -- Pre'Class | Post'Class | Invariant'Class | Type_Invariant'Class
+
+ -- We allow this special usage in all Ada modes, but it would be a pain to
+ -- allow these aspects to pervade the pragma syntax, and the representation
+ -- of pragma nodes internally. So what we do is to replace these
+ -- ASPECT_MARK forms with identifiers whose name is one of the special
+ -- internal names _Pre, _Post, _Invariant, or _Type_Invariant.
+
-- Error recovery: cannot raise Error_Resync
procedure Scan_Pragma_Argument_Association
@@ -461,6 +485,7 @@ package body Ch2 is
begin
Association := New_Node (N_Pragma_Argument_Association, Token_Ptr);
Set_Chars (Association, No_Name);
+ Id_Present := False;
-- Argument starts with identifier
@@ -470,22 +495,69 @@ package body Ch2 is
Scan; -- past Identifier
if Token = Tok_Arrow then
- Identifier_Seen := True;
Scan; -- past arrow
- Set_Chars (Association, Chars (Identifier_Node));
Id_Present := True;
- -- Case of argument with no identifier
+ -- Case of one of the special aspect forms
- else
- Restore_Scan_State (Scan_State); -- to Identifier
- Id_Present := False;
+ elsif Token = Tok_Apostrophe then
+ Scan; -- past apostrophe
+
+ -- We have apostrophe, so check for identifier'Class
+
+ if Token /= Tok_Identifier or else Token_Name /= Name_Class then
+ null;
+
+ -- We have identifier'Class, check for arrow
+
+ else
+ Scan; -- Past Class
+
+ if Token /= Tok_Arrow then
+ null;
+
+ -- Here we have scanned identifier'Class =>
+
+ else
+ Id_Present := True;
+ Scan; -- past arrow
+
+ case Chars (Identifier_Node) is
+ when Name_Pre =>
+ Set_Chars (Identifier_Node, Name_uPre);
+
+ when Name_Post =>
+ Set_Chars (Identifier_Node, Name_uPost);
+
+ when Name_Type_Invariant =>
+ Set_Chars (Identifier_Node, Name_uType_Invariant);
+
+ when Name_Invariant =>
+ Set_Chars (Identifier_Node, Name_uInvariant);
+
+ -- If it is X'Class => for some invalid X, we will give
+ -- an error, and forget that 'Class was present, which
+ -- will give better error recovery. We could do a spell
+ -- check here, but it seems too much work.
+
+ when others =>
+ Error_Msg_SC ("invalid aspect id for pragma");
+ end case;
+ end if;
+ end if;
end if;
- -- Argument does not start with identifier
+ -- Identifier was present
- else
- Id_Present := False;
+ if Id_Present then
+ Set_Chars (Association, Chars (Identifier_Node));
+ Identifier_Seen := True;
+
+ -- Identifier not present after all
+
+ else
+ Restore_Scan_State (Scan_State); -- to Identifier
+ end if;
end if;
-- Diagnose error of "positional" argument for pragma appearing after