aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-03-06 21:34:12 +0000
committerSean Callanan <scallanan@apple.com>2012-03-06 21:34:12 +0000
commitce9c8319f43556d9c3fe2771665483d310d86fd8 (patch)
tree7d0f95820306631ec4f5e768df79feb5d74cca80
parent1c31ee8f9bf8c4de29cd8ca42dfe0fb37aa2bf52 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152147 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp44
-rw-r--r--test/SemaCXX/unknown-anytype-blocks.cpp11
2 files changed, 45 insertions, 10 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 4751db756a..2bc9e064b6 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/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/test/SemaCXX/unknown-anytype-blocks.cpp b/test/SemaCXX/unknown-anytype-blocks.cpp
new file mode 100644
index 0000000000..86ce7e1700
--- /dev/null
+++ b/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;
+ }
+}