forked from OSchip/llvm-project
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
This commit is contained in:
parent
461b7bb9e6
commit
1249511024
|
@ -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);
|
||||
E->setType(DestType);
|
||||
|
||||
// Rebuild the sub-expression as the pointee (function) type.
|
||||
DestType = DestType->castAs<PointerType>()->getPointeeType();
|
||||
// Rebuild the sub-expression as the pointee (function) type.
|
||||
DestType = DestType->castAs<PointerType>()->getPointeeType();
|
||||
|
||||
ExprResult Result = Visit(E->getSubExpr());
|
||||
if (!Result.isUsable()) return ExprError();
|
||||
ExprResult Result = Visit(E->getSubExpr());
|
||||
if (!Result.isUsable()) return ExprError();
|
||||
|
||||
E->setSubExpr(Result.take());
|
||||
return S.Owned(E);
|
||||
E->setSubExpr(Result.take());
|
||||
return S.Owned(E);
|
||||
}
|
||||
else if (E->getCastKind() == CK_LValueToRValue)
|
||||
{
|
||||
assert(E->getValueKind() == VK_RValue);
|
||||
assert(E->getObjectKind() == OK_Ordinary);
|
||||
|
||||
assert(isa<BlockPointerType>(E->getType()));
|
||||
|
||||
E->setType(DestType);
|
||||
|
||||
// The sub-expression has to be a lvalue reference, so rebuild it as such.
|
||||
DestType = S.Context.getLValueReferenceType(DestType);
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue