Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 20-Aug-96: Original Version, nenad 00042 * 00043 * Description: Implementation of demangling utility functions 00044 * needed in emitting user-understandable error 00045 * messages by the (dsm_)prelinker, linker, and 00046 * run-time error checking code generated by LNO. 00047 * 00048 * ==================================================================== 00049 * ==================================================================== 00050 */ 00051 00052 #include <stdio.h> 00053 #include <stdlib.h> 00054 #include <string.h> 00055 00056 #include "dra_demangle.h" 00057 00058 00059 /* 00060 * Constants used in (de)mangling 00061 * 00062 * NOTE: These #define's have their 'static const' counterparts 00063 * in be/be/dra_internal.h 00064 * Any change in this file should also be reflected there. 00065 */ 00066 00067 #define DRA_MANGLE_SIG "__nn__" 00068 #define DRA_MANGLE_SIG_LEN 6 00069 00070 #define DRA_STAR_CODE 'S' 00071 #define DRA_BLOCK_CODE 'B' 00072 #define DRA_CYCLIC_CODE 'C' 00073 #define DRA_NDIMS_END 'D' 00074 #define DRA_ESIZE_END 'E' 00075 #define DRA_ARG_SEPARATOR '_' 00076 00077 #define DRA_STAR_STRING "*" 00078 #define DRA_BLOCK_STRING "BLOCK" 00079 #define DRA_CYCLIC_STRING "CYCLIC" 00080 00081 #define DRA_DEM_BUFSIZE 4096 00082 00083 static char dem_buf[DRA_DEM_BUFSIZE]; 00084 00085 00086 00087 /* 00088 * Extract only the function name 00089 */ 00090 00091 char* 00092 DRA_Demangle_Func(const char *mangled_name) 00093 { 00094 char *func_name; 00095 char *postfix_sig; 00096 int func_name_len; 00097 00098 /* Check for prefix signature */ 00099 if (mangled_name == NULL || 00100 strncmp(mangled_name, DRA_MANGLE_SIG, DRA_MANGLE_SIG_LEN) != 0) 00101 return NULL; 00102 00103 func_name = (char*) mangled_name + DRA_MANGLE_SIG_LEN; 00104 00105 /* Check for postfix signature */ 00106 postfix_sig = strstr(func_name, DRA_MANGLE_SIG); 00107 00108 if (postfix_sig == NULL || 00109 postfix_sig[DRA_MANGLE_SIG_LEN] == 0) 00110 return NULL; 00111 00112 /* Check that the name is not too long */ 00113 func_name_len = postfix_sig - func_name; 00114 if (func_name_len >= DRA_DEM_BUFSIZE) 00115 return NULL; 00116 00117 /* Copy original function name into static buffer */ 00118 (void) strncpy(dem_buf, func_name, func_name_len); 00119 dem_buf[func_name_len] = 0; 00120 00121 return dem_buf; 00122 } 00123 00124 00125 00126 /* 00127 * Extract and demangle the argument list 00128 */ 00129 00130 char* 00131 DRA_Demangle_Arglist(const char *mangled_name, 00132 const char dim_order) 00133 { 00134 char *func_name; 00135 char *postfix_sig; 00136 char *arg_list; 00137 char *arg_begin; 00138 char *arg_end; 00139 char *arg_dim; 00140 char *arg_distr; 00141 char *buf; 00142 00143 int arg_pos; 00144 int num_dims; 00145 int dim; 00146 int chunk; 00147 00148 /* Dimension ordering must be either 'F' or 'C' */ 00149 if (dim_order != DRA_DIMS_COLUMNWISE && dim_order != DRA_DIMS_ROWWISE) 00150 return NULL; 00151 00152 /* Check for prefix signature */ 00153 if (mangled_name == NULL || 00154 strncmp(mangled_name, DRA_MANGLE_SIG, DRA_MANGLE_SIG_LEN) != 0) 00155 return NULL; 00156 00157 func_name = (char*) mangled_name + DRA_MANGLE_SIG_LEN; 00158 00159 /* Check for postfix signature */ 00160 postfix_sig = strstr(func_name, DRA_MANGLE_SIG); 00161 if (postfix_sig == NULL) 00162 return NULL; 00163 00164 /* Check that argument list is not empty */ 00165 arg_list = postfix_sig + DRA_MANGLE_SIG_LEN; 00166 if (arg_list[0] == 0 || arg_list[1] == 0) 00167 return NULL; 00168 00169 buf = dem_buf; 00170 *buf++ = '('; 00171 00172 00173 for (arg_pos = 0, arg_begin = arg_list; *arg_begin != 0; arg_pos++) { 00174 00175 /* Underscore must follow each argument */ 00176 arg_end = strchr(arg_begin, DRA_ARG_SEPARATOR); 00177 if (arg_end == NULL || arg_end == arg_begin) 00178 return NULL; 00179 00180 /* Insert comma before each argument, except for the first one */ 00181 if (arg_pos > 0) 00182 *buf++ = ','; 00183 00184 /* Extract the number of dimensions */ 00185 num_dims = (int) strtol(arg_begin, &arg_begin, 10); 00186 00187 if (num_dims > 0) { 00188 00189 /* 'D' must follow the number of dimensions */ 00190 if (*arg_begin++ != DRA_NDIMS_END) 00191 return NULL; 00192 00193 *buf++ = '('; 00194 00195 /* Skip element size */ 00196 (void) strtol(arg_begin, &arg_begin, 10); 00197 00198 /* 'E' must follow the element size */ 00199 if (*arg_begin++ != DRA_ESIZE_END) 00200 return NULL; 00201 00202 /* For columnwise case (Fortran) decode dimensions in reverse order */ 00203 if (dim_order == DRA_DIMS_COLUMNWISE) 00204 arg_dim = arg_end; 00205 else 00206 arg_dim = arg_begin; 00207 00208 /* Go through all dimensions of the reshaped argument */ 00209 for (dim = 0; dim < num_dims; dim++) { 00210 00211 if (dim_order == DRA_DIMS_COLUMNWISE) { 00212 do { 00213 arg_dim--; 00214 } while (*arg_dim != DRA_STAR_CODE && 00215 *arg_dim != DRA_BLOCK_CODE && 00216 *arg_dim != DRA_CYCLIC_CODE && 00217 *arg_dim != DRA_ESIZE_END); 00218 } 00219 00220 arg_distr = arg_dim; 00221 00222 switch(*arg_distr++) { 00223 00224 case DRA_STAR_CODE: 00225 if (buf-dem_buf+strlen(DRA_STAR_STRING)+2 >= DRA_DEM_BUFSIZE) 00226 return NULL; 00227 buf += sprintf(buf, DRA_STAR_STRING); 00228 break; 00229 00230 case DRA_BLOCK_CODE: 00231 if (buf-dem_buf+strlen(DRA_BLOCK_STRING)+2 >= DRA_DEM_BUFSIZE) 00232 return NULL; 00233 buf += sprintf(buf, DRA_BLOCK_STRING); 00234 break; 00235 00236 case DRA_CYCLIC_CODE: 00237 if (buf-dem_buf+strlen(DRA_CYCLIC_STRING)+25 >= DRA_DEM_BUFSIZE) 00238 return NULL; 00239 buf += sprintf(buf, DRA_CYCLIC_STRING); 00240 chunk = (int) strtol(arg_distr, &arg_distr, 10); 00241 if (chunk != 0) 00242 buf += sprintf(buf, "(%d)", chunk); 00243 else 00244 buf += sprintf(buf, "(sym)"); 00245 break; 00246 00247 default: 00248 return NULL; 00249 } 00250 00251 if (dim == num_dims-1) { 00252 if (dim_order == DRA_DIMS_ROWWISE && arg_distr != arg_end) 00253 return NULL; 00254 if (dim_order == DRA_DIMS_COLUMNWISE && arg_dim != arg_begin) 00255 return NULL; 00256 *buf++ = ')'; 00257 } 00258 else 00259 *buf++ = ','; 00260 } 00261 } 00262 00263 /* Non reshaped argument (num_dims == 0) */ 00264 else { 00265 if (buf-dem_buf+2 >= DRA_DEM_BUFSIZE) 00266 return NULL; 00267 *buf++ = '-'; 00268 00269 /* Underscore must follow each argument */ 00270 if (*arg_begin != DRA_ARG_SEPARATOR) 00271 return NULL; 00272 } 00273 00274 arg_begin = arg_end+1; 00275 } 00276 00277 *buf++ = ')'; 00278 *buf = 0; 00279 00280 return dem_buf; 00281 } 00282 00283 00284 00285 /* 00286 * Extract and demangle both the function name and the argument list 00287 */ 00288 00289 char* 00290 DRA_Demangle(const char *mangled_name, 00291 const char dim_order) 00292 { 00293 char *func_name; 00294 char *postfix_sig; 00295 char *arg_list; 00296 char *arg_begin; 00297 char *arg_end; 00298 char *arg_dim; 00299 char *arg_distr; 00300 char *buf; 00301 00302 int func_name_len; 00303 int arg_pos; 00304 int num_dims; 00305 int dim; 00306 int chunk; 00307 00308 00309 /* Dimension ordering must be either 'F' or 'C' */ 00310 if (dim_order != DRA_DIMS_COLUMNWISE && dim_order != DRA_DIMS_ROWWISE) 00311 return NULL; 00312 00313 /* Check for prefix signature */ 00314 if (mangled_name == NULL || 00315 strncmp(mangled_name, DRA_MANGLE_SIG, DRA_MANGLE_SIG_LEN) != 0) 00316 return NULL; 00317 00318 func_name = (char*) mangled_name + DRA_MANGLE_SIG_LEN; 00319 00320 /* Check for postfix signature */ 00321 postfix_sig = strstr(func_name, DRA_MANGLE_SIG); 00322 00323 if (postfix_sig == NULL) 00324 return NULL; 00325 00326 /* Check that the name is not too long */ 00327 func_name_len = postfix_sig - func_name; 00328 if (func_name_len + 4 >= DRA_DEM_BUFSIZE) 00329 return NULL; 00330 00331 /* Copy original function name into static buffer */ 00332 (void) strncpy(dem_buf, func_name, func_name_len); 00333 00334 /* Check that argument list is not empty */ 00335 arg_list = postfix_sig + DRA_MANGLE_SIG_LEN; 00336 00337 if (arg_list[0] == 0 || arg_list[1] == 0) 00338 return NULL; 00339 00340 buf = dem_buf + (postfix_sig-func_name); 00341 *buf++ = '('; 00342 00343 00344 for (arg_pos = 0, arg_begin = arg_list; *arg_begin != 0; arg_pos++) { 00345 00346 /* Underscore must follow each argument */ 00347 arg_end = strchr(arg_begin, DRA_ARG_SEPARATOR); 00348 if (arg_end == NULL || arg_end == arg_begin) 00349 return NULL; 00350 00351 /* Insert comma before each argument, except for the first one */ 00352 if (arg_pos > 0) 00353 *buf++ = ','; 00354 00355 /* Extract the number of dimensions */ 00356 num_dims = (int) strtol(arg_begin, &arg_begin, 10); 00357 00358 if (num_dims > 0) { 00359 00360 /* 'D' must follow the number of dimensions */ 00361 if (*arg_begin++ != DRA_NDIMS_END) 00362 return NULL; 00363 00364 *buf++ = '('; 00365 00366 /* Skip element size */ 00367 (void) strtol(arg_begin, &arg_begin, 10); 00368 00369 /* 'E' must follow the element size */ 00370 if (*arg_begin++ != DRA_ESIZE_END) 00371 return NULL; 00372 00373 /* For columnwise case (Fortran) decode dimensions in reverse order */ 00374 if (dim_order == DRA_DIMS_COLUMNWISE) 00375 arg_dim = arg_end; 00376 else 00377 arg_dim = arg_begin; 00378 00379 /* Go through all dimensions of the reshaped argument */ 00380 for (dim = 0; dim < num_dims; dim++) { 00381 00382 if (dim_order == DRA_DIMS_COLUMNWISE) { 00383 do { 00384 arg_dim--; 00385 } while (*arg_dim != DRA_STAR_CODE && 00386 *arg_dim != DRA_BLOCK_CODE && 00387 *arg_dim != DRA_CYCLIC_CODE && 00388 *arg_dim != DRA_ESIZE_END); 00389 } 00390 00391 arg_distr = arg_dim; 00392 00393 switch(*arg_distr++) { 00394 00395 case DRA_STAR_CODE: 00396 if (buf-dem_buf+strlen(DRA_STAR_STRING)+2 >= DRA_DEM_BUFSIZE) 00397 return NULL; 00398 buf += sprintf(buf, DRA_STAR_STRING); 00399 break; 00400 00401 case DRA_BLOCK_CODE: 00402 if (buf-dem_buf+strlen(DRA_BLOCK_STRING)+2 >= DRA_DEM_BUFSIZE) 00403 return NULL; 00404 buf += sprintf(buf, DRA_BLOCK_STRING); 00405 break; 00406 00407 case DRA_CYCLIC_CODE: 00408 if (buf-dem_buf+strlen(DRA_CYCLIC_STRING)+25 >= DRA_DEM_BUFSIZE) 00409 return NULL; 00410 buf += sprintf(buf, DRA_CYCLIC_STRING); 00411 chunk = (int) strtol(arg_distr, &arg_distr, 10); 00412 if (chunk != 0) 00413 buf += sprintf(buf, "(%d)", chunk); 00414 else 00415 buf += sprintf(buf, "(sym)"); 00416 break; 00417 00418 default: 00419 return NULL; 00420 } 00421 00422 if (dim == num_dims-1) { 00423 if (dim_order == DRA_DIMS_ROWWISE && arg_distr != arg_end) 00424 return NULL; 00425 if (dim_order == DRA_DIMS_COLUMNWISE && arg_dim != arg_begin) 00426 return NULL; 00427 *buf++ = ')'; 00428 } 00429 else 00430 *buf++ = ','; 00431 } 00432 } 00433 00434 /* Non reshaped argument (num_dims == 0) */ 00435 else { 00436 if (buf-dem_buf+2 >= DRA_DEM_BUFSIZE) 00437 return NULL; 00438 00439 *buf++ = '-'; 00440 /* Underscore must follow each argument */ 00441 if (*arg_begin != DRA_ARG_SEPARATOR) 00442 return NULL; 00443 } 00444 00445 arg_begin = arg_end+1; 00446 } 00447 00448 *buf++ = ')'; 00449 *buf = 0; 00450 00451 return dem_buf; 00452 } 00453 00454 00455