coarray_43.f90: Add "-latomic" option if libatomic_available.
[gcc.git] / libobjc / selector.c
index 4fd213ba919667d6e0629cbab5f3561c23d24444..809e38e1be7f5ff79f2ed17658568e544d24d2de 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU Objective C Runtime selector related functions
-   Copyright (C) 1993, 1995, 1996, 1997, 2002, 2004, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
 
 This file is part of GCC.
@@ -31,6 +31,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "objc-private/runtime.h"
 #include "objc-private/sarray.h"
 #include "objc-private/selector.h"
+#include <stdlib.h>                    /* For malloc.  */
 
 /* Initial selector hash table size. Value doesn't matter much.  */
 #define SELECTOR_HASH_SIZE 128
@@ -225,7 +226,7 @@ sel_isEqual (SEL s1, SEL s2)
 
 /* Return YES iff t1 and t2 have same method types.  Ignore the
    argframe layout.  */
-BOOL
+static BOOL
 sel_types_match (const char *t1, const char *t2)
 {
   if (! t1 || ! t2)
@@ -252,7 +253,7 @@ sel_types_match (const char *t1, const char *t2)
 
 /* Return selector representing name.  */
 SEL
-sel_get_typed_uid (const char *name, const char *types)
+sel_get_any_uid (const char *name)
 {
   struct objc_list *l;
   sidx i;
@@ -260,91 +261,139 @@ sel_get_typed_uid (const char *name, const char *types)
   objc_mutex_lock (__objc_runtime_mutex);
 
   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
-  if (i == 0)
+  if (soffset_decode (i) == 0)
     {
       objc_mutex_unlock (__objc_runtime_mutex);
       return 0;
     }
 
-  for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
-       l; l = l->tail)
-    {
-      SEL s = (SEL) l->head;
-      if (types == 0 || s->sel_types == 0)
-       {
-         if (s->sel_types == types)
-           {
-             objc_mutex_unlock (__objc_runtime_mutex);
-             return s;
-           }
-       }
-      else if (sel_types_match (s->sel_types, types))
-       {
-         objc_mutex_unlock (__objc_runtime_mutex);
-         return s;
-       }
-    }
-
+  l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
   objc_mutex_unlock (__objc_runtime_mutex);
-  return 0;
+
+  if (l == 0)
+    return 0;
+
+  return (SEL) l->head;
 }
 
-/* Return selector representing name; prefer a selector with non-NULL
-   type.  */
 SEL
-sel_get_any_typed_uid (const char *name)
+sel_getTypedSelector (const char *name)
 {
-  struct objc_list *l;
   sidx i;
-  SEL s = NULL;
 
+  if (name == NULL)
+    return NULL;
+  
   objc_mutex_lock (__objc_runtime_mutex);
-
+  
+  /* Look for a typed selector.  */
   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
-  if (i == 0)
+  if (i != 0)
     {
-      objc_mutex_unlock (__objc_runtime_mutex);
-      return 0;
-    }
+      struct objc_list *l;
+      SEL returnValue = NULL;
 
-  for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
-       l; l = l->tail)
-    {
-      s = (SEL) l->head;
-      if (s->sel_types)
+      for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
+          l; l = l->tail)
+       {
+         SEL s = (SEL) l->head;
+         if (s->sel_types)
+           {
+             if (returnValue == NULL)
+               {
+                 /* First typed selector that we find.  Keep it in
+                    returnValue, but keep checking as we want to
+                    detect conflicts.  */
+                 returnValue = s;
+               }
+             else
+               {
+                 /* We had already found a typed selectors, so we
+                    have multiple ones.  Double-check that they have
+                    different types, just in case for some reason we
+                    got duplicates with the same types.  If so, it's
+                    OK, we'll ignore the duplicate.  */
+                 if (returnValue->sel_types == s->sel_types)
+                   continue;
+                 else if (sel_types_match (returnValue->sel_types, s->sel_types))
+                   continue;
+                 else
+                   {
+                     /* The types of the two selectors are different;
+                        it's a conflict.  Too bad.  Return NULL.  */
+                     objc_mutex_unlock (__objc_runtime_mutex);
+                     return NULL;
+                   }
+               }
+           }
+       }
+
+      if (returnValue != NULL)
        {
          objc_mutex_unlock (__objc_runtime_mutex);
-         return s;
+         return returnValue;
        }
     }
 
+  /* No typed selector found.  Return NULL.  */
   objc_mutex_unlock (__objc_runtime_mutex);
-  return s;
+  return 0;
 }
 
-/* Return selector representing name.  */
-SEL
-sel_get_any_uid (const char *name)
+SEL *
+sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
 {
-  struct objc_list *l;
+  unsigned int count = 0;
+  SEL *returnValue = NULL;
   sidx i;
+  
+  if (name == NULL)
+    {
+      if (numberOfReturnedSelectors)
+       *numberOfReturnedSelectors = 0;
+      return NULL;
+    }
 
   objc_mutex_lock (__objc_runtime_mutex);
 
+  /* Count how many selectors we have.  */
   i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
-  if (soffset_decode (i) == 0)
+  if (i != 0)
     {
-      objc_mutex_unlock (__objc_runtime_mutex);
-      return 0;
-    }
+      struct objc_list *selector_list = NULL;
+      selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
 
-  l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
-  objc_mutex_unlock (__objc_runtime_mutex);
+      /* Count how many selectors we have.  */
+      {
+       struct objc_list *l;
+       for (l = selector_list; l; l = l->tail)
+         count++;
+      }
 
-  if (l == 0)
-    return 0;
+      if (count != 0)
+       {
+         /* Allocate enough memory to hold them.  */
+         returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
+         
+         /* Copy the selectors.  */
+         {
+           unsigned int j;
+           for (j = 0; j < count; j++)
+             {
+               returnValue[j] = (SEL)(selector_list->head);
+               selector_list = selector_list->tail;
+             }
+           returnValue[j] = NULL;
+         }
+       }
+    }      
 
-  return (SEL) l->head;
+  objc_mutex_unlock (__objc_runtime_mutex);
+  
+  if (numberOfReturnedSelectors)
+    *numberOfReturnedSelectors = count;
+  
+  return returnValue;
 }
 
 /* Get the name of a selector.  If the selector is unknown, the empty
@@ -366,15 +415,6 @@ const char *sel_getName (SEL selector)
   return ret;
 }
 
-/* Traditional GNU Objective-C Runtime API.  */
-const char *sel_get_name (SEL selector)
-{
-  if (selector == NULL)
-    return 0;
-
-  return sel_getName (selector);
-}
-
 BOOL
 sel_is_mapped (SEL selector)
 {
@@ -382,7 +422,7 @@ sel_is_mapped (SEL selector)
   return ((idx > 0) && (idx <= __objc_selector_max_index));
 }
 
-const char *sel_getType (SEL selector)
+const char *sel_getTypeEncoding (SEL selector)
 {
   if (selector)
     return selector->sel_types;
@@ -390,12 +430,6 @@ const char *sel_getType (SEL selector)
     return 0;
 }
 
-/* Traditional GNU Objective-C Runtime API.  */
-const char *sel_get_type (SEL selector)
-{
-  return sel_getType (selector);
-}
-
 /* The uninstalled dispatch table.  */
 extern struct sarray *__objc_uninstalled_dtable;
 
@@ -470,7 +504,7 @@ __sel_register_typed_name (const char *name, const char *types,
                    return s;
                }
            }
-         else if (! strcmp (s->sel_types, types))
+         else if (sel_types_match (s->sel_types, types))
            {
              if (orig)
                {
@@ -567,6 +601,9 @@ SEL
 sel_registerName (const char *name)
 {
   SEL ret;
+
+  if (name == NULL)
+    return NULL;
     
   objc_mutex_lock (__objc_runtime_mutex);
   /* Assume that name is not constant static memory and needs to be
@@ -577,18 +614,14 @@ sel_registerName (const char *name)
   return ret;
 }
 
-/* Traditional GNU Objective-C Runtime API.  */
-SEL
-sel_register_name (const char *name)
-{
-  return sel_registerName (name);
-}
-
 SEL
 sel_registerTypedName (const char *name, const char *type)
 {
   SEL ret;
 
+  if (name == NULL)
+    return NULL;
+
   objc_mutex_lock (__objc_runtime_mutex);
   /* Assume that name and type are not constant static memory and need
      to be copied before put into a runtime structure.  is_const ==
@@ -599,22 +632,9 @@ sel_registerTypedName (const char *name, const char *type)
   return ret;
 }
 
-SEL
-sel_register_typed_name (const char *name, const char *type)
-{
-  return sel_registerTypedName (name, type);
-}
-
 /* Return the selector representing name.  */
 SEL
 sel_getUid (const char *name)
 {
   return sel_registerTypedName (name, 0);
 }
-
-/* Traditional GNU Objective-C Runtime API.  */
-SEL
-sel_get_uid (const char *name)
-{
-  return sel_getUid (name);
-}