aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/LangOptions.def1
-rw-r--r--include/clang/Driver/CC1Options.td2
-rw-r--r--lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--lib/Sema/SemaExprCXX.cpp2
-rw-r--r--test/SemaObjC/debugger-cast-result-to-id.m27
-rw-r--r--test/SemaObjC/unknown-anytype.m4
6 files changed, 36 insertions, 3 deletions
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 4f107e55a6..d2dff8947c 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/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/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index fd3e32cd35..557e73bbfe 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/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/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 23fe830a03..7fd2247907 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/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/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index b35ea802e5..d0e40ba271 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/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/test/SemaObjC/debugger-cast-result-to-id.m b/test/SemaObjC/debugger-cast-result-to-id.m
new file mode 100644
index 0000000000..86f4c3aa24
--- /dev/null
+++ b/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/test/SemaObjC/unknown-anytype.m b/test/SemaObjC/unknown-anytype.m
index 89e45e4a13..38e058c513 100644
--- a/test/SemaObjC/unknown-anytype.m
+++ b/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}}