|
1 | 1 | /* |
2 | | - * Copyright (c) 2010-2018, NVIDIA CORPORATION. All rights reserved. |
| 2 | + * Copyright (c) 2010-2019, NVIDIA CORPORATION. All rights reserved. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
@@ -30,6 +30,8 @@ static struct type_desc *I8(__f03_ty_to_id)[]; |
30 | 30 | void ENTF90(SET_INTRIN_TYPE, set_intrin_type)(F90_Desc *dd, |
31 | 31 | __INT_T intrin_type); |
32 | 32 |
|
| 33 | +static TYPE_DESC * get_parent_pointer(TYPE_DESC *src_td, __INT_T level); |
| 34 | + |
33 | 35 | #define ARG1_PTR 0x1 |
34 | 36 | #define ARG1_ALLOC 0x2 |
35 | 37 | #define ARG2_PTR 0x4 |
@@ -135,8 +137,7 @@ ENTF90(EXTENDS_TYPE_OF, extends_type_of) |
135 | 137 | return GET_DIST_TRUE_LOG; |
136 | 138 |
|
137 | 139 | if (atd->obj.level > btd->obj.level) { |
138 | | - __INT_T offset = (btd->obj.level + 1) * sizeof(__POINT_T); |
139 | | - TYPE_DESC *parent = *((TYPE_DESC **)(((char *)atd) - offset)); |
| 140 | + TYPE_DESC *parent = get_parent_pointer(atd, btd->obj.level+1); |
140 | 141 | if (btd == parent) |
141 | 142 | return GET_DIST_TRUE_LOG; |
142 | 143 | } |
@@ -245,8 +246,7 @@ ENTF90(KEXTENDS_TYPE_OF, kextends_type_of) |
245 | 246 | return GET_DIST_TRUE_LOG; |
246 | 247 |
|
247 | 248 | if (atd->obj.level > btd->obj.level) { |
248 | | - __INT_T offset = (btd->obj.level + 1) * sizeof(__POINT_T); |
249 | | - TYPE_DESC *parent = *((TYPE_DESC **)(((char *)atd) - offset)); |
| 249 | + TYPE_DESC *parent = get_parent_pointer(atd, btd->obj.level+1); |
250 | 250 | if (btd == parent) |
251 | 251 | return GET_DIST_TRUE_LOG; |
252 | 252 | } |
@@ -310,6 +310,50 @@ ENTF90(KGET_OBJECT_SIZE, kget_object_size)(F90_Desc *d) |
310 | 310 | return (__INT8_T)(td ? td->obj.size : od->size); |
311 | 311 | } |
312 | 312 |
|
| 313 | +/** \brief Returns a type descriptor pointer of a specified ancestor of |
| 314 | + * a type descriptor. |
| 315 | + * |
| 316 | + * \param src_td is the type descriptor used to locate the ancestor type |
| 317 | + * type descriptor. |
| 318 | + * \param level specifies the heirarchical position in the inheritance graph |
| 319 | + * of the desired ancestor type descriptor. To find its immediate |
| 320 | + * parent, specify a level equal to src_td's level. |
| 321 | + * |
| 322 | + * \return a type descriptor representing the ancestor or NULL if there is no |
| 323 | + * ancestor. |
| 324 | + */ |
| 325 | +static TYPE_DESC * |
| 326 | +get_parent_pointer(TYPE_DESC *src_td, __INT_T level) |
| 327 | +{ |
| 328 | + |
| 329 | + __INT_T offset, src_td_level; |
| 330 | + TYPE_DESC *parent; |
| 331 | + |
| 332 | + if (level <= 0 || src_td == NULL) |
| 333 | + return NULL; |
| 334 | + |
| 335 | + src_td_level = src_td->obj.level; |
| 336 | + if (src_td_level < 0 || level > src_td_level) |
| 337 | + return NULL; |
| 338 | + |
| 339 | + if (src_td->parents != NULL) { |
| 340 | + /* The parents field is filled in, so use it to get the desired parent */ |
| 341 | + offset = (src_td_level - level) * sizeof(__POINT_T); |
| 342 | + parent = *((TYPE_DESC **)(((char *)src_td->parents) + offset)); |
| 343 | + } else { |
| 344 | + /* The parents field is not filled in, so find the parent from the |
| 345 | + * src_td base pointer. The parents field is not filled in |
| 346 | + * when a type descriptor is created with an older compiler. |
| 347 | + * Note: This method does not always work if the type descriptor is |
| 348 | + * defined in a shared library. |
| 349 | + */ |
| 350 | + offset = level * sizeof(__POINT_T); |
| 351 | + parent = *((TYPE_DESC **)(((char *)src_td) - offset)); |
| 352 | + } |
| 353 | + |
| 354 | + return parent; |
| 355 | + |
| 356 | +} |
313 | 357 | static void |
314 | 358 | process_final_procedures(char *area, F90_Desc *sd) |
315 | 359 | { |
@@ -408,8 +452,9 @@ process_final_procedures(char *area, F90_Desc *sd) |
408 | 452 |
|
409 | 453 | if (((F90_Desc *)src_td)->tag == __POLY && src_td->obj.level > 0) { |
410 | 454 | /* process parent finals */ |
411 | | - __INT_T offset = (src_td->obj.level) * sizeof(__POINT_T); |
412 | | - TYPE_DESC *parent = *((TYPE_DESC **)(((char *)src_td) - offset)); |
| 455 | + TYPE_DESC *parent = get_parent_pointer(src_td, src_td->obj.level); |
| 456 | + |
| 457 | + |
413 | 458 |
|
414 | 459 | if (rank > 0) { |
415 | 460 | int i; |
@@ -910,14 +955,12 @@ void I8(__fort_dump_type)(TYPE_DESC *d) |
910 | 955 | fprintf(__io_stderr(), "Size: %d\n", d->obj.size); |
911 | 956 | fprintf(__io_stderr(), "Type Descriptor:\n\t'%s'\n", d->name); |
912 | 957 | if (d->obj.level > 0) { |
913 | | - TYPE_DESC *parent; |
914 | 958 | __INT_T offset, level; |
915 | 959 | fprintf(__io_stderr(), "(Child Type)\n"); |
916 | 960 | fprintf(__io_stderr(), "Parent Descriptor%s\n", |
917 | 961 | (d->obj.level == 1) ? ":" : "s:"); |
918 | 962 | for (level = d->obj.level - 1; level >= 0; --level) { |
919 | | - offset = (level + 1) * sizeof(__POINT_T); |
920 | | - TYPE_DESC *parent = *((TYPE_DESC **)(((char *)d) - offset)); |
| 963 | + TYPE_DESC *parent = get_parent_pointer(d, level+1); |
921 | 964 | fprintf(__io_stderr(), "\t'%s'\n", parent->name); |
922 | 965 | } |
923 | 966 |
|
|
0 commit comments