Author: petdance
Date: Thu Jun  7 07:43:51 2007
New Revision: 18862

Modified:
   trunk/include/parrot/compiler.h
   trunk/include/parrot/hash.h
   trunk/include/parrot/intlist.h
   trunk/include/parrot/list.h
   trunk/include/parrot/objects.h
   trunk/include/parrot/pmc.h
   trunk/include/parrot/stacks.h
   trunk/include/parrot/string_funcs.h
   trunk/src/datatypes.c
   trunk/src/hash.c
   trunk/src/intlist.c
   trunk/src/list.c
   trunk/src/objects.c
   trunk/src/pmc.c
   trunk/src/stacks.c
   trunk/src/string.c
   trunk/tools/build/headerize.pl

Log:
The headerizer can now flag pure and const functions, as well as functions 
where ignoring the return value is an error.

Modified: trunk/include/parrot/compiler.h
==============================================================================
--- trunk/include/parrot/compiler.h     (original)
+++ trunk/include/parrot/compiler.h     Thu Jun  7 07:43:51 2007
@@ -31,6 +31,9 @@
 #ifdef HASATTRIBUTE_PURE
 #  define __attribute__pure__               __attribute__((pure))
 #endif
+#ifdef HASATTRIBUTE_CONST
+#  define __attribute__const__              __attribute__((const))
+#endif
 #ifdef HASATTRIBUTE_UNUSED
 #  define __attribute__unused__             __attribute__((unused))
 #endif

Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h (original)
+++ trunk/include/parrot/hash.h Thu Jun  7 07:43:51 2007
@@ -84,16 +84,26 @@
 PARROT_API void parrot_hash_destroy( Interp *interp, Hash *hash /*NN*/ )
         __attribute__nonnull__(2);
 
-PARROT_API INTVAL parrot_hash_exists( Interp *interp, Hash *hash, void *key );
-PARROT_API void * parrot_hash_get( Interp *interp, Hash *hash, void *key );
+PARROT_API INTVAL parrot_hash_exists( Interp *interp, Hash *hash, void *key )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
+
+PARROT_API void * parrot_hash_get( Interp *interp, Hash *hash, void *key )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
+
 PARROT_API HashBucket * parrot_hash_get_bucket( Interp *interp,
     const Hash *hash,
-    void *key );
+    void *key )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API void * parrot_hash_get_idx( Interp *interp,
     const Hash *hash,
     PMC *key /*NN*/ )
-        __attribute__nonnull__(3);
+        __attribute__nonnull__(3)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API HashBucket* parrot_hash_put( Interp *interp,
     Hash *hash,
@@ -101,7 +111,9 @@
     void *value );
 
 PARROT_API INTVAL parrot_hash_size( Interp *interp, Hash *hash /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API void parrot_hash_visit( Interp *interp,
     Hash *hash,

Modified: trunk/include/parrot/intlist.h
==============================================================================
--- trunk/include/parrot/intlist.h      (original)
+++ trunk/include/parrot/intlist.h      Thu Jun  7 07:43:51 2007
@@ -43,18 +43,26 @@
 void intlist_assign( Interp *i, IntList *l /*NN*/, INTVAL idx, INTVAL val )
         __attribute__nonnull__(2);
 
-IntList * intlist_clone( Interp *i, IntList *list );
+IntList * intlist_clone( Interp *i, IntList *list )
+        __attribute__warn_unused_result__;
+
 void intlist_dump( FILE *fp, IntList *list /*NN*/, int verbose )
         __attribute__nonnull__(2);
 
 INTVAL intlist_get( Interp *i, IntList *l /*NN*/, INTVAL idx )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 INTVAL intlist_length( Interp *interp, IntList *list /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 void intlist_mark( Interp *i, IntList *l );
-IntList * intlist_new( Interp *i );
+IntList * intlist_new( Interp *i )
+        __attribute__warn_unused_result__;
+
 INTVAL intlist_pop( Interp *i, IntList *l /*NN*/ )
         __attribute__nonnull__(2);
 

Modified: trunk/include/parrot/list.h
==============================================================================
--- trunk/include/parrot/list.h (original)
+++ trunk/include/parrot/list.h Thu Jun  7 07:43:51 2007
@@ -78,7 +78,10 @@
 
 /* HEADERIZER BEGIN: src/list.c */
 
-PARROT_API UINTVAL ld( UINTVAL x );
+PARROT_API UINTVAL ld( UINTVAL x )
+        __attribute__const__
+        __attribute__warn_unused_result__;
+
 PARROT_API void list_assign( Interp *interp,
     List *list /*NN*/,
     INTVAL idx,
@@ -87,7 +90,8 @@
         __attribute__nonnull__(2);
 
 PARROT_API List * list_clone( Interp *interp, List *other /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__warn_unused_result__;
 
 PARROT_API void list_delete( Interp *interp,
     List *list /*NN*/,
@@ -99,7 +103,9 @@
     List *list /*NN*/,
     INTVAL idx,
     int type )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__warn_unused_result__
+        __attribute__pure__;
 
 PARROT_API void list_insert( Interp *interp,
     List *list /*NN*/,
@@ -108,16 +114,21 @@
         __attribute__nonnull__(2);
 
 PARROT_API INTVAL list_length( Interp *interp, const List *list /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API void list_mark( Interp *interp, List *list /*NN*/ )
         __attribute__nonnull__(2);
 
-PARROT_API List * list_new( Interp *interp, INTVAL type );
+PARROT_API List * list_new( Interp *interp, INTVAL type )
+        __attribute__warn_unused_result__;
+
 PARROT_API List * list_new_init( Interp *interp,
     INTVAL type,
     PMC *init /*NN*/ )
-        __attribute__nonnull__(3);
+        __attribute__nonnull__(3)
+        __attribute__warn_unused_result__;
 
 PARROT_API void list_pmc_new( Interp *interp, PMC *container /*NN*/ )
         __attribute__nonnull__(2);

Modified: trunk/include/parrot/objects.h
==============================================================================
--- trunk/include/parrot/objects.h      (original)
+++ trunk/include/parrot/objects.h      Thu Jun  7 07:43:51 2007
@@ -40,8 +40,14 @@
     PMC *roles_list );
 
 PARROT_API PMC* Parrot_ComputeMRO_C3( Interp *interp, PMC *_class );
-PARROT_API INTVAL Parrot_MMD_method_idx( Interp *interp, const char *name );
-PARROT_API const char* Parrot_MMD_method_name( Interp *interp, INTVAL idx );
+PARROT_API INTVAL Parrot_MMD_method_idx( Interp *interp, const char *name )
+        __attribute__warn_unused_result__
+        __attribute__pure__;
+
+PARROT_API const char* Parrot_MMD_method_name( Interp *interp, INTVAL idx )
+        __attribute__warn_unused_result__
+        __attribute__pure__;
+
 PARROT_API INTVAL Parrot_add_attribute( Interp *interp,
     PMC* _class,
     STRING* attr );

Modified: trunk/include/parrot/pmc.h
==============================================================================
--- trunk/include/parrot/pmc.h  (original)
+++ trunk/include/parrot/pmc.h  Thu Jun  7 07:43:51 2007
@@ -40,7 +40,10 @@
     UINTVAL flags )
         __attribute__nonnull__(2);
 
-PARROT_API INTVAL pmc_type( Interp* interp, STRING *name );
+PARROT_API INTVAL pmc_type( Interp* interp, STRING *name )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
+
 PARROT_API INTVAL pmc_type_p( Interp* interp, PMC *name );
 /* HEADERIZER END: src/pmc.c */
 

Modified: trunk/include/parrot/stacks.h
==============================================================================
--- trunk/include/parrot/stacks.h       (original)
+++ trunk/include/parrot/stacks.h       Thu Jun  7 07:43:51 2007
@@ -54,7 +54,9 @@
 
 PARROT_API Stack_entry_type get_entry_type( Interp *interp,
     const Stack_Entry_t *entry /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API void mark_stack( Interp *interp, Stack_Chunk_t *chunk /*NN*/ )
         __attribute__nonnull__(2);
@@ -73,16 +75,22 @@
 PARROT_API Stack_Entry_t * stack_entry( Interp *interp,
     Stack_Chunk_t *stack /*NN*/,
     INTVAL depth )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API size_t stack_height( Interp *interp,
     const Stack_Chunk_t *chunk /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API void * stack_peek( Interp *interp,
     Stack_Chunk_t *stack_base /*NN*/,
     Stack_entry_type *type /*NULLOK*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API void * stack_pop( Interp *interp,
     Stack_Chunk_t **stack_p /*NN*/,

Modified: trunk/include/parrot/string_funcs.h
==============================================================================
--- trunk/include/parrot/string_funcs.h (original)
+++ trunk/include/parrot/string_funcs.h Thu Jun  7 07:43:51 2007
@@ -31,7 +31,9 @@
 
 PARROT_API const char * Parrot_string_cstring( Interp *interp,
     const STRING *str /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API INTVAL Parrot_string_find_cclass( Interp *interp,
     INTVAL flags,
@@ -95,9 +97,14 @@
     STRING *s2 /*NULLOK*/,
     STRING **dest /*NULLOK*/ );
 
-PARROT_API INTVAL string_bool( Interp *interp, const STRING *s /*NULLOK*/ );
+PARROT_API INTVAL string_bool( Interp *interp, const STRING *s /*NULLOK*/ )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
+
 PARROT_API UINTVAL string_capacity( Interp *interp, const STRING *s /*NN*/ )
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API STRING * string_chopn( Interp *interp,
     STRING *s /*NULLOK*/,
@@ -107,7 +114,9 @@
 PARROT_API STRING * string_chr( Interp *interp, UINTVAL character );
 PARROT_API INTVAL string_compare( Interp *interp,
     const STRING *s1 /*NULLOK*/,
-    const STRING *s2 /*NULLOK*/ );
+    const STRING *s2 /*NULLOK*/ )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API STRING * string_compose( Interp *interp, STRING *src /*NULLOK*/ );
 PARROT_API INTVAL string_compute_strlen( Interp *interp, STRING *s /*NN*/ )
@@ -129,7 +138,9 @@
 
 PARROT_API INTVAL string_equal( Interp *interp,
     const STRING *s1 /*NULLOK*/,
-    const STRING *s2 /*NULLOK*/ );
+    const STRING *s2 /*NULLOK*/ )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
 
 PARROT_API STRING * string_escape_string( Interp *interp,
     const STRING *src /*NULLOK*/ );
@@ -170,7 +181,10 @@
     STRING *j /*NULLOK*/,
     PMC *ar );
 
-PARROT_API UINTVAL string_length( Interp *interp, const STRING *s /*NULLOK*/ );
+PARROT_API UINTVAL string_length( Interp *interp, const STRING *s /*NULLOK*/ )
+        __attribute__pure__
+        __attribute__warn_unused_result__;
+
 PARROT_API STRING * string_make( Interp *interp,
     const char *buffer /*NULLOK*/,
     UINTVAL len,

Modified: trunk/src/datatypes.c
==============================================================================
--- trunk/src/datatypes.c       (original)
+++ trunk/src/datatypes.c       Thu Jun  7 07:43:51 2007
@@ -31,6 +31,7 @@
 PARROT_API
 INTVAL
 Parrot_get_datatype_enum(Interp *interp, const STRING * const typename /*NN*/)
+/* PURE, WARN_UNUSED */
 {
     char * const type = string_to_cstring(interp, typename);
     int i;
@@ -57,6 +58,7 @@
 PARROT_API
 STRING *
 Parrot_get_datatype_name(Interp *interp, INTVAL type)
+/* WARN_UNUSED */
 {
     const char * const s =
         (type < enum_first_type || type >= enum_last_type)

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c    (original)
+++ trunk/src/hash.c    Thu Jun  7 07:43:51 2007
@@ -655,6 +655,7 @@
 PARROT_API
 INTVAL
 parrot_hash_size(Interp *interp, Hash *hash /*NN*/)
+    /*PURE, WARN_UNUSED*/
 {
     UNUSED(interp);
 
@@ -674,6 +675,7 @@
 PARROT_API
 void *
 parrot_hash_get_idx(Interp *interp, const Hash *hash, PMC * const key /*NN*/)
+    /* PURE, WARN_UNUSED */
 {
     INTVAL i = PMC_int_val(key);
     const BucketIndex bi = (BucketIndex)PMC_data(key);
@@ -722,6 +724,7 @@
 PARROT_API
 HashBucket *
 parrot_hash_get_bucket(Interp *interp, const Hash *hash, void *key)
+    /* PURE, WARN_UNUSED */
 {
     const UINTVAL hashval = (hash->hash_val)(interp, key, hash->seed);
     HashBucket *bucket = hash->bi[hashval & hash->mask];
@@ -744,6 +747,7 @@
 PARROT_API
 void *
 parrot_hash_get(Interp *interp, Hash *hash, void *key)
+    /* PURE, WARN_UNUSED */
 {
     const HashBucket * const bucket = parrot_hash_get_bucket(interp, hash, 
key);
     return bucket ? bucket->value : NULL;
@@ -759,6 +763,7 @@
 PARROT_API
 INTVAL
 parrot_hash_exists(Interp *interp, Hash *hash, void *key)
+    /* PURE, WARN_UNUSED */
 {
     const HashBucket * const bucket = parrot_hash_get_bucket(interp, hash, 
key);
     return bucket ? 1 : 0;

Modified: trunk/src/intlist.c
==============================================================================
--- trunk/src/intlist.c (original)
+++ trunk/src/intlist.c Thu Jun  7 07:43:51 2007
@@ -168,6 +168,7 @@
 
 IntList *
 intlist_clone(Interp *i, IntList *list)
+    /* WARN_UNUSED */
 {
     return (IntList *)list_clone(i, (List *)list);
 }
@@ -185,6 +186,7 @@
 
 IntList *
 intlist_new(Interp *i)
+    /* WARN_UNUSED */
 {
     return (IntList *)list_new(i, enum_type_INTVAL);
 }
@@ -202,6 +204,7 @@
 
 INTVAL
 intlist_length(Interp *interp, IntList *list /*NN*/)
+    /* PURE, WARN_UNUSED */
 {
     UNUSED(interp);
     return ((List *)list)->length;
@@ -309,6 +312,7 @@
 
 INTVAL
 intlist_get(Interp *i, IntList *l /*NN*/, INTVAL idx)
+    /* PURE, WARN_UNUSED */
 {
     void * const ret = list_get(i, (List *)l, idx, enum_type_INTVAL);
     const INTVAL retval = ret == (void *)-1 ? 0 : *(INTVAL *)ret;

Modified: trunk/src/list.c
==============================================================================
--- trunk/src/list.c    (original)
+++ trunk/src/list.c    Thu Jun  7 07:43:51 2007
@@ -703,6 +703,7 @@
 PARROT_API
 UINTVAL
 ld(UINTVAL x)
+    /* CONST, WARN_UNUSED */
 {
     UINTVAL m;                  /* bit position of highest set bit of m */
 
@@ -1104,6 +1105,7 @@
 PARROT_API
 List *
 list_new(Interp *interp, INTVAL type)
+    /*WARN_UNUSED*/
 {
     List * const list = (List *)new_bufferlike_header(interp, sizeof (*list));
 
@@ -1175,6 +1177,7 @@
 PARROT_API
 List *
 list_new_init(Interp *interp, INTVAL type, PMC *init /*NN*/)
+    /* WARN_UNUSED */
 {
     List *list;
     PMC * user_array, *multi_key;
@@ -1268,11 +1271,14 @@
 
 TODO - Barely tested. Optimize new array structure, fixed if big.
 
+TODO - The *other arg should be able to be a const pointer
+
 */
 
 PARROT_API
 List *
-list_clone(Interp *interp, List *other /*NN*/) /* XXX This should be constable 
*/
+list_clone(Interp *interp, List * const other /*NN*/)
+    /* WARN_UNUSED */
 {
     List *l;
     List_chunk *chunk, *prev;
@@ -1416,6 +1422,7 @@
 PARROT_API
 INTVAL
 list_length(Interp *interp, const List * const list /*NN*/)
+    /* PURE, WARN_UNUSED */
 {
     UNUSED(interp);
     return list->length;
@@ -1757,6 +1764,7 @@
 PARROT_API
 void *
 list_get(Interp *interp, List *list /*NN*/, INTVAL idx, int type)
+    /* WARN_UNUSED, PURE */
 {
     const INTVAL length = list->length;
 

Modified: trunk/src/objects.c
==============================================================================
--- trunk/src/objects.c (original)
+++ trunk/src/objects.c Thu Jun  7 07:43:51 2007
@@ -371,6 +371,7 @@
 PARROT_API
 const char*
 Parrot_MMD_method_name(Interp *interp, INTVAL idx)
+    /* WARN_UNUSED, PURE */
 {
     assert(idx >= 0);
 
@@ -392,6 +393,7 @@
 PARROT_API
 INTVAL
 Parrot_MMD_method_idx(Interp *interp, const char * const name)
+    /* WARN_UNUSED, PURE */
 {
     INTVAL i;
 

Modified: trunk/src/pmc.c
==============================================================================
--- trunk/src/pmc.c     (original)
+++ trunk/src/pmc.c     Thu Jun  7 07:43:51 2007
@@ -366,6 +366,7 @@
 PARROT_API
 INTVAL
 pmc_type(Interp* interp, STRING * const name)
+    /* PURE, WARN_UNUSED */
 {
     PMC * const classname_hash = interp->class_hash;
     PMC * const item = (PMC *)VTABLE_get_pointer_keyed_str(interp, 
classname_hash, name);

Modified: trunk/src/stacks.c
==============================================================================
--- trunk/src/stacks.c  (original)
+++ trunk/src/stacks.c  Thu Jun  7 07:43:51 2007
@@ -96,6 +96,7 @@
 PARROT_API
 size_t
 stack_height(Interp *interp, const Stack_Chunk_t *chunk /*NN*/)
+    /* PURE, WARN_UNUSED */
 {
     size_t height = 0;
 
@@ -122,6 +123,7 @@
 PARROT_API
 Stack_Entry_t *
 stack_entry(Interp *interp, Stack_Chunk_t *stack /*NN*/, INTVAL depth)
+    /* PURE, WARN_UNUSED */
 {
     Stack_Chunk_t *chunk;
     Stack_Entry_t *entry;
@@ -348,6 +350,7 @@
 void *
 stack_peek(Interp *interp, Stack_Chunk_t *stack_base /*NN*/,
            Stack_entry_type *type /*NULLOK*/)
+    /* PURE, WARN_UNUSED */
 {
     const Stack_Entry_t * const entry = stack_entry(interp, stack_base, 0);
     if (entry == NULL) {
@@ -375,7 +378,8 @@
 
 PARROT_API
 Stack_entry_type
-get_entry_type(Interp *interp, const Stack_Entry_t *entry /*NN*/)
+get_entry_type(Interp *interp, const Stack_Entry_t * const entry /*NN*/)
+    /* PURE, WARN_UNUSED */
 {
     return entry->entry_type;
 }

Modified: trunk/src/string.c
==============================================================================
--- trunk/src/string.c  (original)
+++ trunk/src/string.c  Thu Jun  7 07:43:51 2007
@@ -299,6 +299,7 @@
 PARROT_API
 UINTVAL
 string_capacity(Interp *interp, const STRING *s /*NN*/)
+    /*PURE,WARN_UNUSED*/
 {
     return ((ptrcast_t)PObj_bufstart(s) + PObj_buflen(s) -
             (ptrcast_t)s->strstart);
@@ -691,6 +692,7 @@
 PARROT_API
 UINTVAL
 string_length(Interp *interp, const STRING *s /*NULLOK*/)
+    /*PURE,WARN_UNUSED*/
 {
     return s ? s->strlen : 0;
 }
@@ -1235,6 +1237,7 @@
 PARROT_API
 INTVAL
 string_compare(Interp *interp, const STRING * const s1 /*NULLOK*/, const 
STRING * const s2 /*NULLOK*/)
+    /* PURE, WARN_UNUSED */
 {
     if (!s1 && !s2) {
         return 0;
@@ -1266,7 +1269,8 @@
 
 PARROT_API
 INTVAL
-string_equal(Interp *interp, const STRING *s1 /*NULLOK*/, const STRING *s2 
/*NULLOK*/)
+string_equal(Interp *interp, const STRING * const s1 /*NULLOK*/, const STRING 
* const s2 /*NULLOK*/)
+    /* PURE, WARN_UNUSED */
 {
     if ((s1 == s2) || (!s1 && !s2)) {
         return 0;
@@ -1660,6 +1664,7 @@
 PARROT_API
 INTVAL
 string_bool(Interp *interp, const STRING *s /*NULLOK*/)
+    /* PURE, WARN_UNUSED */
 {
     const INTVAL len = string_length(interp, s);
 
@@ -2403,6 +2408,7 @@
 PARROT_API
 const char *
 Parrot_string_cstring(Interp *interp, const STRING *str /*NN*/)
+    /* PURE, WARN_UNUSED */
 {
     /* TODO handle NUL and friends */
     return str->strstart;

Modified: trunk/tools/build/headerize.pl
==============================================================================
--- trunk/tools/build/headerize.pl      (original)
+++ trunk/tools/build/headerize.pl      Thu Jun  7 07:43:51 2007
@@ -144,9 +144,11 @@
     my $parms      = join( " ", @lines );
 
     $parms =~ s/\s+/ /g;
-    $parms =~ s/([^(]+)\s*\((.+)\);?/$2/ or die qq{Couldn't handle "$proto"};
+    $parms =~ s{([^(]+)\s*\((.+)\)\s*(/\*\s*(.*?)\s*\*/)?;?}{$2} or die 
qq{Couldn't handle "$proto"};
     my $funcname = $1;
     $parms = $2;
+    my $funcflags = $4;
+
     my @parms = split( /\s*,\s*/, $parms );
     for (@parms) {
         /\S+\s+\S+/ || ( $_ eq '...' ) || ( $_ eq 'void' ) || /theINTERP/
@@ -165,7 +167,7 @@
 
     die "Impossible to have both static and PARROT_API" if $parrot_api && 
$static;
 
-    return [ $parrot_api, $static, $returntype, $funcname, @parms ];
+    return [ $parrot_api, $static, $returntype, $funcname, $funcflags, @parms 
];
 }
 
 sub attrs_from_args {
@@ -184,12 +186,44 @@
     return @attrs;
 }
 
+sub attrs_from_funcflags {
+    my $funcflags = shift;
+
+    return if not $funcflags;
+    return if $funcflags =~ /XXX/;
+
+    my @attrs = ();
+    my @opts = split( /\s*,\s*/, $funcflags );
+
+    # For details about these attributes, see
+    # http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Function-Attributes.html
+    for my $opt ( @opts ) {
+        if ( $opt eq 'WARN_UNUSED' ) {
+            push( @attrs, '__attribute__warn_unused_result__' );
+        }
+        elsif ( $opt eq 'NORETURN' ) {
+            push( @attrs, '__attribute__noreturn__' );
+        }
+        elsif ( $opt eq 'CONST' ) {
+            push( @attrs, '__attribute__const__' );
+        }
+        elsif ( $opt eq 'PURE' ) {
+            push( @attrs, '__attribute__pure__' );
+        }
+        else {
+            die qq{Unknown function flag "$funcflags" -> "$opt"\n};
+        }
+    }
+
+    return @attrs;
+}
+
 sub make_function_decls {
     my @funcs = @_;
 
     my @decls;
     foreach my $func ( @funcs ) {
-        my ($parrot_api, $static, $ret_type, $funcname, @args) = @{$func};
+        my ($parrot_api, $static, $ret_type, $funcname, $funcflags, @args) = 
@{$func};
         next if $static;
 
         my $multiline = 0;
@@ -198,6 +232,8 @@
         $decl = "PARROT_API $decl" if $parrot_api;
 
         my @attrs = attrs_from_args( @args );
+        push( @attrs, attrs_from_funcflags( $funcflags ) );
+
         my $argline = join( ", ", @args );
         if ( length($decl.$argline) <= 75 ) {
             $decl = "$decl $argline )";
@@ -211,6 +247,7 @@
             $decl = "$decl$argline )";
             $multiline = 1;
         }
+
         my $attrs = join( "", map { "\n\t\t$_" } @attrs );
         if ( $attrs ) {
             $decl .= $attrs;

Reply via email to