X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=include%2Flibfirm%2Fadt%2Fobstack.h;h=21f9567f1a17e0fca066800f4b1f56bcad50456a;hb=cdcd17c48e951c6e0201c58b94aaf52a8769703c;hp=5863b05bff74d8094e1713305b09da9f06b3b2c1;hpb=bb6d574bb9c74fca9f205b94aef021e57832aaad;p=libfirm diff --git a/include/libfirm/adt/obstack.h b/include/libfirm/adt/obstack.h index 5863b05bf..21f9567f1 100644 --- a/include/libfirm/adt/obstack.h +++ b/include/libfirm/adt/obstack.h @@ -18,6 +18,18 @@ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/** @page obstack Obstack Memory Allocation + * + * Obstacks are the prefered way to handle memory allocation in libFirm. + * Compared to classical malloc they are faster but don't allow fine-grained + * freeing of allocated memory. But in a compile this is fine most of the time + * as memory is allocated for a phase or a graph and later the whole phase ends + * or the whole graph gets discarded. + * + * There's very good documentation about Object stacks in the glibc manual: + * http://www.gnu.org/s/libc/manual/html_node/Obstacks.html + */ + /* Summary: All the apparent functions defined here are macros. The idea @@ -106,10 +118,10 @@ Summary: #ifndef _OBSTACK_H #define _OBSTACK_H 1 -#ifdef __cplusplus -extern "C" { -#endif - +#include "../begin.h" + +/** @cond DISABLED */ + /* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is defined, as with GNU C, use that; that way we don't pollute the namespace with 's symbols. Otherwise, include @@ -151,7 +163,7 @@ struct _obstack_chunk /* Lives at front of each chunk. */ struct obstack /* control current object in current chunk */ { - long chunk_size; /* preferred size to allocate chunks in */ + PTR_INT_TYPE chunk_size; /* preferred size to allocate chunks in */ struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ char *object_base; /* address of object we are building */ char *next_free; /* where to add next char to current object */ @@ -165,7 +177,7 @@ struct obstack /* control current object in current chunk */ /* These prototypes vary based on `use_extra_arg', and we use casts to the prototypeless function type in all assignments, but having prototypes here quiets -Wstrict-prototypes. */ - struct _obstack_chunk *(*chunkfun) (void *, long); + struct _obstack_chunk *(*chunkfun) (void *, PTR_INT_TYPE); void (*freefun) (void *, struct _obstack_chunk *); void *extra_arg; /* first arg for chunk alloc/dealloc funcs */ unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ @@ -180,25 +192,25 @@ struct obstack /* control current object in current chunk */ /* Declare the external functions we use; they are in obstack.c. */ -extern void _obstack_newchunk (struct obstack *, int); -extern int _obstack_begin (struct obstack *, int, int, - void *(*) (long), void (*) (void *)); -extern int _obstack_begin_1 (struct obstack *, int, int, - void *(*) (void *, long), - void (*) (void *, void *), void *); -extern int _obstack_memory_used (struct obstack *); +FIRM_API void _obstack_newchunk (struct obstack *, PTR_INT_TYPE); +FIRM_API int _obstack_begin (struct obstack *, int, int, + void *(*) (PTR_INT_TYPE), void (*) (void *)); +FIRM_API int _obstack_begin_1 (struct obstack *, int, int, + void *(*) (void *, PTR_INT_TYPE), + void (*) (void *, void *), void *); +FIRM_API PTR_INT_TYPE _obstack_memory_used (struct obstack *); -void obstack_free (struct obstack *obstack, void *block); +FIRM_API void obstack_free (struct obstack *obstack, void *block); /* Error handler called when `obstack_chunk_alloc' failed to allocate more memory. This can be set to a user defined function which should either abort gracefully or use longjump - but shouldn't return. The default action is to print a message and abort. */ -extern void (*obstack_alloc_failed_handler) (void); +FIRM_API void (*obstack_alloc_failed_handler) (void); /* Exit value used when `print_and_abort' is used. */ -extern int obstack_exit_failure; +FIRM_API int obstack_exit_failure; /* Pointer to beginning of object being allocated or to be allocated next. Note that this might not be the final address of the object @@ -221,26 +233,26 @@ extern int obstack_exit_failure; /* To prevent prototype warnings provide complete argument list. */ #define obstack_init(h) \ _obstack_begin ((h), 0, 0, \ - (void *(*) (long)) obstack_chunk_alloc, \ + (void *(*) (PTR_INT_TYPE)) obstack_chunk_alloc, \ (void (*) (void *)) obstack_chunk_free) #define obstack_begin(h, size) \ _obstack_begin ((h), (size), 0, \ - (void *(*) (long)) obstack_chunk_alloc, \ + (void *(*) (PTR_INT_TYPE)) obstack_chunk_alloc, \ (void (*) (void *)) obstack_chunk_free) #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ _obstack_begin ((h), (size), (alignment), \ - (void *(*) (long)) (chunkfun), \ + (void *(*) (PTR_INT_TYPE)) (chunkfun), \ (void (*) (void *)) (freefun)) #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ _obstack_begin_1 ((h), (size), (alignment), \ - (void *(*) (void *, long)) (chunkfun), \ + (void *(*) (void *, PTR_INT_TYPE)) (chunkfun), \ (void (*) (void *, void *)) (freefun), (arg)) #define obstack_chunkfun(h, newchunkfun) \ - ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun)) + ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, PTR_INT_TYPE)) (newchunkfun)) #define obstack_freefun(h, newfreefun) \ ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun)) @@ -497,17 +509,43 @@ __extension__ \ ( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ ((((h)->temp.tempint > 0 \ && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ - ? (int) ((h)->next_free = (h)->object_base \ + ? (PTR_INT_TYPE) ((h)->next_free = (h)->object_base \ = (h)->temp.tempint + (char *) (h)->chunk) \ : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0))) #endif /* not __GNUC__ or not __STDC__ */ -int obstack_vprintf(struct obstack *obst, const char *fmt, va_list ap); -int obstack_printf(struct obstack *obst, const char *fmt, ...); - +/** @def FIRM_NOTHROW + * tells that a function does not throw C++ exceptions. Currently this is only + * necessary for obstack_printf to avoid nameclashes when linking with glibc + * which has an obstack library with NOTHROW builtin. */ #ifdef __cplusplus -} /* C++ */ +# define FIRM_NOTHROW throw () +#else +# define FIRM_NOTHROW #endif -#endif /* obstack.h */ +/** + * @def FIRM_PRINTF + * Attribute with marks a function to have a printf style format + * string and variadic argument. + */ +#if defined(__GNUC__) +# define FIRM_PRINTF(a,b) __attribute__((__format__(__printf__, a, b))) +#else +# define FIRM_PRINTF(a,b) +#endif + +/** prints formated string (printf-style format) to an obstack. + * This is done by "growing" the obstack with the obstack_*grow* + * functions. Note: Does NOT append a null-byte. */ +FIRM_API int obstack_printf(struct obstack *obst, const char *fmt, ...) + FIRM_NOTHROW FIRM_PRINTF(2, 3); +FIRM_API int obstack_vprintf(struct obstack *obst, const char *fmt, va_list ap) + FIRM_NOTHROW FIRM_PRINTF(2, 0); + +/** @endcond */ + +#include "../end.h" + +#endif