------------------------------------------------------------------------------ -- -- -- GNAT COMPILER COMPONENTS -- -- -- -- G E N _ I L -- -- -- -- S p e c -- -- -- -- Copyright (C) 2020-2021, Free Software Foundation, Inc. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- -- for more details. You should have received a copy of the GNU General -- -- Public License distributed with GNAT; see file COPYING3. If not, go to -- -- http://www.gnu.org/licenses for a complete copy of the license. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------ pragma Warnings (Off); -- with clauses for children with Ada.Strings.Text_Output.Formatting; use Ada.Strings.Text_Output, Ada.Strings.Text_Output.Formatting; with Ada.Strings.Text_Output.Files; use Ada.Strings.Text_Output.Files; with Ada.Strings.Text_Output.Utils; use Ada.Strings.Text_Output.Utils; with Ada.Characters.Handling; use Ada.Characters.Handling; pragma Warnings (On); package Gen_IL is -- generate intermediate language -- This package and children generates the main intermediate language used -- by the compiler, which is a decorated syntax tree. -- Here's what the hand-written and generated code looks like. The make -- files run the gen_il-main.adb program to generate the generated files -- listed below, before building the compiler proper. -- -- atree.ads, atree.adb: Rewrite according to low-level -- design notes. Remove package Unchecked_Access. -- Low-level getters and setters go in Atree_Private_Part. -- These are called by the high-level automatically-generated -- getters and setters in Sinfo.Nodes and Einfo.Entities. -- Also used by Atree.Traverse_Func, and by Treepr. -- -- sinfo.ads, einfo.ads: Remove getters and setters. -- Remove Write_... routines used by old Treepr. -- Keep commments describing the semantics of all the nodes, -- entities, and fields. These comments are wrong, but only -- a little, and I'm not going to try to fix them. At some -- point, we could remove the comments giving field offsets -- (e.g. "(Flag5-Sem)"), but for now, just note that that's -- obsolete info. -- -- einfo.adb, sinfo.adb: Delete. -- -- gen_il.ads, gen_il.adb: Mostly empty root package for the -- "generate intermediate language" program, which generates -- all the files mentioned here. -- The main program is gen_il-main.adb. -- -- sinfo-utils.ads, sinfo-utils.adb, einfo-utils.ads, einfo-utils.adb: -- Move all handwritten code currently in sinfo&einfo to here, -- if it refers to stuff in sinfo-nodes.ads, einfo-entities.ads -- This includes the "synthesized attributes". -- -- gen_il-types.ads: Enumeration type containing one literal for -- each type of interest. That includes all the Node_Kinds and -- Entity_Kinds, plus the subtypes that include multiple -- Node_Kinds and Entity_Kinds (all from the old sinfo/einfo), -- plus all field types (Uint, Ureal, Name_Id, etc). -- -- gen_il-fields.ads: Enumeration of all the fields of all node -- and entity types. -- -- gen_il-gen.ads, gen_il-gen.adb: Implementation of the "compiler" -- for the "little language". -- -- gen_il-gen-gen_nodes.adb: Procedure to generate Sinfo.Nodes -- (by calling procedures in Gen_IL). -- This defines what abstract and concrete node types exist, -- and what fields they have. This and the next one are the -- hard part. I'm planning to generate this semi-automatically. -- But once it's working, we will maintain it by hand. -- -- gen_il-gen-gen_entities.adb: Procedure to generate einfo-entities.*. -- This defines what abstract and concrete entity types exist, -- and what fields they have. -- -- seinfo.ads: Generated by gen_il-main.adb. Contains declarations shared -- by Sinfo.Nodes and Einfo.Entities. -- -- sinfo-nodes.ads, sinfo-nodes.adb: Generated by gen_il-main.adb -- (really by Gen_Nodes). Contains: -- -- - Information in comments, such as what fields exist in what -- node kinds, which might be hard to compute by hand for -- inherited fields. -- -- - Type Node_Kind. Same as the old Sinfo, but now generated. -- One enumeral for each concrete node type in Gen_Nodes. -- -- - One subtype of Node_Kind for each abstract type in Gen_Nodes. -- Same as the old Sinfo, but now generated. E.g.: -- -- subtype N_Representation_Clause is Node_Kind range -- N_At_Clause .. N_Attribute_Definition_Clause; -- -- - One subtype of Node_Id for each abstract and concrete type, -- with a predicate requiring the right Nkind. E.g.: -- -- subtype N_Representation_Clause_Id is -- Node_Id with Predicate => -- Nkind (N_Representation_Clause_Id) in N_Representation_Clause; -- -- - Getters and setters for every node field. If the field is defined -- for all node kinds in one of the above Node_Id subtypes and no -- others, then we use that as the parameter subtype: -- -- function Abortable_Part -- (N : N_Asynchronous_Select_Id) return Node_Id with Inline; -- -- Otherwise, we use a precondition: -- -- function Abstract_Present -- (N : Node_Id) return Flag with Inline, Pre => -- N in N_Private_Extension_Declaration_Id -- | N_Private_Type_Declaration_Id -- | N_Derived_Type_Definition_Id -- ... -- -- - Type Node_Field: Enumeration of all node fields. Used by Treepr, -- and in tables below. -- -- - Table of syntactic fields. For each node kind, we have a sequence -- of fields. A field is included if it exists in that node kind, -- and it is syntactic, and it is of type Node_Id or List_Id. -- Used by Traverse_Func. -- -- - Table of node sizes, indexed by Node_Kind. Used by Atree when -- allocating and copying nodes. -- -- - Table mapping Node_Kinds to the sequence of fields that exist in -- that Node_Kind. Used by Treepr. -- -- - Node_Field_Descriptors: Table mapping fields to type and offset. -- Used by Treepr to know where to find each field, and what its -- type is, for printing. -- -- - The body contains instantiations of the low-level getters and -- setters declared in Atree, e.g.: -- -- function Get_List_Id is new Get_32_Bit_Field (List_Id) -- with Inline; -- procedure Set_List_Id is new Set_32_Bit_Field (List_Id) -- with Inline; -- -- and bodies of the high-level getters and setters, e.g.: -- -- function Actions -- (N : Node_Id) return List_Id is -- begin -- return Get_List_Id (N, 4); -- end Actions; -- -- einfo-entities.ads, einfo-entities.adb: Generated by gen_il-main.adb -- (really by Gen_Entities). Contains the same sort of stuff as -- Sinfo.Nodes, except no table of syntactic fields. -- -- nmake.ads, nmake.adb: Same contents as the old version, but generated by -- Gen_IL instead of xnmake. -- -- treepr.adb: Rewrite to use the tables in Nodes and Entities. -- -- treeprs.ads: Delete. (Was automatically generated.) -- Treepr no longer needs this; it can use 'Image on the -- enumeration types in Nodes and Entities. -- -- csinfo.adb, ceinfo.adb, xsinfo.adb, xeinfo.adb, xnmake.adb, -- xtreeprs.adb, nmake.adt, treeprs.adt: Delete. -- C++ code: -- -- atree.h (hand-written code): -- -- This code should be entirely deleted, and replaced with low-level -- getters analogous to the generic getters in Atree. One getter for each -- field size (currently 1, 2, 4, 8, and 32 bits. No need for setters. -- -- ---------------- -- -- fe.h (hand-written code): -- -- There are comments in various places that say that gigi -- does not modify the tree. However, I discovered some stuff -- in fe.h that modifies the tree: -- -- #define End_Location sinfo__end_location -- #define Set_Has_No_Elaboration_Code sinfo__set_has_no_elaboration_code -- #define Set_Present_Expr sinfo__set_present_expr -- -- #define Set_Alignment einfo__set_alignment -- #define Set_Component_Bit_Offset einfo__set_component_bit_offset -- #define Set_Component_Size einfo__set_component_size -- #define Set_Esize einfo__set_esize -- #define Set_Mechanism einfo__set_mechanism -- #define Set_Normalized_First_Bit einfo__set_normalized_first_bit -- #define Set_Normalized_Position einfo__set_normalized_position -- #define Set_RM_Size einfo__set_rm_size -- -- #define Is_Entity_Name einfo__utils__is_entity_name -- #define Get_Attribute_Definition_Clause \ -- einfo__utils__get_attribute_definition_clause -- -- These setters and some getters need to be changed because the -- setters and getters are moving from Sinfo to Sinfo.Nodes, -- and from Einfo to Einfo.Entities. The last two will be in Einfo.Utils. -- -- ---------------- -- -- sinfo.h (tool-generated code): -- -- A bunch of #defines for the node kinds. These can remain the same. -- -- A bunch of calls to SUBTYPE (macro defined in gcc-interface/ada.h). -- These can remain the same. -- -- A bunch of getters (no setters), like: -- -- INLINE Boolean Abort_Present (Node_Id N) -- { return Flag15 (N); } -- -- Change this to call the new low-level getters. -- Something like: -- -- INLINE Boolean Abort_Present (Node_Id N) -- { return Get_Flag (N, 15); } -- -- Generate the low-level getters in the same file, before the above -- high-level getters, one for each field type: -- -- Flag -- Node_Id -- List_Id -- Elist_Id -- Name_Id -- String_Id -- Uint -- Ureal -- Node_Kind -- Entity_Kind -- Source_Ptr -- Small_Paren_Count_Type -- Union_Id -- Convention_Id -- Component_Alignment_Kind -- Float_Rep_Kind -- Mechanism_Type -- -- These are in types.h. -- -- ---------------- -- -- einfo.h (tool-generated code): -- -- Can mostly remain the same, except: -- -- Call low-level getters, as for sinfo.h. -- -- The getters that are NOT inlined will be moved from -- Einfo to Einfo.Entities. -- I don't understand why some are not inlined (e.g Float_Rep?). -- Most are not inlined because they are synthesized. -- Maybe that should be hand written, and moved to a different file. -- Or maybe Gen_IL should know about these fields. -- -- We have code like: -- INLINE B Is_Subprogram_Or_Generic_Subprogram (E Id) -- { return IN (Ekind (Id), Subprogram_Kind) || IN (Ekind (Id), -- Generic_Subprogram_Kind); } -- That should be hand written, and moved to atree.h or fe.h. -- Is_Record_Type requires special treatment, because Record_Kind is -- a nonhierarchical type. -- -- Looks like the getters are in alphabetical order. -- Except for the Is_..._Type ones. -- Misc declarations used throughout: type Root_Int is new Integer; function Image (X : Root_Int) return String; -- Without the extra blank. You can derive from Root_Int or the subtypes -- below, and inherit a convenient Image function that leaves out that -- blank. subtype Root_Nat is Root_Int range 0 .. Root_Int'Last; subtype Root_Pos is Root_Int range 1 .. Root_Int'Last; function Capitalize (S : String) return String; procedure Capitalize (S : in out String); -- Turns an identifier into Mixed_Case type String_Ptr is access all String; end Gen_IL;