1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                              A S P E C T S                               --
6--                                                                          --
7--                                 S p e c                                  --
8--                                                                          --
9--          Copyright (C) 2010-2012, 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.                                     --
17--                                                                          --
18-- As a special exception under Section 7 of GPL version 3, you are granted --
19-- additional permissions described in the GCC Runtime Library Exception,   --
20-- version 3.1, as published by the Free Software Foundation.               --
21--                                                                          --
22-- You should have received a copy of the GNU General Public License and    --
23-- a copy of the GCC Runtime Library Exception along with this program;     --
24-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25-- <http://www.gnu.org/licenses/>.                                          --
26--                                                                          --
27-- GNAT was originally developed  by the GNAT team at  New York University. --
28-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29--                                                                          --
30------------------------------------------------------------------------------
31
32--  This package defines the aspects that are recognized by GNAT in aspect
33--  specifications. It also contains the subprograms for storing/retrieving
34--  aspect specifications from the tree. The semantic processing for aspect
35--  specifications is found in Sem_Ch13.Analyze_Aspect_Specifications.
36
37------------------------
38-- Adding New Aspects --
39------------------------
40
41--  In general, each aspect should have a corresponding pragma, so that the
42--  newly developed functionality is available for Ada versions < Ada 2012.
43--  When both are defined, it is convenient to first transform the aspect into
44--  an equivalent pragma in Sem_Ch13.Analyze_Aspect_Specifications, and then
45--  analyze the pragma in Sem_Prag.Analyze_Pragma.
46
47--  To add a new aspect, you need to do the following
48
49--    1. Create a name in snames.ads-tmpl
50
51--    2. Create a value in type Aspect_Id in this unit
52
53--    3. Add a value for the aspect in the global arrays defined in this unit
54
55--    4. Add code for the aspect in Sem_Ch13.Analyze_Aspect_Specifications.
56--       This may involve adding some nodes to the tree to perform additional
57--       treatments later.
58
59--    5. If the semantic analysis of expressions/names in the aspect should not
60--       occur at the point the aspect is defined, add code in the adequate
61--       semantic analysis procedure for the aspect. For example, this is the
62--       case for aspects Pre and Post on subprograms, which are pre-analyzed
63--       at the end of the declaration list to which the subprogram belongs,
64--       and fully analyzed (possibly with expansion) during the semantic
65--       analysis of subprogram bodies.
66
67with Namet;  use Namet;
68with Snames; use Snames;
69with Types;  use Types;
70
71package Aspects is
72
73   --  Type defining recognized aspects
74
75   type Aspect_Id is
76     (No_Aspect,                            -- Dummy entry for no aspect
77      Aspect_Abstract_State,                -- GNAT
78      Aspect_Address,
79      Aspect_Alignment,
80      Aspect_Attach_Handler,
81      Aspect_Bit_Order,
82      Aspect_Component_Size,
83      Aspect_Constant_Indexing,
84      Aspect_Contract_Case,                 -- GNAT
85      Aspect_Contract_Cases,                -- GNAT
86      Aspect_Convention,
87      Aspect_CPU,
88      Aspect_Default_Component_Value,
89      Aspect_Default_Iterator,
90      Aspect_Default_Value,
91      Aspect_Dimension,                     -- GNAT
92      Aspect_Dimension_System,              -- GNAT
93      Aspect_Dispatching_Domain,
94      Aspect_Dynamic_Predicate,
95      Aspect_External_Name,
96      Aspect_External_Tag,
97      Aspect_Global,                        -- GNAT
98      Aspect_Implicit_Dereference,
99      Aspect_Input,
100      Aspect_Interrupt_Priority,
101      Aspect_Invariant,                     -- GNAT
102      Aspect_Iterator_Element,
103      Aspect_Link_Name,
104      Aspect_Machine_Radix,
105      Aspect_Object_Size,                   -- GNAT
106      Aspect_Output,
107      Aspect_Post,
108      Aspect_Postcondition,
109      Aspect_Pre,
110      Aspect_Precondition,
111      Aspect_Predicate,                     -- GNAT
112      Aspect_Priority,
113      Aspect_Read,
114      Aspect_Relative_Deadline,
115      Aspect_Scalar_Storage_Order,          -- GNAT
116      Aspect_Simple_Storage_Pool,           -- GNAT
117      Aspect_Size,
118      Aspect_Small,
119      Aspect_Static_Predicate,
120      Aspect_Storage_Pool,
121      Aspect_Storage_Size,
122      Aspect_Stream_Size,
123      Aspect_Suppress,
124      Aspect_Synchronization,
125      Aspect_Test_Case,                     -- GNAT
126      Aspect_Type_Invariant,
127      Aspect_Unsuppress,
128      Aspect_Value_Size,                    -- GNAT
129      Aspect_Variable_Indexing,
130      Aspect_Warnings,                      -- GNAT
131      Aspect_Write,
132
133      --  The following aspects correspond to library unit pragmas
134
135      Aspect_All_Calls_Remote,
136      Aspect_Compiler_Unit,                 -- GNAT
137      Aspect_Elaborate_Body,
138      Aspect_Preelaborate,
139      Aspect_Preelaborate_05,               -- GNAT
140      Aspect_Pure,
141      Aspect_Pure_05,                       -- GNAT
142      Aspect_Pure_12,                       -- GNAT
143      Aspect_Remote_Call_Interface,
144      Aspect_Remote_Types,
145      Aspect_Shared_Passive,
146      Aspect_Universal_Data,                -- GNAT
147
148      --  Remaining aspects have a static boolean value that turns the aspect
149      --  on or off. They all correspond to pragmas, but are only converted to
150      --  the pragmas where the value is True. A value of False normally means
151      --  that the aspect is ignored, except in the case of derived types where
152      --  the aspect value is inherited from the parent, in which case, we do
153      --  not allow False if we inherit a True value from the parent.
154
155      Aspect_Ada_2005,                      -- GNAT
156      Aspect_Ada_2012,                      -- GNAT
157      Aspect_Asynchronous,
158      Aspect_Atomic,
159      Aspect_Atomic_Components,
160      Aspect_Discard_Names,
161      Aspect_Export,
162      Aspect_Favor_Top_Level,               -- GNAT
163      Aspect_Independent,
164      Aspect_Independent_Components,
165      Aspect_Import,
166      Aspect_Inline,
167      Aspect_Inline_Always,                 -- GNAT
168      Aspect_Interrupt_Handler,
169      Aspect_No_Return,
170      Aspect_Pack,
171      Aspect_Persistent_BSS,                -- GNAT
172      Aspect_Preelaborable_Initialization,
173      Aspect_Pure_Function,                 -- GNAT
174      Aspect_Remote_Access_Type,            -- GNAT
175      Aspect_Shared,                        -- GNAT (equivalent to Atomic)
176      Aspect_Simple_Storage_Pool_Type,      -- GNAT
177      Aspect_Suppress_Debug_Info,           -- GNAT
178      Aspect_Unchecked_Union,
179      Aspect_Universal_Aliasing,            -- GNAT
180      Aspect_Unmodified,                    -- GNAT
181      Aspect_Unreferenced,                  -- GNAT
182      Aspect_Unreferenced_Objects,          -- GNAT
183      Aspect_Volatile,
184      Aspect_Volatile_Components,
185
186      --  Aspects that have a static boolean value but don't correspond to
187      --  pragmas
188
189      Aspect_Lock_Free);
190
191   subtype Aspect_Id_Exclude_No_Aspect is
192     Aspect_Id range Aspect_Id'Succ (No_Aspect) .. Aspect_Id'Last;
193   --  Aspect_Id's excluding No_Aspect
194
195   --  The following array indicates aspects that accept 'Class
196
197   Class_Aspect_OK : constant array (Aspect_Id) of Boolean :=
198                       (Aspect_Invariant      => True,
199                        Aspect_Pre            => True,
200                        Aspect_Predicate      => True,
201                        Aspect_Post           => True,
202                        Aspect_Type_Invariant => True,
203                        others                => False);
204
205   --  The following array indicates aspects that a subtype inherits from
206   --  its base type. True means that the subtype inherits the aspect from
207   --  its base type. False means it is not inherited.
208
209   Base_Aspect : constant array (Aspect_Id) of Boolean :=
210                   (Aspect_Atomic                  => True,
211                    Aspect_Atomic_Components       => True,
212                    Aspect_Discard_Names           => True,
213                    Aspect_Independent_Components  => True,
214                    Aspect_Iterator_Element        => True,
215                    Aspect_Constant_Indexing       => True,
216                    Aspect_Default_Iterator        => True,
217                    Aspect_Type_Invariant          => True,
218                    Aspect_Unchecked_Union         => True,
219                    Aspect_Variable_Indexing       => True,
220                    Aspect_Volatile                => True,
221                    others                         => False);
222
223   --  The following array identifies all implementation defined aspects
224
225   Impl_Defined_Aspects : constant array (Aspect_Id) of Boolean :=
226                            (Aspect_Abstract_State           => True,
227                             Aspect_Ada_2005                 => True,
228                             Aspect_Ada_2012                 => True,
229                             Aspect_Compiler_Unit            => True,
230                             Aspect_Contract_Case            => True,
231                             Aspect_Contract_Cases           => True,
232                             Aspect_Dimension                => True,
233                             Aspect_Dimension_System         => True,
234                             Aspect_Favor_Top_Level          => True,
235                             Aspect_Global                   => True,
236                             Aspect_Inline_Always            => True,
237                             Aspect_Invariant                => True,
238                             Aspect_Lock_Free                => True,
239                             Aspect_Object_Size              => True,
240                             Aspect_Persistent_BSS           => True,
241                             Aspect_Predicate                => True,
242                             Aspect_Preelaborate_05          => True,
243                             Aspect_Pure_05                  => True,
244                             Aspect_Pure_12                  => True,
245                             Aspect_Pure_Function            => True,
246                             Aspect_Remote_Access_Type       => True,
247                             Aspect_Scalar_Storage_Order     => True,
248                             Aspect_Shared                   => True,
249                             Aspect_Simple_Storage_Pool      => True,
250                             Aspect_Simple_Storage_Pool_Type => True,
251                             Aspect_Suppress_Debug_Info      => True,
252                             Aspect_Test_Case                => True,
253                             Aspect_Universal_Aliasing       => True,
254                             Aspect_Universal_Data           => True,
255                             Aspect_Unmodified               => True,
256                             Aspect_Unreferenced             => True,
257                             Aspect_Unreferenced_Objects     => True,
258                             Aspect_Value_Size               => True,
259                             Aspect_Warnings                 => True,
260                             others                          => False);
261
262   --  The following array indicates aspects for which multiple occurrences of
263   --  the same aspect attached to the same declaration are allowed.
264
265   No_Duplicates_Allowed : constant array (Aspect_Id) of Boolean :=
266                             (Aspect_Contract_Case  => False,
267                              Aspect_Test_Case      => False,
268                              others                => True);
269
270   --  The following array indicates type aspects that are inherited and apply
271   --  to the class-wide type as well.
272
273   Inherited_Aspect : constant array (Aspect_Id) of Boolean :=
274                        (Aspect_Constant_Indexing    => True,
275                         Aspect_Default_Iterator     => True,
276                         Aspect_Implicit_Dereference => True,
277                         Aspect_Iterator_Element     => True,
278                         Aspect_Remote_Types         => True,
279                         Aspect_Variable_Indexing    => True,
280                         others                      => False);
281
282   --  The following subtype defines aspects corresponding to library unit
283   --  pragmas, these can only validly appear as aspects for library units,
284   --  and result in a corresponding pragma being inserted immediately after
285   --  the occurrence of the aspect.
286
287   subtype Library_Unit_Aspects is
288     Aspect_Id range Aspect_All_Calls_Remote .. Aspect_Universal_Data;
289
290   --  The following subtype defines aspects accepting an optional static
291   --  boolean parameter indicating if the aspect should be active or
292   --  cancelling. If the parameter is missing the effective value is True,
293   --  enabling the aspect. If the parameter is present it must be a static
294   --  expression of type Standard.Boolean. If the value is True, then the
295   --  aspect is enabled. If it is False, the aspect is disabled.
296
297   subtype Boolean_Aspects is
298     Aspect_Id range Aspect_Ada_2005 .. Aspect_Id'Last;
299
300   subtype Pre_Post_Aspects is
301     Aspect_Id range Aspect_Post .. Aspect_Precondition;
302
303   --  The following type is used for indicating allowed expression forms
304
305   type Aspect_Expression is
306     (Optional,               -- Optional boolean expression
307      Expression,             -- Required expression
308      Name);                  -- Required name
309
310   --  The following array indicates what argument type is required
311
312   Aspect_Argument : constant array (Aspect_Id) of Aspect_Expression :=
313                       (No_Aspect                      => Optional,
314                        Aspect_Abstract_State          => Expression,
315                        Aspect_Address                 => Expression,
316                        Aspect_Alignment               => Expression,
317                        Aspect_Attach_Handler          => Expression,
318                        Aspect_Bit_Order               => Expression,
319                        Aspect_Component_Size          => Expression,
320                        Aspect_Constant_Indexing       => Name,
321                        Aspect_Contract_Case           => Expression,
322                        Aspect_Contract_Cases          => Expression,
323                        Aspect_Convention              => Name,
324                        Aspect_CPU                     => Expression,
325                        Aspect_Default_Component_Value => Expression,
326                        Aspect_Default_Iterator        => Name,
327                        Aspect_Default_Value           => Expression,
328                        Aspect_Dimension               => Expression,
329                        Aspect_Dimension_System        => Expression,
330                        Aspect_Dispatching_Domain      => Expression,
331                        Aspect_Dynamic_Predicate       => Expression,
332                        Aspect_External_Name           => Expression,
333                        Aspect_External_Tag            => Expression,
334                        Aspect_Global                  => Expression,
335                        Aspect_Implicit_Dereference    => Name,
336                        Aspect_Input                   => Name,
337                        Aspect_Interrupt_Priority      => Expression,
338                        Aspect_Invariant               => Expression,
339                        Aspect_Iterator_Element        => Name,
340                        Aspect_Link_Name               => Expression,
341                        Aspect_Machine_Radix           => Expression,
342                        Aspect_Object_Size             => Expression,
343                        Aspect_Output                  => Name,
344                        Aspect_Post                    => Expression,
345                        Aspect_Postcondition           => Expression,
346                        Aspect_Pre                     => Expression,
347                        Aspect_Precondition            => Expression,
348                        Aspect_Predicate               => Expression,
349                        Aspect_Priority                => Expression,
350                        Aspect_Read                    => Name,
351                        Aspect_Relative_Deadline       => Expression,
352                        Aspect_Scalar_Storage_Order    => Expression,
353                        Aspect_Simple_Storage_Pool     => Name,
354                        Aspect_Size                    => Expression,
355                        Aspect_Small                   => Expression,
356                        Aspect_Static_Predicate        => Expression,
357                        Aspect_Storage_Pool            => Name,
358                        Aspect_Storage_Size            => Expression,
359                        Aspect_Stream_Size             => Expression,
360                        Aspect_Suppress                => Name,
361                        Aspect_Synchronization         => Name,
362                        Aspect_Test_Case               => Expression,
363                        Aspect_Type_Invariant          => Expression,
364                        Aspect_Unsuppress              => Name,
365                        Aspect_Value_Size              => Expression,
366                        Aspect_Variable_Indexing       => Name,
367                        Aspect_Warnings                => Name,
368                        Aspect_Write                   => Name,
369
370                        Library_Unit_Aspects           => Optional,
371                        Boolean_Aspects                => Optional);
372
373   -----------------------------------------
374   -- Table Linking Names and Aspect_Id's --
375   -----------------------------------------
376
377   --  Table linking aspect names and id's
378
379   Aspect_Names : constant array (Aspect_Id) of Name_Id := (
380     No_Aspect                           => No_Name,
381     Aspect_Abstract_State               => Name_Abstract_State,
382     Aspect_Ada_2005                     => Name_Ada_2005,
383     Aspect_Ada_2012                     => Name_Ada_2012,
384     Aspect_Address                      => Name_Address,
385     Aspect_Alignment                    => Name_Alignment,
386     Aspect_All_Calls_Remote             => Name_All_Calls_Remote,
387     Aspect_Asynchronous                 => Name_Asynchronous,
388     Aspect_Atomic                       => Name_Atomic,
389     Aspect_Atomic_Components            => Name_Atomic_Components,
390     Aspect_Attach_Handler               => Name_Attach_Handler,
391     Aspect_Bit_Order                    => Name_Bit_Order,
392     Aspect_Compiler_Unit                => Name_Compiler_Unit,
393     Aspect_Component_Size               => Name_Component_Size,
394     Aspect_Constant_Indexing            => Name_Constant_Indexing,
395     Aspect_Contract_Case                => Name_Contract_Case,
396     Aspect_Contract_Cases               => Name_Contract_Cases,
397     Aspect_Convention                   => Name_Convention,
398     Aspect_CPU                          => Name_CPU,
399     Aspect_Default_Iterator             => Name_Default_Iterator,
400     Aspect_Default_Value                => Name_Default_Value,
401     Aspect_Default_Component_Value      => Name_Default_Component_Value,
402     Aspect_Dimension                    => Name_Dimension,
403     Aspect_Dimension_System             => Name_Dimension_System,
404     Aspect_Discard_Names                => Name_Discard_Names,
405     Aspect_Dispatching_Domain           => Name_Dispatching_Domain,
406     Aspect_Dynamic_Predicate            => Name_Dynamic_Predicate,
407     Aspect_Elaborate_Body               => Name_Elaborate_Body,
408     Aspect_External_Name                => Name_External_Name,
409     Aspect_External_Tag                 => Name_External_Tag,
410     Aspect_Export                       => Name_Export,
411     Aspect_Favor_Top_Level              => Name_Favor_Top_Level,
412     Aspect_Global                       => Name_Global,
413     Aspect_Implicit_Dereference         => Name_Implicit_Dereference,
414     Aspect_Import                       => Name_Import,
415     Aspect_Independent                  => Name_Independent,
416     Aspect_Independent_Components       => Name_Independent_Components,
417     Aspect_Inline                       => Name_Inline,
418     Aspect_Inline_Always                => Name_Inline_Always,
419     Aspect_Input                        => Name_Input,
420     Aspect_Interrupt_Handler            => Name_Interrupt_Handler,
421     Aspect_Interrupt_Priority           => Name_Interrupt_Priority,
422     Aspect_Invariant                    => Name_Invariant,
423     Aspect_Iterator_Element             => Name_Iterator_Element,
424     Aspect_Link_Name                    => Name_Link_Name,
425     Aspect_Lock_Free                    => Name_Lock_Free,
426     Aspect_Machine_Radix                => Name_Machine_Radix,
427     Aspect_No_Return                    => Name_No_Return,
428     Aspect_Object_Size                  => Name_Object_Size,
429     Aspect_Output                       => Name_Output,
430     Aspect_Pack                         => Name_Pack,
431     Aspect_Persistent_BSS               => Name_Persistent_BSS,
432     Aspect_Post                         => Name_Post,
433     Aspect_Postcondition                => Name_Postcondition,
434     Aspect_Pre                          => Name_Pre,
435     Aspect_Precondition                 => Name_Precondition,
436     Aspect_Predicate                    => Name_Predicate,
437     Aspect_Preelaborable_Initialization => Name_Preelaborable_Initialization,
438     Aspect_Preelaborate                 => Name_Preelaborate,
439     Aspect_Preelaborate_05              => Name_Preelaborate_05,
440     Aspect_Priority                     => Name_Priority,
441     Aspect_Pure                         => Name_Pure,
442     Aspect_Pure_05                      => Name_Pure_05,
443     Aspect_Pure_12                      => Name_Pure_12,
444     Aspect_Pure_Function                => Name_Pure_Function,
445     Aspect_Read                         => Name_Read,
446     Aspect_Relative_Deadline            => Name_Relative_Deadline,
447     Aspect_Remote_Access_Type           => Name_Remote_Access_Type,
448     Aspect_Remote_Call_Interface        => Name_Remote_Call_Interface,
449     Aspect_Remote_Types                 => Name_Remote_Types,
450     Aspect_Scalar_Storage_Order         => Name_Scalar_Storage_Order,
451     Aspect_Shared                       => Name_Shared,
452     Aspect_Shared_Passive               => Name_Shared_Passive,
453     Aspect_Simple_Storage_Pool          => Name_Simple_Storage_Pool,
454     Aspect_Simple_Storage_Pool_Type     => Name_Simple_Storage_Pool_Type,
455     Aspect_Size                         => Name_Size,
456     Aspect_Small                        => Name_Small,
457     Aspect_Static_Predicate             => Name_Static_Predicate,
458     Aspect_Storage_Pool                 => Name_Storage_Pool,
459     Aspect_Storage_Size                 => Name_Storage_Size,
460     Aspect_Stream_Size                  => Name_Stream_Size,
461     Aspect_Suppress                     => Name_Suppress,
462     Aspect_Suppress_Debug_Info          => Name_Suppress_Debug_Info,
463     Aspect_Synchronization              => Name_Synchronization,
464     Aspect_Test_Case                    => Name_Test_Case,
465     Aspect_Type_Invariant               => Name_Type_Invariant,
466     Aspect_Unchecked_Union              => Name_Unchecked_Union,
467     Aspect_Universal_Aliasing           => Name_Universal_Aliasing,
468     Aspect_Universal_Data               => Name_Universal_Data,
469     Aspect_Unmodified                   => Name_Unmodified,
470     Aspect_Unreferenced                 => Name_Unreferenced,
471     Aspect_Unreferenced_Objects         => Name_Unreferenced_Objects,
472     Aspect_Unsuppress                   => Name_Unsuppress,
473     Aspect_Value_Size                   => Name_Value_Size,
474     Aspect_Variable_Indexing            => Name_Variable_Indexing,
475     Aspect_Volatile                     => Name_Volatile,
476     Aspect_Volatile_Components          => Name_Volatile_Components,
477     Aspect_Warnings                     => Name_Warnings,
478     Aspect_Write                        => Name_Write);
479
480   function Get_Aspect_Id (Name : Name_Id) return Aspect_Id;
481   pragma Inline (Get_Aspect_Id);
482   --  Given a name Nam, returns the corresponding aspect id value. If the name
483   --  does not match any aspect, then No_Aspect is returned as the result.
484
485   ---------------------------------------------------
486   -- Handling of Aspect Specifications in the Tree --
487   ---------------------------------------------------
488
489   --  Several kinds of declaration node permit aspect specifications in Ada
490   --  2012 mode. If there was room in all the corresponding declaration nodes,
491   --  we could just have a field Aspect_Specifications pointing to a list of
492   --  nodes for the aspects (N_Aspect_Specification nodes). But there isn't
493   --  room, so we adopt a different approach.
494
495   --  The following subprograms provide access to a specialized interface
496   --  implemented internally with a hash table in the body, that provides
497   --  access to aspect specifications.
498
499   function Permits_Aspect_Specifications (N : Node_Id) return Boolean;
500   --  Returns True if the node N is a declaration node that permits aspect
501   --  specifications in the grammar. It is possible for other nodes to have
502   --  aspect specifications as a result of Rewrite or Replace calls.
503
504   function Aspect_Specifications (N : Node_Id) return List_Id;
505   --  Given a node N, returns the list of N_Aspect_Specification nodes that
506   --  are attached to this declaration node. If the node is in the class of
507   --  declaration nodes that permit aspect specifications, as defined by the
508   --  predicate above, and if their Has_Aspects flag is set to True, then this
509   --  will always be a non-empty list. If this flag is set to False, then
510   --  No_List is returned. Normally, the only nodes that have Has_Aspects set
511   --  True are the nodes for which Permits_Aspect_Specifications would return
512   --  True (i.e. the declaration nodes defined in the RM as permitting the
513   --  presence of Aspect_Specifications). However, it is possible for the
514   --  flag Has_Aspects to be set on other nodes as a result of Rewrite and
515   --  Replace calls, and this function may be used to retrieve the aspect
516   --  specifications for the original rewritten node in such cases.
517
518   procedure Set_Aspect_Specifications (N : Node_Id; L : List_Id);
519   --  The node N must be in the class of declaration nodes that permit aspect
520   --  specifications and the Has_Aspects flag must be False on entry. L must
521   --  be a non-empty list of N_Aspect_Specification nodes. This procedure sets
522   --  the Has_Aspects flag to True, and makes an entry that can be retrieved
523   --  by a subsequent Aspect_Specifications call. It is an error to call this
524   --  procedure with a node that does not permit aspect specifications, or a
525   --  node that has its Has_Aspects flag set True on entry, or with L being an
526   --  empty list or No_List.
527
528   function Find_Aspect (Ent : Entity_Id; A : Aspect_Id) return Node_Id;
529   --  Find value of a given aspect from aspect list of entity
530
531   procedure Move_Aspects (From : Node_Id; To : Node_Id);
532   --  Moves aspects from 'From' node to 'To' node. Has_Aspects (To) must be
533   --  False on entry. If Has_Aspects (From) is False, the call has no effect.
534   --  Otherwise the aspects are moved and on return Has_Aspects (To) is True,
535   --  and Has_Aspects (From) is False.
536
537   function Same_Aspect (A1 : Aspect_Id; A2 : Aspect_Id) return Boolean;
538   --  Returns True if A1 and A2 are (essentially) the same aspect. This is not
539   --  a simple equality test because e.g. Post and Postcondition are the same.
540   --  This is used for detecting duplicate aspects.
541
542   procedure Tree_Write;
543   --  Writes contents of Aspect_Specifications hash table to the tree file
544
545   procedure Tree_Read;
546   --  Reads contents of Aspect_Specifications hash table from the tree file
547
548end Aspects;
549