aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2017-01-12 17:01:16 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2017-01-12 17:01:16 +0100
commitca0eb951e3e6cbee039db654df513d823fa86c78 (patch)
tree6947b25f5f34c7ae96aa0a29be8ed4aed928a2e6 /gcc/ada
parent661131664980c54b72c6223a53a464f23b8ec0a3 (diff)
downloadgcc-ca0eb951e3e6cbee039db654df513d823fa86c78.zip
gcc-ca0eb951e3e6cbee039db654df513d823fa86c78.tar.gz
gcc-ca0eb951e3e6cbee039db654df513d823fa86c78.tar.bz2
[multiple changes]
2017-01-12 Tristan Gingold <gingold@adacore.com> * s-mmap.ads, s-mmap.adb, s-mmosin-unix.ads, s-mmosin-unix.adb, s-mmauni-long.ads, s-mmosin-mingw.ads, s-mmosin-mingw.adb: New files. 2017-01-12 Yannick Moy <moy@adacore.com> * errout.adb, errout.ads (Initialize): Factor common treatment in Reset_Warnings. (Reset_Warnings): New procedure to reset counts related to warnings. (Record_Compilation_Errors): New variable to store the presence of an error, used in gnat2why to allow changing the Warning_Mode. (Compilation_Errors): Use new variable Record_Compilation_Errors to store the presence of an error. 2017-01-12 Javier Miranda <miranda@adacore.com> * sem_ch13.adb (Analyze_Aspect_Specifications): For Interrupt_Handler and Attach_ Handler aspects, decorate the internally built reference to the protected procedure as coming from sources and force its analysis. 2017-01-12 Ed Schonberg <schonberg@adacore.com> * sem_ch3.adb (Build_Derived_Type): For a scalar derived type, inherit predicates if any from the first_subtype of the parent, not from the anonymous parent type. * sem_eval.adb (Is_Static_Subtype): A type that inherits a dynamic predicate is not a static subtype. 2017-01-12 Gary Dismukes <dismukes@adacore.com> * freeze.adb (Check_Suspicious_Convention): New procedure performing a warning check on discriminated record types with convention C or C++. Factored out of procedure Freeze_Record_Type, and changed to only apply to base types (to avoid spurious warnings on subtypes). Minor improvement of warning messages to refer to discriminated rather than variant record types. (Freeze_Record_Type): Remove code for performing a suspicious convention check. (Freeze_Entity): Only call Freeze_Record_Type on types that aren't declared within any enclosing generic units (rather than just excluding the type when the innermost scope is generic). Call Check_Suspicious_Convention whether or not the type is declared within a generic unit. * sem_ch8.adb (In_Generic_Scope): Move this function to Sem_Util. * sem_util.ads, sem_util.adb (In_Generic_Scope): New function (moved from Sem_Ch8). 2017-01-12 Tristan Gingold <gingold@adacore.com> * sysdep.c, adaint.c, rtinit.c, ming32.h: (__gnat_current_codepage): Renamed from CurrentCodePage (__gnat_current_ccs_encoding): Renamed from CurrentCCSEncoding 2017-01-12 Ed Schonberg <schonberg@adacore.com> * sem_ch6.adb (Fully_Conformant_Expressions): Handle properly quantified expressions, following AI12-050: the loop parameters of two quantified expressions are conformant if they have the same identifier. From-SVN: r244369
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog62
-rw-r--r--gcc/ada/adaint.c4
-rw-r--r--gcc/ada/errout.adb38
-rw-r--r--gcc/ada/errout.ads11
-rw-r--r--gcc/ada/freeze.adb108
-rw-r--r--gcc/ada/mingw32.h13
-rw-r--r--gcc/ada/rtinit.c16
-rw-r--r--gcc/ada/s-mmap.adb548
-rw-r--r--gcc/ada/s-mmap.ads276
-rw-r--r--gcc/ada/s-mmauni-long.ads69
-rw-r--r--gcc/ada/s-mmosin-mingw.adb341
-rw-r--r--gcc/ada/s-mmosin-mingw.ads235
-rw-r--r--gcc/ada/s-mmosin-unix.adb231
-rw-r--r--gcc/ada/s-mmosin-unix.ads105
-rw-r--r--gcc/ada/sem_ch13.adb21
-rw-r--r--gcc/ada/sem_ch3.adb8
-rw-r--r--gcc/ada/sem_ch6.adb14
-rw-r--r--gcc/ada/sem_ch8.adb23
-rw-r--r--gcc/ada/sem_eval.adb9
-rw-r--r--gcc/ada/sem_util.adb20
-rw-r--r--gcc/ada/sem_util.ads9
-rw-r--r--gcc/ada/sysdep.c4
22 files changed, 2061 insertions, 104 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 04e5b8a..9af0589 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,65 @@
+2017-01-12 Tristan Gingold <gingold@adacore.com>
+
+ * s-mmap.ads, s-mmap.adb, s-mmosin-unix.ads, s-mmosin-unix.adb,
+ s-mmauni-long.ads, s-mmosin-mingw.ads, s-mmosin-mingw.adb: New files.
+
+2017-01-12 Yannick Moy <moy@adacore.com>
+
+ * errout.adb, errout.ads (Initialize): Factor common treatment
+ in Reset_Warnings.
+ (Reset_Warnings): New procedure to reset counts related to warnings.
+ (Record_Compilation_Errors): New variable to store the presence of an
+ error, used in gnat2why to allow changing the Warning_Mode.
+ (Compilation_Errors): Use new variable Record_Compilation_Errors to
+ store the presence of an error.
+
+2017-01-12 Javier Miranda <miranda@adacore.com>
+
+ * sem_ch13.adb (Analyze_Aspect_Specifications):
+ For Interrupt_Handler and Attach_ Handler aspects, decorate the
+ internally built reference to the protected procedure as coming
+ from sources and force its analysis.
+
+2017-01-12 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Build_Derived_Type): For a scalar derived type,
+ inherit predicates if any from the first_subtype of the parent,
+ not from the anonymous parent type.
+ * sem_eval.adb (Is_Static_Subtype): A type that inherits a dynamic
+ predicate is not a static subtype.
+
+2017-01-12 Gary Dismukes <dismukes@adacore.com>
+
+ * freeze.adb (Check_Suspicious_Convention): New procedure
+ performing a warning check on discriminated record types with
+ convention C or C++. Factored out of procedure Freeze_Record_Type,
+ and changed to only apply to base types (to avoid spurious
+ warnings on subtypes). Minor improvement of warning messages
+ to refer to discriminated rather than variant record types.
+ (Freeze_Record_Type): Remove code for performing a suspicious
+ convention check.
+ (Freeze_Entity): Only call Freeze_Record_Type
+ on types that aren't declared within any enclosing generic units
+ (rather than just excluding the type when the innermost scope
+ is generic). Call Check_Suspicious_Convention whether or not
+ the type is declared within a generic unit.
+ * sem_ch8.adb (In_Generic_Scope): Move this function to Sem_Util.
+ * sem_util.ads, sem_util.adb (In_Generic_Scope): New function (moved
+ from Sem_Ch8).
+
+2017-01-12 Tristan Gingold <gingold@adacore.com>
+
+ * sysdep.c, adaint.c, rtinit.c, ming32.h:
+ (__gnat_current_codepage): Renamed from CurrentCodePage
+ (__gnat_current_ccs_encoding): Renamed from CurrentCCSEncoding
+
+2017-01-12 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (Fully_Conformant_Expressions): Handle properly
+ quantified expressions, following AI12-050: the loop parameters
+ of two quantified expressions are conformant if they have the
+ same identifier.
+
2017-01-12 Arnaud Charlet <charlet@adacore.com>
* gcc-interface/Makefile.in: Clean up VxWorks targets.
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 819ea47..54a1d6e 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -128,8 +128,8 @@ extern "C" {
#include "mingw32.h"
/* Current code page and CCS encoding to use, set in initialize.c. */
-UINT CurrentCodePage;
-UINT CurrentCCSEncoding;
+UINT __gnat_current_codepage;
+UINT __gnat_current_ccs_encoding;
#include <sys/utime.h>
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index 49aa2a7..001072d 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -60,6 +60,13 @@ package body Errout is
Finalize_Called : Boolean := False;
-- Set True if the Finalize routine has been called
+ Record_Compilation_Errors : Boolean := False;
+ -- Record that a compilation error was witnessed during a given phase of
+ -- analysis for gnat2why. This is needed as Warning_Mode is modified twice
+ -- in gnat2why, hence Erroutc.Compilation_Errors can only return a suitable
+ -- value for each phase of analysis separately. This is updated at each
+ -- call to Compilation_Errors.
+
Warn_On_Instance : Boolean;
-- Flag set true for warning message to be posted on instance
@@ -236,8 +243,17 @@ package body Errout is
begin
if not Finalize_Called then
raise Program_Error;
+
+ -- Record that a compilation error was witnessed during a given phase of
+ -- analysis for gnat2why. This is needed as Warning_Mode is modified
+ -- twice in gnat2why, hence Erroutc.Compilation_Errors can only return a
+ -- suitable value for each phase of analysis separately.
+
else
- return Erroutc.Compilation_Errors;
+ Record_Compilation_Errors := Record_Compilation_Errors or else
+ Erroutc.Compilation_Errors;
+
+ return Record_Compilation_Errors;
end if;
end Compilation_Errors;
@@ -1615,13 +1631,13 @@ package body Errout is
Last_Error_Msg := No_Error_Msg;
Serious_Errors_Detected := 0;
Total_Errors_Detected := 0;
- Warnings_Treated_As_Errors := 0;
- Warnings_Detected := 0;
- Info_Messages := 0;
- Warnings_As_Errors_Count := 0;
Cur_Msg := No_Error_Msg;
List_Pragmas.Init;
+ -- Reset counts for warnings
+
+ Reset_Warnings;
+
-- Initialize warnings tables
Warnings.Init;
@@ -2357,6 +2373,18 @@ package body Errout is
end if;
end Remove_Warning_Messages;
+ --------------------
+ -- Reset_Warnings --
+ --------------------
+
+ procedure Reset_Warnings is
+ begin
+ Warnings_Treated_As_Errors := 0;
+ Warnings_Detected := 0;
+ Info_Messages := 0;
+ Warnings_As_Errors_Count := 0;
+ end Reset_Warnings;
+
----------------------
-- Adjust_Name_Case --
----------------------
diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
index e2e7de4..a8e4d6c 100644
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -803,6 +803,11 @@ package Errout is
-- Remove warnings on all elements of a list (Calls Remove_Warning_Messages
-- on each element of the list, see above).
+ procedure Reset_Warnings;
+ -- Reset the counts related to warnings. This is used both to initialize
+ -- these counts and to reset them after each phase of analysis for a given
+ -- value of Opt.Warning_Mode in gnat2why.
+
procedure Set_Ignore_Errors (To : Boolean);
-- Following a call to this procedure with To=True, all error calls are
-- ignored. A call with To=False restores the default treatment in which
@@ -852,9 +857,9 @@ package Errout is
function Compilation_Errors return Boolean;
-- Returns True if errors have been detected, or warnings in -gnatwe (treat
-- warnings as errors) mode. Note that it is mandatory to call Finalize
- -- before calling this routine. Always returns False in formal verification
- -- mode, because errors issued when analyzing code are not compilation
- -- errors, and should not result in exiting with an error status.
+ -- before calling this routine. To account for changes to Warning_Mode in
+ -- gnat2why between phases, the past or current presence of an error is
+ -- recorded in a global variable at each call.
procedure Error_Msg_CRT (Feature : String; N : Node_Id);
-- Posts a non-fatal message on node N saying that the feature identified
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 6c90bd3..0cc5881 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2035,6 +2035,13 @@ package body Freeze is
-- which is the current instance type can only be applied when the type
-- is limited.
+ procedure Check_Suspicious_Convention (Rec_Type : Entity_Id);
+ -- Give a warning for pragma Convention with language C or C++ applied
+ -- to a discriminated record type. This is suppressed for the unchecked
+ -- union case, since the whole point in this case is interface C. We
+ -- also do not generate this within instantiations, since we will have
+ -- generated a message on the template.
+
procedure Check_Suspicious_Modulus (Utype : Entity_Id);
-- Give warning for modulus of 8, 16, 32, or 64 given as an explicit
-- integer literal without an explicit corresponding size clause. The
@@ -2249,6 +2256,51 @@ package body Freeze is
end if;
end Check_Current_Instance;
+ ---------------------------------
+ -- Check_Suspicious_Convention --
+ ---------------------------------
+
+ procedure Check_Suspicious_Convention (Rec_Type : Entity_Id) is
+ begin
+ if Has_Discriminants (Rec_Type)
+ and then Is_Base_Type (Rec_Type)
+ and then not Is_Unchecked_Union (Rec_Type)
+ and then (Convention (Rec_Type) = Convention_C
+ or else
+ Convention (Rec_Type) = Convention_CPP)
+ and then Comes_From_Source (Rec_Type)
+ and then not In_Instance
+ and then not Has_Warnings_Off (Rec_Type)
+ then
+ declare
+ Cprag : constant Node_Id :=
+ Get_Rep_Pragma (Rec_Type, Name_Convention);
+ A2 : Node_Id;
+
+ begin
+ if Present (Cprag) then
+ A2 := Next (First (Pragma_Argument_Associations (Cprag)));
+
+ if Convention (Rec_Type) = Convention_C then
+ Error_Msg_N
+ ("?x?discriminated record has no direct " &
+ "equivalent in C",
+ A2);
+ else
+ Error_Msg_N
+ ("?x?discriminated record has no direct " &
+ "equivalent in C++",
+ A2);
+ end if;
+
+ Error_Msg_NE
+ ("\?x?use of convention for type& is dubious",
+ A2, Rec_Type);
+ end if;
+ end;
+ end if;
+ end Check_Suspicious_Convention;
+
------------------------------
-- Check_Suspicious_Modulus --
------------------------------
@@ -4348,46 +4400,6 @@ package body Freeze is
end loop;
end if;
- -- Generate warning for applying C or C++ convention to a record
- -- with discriminants. This is suppressed for the unchecked union
- -- case, since the whole point in this case is interface C. We also
- -- do not generate this within instantiations, since we will have
- -- generated a message on the template.
-
- if Has_Discriminants (E)
- and then not Is_Unchecked_Union (E)
- and then (Convention (E) = Convention_C
- or else
- Convention (E) = Convention_CPP)
- and then Comes_From_Source (E)
- and then not In_Instance
- and then not Has_Warnings_Off (E)
- and then not Has_Warnings_Off (Base_Type (E))
- then
- declare
- Cprag : constant Node_Id := Get_Rep_Pragma (E, Name_Convention);
- A2 : Node_Id;
-
- begin
- if Present (Cprag) then
- A2 := Next (First (Pragma_Argument_Associations (Cprag)));
-
- if Convention (E) = Convention_C then
- Error_Msg_N
- ("?x?variant record has no direct equivalent in C",
- A2);
- else
- Error_Msg_N
- ("?x?variant record has no direct equivalent in C++",
- A2);
- end if;
-
- Error_Msg_NE
- ("\?x?use of convention for type& is dubious", A2, E);
- end if;
- end;
- end if;
-
-- See if Size is too small as is (and implicit packing might help)
if not Is_Packed (Rec)
@@ -5643,11 +5655,17 @@ package body Freeze is
-- for the case of a private type with record extension (we will do
-- that later when the full type is frozen).
- elsif Ekind_In (E, E_Record_Type, E_Record_Subtype)
- and then not (Present (Scope (E))
- and then Is_Generic_Unit (Scope (E)))
- then
- Freeze_Record_Type (E);
+ elsif Ekind_In (E, E_Record_Type, E_Record_Subtype) then
+ if not In_Generic_Scope (E) then
+ Freeze_Record_Type (E);
+ end if;
+
+ -- Report a warning if a discriminated record base type has a
+ -- convention with language C or C++ applied to it. This check is
+ -- done even within generic scopes (but not in instantiations),
+ -- which is why we don't do it as part of Freeze_Record_Type.
+
+ Check_Suspicious_Convention (E);
-- For a concurrent type, freeze corresponding record type. This does
-- not correspond to any specific rule in the RM, but the record type
diff --git a/gcc/ada/mingw32.h b/gcc/ada/mingw32.h
index 77caec2..cf2d9de 100644
--- a/gcc/ada/mingw32.h
+++ b/gcc/ada/mingw32.h
@@ -6,7 +6,7 @@
* *
* C Header File *
* *
- * Copyright (C) 2002-2014, Free Software Foundation, Inc. *
+ * Copyright (C) 2002-2016, 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- *
@@ -78,14 +78,15 @@
#ifdef GNAT_UNICODE_SUPPORT
-extern UINT CurrentCodePage;
-extern UINT CurrentCCSEncoding;
+extern UINT __gnat_current_codepage;
+extern UINT __gnat_current_ccs_encoding;
-/* Macros to convert to/from the code page specified in CurrentCodePage. */
+/* Macros to convert to/from the code page specified in
+ __gnat_current_codepage. */
#define S2WSC(wstr,str,len) \
- MultiByteToWideChar (CurrentCodePage,0,str,-1,wstr,len)
+ MultiByteToWideChar (__gnat_current_codepage,0,str,-1,wstr,len)
#define WS2SC(str,wstr,len) \
- WideCharToMultiByte (CurrentCodePage,0,wstr,-1,str,len,NULL,NULL)
+ WideCharToMultiByte (__gnat_current_codepage,0,wstr,-1,str,len,NULL,NULL)
/* Macros to convert to/from UTF-8 code page. */
#define S2WSU(wstr,str,len) \
diff --git a/gcc/ada/rtinit.c b/gcc/ada/rtinit.c
index dcd0903..42defa8 100644
--- a/gcc/ada/rtinit.c
+++ b/gcc/ada/rtinit.c
@@ -169,14 +169,14 @@ __gnat_runtime_initialize(int install_handler)
char *codepage = getenv ("GNAT_CODE_PAGE");
/* Default code page is UTF-8. */
- CurrentCodePage = CP_UTF8;
+ __gnat_current_codepage = CP_UTF8;
if (codepage != NULL)
{
if (strcmp (codepage, "CP_ACP") == 0)
- CurrentCodePage = CP_ACP;
+ __gnat_current_codepage = CP_ACP;
else if (strcmp (codepage, "CP_UTF8") == 0)
- CurrentCodePage = CP_UTF8;
+ __gnat_current_codepage = CP_UTF8;
}
}
@@ -185,29 +185,29 @@ __gnat_runtime_initialize(int install_handler)
char *ccsencoding = getenv ("GNAT_CCS_ENCODING");
/* Default CCS Encoding. */
- CurrentCCSEncoding = _O_TEXT;
+ __gnat_current_ccs_encoding = _O_TEXT;
__gnat_wide_text_translation_required = 0;
if (ccsencoding != NULL)
{
if (strcmp (ccsencoding, "U16TEXT") == 0)
{
- CurrentCCSEncoding = _O_U16TEXT;
+ __gnat_current_ccs_encoding = _O_U16TEXT;
__gnat_wide_text_translation_required = 1;
}
else if (strcmp (ccsencoding, "TEXT") == 0)
{
- CurrentCCSEncoding = _O_TEXT;
+ __gnat_current_ccs_encoding = _O_TEXT;
__gnat_wide_text_translation_required = 0;
}
else if (strcmp (ccsencoding, "WTEXT") == 0)
{
- CurrentCCSEncoding = _O_WTEXT;
+ __gnat_current_ccs_encoding = _O_WTEXT;
__gnat_wide_text_translation_required = 1;
}
else if (strcmp (ccsencoding, "U8TEXT") == 0)
{
- CurrentCCSEncoding = _O_U8TEXT;
+ __gnat_current_ccs_encoding = _O_U8TEXT;
__gnat_wide_text_translation_required = 1;
}
}
diff --git a/gcc/ada/s-mmap.adb b/gcc/ada/s-mmap.adb
new file mode 100644
index 0000000..e9b2aff
--- /dev/null
+++ b/gcc/ada/s-mmap.adb
@@ -0,0 +1,548 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M M A P --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2007-2016, AdaCore --
+-- --
+-- This library is free software; you can redistribute it and/or modify it --
+-- under terms of the GNU General Public License as published by the Free --
+-- Software Foundation; either version 3, or (at your option) any later --
+-- version. This library is distributed in the hope that it will be useful, --
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
+-- TABILITY 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/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.IO_Exceptions;
+with Ada.Unchecked_Conversion;
+with Ada.Unchecked_Deallocation;
+
+with System.Strings; use System.Strings;
+
+with System.Mmap.OS_Interface; use System.Mmap.OS_Interface;
+
+package body System.Mmap is
+
+ type Mapped_File_Record is record
+ Current_Region : Mapped_Region;
+ -- The legacy API enables only one region to be mapped, directly
+ -- associated with the mapped file. This references this region.
+
+ File : System_File;
+ -- Underlying OS-level file
+ end record;
+
+ type Mapped_Region_Record is record
+ File : Mapped_File;
+ -- The file this region comes from. Be careful: for reading file, it is
+ -- valid to have it closed before one of its regions is free'd.
+
+ Write : Boolean;
+ -- Whether the file this region comes from is open for writing.
+
+ Data : Str_Access;
+ -- Unbounded access to the mapped content.
+
+ System_Offset : File_Size;
+ -- Position in the file of the first byte actually mapped in memory
+
+ User_Offset : File_Size;
+ -- Position in the file of the first byte requested by the user
+
+ System_Size : File_Size;
+ -- Size of the region actually mapped in memory
+
+ User_Size : File_Size;
+ -- Size of the region requested by the user
+
+ Mapped : Boolean;
+ -- Whether this region is actually memory mapped
+
+ Mutable : Boolean;
+ -- If the file is opened for reading, wheter this region is writable
+
+ Buffer : System.Strings.String_Access;
+ -- When this region is not actually memory mapped, contains the
+ -- requested bytes.
+
+ Mapping : System_Mapping;
+ -- Underlying OS-level data for the mapping, if any
+ end record;
+
+ Invalid_Mapped_Region_Record : constant Mapped_Region_Record :=
+ (null, False, null, 0, 0, 0, 0, False, False, null,
+ Invalid_System_Mapping);
+ Invalid_Mapped_File_Record : constant Mapped_File_Record :=
+ (Invalid_Mapped_Region, Invalid_System_File);
+
+ Empty_String : constant String := "";
+ -- Used to provide a valid empty Data for empty files, for instanc.
+
+ procedure Dispose is new Ada.Unchecked_Deallocation
+ (Mapped_File_Record, Mapped_File);
+ procedure Dispose is new Ada.Unchecked_Deallocation
+ (Mapped_Region_Record, Mapped_Region);
+
+ function Convert is new Ada.Unchecked_Conversion
+ (Standard.System.Address, Str_Access);
+
+ procedure Compute_Data (Region : Mapped_Region);
+ -- Fill the Data field according to system and user offsets. The region
+ -- must actually be mapped or bufferized.
+
+ procedure From_Disk (Region : Mapped_Region);
+ -- Read a region of some file from the disk
+
+ procedure To_Disk (Region : Mapped_Region);
+ -- Write the region of the file back to disk if necessary, and free memory
+
+ ---------------
+ -- Open_Read --
+ ---------------
+
+ function Open_Read
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return Mapped_File
+ is
+ File : constant System_File :=
+ Open_Read (Filename, Use_Mmap_If_Available);
+ begin
+ return new Mapped_File_Record'
+ (Current_Region => Invalid_Mapped_Region,
+ File => File);
+ end Open_Read;
+
+ ----------------
+ -- Open_Write --
+ ----------------
+
+ function Open_Write
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return Mapped_File
+ is
+ File : constant System_File :=
+ Open_Write (Filename, Use_Mmap_If_Available);
+ begin
+ return new Mapped_File_Record'
+ (Current_Region => Invalid_Mapped_Region,
+ File => File);
+ end Open_Write;
+
+ -----------
+ -- Close --
+ -----------
+
+ procedure Close (File : in out Mapped_File) is
+ begin
+ -- Closing a closed file is allowed and should do nothing
+
+ if File = Invalid_Mapped_File then
+ return;
+ end if;
+
+ if File.Current_Region /= null then
+ Free (File.Current_Region);
+ end if;
+
+ if File.File /= Invalid_System_File then
+ Close (File.File);
+ end if;
+
+ Dispose (File);
+ end Close;
+
+ ----------
+ -- Free --
+ ----------
+
+ procedure Free (Region : in out Mapped_Region) is
+ Ignored : Integer;
+ pragma Unreferenced (Ignored);
+ begin
+ -- Freeing an already free'd file is allowed and should do nothing
+
+ if Region = Invalid_Mapped_Region then
+ return;
+ end if;
+
+ if Region.Mapping /= Invalid_System_Mapping then
+ Dispose_Mapping (Region.Mapping);
+ end if;
+ To_Disk (Region);
+ Dispose (Region);
+ end Free;
+
+ ----------
+ -- Read --
+ ----------
+
+ procedure Read
+ (File : Mapped_File;
+ Region : in out Mapped_Region;
+ Offset : File_Size := 0;
+ Length : File_Size := 0;
+ Mutable : Boolean := False)
+ is
+ File_Length : constant File_Size := Mmap.Length (File);
+
+ Req_Offset : constant File_Size := Offset;
+ Req_Length : File_Size := Length;
+ -- Offset and Length of the region to map, used to adjust mapping
+ -- bounds, reflecting what the user will see.
+
+ Region_Allocated : Boolean := False;
+ begin
+ -- If this region comes from another file, or simply if the file is
+ -- writeable, we cannot re-use this mapping: free it first.
+
+ if Region /= Invalid_Mapped_Region
+ and then
+ (Region.File /= File or else File.File.Write)
+ then
+ Free (Region);
+ end if;
+
+ if Region = Invalid_Mapped_Region then
+ Region := new Mapped_Region_Record'(Invalid_Mapped_Region_Record);
+ Region_Allocated := True;
+ end if;
+
+ Region.File := File;
+
+ if Req_Offset >= File_Length then
+ -- If the requested offset goes beyond file size, map nothing
+
+ Req_Length := 0;
+
+ elsif Length = 0
+ or else
+ Length > File_Length - Req_Offset
+ then
+ -- If Length is 0 or goes beyond file size, map till end of file
+
+ Req_Length := File_Length - Req_Offset;
+
+ else
+ Req_Length := Length;
+ end if;
+
+ -- Past this point, the offset/length the user will see is fixed. On the
+ -- other hand, the system offset/length is either already defined, from
+ -- a previous mapping, or it is set to 0. In the latter case, the next
+ -- step will set them according to the mapping.
+
+ Region.User_Offset := Req_Offset;
+ Region.User_Size := Req_Length;
+
+ -- If the requested region is inside an already mapped region, adjust
+ -- user-requested data and do nothing else.
+
+ if (File.File.Write or else Region.Mutable = Mutable)
+ and then
+ Req_Offset >= Region.System_Offset
+ and then
+ (Req_Offset + Req_Length
+ <= Region.System_Offset + Region.System_Size)
+ then
+ Region.User_Offset := Req_Offset;
+ Compute_Data (Region);
+ return;
+
+ elsif Region.Buffer /= null then
+ -- Otherwise, as we are not going to re-use the buffer, free it
+
+ System.Strings.Free (Region.Buffer);
+ Region.Buffer := null;
+
+ elsif Region.Mapping /= Invalid_System_Mapping then
+ -- Otherwise, there is a memory mapping that we need to unmap.
+ Dispose_Mapping (Region.Mapping);
+ end if;
+
+ -- mmap() will sometimes return NULL when the file exists but is empty,
+ -- which is not what we want, so in the case of a zero length file we
+ -- fall back to read(2)/write(2)-based mode.
+
+ if File_Length > 0 and then File.File.Mapped then
+
+ Region.System_Offset := Req_Offset;
+ Region.System_Size := Req_Length;
+ Create_Mapping
+ (File.File,
+ Region.System_Offset, Region.System_Size,
+ Mutable,
+ Region.Mapping);
+ Region.Mapped := True;
+ Region.Mutable := Mutable;
+
+ else
+ -- There is no alignment requirement when manually reading the file.
+
+ Region.System_Offset := Req_Offset;
+ Region.System_Size := Req_Length;
+ Region.Mapped := False;
+ Region.Mutable := True;
+ From_Disk (Region);
+ end if;
+
+ Region.Write := File.File.Write;
+ Compute_Data (Region);
+
+ exception
+ when others =>
+ -- Before propagating any exception, free any region we allocated
+ -- here.
+
+ if Region_Allocated then
+ Dispose (Region);
+ end if;
+ raise;
+ end Read;
+
+ ----------
+ -- Read --
+ ----------
+
+ procedure Read
+ (File : Mapped_File;
+ Offset : File_Size := 0;
+ Length : File_Size := 0;
+ Mutable : Boolean := False)
+ is
+ begin
+ Read (File, File.Current_Region, Offset, Length, Mutable);
+ end Read;
+
+ ----------
+ -- Read --
+ ----------
+
+ function Read
+ (File : Mapped_File;
+ Offset : File_Size := 0;
+ Length : File_Size := 0;
+ Mutable : Boolean := False) return Mapped_Region
+ is
+ Region : Mapped_Region := Invalid_Mapped_Region;
+ begin
+ Read (File, Region, Offset, Length, Mutable);
+ return Region;
+ end Read;
+
+ ------------
+ -- Length --
+ ------------
+
+ function Length (File : Mapped_File) return File_Size is
+ begin
+ return File.File.Length;
+ end Length;
+
+ ------------
+ -- Offset --
+ ------------
+
+ function Offset (Region : Mapped_Region) return File_Size is
+ begin
+ return Region.User_Offset;
+ end Offset;
+
+ ------------
+ -- Offset --
+ ------------
+
+ function Offset (File : Mapped_File) return File_Size is
+ begin
+ return Offset (File.Current_Region);
+ end Offset;
+
+ ----------
+ -- Last --
+ ----------
+
+ function Last (Region : Mapped_Region) return Integer is
+ begin
+ return Integer (Region.User_Size);
+ end Last;
+
+ ----------
+ -- Last --
+ ----------
+
+ function Last (File : Mapped_File) return Integer is
+ begin
+ return Last (File.Current_Region);
+ end Last;
+
+ -------------------
+ -- To_Str_Access --
+ -------------------
+
+ function To_Str_Access
+ (Str : System.Strings.String_Access) return Str_Access is
+ begin
+ if Str = null then
+ return null;
+ else
+ return Convert (Str.all'Address);
+ end if;
+ end To_Str_Access;
+
+ ----------
+ -- Data --
+ ----------
+
+ function Data (Region : Mapped_Region) return Str_Access is
+ begin
+ return Region.Data;
+ end Data;
+
+ ----------
+ -- Data --
+ ----------
+
+ function Data (File : Mapped_File) return Str_Access is
+ begin
+ return Data (File.Current_Region);
+ end Data;
+
+ ----------------
+ -- Is_Mutable --
+ ----------------
+
+ function Is_Mutable (Region : Mapped_Region) return Boolean is
+ begin
+ return Region.Mutable or Region.Write;
+ end Is_Mutable;
+
+ ----------------
+ -- Is_Mmapped --
+ ----------------
+
+ function Is_Mmapped (File : Mapped_File) return Boolean is
+ begin
+ return File.File.Mapped;
+ end Is_Mmapped;
+
+ -------------------
+ -- Get_Page_Size --
+ -------------------
+
+ function Get_Page_Size return Integer is
+ Result : constant File_Size := Get_Page_Size;
+ begin
+ return Integer (Result);
+ end Get_Page_Size;
+
+ ---------------------
+ -- Read_Whole_File --
+ ---------------------
+
+ function Read_Whole_File
+ (Filename : String;
+ Empty_If_Not_Found : Boolean := False)
+ return System.Strings.String_Access
+ is
+ File : Mapped_File := Open_Read (Filename);
+ Region : Mapped_Region renames File.Current_Region;
+ Result : String_Access;
+ begin
+ Read (File);
+
+ if Region.Data /= null then
+ Result := new String'(String
+ (Region.Data (1 .. Last (Region))));
+
+ elsif Region.Buffer /= null then
+ Result := Region.Buffer;
+ Region.Buffer := null; -- So that it is not deallocated
+ end if;
+
+ Close (File);
+
+ return Result;
+
+ exception
+ when Ada.IO_Exceptions.Name_Error =>
+ if Empty_If_Not_Found then
+ return new String'("");
+ else
+ return null;
+ end if;
+
+ when others =>
+ Close (File);
+ return null;
+ end Read_Whole_File;
+
+ ---------------
+ -- From_Disk --
+ ---------------
+
+ procedure From_Disk (Region : Mapped_Region) is
+ begin
+ pragma Assert (Region.File.all /= Invalid_Mapped_File_Record);
+ pragma Assert (Region.Buffer = null);
+
+ Region.Buffer := Read_From_Disk
+ (Region.File.File, Region.User_Offset, Region.User_Size);
+ Region.Mapped := False;
+ end From_Disk;
+
+ -------------
+ -- To_Disk --
+ -------------
+
+ procedure To_Disk (Region : Mapped_Region) is
+ begin
+ if Region.Write and then Region.Buffer /= null then
+ pragma Assert (Region.File.all /= Invalid_Mapped_File_Record);
+ Write_To_Disk
+ (Region.File.File,
+ Region.User_Offset, Region.User_Size,
+ Region.Buffer);
+ end if;
+
+ System.Strings.Free (Region.Buffer);
+ Region.Buffer := null;
+ end To_Disk;
+
+ ------------------
+ -- Compute_Data --
+ ------------------
+
+ procedure Compute_Data (Region : Mapped_Region) is
+ Base_Data : Str_Access;
+ -- Address of the first byte actually mapped in memory
+
+ Data_Shift : constant Integer :=
+ Integer (Region.User_Offset - Region.System_Offset);
+ begin
+ if Region.User_Size = 0 then
+ Region.Data := Convert (Empty_String'Address);
+ return;
+ elsif Region.Mapped then
+ Base_Data := Convert (Region.Mapping.Address);
+ else
+ Base_Data := Convert (Region.Buffer.all'Address);
+ end if;
+ Region.Data := Convert (Base_Data (Data_Shift + 1)'Address);
+ end Compute_Data;
+
+end System.Mmap;
diff --git a/gcc/ada/s-mmap.ads b/gcc/ada/s-mmap.ads
new file mode 100644
index 0000000..8eed366
--- /dev/null
+++ b/gcc/ada/s-mmap.ads
@@ -0,0 +1,276 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M M A P --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2007-2016, AdaCore --
+-- --
+-- This library is free software; you can redistribute it and/or modify it --
+-- under terms of the GNU General Public License as published by the Free --
+-- Software Foundation; either version 3, or (at your option) any later --
+-- version. This library is distributed in the hope that it will be useful, --
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
+-- TABILITY 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/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides memory mapping of files. Depending on your operating
+-- system, this might provide a more efficient method for accessing the
+-- contents of files.
+-- A description of memory-mapping is available on the sqlite page, at:
+-- http://www.sqlite.org/mmap.html
+--
+-- The traditional method for reading a file is to allocate a buffer in the
+-- application address space, then open the file and copy its contents. When
+-- memory mapping is available though, the application asks the operating
+-- system to return a pointer to the requested page, if possible. If the
+-- requested page has been or can be mapped into the application address
+-- space, the system returns a pointer to that page for the application to
+-- use without having to copy anything. Skipping the copy step is what makes
+-- memory mapped I/O faster.
+--
+-- When memory mapping is not available, this package automatically falls
+-- back to the traditional copy method.
+--
+-- Example of use for this package, when reading a file that can be fully
+-- mapped
+--
+-- declare
+-- File : Mapped_File;
+-- Str : Str_Access;
+-- begin
+-- File := Open_Read ("/tmp/file_on_disk");
+-- Read (File); -- read the whole file
+-- Str := Data (File);
+-- for S in 1 .. Last (File) loop
+-- Put (Str (S));
+-- end loop;
+-- Close (File);
+-- end;
+--
+-- When the file is big, or you only want to access part of it at a given
+-- time, you can use the following type of code.
+
+-- declare
+-- File : Mapped_File;
+-- Str : Str_Access;
+-- Offs : File_Size := 0;
+-- Page : constant Integer := Get_Page_Size;
+-- begin
+-- File := Open_Read ("/tmp/file_on_disk");
+-- while Offs < Length (File) loop
+-- Read (File, Offs, Length => Long_Integer (Page) * 4);
+-- Str := Data (File);
+--
+-- -- Print characters for this chunk:
+-- for S in Integer (Offs - Offset (File)) + 1 .. Last (File) loop
+-- Put (Str (S));
+-- end loop;
+--
+-- -- Since we are reading multiples of Get_Page_Size, we can simplify
+-- -- with
+-- -- for S in 1 .. Last (File) loop ...
+--
+-- Offs := Offs + Long_Integer (Last (File));
+-- end loop;
+
+with Interfaces.C;
+
+with System.Strings;
+
+package System.Mmap is
+
+ type Mapped_File is private;
+ -- File to be mapped in memory.
+
+ -- This package will use the fastest possible algorithm to load the
+ -- file in memory. On systems that support it, the file is not really
+ -- loaded in memory. Instead, a call to the mmap() system call (or
+ -- CreateFileMapping()) will keep the file on disk, but make it
+ -- accessible as if it was in memory.
+
+ -- When the system does not support it, the file is actually loaded in
+ -- memory through calls to read(), and written back with write() when you
+ -- close it. This is of course much slower.
+
+ -- Legacy: each mapped file has a "default" mapped region in it.
+
+ type Mapped_Region is private;
+ -- A representation of part of a file in memory. Actual reading/writing
+ -- is done through a mapped region. After being returned by Read, a mapped
+ -- region must be free'd when done. If the original Mapped_File was open
+ -- for reading, it can be closed before the mapped region is free'd.
+
+ Invalid_Mapped_File : constant Mapped_File;
+ Invalid_Mapped_Region : constant Mapped_Region;
+
+ type Unconstrained_String is new String (Positive);
+ type Str_Access is access all Unconstrained_String;
+ pragma No_Strict_Aliasing (Str_Access);
+
+ type File_Size is new Interfaces.C.size_t;
+
+ function To_Str_Access
+ (Str : System.Strings.String_Access) return Str_Access;
+ -- Convert Str. The returned value points to the same memory block, but no
+ -- longer includes the bounds, which you need to manage yourself
+
+ function Open_Read
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return Mapped_File;
+ -- Open a file for reading. The same file can be shared by multiple
+ -- processes, that will see each others's changes as they occur.
+ -- Any attempt to write the data might result in a segmentation fault,
+ -- depending on how the file is open.
+ -- Name_Error is raised if the file does not exist.
+ -- Filename should be compatible with the filesystem.
+
+ function Open_Write
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return Mapped_File;
+ -- Open a file for writing.
+ -- You cannot change the length of the file.
+ -- Name_Error is raised if the file does not exist
+ -- Filename should be compatible with the filesystem.
+
+ procedure Close (File : in out Mapped_File);
+ -- Close the file, and unmap the memory that is used for the region
+ -- contained in File. If the system does not support the unmmap() system
+ -- call or equivalent, or these were not available for the file itself,
+ -- then the file is written back to the disk if it was opened for writing.
+
+ procedure Free (Region : in out Mapped_Region);
+ -- Unmap the memory that is used for this region and deallocate the region
+
+ procedure Read
+ (File : Mapped_File;
+ Region : in out Mapped_Region;
+ Offset : File_Size := 0;
+ Length : File_Size := 0;
+ Mutable : Boolean := False);
+ -- Read a specific part of File and set Region to the corresponding mapped
+ -- region, or re-use it if possible.
+ -- Offset is the number of bytes since the beginning of the file at which
+ -- we should start reading. Length is the number of bytes that should be
+ -- read. If set to 0, as much of the file as possible is read (presumably
+ -- the whole file unless you are reading a _huge_ file).
+ -- Note that no (un)mapping is is done if that part of the file is already
+ -- available through Region.
+ -- If the file was opened for writing, any modification you do to the
+ -- data stored in File will be stored on disk (either immediately when the
+ -- file is opened through a mmap() system call, or when the file is closed
+ -- otherwise).
+ -- Mutable is processed only for reading files. If set to True, the
+ -- data can be modified, even through it will not be carried through the
+ -- underlying file, nor it is guaranteed to be carried through remapping.
+ -- This function takes care of page size alignment issues. The accessors
+ -- below only expose the region that has been requested by this call, even
+ -- if more bytes were actually mapped by this function.
+ -- TODO??? Enable to have a private copy for readable files
+
+ function Read
+ (File : Mapped_File;
+ Offset : File_Size := 0;
+ Length : File_Size := 0;
+ Mutable : Boolean := False) return Mapped_Region;
+ -- Likewise, return a new mapped region
+
+ procedure Read
+ (File : Mapped_File;
+ Offset : File_Size := 0;
+ Length : File_Size := 0;
+ Mutable : Boolean := False);
+ -- Likewise, use the legacy "default" region in File
+
+ function Length (File : Mapped_File) return File_Size;
+ -- Size of the file on the disk
+
+ function Offset (Region : Mapped_Region) return File_Size;
+ -- Return the offset, in the physical file on disk, corresponding to the
+ -- requested mapped region. The first byte in the file has offest 0.
+
+ function Offset (File : Mapped_File) return File_Size;
+ -- Likewise for the region contained in File
+
+ function Last (Region : Mapped_Region) return Integer;
+ -- Return the number of requested bytes mapped in this region. It is
+ -- erroneous to access Data for indices outside 1 .. Last (Region).
+ -- Such accesses may cause Storage_Error to be raised.
+
+ function Last (File : Mapped_File) return Integer;
+ -- Return the number of requested bytes mapped in the region contained in
+ -- File. It is erroneous to access Data for indices outside of 1 .. Last
+ -- (File); such accesses may cause Storage_Error to be raised.
+
+ function Data (Region : Mapped_Region) return Str_Access;
+ -- The data mapped in Region as requested. The result is an unconstrained
+ -- string, so you cannot use the usual 'First and 'Last attributes.
+ -- Instead, these are respectively 1 and Size.
+
+ function Data (File : Mapped_File) return Str_Access;
+ -- Likewise for the region contained in File
+
+ function Is_Mutable (Region : Mapped_Region) return Boolean;
+ -- Return whether it is safe to change bytes in Data (Region). This is true
+ -- for regions from writeable files, for regions mapped with the "Mutable"
+ -- flag set, and for regions that are copied in a buffer. Note that it is
+ -- not specified whether empty regions are mutable or not, since there is
+ -- no byte no modify.
+
+ function Is_Mmapped (File : Mapped_File) return Boolean;
+ -- Whether regions for this file are opened through an mmap() system call
+ -- or equivalent. This is in general irrelevant to your application, unless
+ -- the file can be accessed by multiple concurrent processes or tasks. In
+ -- such a case, and if the file is indeed mmap-ed, then the various parts
+ -- of the file can be written simulatenously, and thus you cannot ensure
+ -- the integrity of the file. If the file is not mmapped, the latest
+ -- process to Close it overwrite what other processes have done.
+
+ function Get_Page_Size return Integer;
+ -- Returns the number of bytes in a page. Once a file is mapped from the
+ -- disk, its offset and Length should be multiples of this page size (which
+ -- is ensured by this package in any case). Knowing this page size allows
+ -- you to map as much memory as possible at once, thus potentially reducing
+ -- the number of system calls to read the file by chunks.
+
+ function Read_Whole_File
+ (Filename : String;
+ Empty_If_Not_Found : Boolean := False)
+ return System.Strings.String_Access;
+ -- Returns the whole contents of the file.
+ -- The returned string must be freed by the user.
+ -- This is a convenience function, which is of course slower than the ones
+ -- above since we also need to allocate some memory, actually read the file
+ -- and copy the bytes.
+ -- If the file does not exist, null is returned. However, if
+ -- Empty_If_Not_Found is True, then the empty string is returned instead.
+ -- Filename should be compatible with the filesystem.
+
+private
+ pragma Inline (Data, Length, Last, Offset, Is_Mmapped, To_Str_Access);
+
+ type Mapped_File_Record;
+ type Mapped_File is access Mapped_File_Record;
+
+ type Mapped_Region_Record;
+ type Mapped_Region is access Mapped_Region_Record;
+
+ Invalid_Mapped_File : constant Mapped_File := null;
+ Invalid_Mapped_Region : constant Mapped_Region := null;
+
+end System.Mmap;
diff --git a/gcc/ada/s-mmauni-long.ads b/gcc/ada/s-mmauni-long.ads
new file mode 100644
index 0000000..f7fa0bd
--- /dev/null
+++ b/gcc/ada/s-mmauni-long.ads
@@ -0,0 +1,69 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M M A P . U N I X --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2007-2016, AdaCore --
+-- --
+-- This library is free software; you can redistribute it and/or modify it --
+-- under terms of the GNU General Public License as published by the Free --
+-- Software Foundation; either version 3, or (at your option) any later --
+-- version. This library is distributed in the hope that it will be useful, --
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
+-- TABILITY 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/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Declaration of off_t/mmap/munmap. This particular implementation
+-- supposes off_t is long.
+
+with System.OS_Lib;
+with Interfaces.C;
+
+package System.Mmap.Unix is
+
+ type Mmap_Prot is new Interfaces.C.int;
+-- PROT_NONE : constant Mmap_Prot := 16#00#;
+-- PROT_EXEC : constant Mmap_Prot := 16#04#;
+ PROT_READ : constant Mmap_Prot := 16#01#;
+ PROT_WRITE : constant Mmap_Prot := 16#02#;
+
+ type Mmap_Flags is new Interfaces.C.int;
+-- MAP_NONE : constant Mmap_Flags := 16#00#;
+-- MAP_FIXED : constant Mmap_Flags := 16#10#;
+ MAP_SHARED : constant Mmap_Flags := 16#01#;
+ MAP_PRIVATE : constant Mmap_Flags := 16#02#;
+
+ type off_t is new Long_Integer;
+
+ function Mmap (Start : Address := Null_Address;
+ Length : Interfaces.C.size_t;
+ Prot : Mmap_Prot := PROT_READ;
+ Flags : Mmap_Flags := MAP_PRIVATE;
+ Fd : System.OS_Lib.File_Descriptor;
+ Offset : off_t) return Address;
+ pragma Import (C, Mmap, "mmap");
+
+ function Munmap (Start : Address;
+ Length : Interfaces.C.size_t) return Integer;
+ pragma Import (C, Munmap, "munmap");
+
+ function Is_Mapping_Available return Boolean is (True);
+ -- Wheter memory mapping is actually available on this system. It is an
+ -- error to use Create_Mapping and Dispose_Mapping if this is False.
+end System.Mmap.Unix;
diff --git a/gcc/ada/s-mmosin-mingw.adb b/gcc/ada/s-mmosin-mingw.adb
new file mode 100644
index 0000000..0785f3c
--- /dev/null
+++ b/gcc/ada/s-mmosin-mingw.adb
@@ -0,0 +1,341 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M M A P . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2007-2016, AdaCore --
+-- --
+-- This library is free software; you can redistribute it and/or modify it --
+-- under terms of the GNU General Public License as published by the Free --
+-- Software Foundation; either version 3, or (at your option) any later --
+-- version. This library is distributed in the hope that it will be useful, --
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
+-- TABILITY 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/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.IO_Exceptions;
+with System.Strings; use System.Strings;
+
+package body System.Mmap.OS_Interface is
+
+ use Win;
+
+ function Align
+ (Addr : File_Size) return File_Size;
+ -- Align some offset/length to the lowest page boundary
+
+ function Open_Common
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean;
+ Write : Boolean) return System_File;
+
+ function From_UTF8 (Path : String) return Wide_String;
+ -- Convert from UTF-8 to Wide_String
+
+ ---------------
+ -- From_UTF8 --
+ ---------------
+
+ function From_UTF8 (Path : String) return Wide_String is
+ function MultiByteToWideChar
+ (Codepage : Interfaces.C.unsigned;
+ Flags : Interfaces.C.unsigned;
+ Mbstr : Address;
+ Mb : Natural;
+ Wcstr : Address;
+ Wc : Natural) return Integer;
+ pragma Import (C, MultiByteToWideChar);
+
+ Current_Codepage : Interfaces.C.unsigned;
+ pragma Import (C, Current_Codepage, "__gnat_current_codepage");
+
+ Len : Natural;
+ begin
+ -- Compute length of the result
+ Len := MultiByteToWideChar
+ (Current_Codepage, 0, Path'Address, Path'Length, Null_Address, 0);
+ if Len = 0 then
+ raise Constraint_Error;
+ end if;
+
+ declare
+ -- Declare result
+ Res : Wide_String (1 .. Len);
+ begin
+ -- And compute it
+ Len := MultiByteToWideChar
+ (Current_Codepage, 0,
+ Path'Address, Path'Length,
+ Res'Address, Len);
+ if Len = 0 then
+ raise Constraint_Error;
+ end if;
+ return Res;
+ end;
+ end From_UTF8;
+
+ -----------------
+ -- Open_Common --
+ -----------------
+
+ function Open_Common
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean;
+ Write : Boolean) return System_File
+ is
+ dwDesiredAccess, dwShareMode : DWORD;
+ PageFlags : DWORD;
+
+ W_Filename : constant Wide_String :=
+ From_UTF8 (Filename) & Wide_Character'Val (0);
+ File_Handle, Mapping_Handle : HANDLE;
+
+ SizeH : aliased DWORD;
+ Size : File_Size;
+ begin
+ if Write then
+ dwDesiredAccess := GENERIC_READ + GENERIC_WRITE;
+ dwShareMode := 0;
+ PageFlags := Win.PAGE_READWRITE;
+ else
+ dwDesiredAccess := GENERIC_READ;
+ dwShareMode := Win.FILE_SHARE_READ;
+ PageFlags := Win.PAGE_READONLY;
+ end if;
+
+ -- Actually open the file
+
+ File_Handle := CreateFile
+ (W_Filename'Address, dwDesiredAccess, dwShareMode,
+ null, OPEN_EXISTING, Win.FILE_ATTRIBUTE_NORMAL, 0);
+
+ if File_Handle = Win.INVALID_HANDLE_VALUE then
+ raise Ada.IO_Exceptions.Name_Error
+ with "Cannot open " & Filename;
+ end if;
+
+ -- Compute its size
+
+ Size := File_Size (Win.GetFileSize (File_Handle, SizeH'Access));
+
+ if Size = Win.INVALID_FILE_SIZE then
+ raise Ada.IO_Exceptions.Use_Error;
+ end if;
+
+ if SizeH /= 0 and then File_Size'Size > 32 then
+ Size := Size + (File_Size (SizeH) * 2 ** 32);
+ end if;
+
+ -- Then create a mapping object, if needed. On Win32, file memory
+ -- mapping is always available.
+
+ if Use_Mmap_If_Available then
+ Mapping_Handle :=
+ Win.CreateFileMapping
+ (File_Handle, null, PageFlags,
+ 0, DWORD (Size), Standard.System.Null_Address);
+ else
+ Mapping_Handle := Win.INVALID_HANDLE_VALUE;
+ end if;
+
+ return
+ (Handle => File_Handle,
+ Mapped => Use_Mmap_If_Available,
+ Mapping_Handle => Mapping_Handle,
+ Write => Write,
+ Length => Size);
+ end Open_Common;
+
+ ---------------
+ -- Open_Read --
+ ---------------
+
+ function Open_Read
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File is
+ begin
+ return Open_Common (Filename, Use_Mmap_If_Available, False);
+ end Open_Read;
+
+ ----------------
+ -- Open_Write --
+ ----------------
+
+ function Open_Write
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File is
+ begin
+ return Open_Common (Filename, Use_Mmap_If_Available, True);
+ end Open_Write;
+
+ -----------
+ -- Close --
+ -----------
+
+ procedure Close (File : in out System_File) is
+ Ignored : BOOL;
+ pragma Unreferenced (Ignored);
+ begin
+ Ignored := CloseHandle (File.Mapping_Handle);
+ Ignored := CloseHandle (File.Handle);
+ File.Handle := Win.INVALID_HANDLE_VALUE;
+ File.Mapping_Handle := Win.INVALID_HANDLE_VALUE;
+ end Close;
+
+ --------------------
+ -- Read_From_Disk --
+ --------------------
+
+ function Read_From_Disk
+ (File : System_File;
+ Offset, Length : File_Size) return System.Strings.String_Access
+ is
+ Buffer : String_Access := new String (1 .. Integer (Length));
+
+ Pos : DWORD;
+ NbRead : aliased DWORD;
+ pragma Unreferenced (Pos);
+ begin
+ Pos := Win.SetFilePointer
+ (File.Handle, LONG (Offset), null, Win.FILE_BEGIN);
+
+ if Win.ReadFile
+ (File.Handle, Buffer.all'Address,
+ DWORD (Length), NbRead'Unchecked_Access, null) = Win.FALSE
+ then
+ System.Strings.Free (Buffer);
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+ return Buffer;
+ end Read_From_Disk;
+
+ -------------------
+ -- Write_To_Disk --
+ -------------------
+
+ procedure Write_To_Disk
+ (File : System_File;
+ Offset, Length : File_Size;
+ Buffer : System.Strings.String_Access)
+ is
+ Pos : DWORD;
+ NbWritten : aliased DWORD;
+ pragma Unreferenced (Pos);
+ begin
+ pragma Assert (File.Write);
+ Pos := Win.SetFilePointer
+ (File.Handle, LONG (Offset), null, Win.FILE_BEGIN);
+
+ if Win.WriteFile
+ (File.Handle, Buffer.all'Address,
+ DWORD (Length), NbWritten'Unchecked_Access, null) = Win.FALSE
+ then
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+ end Write_To_Disk;
+
+ --------------------
+ -- Create_Mapping --
+ --------------------
+
+ procedure Create_Mapping
+ (File : System_File;
+ Offset, Length : in out File_Size;
+ Mutable : Boolean;
+ Mapping : out System_Mapping)
+ is
+ Flags : DWORD;
+ begin
+ if File.Write then
+ Flags := Win.FILE_MAP_WRITE;
+ elsif Mutable then
+ Flags := Win.FILE_MAP_COPY;
+ else
+ Flags := Win.FILE_MAP_READ;
+ end if;
+
+ -- Adjust offset and mapping length to account for the required
+ -- alignment of offset on page boundary.
+
+ declare
+ Queried_Offset : constant File_Size := Offset;
+ begin
+ Offset := Align (Offset);
+
+ -- First extend the length to compensate the offset shift, then align
+ -- it on the upper page boundary, so that the whole queried area is
+ -- covered.
+
+ Length := Length + Queried_Offset - Offset;
+ Length := Align (Length + Get_Page_Size - 1);
+
+ -- But do not exceed the length of the file
+ if Offset + Length > File.Length then
+ Length := File.Length - Offset;
+ end if;
+ end;
+
+ if Length > File_Size (Integer'Last) then
+ raise Ada.IO_Exceptions.Device_Error;
+ else
+ Mapping := Invalid_System_Mapping;
+ Mapping.Address :=
+ Win.MapViewOfFile
+ (File.Mapping_Handle, Flags,
+ 0, DWORD (Offset), SIZE_T (Length));
+ Mapping.Length := Length;
+ end if;
+ end Create_Mapping;
+
+ ---------------------
+ -- Dispose_Mapping --
+ ---------------------
+
+ procedure Dispose_Mapping
+ (Mapping : in out System_Mapping)
+ is
+ Ignored : BOOL;
+ pragma Unreferenced (Ignored);
+ begin
+ Ignored := Win.UnmapViewOfFile (Mapping.Address);
+ Mapping := Invalid_System_Mapping;
+ end Dispose_Mapping;
+
+ -------------------
+ -- Get_Page_Size --
+ -------------------
+
+ function Get_Page_Size return File_Size is
+ SystemInfo : aliased SYSTEM_INFO;
+ begin
+ GetSystemInfo (SystemInfo'Unchecked_Access);
+ return File_Size (SystemInfo.dwAllocationGranularity);
+ end Get_Page_Size;
+
+ -----------
+ -- Align --
+ -----------
+
+ function Align
+ (Addr : File_Size) return File_Size is
+ begin
+ return Addr - Addr mod Get_Page_Size;
+ end Align;
+
+end System.Mmap.OS_Interface;
diff --git a/gcc/ada/s-mmosin-mingw.ads b/gcc/ada/s-mmosin-mingw.ads
new file mode 100644
index 0000000..76874a8
--- /dev/null
+++ b/gcc/ada/s-mmosin-mingw.ads
@@ -0,0 +1,235 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M M A P . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2007-2016, AdaCore --
+-- --
+-- This library is free software; you can redistribute it and/or modify it --
+-- under terms of the GNU General Public License as published by the Free --
+-- Software Foundation; either version 3, or (at your option) any later --
+-- version. This library is distributed in the hope that it will be useful, --
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
+-- TABILITY 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/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- OS pecularities abstraction package for Win32 systems.
+
+package System.Mmap.OS_Interface is
+
+ -- The Win package contains copy of definition found in recent System.Win32
+ -- unit provided with the GNAT compiler. The copy is needed to be able to
+ -- compile this unit with older compilers. Note that this internal Win
+ -- package can be removed when GNAT 6.1.0 is not supported anymore.
+
+ package Win is
+
+ subtype PVOID is Standard.System.Address;
+
+ type HANDLE is new Interfaces.C.ptrdiff_t;
+
+ type WORD is new Interfaces.C.unsigned_short;
+ type DWORD is new Interfaces.C.unsigned_long;
+ type LONG is new Interfaces.C.long;
+ type SIZE_T is new Interfaces.C.size_t;
+
+ type BOOL is new Interfaces.C.int;
+ for BOOL'Size use Interfaces.C.int'Size;
+
+ FALSE : constant := 0;
+
+ GENERIC_READ : constant := 16#80000000#;
+ GENERIC_WRITE : constant := 16#40000000#;
+ OPEN_EXISTING : constant := 3;
+
+ type OVERLAPPED is record
+ Internal : DWORD;
+ InternalHigh : DWORD;
+ Offset : DWORD;
+ OffsetHigh : DWORD;
+ hEvent : HANDLE;
+ end record;
+
+ type SECURITY_ATTRIBUTES is record
+ nLength : DWORD;
+ pSecurityDescriptor : PVOID;
+ bInheritHandle : BOOL;
+ end record;
+
+ type SYSTEM_INFO is record
+ dwOemId : DWORD;
+ dwPageSize : DWORD;
+ lpMinimumApplicationAddress : PVOID;
+ lpMaximumApplicationAddress : PVOID;
+ dwActiveProcessorMask : PVOID;
+ dwNumberOfProcessors : DWORD;
+ dwProcessorType : DWORD;
+ dwAllocationGranularity : DWORD;
+ wProcessorLevel : WORD;
+ wProcessorRevision : WORD;
+ end record;
+ type LP_SYSTEM_INFO is access all SYSTEM_INFO;
+
+ INVALID_HANDLE_VALUE : constant HANDLE := -1;
+ FILE_BEGIN : constant := 0;
+ FILE_SHARE_READ : constant := 16#00000001#;
+ FILE_ATTRIBUTE_NORMAL : constant := 16#00000080#;
+ FILE_MAP_COPY : constant := 1;
+ FILE_MAP_READ : constant := 4;
+ FILE_MAP_WRITE : constant := 2;
+ PAGE_READONLY : constant := 16#0002#;
+ PAGE_READWRITE : constant := 16#0004#;
+ INVALID_FILE_SIZE : constant := 16#FFFFFFFF#;
+
+ function CreateFile
+ (lpFileName : Standard.System.Address;
+ dwDesiredAccess : DWORD;
+ dwShareMode : DWORD;
+ lpSecurityAttributes : access SECURITY_ATTRIBUTES;
+ dwCreationDisposition : DWORD;
+ dwFlagsAndAttributes : DWORD;
+ hTemplateFile : HANDLE) return HANDLE;
+ pragma Import (Stdcall, CreateFile, "CreateFileW");
+
+ function WriteFile
+ (hFile : HANDLE;
+ lpBuffer : Standard.System.Address;
+ nNumberOfBytesToWrite : DWORD;
+ lpNumberOfBytesWritten : access DWORD;
+ lpOverlapped : access OVERLAPPED) return BOOL;
+ pragma Import (Stdcall, WriteFile, "WriteFile");
+
+ function ReadFile
+ (hFile : HANDLE;
+ lpBuffer : Standard.System.Address;
+ nNumberOfBytesToRead : DWORD;
+ lpNumberOfBytesRead : access DWORD;
+ lpOverlapped : access OVERLAPPED) return BOOL;
+ pragma Import (Stdcall, ReadFile, "ReadFile");
+
+ function CloseHandle (hObject : HANDLE) return BOOL;
+ pragma Import (Stdcall, CloseHandle, "CloseHandle");
+
+ function GetFileSize
+ (hFile : HANDLE; lpFileSizeHigh : access DWORD) return DWORD;
+ pragma Import (Stdcall, GetFileSize, "GetFileSize");
+
+ function SetFilePointer
+ (hFile : HANDLE;
+ lDistanceToMove : LONG;
+ lpDistanceToMoveHigh : access LONG;
+ dwMoveMethod : DWORD) return DWORD;
+ pragma Import (Stdcall, SetFilePointer, "SetFilePointer");
+
+ function CreateFileMapping
+ (hFile : HANDLE;
+ lpSecurityAttributes : access SECURITY_ATTRIBUTES;
+ flProtect : DWORD;
+ dwMaximumSizeHigh : DWORD;
+ dwMaximumSizeLow : DWORD;
+ lpName : Standard.System.Address) return HANDLE;
+ pragma Import (Stdcall, CreateFileMapping, "CreateFileMappingW");
+
+ function MapViewOfFile
+ (hFileMappingObject : HANDLE;
+ dwDesiredAccess : DWORD;
+ dwFileOffsetHigh : DWORD;
+ dwFileOffsetLow : DWORD;
+ dwNumberOfBytesToMap : SIZE_T) return Standard.System.Address;
+ pragma Import (Stdcall, MapViewOfFile, "MapViewOfFile");
+
+ function UnmapViewOfFile
+ (lpBaseAddress : Standard.System.Address) return BOOL;
+ pragma Import (Stdcall, UnmapViewOfFile, "UnmapViewOfFile");
+
+ procedure GetSystemInfo (lpSystemInfo : LP_SYSTEM_INFO);
+ pragma Import (Stdcall, GetSystemInfo, "GetSystemInfo");
+
+ end Win;
+
+ type System_File is record
+ Handle : Win.HANDLE;
+
+ Mapped : Boolean;
+ -- Whether mapping is requested by the user and available on the system
+
+ Mapping_Handle : Win.HANDLE;
+
+ Write : Boolean;
+ -- Whether this file can be written to
+
+ Length : File_Size;
+ -- Length of the file. Used to know what can be mapped in the file
+ end record;
+
+ type System_Mapping is record
+ Address : Standard.System.Address;
+ Length : File_Size;
+ end record;
+
+ Invalid_System_File : constant System_File :=
+ (Win.INVALID_HANDLE_VALUE, False, Win.INVALID_HANDLE_VALUE, False, 0);
+ Invalid_System_Mapping : constant System_Mapping :=
+ (Standard.System.Null_Address, 0);
+
+ function Open_Read
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File;
+ -- Open a file for reading and return the corresponding System_File. Raise
+ -- a Ada.IO_Exceptions.Name_Error if unsuccessful.
+
+ function Open_Write
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File;
+ -- Likewise for writing to a file
+
+ procedure Close (File : in out System_File);
+ -- Close a system file
+
+ function Read_From_Disk
+ (File : System_File;
+ Offset, Length : File_Size) return System.Strings.String_Access;
+ -- Read a fragment of a file. It is up to the caller to free the result
+ -- when done with it.
+
+ procedure Write_To_Disk
+ (File : System_File;
+ Offset, Length : File_Size;
+ Buffer : System.Strings.String_Access);
+ -- Write some content to a fragment of a file
+
+ procedure Create_Mapping
+ (File : System_File;
+ Offset, Length : in out File_Size;
+ Mutable : Boolean;
+ Mapping : out System_Mapping);
+ -- Create a memory mapping for the given File, for the area starting at
+ -- Offset and containing Length bytes. Store it to Mapping.
+ -- Note that Offset and Length may be modified according to the system
+ -- needs (for boudaries, for instance). The caller must cope with actually
+ -- wider mapped areas.
+
+ procedure Dispose_Mapping
+ (Mapping : in out System_Mapping);
+ -- Unmap a previously-created mapping
+
+ function Get_Page_Size return File_Size;
+ -- Return the number of bytes in a system page.
+
+end System.Mmap.OS_Interface;
diff --git a/gcc/ada/s-mmosin-unix.adb b/gcc/ada/s-mmosin-unix.adb
new file mode 100644
index 0000000..a68c59f
--- /dev/null
+++ b/gcc/ada/s-mmosin-unix.adb
@@ -0,0 +1,231 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M M A P . O S _ I N T E R F A C E --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2007-2016, AdaCore --
+-- --
+-- This library is free software; you can redistribute it and/or modify it --
+-- under terms of the GNU General Public License as published by the Free --
+-- Software Foundation; either version 3, or (at your option) any later --
+-- version. This library is distributed in the hope that it will be useful, --
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
+-- TABILITY 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/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.IO_Exceptions;
+with System; use System;
+
+with System.OS_Lib; use System.OS_Lib;
+with System.Mmap.Unix; use System.Mmap.Unix;
+
+package body System.Mmap.OS_Interface is
+
+ function Align
+ (Addr : File_Size) return File_Size;
+ -- Align some offset/length to the lowest page boundary
+
+ function Is_Mapping_Available return Boolean renames
+ System.Mmap.Unix.Is_Mapping_Available;
+ -- Wheter memory mapping is actually available on this system. It is an
+ -- error to use Create_Mapping and Dispose_Mapping if this is False.
+
+ ---------------
+ -- Open_Read --
+ ---------------
+
+ function Open_Read
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File is
+ Fd : constant File_Descriptor :=
+ Open_Read (Filename, Binary);
+ begin
+ if Fd = Invalid_FD then
+ raise Ada.IO_Exceptions.Name_Error
+ with "Cannot open " & Filename;
+ end if;
+ return
+ (Fd => Fd,
+ Mapped => Use_Mmap_If_Available and then Is_Mapping_Available,
+ Write => False,
+ Length => File_Size (File_Length (Fd)));
+ end Open_Read;
+
+ ----------------
+ -- Open_Write --
+ ----------------
+
+ function Open_Write
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File is
+ Fd : constant File_Descriptor :=
+ Open_Read_Write (Filename, Binary);
+ begin
+ if Fd = Invalid_FD then
+ raise Ada.IO_Exceptions.Name_Error
+ with "Cannot open " & Filename;
+ end if;
+ return
+ (Fd => Fd,
+ Mapped => Use_Mmap_If_Available and then Is_Mapping_Available,
+ Write => True,
+ Length => File_Size (File_Length (Fd)));
+ end Open_Write;
+
+ -----------
+ -- Close --
+ -----------
+
+ procedure Close (File : in out System_File) is
+ begin
+ Close (File.Fd);
+ File.Fd := Invalid_FD;
+ end Close;
+
+ --------------------
+ -- Read_From_Disk --
+ --------------------
+
+ function Read_From_Disk
+ (File : System_File;
+ Offset, Length : File_Size) return System.Strings.String_Access
+ is
+ Buffer : String_Access := new String (1 .. Integer (Length));
+ begin
+ -- ??? Lseek offset should be a size_t instead of a Long_Integer
+
+ Lseek (File.Fd, Long_Integer (Offset), Seek_Set);
+ if System.OS_Lib.Read (File.Fd, Buffer.all'Address, Integer (Length))
+ /= Integer (Length)
+ then
+ System.Strings.Free (Buffer);
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+ return Buffer;
+ end Read_From_Disk;
+
+ -------------------
+ -- Write_To_Disk --
+ -------------------
+
+ procedure Write_To_Disk
+ (File : System_File;
+ Offset, Length : File_Size;
+ Buffer : System.Strings.String_Access) is
+ begin
+ pragma Assert (File.Write);
+ Lseek (File.Fd, Long_Integer (Offset), Seek_Set);
+ if System.OS_Lib.Write (File.Fd, Buffer.all'Address, Integer (Length))
+ /= Integer (Length)
+ then
+ raise Ada.IO_Exceptions.Device_Error;
+ end if;
+ end Write_To_Disk;
+
+ --------------------
+ -- Create_Mapping --
+ --------------------
+
+ procedure Create_Mapping
+ (File : System_File;
+ Offset, Length : in out File_Size;
+ Mutable : Boolean;
+ Mapping : out System_Mapping)
+ is
+ Prot : Mmap_Prot;
+ Flags : Mmap_Flags;
+ begin
+ if File.Write then
+ Prot := PROT_READ + PROT_WRITE;
+ Flags := MAP_SHARED;
+ else
+ Prot := PROT_READ;
+ if Mutable then
+ Prot := Prot + PROT_WRITE;
+ end if;
+ Flags := MAP_PRIVATE;
+ end if;
+
+ -- Adjust offset and mapping length to account for the required
+ -- alignment of offset on page boundary.
+
+ declare
+ Queried_Offset : constant File_Size := Offset;
+ begin
+ Offset := Align (Offset);
+
+ -- First extend the length to compensate the offset shift, then align
+ -- it on the upper page boundary, so that the whole queried area is
+ -- covered.
+
+ Length := Length + Queried_Offset - Offset;
+ Length := Align (Length + Get_Page_Size - 1);
+ end;
+
+ if Length > File_Size (Integer'Last) then
+ raise Ada.IO_Exceptions.Device_Error;
+ else
+ Mapping :=
+ (Address => System.Mmap.Unix.Mmap
+ (Offset => off_t (Offset),
+ Length => Interfaces.C.size_t (Length),
+ Prot => Prot,
+ Flags => Flags,
+ Fd => File.Fd),
+ Length => Length);
+ end if;
+ end Create_Mapping;
+
+ ---------------------
+ -- Dispose_Mapping --
+ ---------------------
+
+ procedure Dispose_Mapping
+ (Mapping : in out System_Mapping)
+ is
+ Ignored : Integer;
+ pragma Unreferenced (Ignored);
+ begin
+ Ignored := Munmap
+ (Mapping.Address, Interfaces.C.size_t (Mapping.Length));
+ Mapping := Invalid_System_Mapping;
+ end Dispose_Mapping;
+
+ -------------------
+ -- Get_Page_Size --
+ -------------------
+
+ function Get_Page_Size return File_Size is
+ function Internal return Integer;
+ pragma Import (C, Internal, "getpagesize");
+ begin
+ return File_Size (Internal);
+ end Get_Page_Size;
+
+ -----------
+ -- Align --
+ -----------
+
+ function Align
+ (Addr : File_Size) return File_Size is
+ begin
+ return Addr - Addr mod Get_Page_Size;
+ end Align;
+
+end System.Mmap.OS_Interface;
diff --git a/gcc/ada/s-mmosin-unix.ads b/gcc/ada/s-mmosin-unix.ads
new file mode 100644
index 0000000..0157639
--- /dev/null
+++ b/gcc/ada/s-mmosin-unix.ads
@@ -0,0 +1,105 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . M M A P . O S _ I N T E R F A C E --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2007-2016, AdaCore --
+-- --
+-- This library is free software; you can redistribute it and/or modify it --
+-- under terms of the GNU General Public License as published by the Free --
+-- Software Foundation; either version 3, or (at your option) any later --
+-- version. This library is distributed in the hope that it will be useful, --
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
+-- TABILITY 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/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with System.OS_Lib;
+
+-- OS pecularities abstraction package for Unix systems.
+
+package System.Mmap.OS_Interface is
+
+ type System_File is record
+ Fd : System.OS_Lib.File_Descriptor;
+
+ Mapped : Boolean;
+ -- Whether mapping is requested by the user and available on the system
+
+ Write : Boolean;
+ -- Whether this file can be written to
+
+ Length : File_Size;
+ -- Length of the file. Used to know what can be mapped in the file
+ end record;
+
+ type System_Mapping is record
+ Address : Standard.System.Address;
+ Length : File_Size;
+ end record;
+
+ Invalid_System_File : constant System_File :=
+ (System.OS_Lib.Invalid_FD, False, False, 0);
+ Invalid_System_Mapping : constant System_Mapping :=
+ (Standard.System.Null_Address, 0);
+
+ function Open_Read
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File;
+ -- Open a file for reading and return the corresponding System_File. Raise
+ -- a Ada.IO_Exceptions.Name_Error if unsuccessful.
+
+ function Open_Write
+ (Filename : String;
+ Use_Mmap_If_Available : Boolean := True) return System_File;
+ -- Likewise for writing to a file
+
+ procedure Close (File : in out System_File);
+ -- Close a system file
+
+ function Read_From_Disk
+ (File : System_File;
+ Offset, Length : File_Size) return System.Strings.String_Access;
+ -- Read a fragment of a file. It is up to the caller to free the result
+ -- when done with it.
+
+ procedure Write_To_Disk
+ (File : System_File;
+ Offset, Length : File_Size;
+ Buffer : System.Strings.String_Access);
+ -- Write some content to a fragment of a file
+
+ procedure Create_Mapping
+ (File : System_File;
+ Offset, Length : in out File_Size;
+ Mutable : Boolean;
+ Mapping : out System_Mapping);
+ -- Create a memory mapping for the given File, for the area starting at
+ -- Offset and containing Length bytes. Store it to Mapping.
+ -- Note that Offset and Length may be modified according to the system
+ -- needs (for boudaries, for instance). The caller must cope with actually
+ -- wider mapped areas.
+
+ procedure Dispose_Mapping
+ (Mapping : in out System_Mapping);
+ -- Unmap a previously-created mapping
+
+ function Get_Page_Size return File_Size;
+ -- Return the number of bytes in a system page.
+
+end System.Mmap.OS_Interface;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 7a23005..a88f848 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -59,10 +59,10 @@ with Sem_Res; use Sem_Res;
with Sem_Type; use Sem_Type;
with Sem_Util; use Sem_Util;
with Sem_Warn; use Sem_Warn;
+with Sinfo; use Sinfo;
with Sinput; use Sinput;
with Snames; use Snames;
with Stand; use Stand;
-with Sinfo; use Sinfo;
with Targparm; use Targparm;
with Ttypes; use Ttypes;
with Tbuild; use Tbuild;
@@ -1888,7 +1888,7 @@ package body Sem_Ch13 is
Set_From_Aspect_Specification (Aitem);
end Make_Aitem_Pragma;
- -- Start of processing for Analyze_Aspect_Specifications
+ -- Start of processing for Analyze_One_Aspect
begin
-- Skip aspect if already analyzed, to avoid looping in some cases
@@ -1934,8 +1934,25 @@ package body Sem_Ch13 is
Set_Analyzed (Aspect);
Set_Entity (Aspect, E);
+
+ -- Build the reference to E that will be used in the built pragmas
+
Ent := New_Occurrence_Of (E, Sloc (Id));
+ if A_Id = Aspect_Attach_Handler
+ or else A_Id = Aspect_Interrupt_Handler
+ then
+ -- Decorate the reference as comming from the sources and force
+ -- its reanalysis to generate the reference to E; required to
+ -- avoid reporting spurious warning on E as unreferenced entity
+ -- (because aspects are not fully analyzed).
+
+ Set_Comes_From_Source (Ent, Comes_From_Source (Id));
+ Set_Entity (Ent, Empty);
+
+ Analyze (Ent);
+ end if;
+
-- Check for duplicate aspect. Note that the Comes_From_Source
-- test allows duplicate Pre/Post's that we generate internally
-- to escape being flagged here.
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 512615f..ec47142 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -9127,9 +9127,13 @@ package body Sem_Ch3 is
end if;
end if;
- -- We similarly inherit predicates
+ -- We similarly inherit predicates. Note that for scalar derived types
+ -- the predicate is inherited from the first subtype, and not from its
+ -- (anonymous) base type.
- if Has_Predicates (Parent_Type) then
+ if Has_Predicates (Parent_Type)
+ or else Has_Predicates (First_Subtype (Parent_Type))
+ then
Set_Has_Predicates (Derived_Type);
end if;
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index ec449c1..b3e597f 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -8476,9 +8476,21 @@ package body Sem_Ch6 is
elsif Is_Entity_Name (E1) and then Is_Entity_Name (E2) then
if Present (Entity (E1)) then
return Entity (E1) = Entity (E2)
+
+ -- One may be a discriminant that has been replaced by
+ -- the correspondding discriminal
+
or else (Chars (Entity (E1)) = Chars (Entity (E2))
and then Ekind (Entity (E1)) = E_Discriminant
- and then Ekind (Entity (E2)) = E_In_Parameter);
+ and then Ekind (Entity (E2)) = E_In_Parameter)
+
+ -- AI12-050 : the loop variables of quantified expressions
+ -- match if the have the same identifier, even though they
+ -- are different entities.
+
+ or else (Chars (Entity (E1)) = Chars (Entity (E2))
+ and then Ekind (Entity (E1)) = E_Loop_Parameter
+ and then Ekind (Entity (E2)) = E_Loop_Parameter);
elsif Nkind (E1) = N_Expanded_Name
and then Nkind (E2) = N_Expanded_Name
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index ea86881..1a81cbf 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -760,9 +760,6 @@ package body Sem_Ch8 is
-- has already established its actual subtype. This is only relevant
-- if the renamed object is an explicit dereference.
- function In_Generic_Scope (E : Entity_Id) return Boolean;
- -- Determine whether entity E is inside a generic cope
-
------------------------------
-- Check_Constrained_Object --
------------------------------
@@ -824,26 +821,6 @@ package body Sem_Ch8 is
end if;
end Check_Constrained_Object;
- ----------------------
- -- In_Generic_Scope --
- ----------------------
-
- function In_Generic_Scope (E : Entity_Id) return Boolean is
- S : Entity_Id;
-
- begin
- S := Scope (E);
- while Present (S) and then S /= Standard_Standard loop
- if Is_Generic_Unit (S) then
- return True;
- end if;
-
- S := Scope (S);
- end loop;
-
- return False;
- end In_Generic_Scope;
-
-- Start of processing for Analyze_Object_Renaming
begin
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index fce4643..531dd70 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
@@ -4989,7 +4990,13 @@ package body Sem_Eval is
then
return False;
- elsif Has_Dynamic_Predicate_Aspect (Typ) then
+ -- If there is a dynamic predicate for the type (declared or inherited)
+ -- the expression is not static.
+
+ elsif Has_Dynamic_Predicate_Aspect (Typ)
+ or else (Is_Derived_Type (Typ)
+ and then Has_Aspect (Typ, Aspect_Dynamic_Predicate))
+ then
return False;
-- String types
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index ead3efd..58a157b 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -10518,6 +10518,26 @@ package body Sem_Util is
and then Assertion_Expression_Pragma (Get_Pragma_Id (Prag));
end In_Assertion_Expression_Pragma;
+ ----------------------
+ -- In_Generic_Scope --
+ ----------------------
+
+ function In_Generic_Scope (E : Entity_Id) return Boolean is
+ S : Entity_Id;
+
+ begin
+ S := Scope (E);
+ while Present (S) and then S /= Standard_Standard loop
+ if Is_Generic_Unit (S) then
+ return True;
+ end if;
+
+ S := Scope (S);
+ end loop;
+
+ return False;
+ end In_Generic_Scope;
+
-----------------
-- In_Instance --
-----------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index f1a12a9..a1e79b1 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -556,13 +556,11 @@ package Sem_Util is
-- Returns the declaration node enclosing N (including possibly N itself),
-- if any, or Empty otherwise.
- function Enclosing_Generic_Body
- (N : Node_Id) return Node_Id;
+ function Enclosing_Generic_Body (N : Node_Id) return Node_Id;
-- Returns the Node_Id associated with the innermost enclosing generic
-- body, if any. If none, then returns Empty.
- function Enclosing_Generic_Unit
- (N : Node_Id) return Node_Id;
+ function Enclosing_Generic_Unit (N : Node_Id) return Node_Id;
-- Returns the Node_Id associated with the innermost enclosing generic
-- unit, if any. If none, then returns Empty.
@@ -1193,6 +1191,9 @@ package Sem_Util is
-- Returns True if node N appears within a pragma that acts as an assertion
-- expression. See Sem_Prag for the list of qualifying pragmas.
+ function In_Generic_Scope (E : Entity_Id) return Boolean;
+ -- Returns True if entity E is inside a generic scope
+
function In_Instance return Boolean;
-- Returns True if the current scope is within a generic instance
diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c
index 5390209..679c70a 100644
--- a/gcc/ada/sysdep.c
+++ b/gcc/ada/sysdep.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 1992-2015, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2016, 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- *
@@ -193,7 +193,7 @@ __gnat_set_mode (int handle, int mode)
switch (mode) {
case 0 : WIN_SETMODE (handle, _O_BINARY); break;
- case 1 : WIN_SETMODE (handle, CurrentCCSEncoding); break;
+ case 1 : WIN_SETMODE (handle, __gnat_current_ccs_encoding); break;
case 2 : WIN_SETMODE (handle, _O_TEXT); break;
case 3 : WIN_SETMODE (handle, _O_U8TEXT); break;
case 4 : WIN_SETMODE (handle, _O_WTEXT); break;