00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "defines.h"
00010 #include "host.m"
00011 #include "host.h"
00012 #include "target.m"
00013 #include "globals.m"
00014 #include "globals.h"
00015 #include "sytb.m"
00016 #include "tokens.h"
00017 #include "sytb.h"
00018 #include "s_globals.h"
00019
00020 #if defined(TARG_X8664) || defined(TARG_IA32) || defined(TARG_MIPS) || defined(TARG_IA64)
00021
00022 static unsigned char interoperable_types[] = {
00023 0,
00024 0,
00025 0,
00026 0,
00027 0,
00028 0,
00029 0,
00030 0,
00031 1,
00032 1,
00033 1,
00034 1,
00035 1,
00036 1,
00037 0,
00038 1,
00039 1,
00040 0,
00041 0,
00042 1,
00043 0,
00044 0,
00045 0,
00046 0,
00047 0,
00048 0,
00049 0,
00050 0,
00051 0
00052 };
00053 #else
00054 # error "Define interoperable_types for target architecture"
00055 #endif
00056
00057 static void check_interoperable_data(int);
00058 static void check_interoperable_pgm_unit(int);
00059 static void check_interoperable_derived_type(int);
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 boolean
00075 check_interoperable_type(int attr_idx, boolean quiet, boolean ck_arrayness) {
00076 #ifdef _DEBUG
00077 static int checked = 0;
00078 if (!checked) {
00079 checked = 1;
00080 if ((sizeof interoperable_types) != Num_Linear_Types) {
00081 if (!quiet) {
00082 PRINTMSG(1, 1044, Internal, 1,
00083 "interoperable_types table out of sync with linear types");
00084 }
00085 return FALSE;
00086 }
00087 }
00088 #endif
00089
00090 int atd_array_idx = ATD_ARRAY_IDX(attr_idx);
00091 if (ck_arrayness && atd_array_idx != NULL_IDX) {
00092 bd_array_type bd_array_class = BD_ARRAY_CLASS(atd_array_idx);
00093 if (bd_array_class != Explicit_Shape && bd_array_class != Assumed_Size) {
00094 if (!quiet) {
00095 PRINTMSG(AT_DEF_LINE(attr_idx), 1691, Error, AT_DEF_COLUMN(attr_idx),
00096 AT_OBJ_NAME_PTR(attr_idx),
00097 "non-explicit-shape or non-assumed-size array");
00098 }
00099 return FALSE;
00100 }
00101 }
00102 int type_idx = ATD_TYPE_IDX(attr_idx);
00103 int linear_type = TYP_LINEAR(type_idx);
00104 if (linear_type == Structure_Type) {
00105 int type_attr_idx = TYP_IDX(type_idx);
00106 if (!AT_BIND_ATTR(type_attr_idx)) {
00107 if (!quiet) {
00108 PRINTMSG(AT_DEF_LINE(attr_idx), 1693, Error, AT_DEF_COLUMN(attr_idx),
00109 AT_OBJ_NAME_PTR(attr_idx), AT_OBJ_NAME_PTR(type_attr_idx));
00110 }
00111 return FALSE;
00112 }
00113 else {
00114 check_interoperable_derived_type(type_attr_idx);
00115 }
00116 }
00117 else if (linear_type == Character_1) {
00118 if (!length_type_param_is_one(attr_idx)) {
00119 if (!quiet) {
00120 PRINTMSG(AT_DEF_LINE(attr_idx), 1695, Error, AT_DEF_COLUMN(attr_idx),
00121 AT_OBJ_NAME_PTR(attr_idx));
00122 }
00123 return FALSE;
00124 }
00125 }
00126 else if (!interoperable_types[linear_type]) {
00127 if (!quiet) {
00128 PRINTMSG(AT_DEF_LINE(attr_idx), 1691, Error, AT_DEF_COLUMN(attr_idx),
00129 AT_OBJ_NAME_PTR(attr_idx), get_basic_type_str(type_idx));
00130 }
00131 return FALSE;
00132 }
00133 return TRUE;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 static void
00145 check_interoperable_derived_type(int attr_idx) {
00146
00147
00148
00149
00150
00151
00152
00153
00154 char *problem = 0;
00155 if (ATT_SEQUENCE_SET(attr_idx)) {
00156 problem = "SEQUENCE";
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 if (problem) {
00168 PRINTMSG(AT_DEF_LINE(attr_idx), 1691, Error, AT_DEF_COLUMN(attr_idx),
00169 AT_OBJ_NAME_PTR(attr_idx), problem);
00170 }
00171
00172 for (int sn_idx = ATT_FIRST_CPNT_IDX(attr_idx); sn_idx != NULL_IDX;
00173 sn_idx = SN_SIBLING_LINK(sn_idx)) {
00174 check_interoperable_data(SN_ATTR_IDX(sn_idx));
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184 static int
00185 check_allocatable_pointer_optional(int attr_idx) {
00186 char *problem = 0;
00187 if (AT_OPTIONAL(attr_idx)) {
00188 problem = "OPTIONAL";
00189 }
00190 else if (ATD_ALLOCATABLE(attr_idx)) {
00191 problem = "ALLOCATABLE";
00192 }
00193 else if (ATD_POINTER(attr_idx)) {
00194 problem = "POINTER";
00195 }
00196 if (problem) {
00197 PRINTMSG(AT_DEF_LINE(attr_idx), 1691, Error, AT_DEF_COLUMN(attr_idx),
00198 AT_OBJ_NAME_PTR(attr_idx), problem);
00199 AT_DCL_ERR(attr_idx) = TRUE;
00200 return FALSE;
00201 }
00202 return TRUE;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 static void
00215 check_interoperable_data(int attr_idx) {
00216
00217 switch (ATD_CLASS(attr_idx)) {
00218
00219 case Variable:
00220 if (!AT_MODULE_OBJECT(attr_idx)) {
00221 PRINTMSG(AT_DEF_LINE(attr_idx), 1694, Error, AT_DEF_COLUMN(attr_idx),
00222 AT_OBJ_NAME_PTR(attr_idx));
00223 AT_DCL_ERR(attr_idx) = TRUE;
00224 }
00225 break;
00226
00227 case Function_Result:
00228 case Struct_Component:
00229 case Dummy_Argument:
00230
00231
00232
00233
00234 break;
00235
00236 case Compiler_Tmp:
00237 case CRI__Pointee:
00238 case Constant:
00239 default:
00240
00241 return;
00242 break;
00243 }
00244
00245 if (!(check_allocatable_pointer_optional(attr_idx) &&
00246 check_interoperable_type(attr_idx, FALSE, TRUE))) {
00247 AT_DCL_ERR(attr_idx) = TRUE;
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256 static void
00257 check_interoperable_procedure(int attr_idx) {
00258
00259
00260
00261 char *problem = 0;
00262 if (ATP_ELEMENTAL(attr_idx)) {
00263 problem = "ELEMENTAL";
00264 }
00265 else if (ATP_HAS_ALT_RETURN(attr_idx)) {
00266 problem = "alternate return";
00267 }
00268 if (problem) {
00269 PRINTMSG(AT_DEF_LINE(attr_idx), 1691, Error, AT_DEF_COLUMN(attr_idx),
00270 AT_OBJ_NAME_PTR(attr_idx), problem);
00271 }
00272
00273 switch (ATP_PROC(attr_idx)) {
00274
00275
00276 case Intrin_Proc:
00277 PRINTMSG(AT_DEF_LINE(attr_idx), 1691, Error, AT_DEF_COLUMN(attr_idx),
00278 AT_OBJ_NAME_PTR(attr_idx), "INTRINSIC");
00279 break;
00280
00281
00282 case Intern_Proc:
00283 PRINTMSG(AT_DEF_LINE(attr_idx), 1691, Error, AT_DEF_COLUMN(attr_idx),
00284 AT_OBJ_NAME_PTR(attr_idx), "an internal procedure");
00285 break;
00286
00287 case Module_Proc:
00288 case Extern_Proc:
00289
00290 break;
00291
00292 case Dummy_Proc:
00293
00294
00295 if (!AT_BIND_ATTR(attr_idx)) {
00296 PRINTMSG(AT_DEF_LINE(attr_idx), 1699, Error, AT_DEF_COLUMN(attr_idx),
00297 AT_OBJ_NAME_PTR(attr_idx), AT_OBJ_NAME_PTR(ATP_PARENT_IDX(attr_idx)));
00298 }
00299 break;
00300
00301 case Imported_Proc:
00302 case Unknown_Proc:
00303 default:
00304 PRINTMSG(AT_DEF_LINE(attr_idx), 1044, Internal, AT_DEF_COLUMN(attr_idx),
00305 "Unexpected ATP_PROC in check_interoperable_procedure()");
00306 break;
00307 }
00308 for (int sn_idx = ATP_FIRST_IDX(attr_idx);
00309 sn_idx < (ATP_FIRST_IDX(attr_idx) + ATP_NUM_DARGS(attr_idx)); sn_idx += 1) {
00310 int arg_attr_idx = SN_ATTR_IDX(sn_idx);
00311 if (AT_OBJ_CLASS(arg_attr_idx) == Pgm_Unit) {
00312 check_interoperable_pgm_unit(arg_attr_idx);
00313 }
00314 else if (!AT_DCL_ERR(arg_attr_idx)) {
00315 check_interoperable_data(arg_attr_idx);
00316 }
00317 }
00318 }
00319
00320
00321
00322
00323
00324
00325 static void
00326 check_interoperable_pgm_unit(int attr_idx) {
00327 switch (ATP_PGM_UNIT(attr_idx)) {
00328 case Function:
00329 check_interoperable_data(ATP_RSLT_IDX(attr_idx));
00330 check_interoperable_procedure(attr_idx);
00331 break;
00332
00333 case Subroutine:
00334 check_interoperable_procedure(attr_idx);
00335 break;
00336
00337 case Program:
00338 case Blockdata:
00339 case Module:
00340 case Pgm_Unknown:
00341 default:
00342 PRINTMSG(AT_DEF_LINE(attr_idx), 1044, Internal, AT_DEF_COLUMN(attr_idx),
00343 "Unexpected ATP_PGM_UNIT in check_interoperable_pgm_unit()");
00344 break;
00345 }
00346 }
00347
00348
00349
00350
00351
00352
00353 void
00354 check_interoperable_constraints(int attr_idx) {
00355
00356 switch (AT_OBJ_CLASS(attr_idx)) {
00357 case Data_Obj:
00358 switch (ATD_CLASS(attr_idx)) {
00359 case Dummy_Argument:
00360
00361 break;
00362 case Variable:
00363 if (AT_BIND_ATTR(attr_idx)) {
00364 check_interoperable_data(attr_idx);
00365 }
00366 else if (ATD_IN_COMMON(attr_idx) &&
00367 SB_BIND_ATTR(ATD_STOR_BLK_IDX(attr_idx))) {
00368 check_interoperable_type(attr_idx, FALSE, TRUE);
00369 }
00370 break;
00371 default:
00372 if (AT_BIND_ATTR(attr_idx)) {
00373 check_interoperable_data(attr_idx);
00374 }
00375 break;
00376 }
00377 break;
00378
00379 case Pgm_Unit:
00380 if (AT_BIND_ATTR(attr_idx)) {
00381 check_interoperable_pgm_unit(attr_idx);
00382 }
00383 break;
00384
00385 case Derived_Type:
00386 if (AT_BIND_ATTR(attr_idx)) {
00387 check_interoperable_derived_type(attr_idx);
00388 }
00389 break;
00390
00391 case Common_Block:
00392
00393 break;
00394
00395 case Label:
00396 case Interface:
00397 case Namelist_Grp:
00398 default:
00399 if (AT_BIND_ATTR(attr_idx)) {
00400 PRINTMSG(AT_DEF_LINE(attr_idx), 1044, Internal, AT_DEF_COLUMN(attr_idx),
00401 "Unexpected AT_OBJ_CLASS in check_interoperable_constraints()");
00402 }
00403 break;
00404 }
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 boolean
00416 interoperable_variable(int attr_idx) {
00417 return AT_OBJ_CLASS(attr_idx) == Data_Obj &&
00418 check_interoperable_type(attr_idx, TRUE, FALSE) &&
00419 (!ATD_POINTER(attr_idx)) &&
00420 (!ATD_ALLOCATABLE(attr_idx));
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430 boolean
00431 length_type_param_is_one(int attr_idx) {
00432 int type_idx = ATD_TYPE_IDX(attr_idx);
00433 int linear_type = TYP_LINEAR(type_idx);
00434 return linear_type != Character_1 ||
00435 (TYP_CHAR_CLASS(type_idx) == Const_Len_Char &&
00436 TYP_FLD(type_idx) == CN_Tbl_Idx &&
00437 1 == *(long *) &CN_CONST(TYP_IDX(type_idx)));
00438 }
00439
00440
00441
00442
00443
00444
00445 boolean
00446 no_length_type_param(int attr_idx) {
00447 return length_type_param_is_one(attr_idx);
00448 }