Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / fortran / f95-lang.c
index a68d2fc..60d790b 100644 (file)
@@ -1,6 +1,5 @@
 /* gfortran backend interface
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2013 Free Software Foundation, Inc.
    Contributed by Paul Brook.
 
 This file is part of GCC.
@@ -41,7 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "debug.h"
 #include "diagnostic.h"
-#include "tree-dump.h"
+#include "dumpfile.h"
 #include "cgraph.h"
 #include "gfortran.h"
 #include "cpp.h"
@@ -60,7 +59,6 @@ lang_identifier {
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
      chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
-
 lang_tree_node {
   union tree_node GTY((tag ("0"),
                       desc ("tree_node_structure (&%h)"))) generic;
@@ -77,25 +75,18 @@ language_function {
   struct binding_level *binding_level;
 };
 
-/* We don't have a lex/yacc lexer/parser, but toplev expects these to
-   exist anyway.  */
-void yyerror (const char *str);
-int yylex (void);
-
 static void gfc_init_decl_processing (void);
 static void gfc_init_builtin_functions (void);
+static bool global_bindings_p (void);
 
 /* Each front end provides its own.  */
 static bool gfc_init (void);
 static void gfc_finish (void);
 static void gfc_write_global_declarations (void);
-static void gfc_print_identifier (FILE *, tree, int);
-void do_function_end (void);
-bool global_bindings_p (void);
-static void clear_binding_stack (void);
 static void gfc_be_parse_file (void);
 static alias_set_type gfc_get_alias_set (tree);
 static void gfc_init_ts (void);
+static tree gfc_builtin_function (tree);
 
 #undef LANG_HOOKS_NAME
 #undef LANG_HOOKS_INIT
@@ -106,7 +97,6 @@ static void gfc_init_ts (void);
 #undef LANG_HOOKS_INIT_OPTIONS
 #undef LANG_HOOKS_HANDLE_OPTION
 #undef LANG_HOOKS_POST_OPTIONS
-#undef LANG_HOOKS_PRINT_IDENTIFIER
 #undef LANG_HOOKS_PARSE_FILE
 #undef LANG_HOOKS_MARK_ADDRESSABLE
 #undef LANG_HOOKS_TYPE_FOR_MODE
@@ -125,6 +115,7 @@ static void gfc_init_ts (void);
 #undef LANG_HOOKS_OMP_PRIVATE_OUTER_REF
 #undef LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES
 #undef LANG_HOOKS_BUILTIN_FUNCTION
+#undef LANG_HOOKS_BUILTIN_FUNCTION
 #undef LANG_HOOKS_GET_ARRAY_DESCR_INFO
 
 /* Define lang hooks.  */
@@ -137,7 +128,6 @@ static void gfc_init_ts (void);
 #define LANG_HOOKS_INIT_OPTIONS         gfc_init_options
 #define LANG_HOOKS_HANDLE_OPTION        gfc_handle_option
 #define LANG_HOOKS_POST_OPTIONS                gfc_post_options
-#define LANG_HOOKS_PRINT_IDENTIFIER     gfc_print_identifier
 #define LANG_HOOKS_PARSE_FILE           gfc_be_parse_file
 #define LANG_HOOKS_TYPE_FOR_MODE       gfc_type_for_mode
 #define LANG_HOOKS_TYPE_FOR_SIZE       gfc_type_for_size
@@ -166,64 +156,13 @@ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
 static GTY(()) struct binding_level *free_binding_level;
 
-/* The elements of `ridpointers' are identifier nodes
-   for the reserved type names and storage classes.
-   It is indexed by a RID_... value.  */
-tree *ridpointers = NULL;
-
 /* True means we've initialized exception handling.  */
-bool gfc_eh_initialized_p;
+static bool gfc_eh_initialized_p;
 
 /* The current translation unit.  */
 static GTY(()) tree current_translation_unit;
 
 
-/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
-   or validate its data type for an `if' or `while' statement or ?..: exp.
-
-   This preparation consists of taking the ordinary
-   representation of an expression expr and producing a valid tree
-   boolean expression describing whether expr is nonzero.  We could
-   simply always do build_binary_op (NE_EXPR, expr, boolean_false_node, 1),
-   but we optimize comparisons, &&, ||, and !.
-
-   The resulting type should always be `boolean_type_node'.
-   This is much simpler than the corresponding C version because we have a
-   distinct boolean type.  */
-
-tree
-gfc_truthvalue_conversion (tree expr)
-{
-  switch (TREE_CODE (TREE_TYPE (expr)))
-    {
-    case BOOLEAN_TYPE:
-      if (TREE_TYPE (expr) == boolean_type_node)
-       return expr;
-      else if (COMPARISON_CLASS_P (expr))
-       {
-         TREE_TYPE (expr) = boolean_type_node;
-         return expr;
-       }
-      else if (TREE_CODE (expr) == NOP_EXPR)
-        return fold_build1_loc (input_location, NOP_EXPR,
-                           boolean_type_node, TREE_OPERAND (expr, 0));
-      else
-        return fold_build1_loc (input_location, NOP_EXPR, boolean_type_node,
-                               expr);
-
-    case INTEGER_TYPE:
-      if (TREE_CODE (expr) == INTEGER_CST)
-       return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
-      else
-        return fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
-                               expr, build_int_cst (TREE_TYPE (expr), 0));
-
-    default:
-      internal_error ("Unexpected type in truthvalue_conversion");
-    }
-}
-
-
 static void
 gfc_create_decls (void)
 {
@@ -255,7 +194,9 @@ gfc_be_parse_file (void)
   errorcount += errors;
   warningcount += warnings;
 
-  clear_binding_stack ();
+  /* Clear the binding level stack.  */
+  while (!global_bindings_p ())
+    poplevel (0, 0);
 }
 
 
@@ -299,11 +240,11 @@ gfc_finish (void)
 /* ??? This is something of a hack.
 
    Emulated tls lowering needs to see all TLS variables before we call
-   cgraph_finalize_compilation_unit.  The C/C++ front ends manage this
+   finalize_compilation_unit.  The C/C++ front ends manage this
    by calling decl_rest_of_compilation on each global and static variable
    as they are seen.  The Fortran front end waits until this hook.
 
-   A Correct solution is for cgraph_finalize_compilation_unit not to be
+   A Correct solution is for finalize_compilation_unit not to be
    called during the WRITE_GLOBALS langhook, and have that hook only do what
    its name suggests and write out globals.  But the C++ and Java front ends
    have (unspecified) problems with aliases that gets in the way.  It has
@@ -322,16 +263,6 @@ gfc_write_global_declarations (void)
   write_global_declarations ();
 }
 
-
-static void
-gfc_print_identifier (FILE * file ATTRIBUTE_UNUSED,
-                     tree node ATTRIBUTE_UNUSED,
-                     int indent ATTRIBUTE_UNUSED)
-{
-  return;
-}
-
-
 /* These functions and variables deal with binding contours.  We only
    need these functions for the list of PARM_DECLs, but we leave the
    functions more general; these are a simplified version of the
@@ -351,9 +282,7 @@ struct GTY(())
 binding_level {
   /* A chain of ..._DECL nodes for all variables, constants, functions,
      parameters and type declarations.  These ..._DECL nodes are chained
-     through the DECL_CHAIN field. Note that these ..._DECL nodes are stored
-     in the reverse of the order supplied to be compatible with the
-     back-end.  */
+     through the DECL_CHAIN field.  */
   tree names;
   /* For each level (except the global one), a chain of BLOCK nodes for all
      the levels that were entered and exited one level down from this one.  */
@@ -387,11 +316,10 @@ getdecls (void)
   return current_binding_level->names;
 }
 
-/* Enter a new binding level. The input parameter is ignored, but has to be
-   specified for back-end compatibility.  */
+/* Enter a new binding level. */
 
 void
-pushlevel (int ignore ATTRIBUTE_UNUSED)
+pushlevel (void)
 {
   struct binding_level *newlevel = ggc_alloc_binding_level ();
 
@@ -413,29 +341,19 @@ pushlevel (int ignore ATTRIBUTE_UNUSED)
 
    If FUNCTIONBODY is nonzero, this level is the body of a function,
    so create a block as if KEEP were set and also clear out all
-   label names.
-
-   If REVERSE is nonzero, reverse the order of decls before putting
-   them into the BLOCK.  */
+   label names.  */
 
 tree
-poplevel (int keep, int reverse, int functionbody)
+poplevel (int keep, int functionbody)
 {
   /* Points to a BLOCK tree node. This is the BLOCK node constructed for the
      binding level that we are about to exit and which is returned by this
      routine.  */
   tree block_node = NULL_TREE;
-  tree decl_chain;
+  tree decl_chain = current_binding_level->names;
   tree subblock_chain = current_binding_level->blocks;
   tree subblock_node;
 
-  /* Reverse the list of XXXX_DECL nodes if desired.  Note that the ..._DECL
-     nodes chained through the `names' field of current_binding_level are in
-     reverse order except for PARM_DECL node, which are explicitly stored in
-     the right order.  */
-  decl_chain = (reverse) ? nreverse (current_binding_level->names)
-                        : current_binding_level->names;
-
   /* If there were any declarations in the current binding level, or if this
      binding level is a function body, or if there are any nested blocks then
      create a BLOCK node to record them for the life of this function.  */
@@ -513,10 +431,7 @@ pushdecl (tree decl)
       DECL_CONTEXT (decl) = current_function_decl;
     }
 
-  /* Put the declaration on the list.  The list of declarations is in reverse
-     order. The list will be reversed later if necessary.  This needs to be
-     this way for compatibility with the back-end.  */
-
+  /* Put the declaration on the list.  */
   DECL_CHAIN (decl) = current_binding_level->names;
   current_binding_level->names = decl;
 
@@ -548,16 +463,6 @@ pushdecl_top_level (tree x)
   return t;
 }
 
-
-/* Clear the binding stack.  */
-static void
-clear_binding_stack (void)
-{
-  while (!global_bindings_p ())
-    poplevel (0, 0, 0);
-}
-
-
 #ifndef CHAR_TYPE_SIZE
 #define CHAR_TYPE_SIZE BITS_PER_UNIT
 #endif
@@ -582,7 +487,7 @@ gfc_init_decl_processing (void)
 
   /* Make the binding_level structure for global names. We move all
      variables that are in a COMMON block to this binding level.  */
-  pushlevel (0);
+  pushlevel ();
   global_binding_level = current_binding_level;
 
   /* Build common tree nodes. char_type_node is unsigned because we
@@ -617,23 +522,18 @@ gfc_get_alias_set (tree t)
   return -1;
 }
 
-
-/* press the big red button - garbage (ggc) collection is on */
-
-int ggc_p = 1;
-
 /* Builtin function initialization.  */
 
-tree
+static tree
 gfc_builtin_function (tree decl)
 {
-  make_decl_rtl (decl);
   pushdecl (decl);
   return decl;
 }
 
 /* So far we need just these 4 attribute types.  */
 #define ATTR_NOTHROW_LEAF_LIST         (ECF_NOTHROW | ECF_LEAF)
+#define ATTR_NOTHROW_LEAF_MALLOC_LIST  (ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
 #define ATTR_CONST_NOTHROW_LEAF_LIST   (ECF_NOTHROW | ECF_LEAF | ECF_CONST)
 #define ATTR_NOTHROW_LIST              (ECF_NOTHROW)
 #define ATTR_CONST_NOTHROW_LIST                (ECF_NOTHROW | ECF_CONST)
@@ -646,13 +546,7 @@ gfc_define_builtin (const char *name, tree type, enum built_in_function code,
 
   decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL,
                               library_name, NULL_TREE);
-  if (attr & ECF_CONST)
-    TREE_READONLY (decl) = 1;
-  if (attr & ECF_NOTHROW)
-    TREE_NOTHROW (decl) = 1;
-  if (attr & ECF_LEAF)
-    DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
-                                       NULL, DECL_ATTRIBUTES (decl));
+  set_call_expr_flags (decl, attr);
 
   set_builtin_decl (code, decl, true);
 }
@@ -704,7 +598,7 @@ build_builtin_fntypes (tree *fntype, tree type)
 static tree
 builtin_type_for_size (int size, bool unsignedp)
 {
-  tree type = lang_hooks.types.type_for_size (size, unsignedp);
+  tree type = gfc_type_for_size (size, unsignedp);
   return type ? type : error_mark_node;
 }
 
@@ -740,7 +634,6 @@ gfc_init_builtin_functions (void)
 #undef DEF_POINTER_TYPE
     BT_LAST
   };
-  typedef enum builtin_type builtin_type;
 
   tree mfunc_float[6];
   tree mfunc_double[6];
@@ -872,7 +765,11 @@ gfc_init_builtin_functions (void)
   gfc_define_builtin ("__builtin_fmodf", mfunc_float[1], 
                      BUILT_IN_FMODF, "fmodf", ATTR_CONST_NOTHROW_LEAF_LIST);
 
-  /* lround{f,,l} and llround{f,,l} */
+  /* iround{f,,l}, lround{f,,l} and llround{f,,l} */
+  ftype = build_function_type_list (integer_type_node,
+                                    float_type_node, NULL_TREE); 
+  gfc_define_builtin("__builtin_iroundf", ftype, BUILT_IN_IROUNDF,
+                    "iroundf", ATTR_CONST_NOTHROW_LEAF_LIST);
   ftype = build_function_type_list (long_integer_type_node,
                                     float_type_node, NULL_TREE); 
   gfc_define_builtin ("__builtin_lroundf", ftype, BUILT_IN_LROUNDF,
@@ -882,6 +779,10 @@ gfc_init_builtin_functions (void)
   gfc_define_builtin ("__builtin_llroundf", ftype, BUILT_IN_LLROUNDF,
                      "llroundf", ATTR_CONST_NOTHROW_LEAF_LIST);
 
+  ftype = build_function_type_list (integer_type_node,
+                                    double_type_node, NULL_TREE); 
+  gfc_define_builtin("__builtin_iround", ftype, BUILT_IN_IROUND,
+                    "iround", ATTR_CONST_NOTHROW_LEAF_LIST);
   ftype = build_function_type_list (long_integer_type_node,
                                     double_type_node, NULL_TREE); 
   gfc_define_builtin ("__builtin_lround", ftype, BUILT_IN_LROUND,
@@ -891,6 +792,10 @@ gfc_init_builtin_functions (void)
   gfc_define_builtin ("__builtin_llround", ftype, BUILT_IN_LLROUND,
                      "llround", ATTR_CONST_NOTHROW_LEAF_LIST);
 
+  ftype = build_function_type_list (integer_type_node,
+                                    long_double_type_node, NULL_TREE); 
+  gfc_define_builtin("__builtin_iroundl", ftype, BUILT_IN_IROUNDL,
+                    "iroundl", ATTR_CONST_NOTHROW_LEAF_LIST);
   ftype = build_function_type_list (long_integer_type_node,
                                     long_double_type_node, NULL_TREE); 
   gfc_define_builtin ("__builtin_lroundl", ftype, BUILT_IN_LROUNDL,
@@ -1004,13 +909,12 @@ gfc_init_builtin_functions (void)
   ftype = build_function_type_list (pvoid_type_node,
                                     size_type_node, NULL_TREE);
   gfc_define_builtin ("__builtin_malloc", ftype, BUILT_IN_MALLOC,
-                     "malloc", ATTR_NOTHROW_LEAF_LIST);
-  DECL_IS_MALLOC (builtin_decl_explicit (BUILT_IN_MALLOC)) = 1;
+                     "malloc", ATTR_NOTHROW_LEAF_MALLOC_LIST);
 
   ftype = build_function_type_list (pvoid_type_node, size_type_node,
                                    size_type_node, NULL_TREE);
   gfc_define_builtin ("__builtin_calloc", ftype, BUILT_IN_CALLOC,
-                     "calloc", ATTR_NOTHROW_LEAF_LIST);
+                     "calloc", ATTR_NOTHROW_LEAF_MALLOC_LIST);
   DECL_IS_MALLOC (builtin_decl_explicit (BUILT_IN_CALLOC)) = 1;
 
   ftype = build_function_type_list (pvoid_type_node,