update hashset, try to identify all global function entities
authorMatthias Braun <matze@braunis.de>
Wed, 4 Jun 2008 12:34:29 +0000 (12:34 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 4 Jun 2008 12:34:29 +0000 (12:34 +0000)
[r19969]

Makefile
adt/hashset.c
adt/hashset.h
adt/strset.c
adt/strset.h
ast2firm.c
symbol_table.c
symbol_table_t.h
type_hash.c

index 963fa2f..32bd0b6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,7 @@ SOURCES := \
        ast.c \
        ast2firm.c \
        diagnostic.c \
+       entitymap.c \
        format_check.c \
        lexer.c \
        main.c \
index d7fb989..415aaab 100644 (file)
@@ -1,29 +1,28 @@
 /*
- * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This file is part of libFirm.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
  */
 
 /**
  * @file
- * @date    17.03.2007
- * @brief   Geberic hashset implementation
+ * @brief   Generic hashset implementation
  * @author  Matthias Braun, inspiration from densehash from google sparsehash
  *          package
+ * @date    17.03.2007
  * @version $Id$
  *
  *
 /* quadratic probing */
 #ifndef JUMP
 #define JUMP(num_probes)      (num_probes)
-#endif
+#endif /* JUMP */
 
 #ifndef Hash
 #define ID_HASH
-#define Hash(this,value)      ((unsigned)(value))
-#endif
+#define Hash(self,key)        ((unsigned)(((char *)key) - (char *)0))
+#endif /* Hash */
 
 #ifdef DO_REHASH
 #define HashSetEntry                   ValueType
 #define EntrySetHash(entry,new_hash)
-#define EntryGetHash(this,entry)       Hash(this,entry)
+#define EntryGetHash(self,entry)       Hash(self, GetKey(entry))
 #define EntryGetValue(entry)           (entry)
-#else
-#define EntryGetHash(this,entry)       (entry).hash
+#else /* ! DO_REHASH */
+#define EntryGetHash(self,entry)       (entry).hash
 #define EntrySetHash(entry,new_hash)   (entry).hash = (new_hash)
 #define EntryGetValue(entry)           (entry).data
-#endif
+#endif /* DO_REHASH */
 
 #ifndef Alloc
 #include "xmalloc.h"
 #define Alloc(size)    (HashSetEntry*) xmalloc((size) * sizeof(HashSetEntry))
 #define Free(ptr)      free(ptr)
-#endif
+#endif /* Alloc */
 
 #ifdef ID_HASH
-#define InsertReturnValue               int
-#define GetInsertReturnValue(entry,new) (new)
+#define InsertReturnValue                 int
+#define GetInsertReturnValue(entry,found) (found)
+#define NullReturnValue                   0
+#else /* ! ID_HASH */
+#ifdef SCALAR_RETURN
+#define InsertReturnValue                 ValueType
+#define GetInsertReturnValue(entry,found) EntryGetValue(entry)
+#define NullReturnValue                   NullValue
 #else
-#define InsertReturnValue               ValueType
-#define GetInsertReturnValue(entry,new) EntryGetValue(entry)
+#define InsertReturnValue                 ValueType*
+#define GetInsertReturnValue(entry,found) & EntryGetValue(entry)
+#define NullReturnValue                   & NullValue
 #endif
+#endif /* ID_HASH */
 
 #ifndef KeyType
 #define KeyType                  ValueType
 #define GetKey(value)            (value)
-#define InitData(this,value,key) (value) = (key)
-#endif
+#define InitData(self,value,key) (value) = (key)
+#endif /* KeyType */
 
 #ifndef ConstKeyType
 #define ConstKeyType             const KeyType
-#endif
+#endif /* ConstKeyType */
 
 #ifndef EntrySetEmpty
 #define EntrySetEmpty(entry)    EntryGetValue(entry) = NullValue
-#endif
+#endif /* EntrySetEmpty */
 #ifndef EntrySetDeleted
 #define EntrySetDeleted(entry)  EntryGetValue(entry) = DeletedValue
-#endif
+#endif /* EntrySetDeleted */
 #ifndef EntryIsEmpty
 #define EntryIsEmpty(entry)     (EntryGetValue(entry) == NullValue)
-#endif
+#endif /* EntryIsEmpty */
 #ifndef EntryIsDeleted
 #define EntryIsDeleted(entry)   (EntryGetValue(entry) == DeletedValue)
-#endif
+#endif /* EntryIsDeleted */
 #ifndef SetRangeEmpty
 #define SetRangeEmpty(ptr,size)                \
 {                                              \
                EntrySetEmpty(*entry);                 \
        }                                          \
 }
-#endif
+#endif /* SetRangeEmpty */
 
 #ifndef HT_OCCUPANCY_FLT
 /** how full before we double size */
-#define HT_OCCUPANCY_FLT  0.5f
+#define HT_OCCUPANCY_FLT(x) ((x)/2)
+#endif /* HT_OCCUPANCY_FLT */
+#ifndef HT_1_DIV_OCCUPANCY_FLT
+#define HT_1_DIV_OCCUPANCY_FLT 2
 #endif
 
 #ifndef HT_EMPTY_FLT
 /** how empty before we half size */
-#define HT_EMPTY_FLT      (0.4f * (HT_OCCUPANCY_FLT))
-#endif
+#define HT_EMPTY_FLT(x)     ((x)/5)
+#endif /* HT_EMPTY_FLT */
 
 #ifndef HT_MIN_BUCKETS
 /** default smallest bucket size */
 #define HT_MIN_BUCKETS    32
-#endif
+#endif /* HT_MIN_BUCKETS */
 
 #define ILLEGAL_POS       ((size_t)-1)
 
+/* check that all needed functions are defined */
 #ifndef hashset_init
 #error You have to redefine hashset_init
 #endif
 #error You have to redefine hashset_remove_iterator
 #endif
 
-/* prototypes to silence warnings */
-size_t hashset_size(const HashSet *this);
-void hashset_init(HashSet *this);
-void hashset_init_size(HashSet *this, size_t size);
-void hashset_destroy(HashSet *this);
-InsertReturnValue hashset_insert(HashSet *this, KeyType key);
-ValueType hashset_find(const HashSet *this, ConstKeyType key);
-void hashset_remove(HashSet *this, ConstKeyType key);
-void hashset_iterator_init(HashSetIterator *this, const HashSet *hashset);
-ValueType hashset_iterator_next(HashSetIterator *this);
-void hashset_remove_iterator(HashSet *this, const HashSetIterator *iter);
+/* prototypes to avoid warnings */
+void hashset_init(HashSet *self);
+void hashset_destroy(HashSet *self);
+size_t hashset_size(const HashSet *self);
+InsertReturnValue hashset_insert(HashSet *self, KeyType key);
+InsertReturnValue hashset_find(const HashSet *self, ConstKeyType key);
+void hashset_remove(HashSet *self, ConstKeyType key);
+void hashset_init_size(HashSet *self, size_t expected_elements);
+void hashset_iterator_init(HashSetIterator *self, const HashSet *hashset);
+ValueType hashset_iterator_next(HashSetIterator *self);
+void hashset_remove_iterator(HashSet *self, const HashSetIterator *iter);
 
 /**
  * Returns the number of elements in the hashset
  */
-size_t hashset_size(const HashSet *this)
+size_t hashset_size(const HashSet *self)
 {
-       return this->num_elements - this->num_deleted;
+       return self->num_elements - self->num_deleted;
 }
 
 /**
@@ -218,19 +229,19 @@ size_t hashset_size(const HashSet *this)
  * @internal
  */
 static inline
-InsertReturnValue insert_nogrow(HashSet *this, KeyType key)
+InsertReturnValue insert_nogrow(HashSet *self, KeyType key)
 {
-       size_t num_probes = 0;
-       size_t num_buckets = this->num_buckets;
-       size_t hashmask = num_buckets - 1;
-       unsigned hash = Hash(this, key);
-       size_t bucknum = hash & hashmask;
-       size_t insert_pos = ILLEGAL_POS;
+       size_t   num_probes  = 0;
+       size_t   num_buckets = self->num_buckets;
+       size_t   hashmask    = num_buckets - 1;
+       unsigned hash        = Hash(self, key);
+       size_t   bucknum     = hash & hashmask;
+       size_t   insert_pos  = ILLEGAL_POS;
 
        assert((num_buckets & (num_buckets - 1)) == 0);
 
        while(1) {
-               HashSetEntry *entry = & this->entries[bucknum];
+               HashSetEntry *entry = & self->entries[bucknum];
 
                if(EntryIsEmpty(*entry)) {
                        size_t p;
@@ -242,19 +253,19 @@ InsertReturnValue insert_nogrow(HashSet *this, KeyType key)
                                p = bucknum;
                        }
 
-                       nentry = &this->entries[p];
-                       InitData(this, EntryGetValue(*nentry), key);
+                       nentry = &self->entries[p];
+                       InitData(self, EntryGetValue(*nentry), key);
                        EntrySetHash(*nentry, hash);
-                       this->num_elements++;
-                       return GetInsertReturnValue(*nentry, 1);
+                       self->num_elements++;
+                       return GetInsertReturnValue(*nentry, 0);
                }
                if(EntryIsDeleted(*entry)) {
                        if(insert_pos == ILLEGAL_POS)
                                insert_pos = bucknum;
-               } else if(EntryGetHash(this, *entry) == hash) {
-                       if(KeysEqual(this, GetKey(EntryGetValue(*entry)), key)) {
+               } else if(EntryGetHash(self, *entry) == hash) {
+                       if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) {
                                // Value already in the set, return it
-                               return GetInsertReturnValue(*entry, 0);
+                               return GetInsertReturnValue(*entry, 1);
                        }
                }
 
@@ -270,21 +281,21 @@ InsertReturnValue insert_nogrow(HashSet *this, KeyType key)
  * @internal
  */
 static
-void insert_new(HashSet *this, unsigned hash, ValueType value)
+void insert_new(HashSet *self, unsigned hash, ValueType value)
 {
-       size_t num_probes = 0;
-       size_t num_buckets = this->num_buckets;
-       size_t hashmask = num_buckets - 1;
-       size_t bucknum = hash & hashmask;
-       size_t insert_pos = ILLEGAL_POS;
+       size_t num_probes  = 0;
+       size_t num_buckets = self->num_buckets;
+       size_t hashmask    = num_buckets - 1;
+       size_t bucknum     = hash & hashmask;
+       size_t insert_pos  = ILLEGAL_POS;
 
-       assert(value != NullValue);
+       //assert(value != NullValue);
 
        while(1) {
-               HashSetEntry *entry = & this->entries[bucknum];
+               HashSetEntry *entry = & self->entries[bucknum];
 
                if(EntryIsEmpty(*entry)) {
-                       size_t p;
+                       size_t        p;
                        HashSetEntry *nentry;
 
                        if(insert_pos != ILLEGAL_POS) {
@@ -292,11 +303,11 @@ void insert_new(HashSet *this, unsigned hash, ValueType value)
                        } else {
                                p = bucknum;
                        }
-                       nentry = &this->entries[p];
+                       nentry = &self->entries[p];
 
                        EntryGetValue(*nentry) = value;
                        EntrySetHash(*nentry, hash);
-                       this->num_elements++;
+                       self->num_elements++;
                        return;
                }
                assert(!EntryIsDeleted(*entry));
@@ -312,11 +323,11 @@ void insert_new(HashSet *this, unsigned hash, ValueType value)
  * @internal
  */
 static inline
-void reset_thresholds(HashSet *this)
+void reset_thresholds(HashSet *self)
 {
-       this->enlarge_threshold = (size_t) (this->num_buckets * HT_OCCUPANCY_FLT);
-       this->shrink_threshold = (size_t) (this->num_buckets * HT_EMPTY_FLT);
-       this->consider_shrink = 0;
+       self->enlarge_threshold = (size_t) HT_OCCUPANCY_FLT(self->num_buckets);
+       self->shrink_threshold  = (size_t) HT_EMPTY_FLT(self->num_buckets);
+       self->consider_shrink   = 0;
 }
 
 /**
@@ -324,11 +335,11 @@ void reset_thresholds(HashSet *this)
  * @internal
  */
 static inline
-void resize(HashSet *this, size_t new_size)
+void resize(HashSet *self, size_t new_size)
 {
-       size_t num_buckets = this->num_buckets;
+       size_t num_buckets = self->num_buckets;
        size_t i;
-       HashSetEntry *old_entries = this->entries;
+       HashSetEntry *old_entries = self->entries;
        HashSetEntry *new_entries;
 
        /* allocate a new array with double size */
@@ -336,14 +347,14 @@ void resize(HashSet *this, size_t new_size)
        SetRangeEmpty(new_entries, new_size);
 
        /* use the new array */
-       this->entries = new_entries;
-       this->num_buckets = new_size;
-       this->num_elements = 0;
-       this->num_deleted = 0;
+       self->entries      = new_entries;
+       self->num_buckets  = new_size;
+       self->num_elements = 0;
+       self->num_deleted  = 0;
 #ifndef NDEBUG
-       this->entries_version++;
+       self->entries_version++;
 #endif
-       reset_thresholds(this);
+       reset_thresholds(self);
 
        /* reinsert all elements */
        for(i = 0; i < num_buckets; ++i) {
@@ -351,7 +362,7 @@ void resize(HashSet *this, size_t new_size)
                if(EntryIsEmpty(*entry) || EntryIsDeleted(*entry))
                        continue;
 
-               insert_new(this, EntryGetHash(this, *entry), EntryGetValue(*entry));
+               insert_new(self, EntryGetHash(self, *entry), EntryGetValue(*entry));
        }
 
        /* now we can free the old array */
@@ -363,16 +374,16 @@ void resize(HashSet *this, size_t new_size)
  * @internal
  */
 static inline
-void maybe_grow(HashSet *this)
+void maybe_grow(HashSet *self)
 {
        size_t resize_to;
 
-       if(LIKELY(this->num_elements + 1 <= this->enlarge_threshold))
+       if(LIKELY(self->num_elements + 1 <= self->enlarge_threshold))
                return;
 
        /* double table size */
-       resize_to = this->num_buckets * 2;
-       resize(this, resize_to);
+       resize_to = self->num_buckets * 2;
+       resize(self, resize_to);
 }
 
 /**
@@ -380,17 +391,20 @@ void maybe_grow(HashSet *this)
  * @internal
  */
 static inline
-void maybe_shrink(HashSet *this)
+void maybe_shrink(HashSet *self)
 {
        size_t size;
        size_t resize_to;
 
-       if(!this->consider_shrink)
+       if(!self->consider_shrink)
                return;
 
-       this->consider_shrink = 0;
-       size = hashset_size(this);
-       if(LIKELY(size > this->shrink_threshold))
+       self->consider_shrink = 0;
+       size                  = hashset_size(self);
+       if(size <= HT_MIN_BUCKETS)
+               return;
+
+       if(LIKELY(size > self->shrink_threshold))
                return;
 
        resize_to = ceil_po2(size);
@@ -398,7 +412,7 @@ void maybe_shrink(HashSet *this)
        if(resize_to < 4)
                resize_to = 4;
 
-       resize(this, resize_to);
+       resize(self, resize_to);
 }
 
 /**
@@ -407,48 +421,48 @@ void maybe_shrink(HashSet *this)
  * Otherwise the exisiting element is returned (for hashs where key is equal to
  * value, nothing is returned.)
  *
- * @param this   the hashset
+ * @param self   the hashset
  * @param key    the key that identifies the data
  * @returns      the existing or newly created data element (or nothing in case of hashs where keys are the while value)
  */
-InsertReturnValue hashset_insert(HashSet *this, KeyType key)
+InsertReturnValue hashset_insert(HashSet *self, KeyType key)
 {
 #ifndef NDEBUG
-       this->entries_version++;
+       self->entries_version++;
 #endif
 
-       maybe_shrink(this);
-       maybe_grow(this);
-       return insert_nogrow(this, key);
+       maybe_shrink(self);
+       maybe_grow(self);
+       return insert_nogrow(self, key);
 }
 
 /**
  * Searchs for an element with key @p key.
  *
- * @param this      the hashset
+ * @param self      the hashset
  * @param key       the key to search for
  * @returns         the found value or NullValue if nothing was found
  */
-ValueType hashset_find(const HashSet *this, ConstKeyType key)
+InsertReturnValue hashset_find(const HashSet *self, ConstKeyType key)
 {
-       size_t num_probes = 0;
-       size_t num_buckets = this->num_buckets;
-       size_t hashmask = num_buckets - 1;
-       unsigned hash = Hash(this, key);
-       size_t bucknum = hash & hashmask;
+       size_t   num_probes  = 0;
+       size_t   num_buckets = self->num_buckets;
+       size_t   hashmask    = num_buckets - 1;
+       unsigned hash        = Hash(self, key);
+       size_t   bucknum     = hash & hashmask;
 
        while(1) {
-               HashSetEntry *entry = & this->entries[bucknum];
+               HashSetEntry *entry = & self->entries[bucknum];
 
                if(EntryIsEmpty(*entry)) {
-                       return NullValue;
+                       return NullReturnValue;
                }
                if(EntryIsDeleted(*entry)) {
                        // value is deleted
-               } else if(EntryGetHash(this, *entry) == hash) {
-                       if(KeysEqual(this, GetKey(EntryGetValue(*entry)), key)) {
+               } else if(EntryGetHash(self, *entry) == hash) {
+                       if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) {
                                // found the value
-                               return EntryGetValue(*entry);
+                               return GetInsertReturnValue(*entry, 1);
                        }
                }
 
@@ -462,34 +476,34 @@ ValueType hashset_find(const HashSet *this, ConstKeyType key)
  * Removes an element from a hashset. Does nothing if the set doesn't contain
  * the element.
  *
- * @param this    the hashset
+ * @param self    the hashset
  * @param key     key that identifies the data to remove
  */
-void hashset_remove(HashSet *this, ConstKeyType key)
+void hashset_remove(HashSet *self, ConstKeyType key)
 {
-       size_t num_probes = 0;
-       size_t num_buckets = this->num_buckets;
-       size_t hashmask = num_buckets - 1;
-       unsigned hash = Hash(this, key);
-       size_t bucknum = hash & hashmask;
+       size_t   num_probes  = 0;
+       size_t   num_buckets = self->num_buckets;
+       size_t   hashmask    = num_buckets - 1;
+       unsigned hash        = Hash(self, key);
+       size_t   bucknum     = hash & hashmask;
 
 #ifndef NDEBUG
-       this->entries_version++;
+       self->entries_version++;
 #endif
 
        while(1) {
-               HashSetEntry *entry = & this->entries[bucknum];
+               HashSetEntry *entry = & self->entries[bucknum];
 
                if(EntryIsEmpty(*entry)) {
                        return;
                }
                if(EntryIsDeleted(*entry)) {
                        // entry is deleted
-               } else if(EntryGetHash(this, *entry) == hash) {
-                       if(KeysEqual(this, GetKey(EntryGetValue(*entry)), key)) {
+               } else if(EntryGetHash(self, *entry) == hash) {
+                       if(KeysEqual(self, GetKey(EntryGetValue(*entry)), key)) {
                                EntrySetDeleted(*entry);
-                               this->num_deleted++;
-                               this->consider_shrink = 1;
+                               self->num_deleted++;
+                               self->consider_shrink = 1;
                                return;
                        }
                }
@@ -505,49 +519,49 @@ void hashset_remove(HashSet *this, ConstKeyType key)
  * @internal
  */
 static inline
-void init_size(HashSet *this, size_t initial_size)
+void init_size(HashSet *self, size_t initial_size)
 {
        if(initial_size < 4)
                initial_size = 4;
 
-       this->entries = Alloc(initial_size);
-       SetRangeEmpty(this->entries, initial_size);
-       this->num_buckets = initial_size;
-       this->consider_shrink = 0;
-       this->num_elements = 0;
-       this->num_deleted = 0;
+       self->entries         = Alloc(initial_size);
+       SetRangeEmpty(self->entries, initial_size);
+       self->num_buckets     = initial_size;
+       self->consider_shrink = 0;
+       self->num_elements    = 0;
+       self->num_deleted     = 0;
 #ifndef NDEBUG
-       this->entries_version = 0;
+       self->entries_version = 0;
 #endif
 
-       reset_thresholds(this);
+       reset_thresholds(self);
 }
 
 /**
  * Initialializes a hashset with the default size. The memory for the set has to
  * already allocated.
  */
-void hashset_init(HashSet *this)
+void hashset_init(HashSet *self)
 {
-       init_size(this, HT_MIN_BUCKETS);
+       init_size(self, HT_MIN_BUCKETS);
 }
 
 /**
  * Destroys a hashset, freeing all used memory (except the memory for the
  * HashSet struct itself).
  */
-void hashset_destroy(HashSet *this)
+void hashset_destroy(HashSet *self)
 {
-       Free(this->entries);
+       Free(self->entries);
 #ifndef NDEBUG
-       this->entries = NULL;
+       self->entries = NULL;
 #endif
 }
 
 /**
  * Initializes a hashset expecting expected_element size
  */
-void hashset_init_size(HashSet *this, size_t expected_elements)
+void hashset_init_size(HashSet *self, size_t expected_elements)
 {
        size_t needed_size;
        size_t po2size;
@@ -556,9 +570,9 @@ void hashset_init_size(HashSet *this, size_t expected_elements)
                abort();
        }
 
-       needed_size = (size_t) (expected_elements * (1.0 / HT_OCCUPANCY_FLT));
-       po2size = ceil_po2(needed_size);
-       init_size(this, po2size);
+       needed_size = expected_elements * HT_1_DIV_OCCUPANCY_FLT;
+       po2size     = ceil_po2(needed_size);
+       init_size(self, po2size);
 }
 
 /**
@@ -566,13 +580,13 @@ void hashset_init_size(HashSet *this, size_t expected_elements)
  * already allocated.
  * @note it is not allowed to remove or insert elements while iterating
  */
-void hashset_iterator_init(HashSetIterator *this, const HashSet *hashset)
+void hashset_iterator_init(HashSetIterator *self, const HashSet *hashset)
 {
-       this->current_bucket = hashset->entries - 1;
-       this->end = hashset->entries + hashset->num_buckets;
+       self->current_bucket = hashset->entries - 1;
+       self->end            = hashset->entries + hashset->num_buckets;
 #ifndef NDEBUG
-       this->set = hashset;
-       this->entries_version = hashset->entries_version;
+       self->set             = hashset;
+       self->entries_version = hashset->entries_version;
 #endif
 }
 
@@ -581,26 +595,21 @@ void hashset_iterator_init(HashSetIterator *this, const HashSet *hashset)
  * in the hashset.
  * @note it is not allowed to remove or insert elements while iterating
  */
-ValueType hashset_iterator_next(HashSetIterator *this)
+ValueType hashset_iterator_next(HashSetIterator *self)
 {
-       HashSetEntry *current_bucket = this->current_bucket;
-       HashSetEntry *end = this->end;
-
-       if(current_bucket >= end)
-               return NullValue;
+       HashSetEntry *current_bucket = self->current_bucket;
+       HashSetEntry *end            = self->end;
 
        /* using hashset_insert or hashset_remove is not allowed while iterating */
-       assert(this->entries_version == this->set->entries_version);
+       assert(self->entries_version == self->set->entries_version);
 
        do {
                current_bucket++;
-       } while(current_bucket < end &&
-                       (EntryIsEmpty(*current_bucket) || EntryIsDeleted(*current_bucket)));
-
-       if(current_bucket >= end)
-               return NullValue;
+               if(current_bucket >= end)
+                       return NullValue;
+       } while(EntryIsEmpty(*current_bucket) || EntryIsDeleted(*current_bucket));
 
-       this->current_bucket = current_bucket;
+       self->current_bucket = current_bucket;
        return EntryGetValue(*current_bucket);
 }
 
@@ -608,21 +617,21 @@ ValueType hashset_iterator_next(HashSetIterator *this)
  * Removes the element the iterator points to. Removing an element a second time
  * has no result.
  */
-void hashset_remove_iterator(HashSet *this, const HashSetIterator *iter)
+void hashset_remove_iterator(HashSet *self, const HashSetIterator *iter)
 {
        HashSetEntry *entry = iter->current_bucket;
 
        /* iterator_next needs to have been called at least once */
-       assert(entry >= this->entries);
+       assert(entry >= self->entries);
        /* needs to be on a valid element */
-       assert(entry < this->entries + this->num_buckets);
+       assert(entry < self->entries + self->num_buckets);
 
        if(EntryIsDeleted(*entry))
                return;
 
        EntrySetDeleted(*entry);
-       this->num_deleted++;
-       this->consider_shrink = 1;
+       self->num_deleted++;
+       self->consider_shrink = 1;
 }
 
 #else
index 9c7f2fd..a03a810 100644 (file)
@@ -1,21 +1,20 @@
 /*
- * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This file is part of libFirm.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
  */
 
 /**
  * @brief   Generic hashset functions
  * @author  Matthias Braun
  * @version $Id$
+ *
+ * You have to specialize this header by defining HashSet, HashSetIterator and
+ * ValueType
  */
-
-/* You have to specialize this header by defining HashSet, HashSetIterator and
- * ValueType */
 #ifdef HashSet
 
 #include <stdlib.h>
@@ -41,11 +40,6 @@ typedef struct HashSetEntry {
 } HashSetEntry;
 #endif
 
-#ifndef NO_TYPEDEFS
-typedef struct HashSet         HashSet;
-typedef struct HashSetIterator HashSetIterator;
-#endif
-
 struct HashSet {
        HashSetEntry *entries;
        size_t num_buckets;
@@ -58,7 +52,7 @@ struct HashSet {
        unsigned entries_version;
 #endif
 #ifdef ADDITIONAL_DATA
-       ADDITIONAL_DATA;
+       ADDITIONAL_DATA
 #endif
 };
 
@@ -66,7 +60,7 @@ struct HashSetIterator {
        HashSetEntry *current_bucket;
        HashSetEntry *end;
 #ifndef NDEBUG
-       const HashSet *set;
+       const struct HashSet *set;
        unsigned entries_version;
 #endif
 };
index 06e2d33..8b914ec 100644 (file)
@@ -32,6 +32,7 @@
 #define Hash(this, value)          hash_string(value)
 #define KeysEqual(this,key1,key2)  (strcmp(key1, key2) == 0)
 #define SetRangeEmpty(ptr,size)    memset(ptr, 0, (size) * sizeof(strset_entry_t))
+#define SCALAR_RETURN
 
 #define hashset_init            strset_init
 #define hashset_init_size       strset_init_size
index 5931884..913afad 100644 (file)
@@ -30,6 +30,9 @@
 #undef HashSetIterator
 #undef HashSet
 
+typedef struct strset_t           strset_t;
+typedef struct strset_iterator_t  strset_iterator_t;
+
 /**
  * Initializes a strset
  *
index ec29144..8afcd28 100644 (file)
@@ -39,6 +39,7 @@
 #include "lang_features.h"
 #include "types.h"
 #include "warning.h"
+#include "entitymap_t.h"
 #include "driver/firm_opt.h"
 #include "driver/firm_cmdline.h"
 
@@ -66,6 +67,8 @@ static const declaration_t *current_function_decl;
 static ir_node             *current_function_name;
 static ir_node             *current_funcsig;
 
+static entitymap_t  entitymap;
+
 static struct obstack asm_obst;
 
 typedef enum declaration_kind_t {
@@ -975,8 +978,13 @@ static ir_entity *get_function_entity(declaration_t *declaration)
        ir_type  *ir_type_method = get_ir_type(declaration->type);
        assert(is_Method_type(ir_type_method));
 
-       dbg_info  *const dbgi   = get_dbg_info(&declaration->source_position);
-       ir_entity *const entity = new_d_entity(global_type, id, ir_type_method, dbgi);
+       /* already an entity defined? */
+       ir_entity *entity = entitymap_get(&entitymap, symbol);
+       if (entity != NULL)
+               goto entity_created;
+
+       dbg_info *const dbgi = get_dbg_info(&declaration->source_position);
+       entity               = new_d_entity(global_type, id, ir_type_method, dbgi);
        set_entity_ld_ident(entity, create_ld_ident(entity, declaration));
        if(declaration->storage_class == STORAGE_CLASS_STATIC &&
                declaration->init.statement == NULL) {
@@ -993,9 +1001,6 @@ static ir_entity *get_function_entity(declaration_t *declaration)
        }
        set_entity_allocation(entity, allocation_static);
 
-       declaration->declaration_kind = DECLARATION_KIND_FUNCTION;
-       declaration->v.entity         = entity;
-
        /* We should check for file scope here, but as long as we compile C only
           this is not needed. */
        if (! firm_opt.freestanding) {
@@ -1012,6 +1017,12 @@ static ir_entity *get_function_entity(declaration_t *declaration)
                }
        }
 
+       entitymap_insert(&entitymap, symbol, entity);
+
+entity_created:
+       declaration->declaration_kind = DECLARATION_KIND_FUNCTION;
+       declaration->v.entity         = entity;
+
        return entity;
 }
 
@@ -1456,6 +1467,7 @@ static ir_node *process_builtin_call(const call_expression_t *call)
  */
 static ir_node *call_expression_to_firm(const call_expression_t *call)
 {
+       dbg_info *dbgi  = get_dbg_info(&call->base.source_position);
        assert(get_cur_block() != NULL);
 
        expression_t *function = call->function;
@@ -1472,6 +1484,8 @@ static ir_node *call_expression_to_firm(const call_expression_t *call)
                                expression_t *argument = call->arguments->expression;
                                ir_node      *size     = expression_to_firm(argument);
 
+                               size = create_conv(dbgi, size, get_ir_mode(type_size_t));
+
                                ir_node *store  = get_store();
                                dbg_info *dbgi  = get_dbg_info(&call->base.source_position);
                                ir_node *alloca = new_d_Alloc(dbgi, store, size, firm_unknown_type,
@@ -1493,8 +1507,6 @@ static ir_node *call_expression_to_firm(const call_expression_t *call)
        assert(is_type_function(points_to));
        function_type_t *function_type = &points_to->function;
 
-       dbg_info *dbgi  = get_dbg_info(&call->base.source_position);
-
        int      n_parameters = 0;
        ir_type *ir_method_type  = get_ir_type((type_t*) function_type);
        ir_type *new_method_type = NULL;
@@ -3028,8 +3040,13 @@ static void create_declaration_entity(declaration_t *declaration,
                                       declaration_kind_t declaration_kind,
                                       ir_type *parent_type)
 {
-       ident     *const id     = new_id_from_str(declaration->symbol->string);
        type_t    *const type   = skip_typeref(declaration->type);
+       if (is_type_function(type)) {
+               (void) get_function_entity(declaration);
+               return;
+       }
+
+       ident     *const id     = new_id_from_str(declaration->symbol->string);
        ir_type   *const irtype = get_ir_type(type);
        dbg_info  *const dbgi   = get_dbg_info(&declaration->source_position);
        ir_entity *const entity = new_d_entity(parent_type, id, irtype, dbgi);
@@ -5082,6 +5099,8 @@ void init_ast2firm(void)
        for (size_t i = 0; i < sizeof(rts_data) / sizeof(rts_data[0]); ++i) {
                rts_idents[i] = new_id_from_str(rts_data[i].name);
        }
+
+       entitymap_init(&entitymap);
 }
 
 static void init_ir_types(void)
@@ -5103,6 +5122,7 @@ static void init_ir_types(void)
 
 void exit_ast2firm(void)
 {
+       entitymap_destroy(&entitymap);
        obstack_free(&asm_obst, NULL);
 }
 
index cef0421..e6e4589 100644 (file)
@@ -49,6 +49,7 @@ void init_symbol_table_entry(symbol_t *entry, const char *string)
 #define Hash(this, key)            hash_string(key)
 #define KeysEqual(this,key1,key2)  (strcmp(key1, key2) == 0)
 #define SetRangeEmpty(ptr,size)    memset(ptr, 0, (size) * sizeof(symbol_table_hash_entry_t))
+#define SCALAR_RETURN
 
 #define hashset_init            _symbol_table_init
 #define hashset_init_size       _symbol_table_init_size
index fc93a63..86ccff1 100644 (file)
@@ -33,4 +33,7 @@
 #undef HashSetIterator
 #undef HashSet
 
+typedef struct symbol_table_iterator_t  symbol_table_iterator_t;
+typedef struct symbol_table_t           symbol_table_t;
+
 #endif
index 175bab4..bfb875c 100644 (file)
@@ -36,6 +36,9 @@
 #undef HashSetIterator
 #undef HashSet
 
+typedef struct type_hash_iterator_t  type_hash_iterator_t;
+typedef struct type_hash_t           type_hash_t;
+
 /* TODO: ^= is a bad way of combining hashes since most addresses are very
  * similar */
 
@@ -355,6 +358,7 @@ static bool types_equal(const type_t *type1, const type_t *type2)
 #define hashset_iterator_init    typehash_iterator_init
 #define hashset_iterator_next    typehash_iterator_next
 #define hashset_remove_iterator  typehash_remove_iterator
+#define SCALAR_RETURN
 
 #include "adt/hashset.c"