mips.h (set_volatile): Delete.
[official-gcc.git] / gcc / ada / prj-attr.adb
blob41bd6c4f4cebe347bc2704438488302fbb006346
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J . A T T R --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-2007, 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 ------------------------------------------------------------------------------
26 with Osint;
27 with Prj.Com; use Prj.Com;
28 with System.Case_Util; use System.Case_Util;
30 package body Prj.Attr is
32 -- Data for predefined attributes and packages
34 -- Names are in lower case and end with '#'
36 -- Package names are preceded by 'P'
38 -- Attribute names are preceded by two or three letters:
40 -- The first letter is one of
41 -- 'S' for Single
42 -- 's' for Single with optional index
43 -- 'L' for List
44 -- 'l' for List of strings with optional indexes
46 -- The second letter is one of
47 -- 'V' for single variable
48 -- 'A' for associative array
49 -- 'a' for case insensitive associative array
50 -- 'b' for associative array, case insensitive if file names are case
51 -- insensitive
52 -- 'c' same as 'b', with optional index
54 -- The third optional letter is
55 -- 'R' to indicate that the attribute is read-only
57 -- End is indicated by two consecutive '#'
59 Initialization_Data : constant String :=
61 -- project level attributes
63 -- General
65 "SVRname#" &
66 "lVmain#" &
67 "LVlanguages#" &
68 "SVmain_language#" &
69 "Laroots#" &
70 "SVexternally_built#" &
72 -- Directories
74 "SVobject_dir#" &
75 "SVexec_dir#" &
76 "LVsource_dirs#" &
77 "LVexcluded_source_dirs#" &
79 -- Source files
81 "LVsource_files#" &
82 "LVlocally_removed_files#" &
83 "LVexcluded_source_files#" &
84 "SVsource_list_file#" &
86 -- Libraries
88 "SVlibrary_dir#" &
89 "SVlibrary_name#" &
90 "SVlibrary_kind#" &
91 "SVlibrary_version#" &
92 "LVlibrary_interface#" &
93 "SVlibrary_auto_init#" &
94 "LVlibrary_options#" &
95 "SVlibrary_src_dir#" &
96 "SVlibrary_ali_dir#" &
97 "SVlibrary_gcc#" &
98 "SVlibrary_symbol_file#" &
99 "SVlibrary_symbol_policy#" &
100 "SVlibrary_reference_symbol_file#" &
102 -- Configuration - General
104 "SVdefault_language#" &
105 "LVrun_path_option#" &
106 "Satoolchain_version#" &
107 "Satoolchain_description#" &
109 -- Configuration - Libraries
111 "SVlibrary_builder#" &
112 "SVlibrary_support#" &
114 -- Configuration - Archives
116 "LVarchive_builder#" &
117 "LVarchive_indexer#" &
118 "SVarchive_suffix#" &
119 "LVlibrary_partial_linker#" &
121 -- Configuration - Shared libraries
123 "SVshared_library_prefix#" &
124 "SVshared_library_suffix#" &
125 "SVsymbolic_link_supported#" &
126 "SVlibrary_major_minor_id_supported#" &
127 "SVlibrary_auto_init_supported#" &
128 "LVshared_library_minimum_switches#" &
129 "LVlibrary_version_switches#" &
130 "Saruntime_library_dir#" &
132 -- package Naming
134 "Pnaming#" &
135 "Saspecification_suffix#" &
136 "Saspec_suffix#" &
137 "Saimplementation_suffix#" &
138 "Sabody_suffix#" &
139 "SVseparate_suffix#" &
140 "SVcasing#" &
141 "SVdot_replacement#" &
142 "sAspecification#" &
143 "sAspec#" &
144 "sAimplementation#" &
145 "sAbody#" &
146 "Laspecification_exceptions#" &
147 "Laimplementation_exceptions#" &
149 -- package Compiler
151 "Pcompiler#" &
152 "Ladefault_switches#" &
153 "Lcswitches#" &
154 "SVlocal_configuration_pragmas#" &
155 "Salocal_config_file#" &
157 -- Configuration - Compiling
159 "Sadriver#" &
160 "Larequired_switches#" &
161 "Lapic_option#" &
163 -- Configuration - Mapping files
165 "Lamapping_file_switches#" &
166 "Samapping_spec_suffix#" &
167 "Samapping_body_suffix#" &
169 -- Configuration - Config files
171 "Laconfig_file_switches#" &
172 "Saconfig_body_file_name#" &
173 "Saconfig_spec_file_name#" &
174 "Saconfig_body_file_name_pattern#" &
175 "Saconfig_spec_file_name_pattern#" &
176 "Saconfig_file_unique#" &
178 -- Configuration - Dependencies
180 "Ladependency_switches#" &
181 "Lacompute_dependency#" &
183 -- Configuration - Search paths
185 "Lainclude_switches#" &
186 "Sainclude_path#" &
187 "Sainclude_path_file#" &
189 -- package Builder
191 "Pbuilder#" &
192 "Ladefault_switches#" &
193 "Lcswitches#" &
194 "Scexecutable#" &
195 "SVexecutable_suffix#" &
196 "SVglobal_configuration_pragmas#" &
197 "Saglobal_config_file#" &
199 -- package gnatls
201 "Pgnatls#" &
202 "LVswitches#" &
204 -- package Binder
206 "Pbinder#" &
207 "Ladefault_switches#" &
208 "Lcswitches#" &
210 -- Configuration - Binding
212 "Sadriver#" &
213 "Larequired_switches#" &
214 "Saprefix#" &
215 "Saobjects_path#" &
216 "Saobjects_path_file#" &
218 -- package Linker
220 "Plinker#" &
221 "LVrequired_switches#" &
222 "Ladefault_switches#" &
223 "Lcswitches#" &
224 "LVlinker_options#" &
226 -- Configuration - Linking
228 "SVdriver#" &
229 "LVexecutable_switch#" &
230 "SVlib_dir_switch#" &
231 "SVlib_name_switch#" &
233 -- package Cross_Reference
235 "Pcross_reference#" &
236 "Ladefault_switches#" &
237 "Lbswitches#" &
239 -- package Finder
241 "Pfinder#" &
242 "Ladefault_switches#" &
243 "Lbswitches#" &
245 -- package Pretty_Printer
247 "Ppretty_printer#" &
248 "Ladefault_switches#" &
249 "Lbswitches#" &
251 -- package gnatstub
253 "Pgnatstub#" &
254 "Ladefault_switches#" &
255 "Lbswitches#" &
257 -- package Check
259 "Pcheck#" &
260 "Ladefault_switches#" &
261 "Lbswitches#" &
263 -- package Eliminate
265 "Peliminate#" &
266 "Ladefault_switches#" &
267 "Lbswitches#" &
269 -- package Metrics
271 "Pmetrics#" &
272 "Ladefault_switches#" &
273 "Lbswitches#" &
275 -- package Ide
277 "Pide#" &
278 "Ladefault_switches#" &
279 "SVremote_host#" &
280 "SVprogram_host#" &
281 "SVcommunication_protocol#" &
282 "Sacompiler_command#" &
283 "SVdebugger_command#" &
284 "SVgnatlist#" &
285 "SVvcs_kind#" &
286 "SVvcs_file_check#" &
287 "SVvcs_log_check#" &
289 -- package Stack
291 "Pstack#" &
292 "LVswitches#" &
294 "#";
296 Initialized : Boolean := False;
297 -- A flag to avoid multiple initialization
299 function Name_Id_Of (Name : String) return Name_Id;
300 -- Returns the Name_Id for Name in lower case
302 -----------------------
303 -- Attribute_Kind_Of --
304 -----------------------
306 function Attribute_Kind_Of
307 (Attribute : Attribute_Node_Id) return Attribute_Kind
309 begin
310 if Attribute = Empty_Attribute then
311 return Unknown;
312 else
313 return Attrs.Table (Attribute.Value).Attr_Kind;
314 end if;
315 end Attribute_Kind_Of;
317 -----------------------
318 -- Attribute_Name_Of --
319 -----------------------
321 function Attribute_Name_Of (Attribute : Attribute_Node_Id) return Name_Id is
322 begin
323 if Attribute = Empty_Attribute then
324 return No_Name;
325 else
326 return Attrs.Table (Attribute.Value).Name;
327 end if;
328 end Attribute_Name_Of;
330 --------------------------
331 -- Attribute_Node_Id_Of --
332 --------------------------
334 function Attribute_Node_Id_Of
335 (Name : Name_Id;
336 Starting_At : Attribute_Node_Id) return Attribute_Node_Id
338 Id : Attr_Node_Id := Starting_At.Value;
340 begin
341 while Id /= Empty_Attr
342 and then Attrs.Table (Id).Name /= Name
343 loop
344 Id := Attrs.Table (Id).Next;
345 end loop;
347 return (Value => Id);
348 end Attribute_Node_Id_Of;
350 ----------------
351 -- Initialize --
352 ----------------
354 procedure Initialize is
355 Start : Positive := Initialization_Data'First;
356 Finish : Positive := Start;
357 Current_Package : Pkg_Node_Id := Empty_Pkg;
358 Current_Attribute : Attr_Node_Id := Empty_Attr;
359 Is_An_Attribute : Boolean := False;
360 Var_Kind : Variable_Kind := Undefined;
361 Optional_Index : Boolean := False;
362 Attr_Kind : Attribute_Kind := Single;
363 Package_Name : Name_Id := No_Name;
364 Attribute_Name : Name_Id := No_Name;
365 First_Attribute : Attr_Node_Id := Attr.First_Attribute;
366 Read_Only : Boolean;
368 function Attribute_Location return String;
369 -- Returns a string depending if we are in the project level attributes
370 -- or in the attributes of a package.
372 ------------------------
373 -- Attribute_Location --
374 ------------------------
376 function Attribute_Location return String is
377 begin
378 if Package_Name = No_Name then
379 return "project level attributes";
381 else
382 return "attribute of package """ &
383 Get_Name_String (Package_Name) & """";
384 end if;
385 end Attribute_Location;
387 -- Start of processing for Initialize
389 begin
390 -- Don't allow Initialize action to be repeated
392 if Initialized then
393 return;
394 end if;
396 -- Make sure the two tables are empty
398 Attrs.Init;
399 Package_Attributes.Init;
401 while Initialization_Data (Start) /= '#' loop
402 Is_An_Attribute := True;
403 case Initialization_Data (Start) is
404 when 'P' =>
406 -- New allowed package
408 Start := Start + 1;
410 Finish := Start;
411 while Initialization_Data (Finish) /= '#' loop
412 Finish := Finish + 1;
413 end loop;
415 Package_Name :=
416 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
418 for Index in First_Package .. Package_Attributes.Last loop
419 if Package_Name = Package_Attributes.Table (Index).Name then
420 Osint.Fail ("duplicate name """,
421 Initialization_Data (Start .. Finish - 1),
422 """ in predefined packages.");
423 end if;
424 end loop;
426 Is_An_Attribute := False;
427 Current_Attribute := Empty_Attr;
428 Package_Attributes.Increment_Last;
429 Current_Package := Package_Attributes.Last;
430 Package_Attributes.Table (Current_Package) :=
431 (Name => Package_Name,
432 Known => True,
433 First_Attribute => Empty_Attr);
434 Start := Finish + 1;
436 when 'S' =>
437 Var_Kind := Single;
438 Optional_Index := False;
440 when 's' =>
441 Var_Kind := Single;
442 Optional_Index := True;
444 when 'L' =>
445 Var_Kind := List;
446 Optional_Index := False;
448 when 'l' =>
449 Var_Kind := List;
450 Optional_Index := True;
452 when others =>
453 raise Program_Error;
454 end case;
456 if Is_An_Attribute then
458 -- New attribute
460 Start := Start + 1;
461 case Initialization_Data (Start) is
462 when 'V' =>
463 Attr_Kind := Single;
465 when 'A' =>
466 Attr_Kind := Associative_Array;
468 when 'a' =>
469 Attr_Kind := Case_Insensitive_Associative_Array;
471 when 'b' =>
472 if Osint.File_Names_Case_Sensitive then
473 Attr_Kind := Associative_Array;
474 else
475 Attr_Kind := Case_Insensitive_Associative_Array;
476 end if;
478 when 'c' =>
479 if Osint.File_Names_Case_Sensitive then
480 Attr_Kind := Optional_Index_Associative_Array;
481 else
482 Attr_Kind :=
483 Optional_Index_Case_Insensitive_Associative_Array;
484 end if;
486 when others =>
487 raise Program_Error;
488 end case;
490 Start := Start + 1;
492 if Initialization_Data (Start) = 'R' then
493 Read_Only := True;
494 Start := Start + 1;
496 else
497 Read_Only := False;
498 end if;
500 Finish := Start;
502 while Initialization_Data (Finish) /= '#' loop
503 Finish := Finish + 1;
504 end loop;
506 Attribute_Name :=
507 Name_Id_Of (Initialization_Data (Start .. Finish - 1));
508 Attrs.Increment_Last;
510 if Current_Attribute = Empty_Attr then
511 First_Attribute := Attrs.Last;
513 if Current_Package /= Empty_Pkg then
514 Package_Attributes.Table (Current_Package).First_Attribute
515 := Attrs.Last;
516 end if;
518 else
519 -- Check that there are no duplicate attributes
521 for Index in First_Attribute .. Attrs.Last - 1 loop
522 if Attribute_Name = Attrs.Table (Index).Name then
523 Osint.Fail ("duplicate attribute """,
524 Initialization_Data (Start .. Finish - 1),
525 """ in " & Attribute_Location);
526 end if;
527 end loop;
529 Attrs.Table (Current_Attribute).Next :=
530 Attrs.Last;
531 end if;
533 Current_Attribute := Attrs.Last;
534 Attrs.Table (Current_Attribute) :=
535 (Name => Attribute_Name,
536 Var_Kind => Var_Kind,
537 Optional_Index => Optional_Index,
538 Attr_Kind => Attr_Kind,
539 Read_Only => Read_Only,
540 Next => Empty_Attr);
541 Start := Finish + 1;
542 end if;
543 end loop;
545 Initialized := True;
546 end Initialize;
548 ------------------
549 -- Is_Read_Only --
550 ------------------
552 function Is_Read_Only (Attribute : Attribute_Node_Id) return Boolean is
553 begin
554 return Attrs.Table (Attribute.Value).Read_Only;
555 end Is_Read_Only;
557 ----------------
558 -- Name_Id_Of --
559 ----------------
561 function Name_Id_Of (Name : String) return Name_Id is
562 begin
563 Name_Len := 0;
564 Add_Str_To_Name_Buffer (Name);
565 To_Lower (Name_Buffer (1 .. Name_Len));
566 return Name_Find;
567 end Name_Id_Of;
569 --------------------
570 -- Next_Attribute --
571 --------------------
573 function Next_Attribute
574 (After : Attribute_Node_Id) return Attribute_Node_Id
576 begin
577 if After = Empty_Attribute then
578 return Empty_Attribute;
579 else
580 return (Value => Attrs.Table (After.Value).Next);
581 end if;
582 end Next_Attribute;
584 -----------------------
585 -- Optional_Index_Of --
586 -----------------------
588 function Optional_Index_Of (Attribute : Attribute_Node_Id) return Boolean is
589 begin
590 if Attribute = Empty_Attribute then
591 return False;
592 else
593 return Attrs.Table (Attribute.Value).Optional_Index;
594 end if;
595 end Optional_Index_Of;
597 ------------------------
598 -- Package_Node_Id_Of --
599 ------------------------
601 function Package_Node_Id_Of (Name : Name_Id) return Package_Node_Id is
602 begin
603 for Index in Package_Attributes.First .. Package_Attributes.Last loop
604 if Package_Attributes.Table (Index).Name = Name then
605 return (Value => Index);
606 end if;
607 end loop;
609 -- If there is no package with this name, return Empty_Package
611 return Empty_Package;
612 end Package_Node_Id_Of;
614 ----------------------------
615 -- Register_New_Attribute --
616 ----------------------------
618 procedure Register_New_Attribute
619 (Name : String;
620 In_Package : Package_Node_Id;
621 Attr_Kind : Defined_Attribute_Kind;
622 Var_Kind : Defined_Variable_Kind;
623 Index_Is_File_Name : Boolean := False;
624 Opt_Index : Boolean := False)
626 Attr_Name : Name_Id;
627 First_Attr : Attr_Node_Id := Empty_Attr;
628 Curr_Attr : Attr_Node_Id;
629 Real_Attr_Kind : Attribute_Kind;
631 begin
632 if Name'Length = 0 then
633 Fail ("cannot register an attribute with no name");
634 raise Project_Error;
635 end if;
637 if In_Package = Empty_Package then
638 Fail ("attempt to add attribute """, Name,
639 """ to an undefined package");
640 raise Project_Error;
641 end if;
643 Attr_Name := Name_Id_Of (Name);
645 First_Attr :=
646 Package_Attributes.Table (In_Package.Value).First_Attribute;
648 -- Check if attribute name is a duplicate
650 Curr_Attr := First_Attr;
651 while Curr_Attr /= Empty_Attr loop
652 if Attrs.Table (Curr_Attr).Name = Attr_Name then
653 Fail ("duplicate attribute name """, Name,
654 """ in package """ &
655 Get_Name_String
656 (Package_Attributes.Table (In_Package.Value).Name) &
657 """");
658 raise Project_Error;
659 end if;
661 Curr_Attr := Attrs.Table (Curr_Attr).Next;
662 end loop;
664 Real_Attr_Kind := Attr_Kind;
666 -- If Index_Is_File_Name, change the attribute kind if necessary
668 if Index_Is_File_Name and then not Osint.File_Names_Case_Sensitive then
669 case Attr_Kind is
670 when Associative_Array =>
671 Real_Attr_Kind := Case_Insensitive_Associative_Array;
673 when Optional_Index_Associative_Array =>
674 Real_Attr_Kind :=
675 Optional_Index_Case_Insensitive_Associative_Array;
677 when others =>
678 null;
679 end case;
680 end if;
682 -- Add the new attribute
684 Attrs.Increment_Last;
685 Attrs.Table (Attrs.Last) :=
686 (Name => Attr_Name,
687 Var_Kind => Var_Kind,
688 Optional_Index => Opt_Index,
689 Attr_Kind => Real_Attr_Kind,
690 Read_Only => False,
691 Next => First_Attr);
692 Package_Attributes.Table (In_Package.Value).First_Attribute :=
693 Attrs.Last;
694 end Register_New_Attribute;
696 --------------------------
697 -- Register_New_Package --
698 --------------------------
700 procedure Register_New_Package (Name : String; Id : out Package_Node_Id) is
701 Pkg_Name : Name_Id;
703 begin
704 if Name'Length = 0 then
705 Fail ("cannot register a package with no name");
706 Id := Empty_Package;
707 return;
708 end if;
710 Pkg_Name := Name_Id_Of (Name);
712 for Index in Package_Attributes.First .. Package_Attributes.Last loop
713 if Package_Attributes.Table (Index).Name = Pkg_Name then
714 Fail ("cannot register a package with a non unique name""",
715 Name, """");
716 Id := Empty_Package;
717 return;
718 end if;
719 end loop;
721 Package_Attributes.Increment_Last;
722 Id := (Value => Package_Attributes.Last);
723 Package_Attributes.Table (Package_Attributes.Last) :=
724 (Name => Pkg_Name,
725 Known => True,
726 First_Attribute => Empty_Attr);
727 end Register_New_Package;
729 procedure Register_New_Package
730 (Name : String;
731 Attributes : Attribute_Data_Array)
733 Pkg_Name : Name_Id;
734 Attr_Name : Name_Id;
735 First_Attr : Attr_Node_Id := Empty_Attr;
736 Curr_Attr : Attr_Node_Id;
737 Attr_Kind : Attribute_Kind;
739 begin
740 if Name'Length = 0 then
741 Fail ("cannot register a package with no name");
742 raise Project_Error;
743 end if;
745 Pkg_Name := Name_Id_Of (Name);
747 for Index in Package_Attributes.First .. Package_Attributes.Last loop
748 if Package_Attributes.Table (Index).Name = Pkg_Name then
749 Fail ("cannot register a package with a non unique name""",
750 Name, """");
751 raise Project_Error;
752 end if;
753 end loop;
755 for Index in Attributes'Range loop
756 Attr_Name := Name_Id_Of (Attributes (Index).Name);
758 Curr_Attr := First_Attr;
759 while Curr_Attr /= Empty_Attr loop
760 if Attrs.Table (Curr_Attr).Name = Attr_Name then
761 Fail ("duplicate attribute name """, Attributes (Index).Name,
762 """ in new package """ & Name & """");
763 raise Project_Error;
764 end if;
766 Curr_Attr := Attrs.Table (Curr_Attr).Next;
767 end loop;
769 Attr_Kind := Attributes (Index).Attr_Kind;
771 if Attributes (Index).Index_Is_File_Name
772 and then not Osint.File_Names_Case_Sensitive
773 then
774 case Attr_Kind is
775 when Associative_Array =>
776 Attr_Kind := Case_Insensitive_Associative_Array;
778 when Optional_Index_Associative_Array =>
779 Attr_Kind :=
780 Optional_Index_Case_Insensitive_Associative_Array;
782 when others =>
783 null;
784 end case;
785 end if;
787 Attrs.Increment_Last;
788 Attrs.Table (Attrs.Last) :=
789 (Name => Attr_Name,
790 Var_Kind => Attributes (Index).Var_Kind,
791 Optional_Index => Attributes (Index).Opt_Index,
792 Attr_Kind => Attr_Kind,
793 Read_Only => False,
794 Next => First_Attr);
795 First_Attr := Attrs.Last;
796 end loop;
798 Package_Attributes.Increment_Last;
799 Package_Attributes.Table (Package_Attributes.Last) :=
800 (Name => Pkg_Name,
801 Known => True,
802 First_Attribute => First_Attr);
803 end Register_New_Package;
805 ---------------------------
806 -- Set_Attribute_Kind_Of --
807 ---------------------------
809 procedure Set_Attribute_Kind_Of
810 (Attribute : Attribute_Node_Id;
811 To : Attribute_Kind)
813 begin
814 if Attribute /= Empty_Attribute then
815 Attrs.Table (Attribute.Value).Attr_Kind := To;
816 end if;
817 end Set_Attribute_Kind_Of;
819 --------------------------
820 -- Set_Variable_Kind_Of --
821 --------------------------
823 procedure Set_Variable_Kind_Of
824 (Attribute : Attribute_Node_Id;
825 To : Variable_Kind)
827 begin
828 if Attribute /= Empty_Attribute then
829 Attrs.Table (Attribute.Value).Var_Kind := To;
830 end if;
831 end Set_Variable_Kind_Of;
833 ----------------------
834 -- Variable_Kind_Of --
835 ----------------------
837 function Variable_Kind_Of
838 (Attribute : Attribute_Node_Id) return Variable_Kind
840 begin
841 if Attribute = Empty_Attribute then
842 return Undefined;
843 else
844 return Attrs.Table (Attribute.Value).Var_Kind;
845 end if;
846 end Variable_Kind_Of;
848 ------------------------
849 -- First_Attribute_Of --
850 ------------------------
852 function First_Attribute_Of
853 (Pkg : Package_Node_Id) return Attribute_Node_Id
855 begin
856 if Pkg = Empty_Package then
857 return Empty_Attribute;
858 else
859 return
860 (Value => Package_Attributes.Table (Pkg.Value).First_Attribute);
861 end if;
862 end First_Attribute_Of;
864 end Prj.Attr;