2011-12-21 Javier Miranda <miranda@adacore.com>
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Dec 2011 13:54:55 +0000 (13:54 +0000)
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Dec 2011 13:54:55 +0000 (13:54 +0000)
* sem_ch3.ads, sem_ch3.adb (Check_CPP_Type): New subprogram.
(Process_Full_View): Invoke Check_CPP_Type if processing the
full-view of a CPP type.
* sem_prag.adb (Process_Import_Or_Interface): Add missing support
for importing a CPP type that has an incomplete declaration. Move
to new routine Check_CPP_Type the code that verifies that
components of imported CPP types do not have default expressions.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182587 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/sem_ch3.adb
gcc/ada/sem_ch3.ads
gcc/ada/sem_prag.adb

index 64de1d4..b8f30a9 100644 (file)
@@ -1,3 +1,13 @@
+2011-12-21  Javier Miranda  <miranda@adacore.com>
+
+       * sem_ch3.ads, sem_ch3.adb (Check_CPP_Type): New subprogram.
+       (Process_Full_View): Invoke Check_CPP_Type if processing the
+       full-view of a CPP type.
+       * sem_prag.adb (Process_Import_Or_Interface): Add missing support
+       for importing a CPP type that has an incomplete declaration. Move
+       to new routine Check_CPP_Type the code that verifies that
+       components of imported CPP types do not have default expressions.
+
 2011-12-21  Vincent Celier  <celier@adacore.com>
 
        * prj-nmsc.adb (Report_No_Sources): Remove argument Lang. Report
index 69c5ebf..7de6f86 100644 (file)
@@ -9640,6 +9640,38 @@ package body Sem_Ch3 is
       end loop;
    end Check_Completion;
 
+   --------------------
+   -- Check_CPP_Type --
+   --------------------
+
+   procedure Check_CPP_Type (T : Entity_Id) is
+      Tdef  : constant Node_Id := Type_Definition (Declaration_Node (T));
+      Clist : Node_Id;
+      Comp  : Node_Id;
+
+   begin
+      if Nkind (Tdef) = N_Record_Definition then
+         Clist := Component_List (Tdef);
+
+      else
+         pragma Assert (Nkind (Tdef) = N_Derived_Type_Definition);
+         Clist := Component_List (Record_Extension_Part (Tdef));
+      end if;
+
+      if Present (Clist) then
+         Comp := First (Component_Items (Clist));
+         while Present (Comp) loop
+            if Present (Expression (Comp)) then
+               Error_Msg_N
+                 ("component of imported 'C'P'P type cannot have" &
+                    " default expression", Expression (Comp));
+            end if;
+
+            Next (Comp);
+         end loop;
+      end if;
+   end Check_CPP_Type;
+
    ----------------------------
    -- Check_Delta_Expression --
    ----------------------------
@@ -18094,6 +18126,11 @@ package body Sem_Ch3 is
       if Is_CPP_Class (Priv_T) then
          Set_Is_CPP_Class (Full_T);
          Set_Convention   (Full_T, Convention_CPP);
+
+         --  Check that components of imported CPP types do not have default
+         --  expressions.
+
+         Check_CPP_Type (Full_T);
       end if;
 
       --  If the private view has user specified stream attributes, then so has
index 514cdf3..7b4d2a9 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2010, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2011, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -115,6 +115,10 @@ package Sem_Ch3 is
    --  and errors are posted on that node, rather than on the declarations that
    --  require completion in the package declaration.
 
+   procedure Check_CPP_Type (T : Entity_Id);
+   --  Check that components of imported CPP type T do not have default
+   --  expressions because the constructor (if any) is on the C++ side.
+
    procedure Derive_Subprogram
      (New_Subp     : in out Entity_Id;
       Parent_Subp  : Entity_Id;
index a36af20..adde2d6 100644 (file)
@@ -4602,9 +4602,26 @@ package body Sem_Prag is
 
          --  Import a CPP class
 
-         elsif Is_Record_Type (Def_Id)
-           and then C = Convention_CPP
+         elsif C = Convention_CPP
+           and then (Is_Record_Type (Def_Id)
+                       or else Ekind (Def_Id) = E_Incomplete_Type)
          then
+            if Ekind (Def_Id) = E_Incomplete_Type then
+               if Present (Full_View (Def_Id)) then
+                  Def_Id := Full_View (Def_Id);
+               else
+                  Error_Msg_N
+                    ("cannot import 'C'P'P type before full declaration seen",
+                     Get_Pragma_Arg (Arg2));
+
+                  --  Although we have reported the error we decorate it as
+                  --  CPP_Class to avoid reporting spurious errors
+
+                  Set_Is_CPP_Class (Def_Id);
+                  return;
+               end if;
+            end if;
+
             --  Types treated as CPP classes must be declared limited (note:
             --  this used to be a warning but there is no real benefit to it
             --  since we did effectively intend to treat the type as limited
@@ -4628,38 +4645,13 @@ package body Sem_Prag is
                           (Declaration_Node (Def_Id))));
             end if;
 
-            --  Components of imported CPP types must not have default
-            --  expressions because the constructor (if any) is on the
-            --  C++ side.
-
-            declare
-               Tdef  : constant Node_Id :=
-                         Type_Definition (Declaration_Node (Def_Id));
-               Clist : Node_Id;
-               Comp  : Node_Id;
-
-            begin
-               if Nkind (Tdef) = N_Record_Definition then
-                  Clist := Component_List (Tdef);
-
-               else
-                  pragma Assert (Nkind (Tdef) = N_Derived_Type_Definition);
-                  Clist := Component_List (Record_Extension_Part (Tdef));
-               end if;
-
-               if Present (Clist) then
-                  Comp := First (Component_Items (Clist));
-                  while Present (Comp) loop
-                     if Present (Expression (Comp)) then
-                        Error_Msg_N
-                          ("component of imported 'C'P'P type cannot have" &
-                           " default expression", Expression (Comp));
-                     end if;
+            --  Check that components of imported CPP types do not have default
+            --  expressions. For private types this check is performed when the
+            --  full view is analyzed (see Process_Full_View).
 
-                     Next (Comp);
-                  end loop;
-               end if;
-            end;
+            if not Is_Private_Type (Def_Id) then
+               Check_CPP_Type (Def_Id);
+            end if;
 
          elsif Nkind (Parent (Def_Id)) = N_Incomplete_Type_Declaration then
             Check_No_Link_Name;
@@ -7629,8 +7621,8 @@ package body Sem_Prag is
                   Get_Pragma_Arg (Arg1));
             end if;
 
-            Set_Is_CPP_Class      (Typ);
-            Set_Convention        (Typ, Convention_CPP);
+            Set_Is_CPP_Class (Typ);
+            Set_Convention (Typ, Convention_CPP);
 
             --  Imported CPP types must not have discriminants (because C++
             --  classes do not have discriminants).