OSDN Git Service

PR c++/9704
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch2.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              P A R . C H 2                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --                                                                          --
10 --          Copyright (C) 1992-2002 Free Software Foundation, Inc.          --
11 --                                                                          --
12 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
13 -- terms of the  GNU General Public License as published  by the Free Soft- --
14 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
15 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
18 -- for  more details.  You should have  received  a copy of the GNU General --
19 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
20 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
21 -- MA 02111-1307, USA.                                                      --
22 --                                                                          --
23 -- GNAT was originally developed  by the GNAT team at  New York University. --
24 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
25 --                                                                          --
26 ------------------------------------------------------------------------------
27
28 pragma Style_Checks (All_Checks);
29 --  Turn off subprogram body ordering check. Subprograms are in order
30 --  by RM section rather than alphabetical
31
32 separate (Par)
33 package body Ch2 is
34
35    --  Local functions, used only in this chapter
36
37    function P_Pragma_Argument_Association return Node_Id;
38
39    ---------------------
40    -- 2.3  Identifier --
41    ---------------------
42
43    --  IDENTIFIER ::= LETTER {[UNDERLINE] LETTER_OR_DIGIT}
44
45    --  LETTER_OR_DIGIT ::= IDENTIFIER_LETTER | DIGIT
46
47    --  An IDENTIFIER shall not be a reserved word
48
49    --  Error recovery: can raise Error_Resync (cannot return Error)
50
51    function P_Identifier return Node_Id is
52       Ident_Node : Node_Id;
53
54    begin
55       --  All set if we do indeed have an identifier
56
57       if Token = Tok_Identifier then
58          Ident_Node := Token_Node;
59          Scan; -- past Identifier
60          return Ident_Node;
61
62       --  If we have a reserved identifier, manufacture an identifier with
63       --  a corresponding name after posting an appropriate error message
64
65       elsif Is_Reserved_Identifier then
66          Scan_Reserved_Identifier (Force_Msg => False);
67          Ident_Node := Token_Node;
68          Scan; -- past the node
69          return Ident_Node;
70
71       --  Otherwise we have junk that cannot be interpreted as an identifier
72
73       else
74          T_Identifier; -- to give message
75          raise Error_Resync;
76       end if;
77    end P_Identifier;
78
79    --------------------------
80    -- 2.3  Letter Or Digit --
81    --------------------------
82
83    --  Parsed by P_Identifier (2.3)
84
85    --------------------------
86    -- 2.4  Numeric Literal --
87    --------------------------
88
89    --  NUMERIC_LITERAL ::= DECIMAL_LITERAL | BASED_LITERAL
90
91    --  Numeric literal is returned by the scanner as either
92    --  Tok_Integer_Literal or Tok_Real_Literal
93
94    ----------------------------
95    -- 2.4.1  Decimal Literal --
96    ----------------------------
97
98    --  DECIMAL_LITERAL ::= NUMERAL [.NUMERAL] [EXPONENT]
99
100    --  Handled by scanner as part of numeric lIteral handing (see 2.4)
101
102    --------------------
103    -- 2.4.1  Numeral --
104    --------------------
105
106    --  NUMERAL ::= DIGIT {[UNDERLINE] DIGIT}
107
108    --  Handled by scanner as part of numeric literal handling (see 2.4)
109
110    ---------------------
111    -- 2.4.1  Exponent --
112    ---------------------
113
114    --  EXPONENT ::= E [+] NUMERAL | E - NUMERAL
115
116    --  Handled by scanner as part of numeric literal handling (see 2.4)
117
118    --------------------------
119    -- 2.4.2  Based Literal --
120    --------------------------
121
122    --  BASED_LITERAL ::=
123    --   BASE # BASED_NUMERAL [.BASED_NUMERAL] # [EXPONENT]
124
125    --  Handled by scanner as part of numeric literal handling (see 2.4)
126
127    -----------------
128    -- 2.4.2  Base --
129    -----------------
130
131    --  BASE ::= NUMERAL
132
133    --  Handled by scanner as part of numeric literal handling (see 2.4)
134
135    --------------------------
136    -- 2.4.2  Based Numeral --
137    --------------------------
138
139    --  BASED_NUMERAL ::=
140    --    EXTENDED_DIGIT {[UNDERLINE] EXTENDED_DIGIT}
141
142    --  Handled by scanner as part of numeric literal handling (see 2.4)
143
144    ---------------------------
145    -- 2.4.2  Extended Digit --
146    ---------------------------
147
148    --  EXTENDED_DIGIT ::= DIGIT | A | B | C | D | E | F
149
150    --  Handled by scanner as part of numeric literal handling (see 2.4)
151
152    ----------------------------
153    -- 2.5  Character Literal --
154    ----------------------------
155
156    --  CHARACTER_LITERAL ::= ' GRAPHIC_CHARACTER '
157
158    --  Handled by the scanner and returned as Tok_Character_Literal
159
160    -------------------------
161    -- 2.6  String Literal --
162    -------------------------
163
164    --  STRING LITERAL ::= "{STRING_ELEMENT}"
165
166    --  Handled by the scanner and returned as Tok_Character_Literal
167    --  or if the string looks like an operator as Tok_Operator_Symbol.
168
169    -------------------------
170    -- 2.6  String Element --
171    -------------------------
172
173    --  STRING_ELEMENT ::= "" | non-quotation_mark_GRAPHIC_CHARACTER
174
175    --  A STRING_ELEMENT is either a pair of quotation marks ("),
176    --  or a single GRAPHIC_CHARACTER other than a quotation mark.
177
178    --  Handled by scanner as part of string literal handling (see 2.4)
179
180    ------------------
181    -- 2.7  Comment --
182    ------------------
183
184    --  A COMMENT starts with two adjacent hyphens and extends up to the
185    --  end of the line. A COMMENT may appear on any line of a program.
186
187    --  Handled by the scanner which simply skips past encountered comments
188
189    -----------------
190    -- 2.8  Pragma --
191    -----------------
192
193    --  PRAGMA ::= pragma IDENTIFIER
194    --    [(PRAGMA_ARGUMENT_ASSOCIATION {, PRAGMA_ARGUMENT_ASSOCIATION})];
195
196    --  The caller has checked that the initial token is PRAGMA
197
198    --  Error recovery: cannot raise Error_Resync
199
200    --  One special piece of processing is needed in this routine. As described
201    --  in the section on "Handling semicolon used in place of IS" in module
202    --  Parse, the parser detects the case of missing subprogram bodies to
203    --  allow recovery from this syntactic error. Pragma INTERFACE (and, for
204    --  Ada 95, pragma IMPORT) can appear in place of the body. The parser must
205    --  recognize the use of these two pragmas in this context, otherwise it
206    --  will think there are missing bodies, and try to change ; to IS, when
207    --  in fact the bodies ARE present, supplied by these pragmas.
208
209    function P_Pragma return Node_Id is
210
211       Interface_Check_Required : Boolean := False;
212       --  Set True if check of pragma INTERFACE is required
213
214       Import_Check_Required : Boolean := False;
215       --  Set True if check of pragma IMPORT is required
216
217       Arg_Count : Int := 0;
218       --  Number of argument associations processed
219
220       Pragma_Node   : Node_Id;
221       Pragma_Name   : Name_Id;
222       Semicolon_Loc : Source_Ptr;
223       Ident_Node    : Node_Id;
224       Assoc_Node    : Node_Id;
225       Result        : Node_Id;
226
227       procedure Skip_Pragma_Semicolon;
228       --  Skip past semicolon at end of pragma
229
230       ---------------------------
231       -- Skip_Pragma_Semicolon --
232       ---------------------------
233
234       procedure Skip_Pragma_Semicolon is
235       begin
236          if Token /= Tok_Semicolon then
237             T_Semicolon;
238             Resync_Past_Semicolon;
239          else
240             Scan; -- past semicolon
241          end if;
242       end Skip_Pragma_Semicolon;
243
244    --  Start of processing for P_Pragma
245
246    begin
247       Pragma_Node := New_Node (N_Pragma, Token_Ptr);
248       Scan; -- past PRAGMA
249       Pragma_Name := Token_Name;
250
251       if Style_Check then
252          Style.Check_Pragma_Name;
253       end if;
254
255       Ident_Node := P_Identifier;
256       Set_Chars (Pragma_Node, Pragma_Name);
257       Delete_Node (Ident_Node);
258
259       --  See if special INTERFACE/IMPORT check is required
260
261       if SIS_Entry_Active then
262          Interface_Check_Required := (Pragma_Name = Name_Interface);
263          Import_Check_Required    := (Pragma_Name = Name_Import);
264       else
265          Interface_Check_Required := False;
266          Import_Check_Required    := False;
267       end if;
268
269       --  Scan arguments. We assume that arguments are present if there is
270       --  a left paren, or if a semicolon is missing and there is another
271       --  token on the same line as the pragma name.
272
273       if Token = Tok_Left_Paren
274         or else (Token /= Tok_Semicolon
275                    and then not Token_Is_At_Start_Of_Line)
276       then
277          Set_Pragma_Argument_Associations (Pragma_Node, New_List);
278          T_Left_Paren;
279
280          loop
281             Arg_Count := Arg_Count + 1;
282             Assoc_Node := P_Pragma_Argument_Association;
283
284             if Arg_Count = 2
285               and then (Interface_Check_Required or else Import_Check_Required)
286             then
287                --  Here is where we cancel the SIS active status if this pragma
288                --  supplies a body for the currently active subprogram spec.
289
290                if Nkind (Expression (Assoc_Node)) in N_Direct_Name
291                  and then Chars (Expression (Assoc_Node)) = Chars (SIS_Labl)
292                then
293                   SIS_Entry_Active := False;
294                end if;
295             end if;
296
297             Append (Assoc_Node, Pragma_Argument_Associations (Pragma_Node));
298             exit when Token /= Tok_Comma;
299             Scan; -- past comma
300          end loop;
301
302          T_Right_Paren;
303       end if;
304
305       Semicolon_Loc := Token_Ptr;
306
307       --  Now we have two tasks left, we need to scan out the semicolon
308       --  following the pragma, and we have to call Par.Prag to process
309       --  the pragma. Normally we do them in this order, however, there
310       --  is one exception namely pragma Style_Checks where we like to
311       --  skip the semicolon after processing the pragma, since that way
312       --  the style checks for the scanning of the semicolon follow the
313       --  settings of the pragma.
314
315       --  You might think we could just unconditionally do things in
316       --  the opposite order, but there are other pragmas, notably the
317       --  case of pragma Source_File_Name, which assume the semicolon
318       --  is already scanned out.
319
320       if Chars (Pragma_Node) = Name_Style_Checks then
321          Result := Par.Prag (Pragma_Node, Semicolon_Loc);
322          Skip_Pragma_Semicolon;
323          return Result;
324       else
325          Skip_Pragma_Semicolon;
326          return Par.Prag (Pragma_Node, Semicolon_Loc);
327       end if;
328
329    exception
330       when Error_Resync =>
331          Resync_Past_Semicolon;
332          return Error;
333
334    end P_Pragma;
335
336    --  This routine is called if a pragma is encountered in an inappropriate
337    --  position, the pragma is scanned out and control returns to continue.
338
339    --  The caller has checked that the initial token is pragma
340
341    --  Error recovery: cannot raise Error_Resync
342
343    procedure P_Pragmas_Misplaced is
344    begin
345       while Token = Tok_Pragma loop
346          Error_Msg_SC ("pragma not allowed here");
347          Discard_Junk_Node (P_Pragma);
348       end loop;
349    end P_Pragmas_Misplaced;
350
351    --  This function is called to scan out an optional sequence of pragmas.
352    --  If no pragmas are found, then No_List is returned.
353
354    --  Error recovery: Cannot raise Error_Resync
355
356    function P_Pragmas_Opt return List_Id is
357       L : List_Id;
358
359    begin
360       if Token = Tok_Pragma then
361          L := New_List;
362          P_Pragmas_Opt (L);
363          return L;
364
365       else
366          return No_List;
367       end if;
368    end P_Pragmas_Opt;
369
370    --  This procedure is called to scan out an optional sequence of pragmas.
371    --  Any pragmas found are appended to the list provided as an argument.
372
373    --  Error recovery: Cannot raise Error_Resync
374
375    procedure P_Pragmas_Opt (List : List_Id) is
376       P : Node_Id;
377
378    begin
379       while Token = Tok_Pragma loop
380          P := P_Pragma;
381
382          if Chars (P) = Name_Assert or else Chars (P) = Name_Debug then
383             Error_Msg_Name_1 := Chars (P);
384             Error_Msg_N
385               ("pragma% must be in declaration/statement context", P);
386          else
387             Append (P, List);
388          end if;
389       end loop;
390    end P_Pragmas_Opt;
391
392    --------------------------------------
393    -- 2.8  Pragma_Argument Association --
394    --------------------------------------
395
396    --  PRAGMA_ARGUMENT_ASSOCIATION ::=
397    --    [pragma_argument_IDENTIFIER =>] NAME
398    --  | [pragma_argument_IDENTIFIER =>] EXPRESSION
399
400    --  Error recovery: cannot raise Error_Resync
401
402    function P_Pragma_Argument_Association return Node_Id is
403       Scan_State      : Saved_Scan_State;
404       Pragma_Arg_Node : Node_Id;
405       Identifier_Node : Node_Id;
406
407    begin
408       Pragma_Arg_Node := New_Node (N_Pragma_Argument_Association, Token_Ptr);
409       Set_Chars (Pragma_Arg_Node, No_Name);
410
411       if Token = Tok_Identifier then
412          Identifier_Node := Token_Node;
413          Save_Scan_State (Scan_State); -- at Identifier
414          Scan; -- past Identifier
415
416          if Token = Tok_Arrow then
417             Scan; -- past arrow
418             Set_Chars (Pragma_Arg_Node, Chars (Identifier_Node));
419             Delete_Node (Identifier_Node);
420          else
421             Restore_Scan_State (Scan_State); -- to Identifier
422          end if;
423       end if;
424
425       Set_Expression (Pragma_Arg_Node, P_Expression);
426       return Pragma_Arg_Node;
427
428    end P_Pragma_Argument_Association;
429
430 end Ch2;