OSDN Git Service

2005-06-28 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / libiberty / alloca.c
index 911d42f..9b2e9cb 100644 (file)
    allocating any.  It is a good idea to use alloca(0) in
    your main control loop, etc. to force garbage collection.  */
 
+/*
+
+@deftypefn Replacement void* alloca (size_t @var{size})
+
+This function allocates memory which will be automatically reclaimed
+after the procedure exits.  The @libib{} implementation does not free
+the memory immediately but will do so eventually during subsequent
+calls to this function.  Memory is allocated using @code{xmalloc} under
+normal circumstances.
+
+The header file @file{alloca-conf.h} can be used in conjunction with the
+GNU Autoconf test @code{AC_FUNC_ALLOCA} to test for and properly make
+available this function.  The @code{AC_FUNC_ALLOCA} test requires that
+client code use a block of preprocessor code to be safe (see the Autoconf
+manual for more); this header incorporates that logic and more, including
+the possibility of a GCC built-in function.
+
+@end deftypefn
+
+*/
+
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
-/* If compiling with GCC, this file's not needed.  */
-#ifndef alloca
+#include <libiberty.h>
 
-#ifdef emacs
-#ifdef static
-/* actually, only want this if static is defined as ""
-   -- this is for usg, in which emacs must undefine static
-   in order to make unexec workable
-   */
-#ifndef STACK_DIRECTION
-you
-lose
--- must know STACK_DIRECTION at compile-time
-#endif /* STACK_DIRECTION undefined */
-#endif /* static */
-#endif /* emacs */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+/* These variables are used by the ASTRDUP implementation that relies
+   on C_alloca.  */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+const char *libiberty_optr;
+char *libiberty_nptr;
+unsigned long libiberty_len;
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
 
 /* If your stack is a linked list of frames, you have to
    provide an "address metric" ADDRESS_FUNCTION macro.  */
 
 #if defined (CRAY) && defined (CRAY_STACKSEG_END)
-long i00afunc ();
+static long i00afunc ();
 #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
 #else
 #define ADDRESS_FUNCTION(arg) &(arg)
 #endif
 
-#if __STDC__
-#include <stddef.h>
-typedef void *pointer;
-#else
-typedef char *pointer;
-typedef unsigned size_t;
-#endif
-
 #ifndef NULL
 #define        NULL    0
 #endif
 
-/* Different portions of Emacs need to call different versions of
-   malloc.  The Emacs executable needs alloca to call xmalloc, because
-   ordinary malloc isn't protected from input signals.  On the other
-   hand, the utilities in lib-src need alloca to call malloc; some of
-   them are very simple, and don't have an xmalloc routine.
-
-   Non-Emacs programs expect this to call use xmalloc.
-
-   Callers below should use malloc.  */
-
-#ifndef emacs
-#define malloc xmalloc
-extern pointer xmalloc ();
-#endif
-
 /* Define STACK_DIRECTION if you know the direction of stack
    growth for your system; otherwise it will be automatically
    deduced at run-time.
@@ -101,7 +103,7 @@ static int stack_dir;               /* 1 or -1 once known.  */
 #define        STACK_DIR       stack_dir
 
 static void
-find_stack_direction ()
+find_stack_direction (void)
 {
   static char *addr = NULL;    /* Address of first `dummy', once known.  */
   auto char dummy;             /* To get stack address.  */
@@ -154,9 +156,10 @@ static header *last_alloca_header = NULL;  /* -> last alloca header.  */
    caller, but that method cannot be made to work for some
    implementations of C, for example under Gould's UTX/32.  */
 
-pointer
-alloca (size)
-     size_t size;
+/* @undocumented C_alloca */
+
+PTR
+C_alloca (size_t size)
 {
   auto char probe;             /* Probes stack depth: */
   register char *depth = ADDRESS_FUNCTION (probe);
@@ -167,7 +170,7 @@ alloca (size)
 #endif
 
   /* Reclaim garbage, defined as all alloca'd storage that
-     was allocated from deeper in the stack than currently. */
+     was allocated from deeper in the stack than currently.  */
 
   {
     register header *hp;       /* Traverses linked list.  */
@@ -178,7 +181,7 @@ alloca (size)
        {
          register header *np = hp->h.next;
 
-         free ((pointer) hp);  /* Collect garbage.  */
+         free ((PTR) hp);      /* Collect garbage.  */
 
          hp = np;              /* -> next header.  */
        }
@@ -194,17 +197,20 @@ alloca (size)
   /* Allocate combined header + user data storage.  */
 
   {
-    register pointer new = malloc (sizeof (header) + size);
+    register void *new_storage = XNEWVEC (char, sizeof (header) + size);
     /* Address of header.  */
 
-    ((header *) new)->h.next = last_alloca_header;
-    ((header *) new)->h.deep = depth;
+    if (new_storage == 0)
+      abort();
 
-    last_alloca_header = (header *) new;
+    ((header *) new_storage)->h.next = last_alloca_header;
+    ((header *) new_storage)->h.deep = depth;
+
+    last_alloca_header = (header *) new_storage;
 
     /* User storage begins just after header.  */
 
-    return (pointer) ((char *) new + sizeof (header));
+    return (PTR) ((char *) new_storage + sizeof (header));
   }
 }
 
@@ -326,7 +332,7 @@ struct stk_trailer
 
 #ifdef CRAY2
 /* Determine a "stack measure" for an arbitrary ADDRESS.
-   I doubt that "lint" will like this much. */
+   I doubt that "lint" will like this much.  */
 
 static long
 i00afunc (long *address)
@@ -475,5 +481,3 @@ i00afunc (long address)
 
 #endif /* not CRAY2 */
 #endif /* CRAY */
-
-#endif /* no alloca */