aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-10-23 18:40:39 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-10-23 18:40:39 +0000
commitb8a18805817b17b09764527a86ebc551fa5900b3 (patch)
treec267f9ca3f7d1cb2966e10f23962c1b2d259571a /gcc
parent487a9a3ef8a77211c02d9f130f2db1f20962a58d (diff)
downloadgcc-b8a18805817b17b09764527a86ebc551fa5900b3.zip
gcc-b8a18805817b17b09764527a86ebc551fa5900b3.tar.gz
gcc-b8a18805817b17b09764527a86ebc551fa5900b3.tar.bz2
In gcc/cp/: 2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/cp/: 2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com> * tree.c (cxx_printable_name_internal): In Objective-C++, call objc_maybe_printable_name. In gcc/objc/: 2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (OBJC_GEN_METHOD_LABEL): Updated comments. (objc_demangle): Return NULL if demangling can not be done because the string to demangle is not an Objective-C mangled method name. Be smarter in demangling method names so that at least for methods with no arguments we are able to almost always demangle '_' correctly. Updated comments. (objc_maybe_printable_name): New. (objc_printable_name): Call objc_maybe_printable_name. If it returns NULL, call cxx_printable_name in Objective-C++. In gcc/testsuite/: 2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/demangle-1.m: New test. * obj-c++.dg/demangle-1.mm: New test. * obj-c++.dg/demangle-2.mm: New test. * obj-c++.dg/demangle-3.mm: New test. In gcc/c-family/: 2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com> * c-common.h (objc_maybe_printable_name): New. * stub-objc.c (objc_maybe_printable_name): New. From-SVN: r165887
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/stub-objc.c7
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/tree.c9
-rw-r--r--gcc/objc/ChangeLog12
-rw-r--r--gcc/objc/objc-act.c163
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/obj-c++.dg/demangle-1.mm35
-rw-r--r--gcc/testsuite/obj-c++.dg/demangle-2.mm50
-rw-r--r--gcc/testsuite/obj-c++.dg/demangle-3.mm21
-rw-r--r--gcc/testsuite/objc.dg/demangle-1.m56
12 files changed, 358 insertions, 13 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 93664f3..b73e45a 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * c-common.h (objc_maybe_printable_name): New.
+ * stub-objc.c (objc_maybe_printable_name): New.
+
2010-10-22 Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
Andrew Pinski <pinskia@gmail.com>
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index f882a8f..8031bb4 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1048,6 +1048,7 @@ extern tree objc_build_getter_call (tree, tree);
extern tree objc_build_setter_call (tree, tree);
extern void objc_add_synthesize_declaration (location_t, tree);
extern void objc_add_dynamic_declaration (location_t, tree);
+extern const char * objc_maybe_printable_name (tree, int);
/* The following are provided by the C and C++ front-ends, and called by
ObjC/ObjC++. */
diff --git a/gcc/c-family/stub-objc.c b/gcc/c-family/stub-objc.c
index 7ef4f1e..f808dc7 100644
--- a/gcc/c-family/stub-objc.c
+++ b/gcc/c-family/stub-objc.c
@@ -359,6 +359,13 @@ objc_add_dynamic_declaration (location_t ARG_UNUSED (start_locus),
{
}
+const char *
+objc_maybe_printable_name (tree ARG_UNUSED (decl),
+ int ARG_UNUSED (v))
+{
+ return NULL;
+}
+
tree
objc_build_throw_stmt (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr))
{
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6a3d5c7..bf36e6f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * tree.c (cxx_printable_name_internal): In Objective-C++, call
+ objc_maybe_printable_name.
+
2010-10-22 Jason Merrill <jason@redhat.com>
PR c++/46129
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index b8f76b0..26746f9 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1409,6 +1409,15 @@ cxx_printable_name_internal (tree decl, int v, bool translate)
static int ring_counter;
int i;
+ /* If doing Objective-C++, give Objective-C a chance to demangle
+ Objective-C method names. */
+ if (c_dialect_objc ())
+ {
+ const char *demangled = objc_maybe_printable_name (decl, v);
+ if (demangled)
+ return demangled;
+ }
+
/* Only cache functions. */
if (v < 2
|| TREE_CODE (decl) != FUNCTION_DECL
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index de64a31..7720a9c 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,15 @@
+2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * objc-act.c (OBJC_GEN_METHOD_LABEL): Updated comments.
+ (objc_demangle): Return NULL if demangling can not be done because
+ the string to demangle is not an Objective-C mangled method name.
+ Be smarter in demangling method names so that at least for methods
+ with no arguments we are able to almost always demangle '_' correctly.
+ Updated comments.
+ (objc_maybe_printable_name): New.
+ (objc_printable_name): Call objc_maybe_printable_name. If it
+ returns NULL, call cxx_printable_name in Objective-C++.
+
2010-10-21 Iain Sandoe <iains@gcc.gnu.org>
Based on the CFString implementation in FSF apple/trunk branch.
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index bc07910..97ac0e8 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -75,9 +75,14 @@ bool in_late_binary_op = false;
#endif /* OBJCPLUS */
/* This is the default way of generating a method name. */
-/* I am not sure it is really correct.
- Perhaps there's a danger that it will make name conflicts
- if method names contain underscores. -- rms. */
+/* This has the problem that "test_method:argument:" and
+ "test:method_argument:" will generate the same name
+ ("_i_Test__test_method_argument_" for an instance method of the
+ class "Test"), so you can't have them both in the same class!
+ Moreover, the demangling (going from
+ "_i_Test__test_method_argument" back to the original name) is
+ undefined because there are two correct ways of demangling the
+ name. */
#ifndef OBJC_GEN_METHOD_LABEL
#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
do { \
@@ -10615,7 +10620,64 @@ dump_interface (FILE *fp, tree chain)
fprintf (fp, "@end\n");
}
-/* Demangle function for Objective-C */
+#if 0
+/* Produce the pretty printing for an Objective-C method. This is
+ currently unused, but could be handy while reorganizing the pretty
+ printing to be more robust. */
+static const char *
+objc_pretty_print_method (bool is_class_method,
+ const char *class_name,
+ const char *category_name,
+ const char *selector)
+{
+ if (category_name)
+ {
+ char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
+ + strlen (selector) + 7);
+
+ if (is_class_method)
+ sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
+ else
+ sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
+
+ return result;
+ }
+ else
+ {
+ char *result = XNEWVEC (char, strlen (class_name)
+ + strlen (selector) + 5);
+
+ if (is_class_method)
+ sprintf (result, "+[%s %s]", class_name, selector);
+ else
+ sprintf (result, "-[%s %s]", class_name, selector);
+
+ return result;
+ }
+}
+#endif
+
+/* Demangle function for Objective-C. Attempt to demangle the
+ function name associated with a method (eg, going from
+ "_i_NSObject__class" to "-[NSObject class]"); usually for the
+ purpose of pretty printing or error messages. Return the demangled
+ name, or NULL if the string is not an Objective-C mangled method
+ name.
+
+ Because of how the mangling is done, any method that has a '_' in
+ its original name is at risk of being demangled incorrectly. In
+ some cases there are multiple valid ways to demangle a method name
+ and there is no way we can decide.
+
+ TODO: objc_demangle() can't always get it right; the right way to
+ get this correct for all method names would be to store the
+ Objective-C method name somewhere in the function decl. Then,
+ there is no demangling to do; we'd just pull the method name out of
+ the decl. As an additional bonus, when printing error messages we
+ could check for such a method name, and if we find it, we know the
+ function is actually an Objective-C method and we could print error
+ messages saying "In method '+[NSObject class]" instead of "In
+ function '+[NSObject class]" as we do now. */
static const char *
objc_demangle (const char *mangled)
{
@@ -10638,7 +10700,7 @@ objc_demangle (const char *mangled)
if (cp == NULL)
{
free(demangled); /* not mangled name */
- return mangled;
+ return NULL;
}
if (cp[1] == '_') /* easy case: no category name */
{
@@ -10652,29 +10714,104 @@ objc_demangle (const char *mangled)
if (cp == 0)
{
free(demangled); /* not mangled name */
- return mangled;
+ return NULL;
}
*cp++ = ')';
*cp++ = ' '; /* overwriting 1st char of method name... */
strcpy(cp, mangled + (cp - demangled)); /* get it back */
}
+ /* Now we have the method name. We need to generally replace
+ '_' with ':' but trying to preserve '_' if it could only have
+ been in the mangled string because it was already in the
+ original name. In cases where it's ambiguous, we assume that
+ any '_' originated from a ':'. */
+
+ /* Initial '_'s in method name can't have been generating by
+ converting ':'s. Skip them. */
while (*cp && *cp == '_')
- cp++; /* skip any initial underbars in method name */
- for (; *cp; cp++)
- if (*cp == '_')
- *cp = ':'; /* replace remaining '_' with ':' */
+ cp++;
+
+ /* If the method name does not end with '_', then it has no
+ arguments and there was no replacement of ':'s with '_'s
+ during mangling. Check for that case, and skip any
+ replacement if so. This at least guarantees that methods
+ with no arguments are always demangled correctly (unless the
+ original name ends with '_'). */
+ if (*(mangled + strlen (mangled) - 1) != '_')
+ {
+ /* Skip to the end. */
+ for (; *cp; cp++)
+ ;
+ }
+ else
+ {
+ /* Replace remaining '_' with ':'. This may get it wrong if
+ there were '_'s in the original name. In most cases it
+ is impossible to disambiguate. */
+ for (; *cp; cp++)
+ if (*cp == '_')
+ *cp = ':';
+ }
*cp++ = ']'; /* closing right brace */
*cp++ = 0; /* string terminator */
return demangled;
}
else
- return mangled; /* not an objc mangled name */
+ return NULL; /* not an objc mangled name */
}
+/* Try to pretty-print a decl. If the 'decl' is an Objective-C
+ specific decl, return the printable name for it. If not, return
+ NULL. */
const char *
-objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
+objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
{
- return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ const char *decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));
+
+ switch (TREE_CODE (decl))
+ {
+ case FUNCTION_DECL:
+ return objc_demangle (decl_name);
+ break;
+ /* This unusual case (INSTANCE_METHOD_DECL and
+ CLASS_METHOD_DECL) seems to happen only in ObjC++ and to be a
+ by-product of the method attribute changes. It would be nice
+ to be able to print "-[NSObject autorelease] is deprecated",
+ but to do that, we'd need to store the class and method name
+ in the method decl, which we currently don't do. For now,
+ just return the name of the method. We don't return NULL,
+ because that may trigger further attempts to pretty-print the
+ decl in C/C++, but they wouldn't know how to pretty-print
+ it. */
+ case INSTANCE_METHOD_DECL:
+ case CLASS_METHOD_DECL:
+ return decl_name;
+ break;
+ default:
+ return NULL;
+ break;
+ }
+}
+
+/* Return a printable name for 'decl'. This first tries
+ objc_maybe_printable_name(), and if that fails, it hands it back to
+ C/C++. 'v' is the verbosity level, as this is a
+ LANG_HOOKS_DECL_PRINTABLE_NAME. */
+const char *
+objc_printable_name (tree decl, int v)
+{
+ const char *demangled_name = objc_maybe_printable_name (decl, v);
+
+ if (demangled_name != NULL)
+ return demangled_name;
+ else
+ {
+#ifdef OBJCPLUS
+ return cxx_printable_name (decl, v);
+#else
+ return IDENTIFIER_POINTER (DECL_NAME (decl));
+#endif
+ }
}
static void
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3ab40ac..137f965 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com>
+
+ * objc.dg/demangle-1.m: New test.
+ * obj-c++.dg/demangle-1.mm: New test.
+ * obj-c++.dg/demangle-2.mm: New test.
+ * obj-c++.dg/demangle-3.mm: New test.
+
2010-10-23 Ian Lance Taylor <iant@google.com>
* gcc.c-torture/execute/20101011-1.c: New test.
diff --git a/gcc/testsuite/obj-c++.dg/demangle-1.mm b/gcc/testsuite/obj-c++.dg/demangle-1.mm
new file mode 100644
index 0000000..015a3af
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/demangle-1.mm
@@ -0,0 +1,35 @@
+/* Test demangling a C++ function. */
+/* { dg-do run } */
+
+#include <cstring>
+#include <cstdlib>
+#include <iostream>
+
+class demangle_test
+{
+public:
+ /* Return 0 if the demangling test succeeds. */
+ static int test_function1 ()
+ {
+ std::cout << __PRETTY_FUNCTION__ << "\n";
+ return std::strcmp (__PRETTY_FUNCTION__, "static int demangle_test::test_function1()");
+ }
+
+ /* Return 0 if the demangling test succeeds. */
+ static int test_function2 (int ignored)
+ {
+ std::cout << __PRETTY_FUNCTION__ << "\n";
+ return std::strcmp (__PRETTY_FUNCTION__, "static int demangle_test::test_function2(int)");
+ }
+};
+
+int main ()
+{
+ if (demangle_test::test_function1 () != 0)
+ abort ();
+
+ if (demangle_test::test_function2 (0) != 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/demangle-2.mm b/gcc/testsuite/obj-c++.dg/demangle-2.mm
new file mode 100644
index 0000000..c58a4f8
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/demangle-2.mm
@@ -0,0 +1,50 @@
+/* Test demangling an Objective-C method. */
+/* { dg-do run } */
+
+#include <cstring>
+#include <cstdlib>
+#include <iostream>
+#include <objc/objc.h>
+
+@interface DemangleTest
+{
+ Class isa;
+}
++ (int) testFunction1;
++ (int) test_function2;
++ (int) __testFunction3: (int)unused andArgument: (char)unused2;
+@end
+
+@implementation DemangleTest
++ (int) testFunction1
+{
+ std::cout << __PRETTY_FUNCTION__ << "\n";
+ return std::strcmp (__PRETTY_FUNCTION__, "+[DemangleTest testFunction1]");
+}
++ (int) test_function2
+{
+ std::cout << __PRETTY_FUNCTION__ << "\n";
+ return std::strcmp (__PRETTY_FUNCTION__, "+[DemangleTest test_function2]");
+}
++ (int) __testFunction3: (int)unused andArgument: (char)unused2
+{
+ std::cout << __PRETTY_FUNCTION__ << "\n";
+ return std::strcmp (__PRETTY_FUNCTION__, "+[DemangleTest __testFunction3:andArgument:]");
+}
+@end
+
+int main ()
+{
+ if ([DemangleTest testFunction1] != 0)
+ abort ();
+
+ if ([DemangleTest test_function2] != 0)
+ abort ();
+
+ if ([DemangleTest __testFunction3:0 andArgument: 'c'] != 0)
+ abort ();
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/obj-c++.dg/demangle-3.mm b/gcc/testsuite/obj-c++.dg/demangle-3.mm
new file mode 100644
index 0000000..01e6c61
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/demangle-3.mm
@@ -0,0 +1,21 @@
+/* Test demangling an Objective-C method in error messages. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface DemangleTest
+{
+ Class isa;
+}
++ (int) testFunction1;
+@end
+
+@implementation DemangleTest
++ (int) testFunction1
+{
+ /* TODO: Hack the testsuite so we can test that we get
+ dg-error "In function .+[DemangleTest testFunction1]."
+ At the moment, the message is filtered out. */
+ z; /* { dg-error "was not declared" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/demangle-1.m b/gcc/testsuite/objc.dg/demangle-1.m
new file mode 100644
index 0000000..0cee76b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/demangle-1.m
@@ -0,0 +1,56 @@
+/* Test demangling an Objective-C method. */
+/* { dg-do run } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <objc/objc.h>
+
+@interface DemangleTest
+{
+ Class isa;
+}
++ (int) testFunction1;
++ (int) test_function2;
++ (int) __testFunction3: (int)unused andArgument: (char)unused2;
+@end
+
+@implementation DemangleTest
++ (int) testFunction1
+{
+ printf ("%s\n", __PRETTY_FUNCTION__);
+ return strcmp (__PRETTY_FUNCTION__, "+[DemangleTest testFunction1]");
+}
+/* Note that in general, due to how mangling is done, it's impossible
+ to get the demangling right for all functions containing '_' in the
+ name. But at least we should be able to get that right for single
+ argument ones that don't end with '_', such as the following
+ one. */
++ (int) test_function2
+{
+ printf ("%s\n", __PRETTY_FUNCTION__);
+ return strcmp (__PRETTY_FUNCTION__, "+[DemangleTest test_function2]");
+}
++ (int) __testFunction3: (int)unused andArgument: (char)unused2
+{
+ printf ("%s\n", __PRETTY_FUNCTION__);
+ return strcmp (__PRETTY_FUNCTION__, "+[DemangleTest __testFunction3:andArgument:]");
+}
+@end
+
+int main ()
+{
+ if ([DemangleTest testFunction1] != 0)
+ abort ();
+
+ if ([DemangleTest test_function2] != 0)
+ abort ();
+
+ if ([DemangleTest __testFunction3:0 andArgument: 'c'] != 0)
+ abort ();
+
+ return 0;
+}
+
+