Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
p_dcl_util.c
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 
00037 static char USMID[] = "\n@(#)5.0_pl/sources/p_dcl_util.c        5.7     10/28/99 10:03:56\n";
00038 
00039 # include "defines.h"           /* Machine dependent ifdefs */
00040 
00041 # include "host.m"              /* Host machine dependent macros.*/
00042 # include "host.h"              /* Host machine dependent header.*/
00043 # include "target.m"            /* Target machine dependent macros.*/
00044 # include "target.h"            /* Target machine dependent header.*/
00045 
00046 # include "globals.m"
00047 # include "tokens.m"
00048 # include "sytb.m"
00049 # include "p_globals.m"
00050 # include "debug.m"
00051 
00052 # include "globals.h"
00053 # include "tokens.h"
00054 # include "sytb.h"
00055 # include "p_globals.h"
00056 
00057 /*****************************************************************\
00058 |* function prototypes of static functions declared in this file *|
00059 \*****************************************************************/
00060 
00061 static  int     ntr_bnds_tmp_list(opnd_type *);
00062 static  boolean parse_int_spec_expr(long *, fld_type *, boolean, boolean);
00063 static  void    parse_kind_selector(void);
00064 static  boolean is_attr_referenced_in_bound(int, int);
00065 
00066 
00067 static  boolean kind0seen;
00068 static  boolean kind0E0seen;
00069 static  boolean kind0D0seen;
00070 static  boolean kindconstseen;
00071 
00072 /******************************************************************************\
00073 |*                                                                            *|
00074 |* Description:                                                               *|
00075 |*      Parses the array_spec for declarations                                *|
00076 |*             array_spec is explicit-shape-spec-list                         *|
00077 |*                            is [lower-bound :]upper-bound                   *|
00078 |*                               [specification-expr :] specification-expr    *|
00079 |*                       is assumed-shape-spec-list                           *|
00080 |*                          is [lower-bound] :                                *|
00081 |*                       is deferred-shape-spec-list                          *|
00082 |*                          is :                                              *|
00083 |*                       is assumed-size-spec                                 *|
00084 |*                          is [explicit-shape-spec-list,] [lower-bound:]*    *|
00085 |*                                                                            *|
00086 |*       Position  - entry - token is open paren                              *|
00087 |*                   exit  - token is verified close paren                    *|
00088 |*                           if close paren is missing.  LA_CH is set to      *|
00089 |*                           colon-colon, or EOS                              *|
00090 |*                                                                            *|
00091 |* Returns:                                                                   *|
00092 |*      NONE                                                                  *|
00093 |*                                                                            *|
00094 \******************************************************************************/
00095 int     parse_array_spec(int    attr_idx)
00096 
00097 {
00098    int                  bd_idx;
00099    int                  column;
00100    boolean              fold_it;
00101    boolean              found_end               = FALSE;
00102    boolean              found_error             = FALSE;
00103    fld_type             lb_fld;
00104    long                 lb_len_idx;
00105    int                  line;
00106    boolean              lower_bound_found;
00107    boolean              non_constant_size       = FALSE;
00108    boolean              possible_assumed_shape  = FALSE;
00109    int                  rank                    = 1;
00110    reference_type       referenced;
00111    fld_type             ub_fld;
00112    long                 ub_len_idx;
00113 
00114   
00115    TRACE (Func_Entry, "parse_array_spec", NULL);
00116 
00117 # ifdef _DEBUG
00118    if (LA_CH_VALUE != LPAREN) {
00119       PRINTMSG(LA_CH_LINE, 295, Internal, LA_CH_COLUMN,
00120                "parse_array_spec", "LPAREN");
00121    }
00122 # endif
00123 
00124    NEXT_LA_CH;                                               /* Skip Lparen   */
00125    bd_idx                       = reserve_array_ntry(7);
00126    referenced                   = (reference_type) AT_REFERENCED(attr_idx);
00127    AT_REFERENCED(attr_idx)      = Not_Referenced;
00128    BD_LINE_NUM(bd_idx)          = LA_CH_LINE;
00129    BD_COLUMN_NUM(bd_idx)        = LA_CH_COLUMN;
00130 
00131    /* If LA_CH is RPAREN, there is no dimension, so default to a rank 1       */
00132    /* constant sized array of length 1 and return.                            */
00133 
00134    if (LA_CH_VALUE == RPAREN) {
00135       parse_err_flush(Find_None, "dimension-spec");
00136       BD_ARRAY_CLASS(bd_idx)    = Explicit_Shape;
00137       BD_ARRAY_SIZE(bd_idx)     = Constant_Size;
00138       BD_DCL_ERR(bd_idx)        = TRUE;
00139       BD_RANK(bd_idx)           = 1;
00140       BD_LB_FLD(bd_idx, 1)      = CN_Tbl_Idx;
00141       BD_LB_IDX(bd_idx, 1)      = CN_INTEGER_ONE_IDX;
00142       BD_UB_FLD(bd_idx, 1)      = CN_Tbl_Idx;
00143       BD_UB_IDX(bd_idx, 1)      = CN_INTEGER_ONE_IDX;
00144       NEXT_LA_CH;
00145       goto EXIT;
00146    }
00147 
00148    /* Set fold_it flag.  Will continue on and do pass2 style semantic     */
00149    /* checking and constant folding, if this is a component declaration.  */
00150 
00151    fold_it = (CURR_BLK == Derived_Type_Blk);
00152 
00153    do {  /* Process each dimension of the array */
00154       lower_bound_found         = FALSE;
00155       lb_len_idx                = CN_INTEGER_ONE_IDX;
00156       lb_fld                    = CN_Tbl_Idx;
00157       ub_len_idx                = NULL_IDX;
00158       ub_fld                    = NO_Tbl_Idx;
00159 
00160       if (LA_CH_VALUE != COLON && LA_CH_VALUE != STAR) {
00161          line           = LA_CH_LINE;
00162          column         = LA_CH_COLUMN;
00163 
00164          /* If LA_CH isn't a COLON or a STAR, then this must be an expression.*/
00165          /* Get the expression and determine if it is a lower or upper bound. */
00166          /* If there is a parse error, a constant one is returned.            */
00167 
00168          if (!parse_int_spec_expr(&ub_len_idx, &ub_fld, fold_it, FALSE)) {
00169             ub_len_idx          = CN_INTEGER_ONE_IDX;
00170             ub_fld              = CN_Tbl_Idx;
00171             BD_DCL_ERR(bd_idx)  = TRUE;
00172          }
00173 
00174          if (ub_fld != CN_Tbl_Idx) {
00175             non_constant_size   = TRUE;
00176          }
00177 
00178          if (LA_CH_VALUE == COLON) {                   /* This is lower bound */
00179             lower_bound_found           = TRUE;
00180             possible_assumed_shape      = TRUE;
00181             lb_len_idx                  = ub_len_idx;
00182             lb_fld                      = ub_fld;
00183             ub_len_idx                  = NULL_IDX;
00184             ub_fld                      = NO_Tbl_Idx;
00185          }
00186 
00187          /* If LA_CH isn't a COLON this must be an upper bound.  If it is an  */
00188          /* upper bound and the array has already been classified as deferred */
00189          /* shape, issue an error, because a deferred shape array can never   */
00190          /* have an upper bound.  Otherwise set as an Explicit_Shape array.   */
00191 
00192          else if (BD_ARRAY_CLASS(bd_idx) == Deferred_Shape) {
00193 
00194             /* DIMENSION A(10,:)  --> Illegal - Set Upper bound to NULL_IDX.  */
00195 
00196             ub_len_idx          = NULL_IDX;
00197             ub_fld              = NO_Tbl_Idx;
00198             BD_DCL_ERR(bd_idx)  = TRUE;
00199             PRINTMSG(line, 114, Error, column);
00200          }
00201          else {
00202             BD_ARRAY_CLASS(bd_idx)      = Explicit_Shape;
00203          }
00204       }
00205          
00206       /* Now the parser is in one of 3 states.  1) Lower bound found, upper   */
00207       /* bound = NULL, LA_CH must be COLON.  2) Lower bound not found, so it  */
00208       /* is set to a default of 1, upper bound is found and LA_CH is COMMA or */
00209       /* RPAREN.   (LA_CH must be COLON.)  3) Neither lower bound or upper    */
00210       /* bound have been seen, they are set to defaults of lb=1, ub=NULL.     */
00211       /* LA_CH is COLON or STAR.  If the LA_CH is COLON, this is either a     */
00212       /* Deferred-Shape spec or it is followed by the upper bound for an      */
00213       /* Explicit-Shape spec.  NOTE: LA_CH may be EOS - this is parse error.  */
00214 
00215       if (LA_CH_VALUE == COLON) {
00216          line           = LA_CH_LINE;
00217          column         = LA_CH_COLUMN;
00218          NEXT_LA_CH;                            /* Skip COLON */
00219 
00220          if (LA_CH_VALUE == COMMA || LA_CH_VALUE == RPAREN) {
00221 
00222             /* Have one of two cases  1)  ARRAY(1:)  - This is an assumed     */
00223             /* shape spec which is classed as a Deferred-Shape, or 2) ARRAY(:)*/
00224             /* which is a deferred-Shape spec.   Issue an error if this array */
00225             /* has already been classified as an Explicit_Shape array.        */
00226 
00227             if (BD_ARRAY_CLASS(bd_idx) == Explicit_Shape) {
00228                PRINTMSG(line, 115, Error, column);
00229                BD_DCL_ERR(bd_idx)       = TRUE;
00230             }
00231             else {  /* Must be Deferred-Shape spec */
00232                BD_ARRAY_CLASS(bd_idx)   = Deferred_Shape;
00233             }
00234          }
00235          else {
00236 
00237             /* Have one of two cases  1)  ARRAY (1:10) - legal - pick up upper*/
00238             /* bound expression.  Err if array is already set to Deferred-    */
00239             /* Shape spec.  2) ARRAY (:10) - illegal - issue error.           */
00240             /* If the upper bound is a STAR, pick it up in the next section.  */
00241 
00242             if (!lower_bound_found) {                   /* A(:10) - illegal   */
00243                PRINTMSG(LA_CH_LINE, 119, Error, LA_CH_COLUMN, &LA_CH_VALUE);
00244                BD_DCL_ERR(bd_idx)       = TRUE;
00245             }
00246 
00247             if (LA_CH_VALUE != STAR) {
00248                line     = LA_CH_LINE;
00249                column   = LA_CH_COLUMN;
00250 
00251                if (!parse_int_spec_expr(&ub_len_idx, &ub_fld, fold_it, FALSE)) {
00252 
00253                   /* Expression parser recovers LA_CH to : ) , or EOS */
00254 
00255                   BD_DCL_ERR(bd_idx)    = TRUE;
00256                   ub_len_idx            = CN_INTEGER_ONE_IDX;
00257                   ub_fld                = CN_Tbl_Idx;
00258                }
00259 
00260                if (ub_fld != CN_Tbl_Idx) {
00261                   non_constant_size     = TRUE;
00262                }
00263 
00264                if (BD_ARRAY_CLASS(bd_idx) == Deferred_Shape) { /*A(:,1:2)*/
00265                   PRINTMSG(line, 114, Error, column);
00266                   BD_DCL_ERR(bd_idx)    = TRUE;
00267                   ub_len_idx            = NULL_IDX;
00268                   ub_fld                = NO_Tbl_Idx;
00269                }
00270                else {
00271                   BD_ARRAY_CLASS(bd_idx)= Explicit_Shape;
00272                }
00273             }
00274          }
00275       }
00276 
00277       /* The parser may be:  1)  ARRAY(*) - lb=1, ub=NULL_IDX.  2) ARR(10:*)  */
00278       /* lb is set, and ub=NULL_IDX.  3)  ARRAY(:*) - illegal -error already  */
00279       /* issued.  You could not have picked up a lower bound and/or an upper  */
00280       /* bound and got to this position, because a * is part of an expression.*/
00281       /* The expression parser stops at COLON, COMMA, RPAREN or EOS.          */
00282 
00283       if (LA_CH_VALUE == STAR) {
00284          line   = LA_CH_LINE;
00285          column = LA_CH_COLUMN;
00286          NEXT_LA_CH;                            /* Skip STAR */
00287 
00288          if (BD_ARRAY_CLASS(bd_idx) == Deferred_Shape) {
00289 
00290             /* can't have asterisk with a deferred shape spec */
00291 
00292             PRINTMSG(line, 114, Error, column);
00293             parse_err_flush(Find_Rparen, NULL);
00294             BD_DCL_ERR(bd_idx)  = TRUE;
00295          }
00296          else {
00297             BD_ARRAY_CLASS(bd_idx)      = Assumed_Size;
00298             ub_len_idx                  = lb_len_idx;
00299             ub_fld                      = lb_fld;
00300 
00301             if (LA_CH_VALUE != RPAREN) {
00302  
00303                /* The assumed-size specifier * must be in the last dimension. */
00304 
00305                BD_DCL_ERR(bd_idx)       = TRUE;
00306                PRINTMSG(line, 116, Error, column);
00307                parse_err_flush(Find_Rparen, NULL);
00308             }
00309          }
00310       }
00311 
00312       BD_LB_IDX(bd_idx, rank)   = lb_len_idx;
00313       BD_LB_FLD(bd_idx, rank)   = lb_fld;
00314       BD_UB_IDX(bd_idx, rank)   = ub_len_idx;
00315       BD_UB_FLD(bd_idx, rank)   = ub_fld;
00316 
00317       if (LA_CH_VALUE == COMMA) {
00318 
00319          if (rank++ == 7) {          /* issue error - too many ranks */
00320             found_end           = TRUE;
00321             BD_DCL_ERR(bd_idx)  = TRUE;
00322             PRINTMSG(LA_CH_LINE, 117, Error, LA_CH_COLUMN);
00323             parse_err_flush(Find_Rparen, NULL);
00324          }
00325          else {
00326             NEXT_LA_CH;
00327          }
00328       }
00329       else {
00330          found_end = TRUE;
00331       }
00332 
00333       found_error = BD_DCL_ERR(bd_idx) | found_error;
00334    }
00335    while (!found_end);
00336 
00337    if (LA_CH_VALUE == RPAREN || 
00338        parse_err_flush(Find_Rparen, (found_error) ? NULL : ", or )")) {
00339 
00340       NEXT_LA_CH;               /* Skip RPAREN */
00341    }
00342 
00343    if (BD_ARRAY_CLASS(bd_idx) == Deferred_Shape) {
00344 
00345       if (possible_assumed_shape) {
00346          BD_ARRAY_CLASS(bd_idx) = Assumed_Shape;
00347       }
00348    }
00349    else if (!non_constant_size) {
00350       BD_ARRAY_SIZE(bd_idx) = Constant_Size;
00351    }
00352 
00353    BD_RANK(bd_idx) = rank;
00354 
00355 # ifdef _DEBUG
00356    if (BD_ARRAY_CLASS(bd_idx) == Unknown_Array) {
00357 
00358       /* There is a parsing problem here.  This must never be Unknown_Array */
00359 
00360       PRINTMSG(LA_CH_LINE, 178, Internal, LA_CH_COLUMN);
00361    }
00362 # endif
00363 
00364 EXIT:
00365 
00366    if (AT_REFERENCED(attr_idx) > Not_Referenced) {
00367       is_attr_referenced_in_bound(bd_idx, attr_idx);
00368    }
00369 
00370    if (AT_REFERENCED(attr_idx) < referenced) {
00371       AT_REFERENCED(attr_idx)   = referenced;
00372    }
00373 
00374    bd_idx = ntr_array_in_bd_tbl(bd_idx);
00375 
00376    TRACE (Func_Exit, "parse_array_spec", NULL);
00377 
00378    return(bd_idx);
00379 
00380 }  /* parse_array_spec */
00381 
00382 
00383 /******************************************************************************\
00384 |*                                                                            *|
00385 |* Description:                                                               *|
00386 |*      Parse a POSSIBLE generic spec.                                        *|
00387 |*                                                                            *|
00388 |*      Input position  : The identifier, OPERATOR, or ASSIGNMENT token.      *|
00389 |*      Output position : The comma or EOS after the interface or id.         *|
00390 |*      Called By       : parse_access_stmt, parse_interface_stmt,            *|
00391 |*                        parse_use_stmt                                      *|
00392 |*                                                                            *|
00393 |* Input parameters:                                                          *|
00394 |*      NONE                                                                  *|
00395 |*                                                                            *|
00396 |* Output parameters:                                                         *|
00397 |*      NONE                                                                  *|
00398 |*                                                                            *|
00399 |* Returns:                                                                   *|
00400 |*      TRUE if parsed spec.  FALSE if found a fatal error.                   *|
00401 |*                                                                            *|
00402 \******************************************************************************/
00403 
00404 boolean parse_generic_spec(void)
00405 
00406 {
00407    boolean      parse_ok;
00408 
00409 
00410    TRACE (Func_Entry, "parse_generic_spec", NULL);
00411 
00412    if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) {
00413       parse_ok  = TRUE;
00414 
00415       if (TOKEN_VALUE(token) == Tok_Id) {
00416          /* Intentionally left blank */
00417       }
00418       else if (TOKEN_VALUE(token) == Tok_Kwd_Assignment &&
00419                LA_CH_VALUE == LPAREN) {
00420          NEXT_LA_CH;                            /* Pick up LPAREN */
00421  
00422          if (LA_CH_VALUE == EQUAL) {
00423 
00424             MATCHED_TOKEN_CLASS(Tok_Class_Op);
00425 
00426             if (TOKEN_VALUE(token) == Tok_Op_Assign) {
00427 
00428                if (LA_CH_VALUE == RPAREN || parse_err_flush(Find_Rparen, ")")) {
00429                   NEXT_LA_CH;                   /* Pick up RPAREN */
00430                }
00431             }
00432             else {
00433                PRINTMSG(TOKEN_LINE(token), 197, Error, TOKEN_COLUMN(token),
00434                         "=", TOKEN_STR(token));
00435                parse_ok = FALSE;
00436 
00437                if (parse_err_flush(Find_Rparen, NULL)) {
00438                   NEXT_LA_CH;                         /* Pick up RPAREN */
00439                }
00440             }
00441          }
00442          else if (parse_err_flush(Find_Rparen, "=")) {
00443             parse_ok = FALSE;
00444             NEXT_LA_CH;                         /* Pick up RPAREN */
00445          }
00446       }
00447       else if (TOKEN_VALUE(token) == Tok_Kwd_Operator && 
00448                LA_CH_VALUE == LPAREN) {
00449          NEXT_LA_CH;                            /* Pick up LPAREN */
00450 
00451          if (MATCHED_TOKEN_CLASS(Tok_Class_Op)) {
00452 
00453             switch (TOKEN_VALUE(token)) {
00454                case Tok_Const_True:
00455                case Tok_Const_False:
00456                   parse_ok = FALSE;
00457                   PRINTMSG(TOKEN_LINE(token), 499, Error, TOKEN_COLUMN(token));
00458                   break;
00459 
00460                case Tok_Op_Deref:
00461                case Tok_Op_Ptr_Assign:
00462                case Tok_Op_Assign:
00463                   parse_ok = FALSE;
00464                   PRINTMSG(TOKEN_LINE(token), 300, Error, TOKEN_COLUMN(token));
00465                   break;
00466 
00467                case Tok_Op_Eq :
00468                   TOKEN_STR(token)[0] = 'e';
00469                   TOKEN_STR(token)[1] = 'q';
00470                   break;
00471 
00472                case Tok_Op_Ge :
00473                   TOKEN_STR(token)[0] = 'g';
00474                   TOKEN_STR(token)[1] = 'e';
00475                   break;
00476 
00477                case Tok_Op_Gt :
00478                   TOKEN_STR(token)[0] = 'g';
00479                   TOKEN_STR(token)[1] = 't';
00480                   break;
00481 
00482                case Tok_Op_Le :
00483                   TOKEN_STR(token)[0] = 'l';
00484                   TOKEN_STR(token)[1] = 'e';
00485                   break;
00486 
00487                case Tok_Op_Lt :
00488                   TOKEN_STR(token)[0] = 'l';
00489                   TOKEN_STR(token)[1] = 't';
00490                   break;
00491 
00492                case Tok_Op_Ne :
00493                   TOKEN_STR(token)[0] = 'n';
00494                   TOKEN_STR(token)[1] = 'e';
00495                   break;
00496 
00497                case Tok_Op_Lg :
00498                   TOKEN_STR(token)[0] = 'l';
00499                   TOKEN_STR(token)[1] = 'g';
00500                   break;
00501 
00502                default:
00503                   break;
00504             }
00505 
00506             if (LA_CH_VALUE == RPAREN || parse_err_flush(Find_Rparen, ")")) {
00507                   NEXT_LA_CH;                           /* Pick up RPAREN */
00508             }
00509          }
00510          else if (LA_CH_VALUE == SLASH) {
00511 
00512             /* this clause is needed  because lex thinks that "/)" is an */
00513             /* array constructor punctuator.                             */
00514 
00515             TOKEN_STR(token)[0] = LA_CH_VALUE;
00516             TOKEN_VALUE(token)  = Tok_Op_Div;
00517             TOKEN_LEN(token)    = 1;
00518             NEXT_LA_CH;
00519 
00520             if (LA_CH_VALUE == RPAREN || parse_err_flush(Find_Rparen, ")")) {
00521                   NEXT_LA_CH;                           /* Pick up RPAREN */
00522             }
00523          }
00524          else if (parse_err_flush(Find_Rparen, "defined-operator")) {
00525             parse_ok = FALSE;
00526             NEXT_LA_CH;         /* Pick up RPAREN */
00527          }
00528       }
00529       else {
00530          reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token));
00531          MATCHED_TOKEN_CLASS(Tok_Class_Id);
00532       }
00533    }
00534    else {
00535       parse_err_flush(Find_Comma, "OPERATOR or ASSIGNMENT or generic-name");
00536       parse_ok = FALSE;
00537    }
00538 
00539    TRACE (Func_Exit, "parse_generic_spec", NULL);
00540    return(parse_ok);
00541 
00542 }  /* parse_generic_spec */
00543 
00544 
00545 /******************************************************************************\
00546 |*                                                                            *|
00547 |* Description:                                                               *|
00548 |*      BNF       - intent-spec   is  IN  or  OUT  or INOUT                   *|
00549 |*                                                                            *|
00550 |* Input parameters:                                                          *|
00551 |*      NONE                                                                  *|
00552 |*                                                                            *|
00553 |* Output parameters:                                                         *|
00554 |*      NONE                                                                  *|
00555 |*                                                                            *|
00556 |* Returns:                                                                   *|
00557 |*      intent_type - Returns the INTENT value.  Default is Intent_Inout if   *|
00558 |*                    there is an error.  Otherwise it's whatever was parsed. *|
00559 |*                                                                            *|
00560 \******************************************************************************/
00561 
00562 intent_type     parse_intent_spec()
00563 
00564 {
00565    char         *err_str        = NULL;
00566    intent_type   intent         = Intent_Inout;
00567 
00568 
00569    TRACE (Func_Entry, "parse_intent_spec", NULL);
00570 
00571    if (LA_CH_VALUE != LPAREN) {
00572       err_str = "(";
00573    }
00574    else {
00575       NEXT_LA_CH;                       /* Skip Lparen */
00576 
00577       if (matched_specific_token(Tok_Kwd_In, Tok_Class_Keyword)) {
00578 
00579          if (!matched_specific_token(Tok_Kwd_Out, Tok_Class_Keyword)) {
00580             intent = Intent_In;
00581          }
00582       }
00583       else if (matched_specific_token(Tok_Kwd_Out, Tok_Class_Keyword)) {
00584          intent = Intent_Out;
00585       }
00586       else {
00587          parse_err_flush(Find_Rparen, "IN or OUT or INOUT");
00588          intent = Intent_Unseen;        /* Signal parse error */
00589       }
00590 
00591       if (LA_CH_VALUE == RPAREN) {
00592          NEXT_LA_CH;                    /* Skip Rparen */
00593       }
00594       else {
00595          err_str = ")";
00596       }
00597    }
00598 
00599    if (err_str != NULL) {
00600       parse_err_flush(Find_Rparen, err_str);
00601       matched_specific_token(Tok_Punct_Rparen, Tok_Class_Punct);
00602       intent = Intent_Unseen;
00603    }
00604 
00605    TRACE (Func_Exit, "parse_intent_spec", NULL);
00606 
00607    return(intent);
00608 
00609 }  /* parse_intent_spec */
00610 
00611 
00612 /******************************************************************************\
00613 |*                                                                            *|
00614 |* Description:                                                               *|
00615 |*      BNF       - ([KIND =] scalar-int-initialization-expr)                 *|
00616 |*      Position  - entry - Token before start of expression                  *|
00617 |*                  exit  - Token at end of expression                        *|
00618 |*                                                                            *|
00619 |*      QUESTIONS:  Need to know what the expression parser is going to do,   *|
00620 |*                  if it hits an error?   Need to advance to the end of the  *|
00621 |*                  specification expression.                                 *|
00622 |*                                                                            *|
00623 |* Input parameters:                                                          *|
00624 |*      NONE                                                                  *|
00625 |*                                                                            *|
00626 |* Output parameters:                                                         *|
00627 |*      NONE                                                                  *|
00628 |*                                                                            *|
00629 |* Returns:                                                                   *|
00630 |*      NOTHING                                                               *|
00631 |*                                                                            *|
00632 \******************************************************************************/
00633  
00634 static  void    parse_kind_selector(void)
00635 
00636 {
00637    int          al_idx;
00638    fld_type     field_type;
00639    long         kind_idx;
00640    opnd_type    opnd;
00641 
00642 
00643    TRACE (Func_Entry, "parse_kind_selector", NULL);
00644 
00645    if (matched_specific_token(Tok_Kwd_Kind, Tok_Class_Keyword) &&
00646        !matched_specific_token(Tok_Punct_Eq, Tok_Class_Punct)) {
00647       reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token));
00648    }
00649 
00650    OPND_LINE_NUM(opnd)  = LA_CH_LINE;
00651    OPND_COL_NUM(opnd)   = LA_CH_COLUMN;
00652 
00653    /* Always FOLD - These should be constants.  If not - it's fatal error. */
00654 
00655    parsing_kind_selector = TRUE;
00656    kind0seen = FALSE;
00657    kind0E0seen = FALSE;
00658    kind0D0seen = FALSE;
00659    kindconstseen = FALSE;
00660 
00661    if (parse_int_spec_expr(&kind_idx, &field_type, TRUE, FALSE)) {
00662       OPND_FLD(opnd)            = field_type;
00663       OPND_IDX(opnd)            = kind_idx;
00664 
00665       if (!kind_to_linear_type(&opnd,
00666                                AT_WORK_IDX,
00667                                kind0seen,
00668                                kind0E0seen,
00669                                kind0D0seen,
00670                                kindconstseen)) {
00671          AT_DCL_ERR(AT_WORK_IDX)        = TRUE;
00672       }
00673 
00674 # if !defined(_TARGET_OS_MAX)
00675 
00676       if (!on_off_flags.enable_double_precision &&
00677           (TYP_TYPE(ATD_TYPE_IDX(AT_WORK_IDX)) == Complex ||
00678            TYP_TYPE(ATD_TYPE_IDX(AT_WORK_IDX)) == Real) &&
00679           TYP_DCL_VALUE(ATD_TYPE_IDX(AT_WORK_IDX)) == 16) {
00680          PRINTMSG(OPND_LINE_NUM(opnd), 586, Warning, OPND_COL_NUM(opnd));
00681       }
00682 # endif
00683 
00684 #if 0 /*works well for source-level translation ----fzhao*/
00685 # if defined(_TARGET_OS_LINUX)
00686       if ((TYP_TYPE(ATD_TYPE_IDX(AT_WORK_IDX)) == Complex ||
00687            TYP_TYPE(ATD_TYPE_IDX(AT_WORK_IDX)) == Real) &&
00688           TYP_DCL_VALUE(ATD_TYPE_IDX(AT_WORK_IDX)) == 16) {
00689          PRINTMSG(OPND_LINE_NUM(opnd), 541, Error, OPND_COL_NUM(opnd));
00690       }
00691 # endif
00692 #endif
00693       if (field_type == AT_Tbl_Idx) {
00694 
00695          /* Mark tmp not referenced and remove it from the tmp list.  This */
00696          /* tmp was not shared when it was entered into the bounds list.   */
00697 
00698          AT_REFERENCED(kind_idx)        = Not_Referenced;
00699          al_idx                         = SCP_TMP_FW_IDX(curr_scp_idx);
00700          SCP_TMP_FW_IDX(curr_scp_idx)   = AL_NEXT_IDX(al_idx);
00701       }
00702    }
00703 
00704    parsing_kind_selector = FALSE;
00705 
00706    TRACE (Func_Exit, "parse_kind_selector", NULL);
00707 
00708    return;
00709 
00710 }  /* parse_kind_selector */
00711 
00712 
00713 /******************************************************************************\
00714 |*                                                                            *|
00715 |* Description:                                                               *|
00716 |*   If i_can_have_len_equal                                                  *|
00717 |*      BNF - [LEN =] type-param-value                                        *|
00718 |*   If !(i_can_have_len_equal)                                               *|
00719 |*      BNF - *(type-param-value)  OR *scalar-int-literal-constant            *|
00720 |*   type-param-value IS   specification-expr OR *                            *|
00721 |*                                                                            *|
00722 |*   Position  - entry - token is token following (                           *|
00723 |*                       or following LEN=                                    *|
00724 |*                       or *                                                 *|
00725 |*               exit  - LA is comma or right paren or EOS                    *|
00726 |*                                                                            *|
00727 |* Input parameters:                                                          *|
00728 |*      i_can_have_len_equal - LEN = is allowed.  See description.            *|
00729 |*      parsing_length_selector - We are parsing the length-selector on the   *|
00730 |*                              CHARACTER statement, as opposed to parsing    *|
00731 |*                              the char-length on a variable name in a list. *|
00732 |*                              This is needed for the obsolescence message.  *|
00733 |*                                                                            *|
00734 |* Output parameters:                                                         *|
00735 |*      NONE                                                                  *|
00736 |*                                                                            *|
00737 |* Returns:                                                                   *|
00738 |*      TRUE if there are no errors, else FALSE                               *|
00739 |*                                                                            *|
00740 \******************************************************************************/
00741 void    parse_length_selector(int       attr_idx,
00742                               boolean   i_can_have_len_equal,
00743                               boolean   parsing_length_selector)
00744 
00745 {
00746    type_char_type       char_class      = Unknown_Char;
00747    int                  column;
00748    fld_type             field_type;
00749    boolean              fold_it;
00750    long                 len_idx;
00751    int                  line;
00752    opnd_type            opnd;
00753    reference_type       referenced;
00754 
00755 
00756    TRACE (Func_Entry, "parse_length_selector", NULL);
00757 
00758    /* Set fold_it flag.  Will continue on and do pass2 style semantic     */
00759    /* checking and constant folding, if this is a component declaration.  */
00760   
00761    fold_it                      = (CURR_BLK == Derived_Type_Blk);
00762    referenced                   = (reference_type) AT_REFERENCED(attr_idx);
00763    AT_REFERENCED(attr_idx)      = Not_Referenced;
00764 
00765    CLEAR_TBL_NTRY(type_tbl, TYP_WORK_IDX);
00766 
00767    if (i_can_have_len_equal) {
00768 
00769       if (matched_specific_token(Tok_Kwd_Len, Tok_Class_Keyword) &&
00770           !matched_specific_token(Tok_Punct_Eq, Tok_Class_Punct)) {
00771          reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token));
00772       }
00773       line              = LA_CH_LINE;
00774       column            = LA_CH_COLUMN;
00775 
00776       if (LA_CH_VALUE == STAR) {
00777          NEXT_LA_CH;
00778          len_idx        = 0;
00779          field_type     = NO_Tbl_Idx;
00780          char_class     = Assumed_Size_Char;
00781       }
00782       else {
00783 
00784          if (!parse_int_spec_expr(&len_idx, &field_type, fold_it, TRUE)) {
00785             len_idx     = CN_INTEGER_ONE_IDX;
00786             field_type  = CN_Tbl_Idx;
00787          }
00788 
00789          if (field_type != AT_Tbl_Idx) {
00790             char_class  = Const_Len_Char;
00791          }
00792       }
00793    }
00794    else {
00795       NEXT_LA_CH;                    /* Skip Star */
00796 
00797       if (LA_CH_VALUE == LPAREN) {   /*    *(*)  or *(length)   */
00798          NEXT_LA_CH;  /* Skip Lparen */
00799          line           = LA_CH_LINE;
00800          column         = LA_CH_COLUMN;
00801 
00802          if (LA_CH_VALUE == STAR) {
00803             NEXT_LA_CH;
00804             len_idx     = 0;
00805             field_type  = NO_Tbl_Idx;
00806             char_class  = Assumed_Size_Char;
00807          }
00808          else {
00809 
00810             if (!parse_int_spec_expr(&len_idx, &field_type, fold_it, TRUE)) {
00811                len_idx          = CN_INTEGER_ONE_IDX;
00812                field_type       = CN_Tbl_Idx;
00813             }
00814 
00815             if (field_type != AT_Tbl_Idx) {
00816                char_class       = Const_Len_Char;
00817             }
00818          }
00819 
00820          if (LA_CH_VALUE == RPAREN || parse_err_flush(Find_Rparen, ")")) {
00821             NEXT_LA_CH;                 /* Skip Rparen */
00822          }
00823       }
00824       else if (MATCHED_TOKEN_CLASS(Tok_Class_Int_Spec)) {
00825          len_idx        = TOKEN_CONST_TBL_IDX(token);
00826          field_type     = CN_Tbl_Idx;
00827          char_class     = Const_Len_Char;
00828          line           = TOKEN_LINE(token);
00829          column         = TOKEN_COLUMN(token);
00830 
00831          if (parsing_length_selector) {
00832             PRINTMSG(line, 1563, Comment, column); /* Obsolescent */
00833          }
00834       }
00835       else {
00836          line           = LA_CH_LINE;
00837          column         = LA_CH_COLUMN;
00838          len_idx        = CN_INTEGER_ONE_IDX;
00839          field_type     = CN_Tbl_Idx;
00840          char_class     = Const_Len_Char;
00841          parse_err_flush(Find_None, "scalar-int-literal-constant or (");
00842       }
00843    }
00844 
00845    if (char_class == Assumed_Size_Char && CURR_BLK == Derived_Type_Blk) {
00846 
00847       /* Components cannot be assumed size character. */
00848       
00849       PRINTMSG(line, 191, Error, column);
00850       char_class        = Const_Len_Char;
00851       len_idx           = CN_INTEGER_ONE_IDX;
00852       field_type        = CN_Tbl_Idx;
00853    }
00854   
00855    if (AT_REFERENCED(attr_idx) > Not_Referenced) {
00856 
00857       /* The attr was referenced in the dimension bound describing the attr. */
00858       /* Find the reference to the attr, so that we can issue a really good  */
00859       /* error message.  It's a little compile time, but it's a fatal error. */
00860 
00861       AT_DCL_ERR(attr_idx)      = TRUE;
00862 
00863       if (field_type == AT_Tbl_Idx &&
00864           ATD_FLD(len_idx) == IR_Tbl_Idx &&
00865           find_attr_in_ir(attr_idx, ATD_TMP_IDX(len_idx), &opnd)) {
00866          PRINTMSG(OPND_LINE_NUM(opnd), 1035, Error,
00867                   OPND_COL_NUM(opnd),
00868                   AT_OBJ_NAME_PTR(attr_idx));
00869          len_idx        = CN_INTEGER_ONE_IDX;
00870          field_type     = CN_Tbl_Idx;
00871       }
00872    }
00873 
00874    if (AT_REFERENCED(attr_idx) < referenced) {
00875       AT_REFERENCED(attr_idx)   = referenced;
00876    }
00877 
00878    TYP_TYPE(TYP_WORK_IDX)               = Character;
00879    TYP_LINEAR(TYP_WORK_IDX)             = CHARACTER_DEFAULT_TYPE;
00880    TYP_CHAR_CLASS(TYP_WORK_IDX)         = char_class;
00881    TYP_FLD(TYP_WORK_IDX)                = field_type;
00882    TYP_IDX(TYP_WORK_IDX)                = len_idx;
00883 
00884    TRACE (Func_Exit, "parse_length_selector", NULL);
00885 
00886    return;
00887 
00888 }  /* parse_length_selector */
00889 
00890 /******************************************************************************\
00891 |*                                                                            *|
00892 |* Description:                                                               *|
00893 |*                                                                            *|
00894 |*      BNF    - is INTEGER [kind-selector]                                   *|
00895 |*               or REAL    [kind-selector]                                   *|
00896 |*               or COMPLEX [kind-selector]                                   *|
00897 |*               or LOGICAL [kind-selector]                                   *|
00898 |*               or TYPE(type-name)                                           *|
00899 |*               or DOUBLE PRECISION                                          *|
00900 |*               or DOUBLE COMPLEX                                            *|
00901 |*               CHARACTER [char-selector]                                    *|
00902 |*                         where char_selector is                             *|
00903 |*               * (type-param-value)                                         *|
00904 |*               * scalar-int-literal-constant                                *|
00905 |*               ([LEN=] type-param-value)                                    *|
00906 |*               (LEN=type-param-value,KIND=scalar-int-initialization-exp)    *|
00907 |*               (type-param-value, [KIND=] scalar-int-initialization-exp)    *|
00908 |*               (KIND=scalar-int-initialization-exp [,LEN=type-param-value]) *|
00909 |*                                                                            *|
00910 |* Input parameters:                                                          *|
00911 |*      chk_kind - TRUE if check for kind (or kind/len for character) on type *|
00912 |*                      spec                                                  *|
00913 |*                                                                            *|
00914 |* Output parameters:                                                         *|
00915 |*      NONE                                                                  *|
00916 |*                                                                            *|
00917 |* Returns:                                                                   *|
00918 |*      TRUE is statement parsed okay.  (There may be fatal errors. )         *|
00919 |*      FALSE if first token is not INTEGER, REAL, COMPLEX, LOGICAL, TYPE     *|
00920 |*            DOUBLE or CHARACTER.  ATD_TYPE_IDX will be NULL??               *|
00921 |*      FALSE if this is found to be an assignment statement.                 *|
00922 |*      Note: In case of error and stmt_type is known, the only searching     *|
00923 |*            will be for a right paren, if a left one has been found.        *|
00924 |*                                                                            *|
00925 \******************************************************************************/
00926 
00927 boolean parse_type_spec(boolean         chk_kind)
00928 
00929 {
00930    int                   al_idx;
00931    int                   attr_idx;
00932    int                   column;
00933    boolean               do_kind_first;
00934    boolean               double_precision       = FALSE;
00935    int                   host_attr_idx;
00936    int                   host_name_idx;
00937    int                   line;
00938    linear_type_type      linear_type;
00939    int                   name_idx;
00940    long                  num;
00941    boolean               parse_err              = FALSE;
00942    boolean               save_err               = FALSE;
00943    boolean               type_done              = FALSE;
00944    int                   type_idx;
00945    char                 *type_str;
00946 
00947 
00948    TRACE (Func_Entry, "parse_type_spec", NULL);
00949    
00950    if (SH_ERR_FLG(curr_stmt_sh_idx)) {
00951       SH_ERR_FLG(curr_stmt_sh_idx)      = FALSE;
00952       save_err                          = TRUE;
00953    }
00954 
00955    CLEAR_ATTR_NTRY(AT_WORK_IDX);
00956 
00957    switch (TOKEN_VALUE(token)) {
00958    case Tok_Kwd_Byte:
00959       PRINTMSG(TOKEN_LINE(token), 1253, Ansi, TOKEN_COLUMN(token), "BYTE");
00960       ATD_TYPE_IDX(AT_WORK_IDX) = Integer_1;
00961       break;
00962 
00963    case Tok_Kwd_Integer:
00964       ATD_TYPE_IDX(AT_WORK_IDX) = INTEGER_DEFAULT_TYPE;
00965       break;
00966 
00967    case Tok_Kwd_Real:
00968       ATD_TYPE_IDX(AT_WORK_IDX) = REAL_DEFAULT_TYPE;
00969       break;
00970 
00971    case Tok_Kwd_Complex:
00972       ATD_TYPE_IDX(AT_WORK_IDX) = COMPLEX_DEFAULT_TYPE;
00973       break;
00974 
00975    case Tok_Kwd_Logical:
00976       ATD_TYPE_IDX(AT_WORK_IDX) = LOGICAL_DEFAULT_TYPE;
00977       break;
00978 
00979    case Tok_Kwd_Character:
00980       line                      = TOKEN_LINE(token);
00981       column                    = TOKEN_COLUMN(token);
00982       ATD_TYPE_IDX(AT_WORK_IDX) = CHARACTER_DEFAULT_TYPE;
00983 
00984       if (LA_CH_VALUE == LPAREN) {
00985 
00986          if (chk_kind) {
00987             NEXT_LA_CH;                         /* Skip LPAREN */
00988             do_kind_first = FALSE;
00989 
00990             if (LA_CH_VALUE == 'K' &&
00991                 matched_specific_token(Tok_Kwd_Kind, Tok_Class_Keyword)) {
00992 
00993                if (LA_CH_VALUE == EQUAL) {
00994                   do_kind_first = TRUE;
00995                }
00996                reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token));
00997             }
00998 
00999             if (do_kind_first) {
01000                parse_kind_selector();
01001 
01002                if (LA_CH_VALUE == COMMA) {
01003                   NEXT_LA_CH;                   /* Skip comma */
01004 
01005                   /* We can have length equal and we are parsing the */
01006                   /* length selector.  Hence  TRUE, TRUE.            */
01007 
01008                   parse_length_selector(AT_WORK_IDX, TRUE, TRUE);
01009                   TYP_DCL_VALUE(TYP_WORK_IDX)   = TYP_DCL_VALUE(ATD_TYPE_IDX(
01010                                                                 AT_WORK_IDX));
01011                   TYP_DESC(TYP_WORK_IDX) = TYP_DESC(ATD_TYPE_IDX(AT_WORK_IDX));
01012                   ATD_TYPE_IDX(AT_WORK_IDX) = ntr_type_tbl();
01013                }
01014             }
01015             else {
01016 
01017                /* We can have length equal and we are parsing the */
01018                /* length selector.  Hence  TRUE, TRUE.            */
01019 
01020                parse_length_selector(AT_WORK_IDX, TRUE, TRUE);
01021                ATD_TYPE_IDX(AT_WORK_IDX)        = ntr_type_tbl();
01022 
01023                if (LA_CH_VALUE == COMMA) {
01024                   NEXT_LA_CH;                   /* Skip comma */
01025                   parse_kind_selector();
01026                }
01027             }
01028 
01029             if (LA_CH_VALUE == RPAREN || parse_err_flush(Find_Rparen, ")")) {
01030                NEXT_LA_CH;                      /* Skip Rparen */
01031             }
01032          }
01033       }
01034       else if (LA_CH_VALUE == STAR) {
01035 
01036          /* This can't have LEN =, so pass FALSE */
01037          /* TRUE means this is a length-selector */
01038 
01039          parse_length_selector(AT_WORK_IDX, FALSE, TRUE);
01040          ATD_TYPE_IDX(AT_WORK_IDX)      = ntr_type_tbl();
01041       }
01042 
01043       type_done = TRUE;
01044       break;
01045 
01046 
01047    case Tok_Kwd_Double:
01048       line      = TOKEN_LINE(token);
01049       column    = TOKEN_COLUMN(token);
01050 
01051       if (LA_CH_VALUE == 'C' &&
01052           matched_specific_token(Tok_Kwd_Complex, Tok_Class_Keyword)) {
01053 
01054 # if defined(_TARGET_OS_MAX)
01055 
01056          if (!on_off_flags.enable_double_precision) {
01057             PRINTMSG(line, 20, Ansi, column);
01058          }
01059          else if (cmd_line_flags.s_default32) {
01060 
01061             /* Use DOUBLE COMPLEX because -sdefault32 is built into the macro.*/
01062 
01063             PRINTMSG(line, 20, Ansi, column);
01064          }
01065          else {
01066             PRINTMSG(line, 702, Error, column);
01067          }
01068 # else
01069          PRINTMSG(line, 20, Ansi, column);
01070 # endif
01071 
01072          ATD_TYPE_IDX(AT_WORK_IDX)      = DOUBLE_COMPLEX_TYPE_IDX;
01073          type_done                      = TRUE;
01074       }
01075       else if (LA_CH_VALUE == 'P' &&
01076                matched_specific_token(Tok_Kwd_Precision, Tok_Class_Keyword)) {
01077 
01078          ATD_TYPE_IDX(AT_WORK_IDX)      = DOUBLE_PRECISION_TYPE_IDX;
01079 
01080 # ifdef _TARGET_OS_MAX
01081 
01082          if (! cmd_line_flags.s_default32 &&
01083              on_off_flags.enable_double_precision) {
01084             PRINTMSG(line, 1110, Warning, column);
01085             ATD_TYPE_IDX(AT_WORK_IDX)   = REAL_DEFAULT_TYPE;
01086          }
01087 # endif
01088 
01089          double_precision               = TRUE;
01090 
01091          if (LA_CH_VALUE != STAR) {     /* Kind is not allowed */
01092             type_done                   = TRUE;
01093          }
01094       }
01095       else {
01096          type_done                      = TRUE;
01097          ATD_TYPE_IDX(AT_WORK_IDX)      = DOUBLE_PRECISION_TYPE_IDX;
01098          parse_err_flush(Find_None, "COMPLEX or PRECISION");
01099       }
01100       break;
01101 
01102 
01103    case Tok_Kwd_Type:
01104 
01105       if (LA_CH_VALUE != LPAREN) {
01106          parse_err_flush(Find_None, "(");
01107          ATD_TYPE_IDX(AT_WORK_IDX) = TYPELESS_DEFAULT_TYPE;
01108       }
01109       else {
01110          NEXT_LA_CH;                            /* Skip Lparen */
01111 
01112          if (!MATCHED_TOKEN_CLASS(Tok_Class_Id)) {
01113             parse_err_flush(Find_Rparen, "type-name");
01114          }
01115          else if (LA_CH_VALUE == RPAREN) {
01116             attr_idx = srch_sym_tbl(TOKEN_STR(token), TOKEN_LEN(token),
01117                                     &name_idx);
01118 
01119             if (attr_idx == NULL_IDX) {       /* search host sym table */
01120                host_attr_idx = srch_host_sym_tbl(TOKEN_STR(token),
01121                                                  TOKEN_LEN(token),
01122                                                  &host_name_idx,
01123                                                  FALSE);
01124 
01125                if (host_attr_idx == NULL_IDX) {
01126                   attr_idx                      = ntr_sym_tbl(&token, name_idx);
01127                   AT_OBJ_CLASS(attr_idx)        = Derived_Type;
01128                   AT_LOCKED_IN(attr_idx)        = TRUE;
01129                   ATT_STRUCT_BIT_LEN_FLD(attr_idx)      = CN_Tbl_Idx;
01130                   ATT_STRUCT_BIT_LEN_IDX(attr_idx)      = CN_INTEGER_ZERO_IDX;
01131                }
01132                else if (stmt_type == Implicit_Stmt ||
01133                         stmt_type == Function_Stmt) {
01134 
01135                   /* Enter into the local scope, and link to the host's    */
01136                   /* attr.  Cannot lock in on this, because it may be      */
01137                   /* defined later in this scope.  Cannot issue error if   */
01138                   /* it's not a derived type for the same reason.          */
01139                   /* Catch AT_NOT_VISIBLE stuff when this is resolved.     */
01140 
01141                   /* ntr_host_in_sym_tbl just makes a new empty attr and   */
01142                   /* attr links it to the host_attr_idx.                   */
01143 
01144                   attr_idx = ntr_host_in_sym_tbl(&token,
01145                                                  name_idx,
01146                                                  host_attr_idx,
01147                                                  host_name_idx,
01148                                                  TRUE);
01149 
01150                   if (AT_OBJ_CLASS(host_attr_idx) == Derived_Type) {
01151                      COPY_ATTR_NTRY(attr_idx, host_attr_idx);
01152                      AT_CIF_SYMBOL_ID(attr_idx) = 0;
01153                      AT_DEF_LINE(attr_idx)      = TOKEN_LINE(token);
01154                      AT_DEF_COLUMN(attr_idx)    = TOKEN_COLUMN(token);
01155                      AT_LOCKED_IN(attr_idx)     = FALSE;
01156                      AT_ATTR_LINK(attr_idx)     = host_attr_idx;
01157                   }
01158                   else {
01159                      AT_OBJ_CLASS(attr_idx)             = Derived_Type;
01160                      ATT_STRUCT_BIT_LEN_FLD(attr_idx)   = CN_Tbl_Idx;
01161                      ATT_STRUCT_BIT_LEN_IDX(attr_idx)   = CN_INTEGER_ZERO_IDX;
01162                   }
01163                }
01164                else if (AT_OBJ_CLASS(host_attr_idx) == Derived_Type &&
01165                         !AT_NOT_VISIBLE(host_attr_idx)) {
01166 
01167                   /* Lock into using the host definition */
01168 
01169                   attr_idx = ntr_host_in_sym_tbl(&token,
01170                                                  name_idx,
01171                                                  host_attr_idx,
01172                                                  host_name_idx,
01173                                                  TRUE);
01174 
01175                   COPY_ATTR_NTRY(attr_idx, host_attr_idx);
01176                   AT_CIF_SYMBOL_ID(attr_idx)    = 0;
01177                   AT_DEF_LINE(attr_idx)         = TOKEN_LINE(token);
01178                   AT_DEF_COLUMN(attr_idx)       = TOKEN_COLUMN(token);
01179                   AT_ATTR_LINK(attr_idx)        = host_attr_idx;
01180                   AT_LOCKED_IN(attr_idx)        = TRUE;
01181                }
01182                else if (!fnd_semantic_err(Obj_Use_Derived_Type, 
01183                                           TOKEN_LINE(token),
01184                                           TOKEN_COLUMN(token),
01185                                           host_attr_idx,
01186                                           TRUE)) {
01187 
01188                   /* Has just PUBLIC or PRIVATE set.  Lock into using the  */
01189                   /* host definition.                                      */
01190 
01191                   attr_idx = ntr_host_in_sym_tbl(&token,
01192                                                  name_idx,
01193                                                  host_attr_idx,
01194                                                  host_name_idx,
01195                                                  TRUE);
01196 
01197                   AT_DEF_LINE(attr_idx)         = TOKEN_LINE(token);
01198                   AT_DEF_COLUMN(attr_idx)       = TOKEN_COLUMN(token);
01199                   AT_LOCKED_IN(attr_idx)        = TRUE;
01200                }
01201                else {  /* Lock into this use.  Issue error - create new    */
01202                        /* local attr to hopefully prevent error escalation.*/
01203                        /* Need to make this a better msg, because it comes */
01204                        /* from the host.                                   */
01205 
01206                   attr_idx                      = ntr_sym_tbl(&token, name_idx);
01207                   AT_OBJ_CLASS(attr_idx)        = Derived_Type;
01208                   AT_DCL_ERR(attr_idx)          = TRUE;
01209                   AT_LOCKED_IN(attr_idx)        = TRUE;
01210                   ATT_STRUCT_BIT_LEN_FLD(attr_idx)      = CN_Tbl_Idx;
01211                   ATT_STRUCT_BIT_LEN_IDX(attr_idx)      = CN_INTEGER_ZERO_IDX;
01212                }
01213             }
01214             else if (AT_OBJ_CLASS(attr_idx) == Derived_Type &&
01215                      !AT_NOT_VISIBLE(attr_idx)) {
01216                AT_LOCKED_IN(attr_idx)   = TRUE;
01217             }
01218             else if (AT_ATTR_LINK(attr_idx) != NULL_IDX) {
01219                host_attr_idx = AT_ATTR_LINK(attr_idx);
01220 
01221                while (AT_ATTR_LINK(host_attr_idx) != NULL_IDX) {
01222                   host_attr_idx = AT_ATTR_LINK(host_attr_idx);
01223                }
01224 
01225                if (AT_OBJ_CLASS(host_attr_idx) == Derived_Type) {
01226                   CLEAR_VARIANT_ATTR_INFO(attr_idx, Derived_Type);
01227                   ATT_STRUCT_BIT_LEN_FLD(attr_idx)      = CN_Tbl_Idx;
01228                   ATT_STRUCT_BIT_LEN_IDX(attr_idx)      = CN_INTEGER_ZERO_IDX;
01229                   AT_LOCKED_IN(attr_idx)        = TRUE;
01230                }
01231                else {
01232                   PRINTMSG(TOKEN_LINE(token), 956, Error, 
01233                            TOKEN_COLUMN(token),
01234                            AT_OBJ_NAME_PTR(attr_idx));
01235                   CREATE_ERR_ATTR(attr_idx, TOKEN_LINE(token),
01236                                             TOKEN_COLUMN(token),
01237                                             Derived_Type);
01238                   ATT_STRUCT_BIT_LEN_FLD(attr_idx)      = CN_Tbl_Idx;
01239                   ATT_STRUCT_BIT_LEN_IDX(attr_idx)      = CN_INTEGER_ZERO_IDX;
01240 
01241                   /* Switch the name table to use the new attr, to limit      */
01242                   /* cascading errors for derived type definitions.           */
01243 
01244                   LN_ATTR_IDX(name_idx)         = attr_idx;
01245                   LN_NAME_IDX(name_idx)         = AT_NAME_IDX(attr_idx);
01246                   AT_LOCKED_IN(attr_idx)        = TRUE;
01247                }
01248             }
01249             else if (!fnd_semantic_err(Obj_Use_Derived_Type,
01250                                        TOKEN_LINE(token),
01251                                        TOKEN_COLUMN(token),
01252                                        attr_idx,
01253                                        TRUE)) {
01254 
01255                /* Has just PUBLIC or PRIVATE set */
01256 
01257                CLEAR_VARIANT_ATTR_INFO(attr_idx, Derived_Type);
01258                ATT_STRUCT_BIT_LEN_FLD(attr_idx) = CN_Tbl_Idx;
01259                ATT_STRUCT_BIT_LEN_IDX(attr_idx) = CN_INTEGER_ZERO_IDX;
01260                AT_LOCKED_IN(attr_idx)   = TRUE;
01261             }
01262             else {
01263                CREATE_ERR_ATTR(attr_idx, TOKEN_LINE(token),
01264                                          TOKEN_COLUMN(token), 
01265                                          Derived_Type);
01266                ATT_STRUCT_BIT_LEN_FLD(attr_idx) = CN_Tbl_Idx;
01267                ATT_STRUCT_BIT_LEN_IDX(attr_idx) = CN_INTEGER_ZERO_IDX;
01268 
01269                /* Add replaced attr to cif error list, so it gets a cif rec */
01270                /* Switch the name table to use the new attr, to limit       */
01271                /* cascading errors for derived type definitions.            */
01272 
01273                NTR_ATTR_LIST_TBL(al_idx);
01274                AL_ATTR_IDX(al_idx)      = LN_ATTR_IDX(name_idx);
01275                AL_NEXT_IDX(al_idx)      = SCP_CIF_ERR_LIST(curr_scp_idx);
01276                SCP_CIF_ERR_LIST(curr_scp_idx)   = al_idx;
01277 
01278                LN_ATTR_IDX(name_idx)    = attr_idx;
01279                LN_NAME_IDX(name_idx)    = AT_NAME_IDX(attr_idx);
01280                AT_LOCKED_IN(attr_idx)   = TRUE;
01281 
01282             }
01283 
01284             if ((cif_flags & XREF_RECS) != 0) {
01285       
01286                if (AT_ATTR_LINK(attr_idx) == NULL_IDX) {
01287                   host_attr_idx = attr_idx;
01288                }
01289                else {
01290                   host_attr_idx = AT_ATTR_LINK(attr_idx);
01291 
01292                   while (AT_ATTR_LINK(host_attr_idx) != NULL_IDX) {
01293                      host_attr_idx = AT_ATTR_LINK(host_attr_idx);
01294                   }
01295                }
01296 
01297                cif_usage_rec(host_attr_idx, 
01298                              AT_Tbl_Idx,
01299                              TOKEN_LINE(token),
01300                              TOKEN_COLUMN(token),
01301                              CIF_Derived_Type_Name_Reference);
01302             }
01303             
01304             CLEAR_TBL_NTRY(type_tbl, TYP_WORK_IDX);
01305             TYP_TYPE(TYP_WORK_IDX)      = Structure;
01306             TYP_LINEAR(TYP_WORK_IDX)    = Structure_Type;
01307             TYP_IDX(TYP_WORK_IDX)       = attr_idx;
01308 
01309             ATD_TYPE_IDX(AT_WORK_IDX)   = ntr_type_tbl();
01310  
01311             ATT_TY_IDX(attr_idx) = ATD_TYPE_IDX(AT_WORK_IDX); 
01312 
01313             NEXT_LA_CH;                 /* Skip Rparen */
01314          }
01315          else {
01316             ATD_TYPE_IDX(AT_WORK_IDX) = TYPELESS_DEFAULT_TYPE;
01317             parse_err_flush(Find_Rparen, ")");
01318          }
01319       }
01320 
01321       type_done = TRUE;
01322       break;
01323 
01324 
01325    default:
01326       ATD_TYPE_IDX(AT_WORK_IDX) = TYPELESS_DEFAULT_TYPE;
01327       type_done                 = TRUE;
01328       PRINTMSG(TOKEN_LINE(token), 197, Error, TOKEN_COLUMN(token),
01329                "INTEGER, REAL, DOUBLE, COMPLEX, LOGICAL, CHARACTER or TYPE",
01330                TOKEN_STR(token));
01331       break;
01332 
01333    }  /* end switch */
01334             
01335    AT_TYPED(AT_WORK_IDX) = TRUE;
01336 
01337    if (!type_done) {
01338 
01339       if (chk_kind && LA_CH_VALUE == LPAREN) {
01340            
01341          NEXT_LA_CH;                    /* Skip Lparen */
01342          parse_kind_selector();
01343 
01344          if (LA_CH_VALUE == RPAREN || parse_err_flush(Find_Rparen,  ")")) {
01345             NEXT_LA_CH;                 /* Skip Rparen */
01346          }
01347       }
01348       else if (LA_CH_VALUE == STAR) {
01349          NEXT_LA_CH;                    /* Skip Star */
01350 
01351          if (MATCHED_TOKEN_CLASS(Tok_Class_Int_Spec)) {
01352             num         = (long) CN_INT_TO_C(TOKEN_CONST_TBL_IDX(token));
01353             linear_type = Err_Res;
01354             type_idx    = ATD_TYPE_IDX(AT_WORK_IDX);
01355             type_str    = basic_type_str[TYP_TYPE(type_idx)];
01356 
01357             switch (TYP_TYPE(type_idx)) {
01358 
01359             case Integer:
01360                   
01361                switch (num) {
01362 
01363                case 1:
01364                   linear_type = (cmd_line_flags.s_cf77types) ?
01365                                 INTEGER_DEFAULT_TYPE : Integer_1;
01366                   break;
01367 
01368                case 2:
01369                   linear_type = (cmd_line_flags.s_cf77types) ?
01370                                 INTEGER_DEFAULT_TYPE : Integer_2;
01371                   break;
01372 
01373                case 4:
01374                   linear_type = (cmd_line_flags.s_cf77types) ?
01375                                 INTEGER_DEFAULT_TYPE : Integer_4;
01376                   break;
01377 
01378                case 8:
01379                   linear_type = (cmd_line_flags.s_cf77types) ?
01380                                 INTEGER_DEFAULT_TYPE : Integer_8;
01381                   break;
01382 
01383                };
01384 
01385             break;
01386 
01387 
01388             case Real:
01389 
01390                if (double_precision) {
01391                   type_str      = "DOUBLE PRECISION";
01392 
01393                   if (num == 16) {
01394 
01395 # ifdef _TARGET_OS_MAX /* Msg was issued when DOUBLE PRECISION was parsed.*/
01396                      linear_type = Real_8;
01397 /* works well for source-level translation--fzhao
01398 # elif defined(_TARGET_OS_LINUX)
01399                      PRINTMSG(TOKEN_LINE(token), 541, Error, 
01400                               TOKEN_COLUMN(token));
01401 */
01402 # else
01403                      linear_type = Real_16;
01404 
01405                      if (!on_off_flags.enable_double_precision) {
01406                         PRINTMSG(TOKEN_LINE(token), 710, Warning, 
01407                                  TOKEN_COLUMN(token),
01408                                  type_str,
01409                                  num);
01410                      }
01411 # endif
01412                   }
01413                }
01414                else {
01415                   switch (num) {
01416 
01417                   case 4:
01418                      linear_type = (cmd_line_flags.s_cf77types) ?
01419                                    REAL_DEFAULT_TYPE : Real_4;
01420                      break;
01421 
01422                   case 8:
01423                      linear_type = (cmd_line_flags.s_cf77types) ?
01424                                    REAL_DEFAULT_TYPE : Real_8;
01425                      break;
01426 
01427                   case 16:
01428 
01429 # ifdef _TARGET_OS_MAX
01430                      PRINTMSG(TOKEN_LINE(token), 391, Warning,
01431                               TOKEN_COLUMN(token),
01432                               type_str, num, type_str, 8);
01433                      linear_type = Real_8;
01434 
01435 /* works well for source level translation---fzhao
01436 # elif defined(_TARGET_OS_LINUX)
01437                      PRINTMSG(TOKEN_LINE(token), 541, Error, 
01438                               TOKEN_COLUMN(token));
01439 */
01440 # else
01441                      linear_type = Real_16;
01442 
01443                      if (!on_off_flags.enable_double_precision) {
01444                         PRINTMSG(TOKEN_LINE(token), 710, Warning, 
01445                                  TOKEN_COLUMN(token),
01446                                  type_str,
01447                                  num);
01448                      }
01449 # endif
01450                      break;
01451                   };
01452                }
01453 
01454                break;
01455 
01456 
01457             case Complex:
01458 
01459                switch (num) {
01460 
01461                case 8:
01462                   linear_type = (cmd_line_flags.s_cf77types) ?
01463                                 COMPLEX_DEFAULT_TYPE : Complex_4;
01464                   break;
01465 
01466                case 16:
01467                   linear_type = Complex_8;
01468                   break;
01469 
01470                case 32:
01471 
01472 # ifdef _TARGET_OS_MAX
01473                   PRINTMSG(TOKEN_LINE(token), 391, Warning, 
01474                            TOKEN_COLUMN(token),
01475                            type_str, num, type_str, 16);
01476                   linear_type = Complex_8;
01477 
01478 /* works well for source-level translation---fzhao
01479  *# elif defined(_TARGET_OS_LINUX)
01480  *                     PRINTMSG(TOKEN_LINE(token), 541, Error, 
01481  *                              TOKEN_COLUMN(token));
01482 */
01483 # else
01484                   linear_type = Complex_16;
01485 
01486                   if (!on_off_flags.enable_double_precision) {
01487                      PRINTMSG(TOKEN_LINE(token), 710, Warning, 
01488                               TOKEN_COLUMN(token),
01489                               type_str,
01490                               num);
01491                   }
01492 # endif
01493                   break;
01494                };
01495 
01496                break;
01497 
01498 
01499             case Logical:
01500 
01501                switch (num) {
01502 
01503                case 1:
01504                   linear_type = (cmd_line_flags.s_cf77types) ?
01505                                 LOGICAL_DEFAULT_TYPE : Logical_1;
01506                   break;
01507 
01508                case 2:
01509                   linear_type = (cmd_line_flags.s_cf77types) ?
01510                                 LOGICAL_DEFAULT_TYPE : Logical_2;
01511                   break;
01512 
01513                case 4:
01514                   linear_type = (cmd_line_flags.s_cf77types) ?
01515                                 LOGICAL_DEFAULT_TYPE : Logical_4;
01516                   break;
01517 
01518                case 8:
01519                   linear_type = (cmd_line_flags.s_cf77types) ?
01520                                 LOGICAL_DEFAULT_TYPE : Logical_8;
01521                   break;
01522 
01523                };  /* end switch */
01524 
01525                break;
01526 
01527             }  /* end switch */
01528 
01529 
01530             if (linear_type == Err_Res) {
01531                PRINTMSG(TOKEN_LINE(token), 125, Error,
01532                         TOKEN_COLUMN(token),
01533                         num,
01534                         type_str);
01535             }
01536             else {
01537                CLEAR_TBL_NTRY(type_tbl, TYP_WORK_IDX);
01538                TYP_TYPE(TYP_WORK_IDX)           = TYP_TYPE(type_idx);
01539                TYP_LINEAR(TYP_WORK_IDX)         = linear_type;
01540                TYP_DCL_VALUE(TYP_WORK_IDX)      = num;
01541                TYP_DESC(TYP_WORK_IDX)           = Star_Typed;
01542                ATD_TYPE_IDX(AT_WORK_IDX)        = ntr_type_tbl();
01543 
01544                PRINTMSG(TOKEN_LINE(token), 124, Ansi, 
01545                         TOKEN_COLUMN(token),
01546                         type_str,
01547                         num);
01548 
01549             }
01550          }
01551          else { /* Cannot search - because of IMPLICIT calls */
01552             parse_err_flush(Find_None, "scalar-int-literal-constant");
01553          }
01554       }
01555    }
01556 
01557 
01558 #if 0
01559 
01560    /* LRR    2 Feb 1996                                                       */
01561    /* I turned off the following code in response to an email direction to do */
01562    /* so from Peggy Boike.  I did not remove the code due to the belief that  */
01563    /* we just might need to turn it back on.  If some months go by, and the   */
01564    /* libraries really can handle this, then the code should be safe to       */
01565    /* actually be removed.                                                    */
01566 
01567    if ((target_triton  &&  target_ieee)   &&
01568        (TYP_LINEAR(ATD_TYPE_IDX(AT_WORK_IDX)) == Real_16  ||
01569        TYP_LINEAR(ATD_TYPE_IDX(AT_WORK_IDX)) == Complex_16)) {
01570 
01571       /* Temporary warning because PRECISION may not be as high as requested */
01572 
01573       PRINTMSG(TOKEN_LINE(token), 1145, Warning, 0);
01574       SET_MSG_SUPPRESS_TBL(1145);  /* Issue once per compilation unit */
01575    }
01576 
01577 #endif
01578 
01579 
01580    parse_err                    = SH_ERR_FLG(curr_stmt_sh_idx);
01581    SH_ERR_FLG(curr_stmt_sh_idx) = save_err || parse_err;
01582 
01583    TRACE (Func_Exit, "parse_type_spec", NULL);
01584 
01585    return (!parse_err);
01586 
01587 }  /* parse_type_spec */
01588 
01589 
01590 /******************************************************************************\
01591 |*                                                                            *|
01592 |* Description:                                                               *|
01593 |*      Add the PUBLIC or PRIVATE attribute to an attr.                       *|
01594 |*                                                                            *|
01595 |* Input parameters:                                                          *|
01596 |*      attr_idx -> Attr index to add the PUBLIC or PRIVATE access to.        *|
01597 |*      line     -> The line number of the object to add the attribute to     *|
01598 |*      column   -> The line number of the object to add the attribute to     *|
01599 |*      access   -> Public or Private                                         *|
01600 |*                                                                            *|
01601 |* Output parameters:                                                         *|
01602 |*      NONE                                                                  *|
01603 |*                                                                            *|
01604 |* Returns:                                                                   *|
01605 |*      TRUE if successful merge.                                             *|
01606 |*                                                                            *|
01607 \******************************************************************************/
01608 
01609 boolean merge_access(int                attr_idx,
01610                      int                line,
01611                      int                column,
01612                      access_type        access)
01613 
01614 {
01615    boolean      err_found;
01616    int          sn_idx;
01617 
01618 
01619    TRACE (Func_Entry, "merge_access", NULL);
01620 
01621    /* Error if access is already set, or if it is host associated */
01622 
01623    err_found = ((AT_ACCESS_SET(attr_idx) && access != AT_PRIVATE(attr_idx)) ||
01624                  AT_NOT_VISIBLE(attr_idx) ||
01625                 (AT_ATTR_LINK(attr_idx) != NULL_IDX));
01626 
01627    switch (AT_OBJ_CLASS(attr_idx)) {
01628       case Data_Obj:
01629 
01630          if (ATD_SYMBOLIC_CONSTANT(attr_idx)) {
01631             err_found = TRUE;
01632          }
01633          break;
01634 
01635       case Pgm_Unit:
01636          if (ATP_PROC(attr_idx) == Intrin_Proc ||
01637              ATP_PGM_UNIT(attr_idx) == Program ||
01638              ATP_PGM_UNIT(attr_idx) == Module ||
01639              ATP_PGM_UNIT(attr_idx) == Blockdata) {
01640             err_found = TRUE;
01641          }
01642          break;
01643 
01644       case Interface:
01645          break;
01646 
01647       case Stmt_Func:
01648          err_found = TRUE;
01649          break;
01650 
01651       case Label:
01652          err_found = TRUE;
01653          break;
01654 
01655       default:
01656          break;
01657 
01658    }  /* end switch */
01659 
01660 
01661 # ifdef _DEBUG
01662 
01663    /* Check to make sure that this routine is catching everything in the  */
01664    /* semantic tables, because it only calls fnd_semantic_err if it finds */
01665    /* an error.                                                           */
01666 
01667    if (!err_found &&
01668        fnd_semantic_err(((access == Public) ? Obj_Public : Obj_Private),
01669                         line, 
01670                         column,
01671                         attr_idx,
01672                         TRUE)) {
01673       PRINTMSG(line, 655, Internal, column, "merge_access");
01674    }
01675 # endif
01676 
01677    if (err_found) {
01678       fnd_semantic_err(((access == Public) ? Obj_Public : Obj_Private),
01679                        line,
01680                        column,
01681                        attr_idx,
01682                        TRUE);
01683    }
01684    else {
01685 
01686       if (AT_ACCESS_SET(attr_idx)) {  /* Duplicate declaration */
01687          PRINTMSG(line, 1259, Ansi, column,
01688                   AT_OBJ_NAME_PTR(attr_idx),
01689                   (access == Public) ? "PUBLIC":"PRIVATE");
01690       }
01691 
01692       AT_PRIVATE(attr_idx)      = access;
01693       AT_ACCESS_SET(attr_idx)   = TRUE;
01694 
01695       if (AT_OBJ_CLASS(attr_idx) == Interface) { 
01696 
01697          if (AT_IS_INTRIN(attr_idx)) {
01698             sn_idx      = ATI_FIRST_SPECIFIC_IDX(attr_idx);
01699 
01700             while (sn_idx != NULL_IDX) {
01701 
01702                if (AT_IS_INTRIN(SN_ATTR_IDX(sn_idx))) {
01703                   AT_PRIVATE(SN_ATTR_IDX(sn_idx))       = access;
01704                   AT_ACCESS_SET(SN_ATTR_IDX(sn_idx))    = TRUE;
01705                }
01706                sn_idx = SN_SIBLING_LINK(sn_idx);
01707             }
01708          }
01709          else if (ATI_PROC_IDX(attr_idx) != NULL_IDX) {
01710             AT_PRIVATE(ATI_PROC_IDX(attr_idx))          = access;
01711             AT_ACCESS_SET(ATI_PROC_IDX(attr_idx))       = TRUE;
01712          }
01713       }
01714    }
01715 
01716    TRACE (Func_Exit, "merge_access", NULL);
01717 
01718    return(!err_found);
01719 
01720 }  /* merge_access */
01721 
01722 
01723 /******************************************************************************\
01724 |*                                                                            *|
01725 |* Description:                                                               *|
01726 |*      Add the ALLOCATABLE attribute to an attr.                             *|
01727 |*                                                                            *|
01728 |* Input parameters:                                                          *|
01729 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
01730 |*                       is FALSE, just add the attribute to the attr.        *|
01731 |*      line     -> The line number of the object to add the attribute to     *|
01732 |*      column   -> The line number of the object to add the attribute to     *|
01733 |*      attr_idx -> Attr index to add the ALLOCATABLE attribute to.           *|
01734 |*                                                                            *|
01735 |* Output parameters:                                                         *|
01736 |*      NONE                                                                  *|
01737 |*                                                                            *|
01738 |* Returns:                                                                   *|
01739 |*      TRUE if successful merge.                                             *|
01740 |*                                                                            *|
01741 \******************************************************************************/
01742 
01743 boolean merge_allocatable(boolean chk_semantics,
01744                           int     line,
01745                           int     column,
01746                           int     attr_idx)
01747 
01748 {
01749    boolean      fnd_err         = FALSE;
01750 
01751 
01752    TRACE (Func_Entry, "merge_allocatable", NULL);
01753 
01754    if (chk_semantics) {
01755       fnd_err = fnd_semantic_err(Obj_Allocatable,
01756                                  line,
01757                                  column,
01758                                  attr_idx,
01759                                  TRUE);
01760       if (!fnd_err) {
01761 
01762          if (ATD_ALLOCATABLE(attr_idx)) {
01763             PRINTMSG(line, 1259, Ansi, column,
01764                      AT_OBJ_NAME_PTR(attr_idx),
01765                      "ALLOCATABLE");
01766          }
01767          ATD_ALLOCATABLE(attr_idx) = TRUE;
01768 /*          ATD_IM_A_DOPE(attr_idx)   = TRUE; */
01769       }
01770    }
01771    else {
01772       SET_IMPL_TYPE(attr_idx);
01773       ATD_ALLOCATABLE(attr_idx) = TRUE;
01774 /*      ATD_IM_A_DOPE(attr_idx)   = TRUE; */
01775    }
01776 
01777 
01778    TRACE (Func_Exit, "merge_allocatable", NULL);
01779 
01780    return(!fnd_err);
01781 
01782 }  /* merge_allocatable */
01783 
01784 
01785 
01786 /******************************************************************************\
01787 |*                                                                            *|
01788 |* Description:                                                               *|
01789 |*      Add the AUTOMATIC attribute to an attr.                               *|
01790 |*                                                                            *|
01791 |* Input parameters:                                                          *|
01792 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
01793 |*                       is FALSE, just add the attribute to the attr.        *|
01794 |*      line     -> The line number of the object to add the attribute to     *|
01795 |*      column   -> The line number of the object to add the attribute to     *|
01796 |*      attr_idx -> Attr index to add the AUTOMATIC attribute to.             *|
01797 |*                                                                            *|
01798 |* Output parameters:                                                         *|
01799 |*      NONE                                                                  *|
01800 |*                                                                            *|
01801 |* Returns:                                                                   *|
01802 |*      TRUE if successful merge.                                             *|
01803 |*                                                                            *|
01804 \******************************************************************************/
01805 
01806 boolean merge_automatic(boolean         chk_semantics,
01807                         int             line,
01808                         int             column,
01809                         int             attr_idx)
01810 
01811 {
01812    boolean      fnd_err         = FALSE;
01813    int          rslt_idx;
01814 
01815 
01816    TRACE (Func_Entry, "merge_automatic", NULL);
01817 
01818    if (chk_semantics) {
01819       fnd_err = fnd_semantic_err(Obj_Automatic,
01820                                  line,
01821                                  column,
01822                                  attr_idx,
01823                                  TRUE);
01824 
01825       if (!fnd_err && AT_OBJ_CLASS(attr_idx) == Pgm_Unit) {
01826 
01827          if (ATP_RSLT_IDX(attr_idx) == NULL_IDX) {
01828             CREATE_FUNC_RSLT(attr_idx, rslt_idx);
01829             ATP_PGM_UNIT(attr_idx)      = Function;
01830             SET_IMPL_TYPE(rslt_idx);
01831             attr_idx                    = rslt_idx;
01832          }
01833          else {
01834             attr_idx = ATP_RSLT_IDX(attr_idx);
01835             fnd_err  = fnd_semantic_err(Obj_Automatic, 
01836                                         line,
01837                                         column,
01838                                         attr_idx,
01839                                         TRUE);
01840          }
01841       }
01842 
01843       if (!fnd_err && ATD_CLASS(attr_idx) == Function_Result &&
01844           (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Character ||
01845            TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Structure ||
01846            ATD_ARRAY_IDX(attr_idx) != NULL_IDX ||
01847            ATD_POINTER(attr_idx))) {
01848          AT_DCL_ERR(attr_idx)   = TRUE;
01849          fnd_err                        = TRUE;
01850          PRINTMSG(line, 1255, Error, column, AT_OBJ_NAME_PTR(attr_idx));
01851       }
01852 
01853       if (!fnd_err) {
01854 
01855          if (ATD_STACK(attr_idx)) {
01856             PRINTMSG(line, 1259, Ansi, column,
01857                      AT_OBJ_NAME_PTR(attr_idx),
01858                      "AUTOMATIC");
01859          }
01860          ATD_STACK(attr_idx) = TRUE;
01861       }
01862    }
01863    else {
01864       SET_IMPL_TYPE(attr_idx);
01865       ATD_STACK(attr_idx) = TRUE;
01866    }
01867 
01868    TRACE (Func_Exit, "merge_automatic", NULL);
01869 
01870    return(!fnd_err);
01871 
01872 }  /* merge_automatic */
01873 
01874 
01875 /******************************************************************************\
01876 |*                                                                            *|
01877 |* Description:                                                               *|
01878 |*      Add the DIMENSION attribute to an attr.                               *|
01879 |*                                                                            *|
01880 |* Input parameters:                                                          *|
01881 |*      attr_idx -> Attr index to add the ALLOCATABLE attribute to.           *|
01882 |*      line     -> The line number of the object to add the attribute to     *|
01883 |*      column   -> The line number of the object to add the attribute to     *|
01884 |*      array_idx-> The index of the bounds table index to add to the attr.   *|
01885 |*                                                                            *|
01886 |* Output parameters:                                                         *|
01887 |*      NONE                                                                  *|
01888 |*                                                                            *|
01889 |* Returns:                                                                   *|
01890 |*      TRUE if successful merge.                                             *|
01891 |*                                                                            *|
01892 \******************************************************************************/
01893 
01894 boolean merge_dimension(int     attr_idx,
01895                         int     line,
01896                         int     column,
01897                         int     array_idx)
01898 
01899 {
01900    obj_type             dcl_type;
01901    boolean              err_fnd;
01902    int                  i;
01903    int                  old_bd_idx;
01904    int                  rslt_idx;
01905    boolean              same;
01906 
01907 
01908    TRACE (Func_Entry, "merge_dimension", NULL);
01909 
01910    if (BD_DCL_ERR(array_idx)) {  /* Don't try if bad array declaration */
01911       AT_DCL_ERR(attr_idx)      = TRUE;
01912       err_fnd                   = TRUE;
01913       goto EXIT;
01914    }
01915        
01916    switch (BD_ARRAY_CLASS(array_idx)) {
01917 
01918       case Explicit_Shape:
01919          dcl_type = Obj_Expl_Shp_Arr;
01920          break;
01921 
01922       case Deferred_Shape:
01923          dcl_type = Obj_Defrd_Shp_Arr;
01924          break;
01925 
01926       case Assumed_Size:
01927          dcl_type = Obj_Assum_Size_Arr;
01928          break;
01929 
01930       case Assumed_Shape:
01931          dcl_type = Obj_Assum_Shp_Arr;
01932          break;
01933 
01934    }  /* End switch */
01935 
01936    if (AT_OBJ_CLASS(attr_idx) == Interface && 
01937        ATI_PROC_IDX(attr_idx) != NULL_IDX) {
01938        attr_idx = ATI_PROC_IDX(attr_idx);
01939    }
01940 
01941    if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit && ATP_PGM_UNIT(attr_idx) != Module) {
01942       rslt_idx = ATP_RSLT_IDX(attr_idx);
01943 
01944       if (rslt_idx != NULL_IDX) {       /* Has a function result already */
01945 
01946          if (ATP_RSLT_NAME(attr_idx) && !AT_NOT_VISIBLE(attr_idx)) {
01947             PRINTMSG(line, 27, Error, column, AT_OBJ_NAME_PTR(attr_idx),
01948                      AT_OBJ_NAME_PTR(rslt_idx));
01949             AT_DCL_ERR(attr_idx)        = TRUE;
01950             AT_DCL_ERR(rslt_idx)        = TRUE;
01951          }
01952          else {
01953 
01954             if (AT_REFERENCED(attr_idx) > Not_Referenced &&
01955                 is_attr_referenced_in_bound(array_idx, attr_idx)) {
01956                err_fnd  = TRUE;
01957             }
01958             else {
01959                err_fnd = fnd_semantic_err(dcl_type,
01960                                           line,
01961                                           column,
01962                                           attr_idx,
01963                                           TRUE);
01964             }
01965 
01966             if (!err_fnd) {
01967 
01968                if (ATD_ARRAY_IDX(rslt_idx) != NULL_IDX) {
01969 
01970                   /* This has an array declaration already.  Is it the same? */
01971 
01972                   old_bd_idx    = ATD_ARRAY_IDX(rslt_idx);
01973                   same          = (old_bd_idx == array_idx);
01974 
01975                   if (!same && 
01976                       BD_ARRAY_CLASS(old_bd_idx)==BD_ARRAY_CLASS(array_idx)&&
01977                       BD_RANK(old_bd_idx) == BD_RANK(array_idx) &&
01978                       BD_ARRAY_SIZE(old_bd_idx) == BD_ARRAY_SIZE(array_idx)){
01979 
01980                      if (BD_ARRAY_CLASS(array_idx) != Deferred_Shape) {
01981                         same    = TRUE;
01982 
01983                         for (i = 1; i <= BD_RANK(array_idx); i++) {
01984 
01985                            if (BD_UB_FLD(old_bd_idx,i)!=BD_UB_FLD(array_idx,i)||
01986                                (BD_UB_FLD(old_bd_idx,i) == AT_Tbl_Idx &&
01987                               BD_UB_IDX(old_bd_idx,i)!=BD_UB_IDX(array_idx,i))||
01988                                (BD_UB_FLD(old_bd_idx,i) == CN_Tbl_Idx &&
01989                                 fold_relationals(BD_UB_IDX(old_bd_idx,i),
01990                                                  BD_UB_IDX(array_idx,i),
01991                                                  Ne_Opr)) ||
01992                                BD_LB_FLD(old_bd_idx,i)!=BD_LB_FLD(array_idx,i)||
01993                                (BD_LB_FLD(old_bd_idx,i) == AT_Tbl_Idx &&
01994                               BD_LB_IDX(old_bd_idx,i)!=BD_LB_IDX(array_idx,i))||
01995                                (BD_LB_FLD(old_bd_idx,i) == CN_Tbl_Idx &&
01996                                 fold_relationals(BD_LB_IDX(old_bd_idx,i),
01997                                                  BD_LB_IDX(array_idx,i),
01998                                                  Ne_Opr))) {
01999                               same      = FALSE;
02000                               break;
02001                            }
02002                         }
02003                      }
02004                   }
02005 
02006                   if (same) {
02007                      PRINTMSG(line, 1259, Ansi, column, 
02008                               AT_OBJ_NAME_PTR(rslt_idx), "DIMENSION");
02009                   }
02010                   else {
02011                      PRINTMSG(line, 554, Error, column, 
02012                               AT_OBJ_NAME_PTR(rslt_idx), "DIMENSION",
02013                               "DIMENSION");
02014                   }
02015                }
02016                else {
02017                   ATD_ARRAY_IDX(rslt_idx) = array_idx;
02018                }
02019             }
02020 
02021             if (ATP_RECURSIVE(attr_idx) && !on_off_flags.recursive) {
02022                PRINTMSG(line, 184, Caution, column, AT_OBJ_NAME_PTR(attr_idx));
02023             }
02024          }
02025       }
02026       else {
02027 
02028          if (AT_REFERENCED(attr_idx) > Not_Referenced &&
02029              is_attr_referenced_in_bound(array_idx, attr_idx)) {
02030             err_fnd     = TRUE;
02031          }
02032          else {
02033             err_fnd = fnd_semantic_err(dcl_type,
02034                                        line,
02035                                        column,
02036                                        attr_idx,
02037                                        TRUE);
02038          }
02039 
02040          /* This must be a Function if it's legal */
02041 
02042          if (!err_fnd) {
02043             CREATE_FUNC_RSLT(attr_idx, rslt_idx);
02044             ATP_PGM_UNIT(attr_idx)      = Function;
02045             ATD_ARRAY_IDX(rslt_idx)     = array_idx;
02046             SET_IMPL_TYPE(rslt_idx);
02047          }
02048       }
02049    }
02050    else {
02051       if (AT_REFERENCED(attr_idx) > Not_Referenced &&
02052           is_attr_referenced_in_bound(array_idx, attr_idx)) {
02053          err_fnd        = TRUE;
02054       }
02055       else {
02056          err_fnd = fnd_semantic_err(dcl_type,
02057                                     line,
02058                                     column,
02059                                     attr_idx,
02060                                     TRUE);
02061       }
02062          
02063       if (!err_fnd) {
02064 
02065          if (ATD_ARRAY_IDX(attr_idx) != NULL_IDX) {
02066 
02067             /* This has an array declaration already.  Is it the same? */
02068 
02069             old_bd_idx  = ATD_ARRAY_IDX(attr_idx);
02070             same        = (old_bd_idx == array_idx);
02071 
02072             if (!same && 
02073                 BD_ARRAY_CLASS(old_bd_idx) == BD_ARRAY_CLASS(array_idx) &&
02074                 BD_RANK(old_bd_idx) == BD_RANK(array_idx) &&
02075                 BD_ARRAY_SIZE(old_bd_idx) == BD_ARRAY_SIZE(array_idx)) {
02076 
02077                if (BD_ARRAY_CLASS(array_idx) != Deferred_Shape) {
02078                   same  = TRUE;
02079 
02080                   for (i = 1; i <= BD_RANK(array_idx); i++) {
02081 
02082                      if (BD_UB_FLD(old_bd_idx,i) != BD_UB_FLD(array_idx,i)||
02083                          (BD_UB_FLD(old_bd_idx,i) == AT_Tbl_Idx &&
02084                           BD_UB_IDX(old_bd_idx,i) != BD_UB_IDX(array_idx,i))||
02085                          (BD_UB_FLD(old_bd_idx,i) == CN_Tbl_Idx &&
02086                           fold_relationals(BD_UB_IDX(old_bd_idx,i),
02087                                            BD_UB_IDX(array_idx,i),
02088                                            Ne_Opr)) ||
02089                          BD_LB_FLD(old_bd_idx,i) != BD_LB_FLD(array_idx,i)||
02090                          (BD_LB_FLD(old_bd_idx,i) == AT_Tbl_Idx &&
02091                           BD_LB_IDX(old_bd_idx,i) != BD_LB_IDX(array_idx,i))||
02092                          (BD_LB_FLD(old_bd_idx,i) == CN_Tbl_Idx &&
02093                           fold_relationals(BD_LB_IDX(old_bd_idx,i),
02094                                            BD_LB_IDX(array_idx,i),
02095                                            Ne_Opr))) {
02096 
02097                         same    = FALSE;
02098                         break;
02099                      }
02100                   }
02101                }
02102             }
02103 
02104             if (same) {
02105                PRINTMSG(line, 1259, Ansi, column, 
02106                         AT_OBJ_NAME_PTR(attr_idx), "DIMENSION");
02107             }
02108             else {
02109                PRINTMSG(line, 554, Error, column, 
02110                         AT_OBJ_NAME_PTR(attr_idx), "DIMENSION", "DIMENSION");
02111             }
02112          }
02113          else {
02114             ATD_ARRAY_IDX(attr_idx)     = array_idx;
02115 
02116             if (BD_ARRAY_CLASS(array_idx) == Assumed_Shape ||
02117                 BD_ARRAY_CLASS(array_idx) == Deferred_Shape) {
02118 
02119             }
02120          }
02121       }
02122    }
02123 
02124 EXIT:
02125 
02126    TRACE (Func_Exit, "merge_dimension", NULL);
02127 
02128    return(!err_fnd);
02129 
02130 }  /* merge_dimension */
02131 
02132 /******************************************************************************\
02133 |*                                                                            *|
02134 |* Description:                                                               *|
02135 |*      Add the DATA or initialization attribute to an Attr.                  *|
02136 |*      As long as we're here, also mark the Attr as being defined.           *|
02137 |*                                                                            *|
02138 |* Input parameters:                                                          *|
02139 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02140 |*                       is FALSE, just add the attribute to the Attr.        *|
02141 |*      line     -> The line number of the object to add the attribute to.    *|
02142 |*      column   -> The line number of the object to add the attribute to.    *|
02143 |*      attr_idx -> Attr index to add the DATA attribute to.                  *|
02144 |*                                                                            *|
02145 |* Output parameters:                                                         *|
02146 |*      NONE                                                                  *|
02147 |*                                                                            *|
02148 |* Returns:                                                                   *|
02149 |*      TRUE if successful merge.                                             *|
02150 |*                                                                            *|
02151 \******************************************************************************/
02152 
02153 boolean merge_data(boolean      chk_semantics,
02154                    int          line,
02155                    int          column,
02156                    int          attr_idx)
02157 
02158 {
02159    boolean      fnd_err         = FALSE;
02160 
02161 
02162    TRACE (Func_Entry, "merge_data", NULL);
02163    
02164    if (chk_semantics) {
02165       fnd_err = fnd_semantic_err(Obj_Data_Init,
02166                                  line,
02167                                  column,
02168                                  attr_idx,
02169                                  TRUE);
02170    }
02171 
02172    if (!fnd_err) {
02173       AT_DEFINED(attr_idx)    = TRUE;
02174       ATD_DATA_INIT(attr_idx) = TRUE;
02175       ATD_CLASS(attr_idx)     = Variable;
02176    }
02177 
02178    TRACE (Func_Exit, "merge_data", NULL);
02179 
02180    return(!fnd_err);
02181 
02182 }  /* merge_data */
02183 
02184 
02185 
02186 /******************************************************************************\
02187 |*                                                                            *|
02188 |* Description:                                                               *|
02189 |*      Add the EXTERNAL attribute to an attr.                                *|
02190 |*                                                                            *|
02191 |* Input parameters:                                                          *|
02192 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02193 |*                       is FALSE, just add the attribute to the attr.        *|
02194 |*      line     -> The line number of the object to add the attribute to     *|
02195 |*      column   -> The line number of the object to add the attribute to     *|
02196 |*      attr_idx -> Attr index to add the EXTERNAL attribute to.              *|
02197 |*                                                                            *|
02198 |* Output parameters:                                                         *|
02199 |*      NONE                                                                  *|
02200 |*                                                                            *|
02201 |* Returns:                                                                   *|
02202 |*      TRUE if successful merge.                                             *|
02203 |*                                                                            *|
02204 \******************************************************************************/
02205 
02206 boolean merge_external(boolean  chk_semantics,
02207                        int      line,
02208                        int      column,
02209                        int      attr_idx)
02210 
02211 {
02212    long         chk_err         = FALSE;
02213 
02214 
02215    TRACE (Func_Entry, "merge_external", NULL);
02216 
02217    if (AT_OBJ_CLASS(attr_idx) == Interface && 
02218        !AT_IS_INTRIN(attr_idx) &&               /* JBL  - this is a kludge */
02219        ATI_PROC_IDX(attr_idx) != NULL_IDX) {
02220        attr_idx = ATI_PROC_IDX(attr_idx);
02221    }
02222 
02223    if (chk_semantics && fnd_semantic_err(Obj_Dcl_Extern,
02224                                          line,
02225                                          column,
02226                                          attr_idx,
02227                                          TRUE)) {
02228       chk_err = TRUE;
02229    }
02230    else {
02231 
02232       if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
02233 
02234          /* By passing Pgm_Unknown, chg_data_obj_to_pgm_unit will decide */
02235          /* if this attr, should become a Function or a Pgm_Unknown.     */
02236 
02237          chg_data_obj_to_pgm_unit(attr_idx, 
02238                                   Pgm_Unknown,
02239                                   Extern_Proc);
02240       }
02241       else {
02242 
02243          if (ATP_DCL_EXTERNAL(attr_idx)) {
02244             PRINTMSG(line, 1259, Ansi, column, 
02245                      AT_OBJ_NAME_PTR(attr_idx),
02246                      "EXTERNAL");
02247          }
02248 
02249          if (ATP_PROC(attr_idx) == Unknown_Proc) {
02250             ATP_PROC(attr_idx) = Extern_Proc;
02251          }
02252 
02253          if (attr_idx == SCP_ATTR_IDX(curr_scp_idx)) {
02254 
02255             /* SUBROUTINE JOE(); EXTERNAL JOE   is non-standard. */
02256    
02257             PRINTMSG(line, 279, Ansi, column, AT_OBJ_NAME_PTR(attr_idx));
02258          }
02259       }
02260 
02261       ATP_DCL_EXTERNAL(attr_idx)        = TRUE;
02262       ATP_SCP_IDX(attr_idx)             = curr_scp_idx;
02263    }
02264 
02265    TRACE (Func_Exit, "merge_external", NULL);
02266 
02267    return(!chk_err);
02268 
02269 }  /* merge_external */
02270 
02271 
02272 /******************************************************************************\
02273 |*                                                                            *|
02274 |* Description:                                                               *|
02275 |*      Add the INTENT attribute to an attr.                                  *|
02276 |*      NOTE:  The intent to add is picked up from a global variable, called  *|
02277 |*             new_intent.                                                    *|
02278 |*                                                                            *|
02279 |* Input parameters:                                                          *|
02280 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02281 |*                       is FALSE, just add the attribute to the attr.        *|
02282 |*      line     -> The line number of the object to add the attribute to     *|
02283 |*      column   -> The line number of the object to add the attribute to     *|
02284 |*      attr_idx -> Attr index to add the EXTERNAL attribute to.              *|
02285 |*                                                                            *|
02286 |* Output parameters:                                                         *|
02287 |*      NONE                                                                  *|
02288 |*                                                                            *|
02289 |* Returns:                                                                   *|
02290 |*      TRUE if successful merge.                                             *|
02291 |*                                                                            *|
02292 \******************************************************************************/
02293 
02294 boolean merge_intent(boolean            chk_semantics,
02295                      int                line,
02296                      int                column,
02297                      int                attr_idx)
02298 
02299 {
02300    boolean      fnd_err         = FALSE;
02301 
02302 
02303    TRACE (Func_Entry, "merge_intent", NULL);
02304 
02305    if (AT_OBJ_CLASS(attr_idx) == Interface && 
02306        ATI_PROC_IDX(attr_idx) != NULL_IDX) {
02307        attr_idx = ATI_PROC_IDX(attr_idx);
02308    }
02309    
02310    if (chk_semantics) {
02311       fnd_err = fnd_semantic_err(Obj_Intent,
02312                                  line,
02313                                  column,
02314                                  attr_idx,
02315                                  TRUE);
02316 
02317       if (!fnd_err) {
02318 
02319          if (ATD_INTENT(attr_idx) != Intent_Unseen) {
02320 
02321             if (ATD_INTENT(attr_idx) == new_intent) {
02322                PRINTMSG(line, 1259, Ansi, column, AT_OBJ_NAME_PTR(attr_idx),
02323                         "INTENT");
02324             }
02325             else {  /* The intent is different */
02326                PRINTMSG(line, 554, Error, column, AT_OBJ_NAME_PTR(attr_idx),
02327                         "INTENT", "INTENT");
02328             }
02329          }
02330       }
02331    }
02332    else {
02333       SET_IMPL_TYPE(attr_idx);
02334    }
02335 
02336    if (!fnd_err) {
02337       ATD_CLASS(attr_idx)       = Dummy_Argument;
02338       ATD_INTENT(attr_idx)      = new_intent;
02339    }
02340 
02341    TRACE (Func_Exit, "merge_intent", NULL);
02342 
02343    return(!fnd_err);
02344 
02345 }  /* merge_intent */
02346 
02347 
02348 /******************************************************************************\
02349 |*                                                                            *|
02350 |* Description:                                                               *|
02351 |*      Add the INTRINSIC attribute to an attr.                               *|
02352 |*                                                                            *|
02353 |* Input parameters:                                                          *|
02354 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02355 |*                       is FALSE, just add the attribute to the attr.        *|
02356 |*      line     -> The line number of the object to add the attribute to     *|
02357 |*      column   -> The line number of the object to add the attribute to     *|
02358 |*      attr_idx -> Attr index to add the EXTERNAL attribute to.              *|
02359 |*                                                                            *|
02360 |* Output parameters:                                                         *|
02361 |*      NONE                                                                  *|
02362 |*                                                                            *|
02363 |* Returns:                                                                   *|
02364 |*      TRUE if successful merge.                                             *|
02365 |*                                                                            *|
02366 \******************************************************************************/
02367 
02368 boolean merge_intrinsic(boolean chk_semantics,
02369                         int     line,
02370                         int     column,
02371                         int     attr_idx)
02372 
02373 {
02374    boolean      found_error     = FALSE;
02375    int          save_curr_scp_idx;
02376    int          host_name_idx;
02377    int          host_attr_idx;
02378    int          sn_idx;
02379    int          type_idx;
02380 
02381 
02382    TRACE (Func_Entry, "merge_intrinsic", NULL);
02383 
02384    if (chk_semantics && fnd_semantic_err(Obj_Dcl_Intrin, 
02385                                          line, 
02386                                          column, 
02387                                          attr_idx,
02388                                          TRUE)) {
02389       found_error = TRUE;
02390    }
02391    else if (AT_IS_INTRIN(attr_idx) && AT_OBJ_CLASS(attr_idx) == Interface) {
02392 
02393       if (ATI_DCL_INTRINSIC(attr_idx)) {
02394          PRINTMSG(line, 1259, Ansi, column, AT_OBJ_NAME_PTR(attr_idx),
02395                   "INTRINSIC");
02396       }
02397       ATI_DCL_INTRINSIC(attr_idx) = TRUE;
02398    }
02399    else {
02400 
02401       /* The INTRINSIC has not been copied down yet. - So copy it. */
02402 
02403 # if 0 /* keep intrinsic function has an attribut table entry,don't merge with 
02404         * user defined interface attribute entry
02405         */
02406 
02407       host_attr_idx = srch_host_sym_tbl(AT_OBJ_NAME_PTR(attr_idx),
02408                                         AT_NAME_LEN(attr_idx),
02409                                         &host_name_idx,
02410                                         TRUE);
02411       if (host_attr_idx != NULL_IDX) {
02412 
02413          /* go directly to the INTRINSIC scope if not interface */
02414          /* or if it is not the name of a specific intrinsic.   */
02415 
02416          if (AT_OBJ_CLASS(host_attr_idx) != Interface ||
02417              !ATI_GENERIC_INTRINSIC(host_attr_idx)) {
02418 
02419 #endif
02420             save_curr_scp_idx = curr_scp_idx;
02421             curr_scp_idx = INTRINSIC_SCP_IDX;
02422             host_attr_idx = srch_sym_tbl(AT_OBJ_NAME_PTR(attr_idx),
02423                                          AT_NAME_LEN(attr_idx),
02424                                          &host_name_idx);
02425             curr_scp_idx = save_curr_scp_idx;
02426 
02427 /*         } */
02428 
02429          if (host_attr_idx != NULL_IDX &&
02430              AT_IS_INTRIN(host_attr_idx) &&
02431              ATI_FIRST_SPECIFIC_IDX(host_attr_idx) == NULL_IDX) {
02432             complete_intrinsic_definition(host_attr_idx);
02433          }
02434 
02435 /*      } */
02436 
02437       if (host_attr_idx == NULL_IDX) {
02438 
02439          /* Error - Couldn't find the intrinsic.  Set implicit type.  */
02440 
02441          PRINTMSG(line, 701, Error, column, AT_OBJ_NAME_PTR(attr_idx));
02442          found_error = TRUE;
02443 
02444          if (AT_OBJ_CLASS(attr_idx) == Data_Obj && !AT_TYPED(attr_idx)) {
02445             SET_IMPL_TYPE(attr_idx);
02446          }
02447          else {
02448 
02449             if (AT_OBJ_CLASS(attr_idx) == Interface && 
02450                 ATI_PROC_IDX(attr_idx) != NULL_IDX) {
02451                attr_idx = ATI_PROC_IDX(attr_idx);
02452             }
02453 
02454             if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit && 
02455                 ATP_PGM_UNIT(attr_idx) == Function &&
02456                !AT_TYPED(ATP_RSLT_IDX(attr_idx))) {
02457                SET_IMPL_TYPE(ATP_RSLT_IDX(attr_idx));
02458             }
02459          }
02460       }
02461       else if (AT_OBJ_CLASS(attr_idx) == Interface) {
02462 
02463          /* Both are interfaces.   Add these specific intrinsics behind     */
02464          /* any user declared specifics that have previously been declared. */
02465 
02466          AT_IS_INTRIN(attr_idx)         = TRUE;
02467          ATI_DCL_INTRINSIC(attr_idx)    = TRUE;
02468          ATI_NUM_SPECIFICS(attr_idx)   += ATI_NUM_SPECIFICS(host_attr_idx);
02469 
02470          sn_idx = ATI_FIRST_SPECIFIC_IDX(attr_idx);
02471 
02472          if (sn_idx == NULL_IDX) {
02473             ATI_FIRST_SPECIFIC_IDX(attr_idx) = 
02474                                           ATI_FIRST_SPECIFIC_IDX(host_attr_idx);
02475          }
02476          else {
02477             while (SN_SIBLING_LINK(sn_idx) != NULL_IDX) {
02478                sn_idx = SN_SIBLING_LINK(sn_idx);
02479             }
02480             SN_SIBLING_LINK(sn_idx) = ATI_FIRST_SPECIFIC_IDX(host_attr_idx);
02481          }
02482       }
02483       else {
02484 
02485          if (ATI_INTERFACE_CLASS(host_attr_idx) == 
02486                                                 Generic_Subroutine_Interface) {
02487 
02488             if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit) {
02489 
02490                if (ATP_RSLT_IDX(attr_idx) != NULL_IDX && 
02491                    AT_TYPED(ATP_RSLT_IDX(attr_idx))) {
02492                   PRINTMSG(line, 869, Error, column,
02493                            AT_OBJ_NAME_PTR(attr_idx));
02494                   found_error = TRUE;
02495                }
02496    
02497                ATP_RSLT_IDX(attr_idx) = NULL_IDX;
02498             }
02499             else if (AT_OBJ_CLASS(attr_idx) == Data_Obj && AT_TYPED(attr_idx)){
02500                PRINTMSG(line, 869, Error, column, AT_OBJ_NAME_PTR(attr_idx));
02501                found_error = TRUE;
02502             }
02503          }
02504 
02505          type_idx = NULL_IDX;
02506 
02507          if (AT_TYPED(attr_idx)) {
02508 
02509             if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
02510                type_idx = ATD_TYPE_IDX(attr_idx);
02511             }
02512             else if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit &&
02513                      ATP_RSLT_IDX(attr_idx) != NULL_IDX) {
02514                type_idx = ATD_TYPE_IDX(ATP_RSLT_IDX(attr_idx));
02515             }
02516          }
02517          COPY_VARIANT_ATTR_INFO(host_attr_idx,
02518                                 attr_idx, 
02519                                 Interface);
02520 
02521          AT_ELEMENTAL_INTRIN(attr_idx)  = AT_ELEMENTAL_INTRIN(host_attr_idx);
02522          AT_IS_INTRIN(attr_idx)         = TRUE;
02523          ATD_TYPE_IDX(attr_idx)         = type_idx;
02524          ATI_DCL_INTRINSIC(attr_idx)    = TRUE;
02525       }
02526    }
02527 
02528    TRACE (Func_Exit, "merge_intrinsic", NULL);
02529 
02530    return(!found_error);
02531 
02532 }  /* merge_intrinsic */
02533 
02534 
02535 /******************************************************************************\
02536 |*                                                                            *|
02537 |* Description:                                                               *|
02538 |*      NOTES: The object must be a dummy argument.             (p5-2,17-18)  *|
02539 |*             The object must be in a subpgm or interface blk  (5.2.2)       *|
02540 |*             The stmt must not be declared in a blockdata pgm (p11-6,31-33) *|
02541 |*             If in an ASSIGNMENT or an OPERATOR interface     (p12-6,1-4)   *|
02542 |*                cannot specify optional                                     *|
02543 |*             Must not be specified in a main program          (p11-1,33-36) *|
02544 |*                                                                            *|
02545 |*  END of declaration:                                                       *|
02546 |*         If allocatable - it must be a deferred-shape array.                *|
02547 |*                                                                            *|
02548 |* Input parameters:                                                          *|
02549 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02550 |*                       is FALSE, just add the attribute to the attr.        *|
02551 |*      line     -> The line number of the object to add the attribute to     *|
02552 |*      column   -> The line number of the object to add the attribute to     *|
02553 |*      attr_idx -> Attr index to add the EXTERNAL attribute to.              *|
02554 |*                                                                            *|
02555 |* Output parameters:                                                         *|
02556 |*      NONE                                                                  *|
02557 |*                                                                            *|
02558 |* Returns:                                                                   *|
02559 |*      TRUE if successful merge                                              *|
02560 |*                                                                            *|
02561 \******************************************************************************/
02562 
02563 boolean merge_optional (boolean chk_semantics,
02564                         int     line,
02565                         int     column,
02566                         int     attr_idx)
02567 
02568 {
02569    boolean      chk_err         = FALSE;
02570 
02571 
02572    TRACE (Func_Entry, "merge_optional", NULL);
02573 
02574    if (chk_semantics) {
02575       chk_err = fnd_semantic_err(Obj_Optional,
02576                                  line,
02577                                  column,
02578                                  attr_idx,
02579                                  TRUE);
02580 
02581       if (!chk_err && AT_OPTIONAL(attr_idx)) {
02582          PRINTMSG(line, 1259, Ansi, column, AT_OBJ_NAME_PTR(attr_idx),
02583                   "OPTIONAL");
02584       }
02585    }
02586    else {
02587       SET_IMPL_TYPE(attr_idx);
02588    }
02589 
02590    if (!chk_err) {
02591 
02592       if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
02593          ATD_CLASS(attr_idx)    = Dummy_Argument;
02594       }
02595       else {
02596          ATP_PROC(attr_idx)     = Dummy_Proc;
02597       }
02598       AT_OPTIONAL(attr_idx)     = TRUE;
02599    }
02600 
02601    TRACE (Func_Exit, "merge_optional", NULL);
02602 
02603    return(!chk_err);
02604 
02605 }  /* merge_optional */
02606 
02607 /******************************************************************************\
02608 |*                                                                            *|
02609 |* Description:                                                               *|
02610 |*      Add the POINTER attribute to an attr.                                 *|
02611 |*                                                                            *|
02612 |* Input parameters:                                                          *|
02613 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02614 |*                       is FALSE, just add the attribute to the attr.        *|
02615 |*      line     -> The line number of the object to add the attribute to     *|
02616 |*      column   -> The line number of the object to add the attribute to     *|
02617 |*      attr_idx -> Attr index to add the POINTER attribute to.               *|
02618 |*                                                                            *|
02619 |* Output parameters:                                                         *|
02620 |*      NONE                                                                  *|
02621 |*                                                                            *|
02622 |* Returns:                                                                   *|
02623 |*      TRUE if successful merge.                                             *|
02624 |*                                                                            *|
02625 \******************************************************************************/
02626 
02627 boolean merge_pointer(boolean   chk_semantics,
02628                       int       line,
02629                       int       column,
02630                       int       attr_idx)
02631 
02632 {
02633    boolean      fnd_err         = FALSE;
02634    int          rslt_idx;
02635 
02636 
02637    TRACE (Func_Entry, "merge_pointer", NULL);
02638 
02639    if (AT_OBJ_CLASS(attr_idx) == Interface && 
02640        ATI_PROC_IDX(attr_idx) != NULL_IDX) {
02641        attr_idx = ATI_PROC_IDX(attr_idx);
02642    }
02643 
02644    if (chk_semantics) {
02645 
02646       if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit && ATP_RSLT_NAME(attr_idx)) {
02647          PRINTMSG(line, 36, Error, column, AT_OBJ_NAME_PTR(attr_idx),
02648                   AT_OBJ_NAME_PTR(ATP_RSLT_IDX(attr_idx)));
02649          fnd_err                = TRUE;
02650          AT_DCL_ERR(attr_idx)   = TRUE;
02651       }
02652       else {
02653          fnd_err = fnd_semantic_err(Obj_Pointer,
02654                                     line,
02655                                     column,
02656                                     attr_idx,
02657                                     TRUE);
02658       }
02659 
02660       if (!fnd_err && AT_OBJ_CLASS(attr_idx) == Pgm_Unit) {
02661 
02662          if (ATP_RSLT_IDX(attr_idx) == NULL_IDX) {
02663             CREATE_FUNC_RSLT(attr_idx, rslt_idx);
02664             ATP_PGM_UNIT(attr_idx)      = Function;
02665             SET_IMPL_TYPE(rslt_idx);
02666             attr_idx                    = rslt_idx;
02667          }
02668          else {
02669             attr_idx = ATP_RSLT_IDX(attr_idx);
02670             fnd_err  = fnd_semantic_err(Obj_Pointer, 
02671                                         line,
02672                                         column,
02673                                         attr_idx,
02674                                         TRUE);
02675          }
02676       }
02677 
02678       if (!fnd_err) {
02679 
02680          if (ATD_POINTER(attr_idx)) {
02681             PRINTMSG(line, 1259, Ansi, column, AT_OBJ_NAME_PTR(attr_idx),
02682                      "POINTER");
02683          }
02684          ATD_POINTER(attr_idx)   = TRUE;
02685       }
02686    }
02687    else {
02688       SET_IMPL_TYPE(attr_idx);
02689       ATD_POINTER(attr_idx)   = TRUE;
02690    }
02691 
02692    TRACE (Func_Exit, "merge_pointer", NULL);
02693 
02694    return(!fnd_err);
02695 
02696 }  /* merge_pointer */
02697 
02698 
02699 /******************************************************************************\
02700 |*                                                                            *|
02701 |* Description:                                                               *|
02702 |*      Add the SAVE attribute to an attr.                                    *|
02703 |*                                                                            *|
02704 |* Input parameters:                                                          *|
02705 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02706 |*                       is FALSE, just add the attribute to the attr.        *|
02707 |*      line     -> The line number of the object to add the attribute to     *|
02708 |*      column   -> The line number of the object to add the attribute to     *|
02709 |*      attr_idx -> Attr index to add the EXTERNAL attribute to.              *|
02710 |*                                                                            *|
02711 |* Output parameters:                                                         *|
02712 |*      NONE                                                                  *|
02713 |*                                                                            *|
02714 |* Returns:                                                                   *|
02715 |*      TRUE if successful merge.                                             *|
02716 |*                                                                            *|
02717 \******************************************************************************/
02718 
02719 boolean merge_save(boolean      chk_semantics,
02720                    int          line,
02721                    int          column,
02722                    int          attr_idx)
02723 
02724 {
02725    boolean      fnd_err         = FALSE;
02726 
02727 
02728    TRACE (Func_Entry, "merge_save", NULL);
02729 
02730    if (chk_semantics) {
02731       fnd_err = fnd_semantic_err(Obj_Saved, line, column, attr_idx, TRUE);
02732 
02733       if (!fnd_err && ATD_SAVED(attr_idx)) {
02734          PRINTMSG(line, 1259, Ansi, column, AT_OBJ_NAME_PTR(attr_idx), "SAVE");
02735       }
02736    }
02737    else {
02738       SET_IMPL_TYPE(attr_idx);
02739    }
02740 
02741    if (!fnd_err) {
02742       ATD_SAVED(attr_idx) = TRUE;
02743       ATD_CLASS(attr_idx) = Variable;
02744    }
02745 
02746    TRACE (Func_Exit, "merge_save", NULL);
02747 
02748    return(!fnd_err);
02749 
02750 }  /* merge_save */
02751 
02752 
02753 /******************************************************************************\
02754 |*                                                                            *|
02755 |* Description:                                                               *|
02756 |*      Add the TARGET attribute to an attr.                                  *|
02757 |*                                                                            *|
02758 |* Input parameters:                                                          *|
02759 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
02760 |*                       is FALSE, just add the attribute to the attr.        *|
02761 |*      line     -> The line number of the object to add the attribute to     *|
02762 |*      column   -> The line number of the object to add the attribute to     *|
02763 |*      attr_idx -> Attr index to add the TARGET attribute to.                *|
02764 |*                                                                            *|
02765 |* Output parameters:                                                         *|
02766 |*      NONE                                                                  *|
02767 |*                                                                            *|
02768 |* Returns:                                                                   *|
02769 |*      TRUE if successful merge.                                             *|
02770 |*                                                                            *|
02771 \******************************************************************************/
02772 
02773 boolean merge_target(boolean    chk_semantics,
02774                      int        line,
02775                      int        column,
02776                      int        attr_idx)
02777 
02778 {
02779    boolean      fnd_err         = FALSE;
02780    int          rslt_idx;
02781 
02782 
02783    TRACE (Func_Entry, "merge_target", NULL);
02784 
02785    if (AT_OBJ_CLASS(attr_idx) == Interface && 
02786        ATI_PROC_IDX(attr_idx) != NULL_IDX) {
02787        attr_idx = ATI_PROC_IDX(attr_idx);
02788    }
02789 
02790    if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit && ATP_RSLT_NAME(attr_idx)) {
02791       PRINTMSG(line, 132, Error, column, AT_OBJ_NAME_PTR(attr_idx),
02792                AT_OBJ_NAME_PTR(ATP_RSLT_IDX(attr_idx)));
02793       fnd_err                   = TRUE;
02794       AT_DCL_ERR(attr_idx)      = TRUE;
02795    }
02796    else if (chk_semantics) {
02797       fnd_err = fnd_semantic_err(Obj_Target, line, column, attr_idx, TRUE);
02798    }
02799    else {
02800       SET_IMPL_TYPE(attr_idx);
02801    }
02802 
02803    if (!fnd_err && AT_OBJ_CLASS(attr_idx) == Pgm_Unit) {
02804 
02805       if (ATP_RSLT_IDX(attr_idx) == NULL_IDX) {
02806          CREATE_FUNC_RSLT(attr_idx, rslt_idx);
02807          ATP_PGM_UNIT(attr_idx) = Function;
02808          SET_IMPL_TYPE(rslt_idx);
02809          attr_idx = rslt_idx;
02810       } 
02811       else {
02812          attr_idx = ATP_RSLT_IDX(attr_idx);
02813          fnd_err  = fnd_semantic_err(Obj_Target,
02814                                      line,
02815                                      column,
02816                                      attr_idx,
02817                                      TRUE);
02818       }
02819    }
02820 
02821    if (!fnd_err) {
02822 
02823       if (!fnd_err && ATD_TARGET(attr_idx)) {
02824          PRINTMSG(line, 1259, Ansi, column, AT_OBJ_NAME_PTR(attr_idx),"TARGET");
02825       }
02826       ATD_TARGET(attr_idx) = TRUE;
02827    }
02828 
02829    TRACE (Func_Exit, "merge_target", NULL);
02830 
02831    return(!fnd_err);
02832 
02833 }  /* merge_target */
02834 
02835 /******************************************************************************\
02836 |*                                                                            *|
02837 |* Description:                                                               *|
02838 |*      This routine parses integer specification expressions.  It is used by *|
02839 |*      the parsing routines for array boundaries, character lengths, and     *|
02840 |*      kind type parameters.  It takes a shortcut if there is just a literal *|
02841 |*      integer constant like B(10).  It would pick this up itself without    *|
02842 |*      calling the expression parser.  Expression semantics is called only   *|
02843 |*      if input fold_it tells it do it.  This is because kind type parameters*|
02844 |*      can be folded right away, but array and character bounds must wait    *|
02845 |*      until the end of pass1.  If this doesn't come out to be a constant    *|
02846 |*      value, tmp = is generated and the tmp is added to the bounds list.    *|
02847 |*                                                                            *|
02848 |* Input parameters:                                                          *|
02849 |*      fold_it          -> A flag that tells this routine whether to try to  *|
02850 |*                          fold this value or not.                           *|
02851 |*      kind_type        -> A flag that tells this routine is being called    *|
02852 |*                          to process kind type or not.                      *|
02853 |*                                                                            *|
02854 |* Output parameters:                                                         *|
02855 |*      len_idx     -> This is a ptr to a table index.  field_type tells what *|
02856 |*                     kind of index this is.                                 *|
02857 |*      field_type  -> This is a ptr to what kind of table index this is.  It *|
02858 |*                     contains the fld_type enum. (AT_Tbl_Idx, IR_Tbl_Idx ect*|
02859 |*                                                                            *|
02860 |* Returns:                                                                   *|
02861 |*      Returns TRUE if it parsed okay.                                       *|
02862 |*                                                                            *|
02863 \******************************************************************************/
02864 static boolean  parse_int_spec_expr(long                *len_idx,
02865                                     fld_type            *field_type,
02866                                     boolean              fold_it,
02867                                     boolean              char_len)
02868 
02869 {
02870    int                  column;
02871    expr_arg_type        expr_desc;
02872    opnd_type            len_opnd;
02873    int                  line;
02874    boolean              parse_ok;
02875    expr_mode_type       save_expr_mode  = expr_mode;
02876    int                  type_idx;
02877 
02878 # if defined(GENERATE_WHIRL)
02879    int                  cvrt_idx;
02880    int                  new_type;
02881 # endif
02882 
02883 
02884    TRACE (Func_Entry, "parse_int_spec_expr", NULL);
02885 
02886    xref_state           = CIF_Symbol_Reference;
02887    *field_type          = CN_Tbl_Idx;
02888    *len_idx             = CN_INTEGER_ONE_IDX;
02889    expr_mode            = fold_it ? Initialization_Expr : Specification_Expr;
02890    line                 = LA_CH_LINE;
02891    column               = LA_CH_COLUMN;
02892    expr_desc            = init_exp_desc;
02893 
02894    if (!parse_expr(&len_opnd)) {
02895       parse_ok  = FALSE;
02896       goto EXIT;
02897    }
02898 
02899 
02900    if (fold_it) {
02901 
02902       expr_desc.rank = 0;
02903 
02904       if (!expr_semantics(&len_opnd, &expr_desc)) {
02905          parse_ok       = FALSE;
02906          goto EXIT;
02907       }
02908 
02909       if (expr_desc.rank != 0) {
02910          PRINTMSG(line, 907, Error, column);
02911          parse_ok       = FALSE;
02912          goto EXIT;
02913       }
02914 
02915       if (OPND_FLD(len_opnd) != CN_Tbl_Idx) {
02916          PRINTMSG(line, 1531, Error, column);
02917          parse_ok       = FALSE;
02918          goto EXIT;
02919       }
02920 
02921       if (parsing_kind_selector) {
02922          if (expr_desc.kind0seen) {
02923             kind0seen = TRUE;
02924          }
02925          else if (expr_desc.kind0E0seen) {
02926             kind0E0seen = TRUE;
02927          }
02928          else if (expr_desc.kind0D0seen) {
02929             kind0D0seen = TRUE;
02930          }
02931          else if (! expr_desc.kindnotconst) {
02932             kindconstseen = TRUE;
02933          }
02934       }
02935    }
02936 
02937    parse_ok = TRUE;
02938 
02939    if (OPND_FLD(len_opnd) == CN_Tbl_Idx) {
02940       type_idx  = CN_TYPE_IDX(OPND_IDX(len_opnd));
02941 
02942       if (TYP_TYPE(type_idx) != Integer) {
02943     
02944          if (TYP_TYPE(type_idx) == Typeless) {
02945 
02946             if (TYP_LINEAR(type_idx) == Short_Typeless_Const) {
02947                PRINTMSG(line, 221, Ansi, column);
02948 
02949                OPND_IDX(len_opnd) = cast_typeless_constant(OPND_IDX(len_opnd),
02950                                                            INTEGER_DEFAULT_TYPE,
02951                                                            line, 
02952                                                            column);
02953                type_idx = INTEGER_DEFAULT_TYPE;
02954             }
02955             else { /* hollerith too long */
02956                PRINTMSG(line, 1133, Error, column);
02957                parse_ok = FALSE;
02958             }
02959          }
02960          else {
02961             PRINTMSG(line, 488, Error, column,
02962                      get_basic_type_str(type_idx));
02963             parse_ok    = FALSE;
02964          }
02965       }
02966 
02967       *len_idx          = (long) OPND_IDX(len_opnd);
02968       *field_type       = CN_Tbl_Idx;
02969 
02970 # if defined(GENERATE_WHIRL)
02971 
02972       if (!parsing_kind_selector) {
02973          new_type       = NULL_IDX;
02974 
02975          if (char_len) {     /* All char lens must be integer_4 */
02976 
02977             if (TYP_LINEAR(CN_TYPE_IDX(OPND_IDX(len_opnd))) != Integer_4) {
02978                new_type = Integer_4;
02979             }
02980          }
02981          else if (cmd_line_flags.s_pointer8 &&
02982                   TYP_LINEAR(CN_TYPE_IDX(OPND_IDX(len_opnd))) !=
02983                              SA_INTEGER_DEFAULT_TYPE) {
02984                new_type = SA_INTEGER_DEFAULT_TYPE;
02985          }
02986          else if (TYP_LINEAR(CN_TYPE_IDX(OPND_IDX(len_opnd))) <
02987                              SA_INTEGER_DEFAULT_TYPE) {
02988 
02989             /* Bump up integer*1 and integer*2 to avoid overflows KAY  */
02990 
02991             new_type    = SA_INTEGER_DEFAULT_TYPE;
02992          }
02993 
02994          if (new_type != NULL_IDX) {
02995             NTR_IR_TBL(cvrt_idx);
02996             IR_OPR(cvrt_idx)            = Cvrt_Opr;
02997             IR_TYPE_IDX(cvrt_idx)       = new_type;
02998             IR_LINE_NUM(cvrt_idx)       = line;
02999             IR_COL_NUM(cvrt_idx)        = column;
03000 
03001             COPY_OPND(IR_OPND_L(cvrt_idx), len_opnd);
03002 
03003             OPND_IDX(len_opnd)          = cvrt_idx;
03004             OPND_FLD(len_opnd)          = IR_Tbl_Idx;
03005 
03006             if (fold_it) {
03007                expr_desc.rank = 0;
03008 
03009                if (!expr_semantics(&len_opnd, &expr_desc)) {
03010                   parse_ok      = FALSE;
03011                   goto EXIT;
03012                }
03013 
03014                *len_idx         = (long) OPND_IDX(len_opnd); 
03015                *field_type      = CN_Tbl_Idx;
03016             }
03017             else {
03018 # if 0 
03019                *field_type                      = AT_Tbl_Idx;
03020                *len_idx                         = ntr_bnds_tmp_list(&len_opnd);
03021                ATD_TMP_HAS_CVRT_OPR(*len_idx)   = TRUE;
03022 # endif
03023             }
03024          }
03025          else {
03026             *len_idx    = (long) OPND_IDX(len_opnd); 
03027             *field_type = CN_Tbl_Idx;
03028          }
03029       }
03030 
03031 # endif
03032 
03033    }
03034    else {
03035 
03036 # if defined(GENERATE_WHIRL)
03037       new_type  = NULL_IDX;
03038 
03039       if (!parsing_kind_selector) { 
03040 
03041          if (char_len) {     /* All char lens must be integer_4 */
03042             new_type    = Integer_4;
03043          }
03044          else if (cmd_line_flags.s_pointer8) { 
03045             new_type    = SA_INTEGER_DEFAULT_TYPE;
03046          }
03047 
03048          if (new_type != NULL_IDX) {
03049             NTR_IR_TBL(cvrt_idx);
03050             IR_OPR(cvrt_idx)            = Cvrt_Opr;
03051             IR_TYPE_IDX(cvrt_idx)       = new_type;
03052             IR_LINE_NUM(cvrt_idx)       = line;
03053             IR_COL_NUM(cvrt_idx)        = column;
03054 
03055             COPY_OPND(IR_OPND_L(cvrt_idx), len_opnd);
03056 
03057             OPND_IDX(len_opnd)          = cvrt_idx;
03058             OPND_FLD(len_opnd)          = IR_Tbl_Idx;
03059 
03060             if (fold_it) {
03061                expr_desc.rank = 0;
03062 
03063                if (!expr_semantics(&len_opnd, &expr_desc)) {
03064                   parse_ok      = FALSE;
03065                   goto EXIT;
03066                }
03067             }
03068          }
03069       }
03070 
03071 /* # if 0 fzhao May*/
03072       *field_type       = AT_Tbl_Idx;
03073       *len_idx          = ntr_bnds_tmp_list(&len_opnd);
03074       ATD_TMP_SEMANTICS_DONE(*len_idx) = fold_it;
03075       if (new_type != NULL_IDX) {
03076          ATD_TMP_HAS_CVRT_OPR(*len_idx) = TRUE;
03077       }
03078 /* # endif  may */
03079 
03080 # else
03081       *field_type       = AT_Tbl_Idx;
03082       *len_idx          = ntr_bnds_tmp_list(&len_opnd);
03083 
03084       ATD_TMP_SEMANTICS_DONE(*len_idx) = fold_it;
03085 # endif
03086 
03087    }
03088 
03089 EXIT:
03090 
03091    expr_mode = save_expr_mode;
03092 
03093    TRACE (Func_Exit, "parse_int_spec_expr", NULL);
03094 
03095    return(parse_ok);
03096 
03097 }  /* parse_int_spec_expr */
03098 
03099 /******************************************************************************\
03100 |*                                                                            *|
03101 |* Description:                                                               *|
03102 |*      This routine takes a bounds ir stream, and searches the bounds tmp    *|
03103 |*      list for a match.  If a match is found, it returns the attr_idx of    *|
03104 |*      the matched bound.  If there is no match, a compiler temp is          *|
03105 |*      generated and added to the end of the bounds tmp list.   This assumes *|
03106 |*      that the ir pointed to by ATD_TMP_IDX is always of the form           *|
03107 |*      TMP = ir_stream, so it passes to compare_ir the right operand of      *|
03108 |*      the compiler temp.  And then if a new temp is needed, this routine    *|
03109 |*      generates the TMP =.                                                  *|
03110 |*                                                                            *|
03111 |* Input parameters:                                                          *|
03112 |*      opnd   A pointer to an operand pointing to the attribute or ir stream *|
03113 |*             that needs a temp.  This should NOT have TMP = generated yet.  *|
03114 |*                                                                            *|
03115 |* Output parameters:                                                         *|
03116 |*       NONE                                                                 *|
03117 |*                                                                            *|
03118 |* Returns:                                                                   *|
03119 |*      attr_idx  Index to attr table for this temp.                          *|
03120 |*                                                                            *|
03121 \******************************************************************************/
03122 static int ntr_bnds_tmp_list (opnd_type *opnd)
03123 
03124 {
03125    int          al_idx;
03126    int          attr_idx;
03127    int          cif_attr        = NULL_IDX;
03128    int          column;
03129    int          ir_idx;
03130    int          line;
03131    int          prev_al         = NULL_IDX;
03132 
03133 
03134    TRACE (Func_Entry, "ntr_bnds_tmp_list", NULL);
03135 
03136    al_idx       = SCP_TMP_FW_IDX(curr_scp_idx);
03137    attr_idx     = NULL_IDX;
03138 
03139    while (al_idx != NULL_IDX) {
03140       attr_idx  = AL_ATTR_IDX(al_idx);
03141 
03142       if (ATD_CLASS(attr_idx) == Constant) {
03143          
03144          /* This tmp has resolved to a constant, because it has gone   */
03145          /* thru expr_semantics already.  Remove it from the tmp list. */
03146          /* A tmp may go through expr_semantics early, if the item     */
03147          /* needs to be folded because it is referenced in a bound of  */
03148          /* a component declaration.  prev_al stays the same.          */
03149 
03150          al_idx = AL_NEXT_IDX(al_idx);
03151 
03152          if (prev_al == NULL_IDX) {
03153             SCP_TMP_FW_IDX(curr_scp_idx) = al_idx;
03154          }
03155          else {
03156             AL_NEXT_IDX(prev_al)         = al_idx;
03157          }
03158          continue;
03159       }
03160 
03161       /* Okay to pass a pointer to the operand here, because it should */
03162       /* not move.  This is only a call to compare operands.           */
03163 
03164       if (compare_opnds(opnd, &(IR_OPND_R(ATD_TMP_IDX(attr_idx)))) ) {
03165 
03166          /* If this is CIF - retain the IR, even though the tmp gets shared */
03167 
03168          if ((cif_flags & XREF_RECS) != 0) {
03169 
03170             if (cif_attr == NULL_IDX) {
03171                cif_attr = attr_idx;
03172             }
03173          }
03174          else {
03175 
03176             if (OPND_FLD((*opnd)) == IR_Tbl_Idx) { 
03177                free_ir_stream(OPND_IDX((*opnd)));
03178             }
03179             goto EXIT;
03180          }
03181       }
03182 
03183       prev_al   = al_idx;
03184       al_idx    = AL_NEXT_IDX(al_idx);
03185    }
03186 
03187    /* Each new bound has to be added at the end of the list. */
03188 
03189    NTR_ATTR_LIST_TBL(al_idx);
03190 
03191    if (prev_al == NULL_IDX) {
03192       SCP_TMP_FW_IDX(curr_scp_idx)      = al_idx;
03193    }
03194    else {
03195       AL_NEXT_IDX(prev_al)              = al_idx;
03196    }
03197    find_opnd_line_and_column(opnd, &line, &column);
03198 
03199    GEN_COMPILER_TMP_ASG(ir_idx, 
03200                         attr_idx,
03201                         FALSE,          /* Tmp should go through semantics */
03202                         line,
03203                         column,
03204                         INTEGER_DEFAULT_TYPE,
03205                         Priv);
03206 
03207    AL_ATTR_IDX(al_idx)          = attr_idx;
03208 
03209    COPY_OPND(IR_OPND_R(ir_idx), (*opnd));       /* IR_OPND_R = *opnd  */
03210 
03211    if (cif_attr != NULL_IDX) {
03212 
03213       /* This tmp is only being kept for CIF - Return the tmp to be shared. */
03214 
03215       AT_REFERENCED(attr_idx)   = Not_Referenced;
03216       attr_idx                  = cif_attr;
03217    }
03218 
03219 EXIT:
03220 
03221    TRACE (Func_Exit, "ntr_bnds_tmp_list", NULL);
03222 
03223    return (attr_idx);
03224 
03225 }  /* ntr_bnds_tmp_list */
03226 
03227 /******************************************************************************\
03228 |*                                                                            *|
03229 |* Description:                                                               *|
03230 |*      Parse a POSSIBLE generic spec.  If OPERATOR(operator) or ASSIGNMENT   *|
03231 |*        (=) is found, search for (create if necessary)  an attr entry.      *|
03232 |*        If identifier found, return attr index if found, else 0.            *|
03233 |*                                                                            *|
03234 |* Input parameters:                                                          *|
03235 |*      NONE                                                                  *|
03236 |*                                                                            *|
03237 |* Output parameters:                                                         *|
03238 |*      NONE                                                                  *|
03239 |*                                                                            *|
03240 |* Returns:                                                                   *|
03241 |*      attr index of new attribute.                                          *|
03242 |*                                                                            *|
03243 \******************************************************************************/
03244 
03245 int     generic_spec_semantics(void) 
03246 
03247 {
03248    int          attr_idx;
03249    boolean      generic_name;
03250    int          host_attr_idx;
03251    int          host_name_idx;
03252    int          name_idx;
03253    boolean      new_attr        = FALSE;
03254    int          new_attr_idx;
03255    int          scp_idx;
03256    int          type_idx;
03257 
03258 
03259    TRACE (Func_Entry, "generic_spec_semantics", NULL);
03260 
03261    generic_name = TOKEN_VALUE(token) == Tok_Id;
03262    attr_idx     = srch_sym_tbl(TOKEN_STR(token),
03263                                TOKEN_LEN(token),
03264                                &name_idx);
03265 
03266    if (stmt_type == Interface_Stmt) {
03267 
03268       if (attr_idx == NULL_IDX) {  /* Didn't find entry in local scope */
03269          host_attr_idx = srch_host_sym_tbl(TOKEN_STR(token), 
03270                                            TOKEN_LEN(token),
03271                                            &host_name_idx,
03272                                            TRUE);
03273 
03274          if (host_attr_idx == NULL_IDX ||
03275             AT_OBJ_CLASS(host_attr_idx) != Interface) {
03276 
03277             /* The only host association in this situation, is if the   */
03278             /* host is an INTERFACE.  If it is not, make a LN_DEF_LOC   */
03279             /* interface entry in the local scope.                      */
03280 
03281             attr_idx                    = ntr_sym_tbl(&token, name_idx);
03282             AT_OBJ_CLASS(attr_idx)      = Interface;
03283             LN_DEF_LOC(name_idx)        = TRUE;
03284             new_attr                    = TRUE;
03285 
03286             if (generic_name) {
03287                ATI_INTERFACE_CLASS(attr_idx) = Generic_Unknown_Interface;
03288             }
03289          }
03290          else if (AT_NOT_VISIBLE(host_attr_idx)) {
03291             PRINTMSG(TOKEN_LINE(token), 486, Error,
03292                      TOKEN_COLUMN(token),
03293                      AT_OBJ_NAME_PTR(host_attr_idx),
03294                      AT_OBJ_NAME_PTR(AT_MODULE_IDX((host_attr_idx))));
03295             attr_idx                    = ntr_sym_tbl(&token, name_idx);
03296             AT_OBJ_CLASS(attr_idx)      = Interface;
03297             LN_DEF_LOC(name_idx)        = TRUE;
03298             new_attr                    = TRUE;
03299 
03300             if (generic_name) {
03301                ATI_INTERFACE_CLASS(attr_idx) = Generic_Unknown_Interface;
03302             }
03303          }
03304          else { /* Found interface in host.  Make a new entry in the local   */
03305                 /* scp and copy the attr.  LN_DEF_LOC gets set in local scp. */
03306 
03307             if (AT_IS_INTRIN(host_attr_idx) &&
03308                 ATI_FIRST_SPECIFIC_IDX(host_attr_idx) == NULL_IDX) {
03309                complete_intrinsic_definition(host_attr_idx);
03310                attr_idx = srch_sym_tbl(TOKEN_STR(token), 
03311                                        TOKEN_LEN(token), 
03312                                        &name_idx);
03313             }
03314 
03315             attr_idx = ntr_host_in_sym_tbl(&token, 
03316                                            name_idx,
03317                                            host_attr_idx,
03318                                            host_name_idx,
03319                                            TRUE);
03320 
03321             type_idx = (AT_TYPED(host_attr_idx)) ? ATD_TYPE_IDX(host_attr_idx) :
03322                                                    NULL_IDX;
03323 
03324             COPY_VARIANT_ATTR_INFO(host_attr_idx, attr_idx, Interface);
03325 
03326             LN_DEF_LOC(name_idx)          = TRUE;
03327             AT_ATTR_LINK(attr_idx)        = NULL_IDX;
03328             AT_IS_INTRIN(attr_idx)        = AT_IS_INTRIN(host_attr_idx);
03329             AT_ELEMENTAL_INTRIN(attr_idx) = AT_ELEMENTAL_INTRIN(host_attr_idx);
03330             ATD_TYPE_IDX(attr_idx)        = type_idx;
03331             AT_DEF_LINE(attr_idx)         = TOKEN_LINE(token);
03332             AT_DEF_COLUMN(attr_idx)       = TOKEN_COLUMN(token);
03333          }
03334       }
03335       else if ((!AT_USE_ASSOCIATED(attr_idx) ||
03336                  AT_OBJ_CLASS(attr_idx) != Pgm_Unit ||
03337                  ATP_PROC(attr_idx) != Module_Proc) &&
03338                fnd_semantic_err(Obj_Generic_Interface,
03339                                 TOKEN_LINE(token),
03340                                 TOKEN_COLUMN(token),
03341                                 attr_idx,
03342                                 TRUE)) {
03343          CREATE_ERR_ATTR(attr_idx, TOKEN_LINE(token),
03344                                    TOKEN_COLUMN(token), Interface);
03345          AT_OBJ_CLASS(attr_idx) = Interface;
03346       }
03347       else if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit) {
03348 
03349          /* Must be a function or subroutine */
03350 
03351          NTR_ATTR_TBL(new_attr_idx);
03352          COPY_COMMON_ATTR_INFO(attr_idx, new_attr_idx, Interface);
03353          AT_DEF_LINE(new_attr_idx)      = TOKEN_LINE(token);
03354          AT_DEF_COLUMN(new_attr_idx)    = TOKEN_COLUMN(token);
03355          ATI_PROC_IDX(new_attr_idx)     = attr_idx;
03356          LN_ATTR_IDX(name_idx)          = new_attr_idx;
03357          LN_NAME_IDX(name_idx)          = AT_NAME_IDX(new_attr_idx);
03358 
03359          if (ATP_RSLT_IDX(attr_idx) != NULL_IDX && 
03360              AT_TYPED(ATP_RSLT_IDX(attr_idx))) {
03361             ATD_TYPE_IDX(new_attr_idx) = ATD_TYPE_IDX(ATP_RSLT_IDX(attr_idx));
03362          }
03363 
03364          attr_idx                       = new_attr_idx;
03365 
03366          if (generic_name) {
03367             ATI_INTERFACE_CLASS(attr_idx) = Generic_Unknown_Interface;
03368          }
03369       }
03370       else if (AT_OBJ_CLASS(attr_idx) != Interface) {
03371          scp_idx                = curr_scp_idx;
03372          curr_scp_idx           = INTRINSIC_SCP_IDX;
03373          host_attr_idx          = srch_sym_tbl(TOKEN_STR(token), 
03374                                                TOKEN_LEN(token),
03375                                                &host_name_idx);
03376          curr_scp_idx           = scp_idx;
03377 
03378          if (host_attr_idx == NULL_IDX) {
03379             CLEAR_VARIANT_ATTR_INFO(attr_idx, Interface);
03380             type_idx            = NULL_IDX;
03381          }
03382          else {  /* It is an intrinsic */
03383             complete_intrinsic_definition(host_attr_idx);
03384             COPY_VARIANT_ATTR_INFO(host_attr_idx, attr_idx, Interface);
03385             AT_ATTR_LINK(attr_idx)        = NULL_IDX;
03386             AT_IS_INTRIN(attr_idx)        = AT_IS_INTRIN(host_attr_idx);
03387             AT_ELEMENTAL_INTRIN(attr_idx) = AT_ELEMENTAL_INTRIN(host_attr_idx);
03388             type_idx                      = ATD_TYPE_IDX(host_attr_idx);
03389          }
03390 
03391          ATD_TYPE_IDX(attr_idx)           = type_idx;
03392          AT_DEF_LINE(attr_idx)            = TOKEN_LINE(token);
03393          AT_DEF_COLUMN(attr_idx)          = TOKEN_COLUMN(token);
03394       }
03395    }
03396    else if (CURR_BLK == Module_Blk) {           /* Public/Private statement */
03397 
03398       if (attr_idx == NULL_IDX) {
03399          attr_idx               = ntr_sym_tbl(&token, name_idx);
03400          LN_DEF_LOC(name_idx)   = TRUE;
03401          new_attr               = TRUE;
03402 
03403          if (generic_name) {
03404             SET_IMPL_TYPE(attr_idx);
03405          }
03406          else {
03407             AT_OBJ_CLASS(attr_idx)      = Interface;
03408          }
03409       }  /* NOT_VISIBLE and other semantics are done by the caller */
03410    }
03411    else if (attr_idx == NULL_IDX) {
03412       attr_idx                  = ntr_sym_tbl(&token, name_idx);
03413       LN_DEF_LOC(name_idx)      = TRUE;
03414       new_attr                  = TRUE;
03415 
03416       if (generic_name) {
03417          SET_IMPL_TYPE(attr_idx);
03418       }
03419       else {
03420          AT_OBJ_CLASS(attr_idx) = Interface;
03421       }
03422    }
03423    else if (AT_REFERENCED(attr_idx) == Char_Rslt_Bound_Ref) {
03424       AT_ATTR_LINK(attr_idx)   = NULL_IDX;
03425       LN_DEF_LOC(name_idx)     = TRUE;
03426    }
03427 
03428 
03429    /* CIF processing uses ATI_USER_SPECIFIED and AT_IS_INTRINSIC to determine */
03430    /* that an intrinsic procedure name is being overloaded.  Must check that  */
03431    /* the current statement is an interface block statement because this      */
03432    /* routine is also called to parse the generic name in a PUBLIC/PRIVATE    */
03433    /* statement.                                                              */
03434 
03435    if (stmt_type == Interface_Stmt  && 
03436        AT_OBJ_CLASS(attr_idx) == Interface  &&  generic_name) {
03437       ATI_USER_SPECIFIED(attr_idx) = TRUE;
03438    }
03439 
03440 
03441    if (new_attr && !generic_name) {
03442 
03443       switch (TOKEN_VALUE(token)) {
03444       case Tok_Op_Add :
03445          ATI_DEFINED_OPR(attr_idx)     = Plus_Opr;
03446          ATI_INTERFACE_CLASS(attr_idx) = Defined_Unary_Or_Binary_Interface;
03447          break;
03448 
03449       case Tok_Op_Div :
03450          ATI_DEFINED_OPR(attr_idx)     = Div_Opr;
03451          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03452          break;
03453 
03454       case Tok_Op_Mult :
03455          ATI_DEFINED_OPR(attr_idx)     = Mult_Opr;
03456          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03457          break;
03458 
03459       case Tok_Op_Power :
03460          ATI_DEFINED_OPR(attr_idx)     = Power_Opr;
03461          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03462          break;
03463 
03464       case Tok_Op_Sub :
03465          ATI_DEFINED_OPR(attr_idx)     = Minus_Opr;
03466          ATI_INTERFACE_CLASS(attr_idx) = Defined_Unary_Or_Binary_Interface;
03467          break;
03468 
03469       case Tok_Op_Concat :
03470          ATI_DEFINED_OPR(attr_idx)     = Concat_Opr;
03471          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03472          break;
03473 
03474       case Tok_Op_Eq :
03475          ATI_DEFINED_OPR(attr_idx)     = Eq_Opr;
03476          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03477          break;
03478 
03479       case Tok_Op_Ge :
03480          ATI_DEFINED_OPR(attr_idx)     = Ge_Opr;
03481          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03482          break;
03483 
03484       case Tok_Op_Gt :
03485          ATI_DEFINED_OPR(attr_idx)     = Gt_Opr;
03486          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03487          break;
03488 
03489       case Tok_Op_Le :
03490          ATI_DEFINED_OPR(attr_idx)     = Le_Opr;
03491          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03492          break;
03493 
03494       case Tok_Op_Lt :
03495          ATI_DEFINED_OPR(attr_idx)     = Lt_Opr;
03496          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03497          break;
03498 
03499       case Tok_Op_Ne :
03500          ATI_DEFINED_OPR(attr_idx)     = Ne_Opr;
03501          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03502          break;
03503 
03504       case Tok_Op_Lg :
03505          ATI_DEFINED_OPR(attr_idx)     = Lg_Opr;
03506          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03507          break;
03508 
03509       case Tok_Op_And :
03510          ATI_DEFINED_OPR(attr_idx)     = And_Opr;
03511          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03512          break;
03513 
03514       case Tok_Op_Eqv :
03515          ATI_DEFINED_OPR(attr_idx)     = Eqv_Opr;
03516          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03517          break;
03518 
03519       case Tok_Op_Neqv :
03520          ATI_DEFINED_OPR(attr_idx)     = Neqv_Opr;
03521          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03522          break;
03523 
03524       case Tok_Op_Not :
03525          ATI_DEFINED_OPR(attr_idx)     = Not_Opr;
03526          ATI_INTERFACE_CLASS(attr_idx) = Defined_Unary_Interface;
03527          break;
03528 
03529       case Tok_Op_Or :
03530          ATI_DEFINED_OPR(attr_idx)     = Or_Opr;
03531          ATI_INTERFACE_CLASS(attr_idx) = Defined_Binary_Interface;
03532          break;
03533 
03534       case Tok_Op_Assign :
03535          ATI_DEFINED_OPR(attr_idx)     = Asg_Opr;
03536          ATI_INTERFACE_CLASS(attr_idx) = Defined_Assign_Interface;
03537          break;
03538 
03539       case Tok_Op_Defined :
03540          ATI_DEFINED_OPR(attr_idx)     = Null_Opr;
03541          ATI_INTERFACE_CLASS(attr_idx) = Defined_Unary_Or_Binary_Interface;
03542          break;
03543       }
03544    }
03545 
03546    if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
03547       ATD_SEEN_OUTSIDE_IMP_DO(attr_idx) = TRUE;
03548    }
03549 
03550    if ((cif_flags & XREF_RECS) != 0) {
03551       cif_usage_rec(attr_idx, 
03552                     AT_Tbl_Idx,
03553                     TOKEN_LINE(token),
03554                     TOKEN_COLUMN(token),
03555                     CIF_Symbol_Declaration);
03556    }
03557 
03558    TRACE (Func_Exit, "generic_spec_semantics", NULL);
03559 
03560    return(attr_idx);
03561 
03562 }  /* generic_spec_semantics */
03563 
03564 /******************************************************************************\
03565 |*                                                                            *|
03566 |* Description:                                                               *|
03567 |*      Check to see if attr was used to declare its own bounds.   An object  *|
03568 |*      cannot be dimensioned after it is referenced, so an error situation   *|
03569 |*      definitely exists.  This is a bit of compile time to check, but we    *|
03570 |*      are in an error situation anyway.  This searches the bounds looking   *|
03571 |*      for a reference to the attr in the bounds for the array.              *|
03572 |*                                                                            *|
03573 |* Input parameters:                                                          *|
03574 |*      attr index to look for                                                *|
03575 |*      bd index of dimension to searh                                        *|
03576 |*                                                                            *|
03577 |* Output parameters:                                                         *|
03578 |*      NONE                                                                  *|
03579 |*                                                                            *|
03580 |* Returns:                                                                   *|
03581 |*      TRUE if an error is issued.                                           *|
03582 |*                                                                            *|
03583 \******************************************************************************/
03584 
03585 static boolean  is_attr_referenced_in_bound(int         bd_idx,
03586                                             int         attr_idx) 
03587 
03588 {
03589    boolean      error           = FALSE;
03590    opnd_type    opnd;
03591    int          rank;
03592 
03593 
03594    TRACE (Func_Entry, "is_attr_referenced_in_bound", NULL);
03595 
03596    if (BD_ARRAY_CLASS(bd_idx) != Deferred_Shape) {
03597 
03598       for (rank = BD_RANK(bd_idx); rank >0; rank--) {
03599 
03600          if (BD_LB_FLD(bd_idx, rank) == AT_Tbl_Idx &&
03601              ATD_FLD(BD_LB_IDX(bd_idx, rank)) == IR_Tbl_Idx &&
03602              find_attr_in_ir(attr_idx, 
03603                              ATD_TMP_IDX(BD_LB_IDX(bd_idx, rank)),
03604                              &opnd)) {
03605             AT_DCL_ERR(attr_idx)        = TRUE;
03606             BD_DCL_ERR(bd_idx)          = TRUE;
03607             error                       = TRUE;
03608             PRINTMSG(OPND_LINE_NUM(opnd), 1036, Error,
03609                      OPND_COL_NUM(opnd),
03610                      AT_OBJ_NAME_PTR(attr_idx));
03611             break;
03612          }
03613 
03614          if (BD_UB_FLD(bd_idx, rank) == AT_Tbl_Idx &&
03615              ATD_FLD(BD_UB_IDX(bd_idx, rank)) == IR_Tbl_Idx &&
03616              find_attr_in_ir(attr_idx, 
03617                              ATD_TMP_IDX(BD_UB_IDX(bd_idx, rank)),
03618                              &opnd)) {
03619             AT_DCL_ERR(attr_idx)        = TRUE;
03620             BD_DCL_ERR(bd_idx)          = TRUE;
03621             error                       = TRUE;
03622             PRINTMSG(OPND_LINE_NUM(opnd), 1036, Error,
03623                      OPND_COL_NUM(opnd),
03624                      AT_OBJ_NAME_PTR(attr_idx));
03625             break;
03626          }
03627       }
03628    }
03629 
03630    TRACE (Func_Exit, "is_attr_referenced_in_bound", NULL);
03631 
03632    return(error);
03633 
03634 }  /* is_attr_referenced_in_bound */
03635 
03636 /******************************************************************************\
03637 |*                                                                            *|
03638 |* Description:                                                               *|
03639 |*      Parses the pe array_spec for declarations (F--)                       *|
03640 |*             array_spec is explicit-shape-spec-list                         *|
03641 |*                            is [lower-bound :]upper-bound                   *|
03642 |*                               [specification-expr :] specification-expr    *|
03643 |*                       is assumed-size-spec                                 *|
03644 |*                          is [explicit-shape-spec-list,] [lower-bound:]*    *|
03645 |*                                                                            *|
03646 |*       Position  - entry - token is open brkt                               *|
03647 |*                   exit  - token is verified close brkt                     *|
03648 |*                           if close brkt is missing.  LA_CH is set to       *|
03649 |*                           colon-colon, or EOS                              *|
03650 |*                                                                            *|
03651 |* Returns:                                                                   *|
03652 |*      NONE                                                                  *|
03653 |*                                                                            *|
03654 \******************************************************************************/
03655 int     parse_pe_array_spec(int    attr_idx)
03656 
03657 {
03658    int                  bd_idx;
03659    int                  column;
03660    boolean              fold_it;
03661    boolean              found_end               = FALSE;
03662    boolean              found_error             = FALSE;
03663    fld_type             lb_fld;
03664    long                 lb_len_idx;
03665    int                  line;
03666    boolean              lower_bound_found;
03667    boolean              non_constant_size       = FALSE;
03668    int                  rank                    = 1;
03669    reference_type       referenced;
03670    fld_type             ub_fld;
03671    long                 ub_len_idx;
03672 
03673 
03674    TRACE (Func_Entry, "parse_pe_array_spec", NULL);
03675 
03676 # ifdef _DEBUG
03677    if (LA_CH_VALUE != LBRKT) {
03678       PRINTMSG(LA_CH_LINE, 295, Internal, LA_CH_COLUMN,
03679                "parse_pe_array_spec", "LBRKT");
03680    }
03681 # endif
03682 
03683    NEXT_LA_CH;                                               /* Skip Lbrkt   */
03684    bd_idx                       = reserve_array_ntry(7);
03685    referenced                   = (reference_type) AT_REFERENCED(attr_idx);
03686    AT_REFERENCED(attr_idx)      = Not_Referenced;
03687    BD_LINE_NUM(bd_idx)          = LA_CH_LINE;
03688    BD_COLUMN_NUM(bd_idx)        = LA_CH_COLUMN;
03689 
03690    /* If LA_CH is RBRKT, there is no dimension, so default to a rank 1       */
03691    /* constant sized array of length 1 and return.                            */
03692 
03693    if (LA_CH_VALUE == RBRKT) {
03694       parse_err_flush(Find_None, "dimension-spec");
03695       BD_ARRAY_CLASS(bd_idx)    = Explicit_Shape;
03696       BD_ARRAY_SIZE(bd_idx)     = Constant_Size;
03697       BD_DCL_ERR(bd_idx)        = TRUE;
03698       BD_RANK(bd_idx)           = 1;
03699       BD_LB_FLD(bd_idx, 1)      = CN_Tbl_Idx;
03700       BD_LB_IDX(bd_idx, 1)      = CN_INTEGER_ONE_IDX;
03701       BD_UB_FLD(bd_idx, 1)      = CN_Tbl_Idx;
03702       BD_UB_IDX(bd_idx, 1)      = CN_INTEGER_ONE_IDX;
03703       NEXT_LA_CH;
03704       goto EXIT;
03705    }
03706 
03707    /* Set fold_it flag.  Will continue on and do pass2 style semantic     */
03708    /* checking and constant folding, if this is a component declaration.  */
03709 
03710    fold_it = (CURR_BLK == Derived_Type_Blk);
03711 
03712    do {  /* Process each dimension of the array */
03713       lower_bound_found         = FALSE;
03714       lb_len_idx                = CN_INTEGER_ONE_IDX;
03715       lb_fld                    = CN_Tbl_Idx;
03716       ub_len_idx                = NULL_IDX;
03717       ub_fld                    = NO_Tbl_Idx;
03718 
03719       if (LA_CH_VALUE != COLON && LA_CH_VALUE != STAR) {
03720          line           = LA_CH_LINE;
03721          column         = LA_CH_COLUMN;
03722 
03723          /* If LA_CH isn't a COLON or a STAR, then this must be an expression.*/
03724          /* Get the expression and determine if it is a lower or upper bound. */
03725          /* If there is a parse error, a constant one is returned.            */
03726 
03727          if (!parse_int_spec_expr(&ub_len_idx, &ub_fld, fold_it, FALSE)) {
03728             ub_len_idx          = CN_INTEGER_ONE_IDX;
03729             ub_fld              = CN_Tbl_Idx;
03730             BD_DCL_ERR(bd_idx)  = TRUE;
03731          }
03732 
03733          if (ub_fld != CN_Tbl_Idx) {
03734             non_constant_size   = TRUE;
03735          }
03736 
03737          if (LA_CH_VALUE == COLON) {                   /* This is lower bound */
03738             lower_bound_found           = TRUE;
03739             lb_len_idx                  = ub_len_idx;
03740             lb_fld                      = ub_fld;
03741             ub_len_idx                  = NULL_IDX;
03742             ub_fld                      = NO_Tbl_Idx;
03743          }
03744          else {
03745             BD_ARRAY_CLASS(bd_idx)      = Explicit_Shape;
03746          }
03747       }
03748 
03749       /* Now the parser is in one of 3 states. (1) Lower bound found, upper   */
03750       /* bound = NULL, LA_CH must be COLON. (2) Lower bound not found, so it  */
03751       /* is set to a default of 1, upper bound is found and LA_CH is COMMA or */
03752       /* RBRKT.   (LA_CH must be COLON.) (3) Neither lower bound or upper    */
03753       /* bound have been seen, they are set to defaults of lb=1, ub=NULL.     */
03754       /* LA_CH is COLON or STAR.  If the LA_CH is COLON, this is either a     */
03755       /* Deferred-Shape spec or it is followed by the upper bound for an      */
03756       /* Explicit-Shape spec.  NOTE: LA_CH may be EOS - this is parse error.  */
03757 
03758       if (LA_CH_VALUE == COLON) {
03759          line           = LA_CH_LINE;
03760          column         = LA_CH_COLUMN;
03761          NEXT_LA_CH;                            /* Skip COLON */
03762 
03763          if (LA_CH_VALUE == COMMA || LA_CH_VALUE == RBRKT) {
03764 
03765             /* Have one of two cases  1)  ARRAY(1:)  - This is an assumed     */
03766             /* shape spec which is classed as a Deferred-Shape, or 2) ARRAY(:)*/
03767             /* which is a deferred-Shape spec.   Issue an error if this array */
03768             /* has already been classified as an Explicit_Shape array.        */
03769 
03770             if (BD_ARRAY_CLASS(bd_idx) == Explicit_Shape) {
03771                PRINTMSG(line, 115, Error, column);
03772                BD_DCL_ERR(bd_idx)       = TRUE;
03773             }
03774             else {  /* Must be Deferred-Shape spec */
03775                BD_ARRAY_CLASS(bd_idx)   = Deferred_Shape;
03776             }
03777          }
03778          else {
03779 
03780             /* Have one of two cases  1)  ARRAY (1:10) - legal - pick up upper*/
03781             /* bound expression.  Err if array is already set to Deferred-    */
03782             /* Shape spec.  2) ARRAY (:10) - illegal - issue error.           */
03783             /* If the upper bound is a STAR, pick it up in the next section.  */
03784 
03785             if (!lower_bound_found) {                   /* A(:10) - illegal   */
03786                PRINTMSG(LA_CH_LINE, 119, Error, LA_CH_COLUMN, &LA_CH_VALUE);
03787                BD_DCL_ERR(bd_idx)       = TRUE;
03788             }
03789 
03790             if (LA_CH_VALUE != STAR) {
03791                line     = LA_CH_LINE;
03792                column   = LA_CH_COLUMN;
03793 
03794                if (!parse_int_spec_expr(&ub_len_idx, &ub_fld, fold_it, FALSE)) {
03795 
03796                   /* Expression parser recovers LA_CH to : ) , or EOS */
03797 
03798                   BD_DCL_ERR(bd_idx)    = TRUE;
03799                   ub_len_idx            = CN_INTEGER_ONE_IDX;
03800                   ub_fld                = CN_Tbl_Idx;
03801                }
03802 
03803                if (ub_fld != CN_Tbl_Idx) {
03804                   non_constant_size     = TRUE;
03805                }
03806 
03807                BD_ARRAY_CLASS(bd_idx)= Explicit_Shape;
03808             }
03809          }
03810       }
03811 
03812       /* The parser may be:  1)  ARRAY(*) - lb=1, ub=NULL_IDX.  2) ARR(10:*)  */
03813       /* lb is set, and ub=NULL_IDX.  3)  ARRAY(:*) - illegal -error already  */
03814       /* issued.  You could not have picked up a lower bound and/or an upper  */
03815       /* bound and got to this position, because a * is part of an expression.*/
03816       /* The expression parser stops at COLON, COMMA, RBRKT or EOS.          */
03817 
03818       if (LA_CH_VALUE == STAR) {
03819          line   = LA_CH_LINE;
03820          column = LA_CH_COLUMN;
03821          NEXT_LA_CH;                            /* Skip STAR */
03822 
03823          BD_ARRAY_CLASS(bd_idx)      = Assumed_Size;
03824          ub_len_idx                  = lb_len_idx;
03825          ub_fld                      = lb_fld;
03826 
03827          if (LA_CH_VALUE != RBRKT) {
03828 
03829             /* The assumed-size specifier * must be in the last dimension. */
03830 
03831             BD_DCL_ERR(bd_idx)       = TRUE;
03832             PRINTMSG(line, 116, Error, column);
03833             parse_err_flush(Find_Rparen, NULL);
03834          }
03835       }
03836 
03837       BD_LB_IDX(bd_idx, rank)   = lb_len_idx;
03838       BD_LB_FLD(bd_idx, rank)   = lb_fld;
03839       BD_UB_IDX(bd_idx, rank)   = ub_len_idx;
03840       BD_UB_FLD(bd_idx, rank)   = ub_fld;
03841 
03842       if (LA_CH_VALUE == COMMA) {
03843 
03844          if (rank++ == 7) {          /* issue error - too many ranks */
03845             found_end           = TRUE;
03846             BD_DCL_ERR(bd_idx)  = TRUE;
03847             PRINTMSG(LA_CH_LINE, 117, Error, LA_CH_COLUMN);
03848             parse_err_flush(Find_Rparen, NULL);
03849          }
03850          else {
03851             NEXT_LA_CH;
03852          }
03853       }
03854       else {
03855          found_end = TRUE;
03856       }
03857 
03858       found_error = BD_DCL_ERR(bd_idx) | found_error;
03859    }
03860    while (!found_end);
03861 
03862    if (LA_CH_VALUE == RBRKT ||
03863        parse_err_flush(Find_EOS, (found_error) ? NULL : ", or )")) {
03864 
03865       NEXT_LA_CH;               /* Skip RBRKT */
03866    }
03867 
03868    if (!non_constant_size) {
03869       BD_ARRAY_SIZE(bd_idx) = Constant_Size;
03870    }
03871 
03872    BD_RANK(bd_idx) = rank;
03873 
03874 # ifdef _DEBUG
03875    if (BD_ARRAY_CLASS(bd_idx) == Unknown_Array) {
03876 
03877       /* There is a parsing problem here.  This must never be Unknown_Array */
03878 
03879       PRINTMSG(LA_CH_LINE, 178, Internal, LA_CH_COLUMN);
03880    }
03881 # endif
03882 
03883 EXIT:
03884 
03885    if (AT_REFERENCED(attr_idx) > Not_Referenced) {
03886       is_attr_referenced_in_bound(bd_idx, attr_idx);
03887    }
03888 
03889    if (AT_REFERENCED(attr_idx) < referenced) {
03890       AT_REFERENCED(attr_idx)   = referenced;
03891    }
03892 
03893    bd_idx = ntr_array_in_bd_tbl(bd_idx);
03894 
03895    TRACE (Func_Exit, "parse_pe_array_spec", NULL);
03896 
03897    return(bd_idx);
03898 
03899 }  /* parse_pe_array_spec */
03900 
03901 /******************************************************************************\
03902 |*                                                                            *|
03903 |* Description:                                                               *|
03904 |*      Add the co-array attribute to the attr.                               *|
03905 |*                                                                            *|
03906 |* Input parameters:                                                          *|
03907 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
03908 |*                       is FALSE, just add the attribute to the Attr.        *|
03909 |*      line          -> The line number of the object.                       *|
03910 |*      column        -> The column number of the object.                     *|
03911 |*      attr_idx      -> Attr index to add the co-array attribute to.         *|
03912 |*      pe_array_idx  -> bounds table index describing the co-array.          *|
03913 |*                                                                            *|
03914 |* Output parameters:                                                         *|
03915 |*      NONE                                                                  *|
03916 |*                                                                            *|
03917 |* Returns:                                                                   *|
03918 |*      TRUE if successful merge.                                             *|
03919 |*                                                                            *|
03920 \******************************************************************************/
03921 
03922 boolean merge_co_array(boolean  chk_semantics,
03923                    int          line,
03924                    int          column,
03925                    int          attr_idx,
03926                    int          pe_array_idx)
03927 {
03928    boolean      fnd_err;
03929 
03930 
03931    TRACE (Func_Entry, "merge_co_array", NULL);
03932    
03933    if (!chk_semantics || !fnd_semantic_err(Obj_Co_Array,
03934                                            line,
03935                                            column,
03936                                            attr_idx,
03937                                            TRUE)) {
03938       ATD_PE_ARRAY_IDX(attr_idx) = pe_array_idx;
03939       fnd_err   = FALSE;
03940    }
03941    else {
03942       fnd_err   = TRUE;
03943    }
03944 
03945    TRACE (Func_Exit, "merge_co_array", NULL);
03946 
03947    return(!fnd_err);
03948 
03949 }  /* merge_co_array */
03950 
03951 /******************************************************************************\
03952 |*                                                                            *|
03953 |* Description:                                                               *|
03954 |*      Add the SAVE attribute to an attr.                                    *|
03955 |*                                                                            *|
03956 |* Input parameters:                                                          *|
03957 |*      chk_semantics -> TRUE if semantic checking needs to be done.  If this *|
03958 |*                       is FALSE, just add the attribute to the attr.        *|
03959 |*      line     -> The line number of the object to add the attribute to     *|
03960 |*      column   -> The line number of the object to add the attribute to     *|
03961 |*      attr_idx -> Attr index to add the EXTERNAL attribute to.              *|
03962 |*                                                                            *|
03963 |* Output parameters:                                                         *|
03964 |*      NONE                                                                  *|
03965 |*                                                                            *|
03966 |* Returns:                                                                   *|
03967 |*      TRUE if successful merge.                                             *|
03968 |*                                                                            *|
03969 \******************************************************************************/
03970 
03971 boolean merge_volatile(boolean  chk_semantics,
03972                        int              line,
03973                        int              column,
03974                        int              attr_idx)
03975 
03976 {
03977    boolean      fnd_err         = FALSE;
03978 
03979 
03980    TRACE (Func_Entry, "merge_volatile", NULL);
03981 
03982    if (chk_semantics) {
03983       fnd_err = fnd_semantic_err(Obj_Volatile, line, column, attr_idx, TRUE);
03984 
03985       if (!fnd_err && ATD_VOLATILE(attr_idx)) {
03986          PRINTMSG(line, 1259, Ansi, column, AT_OBJ_NAME_PTR(attr_idx), 
03987                   "VOLATILE");
03988       }
03989    }
03990    else {
03991       SET_IMPL_TYPE(attr_idx);
03992    }
03993 
03994    if (!fnd_err) {
03995       ATD_VOLATILE(attr_idx)    = TRUE;
03996    }
03997 
03998    TRACE (Func_Exit, "merge_volatile", NULL);
03999 
04000    return(!fnd_err);
04001 
04002 }  /* merge_volatile */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines