OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc1/] [gcc/] [ada/] [par-ch10.adb] - Blame information for rev 281

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 281 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                             P A R . C H 1 0                              --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
10
--                                                                          --
11
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12
-- terms of the  GNU General Public License as published  by the Free Soft- --
13
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17
-- for  more details.  You should have  received  a copy of the GNU General --
18
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
19
-- http://www.gnu.org/licenses for a complete copy of the license.          --
20
--                                                                          --
21
-- GNAT was originally developed  by the GNAT team at  New York University. --
22
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
23
--                                                                          --
24
------------------------------------------------------------------------------
25
 
26
pragma Style_Checks (All_Checks);
27
--  Turn off subprogram body ordering check. Subprograms are in order
28
--  by RM section rather than alphabetical
29
 
30
with Fname.UF; use Fname.UF;
31
with Uname;    use Uname;
32
 
33
separate (Par)
34
package body Ch10 is
35
 
36
   --  Local functions, used only in this chapter
37
 
38
   function P_Context_Clause    return List_Id;
39
   function P_Subunit           return Node_Id;
40
 
41
   function Set_Location return Source_Ptr;
42
   --  The current compilation unit starts with Token at Token_Ptr. This
43
   --  function determines the corresponding source location for the start
44
   --  of the unit, including any preceding comment lines.
45
 
46
   procedure Unit_Display
47
     (Cunit      : Node_Id;
48
      Loc        : Source_Ptr;
49
      SR_Present : Boolean);
50
   --  This procedure is used to generate a line of output for a unit in
51
   --  the source program. Cunit is the node for the compilation unit, and
52
   --  Loc is the source location for the start of the unit in the source
53
   --  file (which is not necessarily the Sloc of the Cunit node). This
54
   --  output is written to the standard output file for use by gnatchop.
55
 
56
   procedure Unit_Location (Sind : Source_File_Index; Loc : Source_Ptr);
57
   --  This routine has the same calling sequence as Unit_Display, but
58
   --  it outputs only the line number and offset of the location, Loc,
59
   --  using Cunit to obtain the proper source file index.
60
 
61
   -------------------------
62
   -- 10.1.1  Compilation --
63
   -------------------------
64
 
65
   --  COMPILATION ::= {COMPILATION_UNIT}
66
 
67
   --  There is no specific parsing routine for a compilation, since we only
68
   --  permit a single compilation in a source file, so there is no explicit
69
   --  occurrence of compilations as such (our representation of a compilation
70
   --  is a series of separate source files).
71
 
72
   ------------------------------
73
   -- 10.1.1  Compilation unit --
74
   ------------------------------
75
 
76
   --  COMPILATION_UNIT ::=
77
   --    CONTEXT_CLAUSE LIBRARY_ITEM
78
   --  | CONTEXT_CLAUSE SUBUNIT
79
 
80
   --  LIBRARY_ITEM ::=
81
   --    private LIBRARY_UNIT_DECLARATION
82
   --  | LIBRARY_UNIT_BODY
83
   --  | [private] LIBRARY_UNIT_RENAMING_DECLARATION
84
 
85
   --  LIBRARY_UNIT_DECLARATION ::=
86
   --    SUBPROGRAM_DECLARATION | PACKAGE_DECLARATION
87
   --  | GENERIC_DECLARATION    | GENERIC_INSTANTIATION
88
 
89
   --  LIBRARY_UNIT_RENAMING_DECLARATION ::=
90
   --    PACKAGE_RENAMING_DECLARATION
91
   --  | GENERIC_RENAMING_DECLARATION
92
   --  | SUBPROGRAM_RENAMING_DECLARATION
93
 
94
   --  LIBRARY_UNIT_BODY ::= SUBPROGRAM_BODY | PACKAGE_BODY
95
 
96
   --  Error recovery: cannot raise Error_Resync. If an error occurs, tokens
97
   --  are skipped up to the next possible beginning of a compilation unit.
98
 
99
   --  Note: if only configuration pragmas are found, Empty is returned
100
 
101
   --  Note: in syntax-only mode, it is possible for P_Compilation_Unit
102
   --  to return strange things that are not really compilation units.
103
   --  This is done to help out gnatchop when it is faced with nonsense.
104
 
105
   function P_Compilation_Unit return Node_Id is
106
      Scan_State         : Saved_Scan_State;
107
      Body_Node          : Node_Id;
108
      Specification_Node : Node_Id;
109
      Unit_Node          : Node_Id;
110
      Comp_Unit_Node     : Node_Id;
111
      Name_Node          : Node_Id;
112
      Item               : Node_Id;
113
      Private_Sloc       : Source_Ptr := No_Location;
114
      Config_Pragmas     : List_Id;
115
      P                  : Node_Id;
116
      SR_Present         : Boolean;
117
 
118
      Cunit_Error_Flag : Boolean := False;
119
      --  This flag is set True if we have to scan for a compilation unit
120
      --  token. It is used to ensure clean termination in such cases by
121
      --  not insisting on being at the end of file, and, in the syntax only
122
      --  case by not scanning for additional compilation units.
123
 
124
      Cunit_Location : Source_Ptr;
125
      --  Location of unit for unit identification output (List_Unit option)
126
 
127
   begin
128
      Num_Library_Units := Num_Library_Units + 1;
129
 
130
      --  Set location of the compilation unit if unit list option set
131
      --  and we are in syntax check only mode
132
 
133
      if List_Units and then Operating_Mode = Check_Syntax then
134
         Cunit_Location := Set_Location;
135
      else
136
         Cunit_Location := No_Location;
137
      end if;
138
 
139
      --  Deal with initial pragmas
140
 
141
      Config_Pragmas := No_List;
142
 
143
      --  If we have an initial Source_Reference pragma, then remember the fact
144
      --  to generate an NR parameter in the output line.
145
 
146
      SR_Present := False;
147
 
148
      if Token = Tok_Pragma then
149
         Save_Scan_State (Scan_State);
150
         Item := P_Pragma;
151
 
152
         if Item = Error
153
           or else Pragma_Name (Item) /= Name_Source_Reference
154
         then
155
            Restore_Scan_State (Scan_State);
156
 
157
         else
158
            SR_Present := True;
159
 
160
            --  If first unit, record the file name for gnatchop use
161
 
162
            if Operating_Mode = Check_Syntax
163
              and then List_Units
164
              and then Num_Library_Units = 1
165
            then
166
               Write_Str ("Source_Reference pragma for file """);
167
               Write_Name (Full_Ref_Name (Current_Source_File));
168
               Write_Char ('"');
169
               Write_Eol;
170
            end if;
171
 
172
            Config_Pragmas := New_List (Item);
173
         end if;
174
      end if;
175
 
176
      --  Scan out any configuration pragmas
177
 
178
      while Token = Tok_Pragma loop
179
         Save_Scan_State (Scan_State);
180
         Item := P_Pragma;
181
 
182
         if Item = Error
183
           or else not Is_Configuration_Pragma_Name (Pragma_Name (Item))
184
         then
185
            Restore_Scan_State (Scan_State);
186
            exit;
187
         end if;
188
 
189
         if Config_Pragmas = No_List then
190
            Config_Pragmas := Empty_List;
191
 
192
            if Operating_Mode = Check_Syntax and then List_Units then
193
               Write_Str ("Configuration pragmas at");
194
               Unit_Location (Current_Source_File, Cunit_Location);
195
               Write_Eol;
196
            end if;
197
         end if;
198
 
199
         Append (Item, Config_Pragmas);
200
         Cunit_Location := Set_Location;
201
      end loop;
202
 
203
      --  Establish compilation unit node and scan context items
204
 
205
      Comp_Unit_Node := New_Node (N_Compilation_Unit, No_Location);
206
      Set_Cunit (Current_Source_Unit, Comp_Unit_Node);
207
      Set_Context_Items (Comp_Unit_Node, P_Context_Clause);
208
      Set_Aux_Decls_Node
209
        (Comp_Unit_Node, New_Node (N_Compilation_Unit_Aux, No_Location));
210
 
211
      if Present (Config_Pragmas) then
212
 
213
         --  Check for case of only configuration pragmas present
214
 
215
         if Token = Tok_EOF
216
           and then Is_Empty_List (Context_Items (Comp_Unit_Node))
217
         then
218
            if Operating_Mode = Check_Syntax then
219
               return Empty;
220
 
221
            else
222
               Item := First (Config_Pragmas);
223
               Error_Msg_N
224
                 ("cannot compile configuration pragmas with gcc!", Item);
225
               Error_Msg_N
226
                 ("\use gnatchop -c to process configuration pragmas!", Item);
227
               raise Unrecoverable_Error;
228
            end if;
229
 
230
         --  Otherwise configuration pragmas are simply prepended to the
231
         --  context of the current unit.
232
 
233
         else
234
            Append_List (Context_Items (Comp_Unit_Node), Config_Pragmas);
235
            Set_Context_Items (Comp_Unit_Node, Config_Pragmas);
236
         end if;
237
      end if;
238
 
239
      --  Check for PRIVATE. Note that for the moment we allow this in
240
      --  Ada_83 mode, since we do not yet know if we are compiling a
241
      --  predefined unit, and if we are then it would be allowed anyway.
242
 
243
      if Token = Tok_Private then
244
         Private_Sloc := Token_Ptr;
245
         Set_Keyword_Casing (Current_Source_File, Determine_Token_Casing);
246
 
247
         if Style_Check then
248
            Style.Check_Indentation;
249
         end if;
250
 
251
         Save_Scan_State (Scan_State); -- at PRIVATE
252
         Scan; -- past PRIVATE
253
 
254
         if Token = Tok_Separate then
255
            Error_Msg_SP ("cannot have private subunits!");
256
 
257
         elsif Token = Tok_Package then
258
            Scan; -- past PACKAGE
259
 
260
            if Token = Tok_Body then
261
               Restore_Scan_State (Scan_State); -- to PRIVATE
262
               Error_Msg_SC ("cannot have private package body!");
263
               Scan; -- ignore PRIVATE
264
 
265
            else
266
               Restore_Scan_State (Scan_State); -- to PRIVATE
267
               Scan; -- past PRIVATE
268
               Set_Private_Present (Comp_Unit_Node, True);
269
            end if;
270
 
271
         elsif Token = Tok_Procedure
272
           or else Token = Tok_Function
273
           or else Token = Tok_Generic
274
         then
275
            Set_Private_Present (Comp_Unit_Node, True);
276
         end if;
277
      end if;
278
 
279
      --  Loop to find our way to a compilation unit token
280
 
281
      loop
282
         exit when Token in Token_Class_Cunit and then Token /= Tok_With;
283
 
284
         exit when Bad_Spelling_Of (Tok_Package)
285
           or else Bad_Spelling_Of (Tok_Function)
286
           or else Bad_Spelling_Of (Tok_Generic)
287
           or else Bad_Spelling_Of (Tok_Separate)
288
           or else Bad_Spelling_Of (Tok_Procedure);
289
 
290
         --  Allow task and protected for nice error recovery purposes
291
 
292
         exit when Token = Tok_Task
293
           or else Token = Tok_Protected;
294
 
295
         if Token = Tok_With then
296
            Error_Msg_SC ("misplaced WITH");
297
            Append_List (P_Context_Clause, Context_Items (Comp_Unit_Node));
298
 
299
         elsif Bad_Spelling_Of (Tok_With) then
300
            Append_List (P_Context_Clause, Context_Items (Comp_Unit_Node));
301
 
302
         else
303
            if Operating_Mode = Check_Syntax and then Token = Tok_EOF then
304
               Error_Msg_SC ("?file contains no compilation units");
305
            else
306
               Error_Msg_SC ("compilation unit expected");
307
               Cunit_Error_Flag := True;
308
               Resync_Cunit;
309
            end if;
310
 
311
            --  If we are at an end of file, then just quit, the above error
312
            --  message was complaint enough.
313
 
314
            if Token = Tok_EOF then
315
               return Error;
316
            end if;
317
         end if;
318
      end loop;
319
 
320
      --  We have a compilation unit token, so that's a reasonable choice for
321
      --  determining the standard casing convention used for keywords in case
322
      --  it hasn't already been done on seeing a WITH or PRIVATE.
323
 
324
      Set_Keyword_Casing (Current_Source_File, Determine_Token_Casing);
325
 
326
      if Style_Check then
327
         Style.Check_Indentation;
328
      end if;
329
 
330
      --  Remaining processing depends on particular type of compilation unit
331
 
332
      if Token = Tok_Package then
333
 
334
         --  A common error is to omit the body keyword after package. We can
335
         --  often diagnose this early on (before getting loads of errors from
336
         --  contained subprogram bodies), by knowing that the file we
337
         --  are compiling has a name that requires a body to be found.
338
 
339
         Save_Scan_State (Scan_State);
340
         Scan; -- past Package keyword
341
 
342
         if Token /= Tok_Body
343
           and then
344
             Get_Expected_Unit_Type
345
               (File_Name (Current_Source_File)) = Expect_Body
346
         then
347
            Error_Msg_BC ("keyword BODY expected here [see file name]");
348
            Restore_Scan_State (Scan_State);
349
            Set_Unit (Comp_Unit_Node, P_Package (Pf_Pbod));
350
         else
351
            Restore_Scan_State (Scan_State);
352
            Set_Unit (Comp_Unit_Node, P_Package (Pf_Decl_Gins_Pbod_Rnam));
353
         end if;
354
 
355
      elsif Token = Tok_Generic then
356
         Set_Unit (Comp_Unit_Node, P_Generic);
357
 
358
      elsif Token = Tok_Separate then
359
         Set_Unit (Comp_Unit_Node, P_Subunit);
360
 
361
      elsif Token = Tok_Function
362
        or else Token = Tok_Not
363
        or else Token = Tok_Overriding
364
        or else Token = Tok_Procedure
365
      then
366
         Set_Unit (Comp_Unit_Node, P_Subprogram (Pf_Decl_Gins_Pbod_Rnam));
367
 
368
         --  A little bit of an error recovery check here. If we just scanned
369
         --  a subprogram declaration (as indicated by an SIS entry being
370
         --  active), then if the following token is BEGIN or an identifier,
371
         --  or a token which can reasonably start a declaration but cannot
372
         --  start a compilation unit, then we assume that the semicolon in
373
         --  the declaration should have been IS.
374
 
375
         if SIS_Entry_Active then
376
 
377
            if Token = Tok_Begin
378
               or else Token = Tok_Identifier
379
               or else Token in Token_Class_Deckn
380
            then
381
               Push_Scope_Stack;
382
               Scope.Table (Scope.Last).Etyp := E_Name;
383
               Scope.Table (Scope.Last).Sloc := SIS_Sloc;
384
               Scope.Table (Scope.Last).Ecol := SIS_Ecol;
385
               Scope.Table (Scope.Last).Lreq := False;
386
               SIS_Entry_Active := False;
387
 
388
               --  If we had a missing semicolon in the declaration, then
389
               --  change the message to from <missing ";"> to <missing "is">
390
 
391
               if SIS_Missing_Semicolon_Message /= No_Error_Msg then
392
                  Change_Error_Text     -- Replace: "missing "";"" "
393
                    (SIS_Missing_Semicolon_Message, "missing IS");
394
 
395
               --  Otherwise we saved the semicolon position, so complain
396
 
397
               else
398
                  Error_Msg (""";"" should be IS", SIS_Semicolon_Sloc);
399
               end if;
400
 
401
               Body_Node := Unit (Comp_Unit_Node);
402
               Specification_Node := Specification (Body_Node);
403
               Change_Node (Body_Node, N_Subprogram_Body);
404
               Set_Specification (Body_Node, Specification_Node);
405
               Parse_Decls_Begin_End (Body_Node);
406
               Set_Unit (Comp_Unit_Node, Body_Node);
407
            end if;
408
 
409
         --  If we scanned a subprogram body, make sure we did not have private
410
 
411
         elsif Private_Sloc /= No_Location
412
           and then
413
             Nkind (Unit (Comp_Unit_Node)) not in N_Subprogram_Instantiation
414
           and then
415
             Nkind (Unit (Comp_Unit_Node)) /= N_Subprogram_Renaming_Declaration
416
         then
417
            Error_Msg ("cannot have private subprogram body", Private_Sloc);
418
 
419
         --  P_Subprogram can yield an abstract subprogram, but this cannot
420
         --  be a compilation unit. Treat as a subprogram declaration.
421
 
422
         elsif
423
           Nkind (Unit (Comp_Unit_Node)) = N_Abstract_Subprogram_Declaration
424
         then
425
            Error_Msg_N
426
              ("compilation unit cannot be abstract subprogram",
427
                 Unit (Comp_Unit_Node));
428
 
429
            Unit_Node :=
430
              New_Node (N_Subprogram_Declaration, Sloc (Comp_Unit_Node));
431
            Set_Specification (Unit_Node,
432
              Specification (Unit (Comp_Unit_Node)));
433
            Set_Unit (Comp_Unit_Node, Unit_Node);
434
         end if;
435
 
436
      --  Otherwise we have TASK. This is not really an acceptable token,
437
      --  but we accept it to improve error recovery.
438
 
439
      elsif Token = Tok_Task then
440
         Scan; -- Past TASK
441
 
442
         if Token = Tok_Type then
443
            Error_Msg_SP
444
              ("task type cannot be used as compilation unit");
445
         else
446
            Error_Msg_SP
447
              ("task declaration cannot be used as compilation unit");
448
         end if;
449
 
450
         --  If in check syntax mode, accept the task anyway. This is done
451
         --  particularly to improve the behavior of GNATCHOP in this case.
452
 
453
         if Operating_Mode = Check_Syntax then
454
            Set_Unit (Comp_Unit_Node, P_Task);
455
 
456
         --  If not in syntax only mode, treat this as horrible error
457
 
458
         else
459
            Cunit_Error_Flag := True;
460
            return Error;
461
         end if;
462
 
463
      else pragma Assert (Token = Tok_Protected);
464
         Scan; -- Past PROTECTED
465
 
466
         if Token = Tok_Type then
467
            Error_Msg_SP
468
              ("protected type cannot be used as compilation unit");
469
         else
470
            Error_Msg_SP
471
              ("protected declaration cannot be used as compilation unit");
472
         end if;
473
 
474
         --  If in check syntax mode, accept protected anyway. This is done
475
         --  particularly to improve the behavior of GNATCHOP in this case.
476
 
477
         if Operating_Mode = Check_Syntax then
478
            Set_Unit (Comp_Unit_Node, P_Protected);
479
 
480
         --  If not in syntax only mode, treat this as horrible error
481
 
482
         else
483
            Cunit_Error_Flag := True;
484
            return Error;
485
         end if;
486
      end if;
487
 
488
      --  Here is where locate the compilation unit entity. This is a little
489
      --  tricky, since it is buried in various places.
490
 
491
      Unit_Node := Unit (Comp_Unit_Node);
492
 
493
      --  Another error from which it is hard to recover
494
 
495
      if Nkind (Unit_Node) = N_Subprogram_Body_Stub
496
        or else Nkind (Unit_Node) = N_Package_Body_Stub
497
      then
498
         Cunit_Error_Flag := True;
499
         return Error;
500
      end if;
501
 
502
      --  Only try this if we got an OK unit!
503
 
504
      if Unit_Node /= Error then
505
         if Nkind (Unit_Node) = N_Subunit then
506
            Unit_Node := Proper_Body (Unit_Node);
507
         end if;
508
 
509
         if Nkind (Unit_Node) in N_Generic_Declaration then
510
            Unit_Node := Specification (Unit_Node);
511
         end if;
512
 
513
         if Nkind (Unit_Node) = N_Package_Declaration
514
           or else Nkind (Unit_Node) = N_Subprogram_Declaration
515
           or else Nkind (Unit_Node) = N_Subprogram_Body
516
           or else Nkind (Unit_Node) = N_Subprogram_Renaming_Declaration
517
         then
518
            Unit_Node := Specification (Unit_Node);
519
 
520
         elsif Nkind (Unit_Node) = N_Subprogram_Renaming_Declaration then
521
            if Ada_Version = Ada_83 then
522
               Error_Msg_N
523
                 ("(Ada 83) library unit renaming not allowed", Unit_Node);
524
            end if;
525
         end if;
526
 
527
         if Nkind (Unit_Node) = N_Task_Body
528
           or else Nkind (Unit_Node) = N_Protected_Body
529
           or else Nkind (Unit_Node) = N_Task_Type_Declaration
530
           or else Nkind (Unit_Node) = N_Protected_Type_Declaration
531
           or else Nkind (Unit_Node) = N_Single_Task_Declaration
532
           or else Nkind (Unit_Node) = N_Single_Protected_Declaration
533
         then
534
            Name_Node := Defining_Identifier (Unit_Node);
535
 
536
         elsif Nkind (Unit_Node) = N_Function_Instantiation
537
           or else Nkind (Unit_Node) = N_Function_Specification
538
           or else Nkind (Unit_Node) = N_Generic_Function_Renaming_Declaration
539
           or else Nkind (Unit_Node) = N_Generic_Package_Renaming_Declaration
540
           or else Nkind (Unit_Node) = N_Generic_Procedure_Renaming_Declaration
541
           or else Nkind (Unit_Node) = N_Package_Body
542
           or else Nkind (Unit_Node) = N_Package_Instantiation
543
           or else Nkind (Unit_Node) = N_Package_Renaming_Declaration
544
           or else Nkind (Unit_Node) = N_Package_Specification
545
           or else Nkind (Unit_Node) = N_Procedure_Instantiation
546
           or else Nkind (Unit_Node) = N_Procedure_Specification
547
         then
548
            Name_Node := Defining_Unit_Name (Unit_Node);
549
 
550
         --  Anything else is a serious error, abandon scan
551
 
552
         else
553
            raise Error_Resync;
554
         end if;
555
 
556
         Set_Sloc (Comp_Unit_Node, Sloc (Name_Node));
557
         Set_Sloc (Aux_Decls_Node (Comp_Unit_Node), Sloc (Name_Node));
558
 
559
         --  Set Entity field in file table. Easier now that we have name!
560
         --  Note that this is also skipped if we had a bad unit
561
 
562
         if Nkind (Name_Node) = N_Defining_Program_Unit_Name then
563
            Set_Cunit_Entity
564
              (Current_Source_Unit, Defining_Identifier (Name_Node));
565
         else
566
            Set_Cunit_Entity (Current_Source_Unit, Name_Node);
567
         end if;
568
 
569
         Set_Unit_Name
570
           (Current_Source_Unit, Get_Unit_Name (Unit (Comp_Unit_Node)));
571
 
572
      --  If we had a bad unit, make sure the fatal flag is set in the file
573
      --  table entry, since this is surely a fatal error and also set our
574
      --  flag to inhibit the requirement that we be at end of file.
575
 
576
      else
577
         Cunit_Error_Flag := True;
578
         Set_Fatal_Error (Current_Source_Unit);
579
      end if;
580
 
581
      --  Clear away any missing semicolon indication, we are done with that
582
      --  unit, so what's done is done, and we don't want anything hanging
583
      --  around from the attempt to parse it!
584
 
585
      SIS_Entry_Active := False;
586
 
587
      --  Scan out pragmas after unit
588
 
589
      while Token = Tok_Pragma loop
590
         Save_Scan_State (Scan_State);
591
 
592
         --  If we are in syntax scan mode allowing multiple units, then start
593
         --  the next unit if we encounter a configuration pragma, or a source
594
         --  reference pragma. We take care not to actually scan the pragma in
595
         --  this case (we don't want it to take effect for the current unit).
596
 
597
         if Operating_Mode = Check_Syntax then
598
            Scan;  -- past Pragma
599
 
600
            if Token = Tok_Identifier
601
              and then
602
                (Is_Configuration_Pragma_Name (Token_Name)
603
                   or else Token_Name = Name_Source_Reference)
604
            then
605
               Restore_Scan_State (Scan_State); -- to Pragma
606
               exit;
607
            end if;
608
         end if;
609
 
610
         --  Otherwise eat the pragma, it definitely belongs with the
611
         --  current unit, and not with the following unit.
612
 
613
         Restore_Scan_State (Scan_State); -- to Pragma
614
         P := P_Pragma;
615
 
616
         if No (Pragmas_After (Aux_Decls_Node (Comp_Unit_Node))) then
617
            Set_Pragmas_After
618
              (Aux_Decls_Node (Comp_Unit_Node), New_List);
619
         end if;
620
 
621
         Append (P, Pragmas_After (Aux_Decls_Node (Comp_Unit_Node)));
622
      end loop;
623
 
624
      --  Cancel effect of any outstanding pragma Warnings (Off)
625
 
626
      Set_Warnings_Mode_On (Scan_Ptr);
627
 
628
      --  Ada 83 error checks
629
 
630
      if Ada_Version = Ada_83 then
631
 
632
         --  Check we did not with any child units
633
 
634
         Item := First (Context_Items (Comp_Unit_Node));
635
 
636
         while Present (Item) loop
637
            if Nkind (Item) = N_With_Clause
638
              and then Nkind (Name (Item)) /= N_Identifier
639
            then
640
               Error_Msg_N ("(Ada 83) child units not allowed", Item);
641
            end if;
642
 
643
            Next (Item);
644
         end loop;
645
 
646
         --  Check that we did not have a PRIVATE keyword present
647
 
648
         if Private_Present (Comp_Unit_Node) then
649
            Error_Msg
650
              ("(Ada 83) private units not allowed", Private_Sloc);
651
         end if;
652
      end if;
653
 
654
      --  If no serious error, then output possible unit information line
655
      --  for gnatchop if we are in syntax only, list units mode.
656
 
657
      if not Cunit_Error_Flag
658
        and then List_Units
659
        and then Operating_Mode = Check_Syntax
660
      then
661
         Unit_Display (Comp_Unit_Node, Cunit_Location, SR_Present);
662
      end if;
663
 
664
      --  And now we should be at the end of file
665
 
666
      if Token /= Tok_EOF then
667
 
668
         --  If we already had to scan for a compilation unit, then don't
669
         --  give any further error message, since it just seems to make
670
         --  things worse, and we already gave a serious error message.
671
 
672
         if Cunit_Error_Flag then
673
            null;
674
 
675
         --  If we are in check syntax mode, then we allow multiple units
676
         --  so we just return with Token not set to Tok_EOF and no message.
677
 
678
         elsif Operating_Mode = Check_Syntax then
679
            return Comp_Unit_Node;
680
 
681
         --  We also allow multiple units if we are in multiple unit mode
682
 
683
         elsif Multiple_Unit_Index /= 0 then
684
 
685
            --  Skip tokens to end of file, so that the -gnatl listing
686
            --  will be complete in this situation, but no need to parse
687
            --  the remaining units; no style checking either.
688
 
689
            declare
690
               Save_Style_Check : constant Boolean := Style_Check;
691
 
692
            begin
693
               Style_Check := False;
694
 
695
               while Token /= Tok_EOF loop
696
                  Scan;
697
               end loop;
698
 
699
               Style_Check := Save_Style_Check;
700
            end;
701
 
702
            return Comp_Unit_Node;
703
 
704
         --  Otherwise we have an error. We suppress the error message
705
         --  if we already had a fatal error, since this stops junk
706
         --  cascaded messages in some situations.
707
 
708
         else
709
            if not Fatal_Error (Current_Source_Unit) then
710
               if Token in Token_Class_Cunit then
711
                  Error_Msg_SC
712
                    ("end of file expected, " &
713
                     "file can have only one compilation unit");
714
               else
715
                  Error_Msg_SC ("end of file expected");
716
               end if;
717
            end if;
718
         end if;
719
 
720
         --  Skip tokens to end of file, so that the -gnatl listing
721
         --  will be complete in this situation, but no error checking
722
         --  other than that provided at the token level.
723
 
724
         while Token /= Tok_EOF loop
725
            Scan;
726
         end loop;
727
 
728
         return Error;
729
 
730
      --  Normal return (we were at the end of file as expected)
731
 
732
      else
733
         return Comp_Unit_Node;
734
      end if;
735
 
736
   exception
737
 
738
      --  An error resync is a serious bomb, so indicate result unit no good
739
 
740
      when Error_Resync =>
741
         Set_Fatal_Error (Current_Source_Unit);
742
         return Error;
743
   end P_Compilation_Unit;
744
 
745
   --------------------------
746
   -- 10.1.1  Library Item --
747
   --------------------------
748
 
749
   --  Parsed by P_Compilation_Unit (10.1.1)
750
 
751
   --------------------------------------
752
   -- 10.1.1  Library Unit Declaration --
753
   --------------------------------------
754
 
755
   --  Parsed by P_Compilation_Unit (10.1.1)
756
 
757
   ------------------------------------------------
758
   -- 10.1.1  Library Unit Renaming Declaration  --
759
   ------------------------------------------------
760
 
761
   --  Parsed by P_Compilation_Unit (10.1.1)
762
 
763
   -------------------------------
764
   -- 10.1.1  Library Unit Body --
765
   -------------------------------
766
 
767
   --  Parsed by P_Compilation_Unit (10.1.1)
768
 
769
   ------------------------------
770
   -- 10.1.1  Parent Unit Name --
771
   ------------------------------
772
 
773
   --  Parsed (as a name) by its parent construct
774
 
775
   ----------------------------
776
   -- 10.1.2  Context Clause --
777
   ----------------------------
778
 
779
   --  CONTEXT_CLAUSE ::= {CONTEXT_ITEM}
780
 
781
   --  CONTEXT_ITEM ::= WITH_CLAUSE | USE_CLAUSE | WITH_TYPE_CLAUSE
782
 
783
   --  WITH_CLAUSE ::=
784
   --  [LIMITED] [PRIVATE]  with library_unit_NAME {,library_unit_NAME};
785
   --  Note: the two qualifiers are Ada 2005 extensions.
786
 
787
   --  WITH_TYPE_CLAUSE ::=
788
   --    with type type_NAME is access; | with type type_NAME is tagged;
789
   --  Note: this form is obsolete (old GNAT extension).
790
 
791
   --  Error recovery: Cannot raise Error_Resync
792
 
793
   function P_Context_Clause return List_Id is
794
      Item_List   : List_Id;
795
      Has_Limited : Boolean := False;
796
      Has_Private : Boolean := False;
797
      Scan_State  : Saved_Scan_State;
798
      With_Node   : Node_Id;
799
      First_Flag  : Boolean;
800
 
801
   begin
802
      Item_List := New_List;
803
 
804
      --  Get keyword casing from WITH keyword in case not set yet
805
 
806
      if Token = Tok_With then
807
         Set_Keyword_Casing (Current_Source_File, Determine_Token_Casing);
808
      end if;
809
 
810
      --  Loop through context items
811
 
812
      loop
813
         if Style_Check then
814
            Style.Check_Indentation;
815
         end if;
816
 
817
         --  Gather any pragmas appearing in the context clause
818
 
819
         P_Pragmas_Opt (Item_List);
820
 
821
         --  Processing for WITH clause
822
 
823
         --  Ada 2005 (AI-50217, AI-262): First check for LIMITED WITH,
824
         --  PRIVATE WITH, or both.
825
 
826
         if Token = Tok_Limited then
827
            Has_Limited := True;
828
            Has_Private := False;
829
            Scan; -- past LIMITED
830
 
831
            --  In the context, LIMITED can only appear in a with_clause
832
 
833
            if Token = Tok_Private then
834
               Has_Private := True;
835
               Scan;  -- past PRIVATE
836
            end if;
837
 
838
            if Token /= Tok_With then
839
               Error_Msg_SC ("unexpected LIMITED ignored");
840
            end if;
841
 
842
            if Ada_Version < Ada_05 then
843
               Error_Msg_SP ("LIMITED WITH is an Ada 2005 extension");
844
               Error_Msg_SP
845
                 ("\unit must be compiled with -gnat05 switch");
846
            end if;
847
 
848
         elsif Token = Tok_Private then
849
            Has_Limited := False;
850
            Has_Private := True;
851
            Save_Scan_State (Scan_State);
852
            Scan;  -- past PRIVATE
853
 
854
            if Token /= Tok_With then
855
 
856
               --  Keyword is beginning of private child unit
857
 
858
               Restore_Scan_State (Scan_State); -- to PRIVATE
859
               return Item_List;
860
 
861
            elsif Ada_Version < Ada_05 then
862
               Error_Msg_SP ("`PRIVATE WITH` is an Ada 2005 extension");
863
               Error_Msg_SP
864
                 ("\unit must be compiled with -gnat05 switch");
865
            end if;
866
 
867
         else
868
            Has_Limited := False;
869
            Has_Private := False;
870
         end if;
871
 
872
         if Token = Tok_With then
873
            Scan; -- past WITH
874
 
875
            if Token = Tok_Type then
876
 
877
               --  WITH TYPE is an obsolete GNAT specific extension
878
 
879
               Error_Msg_SP
880
                 ("`WITH TYPE` is an obsolete 'G'N'A'T extension");
881
               Error_Msg_SP ("\use Ada 2005 `LIMITED WITH` clause instead");
882
 
883
               Scan;  -- past TYPE
884
 
885
               T_Is;
886
 
887
               if Token = Tok_Tagged then
888
                  Scan;
889
 
890
               elsif Token = Tok_Access then
891
                  Scan;
892
 
893
               else
894
                  Error_Msg_SC ("expect tagged or access qualifier");
895
               end if;
896
 
897
               TF_Semicolon;
898
 
899
            else
900
               First_Flag := True;
901
 
902
               --  Loop through names in one with clause, generating a separate
903
               --  N_With_Clause node for each name encountered.
904
 
905
               loop
906
                  With_Node := New_Node (N_With_Clause, Token_Ptr);
907
                  Append (With_Node, Item_List);
908
 
909
                  --  Note that we allow with'ing of child units, even in
910
                  --  Ada 83 mode, since presumably if this is not desired,
911
                  --  then the compilation of the child unit itself is the
912
                  --  place where such an "error" should be caught.
913
 
914
                  Set_Name (With_Node, P_Qualified_Simple_Name);
915
                  Set_First_Name (With_Node, First_Flag);
916
                  Set_Limited_Present (With_Node, Has_Limited);
917
                  Set_Private_Present (With_Node, Has_Private);
918
                  First_Flag := False;
919
 
920
                  --  All done if no comma
921
 
922
                  exit when Token /= Tok_Comma;
923
 
924
                  --  If comma is followed by compilation unit token
925
                  --  or by USE, or PRAGMA, then it should have been a
926
                  --  semicolon after all
927
 
928
                  Save_Scan_State (Scan_State);
929
                  Scan; -- past comma
930
 
931
                  if Token in Token_Class_Cunit
932
                    or else Token = Tok_Use
933
                    or else Token = Tok_Pragma
934
                  then
935
                     Restore_Scan_State (Scan_State);
936
                     exit;
937
                  end if;
938
               end loop;
939
 
940
               Set_Last_Name (With_Node, True);
941
               TF_Semicolon;
942
            end if;
943
 
944
         --  Processing for USE clause
945
 
946
         elsif Token = Tok_Use then
947
            Append (P_Use_Clause, Item_List);
948
 
949
         --  Anything else is end of context clause
950
 
951
         else
952
            exit;
953
         end if;
954
      end loop;
955
 
956
      return Item_List;
957
   end P_Context_Clause;
958
 
959
   --------------------------
960
   -- 10.1.2  Context Item --
961
   --------------------------
962
 
963
   --  Parsed by P_Context_Clause (10.1.2)
964
 
965
   -------------------------
966
   -- 10.1.2  With Clause --
967
   -------------------------
968
 
969
   --  Parsed by P_Context_Clause (10.1.2)
970
 
971
   -----------------------
972
   -- 10.1.3  Body Stub --
973
   -----------------------
974
 
975
   --  Subprogram stub parsed by P_Subprogram (6.1)
976
   --  Package stub parsed by P_Package (7.1)
977
   --  Task stub parsed by P_Task (9.1)
978
   --  Protected stub parsed by P_Protected (9.4)
979
 
980
   ----------------------------------
981
   -- 10.1.3  Subprogram Body Stub --
982
   ----------------------------------
983
 
984
   --  Parsed by P_Subprogram (6.1)
985
 
986
   -------------------------------
987
   -- 10.1.3  Package Body Stub --
988
   -------------------------------
989
 
990
   --  Parsed by P_Package (7.1)
991
 
992
   ----------------------------
993
   -- 10.1.3  Task Body Stub --
994
   ----------------------------
995
 
996
   --  Parsed by P_Task (9.1)
997
 
998
   ---------------------------------
999
   -- 10.1.3  Protected Body Stub --
1000
   ---------------------------------
1001
 
1002
   --  Parsed by P_Protected (9.4)
1003
 
1004
   ---------------------
1005
   -- 10.1.3  Subunit --
1006
   ---------------------
1007
 
1008
   --  SUBUNIT ::= separate (PARENT_UNIT_NAME) PROPER_BODY
1009
 
1010
   --  PARENT_UNIT_NAME ::= NAME
1011
 
1012
   --  The caller has checked that the initial token is SEPARATE
1013
 
1014
   --  Error recovery: cannot raise Error_Resync
1015
 
1016
   function P_Subunit return Node_Id is
1017
      Subunit_Node : Node_Id;
1018
      Body_Node    : Node_Id;
1019
 
1020
   begin
1021
      Subunit_Node := New_Node (N_Subunit, Token_Ptr);
1022
      Body_Node := Error; -- in case no good body found
1023
      Scan; -- past SEPARATE;
1024
 
1025
      U_Left_Paren;
1026
      Set_Name (Subunit_Node, P_Qualified_Simple_Name);
1027
      U_Right_Paren;
1028
 
1029
      Ignore (Tok_Semicolon);
1030
 
1031
      if Token = Tok_Function or else Token = Tok_Procedure then
1032
         Body_Node := P_Subprogram (Pf_Pbod);
1033
 
1034
      elsif Token = Tok_Package then
1035
         Body_Node := P_Package (Pf_Pbod);
1036
 
1037
      elsif Token = Tok_Protected then
1038
         Scan; -- past PROTECTED
1039
 
1040
         if Token = Tok_Body then
1041
            Body_Node := P_Protected;
1042
         else
1043
            Error_Msg_AP ("BODY expected");
1044
            return Error;
1045
         end if;
1046
 
1047
      elsif Token = Tok_Task then
1048
         Scan; -- past TASK
1049
 
1050
         if Token = Tok_Body then
1051
            Body_Node := P_Task;
1052
         else
1053
            Error_Msg_AP ("BODY expected");
1054
            return Error;
1055
         end if;
1056
 
1057
      else
1058
         Error_Msg_SC ("proper body expected");
1059
         return Error;
1060
      end if;
1061
 
1062
      Set_Proper_Body  (Subunit_Node, Body_Node);
1063
      return Subunit_Node;
1064
   end P_Subunit;
1065
 
1066
   ------------------
1067
   -- Set_Location --
1068
   ------------------
1069
 
1070
   function Set_Location return Source_Ptr is
1071
      Physical   : Boolean;
1072
      Loc        : Source_Ptr;
1073
      Scan_State : Saved_Scan_State;
1074
 
1075
   begin
1076
      --  A special check. If the first token is pragma, and this is a
1077
      --  Source_Reference pragma, then do NOT eat previous comments, since
1078
      --  the Source_Reference pragma is required to be the first line in
1079
      --  the source file.
1080
 
1081
      if Token = Tok_Pragma then
1082
         Save_Scan_State (Scan_State);
1083
         Scan; --  past Pragma
1084
 
1085
         if Token = Tok_Identifier
1086
           and then Token_Name = Name_Source_Reference
1087
         then
1088
            Restore_Scan_State (Scan_State);
1089
            return Token_Ptr;
1090
         end if;
1091
 
1092
         Restore_Scan_State (Scan_State);
1093
      end if;
1094
 
1095
      --  Otherwise acquire previous comments and blank lines
1096
 
1097
      if Prev_Token = No_Token then
1098
         return Source_First (Current_Source_File);
1099
 
1100
      else
1101
         Loc := Prev_Token_Ptr;
1102
         loop
1103
            exit when Loc = Token_Ptr;
1104
 
1105
            --  Should we worry about UTF_32 line terminators here
1106
 
1107
            if Source (Loc) in Line_Terminator then
1108
               Skip_Line_Terminators (Loc, Physical);
1109
               exit when Physical;
1110
            end if;
1111
 
1112
            Loc := Loc + 1;
1113
         end loop;
1114
 
1115
         return Loc;
1116
      end if;
1117
   end Set_Location;
1118
 
1119
   ------------------
1120
   -- Unit_Display --
1121
   ------------------
1122
 
1123
   --  The format of the generated line, as expected by GNATCHOP is
1124
 
1125
   --    Unit {unit} line {line}, file offset {offs} [, SR], file name {file}
1126
 
1127
   --  where
1128
 
1129
   --     {unit}     unit name with terminating (spec) or (body)
1130
   --     {line}     starting line number
1131
   --     {offs}     offset to start of text in file
1132
   --     {file}     source file name
1133
 
1134
   --  The SR parameter is present only if a source reference pragma was
1135
   --  scanned for this unit. The significance is that gnatchop should not
1136
   --  attempt to add another one.
1137
 
1138
   procedure Unit_Display
1139
     (Cunit      : Node_Id;
1140
      Loc        : Source_Ptr;
1141
      SR_Present : Boolean)
1142
   is
1143
      Unum : constant Unit_Number_Type    := Get_Cunit_Unit_Number (Cunit);
1144
      Sind : constant Source_File_Index   := Source_Index (Unum);
1145
      Unam : constant Unit_Name_Type      := Unit_Name (Unum);
1146
 
1147
   begin
1148
      if List_Units then
1149
         Write_Str ("Unit ");
1150
         Write_Unit_Name (Unit_Name (Unum));
1151
         Unit_Location (Sind, Loc);
1152
 
1153
         if SR_Present then
1154
            Write_Str (", SR");
1155
         end if;
1156
 
1157
         Write_Str (", file name ");
1158
         Write_Name (Get_File_Name (Unam, Nkind (Unit (Cunit)) = N_Subunit));
1159
         Write_Eol;
1160
      end if;
1161
   end Unit_Display;
1162
 
1163
   -------------------
1164
   -- Unit_Location --
1165
   -------------------
1166
 
1167
   procedure Unit_Location (Sind : Source_File_Index; Loc : Source_Ptr) is
1168
      Line : constant Logical_Line_Number := Get_Logical_Line_Number (Loc);
1169
      --  Should the above be the physical line number ???
1170
 
1171
   begin
1172
      Write_Str (" line ");
1173
      Write_Int (Int (Line));
1174
 
1175
      Write_Str (", file offset ");
1176
      Write_Int (Int (Loc) - Int (Source_First (Sind)));
1177
   end Unit_Location;
1178
 
1179
end Ch10;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.