]> granicus.if.org Git - clang/commitdiff
Extended the UnknownAnyTy resolver to handle
authorSean Callanan <scallanan@apple.com>
Tue, 6 Mar 2012 21:34:12 +0000 (21:34 +0000)
committerSean Callanan <scallanan@apple.com>
Tue, 6 Mar 2012 21:34:12 +0000 (21:34 +0000)
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

lib/Sema/SemaExpr.cpp
test/SemaCXX/unknown-anytype-blocks.cpp [new file with mode: 0644]

index 4751db756a26d89d3acd5ac2c0ca58c0e974f989..2bc9e064b6e5429b7b1a65ca1b6800977c705072 100644 (file)
@@ -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 (file)
index 0000000..86ce7e1
--- /dev/null
@@ -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;
+  }
+}