Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
dra_demangle.cxx
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  * ====================================================================
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines