attribs.c: Include hashtab.h
* attribs.c: Include hashtab.h (attribute_hash): New. (substring): New structure. (extract_attribute_substring, substring_hash, hash_attr, eq_attr): New function. (init_attributes): Initialize attribute hash. (decl_attributes): Use attribute hash. * Makefile.in (attribs.c): Depend on hashtab.h. From-SVN: r126996
This commit is contained in:
parent
e3d693e9a3
commit
23b432076e
2 changed files with 91 additions and 16 deletions
|
@ -1,3 +1,14 @@
|
|||
2007-07-27 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* attribs.c: Include hashtab.h
|
||||
(attribute_hash): New.
|
||||
(substring): New structure.
|
||||
(extract_attribute_substring, substring_hash, hash_attr, eq_attr):
|
||||
New function.
|
||||
(init_attributes): Initialize attribute hash.
|
||||
(decl_attributes): Use attribute hash.
|
||||
* Makefile.in (attribs.c): Depend on hashtab.h.
|
||||
|
||||
2007-07-27 Steve Ellcey <sje@cup.hp.com>
|
||||
|
||||
* config/ia64/vect.md (vec_initv2si): Remove bad BIG_ENDIAN test.
|
||||
|
|
|
@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cpplib.h"
|
||||
#include "target.h"
|
||||
#include "langhooks.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
static void init_attributes (void);
|
||||
|
||||
|
@ -39,14 +40,70 @@ static void init_attributes (void);
|
|||
searched. */
|
||||
static const struct attribute_spec *attribute_tables[4];
|
||||
|
||||
/* Hashtable mapping names (represented as substrings) to attribute specs. */
|
||||
static htab_t attribute_hash;
|
||||
|
||||
/* Substring representation. */
|
||||
|
||||
struct substring
|
||||
{
|
||||
const char *str;
|
||||
int length;
|
||||
};
|
||||
|
||||
static bool attributes_initialized = false;
|
||||
|
||||
/* Default empty table of attributes. */
|
||||
|
||||
static const struct attribute_spec empty_attribute_table[] =
|
||||
{
|
||||
{ NULL, 0, 0, false, false, false, NULL }
|
||||
};
|
||||
|
||||
/* Return base name of the attribute. Ie '__attr__' is turned into 'attr'.
|
||||
To avoid need for copying, we simply return length of the string. */
|
||||
|
||||
static void
|
||||
extract_attribute_substring (struct substring *str)
|
||||
{
|
||||
if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
|
||||
&& str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_')
|
||||
{
|
||||
str->length -= 4;
|
||||
str->str += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Simple hash function to avoid need to scan whole string. */
|
||||
|
||||
static inline hashval_t
|
||||
substring_hash (const char *str, int l)
|
||||
{
|
||||
return str[0] + str[l - 1] * 256 + l * 65536;
|
||||
}
|
||||
|
||||
/* Used for attribute_hash. */
|
||||
|
||||
static hashval_t
|
||||
hash_attr (const void *p)
|
||||
{
|
||||
struct attribute_spec *spec = (struct attribute_spec *) p;
|
||||
int l = strlen (spec->name);
|
||||
|
||||
return substring_hash (spec->name, l);
|
||||
}
|
||||
|
||||
/* Used for attribute_hash. */
|
||||
|
||||
static int
|
||||
eq_attr (const void *p, const void *q)
|
||||
{
|
||||
const struct attribute_spec *spec = (struct attribute_spec *) p;
|
||||
const struct substring *str = (struct substring *) q;
|
||||
|
||||
return (!strncmp (spec->name, str->str, str->length) && !spec->name[str->length]);
|
||||
}
|
||||
|
||||
/* Initialize attribute tables, and make some sanity checks
|
||||
if --enable-checking. */
|
||||
|
||||
|
@ -54,6 +111,7 @@ static void
|
|||
init_attributes (void)
|
||||
{
|
||||
size_t i;
|
||||
int k;
|
||||
|
||||
attribute_tables[0] = lang_hooks.common_attribute_table;
|
||||
attribute_tables[1] = lang_hooks.attribute_table;
|
||||
|
@ -120,6 +178,21 @@ init_attributes (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
|
||||
for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
|
||||
for (k = 0; attribute_tables[i][k].name != NULL; k++)
|
||||
{
|
||||
struct substring str;
|
||||
void **slot;
|
||||
|
||||
str.str = attribute_tables[i][k].name;
|
||||
str.length = strlen (attribute_tables[i][k].name);
|
||||
slot = htab_find_slot_with_hash (attribute_hash, &str,
|
||||
substring_hash (str.str, str.length),
|
||||
INSERT);
|
||||
gcc_assert (!*slot);
|
||||
*slot = (void *)&attribute_tables[i][k];
|
||||
}
|
||||
attributes_initialized = true;
|
||||
}
|
||||
|
||||
|
@ -151,23 +224,13 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
const struct attribute_spec *spec = NULL;
|
||||
bool no_add_attrs = 0;
|
||||
tree fn_ptr_tmp = NULL_TREE;
|
||||
size_t i;
|
||||
struct substring attr;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; attribute_tables[i][j].name != NULL; j++)
|
||||
{
|
||||
if (is_attribute_p (attribute_tables[i][j].name, name))
|
||||
{
|
||||
spec = &attribute_tables[i][j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (spec != NULL)
|
||||
break;
|
||||
}
|
||||
attr.str = IDENTIFIER_POINTER (name);
|
||||
attr.length = IDENTIFIER_LENGTH (name);
|
||||
extract_attribute_substring (&attr);
|
||||
spec = htab_find_with_hash (attribute_hash, &attr,
|
||||
substring_hash (attr.str, attr.length));
|
||||
|
||||
if (spec == NULL)
|
||||
{
|
||||
|
@ -183,6 +246,7 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
IDENTIFIER_POINTER (name));
|
||||
continue;
|
||||
}
|
||||
gcc_assert (is_attribute_p (spec->name, name));
|
||||
|
||||
if (spec->decl_required && !DECL_P (*anode))
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue