/*

  $Id$

  Copyright 1989-2016 MINES ParisTech

  This file is part of PIPS.

  PIPS is free software: you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  any later version.

  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.

  See the GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with PIPS.  If not, see <http://www.gnu.org/licenses/>.

*/
/* RI-UTIL Library: Functions dealing with and constants related to
 * PIPS intermediate representation ri.newgen,
 * that are NOT generated by NewGen
 */

 /* Pvecteur is an external type for NewGen and the ri data structure
  * and is not included in ri.h
  *
  * It is included here to avoid changes in many PIPS modules which
  * use ri-util
  *
  * Idem for type Ppolynome (PB 25/07/90); FI: polynomials are not
  * used in ri.newgen; they should not be mentionned here
  *
  * Idem for type Psysteme (FI 3 November 1990)
  *
  * New function call need to be defined to handle omp pragma as a
  * standard PIPS expression. To be easily recognized, all the defined
  * values are prefixed by "OMP_".
  */

/*
 * Modifications:
 * --------------
 * Molka Becher (MB), June 2010
 * - Add and Check of definition of C Intrinsics (#define)
 * - Add of definition of QuadPrecision type and LongDoubleComplex type
 * - Add of package & variable names for memmove intrinsic (string.h)
 */


#include "linear.h"
#include "genC.h"

#include "ri.h"
#include "text.h"
#include "cloning.h"

#include "newgen.h"
#include "naming.h"

/* FC 2015-07-20
 * yuk, temporary fix to avoid an include cycle ri-util <-> prettyprint
 # #include "prettyprint.h"
 */
extern string basic_to_string(basic);
extern string string_of_type(type);
extern void print_type(type);
extern bool same_type_name_p(type, type);

#define UNBOUNDED_DIMENSION_NAME         "UNBOUNDED-DIMENSION"
#define IMPLIED_DO_NAME                  "IMPLIED-DO"
#define IMPLIED_DO_FUNCTION_NAME         "IMPLIED-DO"
#define REPEAT_VALUE_NAME                "REPEAT-VALUE"
#define REPEAT_VALUE_FUNCTION_NAME       "REPEAT-VALUE"
#define STATIC_INITIALIZATION_NAME       "STATIC-INITIALIZATION"
#define STATIC_INITIALIZATION_FUNCTION_NAME     "STATIC-INITIALIZATION"
#define DATA_LIST_FUNCTION_NAME          "DATA-LIST="
#define IO_LIST_STRING_NAME              "IOLIST="


#define BRACE_INTRINSIC                  "BRACE_INTRINSIC"
#define NULL_STATEMENT_INTRINSIC         "NULL_STATEMENT_INTRINSIC"

#define IMPLIED_COMPLEX_NAME             "CMPLX_"
#define IMPLIED_DCOMPLEX_NAME            "DCMPLX_"

#define FIELD_OPERATOR_NAME              "."
#define POINT_TO_OPERATOR_NAME           "->"
#define DEREFERENCING_OPERATOR_NAME      "*indirection"

#define ASSIGN_OPERATOR_NAME             "="
#define ASSIGN_OPERATOR_PRECEDENCE       (2)
#define POST_INCREMENT_OPERATOR_NAME     "post++"
#define POST_DECREMENT_OPERATOR_NAME     "post--"
#define PRE_INCREMENT_OPERATOR_NAME      "++pre"
#define PRE_DECREMENT_OPERATOR_NAME      "--pre"
#define MULTIPLY_UPDATE_OPERATOR_NAME    "*="
#define DIVIDE_UPDATE_OPERATOR_NAME      "/="
#define PLUS_UPDATE_OPERATOR_NAME        "+="
#define MINUS_UPDATE_OPERATOR_NAME       "-="
#define LEFT_SHIFT_UPDATE_OPERATOR_NAME  "<<="
#define RIGHT_SHIFT_UPDATE_OPERATOR_NAME ">>="
#define BITWISE_OR_UPDATE_OPERATOR_NAME  "|="

#define COMMA_OPERATOR_NAME             ","

#define PLUS_OPERATOR_NAME              "+"
#define PLUS_C_OPERATOR_NAME            "+C" /* includes pointer arithmetic */
#define MINUS_OPERATOR_NAME             "-"
#define MINUS_C_OPERATOR_NAME           "-C" /* includes pointer arithmetic */
#define UNARY_MINUS_OPERATOR_NAME       "--"
#define UNARY_PLUS_OPERATOR_NAME        "+unary"
#define MULTIPLY_OPERATOR_NAME          "*"
#define DIVIDE_OPERATOR_NAME            "/"
#define INVERSE_OPERATOR_NAME           "_INV_" /* internal stuff */
#define POWER_OPERATOR_NAME             "**"
#define MODULO_OPERATOR_NAME            "MOD"
#define REAL_MODULO_OPERATOR_NAME       "AMOD"
#define DOUBLE_MODULO_OPERATOR_NAME     "DMOD"
#define SIGN_OPERATOR_NAME              "SIGN"
#define ISIGN_OPERATOR_NAME             "ISIGN"
#define DSIGN_OPERATOR_NAME             "DSIGN"
#define DIM_OPERATOR_NAME               "DIM"
#define IDIM_OPERATOR_NAME              "IDIM"
#define DDIM_OPERATOR_NAME              "DDIM"
#define DPROD_OPERATOR_NAME             "DPROD"
#define CONJG_OPERATOR_NAME             "CONJG"
#define DCONJG_OPERATOR_NAME            "DCONJG"
#define SQRT_OPERATOR_NAME              "SQRT"
#define DSQRT_OPERATOR_NAME             "DSQRT"
#define CSQRT_OPERATOR_NAME             "CSQRT"
#define CDSQRT_OPERATOR_NAME            "CDSQRT"
#define EXP_OPERATOR_NAME               "EXP"
#define DEXP_OPERATOR_NAME              "DEXP"
#define CEXP_OPERATOR_NAME              "CEXP"
#define CDEXP_OPERATOR_NAME             "CDEXP"
#define LOG_OPERATOR_NAME               "LOG"
#define ALOG_OPERATOR_NAME              "ALOG"
#define DLOG_OPERATOR_NAME              "DLOG"
#define CLOG_OPERATOR_NAME              "CLOG"
#define CDLOG_OPERATOR_NAME             "CDLOG"
#define LOG10_OPERATOR_NAME             "LOG10"
#define ALOG10_OPERATOR_NAME            "ALOG10"
#define DLOG10_OPERATOR_NAME            "DLOG10"
#define SIN_OPERATOR_NAME               "SIN"
#define DSIN_OPERATOR_NAME              "DSIN"
#define CSIN_OPERATOR_NAME              "CSIN"
#define CDSIN_OPERATOR_NAME             "CDSIN"
#define COS_OPERATOR_NAME               "COS"
#define DCOS_OPERATOR_NAME              "DCOS"
#define CCOS_OPERATOR_NAME              "CCOS"
#define CDCOS_OPERATOR_NAME             "CDCOS"
#define TAN_OPERATOR_NAME               "TAN"
#define DTAN_OPERATOR_NAME              "DTAN"
#define ASIN_OPERATOR_NAME              "ASIN"
#define DASIN_OPERATOR_NAME             "DASIN"
#define ACOS_OPERATOR_NAME              "ACOS"
#define DACOS_OPERATOR_NAME             "DACOS"
#define ATAN_OPERATOR_NAME              "ATAN"
#define DATAN_OPERATOR_NAME             "DATAN"
#define ATAN2_OPERATOR_NAME             "ATAN2"
#define DATAN2_OPERATOR_NAME            "DATAN2"
#define SINH_OPERATOR_NAME              "SINH"
#define DSINH_OPERATOR_NAME             "DSINH"
#define COSH_OPERATOR_NAME              "COSH"
#define DCOSH_OPERATOR_NAME             "DCOSH"
#define TANH_OPERATOR_NAME              "TANH"
#define DTANH_OPERATOR_NAME             "DTANH"
#define LEFT_SHIFT_OPERATOR_NAME        "<<"
#define RIGHT_SHIFT_OPERATOR_NAME       ">>"

// Conflicts with reserved prefixes for BLOCKDATA (&), COMMON (~),
// MAIN (%), FILESEP (!), MEMBER_SEP_STRING (^), ENUM (?) & al.
// Use "-" to avoid conflict with user defined symbols
#define ADDRESS_OF_OPERATOR_NAME         "__address-of__"       // &
#define BITWISE_AND_OPERATOR_NAME        "__bit-and__"          // &
#define BITWISE_NOT_OPERATOR_NAME        "__bit-not__"          // ~
#define BITWISE_XOR_OPERATOR_NAME        "__C-xor__"            // ^
#define C_AND_OPERATOR_NAME              "__C-and__"            // &&
#define MODULO_UPDATE_OPERATOR_NAME      "__C-modulo-update__"  // %=
#define BITWISE_AND_UPDATE_OPERATOR_NAME "__C-bit-and-update__" // &=
#define BITWISE_XOR_UPDATE_OPERATOR_NAME "__C-bit-xor-update__" // ^=
#define CONDITIONAL_OPERATOR_NAME        "__C-conditional__"    // ?
#define C_NOT_OPERATOR_NAME              "__C-logical-not__"    // !
#define C_NON_EQUAL_OPERATOR_NAME        "__C-non-equal__"      // !=
#define C_MODULO_OPERATOR_NAME           "__C-modulo__"         // %

#define BITWISE_OR_OPERATOR_NAME        "|"
#define MIN_OPERATOR_NAME               "MIN"
#define MIN0_OPERATOR_NAME              "MIN0"
#define MIN1_OPERATOR_NAME              "MIN1"
#define AMIN0_OPERATOR_NAME             "AMIN0"
#define AMIN1_OPERATOR_NAME             "AMIN1"
#define DMIN1_OPERATOR_NAME             "DMIN1"
#define MAX_OPERATOR_NAME               "MAX"
#define MAX0_OPERATOR_NAME              "MAX0"
#define AMAX0_OPERATOR_NAME             "AMAX0"
#define MAX1_OPERATOR_NAME              "MAX1"
#define AMAX1_OPERATOR_NAME             "AMAX1"
#define DMAX1_OPERATOR_NAME             "DMAX1"
#define ABS_OPERATOR_NAME               "ABS"
#define IABS_OPERATOR_NAME              "IABS"
#define DABS_OPERATOR_NAME              "DABS"
#define CABS_OPERATOR_NAME              "CABS"
#define CDABS_OPERATOR_NAME             "CDABS"

#define LENGTH_OPERATOR_NAME            "LEN"
#define INDEX_OPERATOR_NAME             "INDEX"
#define LGE_OPERATOR_NAME               "LGE"
#define LGT_OPERATOR_NAME               "LGT"
#define LLE_OPERATOR_NAME               "LLE"
#define LLT_OPERATOR_NAME               "LLT"

/* generic conversion names.
 */
#define INT_GENERIC_CONVERSION_NAME     "INT"
#define IFIX_GENERIC_CONVERSION_NAME    "IFIX"
#define IDINT_GENERIC_CONVERSION_NAME   "IDINT"
#define REAL_GENERIC_CONVERSION_NAME    "REAL"
#define FLOAT_GENERIC_CONVERSION_NAME   "FLOAT"
#define DFLOAT_GENERIC_CONVERSION_NAME  "DFLOAT"
#define SNGL_GENERIC_CONVERSION_NAME    "SNGL"
#define DBLE_GENERIC_CONVERSION_NAME    "DBLE"
#define DREAL_GENERIC_CONVERSION_NAME   "DREAL"
#define CMPLX_GENERIC_CONVERSION_NAME   "CMPLX"
#define DCMPLX_GENERIC_CONVERSION_NAME  "DCMPLX"

#define INT_TO_CHAR_CONVERSION_NAME     "CHAR"
#define CHAR_TO_INT_CONVERSION_NAME     "ICHAR"

#define AINT_CONVERSION_NAME            "AINT"
#define DINT_CONVERSION_NAME            "DINT"
#define ANINT_CONVERSION_NAME           "ANINT"
#define DNINT_CONVERSION_NAME           "DNINT"
#define NINT_CONVERSION_NAME            "NINT"
#define IDNINT_CONVERSION_NAME          "IDNINT"
#define AIMAG_CONVERSION_NAME           "AIMAG"
#define DIMAG_CONVERSION_NAME           "DIMAG"

/* FI: intrinsics are defined at a third place after bootstrap and effects!
 *     I guess the name should be defined here and used in table(s) there
 */

#define AND_OPERATOR_NAME               ".AND."
#define OR_OPERATOR_NAME                ".OR."
#define C_OR_OPERATOR_NAME              "||"
#define NOT_OPERATOR_NAME               ".NOT."
#define NON_EQUAL_OPERATOR_NAME         ".NE."
#define EQUIV_OPERATOR_NAME             ".EQV."
#define NON_EQUIV_OPERATOR_NAME         ".NEQV."

#define TRUE_OPERATOR_NAME              ".TRUE."
#define FALSE_OPERATOR_NAME             ".FALSE."
#define ONE_OPERATOR_NAME               "1"
#define ZERO_OPERATOR_NAME              "0"

#define GREATER_OR_EQUAL_OPERATOR_NAME  ".GE."
#define C_GREATER_OR_EQUAL_OPERATOR_NAME        ">="
#define GREATER_THAN_OPERATOR_NAME      ".GT."
#define C_GREATER_THAN_OPERATOR_NAME    ">"
#define LESS_OR_EQUAL_OPERATOR_NAME     ".LE."
#define C_LESS_OR_EQUAL_OPERATOR_NAME   "<="
#define LESS_THAN_OPERATOR_NAME         ".LT."
#define C_LESS_THAN_OPERATOR_NAME       "<"
#define EQUAL_OPERATOR_NAME             ".EQ."
#define C_EQUAL_OPERATOR_NAME           "=="

#define CONTINUE_FUNCTION_NAME          "CONTINUE"
#define C_CONTINUE_FUNCTION_NAME        ";"
#define C_STATEMENT_END_STRING          ";"
#define RETURN_FUNCTION_NAME            "RETURN"
#define STOP_FUNCTION_NAME              "STOP"
#define PAUSE_FUNCTION_NAME             "PAUSE"
#define END_FUNCTION_NAME               "END"
#define ENDDO_FUNCTION_NAME             "ENDDO"

#define BREAK_FUNCTION_NAME             "break"
#define CASE_FUNCTION_NAME              "case"
#define DEFAULT_FUNCTION_NAME           "default"
#define C_RETURN_FUNCTION_NAME          "return"

#define SUBSTRING_FUNCTION_NAME         "_SUBSTR"
#define CONCATENATION_FUNCTION_NAME     "//"
#define ASSIGN_SUBSTRING_FUNCTION_NAME  "_ASSIGN_SUBSTR"

#define WRITE_FUNCTION_NAME             "WRITE"
#define PRINT_FUNCTION_NAME             "PRINT"
#define REWIND_FUNCTION_NAME            "REWIND"
#define OPEN_FUNCTION_NAME              "OPEN"
#define CLOSE_FUNCTION_NAME             "CLOSE"
#define INQUIRE_FUNCTION_NAME           "INQUIRE"
#define BACKSPACE_FUNCTION_NAME         "BACKSPACE"
#define READ_FUNCTION_NAME              "READ"
#define BUFFERIN_FUNCTION_NAME          "BUFFERIN"
#define BUFFEROUT_FUNCTION_NAME         "BUFFEROUT"
#define ENDFILE_FUNCTION_NAME           "ENDFILE"
#define FORMAT_FUNCTION_NAME            "FORMAT"


/* Bit manipulation functions */
#define ISHFT_OPERATOR_NAME             "ISHFT"
#define ISHFTC_OPERATOR_NAME            "ISHFTC"
#define IBITS_OPERATOR_NAME             "IBITS"
#define MVBITS_OPERATOR_NAME            "MVBITS"
#define BTEST_OPERATOR_NAME             "BTEST"
#define IBSET_OPERATOR_NAME             "IBSET"
#define IBCLR_OPERATOR_NAME             "IBCLR"
#define BIT_SIZE_OPERATOR_NAME          "BIT_SIZE"
#define IAND_OPERATOR_NAME              "IAND"
#define IEOR_OPERATOR_NAME              "IEOR"
#define IOR_OPERATOR_NAME               "IOR"

/* OMP related function and opertor names */

#define OMP_IF_FUNCTION_NAME            "if"
#define OMP_OMP_FUNCTION_NAME           "omp"
#define OMP_FOR_FUNCTION_NAME           "for"
#define OMP_PRIVATE_FUNCTION_NAME       "private"
#define OMP_PARALLEL_FUNCTION_NAME      "parallel"
#define OMP_REDUCTION_FUNCTION_NAME     "reduction"

/* F95 */
#define ALLOCATE_FUNCTION_NAME          "ALLOCATE"
#define DEALLOCATE_FUNCTION_NAME        "DEALLOCATE"
#define ETIME_FUNCTION_NAME             "ETIME"
#define DTIME_FUNCTION_NAME             "DTIME"
#define CPU_TIME_FUNCTION_NAME          "CPU_TIME"

/* F2003 */
#define C_LOC_FUNCTION_NAME             "C_LOC"

/* F2008 */

/* BSD <err.h> */
#define ERR_FUNCTION_NAME		"err"
#define ERRX_FUNCTION_NAME		"errx"
#define WARN_FUNCTION_NAME		"warn"
#define WARNX_FUNCTION_NAME		"warnx"
#define VERR_FUNCTION_NAME		"verr"
#define VERRX_FUNCTION_NAME		"verrx"
#define VWARN_FUNCTION_NAME		"vwarn"
#define VWARNX_FUNCTION_NAME		"vwarnx"

/* time.h */
#define CLOCK_FUNCTION_NAME		"clock"
#define TIME_FUNCTION_NAME		"time"
#define DIFFTIME_FUNCTION_NAME		"difftime"
#define MKTIME_FUNCTION_NAME		"mktime"
#define STRFTIME_FUNCTION_NAME		"strftime"
#define STRPTIME_FUNCTION_NAME		"strptime"
#define STRFTIME_L_FUNCTION_NAME	"strftime_l"
#define STRPTIME_L_FUNCTION_NAME	"strptime_l"
#define GMTIME_FUNCTION_NAME		"gmtime"
#define LOCALTIME_FUNCTION_NAME		"localtime"
#define GMTIME_R_FUNCTION_NAME		"gmtime_r"
#define LOCALTIME_R_FUNCTION_NAME	"localtime_r"
#define ASCTIME_FUNCTION_NAME		"asctime"
#define CTIME_FUNCTION_NAME		"ctime"
#define ASCTIME_R_FUNCTION_NAME		"asctime_r"
#define CTIME_R_FUNCTION_NAME		"ctime_r"
#define TZSET_FUNCTION_NAME		"tzset"
#define STIME_FUNCTION_NAME             "stime"
#define TIMEGM_FUNCTION_NAME            "timegm"
#define TIMELOCAL_FUNCTION_NAME         "timelocal"
#define DYSIZE_FUNCTION_NAME            "dysize"
#define NANOSLEEP_FUNCTION_NAME         "nanosleep"
#define CLOCK_GETRES_FUNCTION_NAME      "clock_getres"
#define CLOCK_GETTIME_FUNCTION_NAME     "clock_gettime"
#define CLOCK_SETTIME_FUNCTION_NAME     "clock_settime"
#define CLOCK_NANOSLEEP_FUNCTION_NAME   "clock_nanosleep"
#define CLOCK_GETCPULOCKID_FUNCTION_NAME "clock_getcpulockid"
#define TIMER_CREATE_FUNCTION_NAME      "timer_create"
#define TIMER_DELETE_FUNCTION_NAME      "timer_delete"
#define TIMER_SETTIME_FUNCTION_NAME     "timer_settime"
#define TIMER_GETTIME_FUNCTION_NAME     "timer_gettime"
#define TIMER_GETOVERRUN_FUNCTION_NAME  "timer_getoverrun"
#define GETDATE_FUNCTION_NAME           "getdate"
#define GETDATE_R_FUNCTION_NAME         "getdate_r"

//to check
#define DRAND48_FUNCTION_NAME           "drand48"
#define ERAND48_FUNCTION_NAME           "erand48"
#define JRAND48_FUNCTION_NAME           "jrand48"
#define LCONG48_FUNCTION_NAME           "lcong48"
#define LRAND48_FUNCTION_NAME           "lrand48"
#define MRAND48_FUNCTION_NAME           "mrand48"
#define NRAND48_FUNCTION_NAME           "nrand48"
#define SEED48_FUNCTION_NAME            "seed48"
#define SRAND48_FUNCTION_NAME           "srand48"

#define PUTENV_FUNCTION_NAME            "putenv"
#define SETKEY_FUNCTION_NAME            "setkey"
#define SWAB_FUNCTION_NAME              "swab"
#define MKSTEMP_FUNCTION_NAME           "mkstemp"
#define MKSTEMP64_FUNCTION_NAME         "mkstemp64"
#define A614_FUNCTION_NAME              "a64l"
#define ECVT_FUNCTION_NAME              "ecvt"
#define FCVT_FUNCTION_NAME              "fcvt"
#define GCVT_FUNCTION_NAME              "gcvt"
#define GETSUBOPT_FUNCTION_NAME         "getsubopt"
#define GRANTPT_FUNCTION_NAME           "grantpt"
#define INITSTATE_FUNCTION_NAME         "initstate"
#define C_164A_FUNCTION_NAME            "l64a"
#define MKTEMP_FUNCTION_NAME            "mktemp"
#define PTSNAME_FUNCTION_NAME           "ptsname"
#define REALPATH_FUNCTION_NAME          "realpath"
#define SETSTATE_FUNCTION_NAME          "setstate"
#define TTYSLOT_FUNCTION_NAME           "ttyslot"
#define UNLOCKPT_FUNCTION_NAME          "unlockpt"
#define VALLOC_FUNCTION_NAME            "valloc"
#define DUP2_FUNCTION_NAME              "dup2"
#define QECVT_FUNCTION_NAME             "qecvt"
#define QFCVT_FUNCTION_NAME             "qfcvt"
#define QGCVT_FUNCTION_NAME             "qgcvt"
#define GETCWD_FUNCTION_NAME            "getcwd"
#define GETEXECNAME_FUNCTION_NAME       "getexecname"
#define GETLOGIN_FUNCTION_NAME          "getlogin"
#define GETOPT_FUNCTION_NAME            "getopt" // unistd.h
#define GETOPT_LONG_FUNCTION_NAME       "getopt_long"
#define GETOPT_LONG_ONLY_FUNCTION_NAME  "getopt_long_only"
#define GETPASS_FUNCTION_NAME           "getpass"
#define GETPASSPHRASE_FUNCTION_NAME     "getpassphrase"
#define GETPW_FUNCTION_NAME             "getpw"
#define ISATTY_FUNCTION_NAME            "isatty"
#define MEMALIGN_FUNCTION_NAME          "memalign"
#define TTYNAME_FUNCTION_NAME           "ttyname"
#define LLTOSTR_FUNCTION_NAME           "lltostr"
#define ULLTOSTR_FUNCTION_NAME          "ulltostr"

#define POSIX_MEMALIGN_FUNCTION_NAME    "posix_memalign"
#define ATOQ_FUNCTION_NAME              "atoq"
#define RANDOM_FUNCTION_NAME            "random"
#define SRANDOM_FUNCTION_NAME           "srandom"
#define MOD_INTRINSIC_NAME              "MOD"

/* PIPS run-time support for C code generation
 *
 * The first argument is the number of effective arguments, the second
 * argument is the first effective argument and other arguments are
 * passed as varargs. For instance:
 *
 * pips_min(5, 1, 2, 3, 4, 5);
 *
 * Initially, the source code for these two operators is available in
 * validation/Hyperplane/run_time.src/pips_run_time.c
 */
#define PIPS_C_MIN_OPERATOR_NAME        "pips_min"
#define PIPS_C_MAX_OPERATOR_NAME        "pips_max"
#define PIPS_C_DIV_OPERATOR_NAME        "pips_div"


 /* Here are C intrinsics arranged in the order of the standard
    ISO/IEC 9899:TC2. MB */
/* include <assert.h> */

#define ASSERT_FUNCTION_NAME            "__assert"
#define ASSERT_FAIL_FUNCTION_NAME       "__assert_fail"

/* include <complex.h> */

#define CACOS_OPERATOR_NAME             "cacos"
#define CACOSF_OPERATOR_NAME            "cacosf"
#define CACOSL_OPERATOR_NAME            "cacosl"
#define CASIN_OPERATOR_NAME             "casin"
#define CASINF_OPERATOR_NAME            "casinf"
#define CASINL_OPERATOR_NAME            "casinl"
#define CATAN_OPERATOR_NAME             "catan"
#define CATANF_OPERATOR_NAME            "catanf"
#define CATANL_OPERATOR_NAME            "catanl"
#define C_CCOS_OPERATOR_NAME            "ccos"
#define CCOSF_OPERATOR_NAME             "ccosf"
#define CCOSL_OPERATOR_NAME             "ccosl"
#define C_CSIN_OPERATOR_NAME            "csin"
#define CSINF_OPERATOR_NAME             "csinf"
#define CSINL_OPERATOR_NAME             "csinl"
#define CTAN_OPERATOR_NAME              "ctan"
#define CTANF_OPERATOR_NAME             "ctanf"
#define CTANL_OPERATOR_NAME             "ctanl"
#define CACOSH_OPERATOR_NAME            "cacosh"
#define CACOSHF_OPERATOR_NAME           "cacoshf"
#define CACOSHL_OPERATOR_NAME           "cacoshl"
#define CASINH_OPERATOR_NAME            "casinh"
#define CASINHF_OPERATOR_NAME           "casinhf"
#define CASINHL_OPERATOR_NAME           "casinhl"
#define CATANH_OPERATOR_NAME            "catanh"
#define CATANHF_OPERATOR_NAME           "catanhf"
#define CATANHL_OPERATOR_NAME           "catanhl"
#define CCOSH_OPERATOR_NAME             "ccosh"
#define CCOSHF_OPERATOR_NAME            "ccoshf"
#define CCOSHL_OPERATOR_NAME            "ccoshl"
#define CSINH_OPERATOR_NAME             "csinh"
#define CSINHF_OPERATOR_NAME            "csinhf"
#define CSINHL_OPERATOR_NAME            "csinhl"
#define CTANH_OPERATOR_NAME             "ctanh"
#define CTANHF_OPERATOR_NAME            "ctanhf"
#define CTANHL_OPERATOR_NAME            "ctanhl"
#define C_CEXP_OPERATOR_NAME            "cexp"
#define CEXPF_OPERATOR_NAME             "cexpf"
#define CEXPL_OPERATOR_NAME             "cexpl"
#define C_CLOG_OPERATOR_NAME            "clog"
#define CLOGF_OPERATOR_NAME             "clogf"
#define CLOGL_OPERATOR_NAME             "clogl"
#define C_CABS_OPERATOR_NAME            "cabs"
#define CABSF_OPERATOR_NAME             "cabsf"
#define CABSL_OPERATOR_NAME             "cabsl"
#define CPOW_OPERATOR_NAME              "cpow"
#define CPOWF_OPERATOR_NAME             "cpowf"
#define CPOWL_OPERATOR_NAME             "cpowl"
#define C_CSQRT_OPERATOR_NAME           "csqrt"
#define CSQRTF_OPERATOR_NAME            "csqrtf"
#define CSQRTL_OPERATOR_NAME            "csqrtl"
#define CARG_OPERATOR_NAME              "carg"
#define CARGF_OPERATOR_NAME             "cargf"
#define CARGL_OPERATOR_NAME             "cargl"
#define CIMAG_OPERATOR_NAME             "cimag"
#define GCC_CIMAG_OPERATOR_NAME         "__imag__"
#define CIMAGF_OPERATOR_NAME            "cimagf"
#define CIMAGL_OPERATOR_NAME            "cimagl"
#define CONJ_OPERATOR_NAME              "conj"
#define CONJF_OPERATOR_NAME             "conjf"
#define CONJL_OPERATOR_NAME             "conjl"
#define CPROJ_OPERATOR_NAME             "cproj"
#define CPROJF_OPERATOR_NAME            "cprojf"
#define CPROJL_OPERATOR_NAME            "cprojl"
#define CREAL_OPERATOR_NAME             "creal"
#define GCC_CREAL_OPERATOR_NAME         "__real__"
#define CREALF_OPERATOR_NAME            "crealf"
#define CREALL_OPERATOR_NAME            "creall"


/* #include <ctype.h> */

#define ISALNUM_OPERATOR_NAME           "isalnum"
#define ISALPHA_OPERATOR_NAME           "isalpha"
#define ISBLANK_OPERATOR_NAME           "isblank"
#define ISCNTRL_OPERATOR_NAME           "iscntrl"
#define ISDIGIT_OPERATOR_NAME           "isdigit"
#define ISGRAPH_OPERATOR_NAME           "isgraph"
#define ISLOWER_OPERATOR_NAME           "islower"
#define ISPRINT_OPERATOR_NAME           "isprint"
#define ISPUNCT_OPERATOR_NAME           "ispunct"
#define ISSPACE_OPERATOR_NAME           "isspace"
#define ISUPPER_OPERATOR_NAME           "isupper"
#define ISXDIGIT_OPERATOR_NAME          "isxdigit"
#define TOLOWER_OPERATOR_NAME           "tolower"
#define TOUPPER_OPERATOR_NAME           "toupper"

//not found in standard C99 (in GNU C Library)
#define ISASCII_OPERATOR_NAME           "isascii"
#define TOASCII_OPERATOR_NAME           "toascii"
#define _TOLOWER_OPERATOR_NAME          "_tolower"
#define _TOUPPER_OPERATOR_NAME          "_toupper"

/* Part of the binary standard */
#define CTYPE_B_LOC_OPERATOR_NAME       "__ctype_b_loc"


/* bits/errno.h */
#define __ERRNO_LOCATION_OPERATOR_NAME "__errno_location"


/* #include <fenv.h> */
#define FECLEAREXCEPT_FUNCTION_NAME        "feclearexcept"
#define FERAISEEXCEPT_FUNCTION_NAME        "feraiseexcept"
#define FESETEXCEPTFLAG_FUNCTION_NAME      "fesetexceptflag"
#define FETESTEXCEPT_FUNCTION_NAME         "fetestexcept"
#define FEGETROUND_FUNCTION_NAME           "fegetround"
#define FESETROUND_FUNCTION_NAME           "fesetround"

/* #include <inttypes.h> */
#define IMAXABS_FUNCTION_NAME              "imaxabs"
#define IMAXDIV_FUNCTION_NAME              "imaxdiv"

/* #include <locale.h> */
#define SETLOCALE_FUNCTION_NAME            "setlocale"

/* #include <math.h> */

#define FPCLASSIFY_OPERATOR_NAME           "fpclassify"
#define ISFINITE_OPERATOR_NAME             "isfinite"
#define ISINF_OPERATOR_NAME                "isinf"
#define ISNAN_OPERATOR_NAME                "isnan"
#define ISNANL_OPERATOR_NAME               "isnanl"
#define ISNANF_OPERATOR_NAME               "isnanf"
#define ISNORMAL_OPERATOR_NAME             "isnormal"
#define SIGNBIT_OPERATOR_NAME              "signbit"
#define C_ACOS_OPERATOR_NAME               "acos"
#define ACOSF_OPERATOR_NAME                "acosf"
#define ACOSL_OPERATOR_NAME                "acosl"
#define C_ASIN_OPERATOR_NAME               "asin"
#define ASINF_OPERATOR_NAME                "asinf"
#define ASINL_OPERATOR_NAME                "asinl"
#define C_ATAN_OPERATOR_NAME               "atan"
#define ATANF_OPERATOR_NAME                "atanf"
#define ATANL_OPERATOR_NAME                "atanl"
#define C_ATAN2_OPERATOR_NAME              "atan2"
#define ATAN2F_OPERATOR_NAME               "atan2f"
#define ATAN2L_OPERATOR_NAME               "atan2l"
#define C_COS_OPERATOR_NAME                "cos"
#define COSF_OPERATOR_NAME                 "cosf"
#define COSL_OPERATOR_NAME                 "cosl"
#define C_SIN_OPERATOR_NAME                "sin"
#define SINF_OPERATOR_NAME                 "sinf"
#define SINL_OPERATOR_NAME                 "sinl"
#define C_TAN_OPERATOR_NAME                "tan"
#define TANF_OPERATOR_NAME                 "tanf"
#define TANL_OPERATOR_NAME                 "tanl"
#define C_ACOSH_OPERATOR_NAME              "acosh"
#define ACOSHF_OPERATOR_NAME               "acoshf"
#define ACOSHL_OPERATOR_NAME               "acoshl"
#define C_ASINH_OPERATOR_NAME              "asinh"
#define ASINHF_OPERATOR_NAME               "asinhf"
#define ASINHL_OPERATOR_NAME               "asinhl"
#define C_ATANH_OPERATOR_NAME              "atanh"
#define ATANHF_OPERATOR_NAME               "atanhf"
#define ATANHL_OPERATOR_NAME               "atanhl"
#define C_COSH_OPERATOR_NAME               "cosh"
#define COSHF_OPERATOR_NAME                "coshf"
#define COSHL_OPERATOR_NAME                "coshl"
#define C_SINH_OPERATOR_NAME               "sinh"
#define SINHF_OPERATOR_NAME                "sinhf"
#define SINHL_OPERATOR_NAME                "sinhl"
#define C_TANH_OPERATOR_NAME               "tanh"
#define TANHF_OPERATOR_NAME                "tanhf"
#define TANHL_OPERATOR_NAME                "tanhl"
#define C_EXP_OPERATOR_NAME                "exp"
#define EXPF_OPERATOR_NAME                 "expf"
#define EXPL_OPERATOR_NAME                 "expl"
#define EXP2_OPERATOR_NAME                 "exp2"
#define EXP2F_OPERATOR_NAME                "exp2f"
#define EXP2L_OPERATOR_NAME                "exp2l"
#define EXPM1_OPERATOR_NAME                "expm1"
#define EXPM1F_OPERATOR_NAME               "expm1f"
#define EXPM1L_OPERATOR_NAME               "expm1l"
#define FREXP_OPERATOR_NAME                "frexp"
#define ILOGB_OPERATOR_NAME                "ilogb"
#define ILOGBF_OPERATOR_NAME               "ilogbf"
#define ILOGBL_OPERATOR_NAME               "ilogbl"
#define LDEXP_OPERATOR_NAME                "ldexp"
#define LDEXPF_OPERATOR_NAME               "ldexpf"
#define LDEXPL_OPERATOR_NAME               "ldexpl"
#define C_LOG_OPERATOR_NAME                "log"
#define LOGF_OPERATOR_NAME                 "logf"
#define LOGL_OPERATOR_NAME                 "logl"
#define C_LOG10_OPERATOR_NAME              "log10"
#define LOG10F_OPERATOR_NAME               "log10f"
#define LOG10L_OPERATOR_NAME               "log10l"
#define LOG1P_OPERATOR_NAME                "log1p"
#define LOG1PF_OPERATOR_NAME               "log1pf"
#define LOG1PL_OPERATOR_NAME               "log1pl"
#define LOG2_OPERATOR_NAME                 "log2"
#define LOG2F_OPERATOR_NAME                "log2f"
#define LOG2L_OPERATOR_NAME                "log2l"
#define LOGB_OPERATOR_NAME                 "logb"
#define LOGBF_OPERATOR_NAME                "logbf"
#define LOGBL_OPERATOR_NAME                "logbl"
#define MODF_OPERATOR_NAME                 "modf"
#define SCALBN_OPERATOR_NAME               "scalbn"
#define SCALBNF_OPERATOR_NAME              "scalbnf"
#define SCALBNL_OPERATOR_NAME              "scalbnl"
#define SCALB_OPERATOR_NAME                "scalb"
#define SCALBLN_OPERATOR_NAME              "scalbln"
#define SCALBLNF_OPERATOR_NAME             "scalblnf"
#define SCALBLNL_OPERATOR_NAME             "scalblnl"
#define CBRT_OPERATOR_NAME                 "cbrt"
#define CBRTF_OPERATOR_NAME                "cbrtf"
#define CBRTL_OPERATOR_NAME                "cbrtl"
#define FABS_OPERATOR_NAME                 "fabs"
#define FABSF_OPERATOR_NAME                "fabsf"
#define FABSL_OPERATOR_NAME                "fabsl"
#define HYPOT_OPERATOR_NAME                "hypot"
#define HYPOTF_OPERATOR_NAME               "hypotf"
#define HYPOTL_OPERATOR_NAME               "hypotl"
#define POW_OPERATOR_NAME                  "pow"
#define POWF_OPERATOR_NAME                 "powf"
#define POWL_OPERATOR_NAME                 "powl"
#define C_SQRT_OPERATOR_NAME               "sqrt"
#define SQRTF_OPERATOR_NAME                "sqrtf"
#define SQRTL_OPERATOR_NAME                "sqrtl"
#define ERF_OPERATOR_NAME                  "erf"
#define ERFF_OPERATOR_NAME                 "erff"
#define ERFL_OPERATOR_NAME                 "erfl"
#define ERFC_OPERATOR_NAME                 "erfc"
#define ERFCF_OPERATOR_NAME                "erfcf"
#define ERFCL_OPERATOR_NAME                "erfcl"
#define GAMMA_OPERATOR_NAME                "gamma"
#define LGAMMA_OPERATOR_NAME               "lgamma"
#define LGAMMAF_OPERATOR_NAME              "lgammaf"
#define LGAMMAL_OPERATOR_NAME              "lgammal"
#define TGAMMA_OPERATOR_NAME               "tgamma"
#define TGAMMAF_OPERATOR_NAME              "tgammaf"
#define TGAMMAL_OPERATOR_NAME              "tgammal"
#define CEIL_OPERATOR_NAME                 "ceil"
#define CEILF_OPERATOR_NAME                "ceilf"
#define CEILL_OPERATOR_NAME                "ceill"
#define FLOOR_OPERATOR_NAME                "floor"
#define FLOORF_OPERATOR_NAME               "floorf"
#define FLOORL_OPERATOR_NAME               "floorl"
#define NEARBYINT_OPERATOR_NAME            "nearbyint"
#define NEARBYINTF_OPERATOR_NAME           "nearbyintf"
#define NEARBYINTL_OPERATOR_NAME           "nearbyintl"
#define RINT_OPERATOR_NAME                 "rint"
#define RINTF_OPERATOR_NAME                "rintf"
#define RINTL_OPERATOR_NAME                "rintl"
#define LRINT_OPERATOR_NAME                "lrint"
#define LRINTF_OPERATOR_NAME               "lrintf"
#define LRINTL_OPERATOR_NAME               "lrintl"
#define LLRINT_OPERATOR_NAME               "llrint"
#define LLRINTF_OPERATOR_NAME              "llrintf"
#define LLRINTL_OPERATOR_NAME              "llrintl"
#define ROUND_OPERATOR_NAME                "round"
#define ROUNDF_OPERATOR_NAME               "roundf"
#define ROUNDL_OPERATOR_NAME               "roundl"
#define LROUND_OPERATOR_NAME               "lround"
#define LROUNDF_OPERATOR_NAME              "lroundf"
#define LROUNDL_OPERATOR_NAME              "lroundl"
#define LLROUND_OPERATOR_NAME              "llround"
#define LLROUNDF_OPERATOR_NAME             "llroundf"
#define LLROUNDL_OPERATOR_NAME             "llroundl"
#define TRUNC_OPERATOR_NAME                "trunc"
#define TRUNCF_OPERATOR_NAME               "truncf"
#define TRUNCL_OPERATOR_NAME               "truncl"
#define FMOD_OPERATOR_NAME                 "fmod"
#define FMODF_OPERATOR_NAME                "fmodf"
#define FMODL_OPERATOR_NAME                "fmodl"
#define REMAINDER_OPERATOR_NAME            "remainder"
#define REMAINDERF_OPERATOR_NAME           "remainderf"
#define REMAINDERL_OPERATOR_NAME           "remainderl"
#define COPYSIGN_OPERATOR_NAME             "copysign"
#define COPYSIGNF_OPERATOR_NAME            "copysignf"
#define COPYSIGNL_OPERATOR_NAME            "copysignl"
#define NAN_OPERATOR_NAME                  "nan"
#define NANF_OPERATOR_NAME                 "nanf"
#define NANL_OPERATOR_NAME                 "nanl"
#define NEXTAFTER_OPERATOR_NAME            "nextafter"
#define NEXTAFTERF_OPERATOR_NAME           "nextafterf"
#define NEXTAFTERL_OPERATOR_NAME           "nextafterl"
#define NEXTTOWARD_OPERATOR_NAME           "nexttoward"
#define NEXTTOWARDF_OPERATOR_NAME          "nexttowardf"
#define NEXTTOWARDL_OPERATOR_NAME          "nexttowardl"
#define FDIM_OPERATOR_NAME                 "fdim"
#define FDIMF_OPERATOR_NAME                "fdimf"
#define FDIML_OPERATOR_NAME                "fdiml"
#define FMAX_OPERATOR_NAME                 "fmax"
#define FMAXF_OPERATOR_NAME                "fmaxf"
#define FMAXL_OPERATOR_NAME                "fmaxl"
#define FMIN_OPERATOR_NAME                 "fmin"
#define FMINF_OPERATOR_NAME                "fminf"
#define FMINL_OPERATOR_NAME                "fminl"
#define FMA_OPERATOR_NAME                  "fma"
#define FMAF_OPERATOR_NAME                 "fmaf"
#define FMAL_OPERATOR_NAME                 "fmal"
#define ISGREATER_OPERATOR_NAME            "isgreater"
#define ISGREATEREQUAL_OPERATOR_NAME       "isgreaterequal"
#define ISLESS_OPERATOR_NAME               "isless"
#define ISLESSEQUAL_OPERATOR_NAME          "islessequal"
#define ISLESSGREATER_OPERATOR_NAME        "islessgreater"
#define ISUNORDERED_OPERATOR_NAME          "isunordered"


/* signal.h */
#define SIGNAL_OPERATOR_NAME               "signal"
#define RAISE_FUNCTION_NAME                "raise"


/* vararg stuff. va_args is a special construct because its second
   parameter is a type, not an expression. */
#define BUILTIN_VA_END                 "__builtin_va_end"
#define BUILTIN_VA_START               "__builtin_va_start"
#define BUILTIN_VA_COPY                "__builtin_va_copy"


/*io functions: C library and system IO. Amira Mensi*/

/* unistd.h */

#define LSEEK_FUNCTION_NAME             "lseek"
#define LSEEK64_FUNCTION_NAME           "lseekg4"
#define C_CLOSE_FUNCTION_NAME           "close"
#define C_READ_FUNCTION_NAME            "read"
#define C_WRITE_FUNCTION_NAME           "write"
#define PREAD_FUNCTION_NAME             "pread"
#define PWRITE_FUNCTION_NAME            "pwrite"
#define PREAD64_FUNCTION_NAME           "pread64"
#define PIPE_FUNCTION_NAME              "pipe"
#define PIPE2_FUNCTION_NAME             "pipe2"
#define SLEEP_FUNCTION_NAME             "sleep"
#define UALARM_FUNCTION_NAME            "ualarm"
#define USLEEP_FUNCTION_NAME            "usleep"
#define C_PAUSE_FUNCTION_NAME           "pause"
#define CHOWN_FUNCTION_NAME             "chown"
#define FCHOWN_FUNCTION_NAME            "fchown"
#define LCHOWN_FUNCTION_NAME            "lchown"
#define FCHOWNAT_FUNCTION_NAME          "fchownat"
#define CHDIR_FUNCTION_NAME             "chdir"
#define FCHDIR_FUNCTION_NAME            "fchdir"
#define GETCWD_FUNCTION_NAME            "getcwd"
#define GET_CURRENT_DIR_NAME_FUNCTION_NAME "get_current_dir_name"
#define GETWD_FUNCTION_NAME             "getwd"
#define DUP_FUNCTION_NAME               "dup"
#define DUP2_FUNCTION_NAME              "dup2"
#define DUP3_FUNCTION_NAME              "dup3"
#define EXECVE_FUNCTION_NAME            "execve"
#define FEXECVE_FUNCTION_NAME           "fexecve"
#define EXECV_FUNCTION_NAME             "execv"
#define EXECLE_FUNCTION_NAME            "execle"
#define EXECL_FUNCTION_NAME             "execl"
#define EXECVP_FUNCTION_NAME            "execvp"
#define EXECLP_FUNCTION_NAME            "execlp"
#define EXECVPE_FUNCTION_NAME           "execvpe"
#define NICE_FUNCTION_NAME              "nice"
#define _EXIT_FUNCTION_NAME             "_exit"
#define PATHCONF_FUNCTION_NAME          "pathconf"
#define FPATHCONF_FUNCTION_NAME         "fpathconf"
#define SYSCONF_FUNCTION_NAME           "sysconf"
#define CONFSTR_FUNCTION_NAME           "constrf"
#define GETPID_FUNCTION_NAME            "getpid"
#define GETPPID_FUNCTION_NAME           "getppid"
#define GETPGRP_FUNCTION_NAME           "getpgrp"
#define __GETPGID_FUNCTION_NAME         "__getpgid"
#define GETPGID_FUNCTION_NAME           "getpgid"
#define SETPGID_FUNCTION_NAME           "setpgid"
#define SETPGRP_FUNCTION_NAME           "setpgrp"
#define SETSID_FUNCTION_NAME            "setsid"
#define GETSID_FUNCTION_NAME            "getsid"
#define GETUID_FUNCTION_NAME            "getuid"
#define GETEUID_FUNCTION_NAME           "geteuid"
#define GETGID_FUNCTION_NAME            "getgid"
#define GETEGID_FUNCTION_NAME           "getegid"
#define GETPGROUPS_FUNCTION_NAME        "getgroups"
#define GROUP_MEMBER_FUNCTION_NAME      "group_member"
#define SETUID_FUNCTION_NAME            "setuid"
#define SETREUID_FUNCTION_NAME          "setreuid"
#define SETEUID_FUNCTION_NAME           "seteuid"
#define SETGID_FUNCTION_NAME            "setgid"
#define SETREGID_FUNCTION_NAME          "setregid"
#define SETEGID_FUNCTION_NAME           "setegid"
#define GETRESUID_FUNCTION_NAME         "getresuid"
#define GETRESGID_FUNCTION_NAME         "getresgid"
#define SETRESUID_FUNCTION_NAME         "setresuid"
#define SETRESGID_FUNCTION_NAME         "setresgid"
#define FORK_FUNCTION_NAME              "fork"
#define VFORK_FUNCTION_NAME             "vfork"
#define TTYNAME_FUNCTION_NAME           "ttyname"
#define TTYNAME_R_FUNCTION_NAME         "ttyname_r"
#define ISATTY_FUNCTION_NAME            "isatty"
#define TTYSLOT_FUNCTION_NAME           "ttyslot"
#define LINK_FUNCTION_NAME              "link"
#define LINKAT_FUNCTION_NAME            "linkat"
#define SYMLINK_FUNCTION_NAME           "symlink"
#define READLINK_FUNCTION_NAME          "readlink"
#define SYMLINKAT_FUNCTION_NAME         "symlinkar"
#define READLINKAT_FUNCTION_NAME        "readlinkat"
#define UNLINK_FUNCTION_NAME            "unlink"
#define UNLINKAT_FUNCTION_NAME          "unlinkat"
#define RMDIR_FUNCTION_NAME             "rmdir"
#define TCGETPGRP_FUNCTION_NAME         "tcgetpgrp"
#define TCSETPGRP_FUNCTION_NAME         "tcsetpgrp"
#define GETLOGIN_FUNCTION_NAME          "getlogin"
#define GETLOGIN_R_FUNCTION_NAME        "getlogin_r"
#define SETLOGIN_FUNCTION_NAME          "setlogin"
#define GETHOSTNAME_FUNCTION_NAME       "gethostname"
#define SETHOSTNAME_FUNCTION_NAME       "sethostname"
#define SETHOSTID_FUNCTION_NAME         "sethostid"
#define GETDOMAINNAME_FUNCTION_NAME     "getdomainname"
#define SETDOMAINNAME_FUNCTION_NAME     "setdomainname"
#define VHANGUP_FUNCTION_NAME           "vhangup"
#define REVOKE_FUNCTION_NAME            "revoke"
#define PROFIL_FUNCTION_NAME            "profil"
#define ACCT_FUNCTION_NAME              "acct"
#define GETUSERSHELL_FUNCTION_NAME      "getusershell"
#define ENDUSERSHELL_FUNCTION_NAME      "endusershell"
#define SETUSERSHELL_FUNCTION_NAME      "setusershell"
#define DAEMON_FUNCTION_NAME            "daemon"
#define CHROOT_FUNCTION_NAME            "chroot"
#define GETPASS_FUNCTION_NAME           "getpass"
#define FSYNC_FUNCTION_NAME             "fsync"
#define SYNCFS_FUNCTION_NAME            "syncfs"
#define GETHOSTID_FUNCTION_NAME         "gethostid"
#define GETPAGESIZE_FUNCTION_NAME       "getpagesize"
#define GETDTABLESIZE_FUNCTION_NAME     "getdtablesize"
#define TRUNCATE_FUNCTION_NAME          "truncate"
#define TRUNCATE64_FUNCTION_NAME        "truncate64"
#define FTRUNCATE_FUNCTION_NAME         "ftruncate"
#define FTRUNCATE64_FUNCTION_NAME       "ftruncate64"
#define BRK_FUNCTION_NAME               "brk"
#define SBRK_FUNCTION_NAME              "sbrk"
#define SYSCALL_FUNCTION_NAME           "syscall"
#define LOCKF_FUNCTION_NAME             "lockf"
#define LOCKF64_FUNCTION_NAME           "lockf64"
#define FDATASYNC_FUNCTION_NAME         "fdatasync"
#define CRYPT_FUNCTION_NAME             "crypt"
#define ENCRYPT_FUNCTION_NAME           "encrypt"
#define SWAB_FUNCTION_NAME              "swab"
#define CTERMID_FUNCTION_NAME           "ctermid"
/* Not found in unistd.h. Requires sys/types.h sys/stat.h and fcntl.h.
 * The man -S 2 page indicates it is overloaded with two or three
 * arguments.
 */
#define C_OPEN_FUNCTION_NAME            "open"

/*#include<stdio.h> */

#define PRINTF_FUNCTION_NAME            "printf"
#define FPRINTF_FUNCTION_NAME           "fprintf"
#define SCANF_FUNCTION_NAME             "scanf"
#define ISOC99_SCANF_FUNCTION_NAME      "__isoc99_scanf"
#define ISOC99_SCANF_USER_FUNCTION_NAME "scanf"
#define FSCANF_FUNCTION_NAME            "fscanf"
#define ISOC99_FSCANF_FUNCTION_NAME     "__isoc99_fscanf"
#define ISOC99_FSCANF_USER_FUNCTION_NAME "fscanf"
#define PUTS_FUNCTION_NAME              "puts"
#define GETS_FUNCTION_NAME              "gets"
#define FPUTS_FUNCTION_NAME             "fputs"
#define FGETS_FUNCTION_NAME             "fgets"
#define FPUTC_FUNCTION_NAME             "fputc"
#define FGETC_FUNCTION_NAME             "fgetc"
#define FOPEN_FUNCTION_NAME             "fopen"
#define FDOPEN_FUNCTION_NAME            "fdopen"
#define FREOPEN_FUNCTION_NAME           "freopen"
#define FCLOSE_FUNCTION_NAME            "fclose"
#define SNPRINTF_FUNCTION_NAME          "snprintf"
#define SSCANF_FUNCTION_NAME            "sscanf"
#define ISOC99_SSCANF_FUNCTION_NAME     "__isoc99_sscanf"
#define ISOC99_SSCANF_USER_FUNCTION_NAME "sscanf"
#define VFPRINTF_FUNCTION_NAME          "vfprintf"
#define VFSCANF_FUNCTION_NAME           "vfscanf"
#define ISOC99_VFSCANF_FUNCTION_NAME    "__isoc99_vfscanf"
#define ISOC99_VFSCANF_USER_FUNCTION_NAME "vfscanf"
#define VPRINTF_FUNCTION_NAME           "vprintf"
#define VSCANF_FUNCTION_NAME            "vscanf"
#define ISOC99_VSCANF_FUNCTION_NAME    "__isoc99_vscanf"
#define ISOC99_VSCANF_USER_FUNCTION_NAME "vscanf"
#define VSSCANF_FUNCTION_NAME           "vsscanf"
#define ISOC99_VSSCANF_FUNCTION_NAME     "__isoc99_vsscanf"
#define ISOC99_VSSCANF_USER_FUNCTION_NAME "vsscanf"
#define VSNPRINTF_FUNCTION_NAME         "vsnprintf"
#define VSPRINTF_FUNCTION_NAME          "vsprintf"
#define SPRINTF_FUNCTION_NAME           "sprintf"
#define GETC_FUNCTION_NAME              "getc"
#define _IO_GETC_FUNCTION_NAME          "_IO_getc" /* libio.h */
#define GETCHAR_FUNCTION_NAME           "getchar"
#define PUTC_FUNCTION_NAME              "putc"
#define _IO_PUTC_FUNCTION_NAME          "_IO_putc" /* libio.h */
#define PUTCHAR_FUNCTION_NAME           "putchar"
#define UNGETC_FUNCTION_NAME            "ungetc"
#define FREAD_FUNCTION_NAME             "fread"
#define FWRITE_FUNCTION_NAME            "fwrite"
#define FGETPOS_FUNCTION_NAME           "fgetpos"
#define FSEEK_FUNCTION_NAME             "fseek"
#define FSETPOS_FUNCTION_NAME           "fsetpos"
#define FTELL_FUNCTION_NAME             "ftell"
#define C_REWIND_FUNCTION_NAME          "rewind"
#define CLEARERR_FUNCTION_NAME          "clearerr"
#define FEOF_FUNCTION_NAME              "feof"
#define FERROR_FUNCTION_NAME            "ferror"
#define FILENO_FUNCTION_NAME            "fileno"
#define PERROR_FUNCTION_NAME            "perror"
// #define WRITE_SYSTEM_FUNCTION_NAME      "write"
// #define READ_SYSTEM_FUNCTION_NAME       "read"
#define REMOVE_FUNCTION_NAME            "remove"
#define RENAME_FUNCTION_NAME            "rename"
#define TMPFILE_FUNCTION_NAME           "tmpfile"
#define TMPNAM_FUNCTION_NAME            "tmpnam"
#define FFLUSH_FUNCTION_NAME            "fflush"
#define FREOPEN_FUNCTION_NAME           "freopen"
#define SETBUF_FUNCTION_NAME            "setbuf"
#define SETVBUF_FUNCTION_NAME           "setvbuf"
#define __FILBUF_FUNCTION_NAME          "__filbuf"
#define __FILSBUF_FUNCTION_NAME         "__flsbuf"
#define SETBUFFER_FUNCTION_NAME         "setbuffer"
#define SETLINEBUF_FUNCTION_NAME        "setlinebuf"
#define FDOPEN_FUNCTION_NAME            "fdopen"
#define CTERMID_FUNCTION_NAME           "ctermid"
#define FILENO_FUNCTION_NAME            "fileno"
#define POPEN_FUNCTION_NAME             "popen"
#define CUSERID_FUNCTION_NAME           "cuserid"
#define TEMPNAM_FUNCTION_NAME           "tempnam"
#define GETW_FUNCTION_NAME              "getw"
#define PUTW_FUNCTION_NAME              "putw"
#define PCLOSE_FUNCTION_NAME            "pclose"
#define FSEEKO_FUNCTION_NAME            "fseeko"
#define FTELLO_FUNCTION_NAME            "ftello"
#define FOPEN64_FUNCTION_NAME           "fopen64"
#define FREOPEN64_FUNCTION_NAME         "freopen64"
#define TMPFILE64_FUNCTION_NAME         "tmpfile64"
#define FGETPOS64_FUNCTION_NAME         "fgetpos64"
#define FSETPOS64_FUNCTION_NAME         "fsetpos64"
#define FSEEKO64_FUNCTION_NAME          "fseeko64"
#define FTELLO64_FUNCTION_NAME          "ftello64"
#define EXITHANDLE_FUNCTION_NAME        "exithandle"


/* random functions of <stdlib.h> */


#define ATOF_FUNCTION_NAME              "atof"
#define ATOI_FUNCTION_NAME              "atoi"
#define ATOL_FUNCTION_NAME              "atol"
#define ATOLL_FUNCTION_NAME             "atoll"
#define STRTOD_FUNCTION_NAME            "strtod"
#define STRTOF_FUNCTION_NAME            "strtof"
#define STRTOLD_FUNCTION_NAME           "strtold"
#define STRTOL_FUNCTION_NAME            "strtol"
#define STRTOLL_FUNCTION_NAME           "strtoll"
#define STRTOUL_FUNCTION_NAME           "strtoul"
#define STRTOULL_FUNCTION_NAME          "strtoull"
#define RAND_FUNCTION_NAME              "rand"
#define SRAND_FUNCTION_NAME             "srand"
#define CALLOC_FUNCTION_NAME            "calloc"
#define FREE_FUNCTION_NAME              "free"
#define MALLOC_FUNCTION_NAME            "malloc"
#define REALLOC_FUNCTION_NAME           "realloc"
#define ALLOCA_FUNCTION_NAME            "alloca"
#define ABORT_FUNCTION_NAME             "abort"
#define ATEXIT_FUNCTION_NAME            "atexit"
#define EXIT_FUNCTION_NAME              "exit"
#define _EXIT_FUNCTION_NAME             "_exit"
#define GETENV_FUNCTION_NAME            "getenv"
#define SYSTEM_FUNCTION_NAME            "system"
#define BSEARCH_FUNCTION_NAME           "bsearch"
#define QSORT_FUNCTION_NAME             "qsort"
#define C_ABS_FUNCTION_NAME             "abs"
#define LABS_FUNCTION_NAME              "labs"
#define LLABS_FUNCTION_NAME             "llabs"
#define DIV_FUNCTION_NAME               "div"
#define LDIV_FUNCTION_NAME              "ldiv"
#define LLDIV_FUNCTION_NAME             "lldiv"
#define MBLEN_FUNCTION_NAME             "mblen"
#define MBTOWC_FUNCTION_NAME            "mbtowc"
#define WCTOMB_FUNCTION_NAME            "wctomb"
#define MBSTOWCS_FUNCTION_NAME          "mbstowcs"
#define WCSTOMBS_FUNCTION_NAME          "wcstombs"



/* include <string.h> */

#define MEMCPY_FUNCTION_NAME            "memcpy"
#define MEMMOVE_FUNCTION_NAME           "memmove"
#define STRCPY_FUNCTION_NAME            "strcpy"
#define STRDUP_FUNCTION_NAME            "strdup"
#define STRNCPY_FUNCTION_NAME           "strncpy"
#define STRCAT_FUNCTION_NAME            "strcat"
#define STRNCAT_FUNCTION_NAME           "strncat"
#define MEMCMP_FUNCTION_NAME            "memcmp"
#define STRCMP_FUNCTION_NAME            "strcmp"
#define STRCOLL_FUNCTION_NAME           "strcoll"
#define STRNCMP_FUNCTION_NAME           "strncmp"
#define STRXFRM_FUNCTION_NAME           "strxfrm"
#define MEMCHR_FUNCTION_NAME            "memchr"
#define STRCHR_FUNCTION_NAME            "strchr"
#define STRCSPN_FUNCTION_NAME           "strcspn"
#define STRPBRK_FUNCTION_NAME           "strbprk"
#define STRRCHR_FUNCTION_NAME           "strrchr"
#define STRSPN_FUNCTION_NAME            "strspn"
#define STRSTR_FUNCTION_NAME            "strstr"
#define STRTOK_FUNCTION_NAME            "strtok"
#define MEMSET_FUNCTION_NAME            "memset"
//#define FOPEN_FUNCTION_NAME           "fopen"
#define STRERROR_FUNCTION_NAME          "strerror"
#define STRERROR_R_FUNCTION_NAME        "strerror_r"
#define STRLEN_FUNCTION_NAME            "strlen"


/*#include<time.h> */
#define TIME_FUNCTION_NAME              "time"
#define LOCALTIME_FUNCTION_NAME         "localtime"
#define DIFFTIME_FUNCTION_NAME          "difftime"
#define NANOSLEEP_FUNCTION_NAME         "nanosleep"


/* #include <wchar.h> */
#define FWPRINTF_FUNCTION_NAME          "fwprintf"
#define FWSCANF_FUNCTION_NAME           "fwscanf"
#define SWPRINTF_FUNCTION_NAME          "swprintf"
#define SWSCANF_FUNCTION_NAME           "swscanf"
#define VFWPRINTF_FUNCTION_NAME         "vfwprintf"
#define VFWSCANF_FUNCTION_NAME          "vfwscanf"
#define VSWPRINTF_FUNCTION_NAME         "vswprintf"
#define VSWSCANF_FUNCTION_NAME          "vswscanf"
#define VWPRINTF_FUNCTION_NAME          "vwprintf"
#define VWSCANF_FUNCTION_NAME           "vwscanf"
#define WPRINTF_FUNCTION_NAME           "wprintf"
#define WSCANF_FUNCTION_NAME            "wscanf"
#define FGETWC_FUNCTION_NAME            "fgetwc"
#define FGETWS_FUNCTION_NAME            "fgetws"
#define FPUTWC_FUNCTION_NAME            "fputwc"
#define FPUTWS_FUNCTION_NAME            "fputws"
#define FWIDE_FUNCTION_NAME             "fwide"
#define GETWC_FUNCTION_NAME             "getwc"
#define GETWCHAR_FUNCTION_NAME          "getwchar"
#define PUTWC_FUNCTION_NAME             "putwc"
#define PUTWCHAR_FUNCTION_NAME          "putwchar"
#define UNGETWC_FUNCTION_NAME           "ungetwc"
#define WCSTOD_FUNCTION_NAME            "wcstod"
#define WCSTOF_FUNCTION_NAME            "wcstof"
#define WCSTOLD_FUNCTION_NAME           "wcstold"
#define WCSTOL_FUNCTION_NAME            "wcstol"
#define WCSTOLL_FUNCTION_NAME           "wcstoll"
#define WCSTOUL_FUNCTION_NAME           "wcstoul"
#define WCSTOULL_FUNCTION_NAME          "wcstoull"
#define WCSCPY_FUNCTION_NAME            "wcscpy"
#define WCSNCPY_FUNCTION_NAME           "wcsncpy"
#define WMEMCPY_FUNCTION_NAME           "wmemcpy"
#define WMEMMOVE_FUNCTION_NAME          "wmemmove"
#define WCSCAT_FUNCTION_NAME            "wcscat"
#define WCSNCAT_FUNCTION_NAME           "wcsncat"
#define WCSCMP_FUNCTION_NAME            "wcscmp"
#define WCSCOLL_FUNCTION_NAME           "wcscoll"
#define WCSNCMP_FUNCTION_NAME           "wcsncmp"
#define WCSXFRM_FUNCTION_NAME           "wcsxfrm"
#define WMEMCMP_FUNCTION_NAME           "wmemcmp"
#define WCSCHR_FUNCTION_NAME            "wcschr"
#define WCSCSPN_FUNCTION_NAME           "wcscspn"
#define WCSPBRK_FUNCTION_NAME           "wcspbrk"
#define WCSRCHR_FUNCTION_NAME           "wcsrchr"
#define WCSSPN_FUNCTION_NAME            "wcsspn"
#define WCSSTR_FUNCTION_NAME            "wcsstr"
#define WCSTOK_FUNCTION_NAME            "wcstok"
#define WMEMCHR_FUNCTION_NAME           "wmemchr"
#define WCSLEN_FUNCTION_NAME            "wcslen"
#define WMEMSET_FUNCTION_NAME           "wmemset"
#define WCSFTIME_FUNCTION_NAME          "wcsftime"
#define BTOWC_FUNCTION_NAME             "btowc"
#define WCTOB_FUNCTION_NAME             "wctob"
#define MBSINIT_FUNCTION_NAME           "mbsinit"
#define MBRLEN_FUNCTION_NAME            "mbrlen"
#define MBRTOWC_FUNCTION_NAME           "mbrtowc"
#define WCRTOMB_FUNCTION_NAME           "wcrtomb"
#define MBSRTOWCS_FUNCTION_NAME         "mbsrtowcs"
#define WCSRTOMBS_FUNCTION_NAME         "wcsrtombs"


/* #include <wctype.h> */

#define ISWALNUM_OPERATOR_NAME           "iswalnum"
#define ISWALPHA_OPERATOR_NAME           "iswalpha"
#define ISWBLANK_OPERATOR_NAME           "iswblank"
#define ISWCNTRL_OPERATOR_NAME           "iswcntrl"
#define ISWDIGIT_OPERATOR_NAME           "iswdigit"
#define ISWGRAPH_OPERATOR_NAME           "iswgraph"
#define ISWLOWER_OPERATOR_NAME           "iswlower"
#define ISWPRINT_OPERATOR_NAME           "iswprint"
#define ISWPUNCT_OPERATOR_NAME           "iswpunct"
#define ISWSPACE_OPERATOR_NAME           "iswspace"
#define ISWUPPER_OPERATOR_NAME           "iswupper"
#define ISWXDIGIT_OPERATOR_NAME          "iswxdigit"
#define ISWCTYPE_OPERATOR_NAME           "iswctype"
#define WCTYPE_OPERATOR_NAME             "wctype"
#define TOWLOWER_OPERATOR_NAME           "towlower"
#define TOWUPPER_OPERATOR_NAME           "towupper"
#define TOWCTRANS_OPERATOR_NAME          "towctrans"
#define WCTRANS_OPERATOR_NAME            "wctrans"


/* #include <fcntl.h>*/

#define FCNTL_FUNCTION_NAME             "fcntl"
#define CREAT_FUNCTION_NAME             "creat"
#define DIRECTIO_FUNCTION_NAME          "directio"
#define OPEN64_FUNCTION_NAME            "open64"
#define CREAT64_FUNCTION_NAME           "creat64"

/* fcntl is declared with fcntl.h */
#define FSYNC_FUNCTION_NAME             "fsync"
#define FDATASYNC_FUNCTION_NAME         "fdatasync"
#define IOCTL_FUNCTION_NAME             "ioctl"   // sys/ioctl.h
#define SELECT_FUNCTION_NAME            "select"  // sys/select.h
#define PSELECT_FUNCTION_NAME           "pselect" // sys/select.h
#define STAT_FUNCTION_NAME              "stat"    // sys/stat.h
#define FSTAT_FUNCTION_NAME             "fstat"   // sys/stat.h
#define LSTAT_FUNCTION_NAME             "lstat"   // sys/stat.h





#define J0_OPERATOR_NAME "j0"
#define J1_OPERATOR_NAME "j1"
#define JN_OPERATOR_NAME "jn"
#define Y0_OPERATOR_NAME "y0"
#define Y1_OPERATOR_NAME "y1"
#define YN_OPERATOR_NAME "yn"

#define NEXTAFTER_OPERATOR_NAME "nextafter"
#define REMAINDER_OPERATOR_NAME "remainder"


#define MATHERR_OPERATOR_NAME "matherr"
#define SIGNIFICAND_OPERATOR_NAME "significand"


#define MODFF_OPERATOR_NAME "modff"
#define SIGFPE_OPERATOR_NAME "sigfpe"
#define SINGLE_TO_DECIMAL_OPERATOR_NAME "single_to_decimal"
#define DOUBLE_TO_DECIMAL_OPERATOR_NAME "double_to_decimal"
#define EXTENDED_TO_DECIMAL_OPERATOR_NAME "extended_to_decimal"
#define QUADRUPLE_TO_DECIMAL_OPERATOR_NAME "quadruple_to_decimal"
#define DECIMAL_TO_SINGLE_OPERATOR_NAME "decimal_to_single"
#define DECIMAL_TO_DOUBLE_OPERATOR_NAME "decimal_to_double"
#define DECIMAL_TO_EXTENDED_OPERATOR_NAME "decimal_to_extended"
#define DECIMAL_TO_QUADRUPLE_OPERATOR_NAME "decimal_to_quadruple"
#define STRING_TO_DECIMAL_OPERATOR_NAME "string_to_decimal"
#define FUNC_TO_DECIMAL_OPERATOR_NAME "func_to_decimal"
#define FILE_TO_DECIMAL_OPERATOR_NAME "file_to_decimal"
#define SECONVERT_OPERATOR_NAME "seconvert"
#define SFCONVERT_OPERATOR_NAME "sfconvert"
#define SGCONVERT_OPERATOR_NAME "sgconvert"
#define ECONVERT_OPERATOR_NAME "econvert"
#define FCONVERT_OPERATOR_NAME "fconvert"
#define GCONVERT_OPERATOR_NAME "gconvert"
#define QECONVERT_OPERATOR_NAME "qeconvert"
#define QFCONVERT_OPERATOR_NAME "qfconvert"
#define QGCONVERT_OPERATOR_NAME "qgconvert"

#define CLOCK_FUNCTION_NAME            "clock"
#define SECOND_FUNCTION_NAME            "SECOND" //gfortran extension
#define CLOCK_GETTIME_FUNCTION_NAME    "clock_gettime"
#define GETTIMEOFDAY_FUNCTION_NAME    "gettimeofday"

/* netdb.h */
#define __H_ERRNO_LOCATION_OPERATOR_NAME "__h_erno_location"


/* These operators are used within the optimize transformation in
   order to manipulate operators such as n-ary add and multiply or
   multiply-add operators ( JZ - sept 98)
 */
#define EOLE_FMA_OPERATOR_NAME          "EOLE-FMA-OP"
#define EOLE_FMS_OPERATOR_NAME          "EOLE-FMS-OP"
#define EOLE_PROD_OPERATOR_NAME         "EOLE-PROD-OP"
#define EOLE_SUM_OPERATOR_NAME          "EOLE-SUM-OP"

/* Integer Multiply Add and Sub, FC 27/10/2005 for FI
 */
#define IMA_OPERATOR_NAME                               "IMA-OP"
#define IMS_OPERATOR_NAME                               "IMS-OP"

/*****************************************************************************************/

/* moved from ricedg-local.h */
#define LOOP_COUNTER_MODULE_NAME        "LOOP-COUNTER"
#define DI_VAR_MODULE_NAME              "DI-VAR"

/* special pips intrinsics with global effects */
#define PIPS_MEMORY_BARRIER_OPERATOR_NAME "__pips_memory_barrier"
#define PIPS_IO_BARRIER_OPERATOR_NAME "__pips_io_barrier"

/* macros */

/* FI: entity_local_name() should be sufficient for these comparisons */
#define entity_an_operator_p(e,name) \
  (same_string_p(global_name_to_user_name(entity_name(e)), name##_OPERATOR_NAME))
#define entity_a_function_p(e,name) \
  (same_string_p(global_name_to_user_name(entity_name(e)), name##_FUNCTION_NAME))
#define entity_a_special_entity_p(e,name) \
  (same_string_p(global_name_to_user_name(entity_name(e)), name))

#define ENTITY_CONVERSION_P(e,name) \
  (strcmp(entity_local_name(e), name##_GENERIC_CONVERSION_NAME)==0)
#define ENTITY_CONVERSION_CMPLX_P(e) ENTITY_CONVERSION_P(e, CMPLX)
#define ENTITY_CONVERSION_DCMPLX_P(e) ENTITY_CONVERSION_P(e, DCMPLX)

#define ENTITY_CONTINUE_P(e) entity_a_function_p(e, CONTINUE)
#define ENTITY_STOP_P(e) entity_a_function_p(e, STOP)
#define ENTITY_RETURN_P(e) entity_a_function_p(e, RETURN)
#define ENTITY_C_RETURN_P(e) entity_a_function_p(e, C_RETURN)

#define ENTITY_ASSIGN_P(e) entity_an_operator_p(e, ASSIGN)
#define ENTITY_POST_INCREMENT_P(e) entity_an_operator_p(e, POST_INCREMENT)
#define ENTITY_POST_DECREMENT_P(e) entity_an_operator_p(e, POST_DECREMENT)
#define ENTITY_PRE_INCREMENT_P(e) entity_an_operator_p(e, PRE_INCREMENT)
#define ENTITY_PRE_DECREMENT_P(e) entity_an_operator_p(e, PRE_DECREMENT)
#define ENTITY_MULTIPLY_UPDATE_P(e) entity_an_operator_p(e, MULTIPLY_UPDATE)
#define ENTITY_DIVIDE_UPDATE_P(e) entity_an_operator_p(e, DIVIDE_UPDATE)
#define ENTITY_MODULO_UPDATE_P(e) entity_an_operator_p(e, MODULO_UPDATE)
#define ENTITY_PLUS_UPDATE_P(e) entity_an_operator_p(e, PLUS_UPDATE)
#define ENTITY_MINUS_UPDATE_P(e) entity_an_operator_p(e, MINUS_UPDATE)
#define ENTITY_LEFT_SHIFT_UPDATE_P(e) entity_an_operator_p(e, LEFT_SHIFT_UPDATE)
#define ENTITY_RIGHT_SHIFT_UPDATE_P(e) entity_an_operator_p(e, RIGHT_SHIFT_UPDATE)
#define ENTITY_BITWISE_AND_UPDATE_P(e) entity_an_operator_p(e, BITWISE_AND_UPDATE)
#define ENTITY_BITWISE_XOR_UPDATE_P(e) entity_an_operator_p(e, BITWISE_XOR_UPDATE)
#define ENTITY_BITWISE_OR_UPDATE_P(e) entity_an_operator_p(e, BITWISE_OR_UPDATE)
#define ENTITY_COMMA_P(e) entity_an_operator_p(e, COMMA)
#define ENTITY_ADDRESS_OF_P(e) entity_an_operator_p(e, ADDRESS_OF)
#define ENTITY_CONDITIONAL_P(e) entity_an_operator_p(e, CONDITIONAL)

#define ENTITY_PLUS_P(e) entity_an_operator_p(e, PLUS)
#define ENTITY_PLUS_C_P(e) entity_an_operator_p(e, PLUS_C)
#define ENTITY_MINUS_P(e) entity_an_operator_p(e, MINUS)
#define ENTITY_MINUS_C_P(e) entity_an_operator_p(e, MINUS_C)
#define ENTITY_UNARY_MINUS_P(e) entity_an_operator_p(e, UNARY_MINUS)
#define ENTITY_UNARY_PLUS_P(e) entity_an_operator_p(e, UNARY_PLUS)
#define ENTITY_MULTIPLY_P(e) entity_an_operator_p(e, MULTIPLY)
#define ENTITY_MODULO_P(e) entity_an_operator_p(e, MODULO)
#define ENTITY_C_MODULO_P(e) entity_an_operator_p(e, C_MODULO)
#define ENTITY_POWER_P(e) entity_an_operator_p(e, POWER)
#define ENTITY_DIVIDE_P(e) entity_an_operator_p(e, DIVIDE)

#define ENTITY_MIN_P(e) entity_an_operator_p(e, MIN)
#define ENTITY_C_MIN_P(e) entity_an_operator_p(e,PIPS_C_MIN)
#define ENTITY_MAX_P(e) entity_an_operator_p(e, MAX)
#define ENTITY_C_MAX_P(e) entity_an_operator_p(e,PIPS_C_MAX)
#define ENTITY_MIN0_P(e) entity_an_operator_p(e, MIN0)
#define ENTITY_MAX0_P(e) entity_an_operator_p(e, MAX0)
#define ENTITY_AMIN1_P(e) entity_an_operator_p(e, AMIN1)
#define ENTITY_AMAX1_P(e) entity_an_operator_p(e, AMAX1)
#define ENTITY_DMIN1_P(e) entity_an_operator_p(e, DMIN1)
#define ENTITY_DMAX1_P(e) entity_an_operator_p(e, DMAX1)
#define ENTITY_MIN_OR_MAX_P(e) (ENTITY_MIN_P(e) || ENTITY_MAX_P(e) )

#define ENTITY_ABS_P(e) entity_an_operator_p(e, ABS)
#define ENTITY_IABS_P(e) entity_an_operator_p(e, IABS)
#define ENTITY_DABS_P(e) entity_an_operator_p(e, DABS)
#define ENTITY_CABS_P(e) entity_an_operator_p(e, CABS)
//abs in stdlib.h C89
#define ENTITY_C_ABS_P(e) entity_a_function_p(e, C_ABS)
#define ENTITY_LABS_P(e) entity_a_function_p(e, LABS)
#define ENTITY_LLABS_P(e) entity_a_function_p(e, LLABS)     //C99
//abs in inttypes.h C99
#define ENTITY_IMAXABS_P(e) entity_a_function_p(e, IMAXABS)
//abs in math.h C99
#define ENTITY_FABS_P(e) entity_an_operator_p(e, FABS)
#define ENTITY_FABSF_P(e) entity_an_operator_p(e, FABSF)
#define ENTITY_FABSL_P(e) entity_an_operator_p(e, FABSL)
//abs in complex.h C99
#define ENTITY_C_CABS_P(e) entity_an_operator_p(e, C_CABS)
#define ENTITY_CABSF_P(e) entity_an_operator_p(e, CABSF)
#define ENTITY_CABSL_P(e) entity_an_operator_p(e, CABSL)

#define ENTITY_AND_P(e) (entity_an_operator_p(e, AND) || entity_an_operator_p(e, C_AND))
#define ENTITY_OR_P(e) (entity_an_operator_p(e, OR) || entity_an_operator_p(e, C_OR))
#define ENTITY_BITWISE_AND_P(e) (entity_an_operator_p(e, BITWISE_AND))
#define ENTITY_BITWISE_OR_P(e) (entity_an_operator_p(e, BITWISE_OR))
#define ENTITY_BITWISE_XOR_P(e) (entity_an_operator_p(e, BITWISE_XOR))
#define ENTITY_NOT_P(e) (entity_an_operator_p(e, NOT) || entity_an_operator_p(e, C_NOT))
// NON_EQUIV is in fact a logical operator - to simplify semantics
#define ENTITY_NON_EQUAL_P(e) (entity_an_operator_p(e, NON_EQUAL) || entity_an_operator_p(e, NON_EQUIV) || entity_an_operator_p(e, C_NON_EQUAL))
#define ENTITY_EQUIV_P(e) entity_an_operator_p(e, EQUIV)
#define ENTITY_NON_EQUIV_P(e) entity_an_operator_p(e, NON_EQUIV)
#define ENTITY_LEFT_SHIFT_P(e) entity_an_operator_p(e, LEFT_SHIFT)
#define ENTITY_RIGHT_SHIFT_P(e) entity_an_operator_p(e, RIGHT_SHIFT)

#define ENTITY_ADDRESS_OF_P(e) entity_an_operator_p(e, ADDRESS_OF)

/* Attention :
   This definition is different with the Fortran Standard where the logical
   operators are the following only: AND, OR, NOT, EQUIV, NEQUIV (NN-Mars 2000)*/

#define ENTITY_LOGICAL_OPERATOR_P(e) ( ENTITY_RELATIONAL_OPERATOR_P(e) || \
                                       ENTITY_AND_P(e) || \
                                       ENTITY_OR_P(e) || \
                                       ENTITY_NOT_P(e))

#define ENTITY_TRUE_P(e) entity_an_operator_p(e, TRUE)
#define ENTITY_FALSE_P(e) entity_an_operator_p(e, FALSE)
#define ENTITY_ONE_P(e) entity_an_operator_p(e, ONE)
#define ENTITY_ZERO_P(e) entity_an_operator_p(e, ZERO)

#define ENTITY_GREATER_OR_EQUAL_P(e) (entity_an_operator_p(e, GREATER_OR_EQUAL) || entity_an_operator_p(e, C_GREATER_OR_EQUAL))
#define ENTITY_GREATER_THAN_P(e)  (entity_an_operator_p(e, GREATER_THAN) || entity_an_operator_p(e, C_GREATER_THAN))
#define ENTITY_LESS_OR_EQUAL_P(e) (entity_an_operator_p(e, LESS_OR_EQUAL) || entity_an_operator_p(e, C_LESS_OR_EQUAL))
#define ENTITY_LESS_THAN_P(e) (entity_an_operator_p(e, LESS_THAN) || entity_an_operator_p(e, C_LESS_THAN))

// EQUIV is in fact a logical operator - to simplify semantics
#define ENTITY_EQUAL_P(e) (entity_an_operator_p(e, EQUAL) || entity_an_operator_p(e, EQUIV) || entity_an_operator_p(e, C_EQUAL))

#define ENTITY_RELATIONAL_OPERATOR_P(e) ( \
                                         ENTITY_GREATER_OR_EQUAL_P(e) || \
                                         ENTITY_GREATER_THAN_P(e) || \
                                         ENTITY_LESS_OR_EQUAL_P(e) || \
                                         ENTITY_LESS_THAN_P(e) || \
                                         ENTITY_NON_EQUAL_P(e) || \
                                         ENTITY_EQUAL_P(e) )

#define ENTITY_NAME_P(e, name)(same_string_p(entity_user_name(e),name))

/* Fortran IO Management */

#define ENTITY_WRITE_P(e)                ENTITY_NAME_P(e, "WRITE")
#define ENTITY_REWIND_P(e)               ENTITY_NAME_P(e, "REWIND")
#define ENTITY_OPEN_P(e)                 ENTITY_NAME_P(e, "OPEN")
#define ENTITY_CLOSE_P(e)                ENTITY_NAME_P(e, "CLOSE")
#define ENTITY_READ_P(e)                 ENTITY_NAME_P(e, READ_FUNCTION_NAME)
#define ENTITY_BUFFERIN_P(e)             ENTITY_NAME_P(e, "BUFFERIN")
#define ENTITY_BUFFEROUT_P(e)            ENTITY_NAME_P(e, "BUFFEROUT")
#define ENTITY_ENDFILE_P(e)              ENTITY_NAME_P(e, "ENDFILE")
#define ENTITY_IMPLIEDDO_P(e)            ENTITY_NAME_P(e, IMPLIED_DO_NAME)
#define ENTITY_IO_LIST_P(e)              ENTITY_NAME_P(e, IO_LIST_STRING_NAME)
#define ENTITY_FORMAT_P(e)               ENTITY_NAME_P(e, "FORMAT")

/* Bit manipulation functions. Amira Mensi */
#define ENTITY_ISHFT_P(e)                ENTITY_NAME_P(e, "ISHFT")
#define ENTITY_ISHFTC_P(e)               ENTITY_NAME_P(e, "ISHFTC")
#define ENTITY_IBITS_P(e)                ENTITY_NAME_P(e, "IBITS")
#define ENTITY_MVBITS_P(e)               ENTITY_NAME_P(e, "MVBITS")
#define ENTITY_BTEST_P(e)                ENTITY_NAME_P(e, "BTEST")
#define ENTITY_IBSET_P(e)                ENTITY_NAME_P(e, "IBSET")
#define ENTITY_IBCLR_P(e)                ENTITY_NAME_P(e, "IBCLR")
#define ENTITY_BIT_SIZE_P(e)             ENTITY_NAME_P(e, "BIT_SIZE")
#define ENTITY_IOR_P(e)                  ENTITY_NAME_P(e, "IOR")
#define ENTITY_IEOR_P(e)                 ENTITY_NAME_P(e, "IEOR")
#define ENTITY_IAND_P(e)                 ENTITY_NAME_P(e, "IAND")

/* OMP entity test */
#define ENTITY_OMP_IF_P(e)               ENTITY_NAME_P(e,OMP_IF_FUNCTION_NAME)
#define ENTITY_OMP_OMP_P(e)              ENTITY_NAME_P(e,OMP_OMP_FUNCTION_NAME)
#define ENTITY_OMP_FOR_P(e)              ENTITY_NAME_P(e,OMP_FOR_FUNCTION_NAME)
#define ENTITY_OMP_PRIVATE_P(e)          ENTITY_NAME_P(e,OMP_PRIVATE_FUNCTION_NAME)
#define ENTITY_OMP_PARALLEL_P(e)         ENTITY_NAME_P(e,OMP_PARALLEL_FUNCTION_NAME)
#define ENTITY_OMP_REDUCTION_P(e)        ENTITY_NAME_P(e,OMP_REDUCTION_FUNCTION_NAME)


/*io functions: C library and system io.Amira Mensi*/

/*#include<stdio.h> */

#define ENTITY_PRINTF_P(e)               ENTITY_NAME_P(e, "printf")
#define ENTITY_FPRINTF_P(e)              ENTITY_NAME_P(e, "fprintf")
#define ENTITY_SCANF_P(e)                ENTITY_NAME_P(e, "scanf")
#define ENTITY_ISOC99_SCANF_P(e)         ENTITY_NAME_P(e, ISOC99_SCANF_FUNCTION_NAME)
#define ENTITY_FSCANF_P(e)               ENTITY_NAME_P(e, "fscanf")
#define ENTITY_ISOC99_FSCANF_P(e)        ENTITY_NAME_P(e, ISOC99_FSCANF_FUNCTION_NAME)
#define ENTITY_PUTS_P(e)                 ENTITY_NAME_P(e, "puts")
#define ENTITY_GETS_P(e)                 ENTITY_NAME_P(e, "gets")
#define ENTITY_FPUTS_P(e)                ENTITY_NAME_P(e, "fputs")
#define ENTITY_FGETS_P(e)                ENTITY_NAME_P(e, "fgets")
#define ENTITY_FPUTC_P(e)                ENTITY_NAME_P(e, "fputc")
#define ENTITY_FGETC_P(e)                ENTITY_NAME_P(e, "fgetc")
#define ENTITY_FOPEN_P(e)                ENTITY_NAME_P(e, "fopen")
#define ENTITY_FDOPEN_P(e)               ENTITY_NAME_P(e, "fdopen")
#define ENTITY_FREOPEN_P(e)              ENTITY_NAME_P(e, "freopen")
#define ENTITY_FCLOSE_P(e)               ENTITY_NAME_P(e, "fclose")
#define ENTITY_SNPRINTF_P(e)             ENTITY_NAME_P(e, "snprintf")
#define ENTITY_SSCANF_P(e)               ENTITY_NAME_P(e, "sscanf")
#define ENTITY_ISOC99_SSCANF_P(e)        ENTITY_NAME_P(e, ISOC99_SSCANF_FUNCTION_NAME)
#define ENTITY_VFPRINTF_P(e)             ENTITY_NAME_P(e, "vfprintf")
#define ENTITY_VFSCANF_P(e)              ENTITY_NAME_P(e, "vfscanf")
#define ENTITY_ISOC99_VFSCANF_P(e)       ENTITY_NAME_P(e, ISOC99_VFSCANF_FUNCTION_NAME)
#define ENTITY_VPRINTF_P(e)              ENTITY_NAME_P(e, "vprintf")
#define ENTITY_VSCANF_P(e)               ENTITY_NAME_P(e, "vscanf")
#define ENTITY_ISOC99_VSCANF_P(e)        ENTITY_NAME_P(e, ISOC99_VSCANF_FUNCTION_NAME)
#define ENTITY_VSNPRINTF_P(e)            ENTITY_NAME_P(e, "vsnprintf")
#define ENTITY_VSPRINTF_P(e)             ENTITY_NAME_P(e, "vsprintf")
#define ENTITY_SPRINTF_P(e)              ENTITY_NAME_P(e, "sprintf")
#define ENTITY_VSSCANF_P(e)              ENTITY_NAME_P(e, "vsscanf")
#define ENTITY_ISOC99_VSSCANF_P(e)       ENTITY_NAME_P(e, ISOC99_VSSCANF_FUNCTION_NAME)
#define ENTITY_GETC_P(e)                 ENTITY_NAME_P(e, "getc")
#define ENTITY__IO_GETC_P(e)             ENTITY_NAME_P(e, "_IO_getc")
#define ENTITY_GETCHAR_P(e)              ENTITY_NAME_P(e, "getchar")
#define ENTITY_PUTC_P(e)                 ENTITY_NAME_P(e, "putc")
#define ENTITY__IO_PUTC_P(e)             ENTITY_NAME_P(e, "_IO_putc")
#define ENTITY_PUTCHAR_P(e)              ENTITY_NAME_P(e, "putchar")
#define ENTITY_UNGETC_P(e)               ENTITY_NAME_P(e, "ungetc")
#define ENTITY_FREAD_P(e)                ENTITY_NAME_P(e, "fread")
#define ENTITY_FWRITE_P(e)               ENTITY_NAME_P(e, "fwrite")
#define ENTITY_FGETPOS_P(e)              ENTITY_NAME_P(e, "fgetpos")
#define ENTITY_FSEEK_P(e)                ENTITY_NAME_P(e, "fseek")
#define ENTITY_FSETPOS_P(e)              ENTITY_NAME_P(e, "fsetpos")
#define ENTITY_FTELL_P(e)                ENTITY_NAME_P(e, "ftell")
#define ENTITY_C_REWIND_P(e)             ENTITY_NAME_P(e, "rewind")
#define ENTITY_CLEARERR_P(e)             ENTITY_NAME_P(e, "clearer")
#define ENTITY_FEOF_P(e)                 ENTITY_NAME_P(e, "feof")
#define ENTITY_FERROR_P(e)               ENTITY_NAME_P(e, "ferror")
#define ENTITY_FILENO_P(e)               ENTITY_NAME_P(e, "fileno")
#define ENTITY_PERROR_P(e)               ENTITY_NAME_P(e, "perror")

/*io functions: C library and system io.Amira Mensi*/

#define ENTITY_C_OPEN_SYSTEM_P(e)        ENTITY_NAME_P(e, C_OPEN_FUNCTION_NAME)
#define ENTITY_C_CLOSE_SYSTEM_P(e)       ENTITY_NAME_P(e, C_CLOSE_FUNCTION_NAME)
#define ENTITY_C_READ_SYSTEM_P(e)        ENTITY_NAME_P(e, C_READ_FUNCTION_NAME)
#define ENTITY_C_WRITE_SYSTEM_P(e)       ENTITY_NAME_P(e, C_WRITE_FUNCTION_NAME)
#define ENTITY_LINK_SYSTEM_P(e)          ENTITY_NAME_P(e, LINK_FUNCTION_NAME)
#define ENTITY_SYMLINK_SYSTEM_P(e)       ENTITY_NAME_P(e, SYMLINK_FUNCTION_NAME)
#define ENTITY_UNLINK_SYSTEM_P(e)        ENTITY_NAME_P(e, UNLINK_FUNCTION_NAME)

/* fcntl() */
#define ENTITY_FSYNC_SYSTEM_P(e)         ENTITY_NAME_P(e, FSYNC_FUNCTION_NAME)
#define ENTITY_FDATASYNC_SYSTEM_P(e)     ENTITY_NAME_P(e, FDATASYNC_FUNCTION_NAME)
#define ENTITY_IOCTL_SYSTEM_P(e)         ENTITY_NAME_P(e, IOCTL_FUNCTION_NAME)
#define ENTITY_SELECT_SYSTEM_P(e)        ENTITY_NAME_P(e, SELECT_FUNCTION_NAME)
#define ENTITY_PSELECT_SYSTEM_P(e)       ENTITY_NAME_P(e, PSELECT_FUNCTION_NAME)
#define ENTITY_STAT_SYSTEM_P(e)          ENTITY_NAME_P(e, STAT_FUNCTION_NAME)
#define ENTITY_FSTAT_SYSTEM_P(e)         ENTITY_NAME_P(e, FSTAT_FUNCTION_NAME)
#define ENTITY_LSTAT_SYSTEM_P(e)         ENTITY_NAME_P(e, LSTAT_FUNCTION_NAME)

#define ENTITY_REMOVE_SYSTEM_P(e)        ENTITY_NAME_P(e, "remove")
#define ENTITY_RENAME_SYSTEM_P(e)        ENTITY_NAME_P(e, "rename")
#define ENTITY_TMPFILE_SYSTEM_P(e)       ENTITY_NAME_P(e, "tmpfile")
#define ENTITY_TMPNAM_SYSTEM_P(e)        ENTITY_NAME_P(e, "tmpnam")
#define ENTITY_FFLUSH_SYSTEM_P(e)        ENTITY_NAME_P(e, "fflush")
#define ENTITY_FREOPEN_SYSTEM_P(e)       ENTITY_NAME_P(e, "freopen")
#define ENTITY_SETBUF_SYSTEM_P(e)        ENTITY_NAME_P(e, "setbuf")
#define ENTITY_SETVBUF_SYSTEM_P(e)       ENTITY_NAME_P(e, "setvbuf")
#define ENTITY__FILBUF_SYSTEM_P(e)       ENTITY_NAME_P(e, "__filbuf")
#define ENTITY__FILSBUF_SYSTEM_P(e)      ENTITY_NAME_P(e, "__flsbuf")
#define ENTITY_SETBUFFER_SYSTEM_P(e)     ENTITY_NAME_P(e, "setbuffer")
#define ENTITY_SETLINEBUF_SYSTEM_P(e)    ENTITY_NAME_P(e, "setlinebuf")
#define ENTITY_FDOPEN_SYSTEM_P(e)        ENTITY_NAME_P(e, "fdopen")
#define ENTITY_CTERMID_SYSTEM_P(e)       ENTITY_NAME_P(e, "ctermid")
#define ENTITY_FILENO_SYSTEM_P(e)        ENTITY_NAME_P(e, "fileno")
#define ENTITY_POPEN_SYSTEM_P(e)         ENTITY_NAME_P(e, "popen")
#define ENTITY_CUSERID_SYSTEM_P(e)       ENTITY_NAME_P(e, "cuserid")
#define ENTITY_TEMPNAM_SYSTEM_P(e)       ENTITY_NAME_P(e, "tempnam")
#define ENTITY_GETW_SYSTEM_P(e)          ENTITY_NAME_P(e, "getw")
#define ENTITY_PUTW_SYSTEM_P(e)          ENTITY_NAME_P(e, "putw")
#define ENTITY_PCLOSE_SYSTEM_P(e)        ENTITY_NAME_P(e, "pclose")
#define ENTITY_FSEEKO_SYSTEM_P(e)        ENTITY_NAME_P(e, "fseeko")
#define ENTITY_FTELLO_SYSTEM_P(e)        ENTITY_NAME_P(e, "ftello")
#define ENTITY_FOPEN64_SYSTEM_P(e)       ENTITY_NAME_P(e, "fopen64")
#define ENTITY_FREOPEN64_SYSTEM_P(e)     ENTITY_NAME_P(e, "freopen64")
#define ENTITY_TMPFILE64_SYSTEM_P(e)     ENTITY_NAME_P(e, "tmpfile64")
#define ENTITY_FGETPOS64_SYSTEM_P(e)     ENTITY_NAME_P(e, "fgetpos64")
#define ENTITY_FSETPOS64_SYSTEM_P(e)     ENTITY_NAME_P(e, "fsetpos64")
#define ENTITY_FSEEKO64_SYSTEM_P(e)      ENTITY_NAME_P(e, "fseeko64")
#define ENTITY_FTELLO64_SYSTEM_P(e)      ENTITY_NAME_P(e, "ftello64")

#define ENTITY_ABORT_SYSTEM_P(e)         ENTITY_NAME_P(e, "abort")
#define ENTITY_C_ABS_SYSTEM_P(e)         ENTITY_NAME_P(e, "abs")
#define ENTITY_ATEXIT_SYSTEM_P(e)        ENTITY_NAME_P(e, "atexit")
#define ENTITY_ATOF_SYSTEM_P(e)          ENTITY_NAME_P(e, "atof")
#define ENTITY_ATOI_SYSTEM_P(e)          ENTITY_NAME_P(e, "atoi")
#define ENTITY_BSEARCH_SYSTEM_P(e)       ENTITY_NAME_P(e, "bsearch")
#define ENTITY_CALLOC_SYSTEM_P(e)        ENTITY_NAME_P(e, "calloc")
#define ENTITY_DIV_SYSTEM_P(e)           ENTITY_NAME_P(e, "div")
#define ENTITY_EXIT_SYSTEM_P(e)          ENTITY_NAME_P(e, "exit")
#define ENTITY_FREE_SYSTEM_P(e)          ENTITY_NAME_P(e, "free")
#define ENTITY_GETENV_SYSTEM_P(e)        ENTITY_NAME_P(e, "getenv")
#define ENTITY_LABS_SYSTEM_P(e)          ENTITY_NAME_P(e, "labs")
#define ENTITY_LDIV_SYSTEM_P(e)          ENTITY_NAME_P(e, "ldiv")
#define ENTITY_MALLOC_SYSTEM_P(e)        ENTITY_NAME_P(e, "malloc")
#define ENTITY_MBLEN_SYSTEM_P(e)         ENTITY_NAME_P(e, "mblen")
#define ENTITY_MBSTOWCS_SYSTEM_P(e)      ENTITY_NAME_P(e, "mbstowcs")
#define ENTITY_MBTOWC_SYSTEM_P(e)        ENTITY_NAME_P(e, "mbtowc")
#define ENTITY_QSORT_SYSTEM_P(e)         ENTITY_NAME_P(e, "qsort")
#define ENTITY_REALLOC_SYSTEM_P(e)       ENTITY_NAME_P(e, "realloc")
#define ENTITY_STRTOD_SYSTEM_P(e)        ENTITY_NAME_P(e, "strtod")
#define ENTITY_STRTOL_SYSTEM_P(e)        ENTITY_NAME_P(e, "strtol")
#define ENTITY_STRTOUL_SYSTEM_P(e)       ENTITY_NAME_P(e, "strtoul")
#define ENTITY_SYSTEM_SYSTEM_P(e)        ENTITY_NAME_P(e, "system")
#define ENTITY_WCTOMB_SYSTEM_P(e)        ENTITY_NAME_P(e, "wctomb")
#define ENTITY_WCSTOMBS_SYSTEM_P(e)      ENTITY_NAME_P(e, "wcstombs")
#define ENTITY_EXITHANDLESYSTEM_P(e)     ENTITY_NAME_P(e, "exithandle")
#define ENTITY_DRAND48_SYSTEM_P(e)       ENTITY_NAME_P(e, "drand48")
#define ENTITY_ERAND48_SYSTEM_P(e)       ENTITY_NAME_P(e, "erand48")
#define ENTITY_JRAND48_SYSTEM_P(e)       ENTITY_NAME_P(e, "jrand48")
#define ENTITY_LCONG48_SYSTEM_P(e)       ENTITY_NAME_P(e, "lcong48")
#define ENTITY_LRAND48_SYSTEM_P(e)       ENTITY_NAME_P(e, "lrand48")
#define ENTITY_MRAND48_SYSTEM_P(e)       ENTITY_NAME_P(e, "mrand48")
#define ENTITY_NRAND48_SYSTEM_P(e)       ENTITY_NAME_P(e, "nrand48")
#define ENTITY_SEED48_SYSTEM_P(e)        ENTITY_NAME_P(e, "seed48")
#define ENTITY_SRAND48_SYSTEM_P(e)       ENTITY_NAME_P(e, "srand48")
#define ENTITY_PUTENV_SYSTEM_P(e)        ENTITY_NAME_P(e, "putenv")
#define ENTITY_SETKEY_SYSTEM_P(e)        ENTITY_NAME_P(e, "setkey")
#define ENTITY_SWAB_SYSTEM_P(e)          ENTITY_NAME_P(e, "swab")
#define ENTITY_MKSTEMP_SYSTEM_P(e)       ENTITY_NAME_P(e, "mkstemp")
#define ENTITY_MKSTEMP64_SYSTEM_P(e)     ENTITY_NAME_P(e, "mkstemp64")
#define ENTITY_A614_SYSTEM_P(e)          ENTITY_NAME_P(e, "a64l")
#define ENTITY_ECVT_SYSTEM_P(e)          ENTITY_NAME_P(e, "ecvt")
#define ENTITY_FCVT_SYSTEM_P(e)          ENTITY_NAME_P(e, "fcvt")
#define ENTITY_GCVT_SYSTEM_P(e)          ENTITY_NAME_P(e, "gcvt")
#define ENTITY_GETSUBOPT_SYSTEM_P(e)     ENTITY_NAME_P(e, "getsubopt")
#define ENTITY_GRANTPT_SYSTEM_P(e)       ENTITY_NAME_P(e, "grantpt")
#define ENTITY_INITSTATE_SYSTEM_P(e)     ENTITY_NAME_P(e, "initstate")
#define ENTITY_C_164A_SYSTEM_P(e)        ENTITY_NAME_P(e, "l64a")
#define ENTITY_MKTEMP_SYSTEM_P(e)        ENTITY_NAME_P(e, "mktemp")
#define ENTITY_PTSNAME_SYSTEM_P(e)       ENTITY_NAME_P(e, "ptsname")
#define ENTITY_REALPATH_SYSTEM_P(e)      ENTITY_NAME_P(e, "realpath")
#define ENTITY_SETSTATE_SYSTEM_P(e)      ENTITY_NAME_P(e, "setstate")
#define ENTITY_TTYSLOT_SYSTEM_P(e)       ENTITY_NAME_P(e, "ttyslot")
#define ENTITY_UNLOCKPT_SYSTEM_P(e)      ENTITY_NAME_P(e, "unlockpt")
#define ENTITY_VALLOC_SYSTEM_P(e)        ENTITY_NAME_P(e, "valloc")
#define ENTITY_DUP2_SYSTEM_P(e)          ENTITY_NAME_P(e, "dup2")
#define ENTITY_QECVT_SYSTEM_P(e)         ENTITY_NAME_P(e, "qecvt")
#define ENTITY_QFCVT_SYSTEM_P(e)         ENTITY_NAME_P(e, "qfcvt")
#define ENTITY_QGCVT_SYSTEM_P(e)         ENTITY_NAME_P(e, "qgcvt")
#define ENTITY_GETCWD_SYSTEM_P(e)        ENTITY_NAME_P(e, "getcwd")
#define ENTITY_GETEXECNAME_SYSTEM_P(e)   ENTITY_NAME_P(e, "getexecname")
#define ENTITY_GETLOGIN_SYSTEM_P(e)      ENTITY_NAME_P(e, "getlogin")
#define ENTITY_GETOPT_SYSTEM_P(e)        ENTITY_NAME_P(e, "getopt")
#define ENTITY_GETPASS_SYSTEM_P(e)       ENTITY_NAME_P(e, "getpass")
#define ENTITY_GETPASSPHRASE_SYSTEM_P(e) ENTITY_NAME_P(e, "getpassphrase")
#define ENTITY_GETPW_SYSTEM_P(e)         ENTITY_NAME_P(e, "getpw")
#define ENTITY_ISATTY_SYSTEM_P(e)        ENTITY_NAME_P(e, "isatty")
#define ENTITY_MEMALIGN_SYSTEM_P(e)      ENTITY_NAME_P(e, "memalign")
#define ENTITY_TTYNAME_SYSTEM_P(e)       ENTITY_NAME_P(e, "ttyname")
#define ENTITY_ATOLL_SYSTEM_P(e)         ENTITY_NAME_P(e, "atoll")
#define ENTITY_LLABS_SYSTEM_P(e)         ENTITY_NAME_P(e, "llabs")
#define ENTITY_LLDIV_SYSTEM_P(e)         ENTITY_NAME_P(e, "lldiv")
#define ENTITY_LLTOSTR_SYSTEM_P(e)       ENTITY_NAME_P(e, "lltostr")
#define ENTITY_STROLL_SYSTEM_P(e)        ENTITY_NAME_P(e, "strtoll")
#define ENTITY_STROULL_SYSTEM_P(e)       ENTITY_NAME_P(e, "strtoull")
#define ENTITY_ULLOSTR_SYSTEM_P(e)       ENTITY_NAME_P(e, "ulltostr")

/* include <assert.h> */

#define ENTITY_ASSERT_SYSTEM_P(e)        ENTITY_NAME_P(e, ASSERT_FUNCTION_NAME)
#define ENTITY_ASSERT_FAIL_SYSTEM_P(e)   ENTITY_NAME_P(e, ASSERT_FAIL_FUNCTION_NAME)

/* include <string.h> */

#define ENTITY_STRCMP_SYSTEM_P(e)        ENTITY_NAME_P(e, "strcmp")
#define ENTITY_STRNCMP_SYSTEM_P(e)       ENTITY_NAME_P(e, "strncmp")
#define ENTITY_STRCPY_SYSTEM_P(e)        ENTITY_NAME_P(e, "strcpy")
#define ENTITY_STRCAT_SYSTEM_P(e)        ENTITY_NAME_P(e, "strcat")
#define ENTITY_STRNCAT_SYSTEM_P(e)       ENTITY_NAME_P(e, "strncat")
#define ENTITY_STRLEN_SYSTEM_P(e)        ENTITY_NAME_P(e, "strlen")
#define ENTITY_STRERROR_SYSTEM_P(e)      ENTITY_NAME_P(e, "strerror")
#define ENTITY_STRERROR_R_SYSTEM_P(e)    ENTITY_NAME_P(e, "strerror_r")

/* FI: Why is it declared "system"? Why is it in the middle of string functions? */
#define ENTITY_FOPEN_SYSTEM_P(e)         ENTITY_NAME_P(e, "fopen")

/* #include <fcntl.h>*/

#define ENTITY_FCNTL_SYSTEM_P(e)         ENTITY_NAME_P(e,"fcntl")
#define ENTITY_OPEN_SYSTEM_P(e)          ENTITY_NAME_P(e,"open")
#define ENTITY_CREAT_SYSTEM_P(e)         ENTITY_NAME_P(e,"creat")
#define ENTITY_DIRECTIO_SYSTEM_P(e)      ENTITY_NAME_P(e,"directio")
#define ENTITY_OPEN64_SYSTEM_P(e)        ENTITY_NAME_P(e,"open64")
#define ENTITY_CREAT64_SYSTEM_P(e)       ENTITY_NAME_P(e,"creat64")

/* some random functions of stdlib.h */

#define ENTITY_RANDOM_P(e)               ENTITY_NAME_P(e,"random")
#define ENTITY_SRANDOM_P(e)              ENTITY_NAME_P(e,"srandom")
#define ENTITY_RAND_P(e)                 ENTITY_NAME_P(e,"rand")
#define ENTITY_SRAND_P(e)                ENTITY_NAME_P(e,"srand")

/* signal.h */
#define ENTITY_SIGNAL_P(e)               ENTITY_NAME_P(e,"signal")

/* Fortran DATA management */

#define ENTITY_STATIC_INITIALIZATION_P(e) ENTITY_NAME_P(e, STATIC_INITIALIZATION_FUNCTION_NAME)
#define ENTITY_REPEAT_VALUE_P(e)          ENTITY_NAME_P(e, REPEAT_VALUE_FUNCTION_NAME)
#define ENTITY_DATA_LIST_P(e)             ENTITY_NAME_P(e, DATA_LIST_FUNCTION_NAME)

/* C initialization expression */

#define ENTITY_BRACE_INTRINSIC_P(e) ENTITY_NAME_P(e, BRACE_INTRINSIC)

#define ENTITY_IMPLIED_CMPLX_P(e) ENTITY_NAME_P(e, IMPLIED_COMPLEX_NAME)
#define ENTITY_IMPLIED_DCMPLX_P(e) ENTITY_NAME_P(e, IMPLIED_DCOMPLEX_NAME)

/* C data structure and pointer management */

#define ENTITY_FIELD_P(e)         entity_an_operator_p(e, FIELD)
#define ENTITY_POINT_TO_P(e)      entity_an_operator_p(e, POINT_TO)
#define ENTITY_DEREFERENCING_P(e) entity_an_operator_p(e, DEREFERENCING)
/* Defined elsewhere: #define ENTITY_ADDRESS_OF_P(e) entity_an_operator_p(e, ADDRESS_OF) */

/* C varargs stuff */
#define ENTITY_VA_END_P(e)   ENTITY_NAME_P(e, BUILTIN_VA_END)
#define ENTITY_VA_START_P(e) ENTITY_NAME_P(e, BUILTIN_VA_START)
#define ENTITY_VA_COPY_P(e)  ENTITY_NAME_P(e, BUILTIN_VA_COPY)


#define ENTITY_FIVE_OPERATION_P(e) ( ENTITY_PLUS_P(e) || \
                                     ENTITY_PLUS_C_P(e) || \
                                     ENTITY_MINUS_P(e) || \
                                     ENTITY_MINUS_C_P(e) || \
                                     ENTITY_UNARY_MINUS_P(e) || \
                                     ENTITY_MULTIPLY_P(e) || \
                                     ENTITY_MODULO_P(e) ||\
                                     ENTITY_DIVIDE_P(e) )

#define IO_CALL_P(call) io_intrinsic_p(call_function(call))

/*
 * Fortran 95 Allocatable
 */
#define ALLOCATABLE_PREFIX "__pips_allocatable__"
#define ALLOCATABLE_LBOUND_PREFIX "__pips__allocatable__lbound__"
#define ALLOCATABLE_UBOUND_PREFIX "__pips__allocatable__ubound__"
#define ENTITY_ALLOCATABLE_BOUND_P(e) \
  (strncmp(entity_user_name(e), ALLOCATABLE_LBOUND_PREFIX, strlen(ALLOCATABLE_LBOUND_PREFIX)) == 0 \
   || strncmp(entity_user_name(e), ALLOCATABLE_UBOUND_PREFIX, strlen(ALLOCATABLE_UBOUND_PREFIX)) == 0 )


/* classification of basics */

#define basic_numeric_simple_p(b) (basic_int_p(b) || basic_float_p(b))
#define basic_numeric_p(b) (basic_numeric_simple_p(b) || basic_complex_p(b))
#define basic_compatible_simple_p(b1, b2) (\
                (basic_numeric_simple_p(b1) && basic_numeric_simple_p(b2)) ||\
                (basic_string_p(b1) && basic_string_p(b2)) ||\
                (basic_logical_p(b1) && basic_logical_p(b2)) ||\
                (basic_overloaded_p(b1) && basic_overloaded_p(b2)) ||\
                (basic_undefined_p(b1) && basic_undefined_p(b2)))
#define basic_compatible_p(b1, b2) (\
                (basic_numeric_p(b1) && basic_numeric_p(b2)) ||\
                (basic_string_p(b1) && basic_string_p(b2)) ||\
                (basic_logical_p(b1) && basic_logical_p(b2)) ||\
                (basic_overloaded_p(b1) && basic_overloaded_p(b2)) ||\
                (basic_undefined_p(b1) && basic_undefined_p(b2)))

/*  constant sizes */

#define LABEL_SIZE 5
#define INDENTATION (get_int_property("PRETTYPRINT_INDENTATION"))
#define INDENT_A_LIST_OF_WORDS(list_of_words) { \
  if(list_of_words) { \
    list blanks = NIL; \
    for(int i=0; i<INDENTATION; i++) { \
      blanks = CHAIN_SWORD(blanks, " "); \
    } \
    list_of_words = gen_nconc(blanks,list_of_words); \
  } \
}

/*   default values */

#define STATEMENT_NUMBER_UNDEFINED (-1)
#define UNKNOWN_RAM_OFFSET (-1)
// It is for extern variables whose ram offset is not known
#define UNDEFINED_RAM_OFFSET (-2)
// It is for dynamic allocation of arrays whose ram offset is not known either.
/* FI: I would have assumed that it is used for the stack area, but I
   must be wrong... */
#define DYNAMIC_RAM_OFFSET (-3)


/* On devrait utiliser Newgen pour cela, mais comme on ne doit pas
   les utiliser directement (mais via statement_less_p), cela devrait
   decourager les temeraires */

#define MAKE_ORDERING(u,s) (u<<16|s)
#define ORDERING_NUMBER(o) (o>>16)
#define ORDERING_STATEMENT(o) (o & 0xffff)

#define NORMALIZE_EXPRESSION(e) \
    ((expression_normalized(e) == normalized_undefined) ? \
         (expression_normalized(e) = NormalizeExpression(e)) : \
         (expression_normalized(e)))

/*   MISC: newgen shorthands */

#define entity_declarations(e) (code_declarations(entity_code(e)))


/* An entity_variable_p(e) may hide a typedef and hence a functional
   type.  In C, use type_variable_p(ultimate_type(entity_type(e))) to
   make sure e is a variable.

   It may also be a dummy C parameter.

   It may also be a hidden entity such as an abstract location.

   To sum up, this predicate does not imply that entity e represents a
   variable declared in the source code by the programmer.

   See also the function variable_entity_p() which checks the storage
   of the entity.
 */
#define entity_variable_p(e) (type_variable_p(entity_type(e)))

#define entity_symbolic_p(e) (type_functional_p(entity_type(e)) && \
  storage_rom_p(entity_storage(e)) && value_symbolic_p(entity_initial(e)))

/* implemented as a macro to allow lhs */
#define module_language(e)\
    code_language(value_code(entity_initial((e))))

#define module_functional_parameters(func) \
        functional_parameters(type_functional(entity_type(func)))

#define call_intrinsic_p(C)                       \
  value_intrinsic_p(entity_initial(call_function(C)))


#define statement_block_p(stat) \
        (instruction_block_p(statement_instruction(stat)))

#define entity_constant_p(e) (type_functional_p(entity_type(e)) && \
  storage_rom_p(entity_storage(e)) && value_constant_p(entity_initial(e)))

#define loop_to_instruction make_instruction_loop
#define test_to_instruction make_instruction_test
#define call_to_instruction make_instruction_call

#define loop_to_statement(l) instruction_to_statement(loop_to_instruction(l))
#define test_to_statement(t) instruction_to_statement(test_to_instruction(t))
#define call_to_statement(c) instruction_to_statement(call_to_instruction(c))


/***************************************************** BOOLEAN EXPRESSIONS */

/* Building quickly bool expressions, FC. */

#define unary_intrinsic_expression(name, e)\
 call_to_expression(make_call(entity_intrinsic(name),CONS(EXPRESSION,e,NIL)))

#define binary_intrinsic_expression(name, e1, e2)\
 call_to_expression(make_call(entity_intrinsic(name),\
 CONS(EXPRESSION, e1, CONS(EXPRESSION, e2, NIL))))

#define not_expression(e) \
    unary_intrinsic_expression(NOT_OPERATOR_NAME, e)
#define or_expression(e1, e2) \
    binary_intrinsic_expression(OR_OPERATOR_NAME, e1, e2)
#define and_expression(e1, e2) \
    binary_intrinsic_expression(AND_OPERATOR_NAME, e1, e2)
#define ne_expression(e1, e2) \
    binary_intrinsic_expression(NON_EQUAL_OPERATOR_NAME, e1, e2)
#define eq_expression(e1, e2) \
    binary_intrinsic_expression(EQUAL_OPERATOR_NAME, e1, e2)
#define gt_expression(e1, e2) \
    binary_intrinsic_expression(GREATER_THAN_OPERATOR_NAME, e1, e2)
#define ge_expression(e1, e2) \
    binary_intrinsic_expression(GREATER_OR_EQUAL_OPERATOR_NAME, e1, e2)
#define lt_expression(e1, e2) \
    binary_intrinsic_expression(LESS_THAN_OPERATOR_NAME, e1, e2)
#define le_expression(e1, e2) \
    binary_intrinsic_expression(LESS_OR_EQUAL_OPERATOR_NAME, e1, e2)


/******************************************************** CONTROL GRAPH... */

/* For the control graph modifiers: */

/* To specify the way that remove_a_control_from_a_list_and_relink
   acts: */
enum remove_a_control_from_a_list_and_relink_direction
{
   /* Put some strange number to avoid random clash as much as
      possible... */
   source_is_predecessor_and_dest_is_successor = 119,
      source_is_successor_and_dest_is_predecessor = -123
      };
typedef enum remove_a_control_from_a_list_and_relink_direction
remove_a_control_from_a_list_and_relink_direction;

/* Constants for some ex-atomizer variable generation */

#define TMP_ENT 1
#define AUX_ENT 2
#define DOUBLE_PRECISION_SIZE 8


/***************************************************** HPF/HPFC DIRECTIVES */

/* moved here because needed by syntax:-(
 */
/* Directive names encoding: HPF_PREFIX + one character.
 * This encoding is achieved thru a sed script that transforms directives
 * into calls that can be parsed by the PIPS F77 parser. It's a hack but
 * it greatly reduced the number of lines for directive analysis, and
 * it allowed quite simply to figure out where the executable directives
 * are in the code.
 * However the syntax allowed in mapping directives is restricted to F77.
 */

/* prefix for spacial directive calls
 */
#define HPF_PREFIX              "HPFC"

/* suffixies for encoded hpf keywords
 */
#define BLOCK_SUFFIX            "K"
#define CYCLIC_SUFFIX           "C"
#define STAR_SUFFIX             "S"

/* suffixes for HPF directives managed by HPFC
 */
#define ALIGN_SUFFIX            "A"
#define REALIGN_SUFFIX          "B"
#define DISTRIBUTE_SUFFIX       "D"
#define REDISTRIBUTE_SUFFIX     "E"
#define INDEPENDENT_SUFFIX      "I"
#define NEW_SUFFIX              "N"
#define REDUCTION_SUFFIX        "R"
#define PROCESSORS_SUFFIX       "P"
#define TEMPLATE_SUFFIX         "T"
#define PURE_SUFFIX             "U"
#define DYNAMIC_SUFFIX          "Y"

/* suffixes for my own (FCD:-) directives.
 * these directives are used to instrument the code.
 * must be used carefully. may be ignore with some properties.
 */
#define TELL_SUFFIX             "0"
#define SYNCHRO_SUFFIX          "1"
#define TIMEON_SUFFIX           "2"
#define TIMEOFF_SUFFIX          "3"
#define SETBOOL_SUFFIX          "4"
#define SETINT_SUFFIX           "5"
#define HPFCIO_SUFFIX           "6"
#define HOSTSECTION_SUFFIX      "7"
#define DEAD_SUFFIX             "8"
#define FAKE_SUFFIX             "9"

/* property prefix for ignoring FCD directives
 * TIME, SYNCHRO and SET exists.
 */
#define FCD_IGNORE_PREFIX       "HPFC_IGNORE_FCD_"

/* __asm function
 */
#define ASM_FUNCTION_NAME "__asm"

/* soft block->sequence transition
 */
#define is_instruction_block is_instruction_sequence
#define instruction_block_p(i) instruction_sequence_p(i)
#define instruction_block(i) sequence_statements(instruction_sequence(i))

/* easy list constructor
 */
#define make_statement_list( stats... ) \
    (gen_make_list(statement_domain, ##stats, 0))
#define make_expression_list( stats... ) \
    (gen_make_list(expression_domain, ##stats, 0))

/* After the modification in Newgen:  unstructured = entry:control x exit:control
   we have create a macro to transform automatically unstructured_control to unstructured_entry */
#define unstructured_control unstructured_entry

/* Default type sizes */

#define DEFAULT_CHARACTER_TYPE_SIZE (1)
#define DEFAULT_SHORT_INTEGER_TYPE_SIZE (2)
#define DEFAULT_INTEGER_TYPE_SIZE (4)
#define DEFAULT_LONG_INTEGER_TYPE_SIZE (6)
#define DEFAULT_LONG_LONG_INTEGER_TYPE_SIZE (8)
#define DEFAULT_LONG_LONG_LONG_INTEGER_TYPE_SIZE (9)

// To avoid issues with the PIPS validation suite on a 32-bit pointer machine
//#define DEFAULT_POINTER_TYPE_SIZE (sizeof(void *)) // could be 4 or 8 or sizeof(pointer)
#define DEFAULT_POINTER_TYPE_SIZE (8)
#define DEFAULT_UNSIGNED_TYPE_SIZE (1) // type_size/10==1
#define DEFAULT_SIGNED_TYPE_SIZE (2) // type_size/10=2

/* The standard C integer types are represented as follow
char                   = 1
short_int              = 2
int                    = 4
long_int               = 6
long_long_int          = 8
__int128_t             = 9 (gcc extension)

unsigned_char          = 11
unsigned_short_int     = 12
unsigned_int           = 14
unsigned_long_int      = 16
unsigned_long_long_int = 18
__uint128_t            = 19 (gcc extension)

signed_char            = 21
signed_short_int       = 22
signed_int             = 24
signed_long_int        = 26
signed_long_long_int   = 28

mod(i,10) refers to the basic size and div(i,10) refers that
the variable is unsigned, signed or not */

#define DEFAULT_REAL_TYPE_SIZE (4)
#define DEFAULT_DOUBLEPRECISION_TYPE_SIZE (8)
#define DEFAULT_QUADPRECISION_TYPE_SIZE (16)
#define DEFAULT_COMPLEX_TYPE_SIZE (8)
#define DEFAULT_DOUBLECOMPLEX_TYPE_SIZE (16)
#define DEFAULT_LONGDOUBLECOMPLEX_TYPE_SIZE (32)
#define DEFAULT_LOGICAL_TYPE_SIZE (4)

/* Already defined */
//#define DEFAULT_POINTER_TYPE_SIZE (4)

/* package name for region variables */
#define REGIONS_MODULE_NAME "REGIONS-PACKAGE"

/* Implicit variables to handle IO effetcs */
/* package name for io routines */
#define IO_EFFECTS_PACKAGE_NAME "__IO_EFFECTS"
/* package name for time routines */
#define TIME_EFFECTS_PACKAGE_NAME "__TIME_EFFECTS"
/* package name for random routines */
#define RAND_EFFECTS_PACKAGE_NAME "_RANDOM_EFFECTS"
/* variable name for random unit */
#define RAND_GEN_EFFECTS_NAME "GEN_SEED"
/* package name for malloc routines (could be libc package) */
#define MALLOC_EFFECTS_PACKAGE_NAME "_MALLOC_EFFECTS"
/* variable name for heap effects */
#define MALLOC_EFFECTS_NAME "_MALLOC_"
/* package name for memmove routines */
#define MEMMOVE_EFFECTS_PACKAGE_NAME "_MEMMOVE_EFFECTS"
/* variable name for memmove unit */
#define MEMMOVE_EFFECTS_NAME "_MEMMOVE_"
/* array of Logical UNits; it is more or less handled as the current file pointer; in C, used for open, close, read, write... */
#define IO_EFFECTS_ARRAY_NAME "LUNS"
/* Array of struct io_files pointed to by pointers returned by fopen
   and used by fclose, fscanf, fprintf... */
#define IO_EFFECTS_IO_FILE_NAME "IO_FILES"
/* To express C IO intrinsics effects */
#define IO_EFFECTS_PTR_NAME "_C_IO_ptr"
/* array of end of file codes */
#define IO_EOF_ARRAY_NAME "END_LUNS"
/* array of error codes for LUNs */
#define IO_ERROR_ARRAY_NAME "ERR_LUNS"
/* variable holding time effects */
#define TIME_EFFECTS_VARIABLE_NAME "KALI" /* Kali is the goddess of time in the Hindu mythology */
#define TIME_EFFECTS_BUFFER_NAME "KALI-BUFFER" /* Kali is the goddess of time in the Hindu mythology */
/* size of the unit specifier */
#define IO_EFFECTS_UNIT_SPECIFIER_LENGTH 4
/* Standard unit numbers depend on the operating system. Here are UNIX definitions. */
#define STDERR_LUN (0)
#define STDERR_NAME "stderr"
#define ENTITY_STDERR_P(e) entity_a_special_entity_p(e, STDERR_NAME)
#define STDIN_LUN (5)
#define STDIN_NAME "stdin"
#define ENTITY_STDIN_P(e) entity_a_special_entity_p(e, STDIN_NAME)
#define STDOUT_LUN (6)
#define STDOUT_NAME "stdout"
#define ENTITY_STDOUT_P(e) entity_a_special_entity_p(e, STDOUT_NAME)

/*Symbolic constants for the file descriptors belonging to the standard streams: unistd.h */
#if !defined(HAVE_UNISTD_H) && !defined(_UNISTD_H)
#define STDIN_FILENO (0)
#define STDOUT_FILENO (1)
#define STDERR_FILENO (2)
#endif

/* Implicit variable names for C */

#define IMPLICIT_VARIABLE_NAME_1 "__FUNCTION__"
#define IMPLICIT_VARIABLE_NAME_2 "__func__"

/* Empty comments (i.e. default comments) */
/* FI: this is a poor choice as the statements won't be gen_defined_p
   and as strdup() won't be usable without an extra test. Would it be
   so bad to use strdup(""); as empty_comments? */
#define empty_comments string_undefined

/** An alias for make_empty_block_statement */
#define make_empty_statement make_empty_block_statement

/** An alias for make_empty_block_statement */
#define make_nop_statement make_empty_block_statement


/* \addtogroup control_visitors */

/* @{ */
/* Macro to walk through all the controls reachable from a given control
  node of an unstructured

  Reachability is defined by successors and predecessors (i.e. the control
  flow graph is seen as non-directed)

  @param ctl is a name of a control node variable that is declared inside
  this macro and is used by the following code to access the visited
  control node

  @param code is the actions to execute on the visited control node

  @param c is a control node to start visiting with

  @param list is a list that will store the visited control nodes. It is
  used mainly for this macro to avoid visiting twice a node. The simple
  usage is to give a list variable initialized to NIL. A nice side effect
  is that it will contain the list of all the reachable control nodes. Do
  not forget to free this list afterwards. Another classical usage is to
  give to the macro a list with a list of nodes to avoid visiting.
*/
#define CONTROL_MAP( ctl, code, c, list )				\
  do {									\
    GENERIC_CONTROL_MAP( control_map_get_blocs, ctl, code, c, list )	\
      } while(0)


/* Walk through all the controls of un unstructured

  This macro do not work indeed because often the...

  The nodes are those reachable from the entry node and also from the exit
  node (that may be unreachable from the entry node of th unstructured).

  Reachability is defined by successors and predecessors (i.e. the control
  flow graph is seen as non-directed)

  @param c is a name of a control node variable that is declared inside
  this macro and is used by the following code to access the visited
  control node

  @param code is the actions to execute on the visited control node

  @param u is the unstructured to visit

  @param l is a list that will store the visited control nodes. It is used
  mainly for this macro to avoid visiting twice a node. The simple usage
  is to give a list variable initialized to NIL. A nice side effect is
  that it will contain the list of all the reachable control nodes. Do not
  forget to free this list afterwards. Another classical usage is to give
  to the macro a list with a list of nodes to avoid visiting.
*/
#define UNSTRUCTURED_CONTROL_MAP(c, u, l, code)				\
  /* The implementation is sub-optimal because it duplicates the	\
     code... */								\
  do {									\
    /* First get the control nodes reachable from the entry node: */	\
    control_map_get_blocs(unstructured_entry(u), &l);			\
    /* Add then the control nodes reachable from the exit nodes if not	\
       already in: */							\
    control_map_get_blocs(unstructured_exit(u), &l);			\
    /* Reverse the list because previous construction was done in the	\
       reverse way: */							\
    l = gen_nreverse(l);						\
    /* Iterate on all the selected control nodes: */			\
    FOREACH(CONTROL, c, l)						\
      code								\
  } while(0)


/* Walk through all the controls forward-reachable from a given control
  node of an unstructured

  Reachability is defined by successor-only relation (i.e. the control
  flow graph is seen as directed)

  @param ctl is a name of a control node variable that is declared inside
  this macro and is used by the following code to access the visited
  control node

  @param code is the actions to execute on the visited control node

  @param c is a control node to start visiting with

  @param list is a list that will store the visited control nodes. It is
  used mainly for this macro to avoid visiting twice a node. The simple
  usage is to give a list variable initialized to NIL. A nice side effect
  is that it will contain the list of all the forward-reachable control
  nodes. Do not forget to free this list afterwards. Another classical
  usage is to give to the macro a list with a list of nodes to avoid
  visiting.
*/
#define FORWARD_CONTROL_MAP( ctl, code, c, list )			\
  do {									\
    GENERIC_CONTROL_MAP( forward_control_map_get_blocs, ctl, code, c, list ) \
      } while(0)


/* Walk through all the controls backward-reachable from a given control
  node of an unstructured

  Reachability is defined by predecessor-only relation (i.e. the control
  flow graph is seen as directed)

  @param ctl is a name of a control node variable that is declared inside
  this macro and is used by the following code to access the visited
  control node

  @param code is the actions to execute on the visited control node

  @param c is a control node to start visiting with

  @param list is a list that will store the visited control nodes. It is
  used mainly for this macro to avoid visiting twice a node. The simple
  usage is to give a list variable initialized to NIL. A nice side effect
  is that it will contain the list of all the backward-reachable control
  nodes. Do not forget to free this list afterwards. Another classical
  usage is to give to the macro a list with a list of nodes to avoid
  visiting.
*/
#define BACKWARD_CONTROL_MAP( ctl, code, c, list )			\
  do {									\
    GENERIC_CONTROL_MAP( backward_control_map_get_blocs, ctl, code, c, list ) \
    } while(0)


/* Walk through all the controls backward-reachable from a given control
  node of an unstructured

  Reachability is defined by successor-only relation (i.e. the control
  flow graph is seen as directed)

  @param ctl is a name of a control node variable that is declared inside
  this macro and is used by the following code to access the visited
  control node

  @param code is the actions to execute on the visited control node

  @param c is a control node to start visiting with

  @param list is a list that will store the visited control nodes. It is
  used mainly for this macro to avoid visiting twice a node. The simple
  usage is to give a list variable initialized to NIL. A nice side effect
  is that it will contain the list of all the reachable control nodes. Do
  not forget to free this list afterwards. Another classical usage is to
  give to the macro a list with a list of nodes to avoid visiting.
*/
#define WIDE_FORWARD_CONTROL_MAP( ctl, code, c, list )		\
   do {								\
     GENERIC_CONTROL_MAP(wide_forward_control_map_get_blocs,	\
			 ctl, code, c, list )			\
     } while(0)


/* The control node visiting engine. */
#define GENERIC_CONTROL_MAP( get_controls, ctl, code, c, list ) \
{ \
    cons *_cm_list_init = (list) ; \
    cons *_cm_list = _cm_list_init ; \
    if( _cm_list == NIL ) {\
         get_controls( c, &_cm_list ) ; \
         _cm_list = gen_nreverse( _cm_list ) ; \
    }\
    MAPL( _cm_ctls, {control ctl = CONTROL( CAR( _cm_ctls )) ; \
 \
                 code ;}, \
          _cm_list ) ; \
   if( _cm_list_init == NIL ) \
        list = _cm_list ; \
}



/** @} */


/** @defgroup phase_definition Functions used to define phases

    It defines macros for simple transformation phases that use (at least)
    the CODE of a module and write back a (possibly) new version of the
    CODE.

    @{
*/


/** Start a phase that use a module CODE

 @param module_name is a string with the name of the module the phase is
 applied to

 @param debug_env_var is a string with the name of the environment variable used to get the debug level to use inside the phase

 @return the statement of the module
*/
#define PIPS_PHASE_PRELUDE(module_name, debug_env_var)                \
  /* Get and return the CODE resource of the module and define this   \
     module as the current one at the same time to avoid introducing	\
     a new variable: */                                               \
  set_current_module_statement((statement)                            \
                               db_get_memory_resource(DBR_CODE,       \
                                                      module_name,    \
                                                      true));         \
                                                                      \
  /* Set the current module entity required to have many things       \
     working in PIPS: */                                              \
  set_current_module_entity(module_name_to_entity(module_name));      \
                                                                      \
  /* The debug is now controled by this environment variable name: */	\
  debug_on(debug_env_var);                                            \
  pips_debug(1, "Entering...\n");                                     \
  pips_assert("Statement should be OK at entry...",                   \
	      statement_consistent_p(get_current_module_statement()))


/** End a transformation phase by putting back into PIPS the (possibly)
    modified statement

    @param new_module_statement point to the (potentially) new module
    statement of the module
 */
#define PIPS_PHASE_POSTLUDE(new_module_statement)                       \
  pips_assert("Statement should be OK at exit...",                      \
              statement_consistent_p(new_module_statement));            \
  pips_debug(1, "done\n");                                              \
  /* Exit current debug context */                                      \
  debug_off();                                                          \
                                                                        \
  /* Reorder the module, because some statements have been replaced. */	\
  module_reorder(new_module_statement);                                 \
                                                                        \
  /* Put the new CODE ressource into PIPS: */                           \
  DB_PUT_MEMORY_RESOURCE(DBR_CODE,                                      \
                         get_current_module_name(),                     \
                         new_module_statement);                         \
                                                                        \
  /* There is no longer a current module: */                            \
  reset_current_module_statement();                                     \
  reset_current_module_entity();                                        \
                                                                        \
  /* Assume it should have worked by returning true... */               \
  return true

/** @} */


/* polymorhism thanks to newgen ! */
#define INSTANCE_OF(type,value) ( (_int)((value)->u) == (_int)(type##_domain) )

#define binary_call_lhs(c) (EXPRESSION(CAR(call_arguments((c)))))
#define binary_call_rhs(c) (EXPRESSION(CAR(CDR(call_arguments((c))))))
#define expression_scalar_p(e) (expression_reference_p((e)) && reference_scalar_p(expression_reference((e))))
#define hash_contains_p(htp, key) (hash_get(htp, key) != HASH_UNDEFINED_VALUE)

enum range_to_expression_mode{
    range_to_distance,
    range_to_nbiter
} ;
#define range_to_distance_p(e) ((e) == range_to_distance)
#define range_to_nbiter_p(e) ((e) == range_to_nbiter)


#define GENERATED_LABEL_MODULE_NAME "__GENSYM"

/* that is all for ri-util-local.h
 */

typedef enum {
  IGNORE_IF_POLICY,
  AND_IF_POLICY,
  OR_IF_POLICY
} if_clause_policy;

/* for intrinsic registration */
typedef struct {
    list (*f)(call,int,bool,list*);
    int prec;
} intrinsic_desc_t;

enum {
    DEFAULT_ENTITY_KIND = 0,
    EFFECTS_PACKAGE = 1,
    ABSTRACT_LOCATION = 2,
    ENTITY_STACK_AREA = 4,
    ENTITY_HEAP_AREA = 8,
    ENTITY_DYNAMIC_AREA = 16,
    ENTITY_STATIC_AREA = 32,
    ENTITY_POINTER_DUMMY_TARGETS_AREA = 64,
    ENTITY_FORMAL_AREA = 128,
};

#define make_entity(n,t,s,i) make_entity(n,t,s,i,DEFAULT_ENTITY_KIND)

/* SPIRE API */
#define SEND_FUNCTION_NAME                        "send"
#define RECV_FUNCTION_NAME                        "recv"
#define SIGNAL_FUNCTION_NAME                      "signal"
#define WAIT_FUNCTION_NAME                        "wait"


/*MPI calls*/
#define MPI_INIT_FUNCTION_NAME "MPI_Init"
#define MPI_FINALIZE_FUNCTION_NAME "MPI_Finalize"
#define MPI_ISEND_FUNCTION_NAME "MPI_Isend"
#define MPI_RECV_FUNCTION_NAME "MPI_Recv"
#define MPI_BARRIER_FUNCTION_NAME "MPI_Barrier"
//not use yet
#define MPI_COMM_SIZE_FUNCTION_NAME "MPI_Comm_size"
#define MPI_COMM_RANK_FUNCTION_NAME "MPI_Comm_rank"
#define MPI_SEND_FUNCTION_NAME "MPI_Send"             //implementation dependent
#define MPI_SSEND_FUNCTION_NAME "MPI_Ssend"           //Synchronous send
#define MPI_RSEND_FUNCTION_NAME "MPI_Rsend"           //Ready send
#define MPI_BSEND_FUNCTION_NAME "MPI_Bsend"           //Buffer send
#define MPI_ISEND_FUNCTION_NAME "MPI_Isend"           //non blocking version
#define MPI_ISSEND_FUNCTION_NAME "MPI_Issend"
#define MPI_IRSEND_FUNCTION_NAME "MPI_Irsend"
#define MPI_IBSEND_FUNCTION_NAME "MPI_Ibsend"
#define MPI_RECV_FUNCTION_NAME "MPI_Recv"
#define MPI_IRECV_FUNCTION_NAME "MPI_Irecv"
//#define MPI_MRECV_FUNCTION_NAME "MPI_Mrecv"           //match Receive - MPI3.0
//#define MPI_IMRECV_FUNCTION_NAME "MPI_Imrecv"
#define MPI_SENDRECV_FUNCTION_NAME "MPI_Sendrecv"


/*MPI types*/
#define MPI_STATUS "MPI_Status"
#define MPI_REQUEST "MPI_Request"
#define MPI_COMM "MPI_Comm"
#define MPI_DATATYPE "MPI_Datatype"

/* intrinsic entity declarations */
#define ENTITY_SEND_P(e)              ENTITY_NAME_P(e, "send")

// for new entities
extern list integer_entities, real_entities, complex_entities,
  logical_entities, double_entities, char_entities;
