[cfe-commits] r104608 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-block-argument.m
Fariborz Jahanian
fjahanian at apple.com
Tue May 25 08:56:09 PDT 2010
Author: fjahanian
Date: Tue May 25 10:56:08 2010
New Revision: 104608
URL: http://llvm.org/viewvc/llvm-project?rev=104608&view=rev
Log:
Patch to rewrite block pointers as arguments to
methods. (Radar 7987817).
Added:
cfe/trunk/test/Rewriter/rewrite-block-argument.m
Modified:
cfe/trunk/lib/Frontend/RewriteObjC.cpp
Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=104608&r1=104607&r2=104608&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Tue May 25 10:56:08 2010
@@ -276,6 +276,7 @@
bool isSuperReceiver(Expr *recExpr);
QualType getSuperStructType();
QualType getConstantStringStructType();
+ QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
// Expression Rewriting.
@@ -2945,6 +2946,11 @@
QualType type = ICE->getType()->isObjCQualifiedIdType()
? Context->getObjCIdType()
: ICE->getType();
+ // Make sure we convert "type (^)(...)" to "type (*)(...)".
+ if (isTopLevelBlockPointerType(type)) {
+ const BlockPointerType *BPT = type->getAs<BlockPointerType>();
+ type = Context->getPointerType(BPT->getPointeeType());
+ }
userExpr = NoTypeInfoCStyleCastExpr(Context, type, CastExpr::CK_Unknown,
userExpr);
}
@@ -4113,7 +4119,14 @@
E = BD->param_end(); AI != E; ++AI) {
if (AI != BD->param_begin()) S += ", ";
ParamStr = (*AI)->getNameAsString();
- (*AI)->getType().getAsStringInternal(ParamStr, Context->PrintingPolicy);
+ QualType QT = (*AI)->getType();
+ if (isTopLevelBlockPointerType(QT)) {
+ const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+ Context->getPointerType(BPT->getPointeeType()).
+ getAsStringInternal(ParamStr, Context->PrintingPolicy);
+ }
+ else
+ QT.getAsStringInternal(ParamStr, Context->PrintingPolicy);
S += ParamStr;
}
if (FT->isVariadic()) {
@@ -4534,6 +4547,47 @@
return;
}
+/// convertFunctionTypeOfBlocks - This routine converts a function type
+/// whose result type may be a block pointer or whose argument type(s)
+/// might be block pointers to an equivalent funtion type replacing
+/// all block pointers to function pointers.
+QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
+ const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+ // FTP will be null for closures that don't take arguments.
+ // Generate a funky cast.
+ llvm::SmallVector<QualType, 8> ArgTypes;
+ bool HasBlockType = false;
+ QualType Res = FT->getResultType();
+ if (isTopLevelBlockPointerType(Res)) {
+ const BlockPointerType *BPT = Res->getAs<BlockPointerType>();
+ Res = Context->getPointerType(BPT->getPointeeType());
+ HasBlockType = true;
+ }
+
+ if (FTP) {
+ for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
+ E = FTP->arg_type_end(); I && (I != E); ++I) {
+ QualType t = *I;
+ // Make sure we convert "t (^)(...)" to "t (*)(...)".
+ if (isTopLevelBlockPointerType(t)) {
+ const BlockPointerType *BPT = t->getAs<BlockPointerType>();
+ t = Context->getPointerType(BPT->getPointeeType());
+ HasBlockType = true;
+ }
+ ArgTypes.push_back(t);
+ }
+ }
+ QualType FuncType;
+ // FIXME. Does this work if block takes no argument but has a return type
+ // which is of block type?
+ if (HasBlockType)
+ FuncType = Context->getFunctionType(Res,
+ &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0,
+ false, false, 0, 0, FunctionType::ExtInfo());
+ else FuncType = QualType(FT, 0);
+ return FuncType;
+}
+
Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
// Navigate to relevant type information.
const BlockPointerType *CPT = 0;
@@ -5176,7 +5230,8 @@
std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
// Get a pointer to the function type so we can cast appropriately.
- QualType FType = Context->getPointerType(QualType(Exp->getFunctionType(),0));
+ QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
+ QualType FType = Context->getPointerType(BFT);
FunctionDecl *FD;
Expr *NewRep;
Added: cfe/trunk/test/Rewriter/rewrite-block-argument.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-block-argument.m?rev=104608&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-block-argument.m (added)
+++ cfe/trunk/test/Rewriter/rewrite-block-argument.m Tue May 25 10:56:08 2010
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -x objective-c -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -Wno-address-of-temporary -Did="void *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o %t %t-rw.cpp
+// radar 7987817
+
+void *sel_registerName(const char *);
+
+ at interface Test {
+}
+ at end
+
+ at implementation Test
+
+- (void)enumerateProvidersWithBlock:(void (^)(void))block {
+ block();
+}
+
+- (void)providerEnumerator {
+ ^(void (^providerBlock)(void)) {
+ [self enumerateProvidersWithBlock:providerBlock];
+ };
+}
+
+- (void)testNilBlock {
+ [self enumerateProvidersWithBlock:0];
+}
+
+ at end
+
+
+
+int main(int argc, char *argv[]) {
+ return 0;
+}
More information about the cfe-commits
mailing list