--| +=========================================================================+ --| | | --| | BUILD_REGION_VIEW_USING_REGION_SCAN | --| | | --| | Usage: build_region_view_using_region_scan | --| | | --| | This program is a simple driver for the Region_View package. It | --| | accepts two command line arguments, the name of an ASIS library and the | --| | name of a library unit contained therein, and it writes a | --| | textual representation of the declarative region tree for | --| | the library unit and all of its secondary units to standard output. | --| | | --| | This unit differs from Build_Region_View in that it uses GRC's | --| | Region_Scan subsystem, rather than an instantiation of the ASIS | --| | Traverse_Element generic, to traverse the element hierarchy of a | --| | comp unit. Both programs produce identical results. | --| | | --| | Chuck Hobin | --| | General Research Corporation | --| | | --| +=========================================================================+ with Asis; with Command; with Dump_Region_View; with Msg_Log; with Region_Scan; with Region_Support; with Region_View; with Region_View_Structures; with Text_Io; procedure Build_Region_View_Using_Region_Scan is --| Standard Asis renames... package Asis_Cu renames Asis.Compilation_Units; package Asis_D renames Asis.Declarations; package Asis_E renames Asis.Elements; package Asis_En renames Asis.Environment; package Asis_L renames Asis.Libraries; package Asis_Str renames Asis.Strings; package Cli renames Command; Argument_Count : Integer := Cli.Argc - 1; Arguments : constant Cli.String_Ptr_Array := Cli.Arguments; The_Library : Asis.Library; The_Unit : Asis.Compilation_Unit; Find_Error : exception; Usage_Error : exception; The_View : Region_View_Structures.Region_View; ------------------------------------------------------------------------------- procedure Pre_Operation (Region : in Region_Support.Region; Level : in Natural; Control : out Asis.Elements.Traverse_Control; View : in out Region_View_Structures.Region_View) is begin Region_View.Enter_Region (Region, View); Control := Asis.Elements.Continue; end Pre_Operation; procedure Post_Operation (Region : in Region_Support.Region; Level : in Natural; Control : out Asis.Elements.Traverse_Control; View : in out Region_View_Structures.Region_View) is begin Region_View.Leave_Region (Region, View); Control := Asis.Elements.Continue; end Post_Operation; -- Instantiate Region_Scan... package Visit_Regions is new Region_Scan (State_Information => Region_View_Structures.Region_View, Pre_Operation => Pre_Operation, Post_Operation => Post_Operation); ------------------------------------------------------------------------------- procedure Analyze_Unit (The_Unit : in Asis.Compilation_Unit) is Control : Asis.Elements.Traverse_Control := Asis.Elements.Continue; begin Msg_Log.Put_Msg (Msg_Log.Note, "Analyzing " & Asis_Cu.Name (The_Unit) & ' ' & Asis_Cu.Compilation_Unit_Kinds'Image (Asis_Cu.Kind (The_Unit))); Region_View.Start_Comp_Unit (The_Unit, The_View); Visit_Regions.Traverse_Unit (Unit => The_Unit, State => The_View, Expand_Instantiations => True, Include_Instance_Bodies => False, Trace_Scan => False); Region_View.Finish_Comp_Unit (The_Unit, The_View); end Analyze_Unit; procedure Analyze_Subunits_Of_Unit (The_Unit : in Asis.Compilation_Unit) is Subunits : constant Asis.Compilation_Unit_List := Asis_Cu.Subunits (The_Unit); begin for I in Subunits'Range loop case Asis_Cu.Kind (Subunits (I)) is when Asis_Cu.A_Subunit => Analyze_Unit (Subunits (I)); -- Recursively analyze any subunits of this subunit. Analyze_Subunits_Of_Unit (Subunits (I)); when others => -- Asis_Cu.Subunits can return non-existent units; we -- ignore them. null; end case; end loop; end Analyze_Subunits_Of_Unit; ------------------------------------------------------------------------------- begin -- main program Msg_Log.Set_Program ("rv"); if Argument_Count < 2 then raise Usage_Error; end if; Asis_En.Initialize; Asis_L.Associate (The_Library, Asis_Str.To_Asis_String (Arguments (1).all)); Asis_L.Open (The_Library); The_Unit := Asis_Cu.Library_Unit (Arguments (Arguments'Last).all, The_Library); if Asis_Cu.Is_Nil (The_Unit) then raise Find_Error; end if; Region_View.Initialize (The_View); Analyze_Unit (The_Unit); case Asis_D.Kind (Asis_Cu.Unit_Declaration (The_Unit)) is when Asis_D.A_Procedure_Body_Declaration | Asis_D.A_Function_Body_Declaration => -- This is the case where a subprogram body is a library -- unit; thus, there is no corresponding secondary unit. -- Analyze any subunits of the body. Analyze_Subunits_Of_Unit (The_Unit); when others => The_Unit := Asis_Cu.Secondary_Unit (Arguments (Arguments'Last).all, The_Library); if not Asis_Cu.Is_Nil (The_Unit) then Analyze_Unit (The_Unit); Analyze_Subunits_Of_Unit (The_Unit); end if; end case; Dump_Region_View.Dump (The_View, Text_Io.Standard_Output); Region_View.Free (The_View); Asis_L.Close (The_Library); Asis_L.Dissociate (The_Library); Asis_En.Finalize; exception when Usage_Error => Msg_Log.Put_Msg (Msg_Log.Error, "usage is ""build_region_view_using_region_scan """); when Find_Error => Msg_Log.Put_Msg (Msg_Log.Error, "unit not found"); when Asis.Asis_Inappropriate_Library => Msg_Log.Put_Msg (Msg_Log.Error, "exception Asis_Inappropriate_Library raised; status is " & Asis_En.Error_Kinds'Image (Asis_En.Status) & "; diagnosis follows"); Msg_Log.Put_Msg (Msg_Log.Error, Asis_Str.To_Standard_String (Asis_En.Diagnosis)); when Asis.Asis_Failed => Msg_Log.Put_Msg (Msg_Log.Error, "exception Asis_Failed raised; status is " & Asis_En.Error_Kinds'Image (Asis_En.Status) & "; diagnosis follows"); Msg_Log.Put_Msg (Msg_Log.Error, Asis_Str.To_Standard_String (Asis_En.Diagnosis)); end Build_Region_View_Using_Region_Scan;