X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Flibfirm%2Fadt%2Fobstack.h;h=21f9567f1a17e0fca066800f4b1f56bcad50456a;hb=43b545e3269a432382c13559abc75c15ebde83e7;hp=da4461827f8596738d3e98e9f69b207d75166083;hpb=ce6161a7e42a48f7422b7babcc64d8ace18e2687;p=libfirm diff --git a/include/libfirm/adt/obstack.h b/include/libfirm/adt/obstack.h index da4461827..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 @@ -108,6 +120,8 @@ Summary: #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 @@ -149,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 */ @@ -163,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 */ @@ -178,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 @@ -219,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)) @@ -495,25 +509,42 @@ __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__ */ +/** @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 -# define FIRM_NOTHROW throw () +# define FIRM_NOTHROW throw () +#else +# define FIRM_NOTHROW +#endif + +/** + * @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_NOTHROW +# 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. */ -int obstack_printf(struct obstack *obst, const char *fmt, ...) - FIRM_NOTHROW __attribute__ ((__format__ (__printf__, 2, 3))); -int obstack_vprintf(struct obstack *obst, const char *fmt, va_list ap) - FIRM_NOTHROW __attribute__ ((__format__ (__printf__, 2, 0))); +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"