⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intrinsic.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Build up a list of intrinsic subroutines and functions for the   name-resolution stage.   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,   Inc.   Contributed by Andy Vaught & Katherine HolcombThis file is part of GCC.GCC is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.GCC is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public Licensealong with GCC; see the file COPYING.  If not, write to the FreeSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA02110-1301, USA.  */#include "config.h"#include "system.h"#include "flags.h"#include "gfortran.h"#include "intrinsic.h"/* Namespace to hold the resolved symbols for intrinsic subroutines.  */static gfc_namespace *gfc_intrinsic_namespace;int gfc_init_expr = 0;/* Pointers to an intrinsic function and its argument names that are being   checked.  */const char *gfc_current_intrinsic;const char *gfc_current_intrinsic_arg[MAX_INTRINSIC_ARGS];locus *gfc_current_intrinsic_where;static gfc_intrinsic_sym *functions, *subroutines, *conversion, *next_sym;static gfc_intrinsic_arg *next_arg;static int nfunc, nsub, nargs, nconv;static enum{ SZ_NOTHING = 0, SZ_SUBS, SZ_FUNCS, SZ_CONVS }sizing;#define REQUIRED	0#define OPTIONAL	1/* Return a letter based on the passed type.  Used to construct the   name of a type-dependent subroutine.  */chargfc_type_letter (bt type){  char c;  switch (type)    {    case BT_LOGICAL:      c = 'l';      break;    case BT_CHARACTER:      c = 's';      break;    case BT_INTEGER:      c = 'i';      break;    case BT_REAL:      c = 'r';      break;    case BT_COMPLEX:      c = 'c';      break;    case BT_HOLLERITH:      c = 'h';      break;    default:      c = 'u';      break;    }  return c;}/* Get a symbol for a resolved name.  */gfc_symbol *gfc_get_intrinsic_sub_symbol (const char * name){  gfc_symbol *sym;  gfc_get_symbol (name, gfc_intrinsic_namespace, &sym);  sym->attr.always_explicit = 1;  sym->attr.subroutine = 1;  sym->attr.flavor = FL_PROCEDURE;  sym->attr.proc = PROC_INTRINSIC;  return sym;}/* Return a pointer to the name of a conversion function given two   typespecs.  */static const char *conv_name (gfc_typespec * from, gfc_typespec * to){  static char name[30];  sprintf (name, "__convert_%c%d_%c%d", gfc_type_letter (from->type),	   from->kind, gfc_type_letter (to->type), to->kind);  return gfc_get_string (name);}/* Given a pair of typespecs, find the gfc_intrinsic_sym node that   corresponds to the conversion.  Returns NULL if the conversion   isn't found.  */static gfc_intrinsic_sym *find_conv (gfc_typespec * from, gfc_typespec * to){  gfc_intrinsic_sym *sym;  const char *target;  int i;  target = conv_name (from, to);  sym = conversion;  for (i = 0; i < nconv; i++, sym++)    if (strcmp (target, sym->name) == 0)      return sym;  return NULL;}/* Interface to the check functions.  We break apart an argument list   and call the proper check function rather than forcing each   function to manipulate the argument list.  */static trydo_check (gfc_intrinsic_sym * specific, gfc_actual_arglist * arg){  gfc_expr *a1, *a2, *a3, *a4, *a5;  if (arg == NULL)    return (*specific->check.f0) ();  a1 = arg->expr;  arg = arg->next;  if (arg == NULL)    return (*specific->check.f1) (a1);  a2 = arg->expr;  arg = arg->next;  if (arg == NULL)    return (*specific->check.f2) (a1, a2);  a3 = arg->expr;  arg = arg->next;  if (arg == NULL)    return (*specific->check.f3) (a1, a2, a3);  a4 = arg->expr;  arg = arg->next;  if (arg == NULL)    return (*specific->check.f4) (a1, a2, a3, a4);  a5 = arg->expr;  arg = arg->next;  if (arg == NULL)    return (*specific->check.f5) (a1, a2, a3, a4, a5);  gfc_internal_error ("do_check(): too many args");}/*********** Subroutines to build the intrinsic list ****************//* Add a single intrinsic symbol to the current list.   Argument list:      char *     name of function      int        whether function is elemental      int        If the function can be used as an actual argument      bt         return type of function      int        kind of return type of function      int        Fortran standard version      check      pointer to check function      simplify   pointer to simplification function      resolve    pointer to resolution function   Optional arguments come in multiples of four:      char *    name of argument      bt        type of argument      int       kind of argument      int       arg optional flag (1=optional, 0=required)   The sequence is terminated by a NULL name.   TODO: Are checks on actual_ok implemented elsewhere, or is that just   missing here?  */static voidadd_sym (const char *name, int elemental, int actual_ok ATTRIBUTE_UNUSED,	 bt type, int kind, int standard, gfc_check_f check,	 gfc_simplify_f simplify, gfc_resolve_f resolve, ...){  char buf[GFC_MAX_SYMBOL_LEN + 11]; /* 10 for '_gfortran_', 1 for '\0'  */  int optional, first_flag;  va_list argp;  /* First check that the intrinsic belongs to the selected standard.     If not, don't add it to the symbol list.  */  if (!(gfc_option.allow_std & standard))    return;  switch (sizing)    {    case SZ_SUBS:      nsub++;      break;    case SZ_FUNCS:      nfunc++;      break;    case SZ_NOTHING:      next_sym->name = gfc_get_string (name);      strcpy (buf, "_gfortran_");      strcat (buf, name);      next_sym->lib_name = gfc_get_string (buf);      next_sym->elemental = elemental;      next_sym->ts.type = type;      next_sym->ts.kind = kind;      next_sym->standard = standard;      next_sym->simplify = simplify;      next_sym->check = check;      next_sym->resolve = resolve;      next_sym->specific = 0;      next_sym->generic = 0;      break;    default:      gfc_internal_error ("add_sym(): Bad sizing mode");    }  va_start (argp, resolve);  first_flag = 1;  for (;;)    {      name = va_arg (argp, char *);      if (name == NULL)	break;      type = (bt) va_arg (argp, int);      kind = va_arg (argp, int);      optional = va_arg (argp, int);      if (sizing != SZ_NOTHING)	nargs++;      else	{	  next_arg++;	  if (first_flag)	    next_sym->formal = next_arg;	  else	    (next_arg - 1)->next = next_arg;	  first_flag = 0;	  strcpy (next_arg->name, name);	  next_arg->ts.type = type;	  next_arg->ts.kind = kind;	  next_arg->optional = optional;	}    }  va_end (argp);  next_sym++;}/* Add a symbol to the function list where the function takes   0 arguments.  */static voidadd_sym_0 (const char *name, int elemental, int actual_ok, bt type,		       int kind, int standard,		       try (*check)(void),		       gfc_expr *(*simplify)(void),	   void (*resolve)(gfc_expr *)){  gfc_simplify_f sf;  gfc_check_f cf;  gfc_resolve_f rf;  cf.f0 = check;  sf.f0 = simplify;  rf.f0 = resolve;  add_sym (name, elemental, actual_ok, type, kind, standard, cf, sf, rf,	   (void*)0);}/* Add a symbol to the subroutine list where the subroutine takes   0 arguments.  */static voidadd_sym_0s (const char * name, int actual_ok, int standard,	    void (*resolve)(gfc_code *)){  gfc_check_f cf;  gfc_simplify_f sf;  gfc_resolve_f rf;  cf.f1 = NULL;  sf.f1 = NULL;  rf.s1 = resolve;  add_sym (name, 1, actual_ok, BT_UNKNOWN, 0, standard, cf, sf, rf,	   (void*)0);}/* Add a symbol to the function list where the function takes   1 arguments.  */static voidadd_sym_1 (const char *name, int elemental, int actual_ok, bt type,	   int kind, int standard,	   try (*check)(gfc_expr *),	   gfc_expr *(*simplify)(gfc_expr *),	   void (*resolve)(gfc_expr *,gfc_expr *),	   const char* a1, bt type1, int kind1, int optional1){  gfc_check_f cf;  gfc_simplify_f sf;  gfc_resolve_f rf;  cf.f1 = check;  sf.f1 = simplify;  rf.f1 = resolve;  add_sym (name, elemental, actual_ok, type, kind, standard, cf, sf, rf,	   a1, type1, kind1, optional1,	   (void*)0);}/* Add a symbol to the subroutine list where the subroutine takes   1 arguments.  */static voidadd_sym_1s (const char *name, int elemental, int actual_ok, bt type,			int kind, int standard,			try (*check)(gfc_expr *),			gfc_expr *(*simplify)(gfc_expr *),			void (*resolve)(gfc_code *),	    const char* a1, bt type1, int kind1, int optional1){  gfc_check_f cf;  gfc_simplify_f sf;  gfc_resolve_f rf;  cf.f1 = check;  sf.f1 = simplify;  rf.s1 = resolve;  add_sym (name, elemental, actual_ok, type, kind, standard, cf, sf, rf,	   a1, type1, kind1, optional1,	   (void*)0);}/* Add a symbol from the MAX/MIN family of intrinsic functions to the   function.  MAX et al take 2 or more arguments.  */static voidadd_sym_1m (const char *name, int elemental, int actual_ok, bt type,			int kind, int standard,			try (*check)(gfc_actual_arglist *),			gfc_expr *(*simplify)(gfc_expr *),			void (*resolve)(gfc_expr *,gfc_actual_arglist *),			const char* a1, bt type1, int kind1, int optional1,	    const char* a2, bt type2, int kind2, int optional2){  gfc_check_f cf;  gfc_simplify_f sf;  gfc_resolve_f rf;  cf.f1m = check;  sf.f1 = simplify;  rf.f1m = resolve;  add_sym (name, elemental, actual_ok, type, kind, standard, cf, sf, rf,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -