diff options
| author | Sean Callanan <scallanan@apple.com> | 2012-03-06 21:34:12 +0000 |
|---|---|---|
| committer | Sean Callanan <scallanan@apple.com> | 2012-03-06 21:34:12 +0000 |
| commit | 1249511024192f7cb4ba433f709d07a877c75105 (patch) | |
| tree | a1385195f84522e293ddf7b629d29b4e189fc6d8 /clang | |
| parent | 461b7bb9e623d1a1e86a7b754ce179af2deaa52a (diff) | |
| download | bcm5719-llvm-1249511024192f7cb4ba433f709d07a877c75105.tar.gz bcm5719-llvm-1249511024192f7cb4ba433f709d07a877c75105.zip | |
Extended the UnknownAnyTy resolver to handle
blocks with unknown return types. This allows
LLDB to call blocks even when their return types
aren't provided in the debug information.
llvm-svn: 152147
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 44 | ||||
| -rw-r--r-- | clang/test/SemaCXX/unknown-anytype-blocks.cpp | 11 |
2 files changed, 45 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4751db756a2..2bc9e064b6e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10810,20 +10810,44 @@ ExprResult RebuildUnknownAnyExpr::VisitObjCMessageExpr(ObjCMessageExpr *E) { ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) { // The only case we should ever see here is a function-to-pointer decay. - assert(E->getCastKind() == CK_FunctionToPointerDecay); - assert(E->getValueKind() == VK_RValue); - assert(E->getObjectKind() == OK_Ordinary); + if (E->getCastKind() == CK_FunctionToPointerDecay) + { + assert(E->getValueKind() == VK_RValue); + assert(E->getObjectKind() == OK_Ordinary); + + E->setType(DestType); + + // Rebuild the sub-expression as the pointee (function) type. + DestType = DestType->castAs<PointerType>()->getPointeeType(); + + ExprResult Result = Visit(E->getSubExpr()); + if (!Result.isUsable()) return ExprError(); + + E->setSubExpr(Result.take()); + return S.Owned(E); + } + else if (E->getCastKind() == CK_LValueToRValue) + { + assert(E->getValueKind() == VK_RValue); + assert(E->getObjectKind() == OK_Ordinary); - E->setType(DestType); + assert(isa<BlockPointerType>(E->getType())); - // Rebuild the sub-expression as the pointee (function) type. - DestType = DestType->castAs<PointerType>()->getPointeeType(); + E->setType(DestType); - ExprResult Result = Visit(E->getSubExpr()); - if (!Result.isUsable()) return ExprError(); + // The sub-expression has to be a lvalue reference, so rebuild it as such. + DestType = S.Context.getLValueReferenceType(DestType); - E->setSubExpr(Result.take()); - return S.Owned(E); + ExprResult Result = Visit(E->getSubExpr()); + if (!Result.isUsable()) return ExprError(); + + E->setSubExpr(Result.take()); + return S.Owned(E); + } + else + { + llvm_unreachable("Unhandled cast type!"); + } } ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { diff --git a/clang/test/SemaCXX/unknown-anytype-blocks.cpp b/clang/test/SemaCXX/unknown-anytype-blocks.cpp new file mode 100644 index 00000000000..86ce7e17009 --- /dev/null +++ b/clang/test/SemaCXX/unknown-anytype-blocks.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -funknown-anytype -fblocks -fsyntax-only -verify -std=c++11 %s + +namespace test1 { + __unknown_anytype (^foo)(); + __unknown_anytype (^bar)(); + int test() { + auto ret1 = (int)foo(); + auto ret2 = bar(); // expected-error {{'bar' has unknown return type; cast the call to its declared return type}} + return ret1; + } +} |

