summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-03-01 01:45:25 +0000
committerAnders Carlsson <andersca@mac.com>2009-03-01 01:45:25 +0000
commit961763e35ac7ed92817061cf11941b3074b00aec (patch)
tree3f8c3a5373ed2d08e3b46a1205ef74a081220c22 /clang/lib/CodeGen/CGBlocks.cpp
parent25f282f566880245447cbe949e5728765159fa51 (diff)
downloadbcm5719-llvm-961763e35ac7ed92817061cf11941b3074b00aec.tar.gz
bcm5719-llvm-961763e35ac7ed92817061cf11941b3074b00aec.zip
Emit errors about unsupported blocks features.
llvm-svn: 65751
Diffstat (limited to 'clang/lib/CodeGen/CGBlocks.cpp')
-rw-r--r--clang/lib/CodeGen/CGBlocks.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index 93e1b57fc98..ba9480fa0e4 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -132,6 +132,44 @@ static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info)
return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty();
}
+/// CanGenerateCodeForBlockExpr - Returns whether CodeGen for the block expr
+/// is supported. Will emit a diagnostic and return false if not.
+/// FIXME: Once we support everything this should of course be removed.
+static bool CanGenerateCodeForBlockExpr(CodeGenFunction &CGF,
+ const BlockExpr* BE,
+ const CodeGenFunction::BlockInfo &Info)
+{
+ if (!Info.ByRefDeclRefs.empty()) {
+ CGF.ErrorUnsupported(BE, "block expression with __block variables");
+ return false;
+ }
+
+ for (size_t I = 0, E = Info.ByCopyDeclRefs.size(); I != E; ++I) {
+ const BlockDeclRefExpr *E = Info.ByCopyDeclRefs[I];
+
+ E->getType()->dump();
+
+ if (E->getType()->isBlockPointerType()) {
+ CGF.ErrorUnsupported(BE, "block expression with imported block");
+ return false;
+ }
+
+ if (E->getDecl()->getAttr<ObjCNSObjectAttr>() ||
+ CGF.getContext().isObjCNSObjectType(E->getType())) {
+ CGF.ErrorUnsupported(BE, "block expression with __attribute__((NSObject))"
+ " variable");
+ return false;
+ }
+
+ if (CGF.getContext().isObjCObjectPointerType(E->getType())) {
+ CGF.ErrorUnsupported(BE, "block expression with Objective-C variable");
+ return false;
+ }
+ }
+
+ return true;
+}
+
// FIXME: Push most into CGM, passing down a few bits, like current
// function name.
llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
@@ -144,6 +182,9 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
if (CanBlockBeGlobal(Info))
return CGM.GetAddrOfGlobalBlock(BE, Name.c_str());
+ if (!CanGenerateCodeForBlockExpr(*this, BE, Info))
+ return llvm::UndefValue::get(ConvertType(BE->getType()));
+
std::vector<llvm::Constant*> Elts;
llvm::Constant *C;
llvm::Value *V;
OpenPOWER on IntegriCloud