aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2017-05-22 09:24:24 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2017-05-22 09:24:24 +0000
commitd327113612c1b089eee87f04cd517b7f7103c1ea (patch)
tree5b660c58c813d8aea1e713136d95cb2b70afe62d /gcc/ada/gcc-interface/decl.c
parent4c24ec6d58db238f64bda456ebdb0b5c82347d78 (diff)
downloadgcc-d327113612c1b089eee87f04cd517b7f7103c1ea.zip
gcc-d327113612c1b089eee87f04cd517b7f7103c1ea.tar.gz
gcc-d327113612c1b089eee87f04cd517b7f7103c1ea.tar.bz2
sem_ch4.adb (Analyze_Call): In Ada2012 an incomplete type from a limited view may appear in the profile of...
* sem_ch4.adb (Analyze_Call): In Ada2012 an incomplete type from a limited view may appear in the profile of a function, and a call to that function in another unit in which the full view is available must use this full view to spurious type errors at the point of call. * inline.adb (Analyze_Inlined_Bodies): Remove restriction on loading of parent body with a with clause for the main unit. * gcc-interface/decl.c (defer_limited_with_list): Document new usage. (gnat_to_gnu_entity) <E_Access_Type>: Handle completed Taft Amendment types declared in external units like types from limited with clauses. Adjust final processing of defer_limited_with_list accordingly. * gcc-interface/trans.c (gnat_to_gnu) < N_Selected_Component>: Try again to translate the prefix after the field if it is incomplete. From-SVN: r248321
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 4bf1464..91a03cd 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -101,8 +101,8 @@ struct incomplete
static int defer_incomplete_level = 0;
static struct incomplete *defer_incomplete_list;
-/* This variable is used to delay expanding From_Limited_With types until the
- end of the spec. */
+/* This variable is used to delay expanding types coming from a limited with
+ clause and completed Taft Amendment types until the end of the spec. */
static struct incomplete *defer_limited_with_list;
typedef struct subst_pair_d {
@@ -3580,6 +3580,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
const bool is_from_limited_with
= (IN (Ekind (gnat_desig_equiv), Incomplete_Kind)
&& From_Limited_With (gnat_desig_equiv));
+ /* Whether it is a completed Taft Amendment type. Such a type is to
+ be treated as coming from a limited with clause if it is not in
+ the main unit, i.e. we break potential circularities here in case
+ the body of an external unit is loaded for inter-unit inlining. */
+ const bool is_completed_taft_type
+ = (IN (Ekind (gnat_desig_equiv), Incomplete_Kind)
+ && Has_Completion_In_Body (gnat_desig_equiv)
+ && Present (Full_View (gnat_desig_equiv)));
/* The "full view" of the designated type. If this is an incomplete
entity from a limited with, treat its non-limited view as the full
view. Otherwise, if this is an incomplete or private type, use the
@@ -3646,13 +3654,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* Get the type of the thing we are to point to and build a pointer to
it. If it is a reference to an incomplete or private type with a
- full view that is a record or an array, make a dummy type node and
- get the actual type later when we have verified it is safe. */
+ full view that is a record, an array or an access, make a dummy type
+ and get the actual type later when we have verified it is safe. */
else if ((!in_main_unit
&& !present_gnu_tree (gnat_desig_equiv)
&& Present (gnat_desig_full)
&& (Is_Record_Type (gnat_desig_full)
- || Is_Array_Type (gnat_desig_full)))
+ || Is_Array_Type (gnat_desig_full)
+ || Is_Access_Type (gnat_desig_full)))
/* Likewise if this is a reference to a record, an array or a
subprogram type and we are to defer elaborating incomplete
types. We do this because this access type may be the full
@@ -3763,7 +3772,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
save_gnu_tree (gnat_entity, gnu_decl, false);
saved = true;
- if (defer_incomplete_level == 0 && !is_from_limited_with)
+ if (defer_incomplete_level == 0
+ && !is_from_limited_with
+ && !is_completed_taft_type)
{
update_pointer_to (TYPE_MAIN_VARIANT (gnu_desig_type),
gnat_to_gnu_type (gnat_desig_equiv));
@@ -3772,7 +3783,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
{
struct incomplete *p = XNEW (struct incomplete);
struct incomplete **head
- = (is_from_limited_with
+ = (is_from_limited_with || is_completed_taft_type
? &defer_limited_with_list : &defer_incomplete_list);
p->old_type = gnu_desig_type;
@@ -4766,7 +4777,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
}
for (p = defer_limited_with_list; p; p = p->next)
- if (p->old_type && Non_Limited_View (p->full_type) == gnat_entity)
+ if (p->old_type
+ && (Non_Limited_View (p->full_type) == gnat_entity
+ || Full_View (p->full_type) == gnat_entity))
{
update_pointer_to (TYPE_MAIN_VARIANT (p->old_type),
TREE_TYPE (gnu_decl));