===================================================================
@@ -182,6 +182,7 @@
* Pragma Main::
* Pragma Main_Storage::
* Pragma No_Body::
+* Pragma No_Inline::
* Pragma No_Return::
* Pragma No_Strict_Aliasing ::
* Pragma Normalize_Scalars::
@@ -934,6 +935,7 @@
* Pragma Main::
* Pragma Main_Storage::
* Pragma No_Body::
+* Pragma No_Inline::
* Pragma No_Return::
* Pragma No_Strict_Aliasing::
* Pragma Normalize_Scalars::
@@ -3373,8 +3375,8 @@
@noindent
Similar to pragma @code{Inline} except that inlining is not subject to
-the use of option @option{-gnatn} and the inlining happens regardless of
-whether this option is used.
+the use of option @option{-gnatn} or @option{-gnatN} and the inlining
+happens regardless of whether these options are used.
@node Pragma Inline_Generic
@unnumberedsec Pragma Inline_Generic
@@ -4020,6 +4022,24 @@
dummy body with a No_Body pragma ensures that there is no interference from
earlier versions of the package body.
+@node Pragma No_Inline
+@unnumberedsec Pragma No_Inline
+@findex No_Inline
+@noindent
+Syntax:
+
+@smallexample @c ada
+pragma No_Inline (NAME [, NAME]);
+@end smallexample
+
+@noindent
+This pragma suppresses inlining for the callable entity or the instances of
+the generic subprogram designated by @var{NAME}, including inlining that
+results from the use of pragma @code{Inline}. This pragma is always active,
+in particular it is not subject to the use of option @option{-gnatn} or
+@option{-gnatN}. It is illegal to specify both pragma @code{No_Inline} and
+pragma @code{Inline_Always} for the same @var{NAME}.
+
@node Pragma No_Return
@unnumberedsec Pragma No_Return
@findex No_Return
===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 1992-2013, 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- --
@@ -483,6 +483,7 @@
-- Is_Ada_2012_Only Flag199
-- Has_Delayed_Aspects Flag200
+ -- Has_Pragma_No_Inline Flag201
-- Itype_Printed Flag202
-- Has_Pragma_Pure Flag203
-- Is_Known_Null Flag204
@@ -542,8 +543,6 @@
-- Has_Anonymous_Master Flag253
-- Is_Implementation_Defined Flag254
- -- (unused) Flag201
-
-- (unused) Flag255
-- (unused) Flag256
-- (unused) Flag257
@@ -1560,6 +1559,11 @@
return Flag230 (Id);
end Has_Pragma_Inline_Always;
+ function Has_Pragma_No_Inline (Id : E) return B is
+ begin
+ return Flag201 (Id);
+ end Has_Pragma_No_Inline;
+
function Has_Pragma_Ordered (Id : E) return B is
begin
pragma Assert (Is_Enumeration_Type (Id));
@@ -4111,6 +4115,11 @@
Set_Flag230 (Id, V);
end Set_Has_Pragma_Inline_Always;
+ procedure Set_Has_Pragma_No_Inline (Id : E; V : B := True) is
+ begin
+ Set_Flag201 (Id, V);
+ end Set_Has_Pragma_No_Inline;
+
procedure Set_Has_Pragma_Ordered (Id : E; V : B := True) is
begin
pragma Assert (Is_Enumeration_Type (Id));
@@ -7686,6 +7695,7 @@
W ("Has_Pragma_Elaborate_Body", Flag150 (Id));
W ("Has_Pragma_Inline", Flag157 (Id));
W ("Has_Pragma_Inline_Always", Flag230 (Id));
+ W ("Has_Pragma_No_Inline", Flag201 (Id));
W ("Has_Pragma_Ordered", Flag198 (Id));
W ("Has_Pragma_Pack", Flag121 (Id));
W ("Has_Pragma_Preelab_Init", Flag221 (Id));
===================================================================
@@ -1671,6 +1671,11 @@
-- pragma Inline_Always applies. Note that if this flag is set, the flag
-- Has_Pragma_Inline is also set.
+-- Has_Pragma_No_Inline (Flag201)
+-- Defined in all entities. Set for functions and procedures for which a
+-- pragma No_Inline applies. Note that if this flag is set, the flag
+-- Has_Pragma_Inline_Always cannot be set.
+
-- Has_Pragma_Ordered (Flag198) [implementation base type only]
-- Defined in entities for enumeration types. If set indicates that a
-- valid pragma Ordered was given for the type. This flag is inherited
@@ -4833,6 +4838,7 @@
-- Has_Pragma_Elaborate_Body (Flag150)
-- Has_Pragma_Inline (Flag157)
-- Has_Pragma_Inline_Always (Flag230)
+ -- Has_Pragma_No_Inline (Flag201)
-- Has_Pragma_Pure (Flag203)
-- Has_Pragma_Pure_Function (Flag179)
-- Has_Pragma_Thread_Local_Storage (Flag169)
@@ -6232,6 +6238,7 @@
function Has_Pragma_Elaborate_Body (Id : E) return B;
function Has_Pragma_Inline (Id : E) return B;
function Has_Pragma_Inline_Always (Id : E) return B;
+ function Has_Pragma_No_Inline (Id : E) return B;
function Has_Pragma_Ordered (Id : E) return B;
function Has_Pragma_Pack (Id : E) return B;
function Has_Pragma_Preelab_Init (Id : E) return B;
@@ -6831,6 +6838,7 @@
procedure Set_Has_Pragma_Elaborate_Body (Id : E; V : B := True);
procedure Set_Has_Pragma_Inline (Id : E; V : B := True);
procedure Set_Has_Pragma_Inline_Always (Id : E; V : B := True);
+ procedure Set_Has_Pragma_No_Inline (Id : E; V : B := True);
procedure Set_Has_Pragma_Ordered (Id : E; V : B := True);
procedure Set_Has_Pragma_Pack (Id : E; V : B := True);
procedure Set_Has_Pragma_Preelab_Init (Id : E; V : B := True);
@@ -7521,6 +7529,7 @@
pragma Inline (Has_Pragma_Elaborate_Body);
pragma Inline (Has_Pragma_Inline);
pragma Inline (Has_Pragma_Inline_Always);
+ pragma Inline (Has_Pragma_No_Inline);
pragma Inline (Has_Pragma_Ordered);
pragma Inline (Has_Pragma_Pack);
pragma Inline (Has_Pragma_Preelab_Init);
@@ -7971,6 +7980,7 @@
pragma Inline (Set_Has_Pragma_Elaborate_Body);
pragma Inline (Set_Has_Pragma_Inline);
pragma Inline (Set_Has_Pragma_Inline_Always);
+ pragma Inline (Set_Has_Pragma_No_Inline);
pragma Inline (Set_Has_Pragma_Ordered);
pragma Inline (Set_Has_Pragma_Pack);
pragma Inline (Set_Has_Pragma_Preelab_Init);
===================================================================
@@ -886,11 +886,16 @@
-- to declare types that match predefined C types, especially for cases
-- without corresponding Ada predefined type.
- procedure Process_Inline (Active : Boolean);
- -- Common processing for Inline and Inline_Always. The parameter
- -- indicates if the inline pragma is active, i.e. if it should actually
- -- cause inlining to occur.
+ type Inline_Status is (Suppressed, Disabled, Enabled);
+ -- Inline status of a subprogram, indicated as follows:
+ -- Suppressed: inlining is suppressed for the subprogram
+ -- Disabled: no inlining is requested for the subprogram
+ -- Enabled: inlining is requested/required for the subprogram
+ procedure Process_Inline (Status : Inline_Status);
+ -- Common processing for Inline, Inline_Always and No_Inline. Parameter
+ -- indicates the inline status specified by the pragma.
+
procedure Process_Interface_Name
(Subprogram_Def : Entity_Id;
Ext_Arg : Node_Id;
@@ -4912,7 +4917,7 @@
-- Process_Inline --
--------------------
- procedure Process_Inline (Active : Boolean) is
+ procedure Process_Inline (Status : Inline_Status) is
Assoc : Node_Id;
Decl : Node_Id;
Subp_Id : Node_Id;
@@ -5017,7 +5022,9 @@
-- If inlining is not possible, for now do not treat as an error
- elsif Inlining_Not_Possible (Subp) then
+ elsif Status /= Suppressed
+ and then Inlining_Not_Possible (Subp)
+ then
Applies := True;
return;
@@ -5145,18 +5152,56 @@
procedure Set_Inline_Flags (Subp : Entity_Id) is
begin
- if Active then
- Set_Is_Inlined (Subp);
- end if;
+ -- First set the Has_Pragma_XXX flags and issue the appropriate
+ -- errors and warnings for suspicious combinations.
- if not Has_Pragma_Inline (Subp) then
- Set_Has_Pragma_Inline (Subp);
- Effective := True;
+ if Prag_Id = Pragma_No_Inline then
+ if Has_Pragma_Inline_Always (Subp) then
+ Error_Msg_N
+ ("Inline_Always and No_Inline are mutually exclusive", N);
+ elsif Has_Pragma_Inline (Subp) then
+ Error_Msg_NE
+ ("Inline and No_Inline both specified for& ??",
+ N, Entity (Subp_Id));
+ end if;
+
+ Set_Has_Pragma_No_Inline (Subp);
+ else
+ if Prag_Id = Pragma_Inline_Always then
+ if Has_Pragma_No_Inline (Subp) then
+ Error_Msg_N
+ ("Inline_Always and No_Inline are mutually exclusive",
+ N);
+ end if;
+
+ Set_Has_Pragma_Inline_Always (Subp);
+ else
+ if Has_Pragma_No_Inline (Subp) then
+ Error_Msg_NE
+ ("Inline and No_Inline both specified for& ??",
+ N, Entity (Subp_Id));
+ end if;
+ end if;
+
+ if not Has_Pragma_Inline (Subp) then
+ Set_Has_Pragma_Inline (Subp);
+ Effective := True;
+ end if;
end if;
- if Prag_Id = Pragma_Inline_Always then
- Set_Has_Pragma_Inline_Always (Subp);
- end if;
+ -- Then adjust the Is_Inlined flag. It can never be set if the
+ -- subprogram is subject to pragma No_Inline.
+
+ case Status is
+ when Suppressed =>
+ Set_Is_Inlined (Subp, False);
+ when Disabled =>
+ null;
+ when Enabled =>
+ if not Has_Pragma_No_Inline (Subp) then
+ Set_Is_Inlined (Subp, True);
+ end if;
+ end case;
end Set_Inline_Flags;
-- Start of processing for Process_Inline
@@ -5165,7 +5210,7 @@
Check_No_Identifiers;
Check_At_Least_N_Arguments (1);
- if Active then
+ if Status = Enabled then
Inline_Processing_Required := True;
end if;
@@ -5211,7 +5256,7 @@
elsif not Effective
and then Warn_On_Redundant_Constructs
- and then not Suppress_All_Inlining
+ and then not (Status = Suppressed or Suppress_All_Inlining)
then
if Inlining_Not_Possible (Subp) then
Error_Msg_NE
@@ -11061,9 +11106,13 @@
when Pragma_Inline =>
- -- Pragma is active if inlining option is active
+ -- Inline status is Enabled if inlining option is active
- Process_Inline (Inline_Active);
+ if Inline_Active then
+ Process_Inline (Enabled);
+ else
+ Process_Inline (Disabled);
+ end if;
-------------------
-- Inline_Always --
@@ -11078,7 +11127,7 @@
-- this causes walk order issues.
if not (CodePeer_Mode or Alfa_Mode) then
- Process_Inline (True);
+ Process_Inline (Enabled);
end if;
--------------------
@@ -12614,6 +12663,16 @@
Pragma_Misplaced;
---------------
+ -- No_Inline --
+ ---------------
+
+ -- pragma No_Inline ( NAME {, NAME} );
+
+ when Pragma_No_Inline =>
+ GNAT_Pragma;
+ Process_Inline (Suppressed);
+
+ ---------------
-- No_Return --
---------------
@@ -16630,6 +16689,7 @@
Pragma_Memory_Size => -1,
Pragma_No_Return => 0,
Pragma_No_Body => 0,
+ Pragma_No_Inline => 0,
Pragma_No_Run_Time => -1,
Pragma_No_Strict_Aliasing => -1,
Pragma_Normalize_Scalars => -1,
===================================================================
@@ -4055,7 +4055,8 @@
results from the use of the pragma @code{Inline_Always}.
Any occurrences of pragma @code{Inline} or @code{Inline_Always}
are ignored, and @option{-gnatn} and @option{-gnatN} have no
-effect if this switch is present.
+effects if this switch is present. Note that inlining can also
+be suppressed on a finer-grained basis with pragma @code{No_Inline}.
@item -fno-inline-functions
@cindex @option{-fno-inline-functions} (@command{gcc})
===================================================================
@@ -1210,6 +1210,7 @@
Pragma_Main_Storage |
Pragma_Memory_Size |
Pragma_No_Body |
+ Pragma_No_Inline |
Pragma_No_Return |
Pragma_No_Run_Time |
Pragma_No_Strict_Aliasing |
===================================================================
@@ -549,6 +549,7 @@
Name_Main_Storage : constant Name_Id := N + $; -- GNAT
Name_Memory_Size : constant Name_Id := N + $; -- Ada 83
Name_No_Body : constant Name_Id := N + $; -- GNAT
+ Name_No_Inline : constant Name_Id := N + $; -- GNAT
Name_No_Return : constant Name_Id := N + $; -- Ada 05
Name_Obsolescent : constant Name_Id := N + $; -- GNAT
Name_Optimize : constant Name_Id := N + $;
@@ -1819,6 +1820,7 @@
Pragma_Main_Storage,
Pragma_Memory_Size,
Pragma_No_Body,
+ Pragma_No_Inline,
Pragma_No_Return,
Pragma_Obsolescent,
Pragma_Optimize,