aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-02-04 01:29:37 +0000
committerSean Callanan <scallanan@apple.com>2012-02-04 01:29:37 +0000
commit1ce3a6b650fde29a608f7a5664ddf8eddd82826b (patch)
tree255bedec4873ab83a273ef8833ff2b2f96167af9
parenta21bbb24237c5672eb42ff3a07d4b18760992ecb (diff)
downloadllvm-1ce3a6b650fde29a608f7a5664ddf8eddd82826b.zip
llvm-1ce3a6b650fde29a608f7a5664ddf8eddd82826b.tar.gz
llvm-1ce3a6b650fde29a608f7a5664ddf8eddd82826b.tar.bz2
Clang has existing support for debuggers that
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. llvm-svn: 149735
-rw-r--r--clang/include/clang/Basic/LangOptions.def1
-rw-r--r--clang/include/clang/Driver/CC1Options.td2
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp2
-rw-r--r--clang/test/SemaObjC/debugger-cast-result-to-id.m27
-rw-r--r--clang/test/SemaObjC/unknown-anytype.m4
6 files changed, 36 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 4f107e5..d2dff89 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -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")
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
index fd3e32c..557e73b 100644
--- a/clang/include/clang/Driver/CC1Options.td
+++ b/clang/include/clang/Driver/CC1Options.td
@@ -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">,
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 23fe830..7fd2247 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -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);
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index b35ea80..d0e40ba 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -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/clang/test/SemaObjC/debugger-cast-result-to-id.m b/clang/test/SemaObjC/debugger-cast-result-to-id.m
new file mode 100644
index 0000000..86f4c3a
--- /dev/null
+++ b/clang/test/SemaObjC/debugger-cast-result-to-id.m
@@ -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];
+}
diff --git a/clang/test/SemaObjC/unknown-anytype.m b/clang/test/SemaObjC/unknown-anytype.m
index 89e45e4..38e058c 100644
--- a/clang/test/SemaObjC/unknown-anytype.m
+++ b/clang/test/SemaObjC/unknown-anytype.m
@@ -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}}