]> granicus.if.org Git - clang/commitdiff
Clang has existing support for debuggers that
authorSean Callanan <scallanan@apple.com>
Sat, 4 Feb 2012 01:29:37 +0000 (01:29 +0000)
committerSean Callanan <scallanan@apple.com>
Sat, 4 Feb 2012 01:29:37 +0000 (01:29 +0000)
want to provide "po"-like functionality which
treats the result of an expression implicitly as
"id" (if it is not otherwise known) and prints
it as an Objective-C object.

This has in the past been gated by the
"DebuggerSupport" language option, but that is
too general.  Debuggers also provide other commands
like "print" that do not make any assumptions
about whether the object is an Objective-C object.

This patch makes the assumption conditional on a
new language option: DebuggerCastResultToId.  I
have also made corresponding modifications to the
testsuite.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149735 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/LangOptions.def
include/clang/Driver/CC1Options.td
lib/Frontend/CompilerInvocation.cpp
lib/Sema/SemaExprCXX.cpp
test/SemaObjC/debugger-cast-result-to-id.m [new file with mode: 0644]
test/SemaObjC/unknown-anytype.m

index 4f107e55a6d72d4c1938c28a7fc6bfb7348ece84..d2dff8947ced12734afbc603a214a1d80eb148f8 100644 (file)
@@ -123,6 +123,7 @@ LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings")
 BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods")
 BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
 BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
+BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
 BENIGN_LANGOPT(AddressSanitizer , 1, 0, "AddressSanitizer enabled")
 
 BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
index fd3e32cd35d104d73f6f4d063018178bb342a1b6..557e73bbfe80829281958dc6acdc946c7a15da0b 100644 (file)
@@ -651,6 +651,8 @@ def funknown_anytype : Flag<"-funknown-anytype">,
   HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">;
 def fdebugger_support : Flag<"-fdebugger-support">,
   HelpText<"Enable special debugger support behavior">;
+def fdebugger_cast_result_to_id : Flag<"-fdebugger-cast-result-to-id">,
+  HelpText<"Enable casting unknown expression results to id">;
 def fdeprecated_macro : Flag<"-fdeprecated-macro">,
   HelpText<"Defines the __DEPRECATED macro">;
 def fno_deprecated_macro : Flag<"-fno-deprecated-macro">,
index 23fe830a03584184140e263ab295433d3e288020..7fd224790788191b91a921a5da172567f6e8dac9 100644 (file)
@@ -826,6 +826,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
     Res.push_back("-funknown-anytype");
   if (Opts.DebuggerSupport)
     Res.push_back("-fdebugger-support");
+  if (Opts.DebuggerCastResultToId)
+    Res.push_back("-fdebugger-cast-result-to-id");
   if (Opts.DelayedTemplateParsing)
     Res.push_back("-fdelayed-template-parsing");
   if (Opts.Deprecated)
@@ -1885,6 +1887,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   Opts.FakeAddressSpaceMap = Args.hasArg(OPT_ffake_address_space_map);
   Opts.ParseUnknownAnytype = Args.hasArg(OPT_funknown_anytype);
   Opts.DebuggerSupport = Args.hasArg(OPT_fdebugger_support);
+  Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id);
   Opts.AddressSanitizer = Args.hasArg(OPT_faddress_sanitizer);
   Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
   Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name);
index b35ea802e56bd8521beb57646c67567cf5fb86c1..d0e40ba27134df4a3595f0f443a2e5398a6e291b 100644 (file)
@@ -4767,7 +4767,7 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE) {
     return ExprError();
 
   // Top-level message sends default to 'id' when we're in a debugger.
-  if (getLangOptions().DebuggerSupport &&
+  if (getLangOptions().DebuggerCastResultToId &&
       FullExpr.get()->getType() == Context.UnknownAnyTy &&
       isa<ObjCMessageExpr>(FullExpr.get())) {
     FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType());
diff --git a/test/SemaObjC/debugger-cast-result-to-id.m b/test/SemaObjC/debugger-cast-result-to-id.m
new file mode 100644 (file)
index 0000000..86f4c3a
--- /dev/null
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -funknown-anytype -fsyntax-only -fdebugger-support -fdebugger-cast-result-to-id -verify %s
+
+extern __unknown_anytype test0;
+extern __unknown_anytype test1();
+
+void test_unknown_anytype_receiver() {
+  (void)(int)[[test0 unknownMethod] otherUnknownMethod];;
+  (void)(id)[[test1() unknownMethod] otherUnknownMethod];
+}
+// RUN: %clang_cc1 -funknown-anytype -fsyntax-only -fdebugger-support -fdebugger-cast-result-to-id -verify %s
+
+extern __unknown_anytype test0;
+extern __unknown_anytype test1();
+
+void test_unknown_anytype_receiver() {
+  (void)(int)[[test0 unknownMethod] otherUnknownMethod];;
+  (void)(id)[[test1() unknownMethod] otherUnknownMethod];
+}
+// RUN: %clang_cc1 -funknown-anytype -fsyntax-only -fdebugger-support -fdebugger-cast-result-to-id -verify %s
+
+extern __unknown_anytype test0;
+extern __unknown_anytype test1();
+
+void test_unknown_anytype_receiver() {
+  (void)(int)[[test0 unknownMethod] otherUnknownMethod];;
+  (void)(id)[[test1() unknownMethod] otherUnknownMethod];
+}
index 89e45e4a1317f86b9e7995166c1fe040456a6945..38e058c513f6a0a46f7b444cef48a6936cafb2d4 100644 (file)
@@ -17,9 +17,9 @@ void test_unknown_anytype_receiver() {
   int *ip = [test0 getIntPtr];
   float *fp = [test1() getFloatPtr];
   double *dp = [test1() getSomePtr]; // okay: picks first method found
-  [[test0 unknownMethod] otherUnknownMethod]; 
+  [[test0 unknownMethod] otherUnknownMethod]; // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}}
   (void)(int)[[test0 unknownMethod] otherUnknownMethod];;
-  [[test1() unknownMethod] otherUnknownMethod];
+  [[test1() unknownMethod] otherUnknownMethod]; // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}}
   (void)(id)[[test1() unknownMethod] otherUnknownMethod];
 
   if ([[test0 unknownMethod] otherUnknownMethod]) { // expected-error{{no known method '-otherUnknownMethod'; cast the message send to the method's return type}}