decl.c (annotate_value): Be prepared for discriminants inherited from parent record...
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 6 Jan 2013 11:41:47 +0000 (11:41 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 6 Jan 2013 11:41:47 +0000 (11:41 +0000)
* gcc-interface/decl.c (annotate_value) <COMPONENT_REF>: Be prepared
for discriminants inherited from parent record types.

From-SVN: r194939

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c

index 14ee24d..1ade2a0 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (annotate_value) <COMPONENT_REF>: Be prepared
+       for discriminants inherited from parent record types.
+
 2013-01-04  Robert Dewar  <dewar@adacore.com>
 
        * warnsw.adb: Minor fixes to -gnatw.d handling.
index 094d7e0..f7db364 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *          Copyright (C) 1992-2012, Free Software Foundation, Inc.         *
+ *          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- *
@@ -4965,7 +4965,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
            }
        }
 
-      /* If this is a record type or subtype, call elaborate_expression_1 on
+      /* If this is a record type or subtype, call elaborate_expression_2 on
         any field position.  Do this for both global and local types.
         Skip any fields that we haven't made trees for to avoid problems with
         class wide types.  */
@@ -7286,15 +7286,22 @@ annotate_value (tree gnu_size)
 
     case COMPONENT_REF:
       /* The only case we handle here is a simple discriminant reference.  */
-      if (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == PLACEHOLDER_EXPR
-         && TREE_CODE (TREE_OPERAND (gnu_size, 1)) == FIELD_DECL
-         && DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1)))
-       return Create_Node (Discrim_Val,
-                           annotate_value (DECL_DISCRIMINANT_NUMBER
-                                           (TREE_OPERAND (gnu_size, 1))),
-                           No_Uint, No_Uint);
-      else
-       return No_Uint;
+      if (DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1)))
+       {
+         tree n = DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1));
+
+         /* Climb up the chain of successive extensions, if any.  */
+         while (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == COMPONENT_REF
+                && DECL_NAME (TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 1))
+                   == parent_name_id)
+           gnu_size = TREE_OPERAND (gnu_size, 0);
+
+         if (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == PLACEHOLDER_EXPR)
+           return
+             Create_Node (Discrim_Val, annotate_value (n), No_Uint, No_Uint);
+       }
+
+      return No_Uint;
 
     CASE_CONVERT:   case NON_LVALUE_EXPR:
       return annotate_value (TREE_OPERAND (gnu_size, 0));