summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-15 14:33:46 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2011-12-15 14:33:46 +0000
commit8569650836011e7bfe45b3f76dd9673725785c88 (patch)
tree20975a66444ac1e00f9193125dafa7c1e23e8fe7
parentbace6acf1555d1d335e126a726790c388e85bc85 (diff)
downloadppe42-gcc-8569650836011e7bfe45b3f76dd9673725785c88.tar.gz
ppe42-gcc-8569650836011e7bfe45b3f76dd9673725785c88.zip
2011-12-15 Vincent Pucci <pucci@adacore.com>
* aspects.adb, aspects.ads Aspect_Dimension and Aspect_Dimension_System added * exp_ch6.adb (Expand_Call): Expand_Put_Call_With_Dimension_String case added * gcc-interface/Make-lang.in: s-llflex, sem_dim added. * impunit.adb :s-diflio and s-diinio defined as GNAT Defined Additions to System. * Makefile.rtl: s-diflio, s-diinio and s-llflex added * par-prag.adb, sem_prag.adb: Pragma_Dimension removed * rtsfind.ads: Expon_LLF added * sem_aggr.adb (Resolve_Aggregate): handles aggregate for Aspect_Dimension case * sem_attr.adb (Resolve_Attribute): analyze dimension for attribute * sem_ch10.adb (Analyze_With_Clause): Avoid the warning messages due to the use of a GNAT library for Dimension packages * sem_ch13.adb (Analyze_Aspect_Specifications): Aspect_Dimension and Aspect_Dimension_System cases added (Check_Aspect_At_Freeze_Point): Aspect_Dimension and Aspect_Dimension_System cases added * sem_ch2.adb (Analyze_Identifier): analyze dimension for identifier * sem_ch3.adb (Analyze_Component_Declaration): analyze dimension for component declaration (Analyze_Object_Declaration): analyze dimension for object declaration (Analyze_Subtype_Declaration): analyze dimension for subtype declaration * sem_ch4.adb (Operator_Check): checks exponent is a rational for dimensioned operand for a N_Op_Expon * sem_ch5.adb (Analyze_Assignment): analyze dimension for assignment (Analyze_Statements): removal of dimensions in all statements * sem_ch6.adb (Analyze_Return_Statement): analyze dimension for return statement * sem_ch8.adb (Analyze_Object_Renaming): analyze dimension for object renaming * sem_dim.adb, sem_dim.ads (Analyze_Aspect_Dimension): analyze the expression for aspect dimension and store the values in a Htable. (Analyze_Aspect_Dimension_System): analyze the expression for aspect dimension system and store the new system in a Table. (Analyze_Dimension): propagates dimension (Expand_Put_Call_With_Dimension_String): add the dimension string as a suffix of the numeric value in the output (Has_Dimension): return True if the node has a dimension (Remove_Dimension_In_Declaration): removal of dimension in the expression of the declaration. (Remove_Dimension_In_Statement): removal of dimension in statement * sem_res.adb (Resolve): analyze dimension if the node has already been analyzed. (Resolve_Arithmetic_Op): analyze dimension for arithmetic op. (Resolve_Call): analyze dimension for function call. (Resolve_Comparison_Op): analyze dimension for comparison op. (Resolve_Equality_Op): analyze dimension for equality op. (Resolve_Indexed_Component): analyze dimension for indexed component. (Resolve_Op_Expon): analyze dimension for op expon. (Resolve_Selected_Component): analyze dimension for selected component. (Resolve_Slice): analyze dimension for slice. (Resolve_Unary_Op): analyze dimension for unary op (Resolve_Type_Conversion): analyze dimension for type conversion (Resolve_Unchecked_Type_Conversion): analyze dimension for unchecked type conversion * snames.ads-tmpl Name_Dimension, Name_Dimension_System, Name_Dim_Float_IO, Name_Dim_Integer_IO, Name_Generic_Elementary_Functions, Name_Sqrt added. Pragma_Dimension removed * s-diflio.adb, s-diflio.ads New GNAT library generic package for dimensioned float type IO * s-diinio.adb, s-diinio.ads New GNAT library generic package for dimensioned integer type IO * s-llflex.ads (Expon_LLF): exponentiation routine for long long floats operand and exponent 2011-12-15 Robert Dewar <dewar@adacore.com> * sem_aggr.adb: Minor comment addition. 2011-12-15 Bob Duff <duff@adacore.com> * s-tasren.adb (Task_Count): Do not call Yield; E'Count is not a task dispatching point. * s-taprop-mingw.adb (Yield): Do not yield if Do_Yield is False. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182368 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ada/ChangeLog87
-rw-r--r--gcc/ada/Makefile.rtl3
-rwxr-xr-xgcc/ada/aspects.adb2
-rwxr-xr-xgcc/ada/aspects.ads6
-rw-r--r--gcc/ada/exp_ch6.adb17
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in5
-rw-r--r--gcc/ada/impunit.adb2
-rw-r--r--gcc/ada/par-prag.adb1
-rw-r--r--gcc/ada/rtsfind.ads5
-rw-r--r--gcc/ada/s-diflio.adb77
-rw-r--r--gcc/ada/s-diflio.ads77
-rw-r--r--gcc/ada/s-diinio.adb77
-rw-r--r--gcc/ada/s-diinio.ads73
-rw-r--r--gcc/ada/s-llflex.ads42
-rw-r--r--gcc/ada/s-taprop-mingw.adb7
-rw-r--r--gcc/ada/s-tasren.adb4
-rw-r--r--gcc/ada/sem_aggr.adb10
-rw-r--r--gcc/ada/sem_attr.adb2
-rw-r--r--gcc/ada/sem_ch13.adb19
-rw-r--r--gcc/ada/sem_ch2.adb3
-rw-r--r--gcc/ada/sem_ch3.adb9
-rw-r--r--gcc/ada/sem_ch4.adb13
-rw-r--r--gcc/ada/sem_ch5.adb6
-rw-r--r--gcc/ada/sem_ch6.adb3
-rw-r--r--gcc/ada/sem_ch8.adb2
-rw-r--r--gcc/ada/sem_dim.adb2779
-rw-r--r--gcc/ada/sem_dim.ads150
-rw-r--r--gcc/ada/sem_prag.adb19
-rw-r--r--gcc/ada/sem_res.adb36
-rw-r--r--gcc/ada/snames.ads-tmpl12
30 files changed, 3513 insertions, 35 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index d36fdcd012b..ffc91dee409 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,90 @@
+2011-12-15 Vincent Pucci <pucci@adacore.com>
+
+ * aspects.adb, aspects.ads Aspect_Dimension and
+ Aspect_Dimension_System added
+ * exp_ch6.adb (Expand_Call): Expand_Put_Call_With_Dimension_String
+ case added
+ * gcc-interface/Make-lang.in: s-llflex, sem_dim added.
+ * impunit.adb :s-diflio and s-diinio defined as GNAT Defined
+ Additions to System.
+ * Makefile.rtl: s-diflio, s-diinio and s-llflex added
+ * par-prag.adb, sem_prag.adb: Pragma_Dimension removed
+ * rtsfind.ads: Expon_LLF added
+ * sem_aggr.adb (Resolve_Aggregate): handles aggregate for
+ Aspect_Dimension case
+ * sem_attr.adb (Resolve_Attribute): analyze dimension for
+ attribute
+ * sem_ch10.adb (Analyze_With_Clause): Avoid the warning messages
+ due to the use of a GNAT library for Dimension packages
+ * sem_ch13.adb (Analyze_Aspect_Specifications):
+ Aspect_Dimension and Aspect_Dimension_System cases added
+ (Check_Aspect_At_Freeze_Point): Aspect_Dimension and
+ Aspect_Dimension_System cases added
+ * sem_ch2.adb (Analyze_Identifier): analyze dimension for
+ identifier
+ * sem_ch3.adb (Analyze_Component_Declaration): analyze dimension
+ for component declaration (Analyze_Object_Declaration): analyze
+ dimension for object declaration (Analyze_Subtype_Declaration):
+ analyze dimension for subtype declaration
+ * sem_ch4.adb (Operator_Check): checks exponent is a rational
+ for dimensioned operand for a N_Op_Expon
+ * sem_ch5.adb (Analyze_Assignment): analyze dimension for
+ assignment (Analyze_Statements): removal of dimensions in all
+ statements
+ * sem_ch6.adb (Analyze_Return_Statement): analyze dimension for
+ return statement
+ * sem_ch8.adb (Analyze_Object_Renaming): analyze dimension for
+ object renaming
+ * sem_dim.adb, sem_dim.ads (Analyze_Aspect_Dimension):
+ analyze the expression for aspect dimension and store the
+ values in a Htable.
+ (Analyze_Aspect_Dimension_System): analyze
+ the expression for aspect dimension system and store the new
+ system in a Table.
+ (Analyze_Dimension): propagates dimension
+ (Expand_Put_Call_With_Dimension_String): add the dimension
+ string as a suffix of the numeric value in the output
+ (Has_Dimension): return True if the node has a dimension
+ (Remove_Dimension_In_Declaration): removal of dimension in the
+ expression of the declaration.
+ (Remove_Dimension_In_Statement): removal of dimension in statement
+ * sem_res.adb (Resolve): analyze dimension if the node
+ has already been analyzed.
+ (Resolve_Arithmetic_Op): analyze
+ dimension for arithmetic op.
+ (Resolve_Call): analyze dimension for function call.
+ (Resolve_Comparison_Op): analyze dimension for comparison op.
+ (Resolve_Equality_Op): analyze dimension for equality op.
+ (Resolve_Indexed_Component): analyze dimension for indexed component.
+ (Resolve_Op_Expon): analyze dimension for op expon.
+ (Resolve_Selected_Component): analyze dimension
+ for selected component.
+ (Resolve_Slice): analyze dimension for slice.
+ (Resolve_Unary_Op): analyze dimension for unary op
+ (Resolve_Type_Conversion): analyze dimension for type conversion
+ (Resolve_Unchecked_Type_Conversion): analyze dimension for
+ unchecked type conversion
+ * snames.ads-tmpl Name_Dimension, Name_Dimension_System,
+ Name_Dim_Float_IO, Name_Dim_Integer_IO,
+ Name_Generic_Elementary_Functions, Name_Sqrt added.
+ Pragma_Dimension removed
+ * s-diflio.adb, s-diflio.ads New GNAT library generic package
+ for dimensioned float type IO
+ * s-diinio.adb, s-diinio.ads New GNAT library generic package
+ for dimensioned integer type IO
+ * s-llflex.ads (Expon_LLF): exponentiation routine for long long
+ floats operand and exponent
+
+2011-12-15 Robert Dewar <dewar@adacore.com>
+
+ * sem_aggr.adb: Minor comment addition.
+
+2011-12-15 Bob Duff <duff@adacore.com>
+
+ * s-tasren.adb (Task_Count): Do not call Yield; E'Count is not a
+ task dispatching point.
+ * s-taprop-mingw.adb (Yield): Do not yield if Do_Yield is False.
+
2011-12-15 Robert Dewar <dewar@adacore.com>
* sigtramp-ppcvxw.c, sigtramp.h: Fix header.
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 5c3e307f713..e04a5ff87b4 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -504,6 +504,8 @@ GNATRTL_NONTASKING_OBJS= \
s-crc32$(objext) \
s-crtl$(objext) \
s-crtrun$(objext) \
+ s-diflio$(objext) \
+ s-diinio$(objext) \
s-direio$(objext) \
s-dsaser$(objext) \
s-excdeb$(objext) \
@@ -554,6 +556,7 @@ GNATRTL_NONTASKING_OBJS= \
s-imgwch$(objext) \
s-imgwiu$(objext) \
s-io$(objext) \
+ s-llflex$(objext) \
s-maccod$(objext) \
s-mantis$(objext) \
s-mastop$(objext) \
diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb
index 7cc218e1d98..8dc9a12bccb 100755
--- a/gcc/ada/aspects.adb
+++ b/gcc/ada/aspects.adb
@@ -240,6 +240,8 @@ package body Aspects is
Aspect_Default_Component_Value => Aspect_Default_Component_Value,
Aspect_Default_Iterator => Aspect_Default_Iterator,
Aspect_Default_Value => Aspect_Default_Value,
+ Aspect_Dimension => Aspect_Dimension,
+ Aspect_Dimension_System => Aspect_Dimension_System,
Aspect_Discard_Names => Aspect_Discard_Names,
Aspect_Dispatching_Domain => Aspect_Dispatching_Domain,
Aspect_Dynamic_Predicate => Aspect_Predicate,
diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
index c1dbe72cd3f..b701fe529df 100755
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -54,6 +54,8 @@ package Aspects is
Aspect_Default_Component_Value,
Aspect_Default_Iterator,
Aspect_Default_Value,
+ Aspect_Dimension,
+ Aspect_Dimension_System,
Aspect_Dispatching_Domain,
Aspect_Dynamic_Predicate,
Aspect_External_Tag,
@@ -232,6 +234,8 @@ package Aspects is
Aspect_Default_Component_Value => Expression,
Aspect_Default_Iterator => Name,
Aspect_Default_Value => Expression,
+ Aspect_Dimension => Expression,
+ Aspect_Dimension_System => Expression,
Aspect_Dispatching_Domain => Expression,
Aspect_Dynamic_Predicate => Expression,
Aspect_External_Tag => Expression,
@@ -293,6 +297,8 @@ package Aspects is
Aspect_Default_Iterator => Name_Default_Iterator,
Aspect_Default_Value => Name_Default_Value,
Aspect_Default_Component_Value => Name_Default_Component_Value,
+ Aspect_Dimension => Name_Dimension,
+ Aspect_Dimension_System => Name_Dimension_System,
Aspect_Discard_Names => Name_Discard_Names,
Aspect_Dispatching_Domain => Name_Dispatching_Domain,
Aspect_Dynamic_Predicate => Name_Dynamic_Predicate,
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 4c9460438d3..7a55ad8b14d 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -60,9 +60,10 @@ with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Ch12; use Sem_Ch12;
with Sem_Ch13; use Sem_Ch13;
-with Sem_Eval; use Sem_Eval;
+with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
+with Sem_Eval; use Sem_Eval;
with Sem_Mech; use Sem_Mech;
with Sem_Res; use Sem_Res;
with Sem_SCIL; use Sem_SCIL;
@@ -2103,6 +2104,20 @@ package body Exp_Ch6 is
-- Start of processing for Expand_Call
begin
+ -- Expand the procedure call if the first actual has a dimension and if
+ -- the procedure is Put (Ada 2012).
+
+ if Ada_Version >= Ada_2012
+ and then Nkind (Call_Node) = N_Procedure_Call_Statement
+ and then Present (Parameter_Associations (Call_Node))
+ then
+ Expand_Put_Call_With_Dimension_String (Call_Node);
+ end if;
+
+ -- Remove the dimensions of every parameters in call
+
+ Remove_Dimension_In_Call (N);
+
-- Ignore if previous error
if Nkind (Call_Node) in N_Has_Etype
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index 35cddf75142..a79c0541c2c 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -304,6 +304,7 @@ GNAT_ADA_OBJS = \
ada/s-htable.o \
ada/s-imenne.o \
ada/s-imgenu.o \
+ ada/s-llflex.o \
ada/s-mastop.o \
ada/s-memory.o \
ada/s-os_lib.o \
@@ -353,6 +354,7 @@ GNAT_ADA_OBJS = \
ada/sem_ch7.o \
ada/sem_ch8.o \
ada/sem_ch9.o \
+ ada/sem_dim.o \
ada/sem_disp.o \
ada/sem_dist.o \
ada/sem_elab.o \
@@ -4307,6 +4309,9 @@ ada/sem_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \
ada/warnsw.ads ada/widechar.ads
+ada/sem_dim.o : ada/sem_util.ads ada/sem_util.adb ada/nmake.ads \
+ ada/nmake.adb
+
ada/sem_disp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/checks.ads ada/csets.ads ada/debug.ads \
diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb
index 496f6ce50d4..49a44adf723 100644
--- a/gcc/ada/impunit.adb
+++ b/gcc/ada/impunit.adb
@@ -366,6 +366,8 @@ package body Impunit is
("s-addima", F), -- System.Address_Image
("s-assert", F), -- System.Assertions
+ ("s-diflio", F), -- System.Dim_Float_IO
+ ("s-diinio", F), -- System.Dim_Integer_IO
("s-memory", F), -- System.Memory
("s-parint", F), -- System.Partition_Interface
("s-pooglo", F), -- System.Pool_Global
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index 1a126759f6b..b3d029f3e40 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -1126,7 +1126,6 @@ begin
Pragma_Debug_Policy |
Pragma_Detect_Blocking |
Pragma_Default_Storage_Pool |
- Pragma_Dimension |
Pragma_Disable_Atomic_Synchronization |
Pragma_Discard_Names |
Pragma_Dispatching_Domain |
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 8cd7771628c..64d10566067 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -262,6 +262,7 @@ package Rtsfind is
System_Img_Uns,
System_Img_WChar,
System_Interrupts,
+ System_Long_Long_Float_Expon,
System_Machine_Code,
System_Mantissa,
System_Memcop,
@@ -866,6 +867,8 @@ package Rtsfind is
RE_Static_Interrupt_Protection, -- System.Interrupts
RE_System_Interrupt_Id, -- System.Interrupts
+ RE_Expon_LLF, -- System.Long_Long_Float_Expon
+
RE_Asm_Insn, -- System.Machine_Code
RE_Asm_Input_Operand, -- System.Machine_Code
RE_Asm_Output_Operand, -- System.Machine_Code
@@ -2066,6 +2069,8 @@ package Rtsfind is
RE_Static_Interrupt_Protection => System_Interrupts,
RE_System_Interrupt_Id => System_Interrupts,
+ RE_Expon_LLF => System_Long_Long_Float_Expon,
+
RE_Asm_Insn => System_Machine_Code,
RE_Asm_Input_Operand => System_Machine_Code,
RE_Asm_Output_Operand => System_Machine_Code,
diff --git a/gcc/ada/s-diflio.adb b/gcc/ada/s-diflio.adb
new file mode 100644
index 00000000000..7a14b8f1f94
--- /dev/null
+++ b/gcc/ada/s-diflio.adb
@@ -0,0 +1,77 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . D I M _ F L O A T _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- --
+-- GNARL 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. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package body System.Dim_Float_IO is
+
+ package Num_Dim_Float_IO is new Ada.Text_IO.Float_IO (Num_Dim_Float);
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num_Dim_Float;
+ Unit : String := "";
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Num_Dim_Float_IO.Put (File, Item, Fore, Aft, Exp);
+ Ada.Text_IO.Put (File, Unit);
+ end Put;
+
+ procedure Put
+ (Item : Num_Dim_Float;
+ Unit : String := "";
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Num_Dim_Float_IO.Put (Item, Fore, Aft, Exp);
+ Ada.Text_IO.Put (Unit);
+ end Put;
+
+ procedure Put
+ (To : out String;
+ Item : Num_Dim_Float;
+ Unit : String := "";
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp)
+ is
+ begin
+ Num_Dim_Float_IO.Put (To, Item, Aft, Exp);
+ To := To & Unit;
+ end Put;
+
+end System.Dim_Float_IO;
diff --git a/gcc/ada/s-diflio.ads b/gcc/ada/s-diflio.ads
new file mode 100644
index 00000000000..e70dc499633
--- /dev/null
+++ b/gcc/ada/s-diflio.ads
@@ -0,0 +1,77 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . D I M _ F L O A T _ I O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- --
+-- GNARL 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. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Note that this package should only be instantiated with a float dimensioned
+-- type.
+
+-- This package is a generic package that provides IO facilities for float
+-- dimensioned types.
+
+-- Note that there is a default string parameter in every Put routine
+-- rewritten at compile time to output the corresponding dimensions as a
+-- suffix of the numeric value.
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+generic
+ type Num_Dim_Float is digits <>;
+
+package System.Dim_Float_IO is
+
+ Default_Fore : Field := 2;
+ Default_Aft : Field := Num_Dim_Float'Digits - 1;
+ Default_Exp : Field := 3;
+
+ procedure Put
+ (File : File_Type;
+ Item : Num_Dim_Float;
+ Unit : String := "";
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp);
+
+ procedure Put
+ (Item : Num_Dim_Float;
+ Unit : String := "";
+ Fore : Field := Default_Fore;
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp);
+
+ procedure Put
+ (To : out String;
+ Item : Num_Dim_Float;
+ Unit : String := "";
+ Aft : Field := Default_Aft;
+ Exp : Field := Default_Exp);
+
+ pragma Inline (Put);
+
+end System.Dim_Float_IO;
diff --git a/gcc/ada/s-diinio.adb b/gcc/ada/s-diinio.adb
new file mode 100644
index 00000000000..b530942aeb6
--- /dev/null
+++ b/gcc/ada/s-diinio.adb
@@ -0,0 +1,77 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . D I M _ I N T E G E R _ I O --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- --
+-- GNARL 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. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package body System.Dim_Integer_IO is
+
+ package Num_Dim_Integer_IO is new Ada.Text_IO.Integer_IO (Num_Dim_Integer);
+
+ ---------
+ -- Put --
+ ---------
+
+ procedure Put
+ (File : File_Type;
+ Item : Num_Dim_Integer;
+ Unit : String := "";
+ Width : Field := Default_Width;
+ Base : Number_Base := Default_Base)
+
+ is
+ begin
+ Num_Dim_Integer_IO.Put (File, Item, Width, Base);
+ Ada.Text_IO.Put (File, Unit);
+ end Put;
+
+ procedure Put
+ (Item : Num_Dim_Integer;
+ Unit : String := "";
+ Width : Field := Default_Width;
+ Base : Number_Base := Default_Base)
+
+ is
+ begin
+ Num_Dim_Integer_IO.Put (Item, Width, Base);
+ Ada.Text_IO.Put (Unit);
+ end Put;
+
+ procedure Put
+ (To : out String;
+ Item : Num_Dim_Integer;
+ Unit : String := "";
+ Base : Number_Base := Default_Base)
+
+ is
+ begin
+ Num_Dim_Integer_IO.Put (To, Item, Base);
+ To := To & Unit;
+ end Put;
+
+end System.Dim_Integer_IO;
diff --git a/gcc/ada/s-diinio.ads b/gcc/ada/s-diinio.ads
new file mode 100644
index 00000000000..2325cea36bb
--- /dev/null
+++ b/gcc/ada/s-diinio.ads
@@ -0,0 +1,73 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . D I M _ I N T E G E R _ I O --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- --
+-- GNARL 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. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Note that this package should only be instantiated with an integer
+-- dimensioned type
+
+-- This package is a generic package that provides IO facilities for integer
+-- dimensioned types.
+
+-- Note that there is a default string parameter in every Put routine
+-- rewritten at compile time to output the corresponding dimensions as a
+-- suffix of the numeric value.
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+generic
+ type Num_Dim_Integer is range <>;
+
+package System.Dim_Integer_IO is
+
+ Default_Width : Field := Num_Dim_Integer'Width;
+ Default_Base : Number_Base := 10;
+
+ procedure Put
+ (File : File_Type;
+ Item : Num_Dim_Integer;
+ Unit : String := "";
+ Width : Field := Default_Width;
+ Base : Number_Base := Default_Base);
+
+ procedure Put
+ (Item : Num_Dim_Integer;
+ Unit : String := "";
+ Width : Field := Default_Width;
+ Base : Number_Base := Default_Base);
+
+ procedure Put
+ (To : out String;
+ Item : Num_Dim_Integer;
+ Unit : String := "";
+ Base : Number_Base := Default_Base);
+
+ pragma Inline (Put);
+
+end System.Dim_Integer_IO;
diff --git a/gcc/ada/s-llflex.ads b/gcc/ada/s-llflex.ads
new file mode 100644
index 00000000000..2ff301f0488
--- /dev/null
+++ b/gcc/ada/s-llflex.ads
@@ -0,0 +1,42 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . L O N G _ L O N G _ F L O A T _ E X P O N --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- --
+-- GNARL 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. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package contains an instantiation of the functions "**" and Sqrt
+-- between two long long floats.
+
+with Ada.Numerics.Long_Long_Elementary_Functions;
+
+package System.Long_Long_Float_Expon is
+
+ function Expon_LLF (Left, Right : Long_Long_Float) return Long_Long_Float
+ renames Ada.Numerics.Long_Long_Elementary_Functions."**";
+
+end System.Long_Long_Float_Expon;
diff --git a/gcc/ada/s-taprop-mingw.adb b/gcc/ada/s-taprop-mingw.adb
index 0a1a3c13003..0a976a4e8b1 100644
--- a/gcc/ada/s-taprop-mingw.adb
+++ b/gcc/ada/s-taprop-mingw.adb
@@ -710,10 +710,9 @@ package body System.Task_Primitives.Operations is
-- Moreover, CXD8002 appears to pass on Windows (although we do not
-- guarantee full Annex D compliance on Windows in any case).
- -- What is not clear is why we now call SwitchToThread in the False
- -- case. Other versions don't do that, is it necessary???
-
- SwitchToThread;
+ if Do_Yield then
+ SwitchToThread;
+ end if;
end Yield;
------------------
diff --git a/gcc/ada/s-tasren.adb b/gcc/ada/s-tasren.adb
index e2541a106fd..04da4919c3f 100644
--- a/gcc/ada/s-tasren.adb
+++ b/gcc/ada/s-tasren.adb
@@ -1069,10 +1069,6 @@ package body System.Tasking.Rendezvous is
Initialization.Undefer_Abort (Self_Id);
- -- Call Yield to let other tasks get a chance to run as this is a
- -- potential dispatching point.
-
- Yield (Do_Yield => False);
return Return_Count;
end Task_Count;
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index ea75d48e69d..e70333cc7e6 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -1691,6 +1691,11 @@ package body Sem_Aggr is
end if;
end if;
+ -- If an aggregate component has a type with predicates, an explicit
+ -- predicate check must be applied, as for an assignment statement,
+ -- because the aggegate might not be expanded into individual
+ -- component assignments.
+
if Present (Predicate_Function (Component_Typ)) then
Apply_Predicate_Check (Expr, Component_Typ);
end if;
@@ -3297,6 +3302,11 @@ package body Sem_Aggr is
Aggregate_Constraint_Checks (Expr, Expr_Type);
end if;
+ -- If an aggregate component has a type with predicates, an explicit
+ -- predicate check must be applied, as for an assignment statement,
+ -- because the aggegate might not be expanded into individual
+ -- component assignments.
+
if Present (Predicate_Function (Expr_Type)) then
Apply_Predicate_Check (Expr, Expr_Type);
end if;
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index f72bebdba7b..6e1493afbba 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -52,6 +52,7 @@ with Sem_Cat; use Sem_Cat;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Ch10; use Sem_Ch10;
+with Sem_Dim; use Sem_Dim;
with Sem_Dist; use Sem_Dist;
with Sem_Elim; use Sem_Elim;
with Sem_Eval; use Sem_Eval;
@@ -9165,6 +9166,7 @@ package body Sem_Attr is
-- Finally perform static evaluation on the attribute reference
+ Analyze_Dimension (N);
Eval_Attribute (N);
end Resolve_Attribute;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index bd077364c2d..31bbd130903 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -46,6 +46,7 @@ with Sem_Aux; use Sem_Aux;
with Sem_Ch3; use Sem_Ch3;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Dim; use Sem_Dim;
with Sem_Eval; use Sem_Eval;
with Sem_Res; use Sem_Res;
with Sem_Type; use Sem_Type;
@@ -1476,6 +1477,15 @@ package body Sem_Ch13 is
goto Continue;
end;
+
+ when Aspect_Dimension =>
+ Analyze_Aspect_Dimension (N, Id, Expr);
+ goto Continue;
+
+ when Aspect_Dimension_System =>
+ Analyze_Aspect_Dimension_System (N, Id, Expr);
+ goto Continue;
+
end case;
-- If a delay is required, we delay the freeze (not much point in
@@ -6046,6 +6056,11 @@ package body Sem_Ch13 is
Aspect_Static_Predicate |
Aspect_Type_Invariant =>
T := Standard_Boolean;
+
+ when Aspect_Dimension |
+ Aspect_Dimension_System =>
+ raise Program_Error;
+
end case;
-- Do the preanalyze call
@@ -8777,8 +8792,8 @@ package body Sem_Ch13 is
Source : constant Entity_Id := T.Source;
Target : constant Entity_Id := T.Target;
- Source_Siz : Uint;
- Target_Siz : Uint;
+ Source_Siz : Uint;
+ Target_Siz : Uint;
begin
-- This validation check, which warns if we have unequal sizes for
diff --git a/gcc/ada/sem_ch2.adb b/gcc/ada/sem_ch2.adb
index 84cd62db2c6..efa965eb941 100644
--- a/gcc/ada/sem_ch2.adb
+++ b/gcc/ada/sem_ch2.adb
@@ -30,6 +30,7 @@ with Opt; use Opt;
with Restrict; use Restrict;
with Rident; use Rident;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Dim; use Sem_Dim;
with Sinfo; use Sinfo;
with Stand; use Stand;
with Uintp; use Uintp;
@@ -75,6 +76,8 @@ package body Sem_Ch2 is
else
Find_Direct_Name (N);
end if;
+
+ Analyze_Dimension (N);
end Analyze_Identifier;
-----------------------------
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 6c5a05573d8..9070b4505e9 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -56,6 +56,7 @@ with Sem_Ch6; use Sem_Ch6;
with Sem_Ch7; use Sem_Ch7;
with Sem_Ch8; use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
+with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
with Sem_Elim; use Sem_Elim;
@@ -2036,6 +2037,7 @@ package body Sem_Ch3 is
if Has_Aspects (N) then
Analyze_Aspect_Specifications (N, Id);
end if;
+ Analyze_Dimension (N);
end Analyze_Component_Declaration;
--------------------------
@@ -2089,6 +2091,11 @@ package body Sem_Ch3 is
-- Complete analysis of declaration
Analyze (D);
+
+ -- Removal of the dimension in the expression for object & component
+ -- declaration.
+
+ Remove_Dimension_In_Declaration (D);
Next_Node := Next (D);
if No (Freeze_From) then
@@ -3773,6 +3780,7 @@ package body Sem_Ch3 is
if Has_Aspects (N) then
Analyze_Aspect_Specifications (N, Id);
end if;
+ Analyze_Dimension (N);
end Analyze_Object_Declaration;
---------------------------
@@ -4571,6 +4579,7 @@ package body Sem_Ch3 is
if Has_Aspects (N) then
Analyze_Aspect_Specifications (N, Id);
end if;
+ Analyze_Dimension (N);
end Analyze_Subtype_Declaration;
--------------------------------
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 7e8fed1d852..bd56eeff034 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -50,6 +50,7 @@ with Sem_Ch3; use Sem_Ch3;
with Sem_Ch5; use Sem_Ch5;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
with Sem_Eval; use Sem_Eval;
@@ -6040,8 +6041,16 @@ package body Sem_Ch4 is
First_Subtype (Base_Type (Etype (R))) /= Standard_Integer
and then Base_Type (Etype (R)) /= Universal_Integer
then
- Error_Msg_NE
- ("exponent must be of type Natural, found}", R, Etype (R));
+ if Ada_Version >= Ada_2012
+ and then Is_Dimensioned_Type (Etype (L))
+ then
+ Error_Msg_NE
+ ("exponent for dimensioned type must be a Rational" &
+ ", found}", R, Etype (R));
+ else
+ Error_Msg_NE
+ ("exponent must be of type Natural, found}", R, Etype (R));
+ end if;
return;
end if;
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 073bc2b840a..62df0de17b1 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -47,6 +47,7 @@ with Sem_Case; use Sem_Case;
with Sem_Ch3; use Sem_Ch3;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Elab; use Sem_Elab;
with Sem_Eval; use Sem_Eval;
@@ -839,6 +840,7 @@ package body Sem_Ch5 is
Set_Last_Assignment (Ent, Lhs);
end if;
end;
+ Analyze_Dimension (N);
end Analyze_Assignment;
-----------------------------
@@ -2731,6 +2733,10 @@ package body Sem_Ch5 is
S := First (L);
while Present (S) loop
Analyze (S);
+
+ -- Remove dimension in all statements
+
+ Remove_Dimension_In_Statement (S);
Next (S);
end loop;
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 92c5eed8de1..dbb4bb86e39 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -60,6 +60,7 @@ with Sem_Ch8; use Sem_Ch8;
with Sem_Ch10; use Sem_Ch10;
with Sem_Ch12; use Sem_Ch12;
with Sem_Ch13; use Sem_Ch13;
+with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
with Sem_Elim; use Sem_Elim;
@@ -1529,6 +1530,8 @@ package body Sem_Ch6 is
Kill_Current_Values (Last_Assignment_Only => True);
Check_Unreachable_Code (N);
+
+ Analyze_Dimension (N);
end Analyze_Return_Statement;
-------------------------------------
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index 296e3edfd3a..79fe3680e19 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -53,6 +53,7 @@ with Sem_Ch4; use Sem_Ch4;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch12; use Sem_Ch12;
with Sem_Ch13; use Sem_Ch13;
+with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
with Sem_Eval; use Sem_Eval;
@@ -1215,6 +1216,7 @@ package body Sem_Ch8 is
end if;
Set_Renamed_Object (Id, Nam);
+ Analyze_Dimension (N);
end Analyze_Object_Renaming;
------------------------------
diff --git a/gcc/ada/sem_dim.adb b/gcc/ada/sem_dim.adb
new file mode 100644
index 00000000000..b0691695b72
--- /dev/null
+++ b/gcc/ada/sem_dim.adb
@@ -0,0 +1,2779 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S E M _ D I M --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2011, 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. --
+-- --
+------------------------------------------------------------------------------
+
+with Aspects; use Aspects;
+with Atree; use Atree;
+with Einfo; use Einfo;
+with Errout; use Errout;
+with Lib; use Lib;
+with Namet; use Namet;
+with Namet.Sp; use Namet.Sp;
+with Nlists; use Nlists;
+with Nmake; use Nmake;
+with Opt; use Opt;
+with Rtsfind; use Rtsfind;
+with Sem; use Sem;
+with Sem_Eval; use Sem_Eval;
+with Sem_Res; use Sem_Res;
+with Sem_Util; use Sem_Util;
+with Sinfo; use Sinfo;
+with Snames; use Snames;
+with Stand; use Stand;
+with Stringt; use Stringt;
+with Table;
+with Tbuild; use Tbuild;
+with Uintp; use Uintp;
+with Urealp; use Urealp;
+
+with GNAT.HTable;
+
+package body Sem_Dim is
+
+ -- Maximum number of dimensions in a dimension system
+
+ Max_Dimensions : constant Int := 7;
+
+ -- Dim_Id values are used to identify dimensions in a dimension system
+ -- Note that the highest value of Dim_Id is Max_Dimensions
+
+ subtype Dim_Id is Pos range 1 .. Max_Dimensions;
+
+ -- Record type for dimension system
+ -- A dimension system is defined by the number and the names of its
+ -- dimensions and its base type.
+
+ subtype N_Of_Dimensions is Int range 0 .. Max_Dimensions;
+
+ No_Dimensions : constant N_Of_Dimensions := N_Of_Dimensions'First;
+
+ type Name_Array is array (Dim_Id) of Name_Id;
+
+ No_Names : constant Name_Array := (others => No_Name);
+
+ -- The symbols are used for IO purposes
+
+ type Symbol_Array is array (Dim_Id) of String_Id;
+
+ No_Symbols : constant Symbol_Array := (others => No_String);
+
+ type Dimension_System is record
+ Base_Type : Node_Id;
+ Names : Name_Array;
+ N_Of_Dims : N_Of_Dimensions;
+ Symbols : Symbol_Array;
+ end record;
+
+ No_Dimension_System : constant Dimension_System :=
+ (Empty, No_Names, No_Dimensions, No_Symbols);
+
+ -- Dim_Sys_Id values are used to identify dimension system in the Table
+ -- Note that the special value No_Dim_Sys has no corresponding component in
+ -- the Table since it represents no dimension system.
+
+ subtype Dim_Sys_Id is Nat;
+
+ No_Dim_Sys : constant Dim_Sys_Id := Dim_Sys_Id'First;
+
+ -- The following table records every dimension system
+
+ package Dim_Systems is new Table.Table (
+ Table_Component_Type => Dimension_System,
+ Table_Index_Type => Dim_Sys_Id,
+ Table_Low_Bound => 1,
+ Table_Initial => 5,
+ Table_Increment => 5,
+ Table_Name => "Dim_Systems");
+
+ -- Rational (definitions & operations)
+
+ type Whole is new Int;
+ subtype Positive_Whole is Whole range 1 .. Whole'Last;
+
+ type Rational is record
+ Numerator : Whole;
+ Denominator : Positive_Whole;
+ end record;
+
+ Zero_Rational : constant Rational := (0, 1);
+
+ -- Rational constructors
+
+ function "+" (Right : Whole) return Rational;
+ function "/" (Left, Right : Whole) return Rational;
+ function GCD (Left, Right : Whole) return Int;
+ function Reduce (X : Rational) return Rational;
+
+ -- Unary operator for Rational
+
+ function "-" (Right : Rational) return Rational;
+
+ -- Rational operations for Rationals
+
+ function "+" (Left, Right : Rational) return Rational;
+ function "-" (Left, Right : Rational) return Rational;
+ function "*" (Left, Right : Rational) return Rational;
+
+ -- Operation between Rational and Int
+
+ function "*" (Left : Rational; Right : Whole) return Rational;
+
+ ---------
+ -- GCD --
+ ---------
+
+ function GCD (Left, Right : Whole) return Int is
+ L : Whole := Left;
+ R : Whole := Right;
+
+ begin
+ while R /= 0 loop
+ L := L mod R;
+
+ if L = 0 then
+ return Int (R);
+ end if;
+
+ R := R mod L;
+ end loop;
+
+ return Int (L);
+ end GCD;
+
+ ------------
+ -- Reduce --
+ ------------
+
+ function Reduce (X : Rational) return Rational is
+ begin
+ if X.Numerator = 0 then
+ return Zero_Rational;
+ end if;
+
+ declare
+ G : constant Int := GCD (X.Numerator, X.Denominator);
+
+ begin
+ return Rational'(Numerator => Whole (Int (X.Numerator) / G),
+ Denominator => Whole (Int (X.Denominator) / G));
+ end;
+ end Reduce;
+
+ ---------
+ -- "+" --
+ ---------
+
+ function "+" (Right : Whole) return Rational is
+ begin
+ return (Right, 1);
+ end "+";
+
+ function "+" (Left, Right : Rational) return Rational is
+ R : constant Rational :=
+ Rational'(Numerator => Left.Numerator * Right.Denominator +
+ Left.Denominator * Right.Numerator,
+ Denominator => Left.Denominator * Right.Denominator);
+
+ begin
+ return Reduce (R);
+ end "+";
+
+ ---------
+ -- "-" --
+ ---------
+
+ function "-" (Right : Rational) return Rational is
+ begin
+ return Rational'(Numerator => -Right.Numerator,
+ Denominator => Right.Denominator);
+ end "-";
+
+ function "-" (Left, Right : Rational) return Rational is
+ R : constant Rational :=
+ Rational'(Numerator => Left.Numerator * Right.Denominator -
+ Left.Denominator * Right.Numerator,
+ Denominator => Left.Denominator * Right.Denominator);
+
+ begin
+ return Reduce (R);
+ end "-";
+
+ ---------
+ -- "*" --
+ ---------
+
+ function "*" (Left, Right : Rational) return Rational is
+ R : constant Rational :=
+ Rational'(Numerator => Left.Numerator * Right.Numerator,
+ Denominator => Left.Denominator * Right.Denominator);
+
+ begin
+ return Reduce (R);
+ end "*";
+
+ function "*" (Left : Rational; Right : Whole) return Rational is
+ R : constant Rational :=
+ Rational'(Numerator => Left.Numerator * Right,
+ Denominator => Left.Denominator);
+
+ begin
+ return Reduce (R);
+ end "*";
+
+ ---------
+ -- "/" --
+ ---------
+
+ function "/" (Left, Right : Whole) return Rational is
+ R : constant Int := abs Int (Right);
+ L : Int := Int (Left);
+
+ begin
+ if Right < 0 then
+ L := -L;
+ end if;
+
+ return Reduce (Rational'(Numerator => Whole (L),
+ Denominator => Whole (R)));
+ end "/";
+
+ -- Hash Table for aspect dimension.
+
+ -- The following table provides a relation between nodes and its dimension
+ -- (if not dimensionless). If a node is not stored in the Hash Table, the
+ -- node is considered to be dimensionless.
+ -- A dimension is represented by an array of Max_Dimensions Rationals.
+ -- If the corresponding dimension system has less than Max_Dimensions
+ -- dimensions, the array is filled by as many as Zero_Rationals needed to
+ -- complete the array.
+
+ -- Here is a list of nodes that can have entries in this Htable:
+
+ -- N_Attribute_Reference
+ -- N_Defining_Identifier
+ -- N_Function_Call
+ -- N_Identifier
+ -- N_Indexed_Component
+ -- N_Integer_Literal
+ -- N_Op_Abs
+ -- N_Op_Add
+ -- N_Op_Divide
+ -- N_Op_Expon
+ -- N_Op_Minus
+ -- N_Op_Mod
+ -- N_Op_Multiply
+ -- N_Op_Plus
+ -- N_Op_Rem
+ -- N_Op_Subtract
+ -- N_Qualified_Expression
+ -- N_Real_Literal
+ -- N_Selected_Component
+ -- N_Slice
+ -- N_Type_Conversion
+ -- N_Unchecked_Type_Conversion
+
+ type Dimensions is array (Dim_Id) of Rational;
+
+ Zero_Dimensions : constant Dimensions := (others => Zero_Rational);
+
+ type AD_Hash_Range is range 0 .. 511;
+
+ function AD_Hash (F : Node_Id) return AD_Hash_Range;
+
+ function AD_Hash (F : Node_Id) return AD_Hash_Range is
+ begin
+ return AD_Hash_Range (F mod 512);
+ end AD_Hash;
+
+ -- Node_Id --> Dimensions
+
+ package Aspect_Dimension_Hash_Table is new
+ GNAT.HTable.Simple_HTable
+ (Header_Num => AD_Hash_Range,
+ Element => Dimensions,
+ No_Element => Zero_Dimensions,
+ Key => Node_Id,
+ Hash => AD_Hash,
+ Equal => "=");
+
+ -- Table to record the string of each subtype declaration
+ -- Note that this table is only used for IO purposes
+
+ -- Entity_Id --> String_Id
+
+ package Aspect_Dimension_String_Id_Hash_Table is new
+ GNAT.HTable.Simple_HTable
+ (Header_Num => AD_Hash_Range,
+ Element => String_Id,
+ No_Element => No_String,
+ Key => Entity_Id,
+ Hash => AD_Hash,
+ Equal => "=");
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Analyze_Dimension_Assignment_Statement (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for assignment statement
+
+ procedure Analyze_Dimension_Binary_Op (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for binary operators
+
+ procedure Analyze_Dimension_Component_Declaration (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for component declaration
+
+ procedure Analyze_Dimension_Extended_Return_Statement (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for extended return statement
+
+ procedure Analyze_Dimension_Function_Call (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for function call
+
+ procedure Analyze_Dimension_Has_Etype (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for N_Has_Etype nodes:
+ -- N_Attribute_Reference
+ -- N_Indexed_Component
+ -- N_Qualified_Expression
+ -- N_Selected_Component
+ -- N_Slice
+ -- N_Type_Conversion
+ -- N_Unchecked_Type_Conversion
+
+ procedure Analyze_Dimension_Identifier (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for identifier
+
+ procedure Analyze_Dimension_Object_Declaration (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for object declaration
+
+ procedure Analyze_Dimension_Object_Renaming_Declaration (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for object renaming declaration
+
+ procedure Analyze_Dimension_Simple_Return_Statement (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for simple return statement
+
+ procedure Analyze_Dimension_Subtype_Declaration (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for subtype declaration
+
+ procedure Analyze_Dimension_Unary_Op (N : Node_Id);
+ -- Subroutine of Analyze_Dimension for unary operators
+
+ procedure Copy_Dimensions (From, To : Node_Id);
+ -- Propagate dimensions between two nodes
+
+ procedure Create_Rational_From_Expr (Expr : Node_Id; R : in out Rational);
+ -- Given an expression, creates a rational number
+
+ procedure Eval_Op_Expon_With_Rational_Exponent
+ (N : Node_Id;
+ Rat : Rational);
+ -- Evaluate the Expon if the exponent is a rational and the operand has a
+ -- dimension.
+
+ function From_Dimension_To_String_Id
+ (Dims : Dimensions;
+ Sys : Dim_Sys_Id) return String_Id;
+ -- Given a dimension vector and a dimension system, return the proper
+ -- string of symbols.
+
+ function Get_Dimensions (N : Node_Id) return Dimensions;
+ -- Return the dimensions for the corresponding node
+
+ function Get_Dimensions_String_Id (E : Entity_Id) return String_Id;
+ -- Return the String_Id of dimensions for the corresponding entity
+
+ function Get_Dimension_System_Id (E : Entity_Id) return Dim_Sys_Id;
+ -- Return the Dim_Id of the corresponding dimension system
+
+ procedure Move_Dimensions (From, To : Node_Id);
+ -- Move Dimensions from 'From' to 'To'. Only called when 'From' has a
+ -- dimension.
+
+ function Permits_Dimensions (N : Node_Id) return Boolean;
+ -- Return True if a node can have a dimension
+
+ function Present (Dim : Dimensions) return Boolean;
+ -- Return True if Dim is not equal to Zero_Dimensions.
+
+ procedure Remove_Dimensions (N : Node_Id);
+ -- Remove the node from the HTable
+
+ procedure Set_Dimensions (N : Node_Id; Dims : Dimensions);
+ -- Store the dimensions of N in the Hash_Table for Dimensions
+
+ procedure Set_Dimensions_String_Id (E : Entity_Id; Str : String_Id);
+ -- Store the string of dimensions of E in the Hash_Table for String_Id
+
+ ------------------------------
+ -- Analyze_Aspect_Dimension --
+ ------------------------------
+
+ -- with Dimension => DIMENSION_FOR_SUBTYPE
+ -- DIMENSION_FOR_SUBTYPE ::= (DIMENSION_STRING, DIMENSION_RATIONALS)
+ -- DIMENSION_RATIONALS ::=
+ -- RATIONAL, {, RATIONAL}
+ -- | RATIONAL {, RATIONAL}, others => RATIONAL
+ -- | DISCRETE_CHOICE_LIST => RATIONAL
+
+ -- (see Analyze_Aspect_Dimension_System for DIMENSION_STRING grammar)
+
+ procedure Analyze_Aspect_Dimension
+ (N : Node_Id;
+ Id : Node_Id;
+ Expr : Node_Id)
+ is
+ Def_Id : constant Entity_Id := Defining_Identifier (N);
+ N_Kind : constant Node_Kind := Nkind (N);
+ Analyzed : array (Dimensions'Range) of Boolean := (others => False);
+ -- This array has been defined in order to deals with Others_Choice
+ -- It is a reminder of the dimensions in the aggregate that have already
+ -- been analyzed.
+
+ Choice : Node_Id;
+ Comp_Expr : Node_Id;
+ Comp_Assn : Node_Id;
+ Dim : Dim_Id;
+ Dims : Dimensions := Zero_Dimensions;
+ Dim_Str_Lit : Node_Id;
+ D_Sys : Dim_Sys_Id := No_Dim_Sys;
+ N_Of_Dims : N_Of_Dimensions;
+ Str : String_Id := No_String;
+
+ function Check_Identifier_Is_Dimension
+ (Id : Node_Id;
+ D_Sys : Dim_Sys_Id) return Boolean;
+ -- Return True if the identifier name is the name of a dimension in the
+ -- dimension system D_Sys.
+
+ function Check_Compile_Time_Known_Expressions_In_Aggregate
+ (Expr : Node_Id) return Boolean;
+ -- Check that each expression in the aggregate is known at compile time
+
+ function Check_Number_Dimensions_Aggregate
+ (Expr : Node_Id;
+ D_Sys : Dim_Sys_Id;
+ N_Of_Dims : N_Of_Dimensions) return Boolean;
+ -- This routine checks the number of dimensions in the aggregate.
+
+ function Corresponding_Dimension_System (N : Node_Id) return Dim_Sys_Id;
+ -- Return the Dim_Sys_Id of the corresponding dimension system
+
+ function Corresponding_Etype_Has_Dimensions (N : Node_Id) return Boolean;
+ -- Return True if the Etype of N has a dimension
+
+ function Get_Dimension_Id
+ (Id : Node_Id;
+ D_Sys : Dim_Sys_Id) return Dim_Id;
+ -- Given an identifier and the Dim_Sys_Id of the dimension system in the
+ -- Table, returns the Dim_Id that has the same name as the identifier.
+
+ ------------------------------------
+ -- Corresponding_Dimension_System --
+ ------------------------------------
+
+ function Corresponding_Dimension_System
+ (N : Node_Id) return Dim_Sys_Id
+ is
+ B_Typ : Node_Id;
+ Sub_Ind : Node_Id;
+ begin
+ -- Aspect_Dimension can only apply for subtypes
+
+ -- Look for the dimension system corresponding to this
+ -- Aspect_Dimension.
+
+ if Nkind (N) = N_Subtype_Declaration then
+ Sub_Ind := Subtype_Indication (N);
+
+ if Nkind (Sub_Ind) /= N_Subtype_Indication then
+ B_Typ := Etype (Sub_Ind);
+ return Get_Dimension_System_Id (B_Typ);
+
+ else
+ return No_Dim_Sys;
+ end if;
+
+ else
+ return No_Dim_Sys;
+ end if;
+ end Corresponding_Dimension_System;
+
+ ----------------------------------------
+ -- Corresponding_Etype_Has_Dimensions --
+ ----------------------------------------
+
+ function Corresponding_Etype_Has_Dimensions
+ (N : Node_Id) return Boolean
+ is
+ Dims_Typ : Dimensions;
+ Typ : Entity_Id;
+
+ begin
+
+ -- Check the type is dimensionless before assigning a dimension
+
+ if Nkind (N) = N_Subtype_Declaration then
+ declare
+ Sub : constant Node_Id := Subtype_Indication (N);
+
+ begin
+ if Nkind (Sub) /= N_Subtype_Indication then
+ Typ := Etype (Sub);
+ else
+ Typ := Etype (Subtype_Mark (Sub));
+ end if;
+
+ Dims_Typ := Get_Dimensions (Typ);
+ return Present (Dims_Typ);
+ end;
+
+ else
+ return False;
+ end if;
+ end Corresponding_Etype_Has_Dimensions;
+
+ ---------------------------------------
+ -- Check_Number_Dimensions_Aggregate --
+ ---------------------------------------
+
+ function Check_Number_Dimensions_Aggregate
+ (Expr : Node_Id;
+ D_Sys : Dim_Sys_Id;
+ N_Of_Dims : N_Of_Dimensions) return Boolean
+ is
+ Assoc : Node_Id;
+ Choice : Node_Id;
+ Comp_Expr : Node_Id;
+ N_Dims_Aggr : Int := No_Dimensions;
+ -- The number of dimensions in this aggregate
+
+ begin
+ -- Check the size of the aggregate match with the size of the
+ -- corresponding dimension system.
+
+ Comp_Expr := First (Expressions (Expr));
+
+ -- Skip the first argument in the aggregate since it's a character or
+ -- a string and not a dimension value.
+
+ Next (Comp_Expr);
+
+ if Present (Component_Associations (Expr)) then
+
+ -- If the aggregate is a positional aggregate with an
+ -- Others_Choice, the number of expressions must be less than or
+ -- equal to N_Of_Dims - 1.
+
+ if Present (Comp_Expr) then
+ N_Dims_Aggr := List_Length (Expressions (Expr)) - 1;
+ return N_Dims_Aggr <= N_Of_Dims - 1;
+
+ -- If the aggregate is a named aggregate, N_Dims_Aggr is used to
+ -- count all the dimensions referenced by the aggregate.
+
+ else
+ Assoc := First (Component_Associations (Expr));
+
+ while Present (Assoc) loop
+ if Nkind (Assoc) = N_Range then
+ Choice := First (Choices (Assoc));
+
+ declare
+ HB : constant Node_Id := High_Bound (Choice);
+ LB : constant Node_Id := Low_Bound (Choice);
+ LB_Dim : Dim_Id;
+ HB_Dim : Dim_Id;
+
+ begin
+ if not Check_Identifier_Is_Dimension (HB, D_Sys)
+ or else not Check_Identifier_Is_Dimension (LB, D_Sys)
+ then
+ return False;
+ end if;
+
+ HB_Dim := Get_Dimension_Id (HB, D_Sys);
+ LB_Dim := Get_Dimension_Id (LB, D_Sys);
+
+ N_Dims_Aggr := N_Dims_Aggr + HB_Dim - LB_Dim + 1;
+ end;
+
+ else
+ N_Dims_Aggr :=
+ N_Dims_Aggr + List_Length (Choices (Assoc));
+ end if;
+
+ Next (Assoc);
+ end loop;
+
+ -- Check whether an Others_Choice is present or not
+
+ if Nkind
+ (First (Choices (Last (Component_Associations (Expr))))) =
+ N_Others_Choice
+ then
+ return N_Dims_Aggr <= N_Of_Dims;
+ else
+ return N_Dims_Aggr = N_Of_Dims;
+ end if;
+ end if;
+
+ -- If the aggregate is a positional aggregate without Others_Choice,
+ -- the number of expressions must match the number of dimensions in
+ -- the dimension system.
+
+ else
+ N_Dims_Aggr := List_Length (Expressions (Expr)) - 1;
+ return N_Dims_Aggr = N_Of_Dims;
+ end if;
+ end Check_Number_Dimensions_Aggregate;
+
+ -----------------------------------
+ -- Check_Identifier_Is_Dimension --
+ -----------------------------------
+
+ function Check_Identifier_Is_Dimension
+ (Id : Node_Id;
+ D_Sys : Dim_Sys_Id) return Boolean
+ is
+ Na_Id : constant Name_Id := Chars (Id);
+ Dim_Name1 : Name_Id;
+ Dim_Name2 : Name_Id;
+
+ begin
+
+ for Dim1 in Dim_Id'Range loop
+ Dim_Name1 := Dim_Systems.Table (D_Sys).Names (Dim1);
+
+ if Dim_Name1 = Na_Id then
+ return True;
+ end if;
+
+ if Dim1 = Max_Dimensions then
+
+ -- Check for possible misspelling
+
+ Error_Msg_N ("& is not a dimension argument for aspect%", Id);
+
+ for Dim2 in Dim_Id'Range loop
+ Dim_Name2 := Dim_Systems.Table (D_Sys).Names (Dim2);
+
+ if Is_Bad_Spelling_Of (Na_Id, Dim_Name2) then
+ Error_Msg_Name_1 := Dim_Name2;
+ Error_Msg_N ("\possible misspelling of%", Id);
+ exit;
+ end if;
+ end loop;
+ end if;
+ end loop;
+
+ return False;
+ end Check_Identifier_Is_Dimension;
+
+ ----------------------
+ -- Get_Dimension_Id --
+ ----------------------
+
+ -- Given an identifier, returns the correponding position of the
+ -- dimension in the dimension system.
+
+ function Get_Dimension_Id
+ (Id : Node_Id;
+ D_Sys : Dim_Sys_Id) return Dim_Id
+ is
+ Na_Id : constant Name_Id := Chars (Id);
+ Dim : Dim_Id;
+ Dim_Name : Name_Id;
+
+ begin
+ for D in Dim_Id'Range loop
+ Dim_Name := Dim_Systems.Table (D_Sys).Names (D);
+
+ if Dim_Name = Na_Id then
+ Dim := D;
+ end if;
+
+ end loop;
+
+ return Dim;
+ end Get_Dimension_Id;
+
+ -------------------------------------------------------
+ -- Check_Compile_Time_Known_Expressions_In_Aggregate --
+ -------------------------------------------------------
+
+ function Check_Compile_Time_Known_Expressions_In_Aggregate
+ (Expr : Node_Id) return Boolean
+ is
+ Comp_Assn : Node_Id;
+ Comp_Expr : Node_Id;
+
+ begin
+ Comp_Expr := First (Expressions (Expr));
+ Next (Comp_Expr);
+
+ while Present (Comp_Expr) loop
+
+ -- First, analyze the expression
+
+ Analyze_And_Resolve (Comp_Expr);
+ if not Compile_Time_Known_Value (Comp_Expr) then
+ return False;
+ end if;
+
+ Next (Comp_Expr);
+ end loop;
+
+ Comp_Assn := First (Component_Associations (Expr));
+
+ while Present (Comp_Assn) loop
+ Comp_Expr := Expression (Comp_Assn);
+
+ -- First, analyze the expression
+
+ Analyze_And_Resolve (Comp_Expr);
+
+ if not Compile_Time_Known_Value (Comp_Expr) then
+ return False;
+ end if;
+
+ Next (Comp_Assn);
+ end loop;
+
+ return True;
+ end Check_Compile_Time_Known_Expressions_In_Aggregate;
+
+ -- Start of processing for Analyze_Aspect_Dimension
+
+ begin
+ -- Syntax checking
+
+ Error_Msg_Name_1 := Chars (Id);
+
+ if N_Kind /= N_Subtype_Declaration then
+ Error_Msg_N ("aspect% doesn't apply here", N);
+ return;
+ end if;
+
+ if Nkind (Expr) /= N_Aggregate then
+ Error_Msg_N ("wrong syntax for aspect%", Expr);
+ return;
+ end if;
+
+ D_Sys := Corresponding_Dimension_System (N);
+
+ if D_Sys = No_Dim_Sys then
+ Error_Msg_N ("dimension system not found for aspect%", N);
+ return;
+ end if;
+
+ if Corresponding_Etype_Has_Dimensions (N) then
+ Error_Msg_N ("corresponding type already has a dimension", N);
+ return;
+ end if;
+
+ -- Check the first expression is a string or a character literal and
+ -- skip it.
+
+ Dim_Str_Lit := First (Expressions (Expr));
+
+ if not Present (Dim_Str_Lit)
+ or else not Nkind_In (Dim_Str_Lit,
+ N_String_Literal,
+ N_Character_Literal)
+ then
+ Error_Msg_N
+ ("wrong syntax for aspect%: first argument in the aggregate must " &
+ "be a character or a string",
+ Expr);
+ return;
+ end if;
+
+ Comp_Expr := Next (Dim_Str_Lit);
+
+ -- Check the number of dimensions match with the dimension system
+
+ N_Of_Dims := Dim_Systems.Table (D_Sys).N_Of_Dims;
+
+ if not Check_Number_Dimensions_Aggregate (Expr, D_Sys, N_Of_Dims) then
+ Error_Msg_N ("wrong number of dimensions for aspect%", Expr);
+ return;
+ end if;
+
+ Dim := Dim_Id'First;
+ Comp_Assn := First (Component_Associations (Expr));
+
+ if Present (Comp_Expr) then
+
+ if List_Length (Component_Associations (Expr)) > 1 then
+ Error_Msg_N ("named association cannot follow " &
+ "positional association for aspect%", Expr);
+ return;
+ end if;
+
+ if Present (Comp_Assn)
+ and then Nkind (First (Choices (Comp_Assn))) /= N_Others_Choice
+ then
+ Error_Msg_N ("named association cannot follow " &
+ "positional association for aspect%", Expr);
+ return;
+ end if;
+ end if;
+
+ -- Check each expression in the aspect Dimension aggregate is known at
+ -- compile time.
+
+ if not Check_Compile_Time_Known_Expressions_In_Aggregate (Expr) then
+ Error_Msg_N ("wrong syntax for aspect%", Expr);
+ return;
+ end if;
+
+ -- Get the dimension values and store them in the Hash_Table
+
+ -- Positional aggregate case
+
+ while Present (Comp_Expr) loop
+ if Is_Integer_Type (Def_Id) then
+ Dims (Dim) := +Whole (UI_To_Int (Expr_Value (Comp_Expr)));
+ else
+ Create_Rational_From_Expr (Comp_Expr, Dims (Dim));
+ end if;
+
+ Analyzed (Dim) := True;
+
+ exit when Dim = Max_Dimensions;
+
+ Dim := Dim + 1;
+ Next (Comp_Expr);
+ end loop;
+
+ -- Named aggregate case
+
+ while Present (Comp_Assn) loop
+ Comp_Expr := Expression (Comp_Assn);
+ Choice := First (Choices (Comp_Assn));
+
+ if List_Length (Choices (Comp_Assn)) = 1 then
+
+ -- N_Identifier case
+
+ if Nkind (Choice) = N_Identifier then
+
+ if not Check_Identifier_Is_Dimension (Choice, D_Sys) then
+ return;
+ end if;
+
+ Dim := Get_Dimension_Id (Choice, D_Sys);
+
+ if Is_Integer_Type (Def_Id) then
+ Dims (Dim) := +Whole (UI_To_Int (Expr_Value (Comp_Expr)));
+ else
+ Create_Rational_From_Expr (Comp_Expr, Dims (Dim));
+ end if;
+
+ Analyzed (Dim) := True;
+
+ -- N_Range case
+
+ elsif Nkind (Choice) = N_Range then
+ declare
+ HB : constant Node_Id := High_Bound (Choice);
+ LB : constant Node_Id := Low_Bound (Choice);
+ LB_Dim : constant Dim_Id := Get_Dimension_Id (LB, D_Sys);
+ HB_Dim : constant Dim_Id := Get_Dimension_Id (HB, D_Sys);
+
+ begin
+ for Dim in LB_Dim .. HB_Dim loop
+ if Is_Integer_Type (Def_Id) then
+ Dims (Dim) :=
+ +Whole (UI_To_Int (Expr_Value (Comp_Expr)));
+ else
+ Create_Rational_From_Expr (Comp_Expr, Dims (Dim));
+ end if;
+
+ Analyzed (Dim) := True;
+ end loop;
+ end;
+
+ -- N_Others_Choice case
+
+ elsif Nkind (Choice) = N_Others_Choice then
+
+ -- Check the Others_Choice is alone and last in the aggregate
+
+ if Present (Next (Comp_Assn)) then
+ Error_Msg_N
+ ("OTHERS must appear alone and last in expression " &
+ "for aspect%", Choice);
+ return;
+ end if;
+
+ -- End the filling of Dims by the Others_Choice value
+ -- If N_Of_Dims < Max_Dimensions then only the
+ -- positions that haven't been already analyzed from
+ -- Dim_Id'First to N_Of_Dims are filled.
+
+ for Dim in Dim_Id'First .. N_Of_Dims loop
+ if not Analyzed (Dim) then
+ if Is_Integer_Type (Def_Id) then
+ Dims (Dim) :=
+ +Whole (UI_To_Int (Expr_Value (Comp_Expr)));
+ else
+ Create_Rational_From_Expr (Comp_Expr, Dims (Dim));
+ end if;
+ end if;
+ end loop;
+
+ else
+ Error_Msg_N ("wrong syntax for aspect%", Id);
+ end if;
+
+ else
+ while Present (Choice) loop
+ if Nkind (Choice) = N_Identifier then
+
+ if not Check_Identifier_Is_Dimension (Choice, D_Sys) then
+ return;
+ end if;
+
+ Dim := Get_Dimension_Id (Choice, D_Sys);
+
+ if Is_Integer_Type (Def_Id) then
+ Dims (Dim) := +Whole (UI_To_Int (Expr_Value (Comp_Expr)));
+ else
+ Create_Rational_From_Expr (Comp_Expr, Dims (Dim));
+ end if;
+
+ Analyzed (Dim) := True;
+ Next (Choice);
+ else
+ Error_Msg_N ("wrong syntax for aspect%", Id);
+ end if;
+ end loop;
+ end if;
+
+ Next (Comp_Assn);
+ end loop;
+
+ -- Create the string of dimensions
+
+ if Nkind (Dim_Str_Lit) = N_Character_Literal then
+ Start_String;
+ Store_String_Char (UI_To_CC (Char_Literal_Value (Dim_Str_Lit)));
+ Str := End_String;
+ else
+ Str := Strval (Dim_Str_Lit);
+ end if;
+
+ -- Store the dimensions in the Hash Table if not all equal to zero and
+ -- string is empty.
+
+ if not Present (Dims) then
+ if String_Length (Str) = 0 then
+ Error_Msg_N
+ ("?dimension values all equal to zero for aspect%", Expr);
+ return;
+ end if;
+ else
+ Set_Dimensions (Def_Id, Dims);
+ end if;
+
+ -- Store the string in the Hash Table
+ -- When the string is empty, don't store the string in the Hash Table
+
+ if Str /= No_String
+ and then String_Length (Str) /= 0
+ then
+ Set_Dimensions_String_Id (Def_Id, Str);
+ end if;
+ end Analyze_Aspect_Dimension;
+
+ -------------------------------------
+ -- Analyze_Aspect_Dimension_System --
+ -------------------------------------
+
+ -- with Dimension_System => DIMENSION_PAIRS
+ -- DIMENSION_PAIRS ::=
+ -- (DIMENSION_PAIR
+ -- [, DIMENSION_PAIR]
+ -- [, DIMENSION_PAIR]
+ -- [, DIMENSION_PAIR]
+ -- [, DIMENSION_PAIR]
+ -- [, DIMENSION_PAIR]
+ -- [, DIMENSION_PAIR])
+ -- DIMENSION_PAIR ::= (DIMENSION_IDENTIFIER, DIMENSION_STRING)
+ -- DIMENSION_IDENTIFIER ::= IDENTIFIER
+ -- DIMENSION_STRING ::= STRING_LITERAL | CHARACTER_LITERAL
+
+ procedure Analyze_Aspect_Dimension_System
+ (N : Node_Id;
+ Id : Node_Id;
+ Expr : Node_Id)
+ is
+ Dim_Name : Node_Id;
+ Dim_Node : Node_Id;
+ Dim_Symbol : Node_Id;
+ D_Sys : Dimension_System := No_Dimension_System;
+ Names : Name_Array := No_Names;
+ N_Of_Dims : N_Of_Dimensions;
+ Symbols : Symbol_Array := No_Symbols;
+
+ function Derived_From_Numeric_Type (N : Node_Id) return Boolean;
+ -- Return True if the node is a derived type declaration from any
+ -- numeric type.
+
+ function Check_Dimension_System_Syntax (N : Node_Id) return Boolean;
+ -- Return True if the expression is an aggregate of names
+
+ function Check_Number_Of_Dimensions (Expr : Node_Id) return Boolean;
+ -- Return True if the number of dimensions in the corresponding
+ -- dimension is positive and lower than Max_Dimensions.
+
+ -------------------------------
+ -- Derived_From_Numeric_Type --
+ -------------------------------
+
+ function Derived_From_Numeric_Type (N : Node_Id) return Boolean is
+ begin
+ case (Nkind (N)) is
+ when N_Full_Type_Declaration =>
+ declare
+ T_Def : constant Node_Id := Type_Definition (N);
+ Ent : Entity_Id;
+
+ begin
+ -- Check that the node is a derived type declaration from
+ -- a numeric type.
+
+ if Nkind (T_Def) /= N_Derived_Type_Definition then
+ return False;
+ else
+ Ent := Entity (Subtype_Indication (T_Def));
+
+ if Is_Numeric_Type (Ent) then
+ return True;
+ else
+ return False;
+ end if;
+ end if;
+ end;
+
+ when others => return False;
+ end case;
+ end Derived_From_Numeric_Type;
+
+ -----------------------------------
+ -- Check_Dimension_System_Syntax --
+ -----------------------------------
+
+ -- Check that the expression of aspect Dimension_System is an aggregate
+ -- which contains pairs of identifier and string or character literal.
+
+ function Check_Dimension_System_Syntax (N : Node_Id) return Boolean is
+ Dim_Node : Node_Id;
+ Expr_Dim : Node_Id;
+ begin
+ -- Chek that the aggregate is a positional array
+
+ if Present (Component_Associations (N)) then
+ return False;
+ else
+ Dim_Node := First (Expressions (N));
+
+ -- Check that each component of the aggregate is an aggregate
+
+ while Present (Dim_Node) loop
+
+ -- Verify that the aggregate is a pair of identifier and string
+ -- or character literal.
+
+ if Nkind (Dim_Node) = N_Aggregate then
+ if not Present (Expressions (Dim_Node)) then
+ return False;
+ end if;
+
+ if Present (Component_Associations (Dim_Node)) then
+ return False;
+ end if;
+
+ -- First expression in the aggregate
+
+ Expr_Dim := First (Expressions (Dim_Node));
+
+ if Nkind (Expr_Dim) /= N_Identifier then
+ return False;
+ end if;
+
+ -- Second expression in the aggregate
+
+ Next (Expr_Dim);
+
+ if not Nkind_In (Expr_Dim,
+ N_String_Literal,
+ N_Character_Literal)
+ then
+ return False;
+ end if;
+
+ -- If the aggregate has a third expression, return False
+
+ Next (Expr_Dim);
+
+ if Present (Expr_Dim) then
+ return False;
+ end if;
+ else
+ return False;
+ end if;
+
+ Next (Dim_Node);
+ end loop;
+
+ return True;
+ end if;
+ end Check_Dimension_System_Syntax;
+
+ --------------------------------
+ -- Check_Number_Of_Dimensions --
+ --------------------------------
+
+ function Check_Number_Of_Dimensions (Expr : Node_Id) return Boolean is
+ List_Expr : constant List_Id := Expressions (Expr);
+
+ begin
+ if List_Length (List_Expr) < Dim_Id'First
+ or else List_Length (List_Expr) > Max_Dimensions then
+ return False;
+ else
+ return True;
+ end if;
+ end Check_Number_Of_Dimensions;
+
+ -- Start of processing for Analyze_Aspect_Dimension_System
+
+ begin
+ Error_Msg_Name_1 := Chars (Id);
+
+ -- Syntax checking
+
+ if Nkind (Expr) /= N_Aggregate then
+ Error_Msg_N ("wrong syntax for aspect%", Expr);
+ return;
+ end if;
+
+ if not Derived_From_Numeric_Type (N) then
+ Error_Msg_N ("aspect% only apply for type derived from numeric type",
+ Id);
+ return;
+ end if;
+
+ if not Check_Dimension_System_Syntax (Expr) then
+ Error_Msg_N ("wrong syntax for aspect%", Expr);
+ return;
+ end if;
+
+ if not Check_Number_Of_Dimensions (Expr) then
+ Error_Msg_N ("wrong number of dimensions for aspect%", Expr);
+ return;
+ end if;
+
+ -- Number of dimensions in the system
+
+ N_Of_Dims := List_Length (Expressions (Expr));
+
+ -- Create the new dimension system
+
+ D_Sys.Base_Type := N;
+ Dim_Node := First (Expressions (Expr));
+
+ for Dim in Dim_Id'First .. N_Of_Dims loop
+ Dim_Name := First (Expressions (Dim_Node));
+ Names (Dim) := Chars (Dim_Name);
+ Dim_Symbol := Next (Dim_Name);
+
+ -- N_Character_Literal case
+
+ if Nkind (Dim_Symbol) = N_Character_Literal then
+ Start_String;
+ Store_String_Char (UI_To_CC (Char_Literal_Value (Dim_Symbol)));
+ Symbols (Dim) := End_String;
+
+ -- N_String_Literal case
+
+ else
+ Symbols (Dim) := Strval (Dim_Symbol);
+ end if;
+
+ Next (Dim_Node);
+ end loop;
+
+ D_Sys.Names := Names;
+ D_Sys.N_Of_Dims := N_Of_Dims;
+ D_Sys.Symbols := Symbols;
+
+ -- Store the dimension system in the Table
+
+ Dim_Systems.Append (D_Sys);
+ end Analyze_Aspect_Dimension_System;
+
+ -----------------------
+ -- Analyze_Dimension --
+ -----------------------
+
+ -- This dispatch routine propagates dimensions for each node
+
+ procedure Analyze_Dimension (N : Node_Id) is
+ begin
+ -- Aspect is an Ada 2012 feature
+
+ if Ada_Version < Ada_2012 then
+ return;
+ end if;
+
+ case Nkind (N) is
+
+ when N_Assignment_Statement =>
+ Analyze_Dimension_Assignment_Statement (N);
+
+ when N_Subtype_Declaration =>
+ Analyze_Dimension_Subtype_Declaration (N);
+
+ when N_Object_Declaration =>
+ Analyze_Dimension_Object_Declaration (N);
+
+ when N_Object_Renaming_Declaration =>
+ Analyze_Dimension_Object_Renaming_Declaration (N);
+
+ when N_Component_Declaration =>
+ Analyze_Dimension_Component_Declaration (N);
+
+ when N_Binary_Op =>
+ Analyze_Dimension_Binary_Op (N);
+
+ when N_Unary_Op =>
+ Analyze_Dimension_Unary_Op (N);
+
+ when N_Identifier =>
+ Analyze_Dimension_Identifier (N);
+
+ when N_Attribute_Reference |
+ N_Indexed_Component |
+ N_Qualified_Expression |
+ N_Selected_Component |
+ N_Slice |
+ N_Type_Conversion |
+ N_Unchecked_Type_Conversion =>
+ Analyze_Dimension_Has_Etype (N);
+
+ when N_Function_Call =>
+ Analyze_Dimension_Function_Call (N);
+
+ when N_Extended_Return_Statement =>
+ Analyze_Dimension_Extended_Return_Statement (N);
+
+ when N_Simple_Return_Statement =>
+ Analyze_Dimension_Simple_Return_Statement (N);
+
+ when others => null;
+
+ end case;
+ end Analyze_Dimension;
+
+ --------------------------------------------
+ -- Analyze_Dimension_Assignment_Statement --
+ --------------------------------------------
+
+ procedure Analyze_Dimension_Assignment_Statement (N : Node_Id) is
+ Lhs : constant Node_Id := Name (N);
+ Dim_Lhs : constant Dimensions := Get_Dimensions (Lhs);
+ Rhs : constant Node_Id := Expression (N);
+ Dim_Rhs : constant Dimensions := Get_Dimensions (Rhs);
+
+ procedure Analyze_Dimensions_In_Assignment
+ (Dim_Lhs : Dimensions;
+ Dim_Rhs : Dimensions);
+ -- Subroutine to perform the dimensionnality checking for assignment
+
+ --------------------------------------
+ -- Analyze_Dimensions_In_Assignment --
+ --------------------------------------
+
+ procedure Analyze_Dimensions_In_Assignment
+ (Dim_Lhs : Dimensions;
+ Dim_Rhs : Dimensions)
+ is
+ begin
+ -- Check the lhs and the rhs have the same dimension
+
+ if not Present (Dim_Lhs) then
+
+ if Present (Dim_Rhs) then
+ Error_Msg_N ("?dimensions missmatch in assignment", N);
+ end if;
+ else
+
+ if Dim_Lhs /= Dim_Rhs then
+ Error_Msg_N ("?dimensions missmatch in assignment", N);
+ end if;
+
+ end if;
+ end Analyze_Dimensions_In_Assignment;
+
+ -- Start of processing for Analyze_Dimension_Assignment
+
+ begin
+ Analyze_Dimensions_In_Assignment (Dim_Lhs, Dim_Rhs);
+ end Analyze_Dimension_Assignment_Statement;
+
+ ---------------------------------
+ -- Analyze_Dimension_Binary_Op --
+ ---------------------------------
+
+ procedure Analyze_Dimension_Binary_Op (N : Node_Id) is
+ N_Kind : constant Node_Kind := Nkind (N);
+
+ begin
+ if Nkind_In (N_Kind, N_Op_Add, N_Op_Expon, N_Op_Subtract)
+ or else N_Kind in N_Multiplying_Operator
+ or else N_Kind in N_Op_Compare
+ then
+ declare
+ L : constant Node_Id := Left_Opnd (N);
+ L_Dims : constant Dimensions := Get_Dimensions (L);
+ L_Has_Dimensions : constant Boolean := Present (L_Dims);
+ R : constant Node_Id := Right_Opnd (N);
+ R_Dims : constant Dimensions := Get_Dimensions (R);
+ R_Has_Dimensions : constant Boolean := Present (R_Dims);
+ Dims : Dimensions := Zero_Dimensions;
+
+ begin
+
+ if Nkind_In (N, N_Op_Add, N_Op_Mod, N_Op_Rem, N_Op_Subtract) then
+ Error_Msg_Name_1 := Chars (N);
+
+ -- Check both operands dimension
+
+ if L_Has_Dimensions and R_Has_Dimensions then
+
+ -- If dimensions missmatch
+
+ if L_Dims /= R_Dims then
+ Error_Msg_N
+ ("?both operands for operation% must have same " &
+ "dimension", N);
+ else
+ Set_Dimensions (N, L_Dims);
+ end if;
+
+ elsif not L_Has_Dimensions and R_Has_Dimensions then
+ Error_Msg_N
+ ("?both operands for operation% must have same dimension",
+ N);
+
+ elsif L_Has_Dimensions and not R_Has_Dimensions then
+ Error_Msg_N
+ ("?both operands for operation% must have same dimension",
+ N);
+
+ end if;
+
+ elsif Nkind_In (N_Kind, N_Op_Multiply, N_Op_Divide) then
+
+ if L_Has_Dimensions and R_Has_Dimensions then
+
+ -- Get both operands dimension and add them
+
+ if N_Kind = N_Op_Multiply then
+ for Dim in Dimensions'Range loop
+ Dims (Dim) := L_Dims (Dim) + R_Dims (Dim);
+ end loop;
+
+ -- Get both operands dimension and subtract them
+
+ else
+ for Dim in Dimensions'Range loop
+ Dims (Dim) := L_Dims (Dim) - R_Dims (Dim);
+ end loop;
+ end if;
+
+ elsif L_Has_Dimensions and not R_Has_Dimensions then
+ Dims := L_Dims;
+
+ elsif not L_Has_Dimensions and R_Has_Dimensions then
+
+ if N_Kind = N_Op_Multiply then
+ Dims := R_Dims;
+ else
+ for Dim in R_Dims'Range loop
+ Dims (Dim) := -R_Dims (Dim);
+ end loop;
+ end if;
+ end if;
+
+ if Present (Dims) then
+ Set_Dimensions (N, Dims);
+ end if;
+
+ -- N_Op_Expon
+ -- Propagation of the dimension and evaluation of the result if
+ -- the exponent is a rational and if the operand has a dimension.
+
+ elsif N_Kind = N_Op_Expon then
+ declare
+ Rat : Rational := Zero_Rational;
+
+ begin
+ -- Check exponent is dimensionless
+
+ if R_Has_Dimensions then
+ Error_Msg_N
+ ("?right operand cannot have a dimension for&",
+ Identifier (N));
+
+ else
+ -- Check the left operand is not dimensionless
+
+ -- Note that the value of the exponent must be know at
+ -- compile time. Otherwise, the exponentiation evaluation
+ -- will return an error message.
+
+ if Get_Dimension_System_Id
+ (Base_Type (Etype (L))) /= No_Dim_Sys
+ and then Compile_Time_Known_Value (R)
+ then
+ -- Real exponent case
+
+ if Is_Real_Type (Etype (L)) then
+ -- Define the exponent as a Rational number
+
+ Create_Rational_From_Expr (R, Rat);
+
+ if L_Has_Dimensions then
+ for Dim in Dimensions'Range loop
+ Dims (Dim) := L_Dims (Dim) * Rat;
+ end loop;
+
+ if Present (Dims) then
+ Set_Dimensions (N, Dims);
+ end if;
+ end if;
+
+ -- Evaluate the operator with rational exponent
+
+ -- Eval_Op_Expon_With_Rational_Exponent (N, Rat);
+
+ -- Integer exponent case
+
+ else
+ for Dim in Dimensions'Range loop
+ Dims (Dim) :=
+ L_Dims (Dim) *
+ Whole (UI_To_Int (Expr_Value (R)));
+ end loop;
+
+ if Present (Dims) then
+ Set_Dimensions (N, Dims);
+ end if;
+ end if;
+ end if;
+ end if;
+ end;
+
+ -- For relational operations, only a dimension checking is
+ -- performed.
+ -- No propagation
+
+ elsif N_Kind in N_Op_Compare then
+ Error_Msg_Name_1 := Chars (N);
+
+ if (L_Has_Dimensions or R_Has_Dimensions)
+ and then L_Dims /= R_Dims
+ then
+ Error_Msg_N
+ ("?both operands for operation% must have same dimension",
+ N);
+ end if;
+ end if;
+
+ Remove_Dimensions (L);
+ Remove_Dimensions (R);
+ end;
+ end if;
+ end Analyze_Dimension_Binary_Op;
+
+ ---------------------------------------------
+ -- Analyze_Dimension_Component_Declaration --
+ ---------------------------------------------
+
+ procedure Analyze_Dimension_Component_Declaration (N : Node_Id) is
+ Expr : constant Node_Id := Expression (N);
+ Id : constant Entity_Id := Defining_Identifier (N);
+ E_Typ : constant Entity_Id := Etype (Id);
+ Dim_T : constant Dimensions := Get_Dimensions (E_Typ);
+ Dim_E : Dimensions;
+
+ begin
+ if Present (Dim_T) then
+
+ -- If the component type has a dimension and there is no expression,
+ -- propagates the dimension.
+
+ if Present (Expr) then
+ Dim_E := Get_Dimensions (Expr);
+
+ if Present (Dim_E) then
+ -- Return an error if the dimension of the expression and the
+ -- dimension of the type missmatch.
+
+ if Dim_E /= Dim_T then
+ Error_Msg_N ("?dimensions missmatch in object " &
+ "declaration", N);
+ end if;
+
+ -- If the expression is dimensionless
+
+ else
+ Error_Msg_N
+ ("?dimensions missmatch in component declaration", N);
+ end if;
+
+ -- For every other cases, propagate the dimensions
+
+ else
+ Copy_Dimensions (E_Typ, Id);
+ end if;
+ end if;
+ end Analyze_Dimension_Component_Declaration;
+
+ -------------------------------------------------
+ -- Analyze_Dimension_Extended_Return_Statement --
+ -------------------------------------------------
+
+ procedure Analyze_Dimension_Extended_Return_Statement (N : Node_Id) is
+ Obj_Decls : constant List_Id := Return_Object_Declarations (N);
+ R_Ent : constant Entity_Id := Return_Statement_Entity (N);
+ R_Etyp : constant Entity_Id := Etype (Return_Applies_To (R_Ent));
+ Dims_R : constant Dimensions := Get_Dimensions (R_Etyp);
+ Dims_Obj : Dimensions;
+ Obj_Decl : Node_Id;
+ Obj_Id : Entity_Id;
+
+ begin
+ if Present (Obj_Decls) then
+ Obj_Decl := First (Obj_Decls);
+
+ while Present (Obj_Decl) loop
+ if Nkind (Obj_Decl) = N_Object_Declaration then
+ Obj_Id := Defining_Identifier (Obj_Decl);
+
+ if Is_Return_Object (Obj_Id) then
+ Dims_Obj := Get_Dimensions (Obj_Id);
+
+ if Dims_R /= Dims_Obj then
+ Error_Msg_N ("?dimensions missmatch in return statement",
+ N);
+ return;
+ end if;
+ end if;
+ end if;
+
+ Next (Obj_Decl);
+ end loop;
+ end if;
+ end Analyze_Dimension_Extended_Return_Statement;
+
+ -------------------------------------
+ -- Analyze_Dimension_Function_Call --
+ -------------------------------------
+
+ procedure Analyze_Dimension_Function_Call (N : Node_Id) is
+ Name_Call : constant Node_Id := Name (N);
+ Par_Ass : constant List_Id := Parameter_Associations (N);
+ Dims : Dimensions;
+ Dims_Param : Dimensions;
+ Param : Node_Id;
+
+ function Is_Elementary_Function_Call (N : Node_Id) return Boolean;
+ -- Return True if the call is a call of an elementary function (see
+ -- Ada.Numerics.Generic_Elementary_Functions).
+
+ ---------------------------------
+ -- Is_Elementary_Function_Call --
+ ---------------------------------
+
+ function Is_Elementary_Function_Call (N : Node_Id) return Boolean is
+ Ent : Entity_Id;
+
+ begin
+ -- Note that the node must come from source
+
+ if Comes_From_Source (N)
+ and then Is_Entity_Name (Name_Call)
+ then
+ Ent := Entity (Name_Call);
+
+ -- Check the procedure is defined in an instantiation of a generic
+ -- package.
+
+ if Is_Generic_Instance (Scope (Ent)) then
+ Ent := Cunit_Entity (Get_Source_Unit (Ent));
+
+ -- Check the name of the generic package is
+ -- Generic_Elementary_Functions
+
+ if Is_Library_Level_Entity (Ent)
+ and then Chars (Ent) = Name_Generic_Elementary_Functions
+ then
+ return True;
+ end if;
+ end if;
+ end if;
+
+ return False;
+ end Is_Elementary_Function_Call;
+
+ -- Start of processing for Analyze_Dimension_Function_Call
+
+ begin
+ -- Elementary function case
+
+ if Is_Elementary_Function_Call (N) then
+
+ -- Sqrt function call case
+
+ if Chars (Name_Call) = Name_Sqrt then
+ Dims := Get_Dimensions (First (Par_Ass));
+
+ if Present (Dims) then
+ for Dim in Dims'Range loop
+ Dims (Dim) := Dims (Dim) * (1, 2);
+ end loop;
+
+ Set_Dimensions (N, Dims);
+ end if;
+
+ -- All other functions in Ada.Numerics.Generic_Elementary_Functions
+ -- Note that all parameters here should be dimensionless
+
+ else
+ Param := First (Par_Ass);
+
+ while Present (Param) loop
+ Dims_Param := Get_Dimensions (Param);
+
+ if Present (Dims_Param) then
+ Error_Msg_Name_1 := Chars (Name_Call);
+ Error_Msg_N
+ ("?parameter should be dimensionless for elementary " &
+ "function%",
+ Param);
+ return;
+ end if;
+
+ Next (Param);
+ end loop;
+ end if;
+
+ -- General case
+
+ else
+ Analyze_Dimension_Has_Etype (N);
+ end if;
+ end Analyze_Dimension_Function_Call;
+
+ ---------------------------------
+ -- Analyze_Dimension_Has_Etype --
+ ---------------------------------
+
+ procedure Analyze_Dimension_Has_Etype (N : Node_Id) is
+ E_Typ : constant Entity_Id := Etype (N);
+ Dims : constant Dimensions := Get_Dimensions (E_Typ);
+ N_Kind : constant Node_Kind := Nkind (N);
+
+ begin
+ -- Propagation of the dimensions from the type
+
+ if Present (Dims) then
+ Set_Dimensions (N, Dims);
+ end if;
+
+ -- Removal of dimensions in expression
+
+ if Nkind_In (N_Kind, N_Attribute_Reference, N_Indexed_Component) then
+ declare
+ Expr : Node_Id;
+ Exprs : constant List_Id := Expressions (N);
+
+ begin
+ if Present (Exprs) then
+ Expr := First (Exprs);
+
+ while Present (Expr) loop
+ Remove_Dimensions (Expr);
+ Next (Expr);
+ end loop;
+ end if;
+ end;
+
+ elsif Nkind_In
+ (N_Kind,
+ N_Qualified_Expression,
+ N_Type_Conversion,
+ N_Unchecked_Type_Conversion)
+ then
+ Remove_Dimensions (Expression (N));
+
+ elsif N_Kind = N_Selected_Component then
+ Remove_Dimensions (Selector_Name (N));
+ end if;
+ end Analyze_Dimension_Has_Etype;
+
+ ----------------------------------
+ -- Analyze_Dimension_Identifier --
+ ----------------------------------
+
+ procedure Analyze_Dimension_Identifier (N : Node_Id) is
+ Ent : constant Entity_Id := Entity (N);
+ Dims : constant Dimensions := Get_Dimensions (Ent);
+
+ begin
+ if Present (Dims) then
+ Set_Dimensions (N, Dims);
+ else
+ Analyze_Dimension_Has_Etype (N);
+ end if;
+ end Analyze_Dimension_Identifier;
+
+ ------------------------------------------
+ -- Analyze_Dimension_Object_Declaration --
+ ------------------------------------------
+
+ procedure Analyze_Dimension_Object_Declaration (N : Node_Id) is
+ Expr : constant Node_Id := Expression (N);
+ Id : constant Entity_Id := Defining_Identifier (N);
+ E_Typ : constant Entity_Id := Etype (Id);
+ Dim_T : constant Dimensions := Get_Dimensions (E_Typ);
+ Dim_E : Dimensions;
+
+ begin
+ if Present (Dim_T) then
+ -- Expression is present
+
+ if Present (Expr) then
+ Dim_E := Get_Dimensions (Expr);
+
+ if Present (Dim_E) then
+ -- Return an error if the dimension of the expression and the
+ -- dimension of the type missmatch.
+
+ if Dim_E /= Dim_T then
+ Error_Msg_N ("?dimensions missmatch in object " &
+ "declaration", N);
+ end if;
+
+ -- If the expression is dimensionless
+
+ else
+ -- If the node is not a real constant or an integer constant
+ -- (depending on the dimensioned numeric type), return an error
+ -- message.
+
+ if not Nkind_In
+ (Original_Node (Expr),
+ N_Real_Literal,
+ N_Integer_Literal)
+ then
+ Error_Msg_N ("?dimensions missmatch in object " &
+ "declaration", N);
+ end if;
+ end if;
+
+ -- For every other cases, propagate the dimensions
+
+ else
+ Copy_Dimensions (E_Typ, Id);
+ end if;
+ end if;
+ end Analyze_Dimension_Object_Declaration;
+
+ ---------------------------------------------------
+ -- Analyze_Dimension_Object_Renaming_Declaration --
+ ---------------------------------------------------
+
+ procedure Analyze_Dimension_Object_Renaming_Declaration (N : Node_Id) is
+ Id : constant Entity_Id := Defining_Identifier (N);
+ Ren_Id : constant Node_Id := Name (N);
+ E_Typ : constant Entity_Id := Etype (Ren_Id);
+ Dims_Typ : constant Dimensions := Get_Dimensions (E_Typ);
+
+ begin
+ if Present (Dims_Typ) then
+ Copy_Dimensions (E_Typ, Id);
+ end if;
+ end Analyze_Dimension_Object_Renaming_Declaration;
+
+ -----------------------------------------------
+ -- Analyze_Dimension_Simple_Return_Statement --
+ -----------------------------------------------
+
+ procedure Analyze_Dimension_Simple_Return_Statement (N : Node_Id) is
+ Expr : constant Node_Id := Expression (N);
+ Dims_Expr : constant Dimensions := Get_Dimensions (Expr);
+ R_Ent : constant Entity_Id := Return_Statement_Entity (N);
+ R_Etyp : constant Entity_Id := Etype (Return_Applies_To (R_Ent));
+ Dims_R : constant Dimensions := Get_Dimensions (R_Etyp);
+
+ begin
+ if Dims_R /= Dims_Expr then
+ Error_Msg_N ("?dimensions missmatch in return statement", N);
+ Remove_Dimensions (Expr);
+ end if;
+ end Analyze_Dimension_Simple_Return_Statement;
+
+ -------------------------------------------
+ -- Analyze_Dimension_Subtype_Declaration --
+ -------------------------------------------
+
+ procedure Analyze_Dimension_Subtype_Declaration (N : Node_Id) is
+ Ent : constant Entity_Id := Defining_Identifier (N);
+ Dims_Ent : constant Dimensions := Get_Dimensions (Ent);
+ E_Typ : Node_Id;
+
+ begin
+ if Nkind (Subtype_Indication (N)) /= N_Subtype_Indication then
+ E_Typ := Etype (Subtype_Indication (N));
+ declare
+ Dims_Typ : constant Dimensions := Get_Dimensions (E_Typ);
+
+ begin
+ if Present (Dims_Typ) then
+
+ -- If the subtype already has a dimension (from
+ -- Aspect_Dimension), it cannot inherit a dimension from its
+ -- subtype.
+
+ if Present (Dims_Ent) then
+ Error_Msg_N ("?subtype& already has a dimension", N);
+
+ else
+ Set_Dimensions (Ent, Dims_Typ);
+ Set_Dimensions_String_Id
+ (Ent, Get_Dimensions_String_Id (E_Typ));
+ end if;
+ end if;
+ end;
+
+ else
+ E_Typ := Etype (Subtype_Mark (Subtype_Indication (N)));
+ declare
+ Dims_Typ : constant Dimensions := Get_Dimensions (E_Typ);
+
+ begin
+ if Present (Dims_Typ) then
+
+ -- If the subtype already has a dimension (from
+ -- Aspect_Dimension), it cannot inherit a dimension from its
+ -- subtype.
+
+ if Present (Dims_Ent) then
+ Error_Msg_N ("?subtype& already has a dimension", N);
+
+ else
+ Set_Dimensions (Ent, Dims_Typ);
+ Set_Dimensions_String_Id
+ (Ent, Get_Dimensions_String_Id (E_Typ));
+ end if;
+ end if;
+ end;
+ end if;
+ end Analyze_Dimension_Subtype_Declaration;
+
+ --------------------------------
+ -- Analyze_Dimension_Unary_Op --
+ --------------------------------
+
+ procedure Analyze_Dimension_Unary_Op (N : Node_Id) is
+ begin
+ case Nkind (N) is
+ when N_Op_Plus | N_Op_Minus | N_Op_Abs =>
+ declare
+ R : constant Node_Id := Right_Opnd (N);
+
+ begin
+ -- Propagate the dimension if the operand is not dimensionless
+
+ Move_Dimensions (R, N);
+ end;
+
+ when others => null;
+
+ end case;
+ end Analyze_Dimension_Unary_Op;
+
+ ---------------------
+ -- Copy_Dimensions --
+ ---------------------
+
+ procedure Copy_Dimensions (From, To : Node_Id) is
+ Dims : constant Dimensions := Aspect_Dimension_Hash_Table.Get (From);
+
+ begin
+ -- Propagate the dimension from one node to another
+
+ pragma Assert (Permits_Dimensions (To));
+ pragma Assert (Present (Dims));
+ Aspect_Dimension_Hash_Table.Set (To, Dims);
+ end Copy_Dimensions;
+
+ -------------------------------
+ -- Create_Rational_From_Expr --
+ -------------------------------
+
+ procedure Create_Rational_From_Expr (Expr : Node_Id; R : in out Rational) is
+ Or_N : constant Node_Id := Original_Node (Expr);
+ Left : Node_Id;
+ Left_Int : Int;
+ Ltype : Entity_Id;
+ Right : Node_Id;
+ Right_Int : Int;
+ R_Opnd_Minus : Node_Id;
+ Rtype : Entity_Id;
+
+ begin
+ -- A rational number is any number that can be expressed as the quotient
+ -- or fraction a/b of two integers, with the denominator b not equal to
+ -- zero.
+
+ -- Check the expression is either a division of two integers or an
+ -- integer itself. The check applies to the original node since the
+ -- node could have already been rewritten.
+
+ -- Numerator is positive
+
+ if Nkind (Or_N) = N_Op_Divide then
+ Left := Left_Opnd (Or_N);
+ Ltype := Etype (Left);
+ Right := Right_Opnd (Or_N);
+ Rtype := Etype (Right);
+
+ if Is_Integer_Type (Ltype)
+ and then Is_Integer_Type (Rtype)
+ then
+ Left_Int := UI_To_Int (Expr_Value (Left));
+ Right_Int := UI_To_Int (Expr_Value (Right));
+
+ -- Verify that the denominator of the rational is positive
+
+ if Right_Int > 0 then
+
+ if Left_Int mod Right_Int = 0 then
+ R := +Whole (UI_To_Int (Expr_Value (Expr)));
+ else
+ R := Whole (Left_Int) / Whole (Right_Int);
+ end if;
+
+ else
+ Error_Msg_N
+ ("denominator in a rational number must be positive", Right);
+ end if;
+
+ else
+ Error_Msg_N ("must be a rational", Expr);
+ end if;
+
+ -- Numerator is negative
+
+ elsif Nkind (Or_N) = N_Op_Minus
+ and then Nkind (Original_Node (Right_Opnd (Or_N))) = N_Op_Divide
+ then
+ R_Opnd_Minus := Original_Node (Right_Opnd (Or_N));
+ Left := Left_Opnd (R_Opnd_Minus);
+ Ltype := Etype (Left);
+ Right := Right_Opnd (R_Opnd_Minus);
+ Rtype := Etype (Right);
+
+ if Is_Integer_Type (Ltype)
+ and then Is_Integer_Type (Rtype)
+ then
+ Left_Int := UI_To_Int (Expr_Value (Left));
+ Right_Int := UI_To_Int (Expr_Value (Right));
+
+ -- Verify that the denominator of the rational is positive
+
+ if Right_Int > 0 then
+
+ if Left_Int mod Right_Int = 0 then
+ R := +Whole (-UI_To_Int (Expr_Value (Expr)));
+ else
+ R := Whole (-Left_Int) / Whole (Right_Int);
+ end if;
+
+ else
+ Error_Msg_N
+ ("denominator in a rational number must be positive", Right);
+ end if;
+
+ else
+ Error_Msg_N ("must be a rational", Expr);
+ end if;
+
+ -- Integer case
+
+ else
+ if Is_Integer_Type (Etype (Expr)) then
+ Right_Int := UI_To_Int (Expr_Value (Expr));
+ R := +Whole (Right_Int);
+ else
+ Error_Msg_N ("must be a rational", Expr);
+ end if;
+ end if;
+ end Create_Rational_From_Expr;
+
+ ----------------------------------------
+ -- Eval_Op_Expon_For_Dimensioned_Type --
+ ----------------------------------------
+
+ -- Eval the expon operator for dimensioned type
+
+ -- Note that if the exponent is an integer (denominator equals to 1) the
+ -- node is not evaluated here and must be evaluated by the Eval_Op_Expon
+ -- routine.
+
+ procedure Eval_Op_Expon_For_Dimensioned_Type
+ (N : Node_Id;
+ B_Typ : Entity_Id)
+ is
+ R : constant Node_Id := Right_Opnd (N);
+ Rat : Rational := Zero_Rational;
+
+ begin
+ if Compile_Time_Known_Value (R)
+ and then Is_Real_Type (B_Typ)
+ then
+ Create_Rational_From_Expr (R, Rat);
+ Eval_Op_Expon_With_Rational_Exponent (N, Rat);
+ end if;
+ end Eval_Op_Expon_For_Dimensioned_Type;
+
+ ------------------------------------------
+ -- Eval_Op_Expon_With_Rational_Exponent --
+ ------------------------------------------
+
+ -- For dimensioned operand in exponentiation, exponent is allowed to be a
+ -- Rational and not only an Integer like for dimensionless operands. For
+ -- that particular case, the left operand is rewritten as a function call
+ -- using the function Expon_LLF from s-llflex.ads.
+
+ procedure Eval_Op_Expon_With_Rational_Exponent
+ (N : Node_Id;
+ Rat : Rational)
+ is
+ Dims : constant Dimensions := Get_Dimensions (N);
+ L : constant Node_Id := Left_Opnd (N);
+ Etyp : constant Entity_Id := Etype (L);
+ Loc : constant Source_Ptr := Sloc (N);
+ Actual_1 : Node_Id;
+ Actual_2 : Node_Id;
+ Base_Typ : Entity_Id;
+ Dim_Value : Rational;
+ List_Of_Dims : List_Id;
+ New_Aspect : Node_Id;
+ New_Aspects : List_Id;
+ New_E : Entity_Id;
+ New_N : Node_Id;
+ New_Typ_L : Node_Id;
+ Sys : Dim_Sys_Id;
+
+ begin
+ -- If Rat.Denominator = 1 that means the exponent is an Integer so
+ -- nothing has to be changed.
+ -- Note that the node must come from source
+
+ if Comes_From_Source (N)
+ and then Rat.Denominator /= 1
+ then
+ Base_Typ := Base_Type (Etyp);
+
+ -- Case when the operand is not dimensionless
+
+ if Present (Dims) then
+
+ -- Get the corresponding Dim_Sys_Id to know the exact number of
+ -- dimensions in the system.
+
+ Sys := Get_Dimension_System_Id (Base_Typ);
+
+ -- Step 1: Generation of a new subtype with the proper dimensions
+
+ -- In order to rewrite the operator as a function call, a new
+ -- subtype with an aspect dimension using the dimensions of the
+ -- node has to be created.
+
+ -- Generate:
+
+ -- Base_Typ : constant Entity_Id := Base_Type (Etyp);
+ -- Sys : constant Dim_Sys_Id :=
+ -- Get_Dimension_System_Id (Base_Typ);
+ -- N_Dims : constant N_Of_Dimensions :=
+ -- Dim_Systems.Table (Sys).N_Of_Dims;
+ -- Dim_Value : Rational;
+
+ -- Aspect_Dim_Expr : List;
+
+ -- Append ("", Aspect_Dim_Expr);
+
+ -- for Dim in Dims'First .. N_Dims loop
+ -- Dim_Value := Dims (Dim);
+ -- if Dim_Value.Denominator /= 1 then
+ -- Append (Dim_Value.Numerator / Dim_Value.Denominator,
+ -- Aspect_Dim_Expr);
+ -- else
+ -- Append (Dim_Value.Numerator, Aspect_Dim_Expr);
+ -- end if;
+ -- end loop;
+
+ -- subtype T is Base_Typ with Dimension => Aspect_Dim_Expr;
+
+ -- Step 1a: Generate the aggregate for the new Aspect_dimension
+
+ New_Aspects := Empty_List;
+ List_Of_Dims := New_List;
+
+ Append (Make_String_Literal (Loc, No_String), List_Of_Dims);
+
+ for Dim in Dims'First .. Dim_Systems.Table (Sys).N_Of_Dims loop
+ Dim_Value := Dims (Dim);
+ if Dim_Value.Denominator /= 1 then
+ Append (
+ Make_Op_Divide (Loc,
+ Left_Opnd =>
+ Make_Integer_Literal (Loc,
+ Int (Dim_Value.Numerator)),
+ Right_Opnd =>
+ Make_Integer_Literal (Loc,
+ Int (Dim_Value.Denominator))),
+ List_Of_Dims);
+ else
+ Append (
+ Make_Integer_Literal (Loc,
+ Int (Dim_Value.Numerator)),
+ List_Of_Dims);
+ end if;
+ end loop;
+
+ -- Step 1b: Create the new Aspect_Dimension
+
+ New_Aspect :=
+ Make_Aspect_Specification (Loc,
+ Identifier =>
+ Make_Identifier (Loc, Name_Dimension),
+ Expression =>
+ Make_Aggregate (Loc,
+ Expressions => List_Of_Dims));
+
+ -- Step 1c: New identifier for the subtype
+
+ New_E := Make_Temporary (Loc, 'T');
+ Set_Is_Internal (New_E);
+
+ -- Step 1d: Declaration of the new subtype
+
+ New_Typ_L :=
+ Make_Subtype_Declaration (Loc,
+ Defining_Identifier => New_E,
+ Subtype_Indication =>
+ New_Occurrence_Of (Base_Typ, Loc));
+
+ Append (New_Aspect, New_Aspects);
+ Set_Parent (New_Aspects, New_Typ_L);
+ Set_Aspect_Specifications (New_Typ_L, New_Aspects);
+
+ Analyze (New_Typ_L);
+
+ -- Case where the operand is dimensionless
+
+ else
+ New_E := Base_Typ;
+ end if;
+
+ -- Step 2: Generation of the function call
+
+ -- Generate:
+
+ -- Actual_1 := Long_Long_Float (L),
+
+ -- Actual_2 := Long_Long_Float (Rat.Numerator) /
+ -- Long_Long_Float (Rat.Denominator);
+
+ -- (T (Expon_LLF (Actual_1, Actual_2)));
+
+ -- -- where T is the subtype declared in step 1
+
+ -- -- The node is rewritten as a type conversion
+
+ -- Step 2a: Creation of the two parameters for function Expon_LLF
+
+ Actual_1 :=
+ Make_Type_Conversion (Loc,
+ Subtype_Mark => New_Reference_To (Standard_Long_Long_Float, Loc),
+ Expression => Relocate_Node (L));
+
+ Actual_2 :=
+ Make_Op_Divide (Loc,
+ Left_Opnd =>
+ Make_Real_Literal (Loc,
+ UR_From_Uint (UI_From_Int (Int (Rat.Numerator)))),
+ Right_Opnd =>
+ Make_Real_Literal (Loc,
+ UR_From_Uint (UI_From_Int (Int (Rat.Denominator)))));
+
+ -- Step 2b: New Node N
+
+ New_N :=
+ Make_Type_Conversion (Loc,
+ Subtype_Mark => New_Reference_To (New_E, Loc),
+ Expression =>
+ Make_Function_Call (Loc,
+ Name => New_Reference_To (RTE (RE_Expon_LLF), Loc),
+ Parameter_Associations => New_List (
+ Actual_1, Actual_2)));
+
+ -- Step 3: Rewitten of N
+
+ Rewrite (N, New_N);
+ Set_Etype (N, New_E);
+ Analyze_And_Resolve (N, New_E);
+ end if;
+ end Eval_Op_Expon_With_Rational_Exponent;
+
+ -------------------------------------------
+ -- Expand_Put_Call_With_Dimension_String --
+ -------------------------------------------
+
+ -- For procedure Put defined in System.Dim_Float_IO and
+ -- System.Dim_Integer_IO, the default string parameter must be rewritten to
+ -- include the dimension symbols in the output of a dimensioned object.
+
+ -- There are two different cases:
+
+ -- 1) If the parameter is a variable, the default string parameter is
+ -- replaced by the string defined in the aspect Dimension of the subtype.
+ -- For instance if the user wants to output a speed:
+
+ -- subtype Speed is Mks_Type with Dimension =>
+ -- ("speed", Meter => 1, Second => -1, others => 0);
+ -- v : Speed := 2.1 * m * s**(-1);
+
+ -- Put (v) returns:
+ -- > 2.1 speed
+
+ -- 2) If the parameter is an expression, the procedure
+ -- Expand_Put_Call_With_Dimension_String creates the string (for instance
+ -- "m.s**(-1)") and rewrites the default string parameter of Put with the
+ -- corresponding the String_Id.
+
+ procedure Expand_Put_Call_With_Dimension_String (N : Node_Id) is
+ Actuals : constant List_Id := Parameter_Associations (N);
+ Loc : constant Source_Ptr := Sloc (N);
+ Name_Call : constant Node_Id := Name (N);
+ Actual : Node_Id;
+ Base_Typ : Node_Id;
+ Char_Pack : Name_Id;
+ Dims : Dimensions;
+ Etyp : Entity_Id;
+ First_Actual : Node_Id;
+ New_Par_Ass : List_Id;
+ New_Str_Lit : Node_Id;
+ Sys : Dim_Sys_Id;
+
+ function Is_Procedure_Put_Call (N : Node_Id) return Boolean;
+ -- Return True if the current call is a call of an instantiation of a
+ -- procedure Put defined in the package System.Dim_Float_IO and
+ -- System.Dim_Integer_IO.
+
+ function Is_Procedure_Put_Call (N : Node_Id) return Boolean is
+ Name_Call : constant Node_Id := Name (N);
+ Ent : Entity_Id;
+
+ begin
+ -- There are three different Put routine in each generic package
+ -- Check that the current procedure call is one of them
+
+ if Is_Entity_Name (Name_Call) then
+ Ent := Entity (Name_Call);
+
+ -- Check that the name of the procedure is Put
+
+ if Chars (Name_Call) /= Name_Put then
+ return False;
+ end if;
+
+ -- Check the procedure is defined in an instantiation of a
+ -- generic package.
+
+ if Is_Generic_Instance (Scope (Ent)) then
+ Ent := Cunit_Entity (Get_Source_Unit (Ent));
+
+ -- Verify that the generic package is System.Dim_Float_IO or
+ -- System.Dim_Integer_IO.
+
+ if Is_Library_Level_Entity (Ent) then
+ Char_Pack := Chars (Ent);
+
+ if Char_Pack = Name_Dim_Float_IO
+ or else Char_Pack = Name_Dim_Integer_IO
+ then
+ return True;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ return False;
+ end Is_Procedure_Put_Call;
+
+ -- Start of processing for Expand_Put_Call_With_Dimension_String
+
+ begin
+ if Is_Procedure_Put_Call (N) then
+
+ -- Get the first parameter
+
+ First_Actual := First (Actuals);
+
+ -- Case when the Put routine has four (integer case) or five (float
+ -- case) parameters.
+
+ if List_Length (Actuals) = 5
+ or else List_Length (Actuals) = 4
+ then
+ Actual := Next (First_Actual);
+
+ if Nkind (Actual) = N_Parameter_Association then
+
+ -- Get the dimensions and the corresponding dimension system
+ -- from the first actual.
+
+ Actual := First_Actual;
+ end if;
+
+ -- Case when the Put routine has six parameters
+
+ else
+ Actual := Next (First_Actual);
+ end if;
+
+ Base_Typ := Base_Type (Etype (Actual));
+ Sys := Get_Dimension_System_Id (Base_Typ);
+
+ if Sys /= No_Dim_Sys then
+ Dims := Get_Dimensions (Actual);
+ Etyp := Etype (Actual);
+
+ -- Add the string as a suffix of the value if the subtype has a
+ -- string of dimensions or if the parameter is not dimensionless.
+
+ if Present (Dims)
+ or else Get_Dimensions_String_Id (Etyp) /= No_String
+ then
+ New_Par_Ass := New_List;
+
+ -- Add to the list First_Actual and Actual if they differ
+
+ if Actual /= First_Actual then
+ Append (New_Copy (First_Actual), New_Par_Ass);
+ end if;
+
+ Append (New_Copy (Actual), New_Par_Ass);
+
+ -- Look to the next parameter
+
+ Next (Actual);
+
+ -- Check if the type of N is a subtype that has a string of
+ -- dimensions in Aspect_Dimension_String_Id_Hash_Table.
+
+ if Get_Dimensions_String_Id (Etyp) /= No_String then
+ Start_String;
+
+ -- Put a space between the value and the dimension
+
+ Store_String_Char (' ');
+ Store_String_Chars (Get_Dimensions_String_Id (Etyp));
+ New_Str_Lit :=
+ Make_String_Literal (Loc, End_String);
+
+ -- Rewrite the String_Literal of the second actual with the
+ -- new String_Id created by the routine
+ -- From_Dimension_To_String.
+
+ else
+ New_Str_Lit :=
+ Make_String_Literal (Loc,
+ From_Dimension_To_String_Id (Dims, Sys));
+ end if;
+
+ Append (New_Str_Lit, New_Par_Ass);
+
+ -- Rewrite the procedure call with the new list of parameters
+
+ Rewrite (N,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Copy (Name_Call),
+ Parameter_Associations => New_Par_Ass));
+
+ Analyze (N);
+ end if;
+ end if;
+ end if;
+ end Expand_Put_Call_With_Dimension_String;
+
+ ---------------------------------
+ -- From_Dimension_To_String_Id --
+ ---------------------------------
+
+ -- Given a dimension vector and the corresponding dimension system, create
+ -- a String_Id to output the dimension symbols corresponding to the
+ -- dimensions Dims.
+
+ function From_Dimension_To_String_Id
+ (Dims : Dimensions;
+ Sys : Dim_Sys_Id) return String_Id
+ is
+ Dim_Rat : Rational;
+ First_Dim_In_Str : Boolean := True;
+
+ begin
+ -- Initialization of the new String_Id
+
+ Start_String;
+
+ -- Put a space between the value and the dimensions
+
+ Store_String_Char (' ');
+
+ for Dim in Dimensions'Range loop
+
+ Dim_Rat := Dims (Dim);
+ if Dim_Rat /= Zero_Rational then
+
+ if First_Dim_In_Str then
+ First_Dim_In_Str := False;
+ else
+ Store_String_Char ('.');
+ end if;
+
+ -- Positive dimension case
+
+ if Dim_Rat.Numerator > 0 then
+
+ if Dim_Systems.Table (Sys).Symbols (Dim) = No_String then
+ Store_String_Chars
+ (Get_Name_String (Dim_Systems.Table (Sys).Names (Dim)));
+ else
+ Store_String_Chars (Dim_Systems.Table (Sys).Symbols (Dim));
+ end if;
+
+ -- Integer case
+
+ if Dim_Rat.Denominator = 1 then
+
+ if Dim_Rat.Numerator /= 1 then
+ Store_String_Chars ("**");
+ Store_String_Int (Int (Dim_Rat.Numerator));
+ end if;
+
+ -- Rational case when denominator /= 1
+
+ else
+ Store_String_Chars ("**");
+ Store_String_Char ('(');
+ Store_String_Int (Int (Dim_Rat.Numerator));
+ Store_String_Char ('/');
+ Store_String_Int (Int (Dim_Rat.Denominator));
+ Store_String_Char (')');
+ end if;
+
+ -- Negative dimension case
+
+ else
+ if Dim_Systems.Table (Sys).Symbols (Dim) = No_String then
+ Store_String_Chars
+ (Get_Name_String (Dim_Systems.Table (Sys).Names (Dim)));
+ else
+ Store_String_Chars (Dim_Systems.Table (Sys).Symbols (Dim));
+ end if;
+
+ Store_String_Chars ("**");
+ Store_String_Char ('(');
+ Store_String_Char ('-');
+ Store_String_Int (Int (-Dim_Rat.Numerator));
+
+ -- Integer case
+
+ if Dim_Rat.Denominator = 1 then
+ Store_String_Char (')');
+
+ -- Rational case when denominator /= 1
+
+ else
+ Store_String_Char ('/');
+ Store_String_Int (Int (Dim_Rat.Denominator));
+ Store_String_Char (')');
+ end if;
+ end if;
+ end if;
+ end loop;
+
+ return End_String;
+ end From_Dimension_To_String_Id;
+
+ --------------------
+ -- Get_Dimensions --
+ --------------------
+
+ function Get_Dimensions (N : Node_Id) return Dimensions is
+ begin
+ return Aspect_Dimension_Hash_Table.Get (N);
+ end Get_Dimensions;
+
+ ------------------------------
+ -- Get_Dimensions_String_Id --
+ ------------------------------
+
+ function Get_Dimensions_String_Id (E : Entity_Id) return String_Id is
+ begin
+ return Aspect_Dimension_String_Id_Hash_Table.Get (E);
+ end Get_Dimensions_String_Id;
+
+ -----------------------------
+ -- Get_Dimension_System_Id --
+ -----------------------------
+
+ function Get_Dimension_System_Id (E : Entity_Id) return Dim_Sys_Id is
+ D_Sys : Dim_Sys_Id := No_Dim_Sys;
+
+ begin
+ -- Scan the Table in order to find N
+
+ for Dim_Sys in 1 .. Dim_Systems.Last loop
+ if Parent (E) = Dim_Systems.Table (Dim_Sys).Base_Type then
+ D_Sys := Dim_Sys;
+ end if;
+ end loop;
+
+ return D_Sys;
+ end Get_Dimension_System_Id;
+
+ --------------------------
+ -- Is_Dimensioned_Type --
+ --------------------------
+
+ function Is_Dimensioned_Type (E : Entity_Id) return Boolean
+ is
+ begin
+ if Get_Dimension_System_Id (E) /= No_Dim_Sys then
+ return True;
+ end if;
+
+ return False;
+ end Is_Dimensioned_Type;
+
+ ---------------------
+ -- Move_Dimensions --
+ ---------------------
+
+ procedure Move_Dimensions (From, To : Node_Id) is
+ Dims : constant Dimensions := Get_Dimensions (From);
+
+ begin
+ -- Copy the dimension of 'From to 'To' and remove the dimension of
+ -- 'From'.
+
+ if Present (Dims) then
+ Set_Dimensions (To, Dims);
+ Remove_Dimensions (From);
+ end if;
+ end Move_Dimensions;
+
+ ------------------------
+ -- Permits_Dimensions --
+ ------------------------
+
+ -- Here is the list of node that permits a dimension
+
+ Dimensions_Permission : constant array (Node_Kind) of Boolean :=
+ (N_Attribute_Reference => True,
+ N_Defining_Identifier => True,
+ N_Function_Call => True,
+ N_Identifier => True,
+ N_Indexed_Component => True,
+ N_Integer_Literal => True,
+
+ N_Op_Abs => True,
+ N_Op_Add => True,
+ N_Op_Divide => True,
+ N_Op_Expon => True,
+ N_Op_Minus => True,
+ N_Op_Mod => True,
+ N_Op_Multiply => True,
+ N_Op_Plus => True,
+ N_Op_Rem => True,
+ N_Op_Subtract => True,
+
+ N_Qualified_Expression => True,
+ N_Real_Literal => True,
+ N_Selected_Component => True,
+ N_Slice => True,
+ N_Type_Conversion => True,
+ N_Unchecked_Type_Conversion => True,
+
+ others => False);
+
+ function Permits_Dimensions (N : Node_Id) return Boolean is
+ begin
+ return Dimensions_Permission (Nkind (N));
+ end Permits_Dimensions;
+
+ -------------
+ -- Present --
+ -------------
+
+ function Present (Dim : Dimensions) return Boolean is
+ begin
+ return Dim /= Zero_Dimensions;
+ end Present;
+
+ -----------------------
+ -- Remove_Dimensions --
+ -----------------------
+
+ procedure Remove_Dimensions (N : Node_Id) is
+ Dims : constant Dimensions := Get_Dimensions (N);
+
+ begin
+ if Present (Dims) then
+ Aspect_Dimension_Hash_Table.Remove (N);
+ end if;
+ end Remove_Dimensions;
+
+ ------------------------------
+ -- Remove_Dimension_In_Call --
+ ------------------------------
+
+ procedure Remove_Dimension_In_Call (N : Node_Id) is
+ Actual : Node_Id;
+ Par_Ass : constant List_Id := Parameter_Associations (N);
+
+ begin
+ if Ada_Version < Ada_2012 then
+ return;
+ end if;
+
+ if Present (Par_Ass) then
+ Actual := First (Par_Ass);
+
+ while Present (Actual) loop
+ Remove_Dimensions (Actual);
+ Next (Actual);
+ end loop;
+ end if;
+ end Remove_Dimension_In_Call;
+
+ -------------------------------------
+ -- Remove_Dimension_In_Declaration --
+ -------------------------------------
+
+ -- Removal of dimension in expressions of N_Object_Declaration and
+ -- N_Component_Declaration as part of the Analyze_Declarations routine
+ -- (see package Sem_Ch3).
+
+ procedure Remove_Dimension_In_Declaration (D : Node_Id) is
+ begin
+ if Ada_Version < Ada_2012 then
+ return;
+ end if;
+
+ if Nkind_In (D, N_Object_Declaration, N_Component_Declaration) then
+ if Present (Expression (D)) then
+ Remove_Dimensions (Expression (D));
+ end if;
+ end if;
+ end Remove_Dimension_In_Declaration;
+
+ -----------------------------------
+ -- Remove_Dimension_In_Statement --
+ -----------------------------------
+
+ -- Removal of dimension in statement as part of the Analyze_Statements
+ -- routine (see package Sem_Ch5).
+
+ procedure Remove_Dimension_In_Statement (S : Node_Id) is
+ S_Kind : constant Node_Kind := Nkind (S);
+
+ begin
+ if Ada_Version < Ada_2012 then
+ return;
+ end if;
+
+ -- Remove dimension in parameter specifications for accept statement
+
+ if S_Kind = N_Accept_Statement then
+ declare
+ Param : Node_Id := First (Parameter_Specifications (S));
+
+ begin
+ while Present (Param) loop
+ Remove_Dimensions (Param);
+ Next (Param);
+ end loop;
+ end;
+
+ -- Remove dimension of name and expression in assignments
+
+ elsif S_Kind = N_Assignment_Statement then
+ Remove_Dimensions (Expression (S));
+ Remove_Dimensions (Name (S));
+ end if;
+ end Remove_Dimension_In_Statement;
+
+ --------------------
+ -- Set_Dimensions --
+ --------------------
+
+ procedure Set_Dimensions (N : Node_Id; Dims : Dimensions) is
+ begin
+ pragma Assert (Permits_Dimensions (N));
+ pragma Assert (Present (Dims));
+ Aspect_Dimension_Hash_Table.Set (N, Dims);
+ end Set_Dimensions;
+
+ ------------------------------
+ -- Set_Dimensions_String_Id --
+ ------------------------------
+
+ procedure Set_Dimensions_String_Id (E : Entity_Id; Str : String_Id) is
+ begin
+ Aspect_Dimension_String_Id_Hash_Table.Set (E, Str);
+ end Set_Dimensions_String_Id;
+
+end Sem_Dim;
diff --git a/gcc/ada/sem_dim.ads b/gcc/ada/sem_dim.ads
new file mode 100644
index 00000000000..8089f432160
--- /dev/null
+++ b/gcc/ada/sem_dim.ads
@@ -0,0 +1,150 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S E M _ D I M --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 1992-2011, 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. --
+-- --
+------------------------------------------------------------------------------
+
+-- This new package of the GNAT compiler has been created in order to enable
+-- any user of the GNAT compiler to deal with physical issues.
+
+-- Indeed, the user is now able to create his own dimension system and to
+-- assign a dimension, defined from the MKS system (package System.Dim_Mks)
+-- or his own dimension systems, with any item and to run operations with
+-- dimensionned entities.
+-- In that case, a dimensionnality checking will be performed at compile time.
+-- If no dimension has been assigned, the compiler assumes that the item is
+-- dimensionless.
+
+-----------------------------
+-- Aspect_Dimension_System --
+-----------------------------
+
+-- In order to enable the user to create his own dimension system, a new
+-- aspect: Aspect_Dimension_System has been created.
+-- Note that this aspect applies for type declaration of type derived from any
+-- numeric type.
+
+-- It defines the names of each dimension.
+
+----------------------
+-- Aspect_Dimension --
+----------------------
+
+-- This new aspect applies for subtype and object declarations in order to
+-- define new dimensions.
+-- Using this aspect, the user is able to create new subtype/object with any
+-- dimension needed.
+-- Note that the base type of the subtype/object must be the type that defines
+-- the corresponding dimension system.
+
+-- The expression of this aspect is an aggregate of rational values for each
+-- dimension in the corresponding dimension system.
+
+-------------------------------------------
+-- Dimensionality checking & propagation --
+-------------------------------------------
+
+-- For each node (when needed), a dimension analysis (Analyze_Dimension) is
+-- performed as part of the Resolution routine or the Analysis routine if no
+-- Resolution.
+
+-- The dimension analysis is divided into two phases:
+
+-- Phase 1: dimension checking
+
+-- Phase 2: propagation of dimensions
+
+-- Depending on the node kind, either none, one phase or two phases are
+-- executed.
+-- Phase 2 is called only when the node allows a dimension (see body of
+-- Sem_Dim to get the list of nodes that permit dimensions).
+
+------------------
+-- Dimension_IO --
+------------------
+
+-- This section contains the routine used for IO purposes.
+
+with Types; use Types;
+
+package Sem_Dim is
+
+ -----------------------------
+ -- Aspect_Dimension_System --
+ -----------------------------
+
+ procedure Analyze_Aspect_Dimension_System
+ (N : Node_Id;
+ Id : Node_Id;
+ Expr : Node_Id);
+ -- Analyzes the aggregate of Aspect_Dimension_System
+
+ ----------------------
+ -- Aspect_Dimension --
+ ----------------------
+
+ procedure Analyze_Aspect_Dimension
+ (N : Node_Id;
+ Id : Node_Id;
+ Expr : Node_Id);
+ -- Analyzes the aggregate of Aspect_Dimension and attaches the
+ -- corresponding dimension to N.
+
+ -------------------------------------------
+ -- Dimensionality checking & propagation --
+ -------------------------------------------
+
+ procedure Analyze_Dimension (N : Node_Id);
+ -- Performs a dimension analysis and propagates dimension between nodes
+ -- when needed.
+
+ procedure Eval_Op_Expon_For_Dimensioned_Type
+ (N : Node_Id;
+ B_Typ : Entity_Id);
+ -- Eval the Expon operator for dimensioned type with rational exponent
+
+ function Is_Dimensioned_Type (E : Entity_Id) return Boolean;
+ -- Return True if the type is a dimensioned type (i.e: a type which has an
+ -- aspect Dimension_System)
+
+ procedure Remove_Dimension_In_Call (N : Node_Id);
+ -- At the end of the Expand_Call routine, remove the dimensions of every
+ -- parameters in the call N.
+
+ procedure Remove_Dimension_In_Declaration (D : Node_Id);
+ -- At the end of Analyze_Declarations routine (see Sem_Ch3), removes the
+ -- dimension of the expression for each declaration.
+
+ procedure Remove_Dimension_In_Statement (S : Node_Id);
+ -- At the end of the Analyze_Statements routine (see Sem_Ch5), removes the
+ -- dimension for every statements.
+
+ ------------------
+ -- Dimension_IO --
+ ------------------
+
+ procedure Expand_Put_Call_With_Dimension_String (N : Node_Id);
+ -- Expansion of Put call (from package System.Dim_Float_IO and
+ -- System.Dim_Integer_IO) for a dimensioned object in order to add the
+ -- dimension symbols as a suffix of the numeric value.
+
+end Sem_Dim;
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index ad989d2784a..49460d00b96 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -8062,24 +8062,6 @@ package body Sem_Prag is
Default_Pool := Expression (Arg1);
- ---------------
- -- Dimension --
- ---------------
-
- when Pragma_Dimension =>
- GNAT_Pragma;
- Check_Arg_Count (4);
- Check_No_Identifiers;
- Check_Arg_Is_Local_Name (Arg1);
-
- if not Is_Type (Arg1) then
- Error_Pragma ("first argument for pragma% must be subtype");
- end if;
-
- Check_Arg_Is_Static_Expression (Arg2, Standard_Integer);
- Check_Arg_Is_Static_Expression (Arg3, Standard_Integer);
- Check_Arg_Is_Static_Expression (Arg4, Standard_Integer);
-
------------------------------------
-- Disable_Atomic_Synchronization --
------------------------------------
@@ -14956,7 +14938,6 @@ package body Sem_Prag is
Pragma_Debug_Policy => 0,
Pragma_Detect_Blocking => -1,
Pragma_Default_Storage_Pool => -1,
- Pragma_Dimension => -1,
Pragma_Disable_Atomic_Synchronization => -1,
Pragma_Discard_Names => 0,
Pragma_Dispatching_Domain => -1,
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 663e0e8203a..55a5e365904 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -57,6 +57,7 @@ with Sem_Ch4; use Sem_Ch4;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
+with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
with Sem_Dist; use Sem_Dist;
with Sem_Elim; use Sem_Elim;
@@ -2010,6 +2011,7 @@ package body Sem_Res is
if Analyzed (N) then
Debug_A_Exit ("resolving ", N, " (done, already analyzed)");
+ Analyze_Dimension (N);
return;
-- Return if type = Any_Type (previous error encountered)
@@ -4878,6 +4880,7 @@ package body Sem_Res is
end if;
Generate_Operator_Reference (N, Typ);
+ Analyze_Dimension (N);
Eval_Arithmetic_Op (N);
-- In SPARK, a multiplication or division with operands of fixed point
@@ -5808,6 +5811,10 @@ package body Sem_Res is
end;
end if;
+ -- dimension analysis
+
+ Analyze_Dimension (N);
+
-- All done, evaluate call and deal with elaboration issues
Eval_Call (N);
@@ -6004,6 +6011,7 @@ package body Sem_Res is
-- Evaluate the relation (note we do this after the above check since
-- this Eval call may change N to True/False.
+ Analyze_Dimension (N);
Eval_Relational_Op (N);
end Resolve_Comparison_Op;
@@ -6889,6 +6897,7 @@ package body Sem_Res is
or else Is_Intrinsic_Subprogram
(Corresponding_Equality (Entity (N)))
then
+ Analyze_Dimension (N);
Eval_Relational_Op (N);
elsif Nkind (N) = N_Op_Ne
@@ -7143,6 +7152,8 @@ package body Sem_Res is
end loop;
end if;
+ Analyze_Dimension (N);
+
-- Do not generate the warning on suspicious index if we are analyzing
-- package Ada.Tags; otherwise we will report the warning with the
-- Prims_Ptr field of the dispatch table.
@@ -7998,6 +8009,24 @@ package body Sem_Res is
Set_Etype (N, B_Typ);
Generate_Operator_Reference (N, B_Typ);
+
+ Analyze_Dimension (N);
+
+ -- Evaluate the Expon operator for dimensioned type with rational
+ -- exponent.
+
+ if Ada_Version >= Ada_2012
+ and then Is_Dimensioned_Type (B_Typ)
+ then
+ Eval_Op_Expon_For_Dimensioned_Type (N, B_Typ);
+
+ -- Skip the Eval_Op_Expon if the node has already been evaluated
+
+ if Nkind (N) = N_Type_Conversion then
+ return;
+ end if;
+ end if;
+
Eval_Op_Expon (N);
-- Set overflow checking bit. Much cleverer code needed here eventually
@@ -8196,6 +8225,7 @@ package body Sem_Res is
Set_Etype (N, Etype (Expr));
end if;
+ Analyze_Dimension (N);
Eval_Qualified_Expression (N);
end Resolve_Qualified_Expression;
@@ -8629,6 +8659,7 @@ package body Sem_Res is
Error_Msg_N ("?\may cause unexpected accesses to atomic object",
Prefix (N));
end if;
+ Analyze_Dimension (N);
end Resolve_Selected_Component;
-------------------
@@ -8940,6 +8971,7 @@ package body Sem_Res is
Warn_On_Suspicious_Index (Name, High_Bound (Drange));
end if;
+ Analyze_Dimension (N);
Eval_Slice (N);
end Resolve_Slice;
@@ -9346,6 +9378,8 @@ package body Sem_Res is
Check_SPARK_Restriction ("object required", Operand);
end if;
+ Analyze_Dimension (N);
+
-- Note: we do the Eval_Type_Conversion call before applying the
-- required checks for a subtype conversion. This is important, since
-- both are prepared under certain circumstances to change the type
@@ -9629,6 +9663,7 @@ package body Sem_Res is
Check_Unset_Reference (R);
Generate_Operator_Reference (N, B_Typ);
+ Analyze_Dimension (N);
Eval_Unary_Op (N);
-- Set overflow checking bit. Much cleverer code needed here eventually
@@ -9795,6 +9830,7 @@ package body Sem_Res is
-- Resolve operand using its own type
Resolve (Operand, Opnd_Type);
+ Analyze_Dimension (N);
Eval_Unchecked_Conversion (N);
end Resolve_Unchecked_Type_Conversion;
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index d15892a5f02..dd2e5948d3c 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -139,6 +139,8 @@ package Snames is
Name_Default_Value : constant Name_Id := N + $;
Name_Default_Component_Value : constant Name_Id := N + $;
+ Name_Dimension : constant Name_Id := N + $;
+ Name_Dimension_System : constant Name_Id := N + $;
Name_Dynamic_Predicate : constant Name_Id := N + $;
Name_Post : constant Name_Id := N + $;
Name_Pre : constant Name_Id := N + $;
@@ -219,6 +221,14 @@ package Snames is
subtype Text_IO_Package_Name is Name_Id
range First_Text_IO_Package .. Last_Text_IO_Package;
+ -- Names used by the analyzer and expander for aspect Dimension and
+ -- Dimension_System to deal with Sqrt and IO routines.
+
+ Name_Dim_Float_IO : constant Name_Id := N + $; -- Ada 12
+ Name_Dim_Integer_IO : constant Name_Id := N + $; -- Ada 12
+ Name_Generic_Elementary_Functions : constant Name_Id := N + $; -- Ada 12
+ Name_Sqrt : constant Name_Id := N + $; -- Ada 12
+
-- Some miscellaneous names used for error detection/recovery
Name_Const : constant Name_Id := N + $;
@@ -447,7 +457,6 @@ package Snames is
Name_CPP_Vtable : constant Name_Id := N + $; -- GNAT
Name_CPU : constant Name_Id := N + $; -- Ada 12
Name_Debug : constant Name_Id := N + $; -- GNAT
- Name_Dimension : constant Name_Id := N + $; -- GNAT
Name_Elaborate : constant Name_Id := N + $; -- Ada 83
Name_Elaborate_All : constant Name_Id := N + $;
Name_Elaborate_Body : constant Name_Id := N + $;
@@ -1610,7 +1619,6 @@ package Snames is
Pragma_CPP_Vtable,
Pragma_CPU,
Pragma_Debug,
- Pragma_Dimension,
Pragma_Elaborate,
Pragma_Elaborate_All,
Pragma_Elaborate_Body,
OpenPOWER on IntegriCloud