diff options
author | Douglas Gregor <dgregor@apple.com> | 2013-03-07 22:57:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2013-03-07 22:57:58 +0000 |
commit | b5af2e9c5a4f995c3d2515d007b8b40659808a18 (patch) | |
tree | b795d35bb0628e730f062b1a2f86f6911e629564 | |
parent | c1a658314332fecdd04046fa714edcd14b5484ad (diff) | |
download | bcm5719-llvm-b5af2e9c5a4f995c3d2515d007b8b40659808a18.tar.gz bcm5719-llvm-b5af2e9c5a4f995c3d2515d007b8b40659808a18.zip |
Improve LLDB's implicit cast-to-id to work with C++11 auto and any Objective-C object type <rdar://problem/13338107>.
llvm-svn: 176665
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 36 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 5 | ||||
-rw-r--r-- | clang/test/SemaObjC/debugger-cast-result-to-id.m | 2 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/debugger-cast-result-to-id.mm | 34 |
4 files changed, 59 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4fa790515da..00d1cf157be 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7125,6 +7125,20 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, DeduceInit = CXXDirectInit->getExpr(0); } } + + // Expressions default to 'id' when we're in a debugger. + bool DefaultedToAuto = false; + if (getLangOpts().DebuggerCastResultToId && + Init->getType() == Context.UnknownAnyTy) { + ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); + return; + } + Init = Result.take(); + DefaultedToAuto = true; + } + TypeSourceInfo *DeducedType = 0; if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) == DAR_Failed) @@ -7145,7 +7159,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // 'id' instead of a specific object type prevents most of our usual checks. // We only want to warn outside of template instantiations, though: // inside a template, the 'id' could have come from a parameter. - if (ActiveTemplateInstantiations.empty() && + if (ActiveTemplateInstantiations.empty() && !DefaultedToAuto && DeducedType->getType()->isObjCIdType()) { SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc(); Diag(Loc, diag::warn_auto_var_is_id) @@ -7236,17 +7250,17 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // CheckInitializerTypes may change it. QualType DclT = VDecl->getType(), SavT = DclT; - // Top-level message sends default to 'id' when we're in a debugger - // and we are assigning it to a variable of 'id' type. - if (getLangOpts().DebuggerCastResultToId && DclT->isObjCIdType()) - if (Init->getType() == Context.UnknownAnyTy && isa<ObjCMessageExpr>(Init)) { - ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); - if (Result.isInvalid()) { - VDecl->setInvalidDecl(); - return; - } - Init = Result.take(); + // Expressions default to 'id' when we're in a debugger + // and we are assigning it to a variable of Objective-C pointer type. + if (getLangOpts().DebuggerCastResultToId && DclT->isObjCObjectPointerType() && + Init->getType() == Context.UnknownAnyTy) { + ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); + return; } + Init = Result.take(); + } // Perform the initialization. if (!VDecl->isInvalidDecl()) { diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 49d66113dcd..f63ed093a67 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -5489,10 +5489,9 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, if (DiagnoseUnexpandedParameterPack(FullExpr.get())) return ExprError(); - // Top-level message sends default to 'id' when we're in a debugger. + // Top-level expressions default to 'id' when we're in a debugger. if (DiscardedValue && getLangOpts().DebuggerCastResultToId && - FullExpr.get()->getType() == Context.UnknownAnyTy && - isa<ObjCMessageExpr>(FullExpr.get())) { + FullExpr.get()->getType() == Context.UnknownAnyTy) { FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType()); if (FullExpr.isInvalid()) return ExprError(); diff --git a/clang/test/SemaObjC/debugger-cast-result-to-id.m b/clang/test/SemaObjC/debugger-cast-result-to-id.m index 00a02be2c30..ecf3e74ba79 100644 --- a/clang/test/SemaObjC/debugger-cast-result-to-id.m +++ b/clang/test/SemaObjC/debugger-cast-result-to-id.m @@ -6,6 +6,8 @@ extern __unknown_anytype test1(); void test_unknown_anytype_receiver() { (void)(int)[[test0 unknownMethod] otherUnknownMethod];; (void)(id)[[test1() unknownMethod] otherUnknownMethod]; + id x = test0; + id y = test1(); } // rdar://10988847 diff --git a/clang/test/SemaObjCXX/debugger-cast-result-to-id.mm b/clang/test/SemaObjCXX/debugger-cast-result-to-id.mm index cd7aa7b6ac0..815ae3833d7 100644 --- a/clang/test/SemaObjCXX/debugger-cast-result-to-id.mm +++ b/clang/test/SemaObjCXX/debugger-cast-result-to-id.mm @@ -1,7 +1,21 @@ -// RUN: %clang_cc1 -fdebugger-support -fdebugger-cast-result-to-id -funknown-anytype -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fdebugger-support -fdebugger-cast-result-to-id -funknown-anytype -fsyntax-only -verify %s + +extern __unknown_anytype test0a; +extern __unknown_anytype test1a(); +extern __unknown_anytype test0b; +extern __unknown_anytype test1b(); +extern __unknown_anytype test0c; +extern __unknown_anytype test1c(); +extern __unknown_anytype test0d; +extern __unknown_anytype test1d(); +extern __unknown_anytype test0d; +extern __unknown_anytype test1d(); + +@interface A +@end // rdar://problem/9416370 -namespace test0 { +namespace rdar9416370 { void test(id x) { if ([x foo]) {} // expected-error {{no known method '-foo'; cast the message send to the method's return type}} [x foo]; @@ -10,8 +24,20 @@ namespace test0 { // rdar://10988847 @class NSString; // expected-note {{forward declaration of class here}} -namespace test1 { - void rdar10988847() { +namespace rdar10988847 { + void test() { id s = [NSString stringWithUTF8String:"foo"]; // expected-warning {{receiver 'NSString' is a forward class and corresponding @interface may not exist}} } } + +// rdar://13338107 +namespace rdar13338107 { + void test() { + id x1 = test0a; + id x2 = test1a(); + A *x3 = test0b; + A *x4 = test1b(); + auto x5 = test0c; + auto x6 = test1c(); + } +} |